From 4c58a32f4784eb6a77c1ba8608d3d52e3a4cdc40 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Fri, 14 Aug 2020 06:04:51 -0700 Subject: [PATCH] c++: More simplification of name_lookup api Continuing fixing name lookup's API we have two parameters saying what we'd like to find 'prefer_type', which is a tri-valued boolan with meaning 'don't care', 'type or namespace', 'type or death'. And we have a second parameter 'namespaces_only', which means 'namespace or death'. There are only 4 states, because the latter one has priority. Firstly 'prefer_type' isn't really the right name -- it's not a preference, it's a requirement. Name lookup maps those two parameters into 2 LOOKUP_ bits. We can simply have callers express that desire directly. So this adds another enum class, LOOK_want, which expresses all those options in 2 bits. Most of this patch is then the expected fallout from such a change. The parser was mapping its internal state into a prefer_type value, which was then mapped into the LOOKUP_ bits. So this saves a conversion there. Also the parser's conversion routine had an 'is_template' flag, which was only ever true in one place, where the parser also had to deal with other nuances of the flags to pass. So just drop that parm and deal with it at the call site too. I've left LOOKUP_HIDDEN alone for the moment. That'll be next. gcc/cp/ * cp-tree.h (LOOKUP_PREFER_TYPES, LOOKUP_PREFER_NAMESPACES) (LOOKUP_NAMESPACES_ONLY, LOOKUP_TYPES_ONLY) (LOOKUP_QUALIFIERS_ONL): Delete. (LOOKUP_HIDDEN): Adjust. * name-lookup.h (enum class LOOK_want): New. (operator|, operator&): Overloads for it. (lookup_name_real): Replace prefer_type & namespaces_only with LOOK_want parm. (lookup_qualified_name): Replace prefer_type with LOOK_want. (lookup_name_prefer_type): Replace with ... (lookup_name): ... this. New overload with LOOK_want parm. * name-lookup.c (struct name_lookup): Replace flags with want and hidden fields. Adjust constructors. (name_lookyp::add_overload): Correct hidden stripping test. Update for new LOOK_want type. (name_lookup::process_binding): Likewise. (name_lookup::search_unqualified): Use hidden flag. (identifier_type_value_1): Adjust lookup_name_real call. (set_decl_namespace): Adjust name_lookup ctor. (lookup_flags): Delete. (qualify_lookup): Add LOOK_want parm, adjust. (lookup_qualified_name): Replace prefer_type parm with LOOK_want. (lookup_name_real_1): Replace prefer_type and namespaces_only with LOOK_want parm. (lookup_name_real): Likewise. (lookup_name_nonclass, lookup_name): Adjust lookup_name_real call. (lookup_name_prefer_type): Rename to ... (lookup_name): ... here. New overload with LOOK_want parm. (lookup_type_scope_1): Adjust qualify_lookup calls. * call.c (build_operator_new_call) (add_operator_candidates): Adjust lookup_name_real calls. * coroutines.cc (find_coro_traits_template_decl) (find_coro_handle_template_decl, morph_fn_to_coro): Adjust lookup_qualified_name calls. * cp-objcp-common.c (identifier_global_tag): Likewise. * decl.c (get_tuple_size, get_tuple_decomp_init): Likewise. (lookup_and_check_tag): Use lookup_name overload. * parser.c (cp_parser_userdef_numeric_literal): Adjust lookup_qualified_name call. (prefer_arg_type): Drop template_mem_access parm, return LOOK_want value. (cp_parser_lookup_name): Adjust lookup_member, lookup_name_real calls. * pt.c (check_explicit_specialization): Adjust lookup_qualified_name call. (tsubst_copy_and_build, tsubst_qualified_name): Likewise (deduction_guides_for): Likewise. (tsubst_friend_class): Adjust lookup_name_real call. (lookup_init_capture, tsubst_expr): Likewise. * rtti.c (emit_support_tinfos): Adjust lookup_qualified_name call. * semantics.c (omp_reduction_lookup): Likewise. (capture_decltype): Adjust lookup_name_real call. libcc1/ * libcp1plugin.cc (plugin_build_dependent_expr): Adjust lookup_name_real & lookup_qualified_name calls. --- gcc/cp/call.c | 4 +- gcc/cp/coroutines.cc | 8 ++- gcc/cp/cp-objcp-common.c | 2 +- gcc/cp/cp-tree.h | 15 +--- gcc/cp/decl.c | 6 +- gcc/cp/name-lookup.c | 152 ++++++++++++++++++--------------------- gcc/cp/name-lookup.h | 34 +++++++-- gcc/cp/parser.c | 34 ++++----- gcc/cp/pt.c | 21 +++--- gcc/cp/rtti.c | 2 +- gcc/cp/semantics.c | 4 +- libcc1/libcp1plugin.cc | 5 +- 12 files changed, 142 insertions(+), 145 deletions(-) diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 47a368d069da..d4935bd0ce13 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4704,7 +4704,7 @@ build_operator_new_call (tree fnname, vec **args, up in the global scope. we disregard block-scope declarations of "operator new". */ - fns = lookup_name_real (fnname, LOOK_where::NAMESPACE, 0, 0, 0); + fns = lookup_name_real (fnname, LOOK_where::NAMESPACE, LOOK_want::NORMAL, 0); fns = lookup_arg_dependent (fnname, fns, *args); if (align_arg) @@ -5983,7 +5983,7 @@ add_operator_candidates (z_candidate **candidates, if (!memonly) { tree fns = lookup_name_real (fnname, LOOK_where::BLOCK_NAMESPACE, - 0, 0, 0); + LOOK_want::NORMAL, 0); fns = lookup_arg_dependent (fnname, fns, arglist); add_candidates (fns, NULL_TREE, arglist, NULL_TREE, NULL_TREE, false, NULL_TREE, NULL_TREE, diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 8bebbe3f9e1a..22ba81c80252 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -267,7 +267,7 @@ find_coro_traits_template_decl (location_t kw) static bool traits_error_emitted = false; tree traits_decl = lookup_qualified_name (std_node, coro_traits_identifier, - 0, + LOOK_want::NORMAL, /*complain=*/!traits_error_emitted); if (traits_decl == error_mark_node || !DECL_TYPE_TEMPLATE_P (traits_decl)) @@ -348,7 +348,8 @@ find_coro_handle_template_decl (location_t kw) it once. */ static bool coro_handle_error_emitted = false; tree handle_decl = lookup_qualified_name (std_node, coro_handle_identifier, - 0, !coro_handle_error_emitted); + LOOK_want::NORMAL, + !coro_handle_error_emitted); if (handle_decl == error_mark_node || !DECL_CLASS_TEMPLATE_P (handle_decl)) { @@ -4309,7 +4310,8 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) non-throwing noexcept-specification. So we need std::nothrow. */ tree std_nt = lookup_qualified_name (std_node, get_identifier ("nothrow"), - 0, /*complain=*/true, false); + LOOK_want::NORMAL, + /*complain=*/true, false); if (!std_nt || std_nt == error_mark_node) error_at (fn_start, "%qE is provided by %qT but % " "cannot be found", grooaf, promise_type); diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index fecf86698804..852a34dbc5f2 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -355,7 +355,7 @@ identifier_global_value (tree name) tree identifier_global_tag (tree name) { - tree ret = lookup_qualified_name (global_namespace, name, /*prefer_type*/2, + tree ret = lookup_qualified_name (global_namespace, name, LOOK_want::TYPE, /*complain*/false); if (ret == error_mark_node) return NULL_TREE; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index fc54e6bb9bdf..82834e65a53f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5567,16 +5567,10 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; #define LOOKUP_DESTRUCTOR (1 << 5) /* Do not permit references to bind to temporaries. */ #define LOOKUP_NO_TEMP_BIND (1 << 6) -/* Do not accept objects, and possibly namespaces. */ -#define LOOKUP_PREFER_TYPES (1 << 7) -/* Do not accept objects, and possibly types. */ -#define LOOKUP_PREFER_NAMESPACES (1 << 8) -/* Accept types or namespaces. */ -#define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES) /* Return friend declarations and un-declared builtin functions. (Normally, these entities are registered in the symbol table, but not found by lookup.) */ -#define LOOKUP_HIDDEN (LOOKUP_PREFER_NAMESPACES << 1) +#define LOOKUP_HIDDEN (1 << 7) /* We're trying to treat an lvalue as an rvalue. */ /* FIXME remove when we extend the P1825 semantics to all standard modes, the C++20 approach uses IMPLICIT_RVALUE_P instead. */ @@ -5626,13 +5620,6 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; /* We're initializing an aggregate from a parenthesized list of values. */ #define LOOKUP_AGGREGATE_PAREN_INIT (LOOKUP_REVERSED << 1) -#define LOOKUP_NAMESPACES_ONLY(F) \ - (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES)) -#define LOOKUP_TYPES_ONLY(F) \ - (!((F) & LOOKUP_PREFER_NAMESPACES) && ((F) & LOOKUP_PREFER_TYPES)) -#define LOOKUP_QUALIFIERS_ONLY(F) ((F) & LOOKUP_PREFER_BOTH) - - /* These flags are used by the conversion code. CONV_IMPLICIT : Perform implicit conversions (standard and user-defined). CONV_STATIC : Perform the explicit conversions for static_cast. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a68bbe04da7e..d1af63e73009 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8100,7 +8100,7 @@ get_tuple_size (tree type) if (inst == error_mark_node || !COMPLETE_TYPE_P (inst)) return NULL_TREE; tree val = lookup_qualified_name (inst, value_identifier, - /*type*/false, /*complain*/false); + LOOK_want::NORMAL, /*complain*/false); if (TREE_CODE (val) == VAR_DECL || TREE_CODE (val) == CONST_DECL) val = maybe_constant_value (val); if (TREE_CODE (val) == INTEGER_CST) @@ -8144,7 +8144,7 @@ get_tuple_decomp_init (tree decl, unsigned i) e = move (e); tree fns = lookup_qualified_name (TREE_TYPE (e), get__identifier, - /*type*/false, /*complain*/false); + LOOK_want::NORMAL, /*complain*/false); bool use_member_get = false; /* To use a member get, member lookup must find at least one @@ -14834,7 +14834,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, { /* First try ordinary name lookup, ignoring hidden class name injected via friend declaration. */ - decl = lookup_name_prefer_type (name, 2); + decl = lookup_name (name, LOOK_want::TYPE); decl = strip_using_decl (decl); /* If that fails, the name will be placed in the smallest non-class, non-function-prototype scope according to 3.3.1/5. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 4fdac9421d16..51de6fb4c36e 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -164,7 +164,9 @@ public: tree name; /* The identifier being looked for. */ tree value; /* A (possibly ambiguous) set of things found. */ tree type; /* A type that has been found. */ - int flags; /* Lookup flags. */ + LOOK_want want; /* What kind of entity we want. */ + bool hidden; /* Allow hidden */ + bool deduping; /* Full deduping is needed because using declarations are in play. */ vec *scopes; @@ -177,8 +179,9 @@ protected: static name_lookup *active; public: - name_lookup (tree n, int f = 0) - : name (n), value (NULL_TREE), type (NULL_TREE), flags (f), + name_lookup (tree n, LOOK_want w = LOOK_want::NORMAL, bool h = false) + : name (n), value (NULL_TREE), type (NULL_TREE), + want (w), hidden (h), deduping (false), scopes (NULL), previous (NULL) { preserve_state (); @@ -417,7 +420,7 @@ name_lookup::add_overload (tree fns) if (!deduping && TREE_CODE (fns) == OVERLOAD) { tree probe = fns; - if (flags & LOOKUP_HIDDEN) + if (!hidden) probe = ovl_skip_hidden (probe); if (probe && TREE_CODE (probe) == OVERLOAD && OVL_DEDUP_P (probe)) @@ -485,13 +488,13 @@ name_lookup::process_binding (tree new_val, tree new_type) { /* Did we really see a type? */ if (new_type - && (LOOKUP_NAMESPACES_ONLY (flags) - || (!(flags & LOOKUP_HIDDEN) + && ((want & LOOK_want::TYPE_NAMESPACE) == LOOK_want::NAMESPACE + || (!hidden && DECL_LANG_SPECIFIC (new_type) && DECL_ANTICIPATED (new_type)))) new_type = NULL_TREE; - if (new_val && !(flags & LOOKUP_HIDDEN)) + if (new_val && !hidden) new_val = ovl_skip_hidden (new_val); /* Do we really see a value? */ @@ -501,21 +504,21 @@ name_lookup::process_binding (tree new_val, tree new_type) case TEMPLATE_DECL: /* If we expect types or namespaces, and not templates, or this is not a template class. */ - if ((LOOKUP_QUALIFIERS_ONLY (flags) - && !DECL_TYPE_TEMPLATE_P (new_val))) + if (bool (want & LOOK_want::TYPE_NAMESPACE) + && !DECL_TYPE_TEMPLATE_P (new_val)) new_val = NULL_TREE; break; case TYPE_DECL: - if (LOOKUP_NAMESPACES_ONLY (flags) - || (new_type && (flags & LOOKUP_PREFER_TYPES))) + if ((want & LOOK_want::TYPE_NAMESPACE) == LOOK_want::NAMESPACE + || (new_type && bool (want & LOOK_want::TYPE))) new_val = NULL_TREE; break; case NAMESPACE_DECL: - if (LOOKUP_TYPES_ONLY (flags)) + if ((want & LOOK_want::TYPE_NAMESPACE) == LOOK_want::TYPE) new_val = NULL_TREE; break; default: - if (LOOKUP_QUALIFIERS_ONLY (flags)) + if (bool (want & LOOK_want::TYPE_NAMESPACE)) new_val = NULL_TREE; } @@ -721,7 +724,7 @@ name_lookup::search_unqualified (tree scope, cp_binding_level *level) function, class template or function template the friend is a member of the innermost enclosing namespace. See also [basic.lookup.unqual]/7 */ - if (flags & LOOKUP_HIDDEN) + if (hidden) break; } @@ -3741,7 +3744,7 @@ identifier_type_value_1 (tree id) return REAL_IDENTIFIER_TYPE_VALUE (id); /* Have to search for it. It must be on the global level, now. Ask lookup_name not to return non-types. */ - id = lookup_name_real (id, LOOK_where::BLOCK_NAMESPACE, 2, 0, 0); + id = lookup_name_real (id, LOOK_where::BLOCK_NAMESPACE, LOOK_want::TYPE, 0); if (id) return TREE_TYPE (id); return NULL_TREE; @@ -4742,7 +4745,7 @@ do_class_using_decl (tree scope, tree name) || scope == error_mark_node) return NULL_TREE; - name_lookup lookup (name, 0); + name_lookup lookup (name); if (!lookup_using_decl (scope, lookup)) return NULL_TREE; @@ -4815,7 +4818,7 @@ set_decl_namespace (tree decl, tree scope, bool friendp) children. */ tree old = NULL_TREE; { - name_lookup lookup (DECL_NAME (decl), LOOKUP_HIDDEN); + name_lookup lookup (DECL_NAME (decl), LOOK_want::NORMAL, true); if (!lookup.search_qualified (scope, /*usings=*/false)) /* No old declaration at all. */ goto not_found; @@ -5127,7 +5130,7 @@ finish_nonmember_using_decl (tree scope, tree name) if (scope == error_mark_node || name == error_mark_node) return; - name_lookup lookup (name, 0); + name_lookup lookup (name); if (!lookup_using_decl (scope, lookup)) return; @@ -5209,43 +5212,35 @@ cp_namespace_decls (tree ns) return NAMESPACE_LEVEL (ns)->names; } -/* Combine prefer_type and namespaces_only into flags. */ - -static int -lookup_flags (int prefer_type, int namespaces_only) -{ - if (namespaces_only) - return LOOKUP_PREFER_NAMESPACES; - if (prefer_type > 1) - return LOOKUP_PREFER_TYPES; - if (prefer_type > 0) - return LOOKUP_PREFER_BOTH; - return 0; -} - /* Given a lookup that returned VAL, use FLAGS to decide if we want to ignore it or not. Subroutine of lookup_name_real and lookup_type_scope. */ static bool -qualify_lookup (tree val, int flags) +qualify_lookup (tree val, LOOK_want want, int flags) { if (val == NULL_TREE) return false; - if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL) + + if (bool (want & LOOK_want::NAMESPACE) && TREE_CODE (val) == NAMESPACE_DECL) return true; - if (flags & LOOKUP_PREFER_TYPES) + + if (bool (want & LOOK_want::TYPE)) { tree target_val = strip_using_decl (val); + if (TREE_CODE (target_val) == TYPE_DECL || TREE_CODE (target_val) == TEMPLATE_DECL) return true; } - if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES)) + + if (bool (want & LOOK_want::TYPE_NAMESPACE)) return false; + /* Look through lambda things that we shouldn't be able to see. */ if (!(flags & LOOKUP_HIDDEN) && is_lambda_ignored_entity (val)) return false; + return true; } @@ -5992,8 +5987,7 @@ suggest_alternative_in_scoped_enum (tree name, tree scoped_enum) /* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL or a class TYPE). - If PREFER_TYPE is > 0, we only return TYPE_DECLs or namespaces. - If PREFER_TYPE is > 1, we only return TYPE_DECLs. + WANT as for lookup_name_real_1. Returns a DECL (or OVERLOAD, or BASELINK) representing the declaration found. If no suitable declaration can be found, @@ -6001,17 +5995,14 @@ suggest_alternative_in_scoped_enum (tree name, tree scoped_enum) neither a class-type nor a namespace a diagnostic is issued. */ tree -lookup_qualified_name (tree scope, tree name, int prefer_type, bool complain, +lookup_qualified_name (tree scope, tree name, LOOK_want want, bool complain, bool find_hidden /*=false*/) { tree t = NULL_TREE; if (TREE_CODE (scope) == NAMESPACE_DECL) { - int flags = lookup_flags (prefer_type, /*namespaces_only*/false); - if (find_hidden) - flags |= LOOKUP_HIDDEN; - name_lookup lookup (name, flags); + name_lookup lookup (name, want, find_hidden); if (qualified_namespace_lookup (scope, &lookup)) t = lookup.value; @@ -6019,7 +6010,8 @@ lookup_qualified_name (tree scope, tree name, int prefer_type, bool complain, else if (cxx_dialect != cxx98 && TREE_CODE (scope) == ENUMERAL_TYPE) t = lookup_enumerator (scope, name); else if (is_class_type (scope, complain)) - t = lookup_member (scope, name, 2, prefer_type, tf_warning_or_error); + t = lookup_member (scope, name, 2, bool (want & LOOK_want::TYPE), + tf_warning_or_error); if (!t) return error_mark_node; @@ -6029,8 +6021,10 @@ lookup_qualified_name (tree scope, tree name, int prefer_type, bool complain, /* Wrapper for the above that takes a string argument. The function name is not at the beginning of the line to keep this wrapper out of etags. */ -tree lookup_qualified_name (tree t, const char *p, int wt, bool c, bool fh) -{ return lookup_qualified_name (t, get_identifier (p), wt, c, fh); } +tree lookup_qualified_name (tree t, const char *p, LOOK_want w, bool c, bool fh) +{ + return lookup_qualified_name (t, get_identifier (p), w, c, fh); +} /* [namespace.qual] Accepts the NAME to lookup and its qualifying SCOPE. @@ -6418,23 +6412,20 @@ innermost_non_namespace_value (tree name) not ignored. WHERE controls which scopes are considered. It is a bit mask of - LOOKUP_where::BLOCK (look in block scope), LOOKUP_where::CLASS - (look in class scopes) & LOOKUP_where::NAMESPACE (look in namespace + LOOK_where::BLOCK (look in block scope), LOOK_where::CLASS + (look in class scopes) & LOOK_where::NAMESPACE (look in namespace scopes). It is an error for no bits to be set. These scopes are searched from innermost to outermost. - If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces. - If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces). - Otherwise we prefer non-TYPE_DECLs. - - If NONCLASS is nonzero, bindings in class scopes are ignored. If - BLOCK_P is false, bindings in block scopes are ignored. */ + WANT controls what kind of entity we'd happy with. + LOOK_want::NORMAL for normal lookup (implicit typedefs can be + hidden). LOOK_want::TYPE for only TYPE_DECLS, LOOK_want::NAMESPACE + for only NAMESPACE_DECLS. These two can be bit-ored to find + namespace or type. */ static tree -lookup_name_real_1 (tree name, LOOK_where where, int prefer_type, - int namespaces_only, int flags) +lookup_name_real_1 (tree name, LOOK_where where, LOOK_want want, int flags) { - cxx_binding *iter; tree val = NULL_TREE; gcc_checking_assert (unsigned (where) != 0); @@ -6471,31 +6462,28 @@ lookup_name_real_1 (tree name, LOOK_where where, int prefer_type, return NULL_TREE; } - flags |= lookup_flags (prefer_type, namespaces_only); - /* First, look in non-namespace scopes. */ if (current_class_type == NULL_TREE) /* Maybe avoid searching the binding stack at all. */ where = LOOK_where (unsigned (where) & ~unsigned (LOOK_where::CLASS)); - if (where & (LOOK_where::BLOCK | LOOK_where::CLASS)) - for (iter = outer_binding (name, NULL, where & LOOK_where::CLASS); - iter; - iter = outer_binding (name, iter, where & LOOK_where::CLASS)) + if (bool (where & (LOOK_where::BLOCK | LOOK_where::CLASS))) + for (cxx_binding *iter = nullptr; + (iter = outer_binding (name, iter, bool (where & LOOK_where::CLASS)));) { tree binding; /* Skip entities we don't want. */ - if (!(where & (LOCAL_BINDING_P (iter) - ? LOOK_where::BLOCK : LOOK_where::CLASS))) + if (!bool (where & (LOCAL_BINDING_P (iter) + ? LOOK_where::BLOCK : LOOK_where::CLASS))) continue; /* If this is the kind of thing we're looking for, we're done. */ - if (qualify_lookup (iter->value, flags)) + if (qualify_lookup (iter->value, want, flags)) binding = iter->value; - else if ((flags & LOOKUP_PREFER_TYPES) - && qualify_lookup (iter->type, flags)) + else if (bool (want & LOOK_want::TYPE) + && qualify_lookup (iter->type, want, flags)) binding = iter->type; else binding = NULL_TREE; @@ -6558,9 +6546,9 @@ lookup_name_real_1 (tree name, LOOK_where where, int prefer_type, } /* Now lookup in namespace scopes. */ - if (!val && (where & LOOK_where::NAMESPACE)) + if (!val && bool (where & LOOK_where::NAMESPACE)) { - name_lookup lookup (name, flags); + name_lookup lookup (name, want, flags & LOOKUP_HIDDEN); if (lookup.search_unqualified (current_decl_namespace (), current_binding_level)) val = lookup.value; @@ -6576,13 +6564,11 @@ lookup_name_real_1 (tree name, LOOK_where where, int prefer_type, /* Wrapper for lookup_name_real_1. */ tree -lookup_name_real (tree name, LOOK_where where, int prefer_type, - int namespaces_only, int flags) +lookup_name_real (tree name, LOOK_where where, LOOK_want want, int flags) { tree ret; bool subtime = timevar_cond_start (TV_NAME_LOOKUP); - ret = lookup_name_real_1 (name, where, prefer_type, - namespaces_only, flags); + ret = lookup_name_real_1 (name, where, want, flags); timevar_cond_stop (TV_NAME_LOOKUP, subtime); return ret; } @@ -6591,19 +6577,19 @@ tree lookup_name_nonclass (tree name) { return lookup_name_real (name, LOOK_where::BLOCK_NAMESPACE, - 0, 0, 0); + LOOK_want::NORMAL, 0); } tree lookup_name (tree name) { - return lookup_name_real (name, LOOK_where::ALL, 0, 0, 0); + return lookup_name_real (name, LOOK_where::ALL, LOOK_want::NORMAL, 0); } tree -lookup_name_prefer_type (tree name, int prefer_type) +lookup_name (tree name, LOOK_want want) { - return lookup_name_real (name, LOOK_where::ALL, prefer_type, 0, 0); + return lookup_name_real (name, LOOK_where::ALL, want, 0); } /* Look up NAME for type used in elaborated name specifier in @@ -6651,13 +6637,13 @@ lookup_type_scope_1 (tree name, tag_scope scope) typedef struct C {} C; correctly. */ if (tree type = iter->type) - if (qualify_lookup (type, LOOKUP_PREFER_TYPES) + if (qualify_lookup (type, LOOK_want::TYPE, false) && (scope != ts_current || LOCAL_BINDING_P (iter) || DECL_CONTEXT (type) == iter->scope->this_entity)) return type; - if (qualify_lookup (iter->value, LOOKUP_PREFER_TYPES) + if (qualify_lookup (iter->value, LOOK_want::TYPE, false) && (scope != ts_current || !INHERITED_VALUE_BINDING_P (iter))) return iter->value; @@ -6678,11 +6664,11 @@ lookup_type_scope_1 (tree name, tag_scope scope) { /* If this is the kind of thing we're looking for, we're done. */ if (tree type = MAYBE_STAT_TYPE (*slot)) - if (qualify_lookup (type, LOOKUP_PREFER_TYPES)) + if (qualify_lookup (type, LOOK_want::TYPE, false)) return type; if (tree decl = MAYBE_STAT_DECL (*slot)) - if (qualify_lookup (decl, LOOKUP_PREFER_TYPES)) + if (qualify_lookup (decl, LOOK_want::TYPE, false)) return decl; } @@ -7384,7 +7370,7 @@ push_namespace (tree name, bool make_inline) tree ns = NULL_TREE; { - name_lookup lookup (name, 0); + name_lookup lookup (name); if (!lookup.search_qualified (current_namespace, /*usings=*/false)) ; else if (TREE_CODE (lookup.value) == TREE_LIST) diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 4368c14d48ce..79b7a590915f 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -295,16 +295,29 @@ constexpr LOOK_where operator| (LOOK_where a, LOOK_where b) { return LOOK_where (unsigned (a) | unsigned (b)); } -constexpr bool operator& (LOOK_where a, LOOK_where b) +constexpr LOOK_where operator& (LOOK_where a, LOOK_where b) { - return 0 != (unsigned (a) & unsigned (b)); + return LOOK_where (unsigned (a) & unsigned (b)); } -extern tree lookup_name_prefer_type (tree, int); +enum class LOOK_want +{ + NORMAL = 0, /* Normal lookup -- non-types can hide implicit types. */ + TYPE = 1 << 1, /* We only want TYPE_DECLS. */ + NAMESPACE = 1 << 2, /* We only want NAMESPACE_DECLS. */ + TYPE_NAMESPACE = TYPE | NAMESPACE, /* Either NAMESPACE or TYPE. */ +}; +constexpr LOOK_want operator| (LOOK_want a, LOOK_want b) +{ + return LOOK_want (unsigned (a) | unsigned (b)); +} +constexpr LOOK_want operator& (LOOK_want a, LOOK_want b) +{ + return LOOK_want (unsigned (a) & unsigned (b)); +} -extern tree lookup_name_real (tree, LOOK_where, int prefer_type, - int namespaces_only, int flags); +extern tree lookup_name_real (tree, LOOK_where, LOOK_want, int flags); extern tree lookup_type_scope (tree, tag_scope); extern tree get_namespace_binding (tree ns, tree id); extern void set_global_binding (tree decl); @@ -312,8 +325,15 @@ inline tree get_global_binding (tree id) { return get_namespace_binding (NULL_TREE, id); } -extern tree lookup_qualified_name (tree, tree, int = 0, bool = true, /*hidden*/bool = false); -extern tree lookup_qualified_name (tree t, const char *p, int = 0, bool = true, bool = false); +/* Also declared in c-family/c-common.h. */ +extern tree lookup_name (tree name); +extern tree lookup_name (tree name, LOOK_want); +extern tree lookup_qualified_name (tree scope, tree name, + LOOK_want = LOOK_want::NORMAL, + bool = true, /*hidden*/bool = false); +extern tree lookup_qualified_name (tree scope, const char *name, + LOOK_want = LOOK_want::NORMAL, + bool = true, bool = false); extern tree lookup_name_nonclass (tree); extern bool is_local_extern (tree); extern bool pushdecl_class_level (tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 2c45a3d6f41b..2e12a5997278 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -4617,7 +4617,7 @@ cp_parser_userdef_numeric_literal (cp_parser *parser) if (i14 && ext) { tree cxlit = lookup_qualified_name (std_node, "complex_literals", - 0, false); + LOOK_want::NORMAL, false); if (cxlit == error_mark_node) { /* No , so pedwarn and use GNU semantics. */ @@ -28214,20 +28214,16 @@ cp_parser_nested_requirement (cp_parser *parser) /* Support Functions */ /* Return the appropriate prefer_type argument for lookup_name_real based on - tag_type and template_mem_access. */ + tag_type. */ -static inline int -prefer_type_arg (tag_types tag_type, bool template_mem_access = false) +static inline LOOK_want +prefer_type_arg (tag_types tag_type) { - /* DR 141: When looking in the current enclosing context for a template-name - after -> or ., only consider class templates. */ - if (template_mem_access) - return 2; switch (tag_type) { - case none_type: return 0; // No preference. - case scope_type: return 1; // Type or namespace. - default: return 2; // Type only. + case none_type: return LOOK_want::NORMAL; // No preference. + case scope_type: return LOOK_want::TYPE_NAMESPACE; // Type or namespace. + default: return LOOK_want::TYPE; // Type only. } } @@ -28451,7 +28447,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, decl = lookup_member (object_type, name, /*protect=*/0, - prefer_type_arg (tag_type), + /*prefer_type=*/tag_type != none_type, tf_warning_or_error); else decl = NULL_TREE; @@ -28460,16 +28456,22 @@ cp_parser_lookup_name (cp_parser *parser, tree name, /* Look it up in the enclosing context. DR 141: When looking for a template-name after -> or ., only consider class templates. */ decl = lookup_name_real (name, LOOK_where::ALL, - prefer_type_arg (tag_type, is_template), - is_namespace, 0); + is_namespace ? LOOK_want::NAMESPACE + /* DR 141: When looking in the + current enclosing context for a + template-name after -> or ., only + consider class templates. */ + : is_template ? LOOK_want::TYPE + : prefer_type_arg (tag_type), 0); parser->object_scope = object_type; parser->qualifying_scope = NULL_TREE; } else { decl = lookup_name_real (name, LOOK_where::ALL, - prefer_type_arg (tag_type), - is_namespace, 0); + is_namespace ? LOOK_want::NAMESPACE + : prefer_type_arg (tag_type), + 0); parser->qualifying_scope = NULL_TREE; parser->object_scope = NULL_TREE; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5fd16bf781cd..fe7f71dc05b7 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2995,12 +2995,12 @@ check_explicit_specialization (tree declarator, /* Find the namespace binding, using the declaration context. */ fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname, - false, true); + LOOK_want::NORMAL, true); if (fns == error_mark_node) /* If lookup fails, look for a friend declaration so we can give a better diagnostic. */ fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname, - /*type*/false, /*complain*/true, + LOOK_want::NORMAL, /*complain*/true, /*hidden*/true); if (fns == error_mark_node || !is_overloaded_fn (fns)) @@ -11184,8 +11184,7 @@ tsubst_friend_class (tree friend_tmpl, tree args) } tmpl = lookup_name_real (DECL_NAME (friend_tmpl), LOOK_where::CLASS_NAMESPACE, - /*prefer_type=*/0, /*namespaces_only=*/false, - LOOKUP_HIDDEN); + LOOK_want::NORMAL, LOOKUP_HIDDEN); if (tmpl && DECL_CLASS_TEMPLATE_P (tmpl)) { @@ -16186,10 +16185,10 @@ tsubst_qualified_id (tree qualified_id, tree args, } else expr = lookup_qualified_name (scope, complete_dtor_identifier, - /*is_type_p=*/0, false); + LOOK_want::NORMAL, false); } else - expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false); + expr = lookup_qualified_name (scope, expr, LOOK_want::NORMAL, false); if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL) { @@ -17835,7 +17834,8 @@ lookup_init_capture_pack (tree decl) for (int i = 0; i < len; ++i) { tree ename = vec ? make_ith_pack_parameter_name (cname, i) : cname; - tree elt = lookup_name_real (ename, LOOK_where::ALL, 0, 0, LOOKUP_NORMAL); + tree elt = lookup_name_real (ename, LOOK_where::ALL, LOOK_want::NORMAL, + LOOKUP_NORMAL); if (vec) TREE_VEC_ELT (vec, i) = elt; else @@ -17942,7 +17942,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, { inst = lookup_name_real (DECL_NAME (decl), LOOK_where::BLOCK_NAMESPACE, - /*prefer_type*/0, /*ns_only*/0, + LOOK_want::NORMAL, LOOKUP_HIDDEN); gcc_assert (inst != decl && is_capture_proxy (inst)); } @@ -20223,8 +20223,7 @@ tsubst_copy_and_build (tree t, tree scope = TREE_OPERAND (member, 0); tree tmpl = TREE_OPERAND (TREE_OPERAND (member, 1), 0); tree args = TREE_OPERAND (TREE_OPERAND (member, 1), 1); - member = lookup_qualified_name (scope, tmpl, - /*is_type_p=*/false, + member = lookup_qualified_name (scope, tmpl, LOOK_want::NORMAL, /*complain=*/false); if (BASELINK_P (member)) { @@ -28727,7 +28726,7 @@ deduction_guides_for (tree tmpl, tsubst_flags_t complain) { guides = lookup_qualified_name (CP_DECL_CONTEXT (tmpl), dguide_name (tmpl), - /*type*/false, /*complain*/false, + LOOK_want::NORMAL, /*complain*/false, /*hidden*/false); if (guides == error_mark_node) guides = NULL_TREE; diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index d43248cba7cd..432ebab26393 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -1564,7 +1564,7 @@ emit_support_tinfos (void) /* Look for a defined class. */ tree bltn_type = lookup_qualified_name - (abi_node, "__fundamental_type_info", true, false); + (abi_node, "__fundamental_type_info", LOOK_want::TYPE, false); if (TREE_CODE (bltn_type) != TYPE_DECL) return; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index e979a8b716c6..a7b8eb84b7e2 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5522,7 +5522,7 @@ omp_reduction_lookup (location_t loc, tree id, tree type, tree *baselinkp, omp_reduction_id (ERROR_MARK, TREE_OPERAND (id, 1), type), - false, false); + LOOK_want::NORMAL, false); tree fns = id; id = NULL_TREE; if (fns && is_overloaded_fn (fns)) @@ -10323,7 +10323,7 @@ capture_decltype (tree decl) { tree lam = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (current_function_decl)); tree cap = lookup_name_real (DECL_NAME (decl), LOOK_where::BLOCK_NAMESPACE, - /*type*/0, /*ns*/false, LOOKUP_HIDDEN); + LOOK_want::NORMAL, LOOKUP_HIDDEN); tree type; if (cap && is_capture_proxy (cap)) diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc index 24582c74a86d..ddff74522263 100644 --- a/libcc1/libcp1plugin.cc +++ b/libcc1/libcp1plugin.cc @@ -2652,10 +2652,11 @@ plugin_build_dependent_expr (cc1_plugin::connection *self, } tree res = identifier; if (!scope) - res = lookup_name_real (res, LOOK_where::BLOCK_NAMESPACE, 0, 0, 0); + res = lookup_name_real (res, LOOK_where::BLOCK_NAMESPACE, + LOOK_want::NORMAL, 0); else if (!TYPE_P (scope) || !dependent_scope_p (scope)) { - res = lookup_qualified_name (scope, res, false, true); + res = lookup_qualified_name (scope, res, LOOK_want::NORMAL, true); /* We've already resolved the name in the scope, so skip the build_qualified_name call below. */ scope = NULL; -- 2.39.2