From db1c2a89db09c8fe140ed3e65a707a08737e3b41 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Fri, 14 Aug 2020 09:55:33 -0700 Subject: [PATCH] c++: Yet more name-lookup api simplification This patch deals with LOOKUP_HIDDEN, which originally meant 'find hidden friends', but it's being pressed into service for not ignoring lambda-relevant internals. However these two functions are different. (a) hidden friends can occur in block scope (very uncommon) and (b) it had the semantics of stopping after the innermost enclosing namepspace. That's really suspect for the lambda case, but not relevant there because we never get to namespace scope (I think). Anyway, I've split the flag into two and adjusted the lambda callers to just search block scope. These two flags are added to the LOOK_want enum class, which allows dropping another parameter from the name lookup routines. The remaining LOOKUP_$FOO flags in cp-tree.h are, I think, now all related to features of overload resolution, conversion operators and reference binding. Nothing to do with /name/ lookup. gcc/cp/ * cp-tree.h (LOOKUP_HIDDEN): Delete. (LOOKUP_PREFER_RVALUE): Adjust initializer. * name-lookup.h (enum class LOOK_want): Add HIDDEN_FRIEND and HIDDEN_LAMBDA flags. (lookup_name_real): Drop flags parm. (lookup_qualified_name): Drop find_hidden parm. * name-lookup.c (class name_lookup): Drop hidden field, adjust ctors. (name_lookup::add_overload): Check want for hiddenness. (name_lookup::process_binding): Likewise. (name_lookup::search_unqualified): Likewise. (identifier_type_value_1): Adjust lookup_name_real call. (set_decl_namespace): Adjust name_lookup ctor. (qualify_lookup): Drop flags parm, use want for hiddenness. (lookup_qualified_name): Drop find_hidden parm. (lookup_name_real_1): Drop flags parm, adjust qualify_lookup calls. (lookup_name_real): Drop flags parm. (lookup_name_nonclass, lookup_name): Adjust lookup_name_real calls. (lookup_type_scope_1): Adjust qualify_lookup calls. * call.c (build_operator_new_call): Adjust lookup_name_real call. (add_operator_candidates): Likewise. * coroutines.cc (morph_fn_to_coro): Adjust lookup_qualified_name call. * parser.c (cp_parser_lookup_name): Adjust lookup_name_real calls. * pt.c (check_explicit_specialization): Adjust lookup_qualified_name call. (deduction_guides_for): Likewise. (tsubst_friend_class): Adjust lookup_name_real call. (lookup_init_capture_pack): Likewise. (tsubst_expr): Likewise, don't look in namespaces. * semantics.c (capture_decltype): Adjust lookup_name_real. Don't look in namespaces. libcc1/ * libcp1plugin.cc (plugin_build_dependent_exp): Adjust lookup_name_real call. --- gcc/cp/call.c | 4 +-- gcc/cp/coroutines.cc | 2 +- gcc/cp/cp-tree.h | 6 +---- gcc/cp/name-lookup.c | 61 ++++++++++++++++++++---------------------- gcc/cp/name-lookup.h | 9 ++++--- gcc/cp/parser.c | 5 ++-- gcc/cp/pt.c | 22 +++++++-------- gcc/cp/semantics.c | 4 +-- libcc1/libcp1plugin.cc | 2 +- 9 files changed, 54 insertions(+), 61 deletions(-) diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 94aaf65b3f4..8c03fcaf74b 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, LOOK_want::NORMAL, 0); + fns = lookup_name_real (fnname, LOOK_where::NAMESPACE, LOOK_want::NORMAL); 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, - LOOK_want::NORMAL, 0); + LOOK_want::NORMAL); 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 22ba81c8025..898b88b7075 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -4311,7 +4311,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) tree std_nt = lookup_qualified_name (std_node, get_identifier ("nothrow"), LOOK_want::NORMAL, - /*complain=*/true, false); + /*complain=*/true); 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-tree.h b/gcc/cp/cp-tree.h index 59ab2309d18..04758574019 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5567,14 +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) -/* 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 (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. */ -#define LOOKUP_PREFER_RVALUE (LOOKUP_HIDDEN << 1) +#define LOOKUP_PREFER_RVALUE (LOOKUP_NO_TEMP_BIND << 1) /* We're inside an init-list, so narrowing conversions are ill-formed. */ #define LOOKUP_NO_NARROWING (LOOKUP_PREFER_RVALUE << 1) /* We're looking up a constructor for list-initialization. */ diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 51de6fb4c36..4753dc529e6 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -165,7 +165,6 @@ public: tree value; /* A (possibly ambiguous) set of things found. */ tree type; /* A type that has been found. */ 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. */ @@ -179,9 +178,9 @@ protected: static name_lookup *active; public: - name_lookup (tree n, LOOK_want w = LOOK_want::NORMAL, bool h = false) + name_lookup (tree n, LOOK_want w = LOOK_want::NORMAL) : name (n), value (NULL_TREE), type (NULL_TREE), - want (w), hidden (h), + want (w), deduping (false), scopes (NULL), previous (NULL) { preserve_state (); @@ -420,7 +419,7 @@ name_lookup::add_overload (tree fns) if (!deduping && TREE_CODE (fns) == OVERLOAD) { tree probe = fns; - if (!hidden) + if (!bool (want & LOOK_want::HIDDEN_FRIEND)) probe = ovl_skip_hidden (probe); if (probe && TREE_CODE (probe) == OVERLOAD && OVL_DEDUP_P (probe)) @@ -489,12 +488,12 @@ name_lookup::process_binding (tree new_val, tree new_type) /* Did we really see a type? */ if (new_type && ((want & LOOK_want::TYPE_NAMESPACE) == LOOK_want::NAMESPACE - || (!hidden + || (!bool (want & LOOK_want::HIDDEN_FRIEND) && DECL_LANG_SPECIFIC (new_type) && DECL_ANTICIPATED (new_type)))) new_type = NULL_TREE; - if (new_val && !hidden) + if (new_val && !bool (want & LOOK_want::HIDDEN_FRIEND)) new_val = ovl_skip_hidden (new_val); /* Do we really see a value? */ @@ -718,13 +717,13 @@ name_lookup::search_unqualified (tree scope, cp_binding_level *level) if (scope == global_namespace) break; - /* If looking for hidden names, we only look in the innermost + /* If looking for hidden friends, we only look in the innermost namespace scope. [namespace.memdef]/3 If a friend declaration in a non-local class first declares a class, function, class template or function template the friend is a member of the innermost enclosing namespace. See also [basic.lookup.unqual]/7 */ - if (hidden) + if (bool (want & LOOK_want::HIDDEN_FRIEND)) break; } @@ -3744,7 +3743,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, LOOK_want::TYPE, 0); + id = lookup_name_real (id, LOOK_where::BLOCK_NAMESPACE, LOOK_want::TYPE); if (id) return TREE_TYPE (id); return NULL_TREE; @@ -4818,7 +4817,8 @@ set_decl_namespace (tree decl, tree scope, bool friendp) children. */ tree old = NULL_TREE; { - name_lookup lookup (DECL_NAME (decl), LOOK_want::NORMAL, true); + name_lookup lookup (DECL_NAME (decl), + LOOK_want::NORMAL | LOOK_want::HIDDEN_FRIEND); if (!lookup.search_qualified (scope, /*usings=*/false)) /* No old declaration at all. */ goto not_found; @@ -5217,7 +5217,7 @@ cp_namespace_decls (tree ns) lookup_type_scope. */ static bool -qualify_lookup (tree val, LOOK_want want, int flags) +qualify_lookup (tree val, LOOK_want want) { if (val == NULL_TREE) return false; @@ -5238,7 +5238,7 @@ qualify_lookup (tree val, LOOK_want want, int flags) return false; /* Look through lambda things that we shouldn't be able to see. */ - if (!(flags & LOOKUP_HIDDEN) && is_lambda_ignored_entity (val)) + if (!bool (want & LOOK_want::HIDDEN_LAMBDA) && is_lambda_ignored_entity (val)) return false; return true; @@ -5995,14 +5995,13 @@ 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, LOOK_want want, bool complain, - bool find_hidden /*=false*/) +lookup_qualified_name (tree scope, tree name, LOOK_want want, bool complain) { tree t = NULL_TREE; if (TREE_CODE (scope) == NAMESPACE_DECL) { - name_lookup lookup (name, want, find_hidden); + name_lookup lookup (name, want); if (qualified_namespace_lookup (scope, &lookup)) t = lookup.value; @@ -6021,9 +6020,9 @@ lookup_qualified_name (tree scope, tree name, LOOK_want want, 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, LOOK_want w, bool c, bool fh) +tree lookup_qualified_name (tree t, const char *p, LOOK_want w, bool c) { - return lookup_qualified_name (t, get_identifier (p), w, c, fh); + return lookup_qualified_name (t, get_identifier (p), w, c); } /* [namespace.qual] @@ -6424,7 +6423,7 @@ innermost_non_namespace_value (tree name) namespace or type. */ static tree -lookup_name_real_1 (tree name, LOOK_where where, LOOK_want want, int flags) +lookup_name_real_1 (tree name, LOOK_where where, LOOK_want want) { tree val = NULL_TREE; @@ -6480,10 +6479,10 @@ lookup_name_real_1 (tree name, LOOK_where where, LOOK_want want, int flags) continue; /* If this is the kind of thing we're looking for, we're done. */ - if (qualify_lookup (iter->value, want, flags)) + if (qualify_lookup (iter->value, want)) binding = iter->value; else if (bool (want & LOOK_want::TYPE) - && qualify_lookup (iter->type, want, flags)) + && qualify_lookup (iter->type, want)) binding = iter->type; else binding = NULL_TREE; @@ -6548,7 +6547,7 @@ lookup_name_real_1 (tree name, LOOK_where where, LOOK_want want, int flags) /* Now lookup in namespace scopes. */ if (!val && bool (where & LOOK_where::NAMESPACE)) { - name_lookup lookup (name, want, flags & LOOKUP_HIDDEN); + name_lookup lookup (name, want); if (lookup.search_unqualified (current_decl_namespace (), current_binding_level)) val = lookup.value; @@ -6564,11 +6563,10 @@ lookup_name_real_1 (tree name, LOOK_where where, LOOK_want want, int flags) /* Wrapper for lookup_name_real_1. */ tree -lookup_name_real (tree name, LOOK_where where, LOOK_want want, int flags) +lookup_name_real (tree name, LOOK_where where, LOOK_want want) { - tree ret; bool subtime = timevar_cond_start (TV_NAME_LOOKUP); - ret = lookup_name_real_1 (name, where, want, flags); + tree ret = lookup_name_real_1 (name, where, want); timevar_cond_stop (TV_NAME_LOOKUP, subtime); return ret; } @@ -6576,20 +6574,19 @@ lookup_name_real (tree name, LOOK_where where, LOOK_want want, int flags) tree lookup_name_nonclass (tree name) { - return lookup_name_real (name, LOOK_where::BLOCK_NAMESPACE, - LOOK_want::NORMAL, 0); + return lookup_name_real (name, LOOK_where::BLOCK_NAMESPACE, LOOK_want::NORMAL); } tree lookup_name (tree name) { - return lookup_name_real (name, LOOK_where::ALL, LOOK_want::NORMAL, 0); + return lookup_name_real (name, LOOK_where::ALL, LOOK_want::NORMAL); } tree lookup_name (tree name, LOOK_want want) { - return lookup_name_real (name, LOOK_where::ALL, want, 0); + return lookup_name_real (name, LOOK_where::ALL, want); } /* Look up NAME for type used in elaborated name specifier in @@ -6637,13 +6634,13 @@ lookup_type_scope_1 (tree name, tag_scope scope) typedef struct C {} C; correctly. */ if (tree type = iter->type) - if (qualify_lookup (type, LOOK_want::TYPE, false) + if (qualify_lookup (type, LOOK_want::TYPE) && (scope != ts_current || LOCAL_BINDING_P (iter) || DECL_CONTEXT (type) == iter->scope->this_entity)) return type; - if (qualify_lookup (iter->value, LOOK_want::TYPE, false) + if (qualify_lookup (iter->value, LOOK_want::TYPE) && (scope != ts_current || !INHERITED_VALUE_BINDING_P (iter))) return iter->value; @@ -6664,11 +6661,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, LOOK_want::TYPE, false)) + if (qualify_lookup (type, LOOK_want::TYPE)) return type; if (tree decl = MAYBE_STAT_DECL (*slot)) - if (qualify_lookup (decl, LOOK_want::TYPE, false)) + if (qualify_lookup (decl, LOOK_want::TYPE)) return decl; } diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 79b7a590915..e43a04c1d6e 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -306,6 +306,9 @@ enum class LOOK_want TYPE = 1 << 1, /* We only want TYPE_DECLS. */ NAMESPACE = 1 << 2, /* We only want NAMESPACE_DECLS. */ + HIDDEN_FRIEND = 1 << 3, /* See hidden friends. */ + HIDDEN_LAMBDA = 1 << 4, /* See lambda-ignored entities. */ + TYPE_NAMESPACE = TYPE | NAMESPACE, /* Either NAMESPACE or TYPE. */ }; constexpr LOOK_want operator| (LOOK_want a, LOOK_want b) @@ -317,7 +320,7 @@ 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, LOOK_want, int flags); +extern tree lookup_name_real (tree, LOOK_where, LOOK_want); extern tree lookup_type_scope (tree, tag_scope); extern tree get_namespace_binding (tree ns, tree id); extern void set_global_binding (tree decl); @@ -330,10 +333,10 @@ 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); + bool = true); extern tree lookup_qualified_name (tree scope, const char *name, LOOK_want = LOOK_want::NORMAL, - bool = true, bool = false); + bool = true); 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 2e12a599727..641cedbe3f8 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -28462,7 +28462,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, template-name after -> or ., only consider class templates. */ : is_template ? LOOK_want::TYPE - : prefer_type_arg (tag_type), 0); + : prefer_type_arg (tag_type)); parser->object_scope = object_type; parser->qualifying_scope = NULL_TREE; } @@ -28470,8 +28470,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, { decl = lookup_name_real (name, LOOK_where::ALL, is_namespace ? LOOK_want::NAMESPACE - : prefer_type_arg (tag_type), - 0); + : prefer_type_arg (tag_type)); parser->qualifying_scope = NULL_TREE; parser->object_scope = NULL_TREE; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index fe7f71dc05b..74c745a2c5d 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2999,9 +2999,10 @@ check_explicit_specialization (tree declarator, 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, - LOOK_want::NORMAL, /*complain*/true, - /*hidden*/true); + fns = (lookup_qualified_name + (CP_DECL_CONTEXT (decl), dname, + LOOK_want::NORMAL | LOOK_want::HIDDEN_FRIEND, + /*complain*/true)); if (fns == error_mark_node || !is_overloaded_fn (fns)) { @@ -11184,7 +11185,7 @@ tsubst_friend_class (tree friend_tmpl, tree args) } tmpl = lookup_name_real (DECL_NAME (friend_tmpl), LOOK_where::CLASS_NAMESPACE, - LOOK_want::NORMAL, LOOKUP_HIDDEN); + LOOK_want::NORMAL | LOOK_want::HIDDEN_FRIEND); if (tmpl && DECL_CLASS_TEMPLATE_P (tmpl)) { @@ -17834,8 +17835,7 @@ 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, LOOK_want::NORMAL, - LOOKUP_NORMAL); + tree elt = lookup_name_real (ename, LOOK_where::ALL, LOOK_want::NORMAL); if (vec) TREE_VEC_ELT (vec, i) = elt; else @@ -17940,10 +17940,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, tree inst; if (!DECL_PACK_P (decl)) { - inst = lookup_name_real (DECL_NAME (decl), - LOOK_where::BLOCK_NAMESPACE, - LOOK_want::NORMAL, - LOOKUP_HIDDEN); + inst = (lookup_name_real + (DECL_NAME (decl), LOOK_where::BLOCK, + LOOK_want::NORMAL | LOOK_want::HIDDEN_LAMBDA)); gcc_assert (inst != decl && is_capture_proxy (inst)); } else if (is_normal_capture_proxy (decl)) @@ -28726,8 +28725,7 @@ deduction_guides_for (tree tmpl, tsubst_flags_t complain) { guides = lookup_qualified_name (CP_DECL_CONTEXT (tmpl), dguide_name (tmpl), - LOOK_want::NORMAL, /*complain*/false, - /*hidden*/false); + LOOK_want::NORMAL, /*complain*/false); if (guides == error_mark_node) guides = NULL_TREE; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index a7b8eb84b7e..da452c58daa 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -10322,8 +10322,8 @@ static tree 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, - LOOK_want::NORMAL, LOOKUP_HIDDEN); + tree cap = lookup_name_real (DECL_NAME (decl), LOOK_where::BLOCK, + LOOK_want::NORMAL | LOOK_want::HIDDEN_LAMBDA); tree type; if (cap && is_capture_proxy (cap)) diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc index ddff7452226..e30cb8c024b 100644 --- a/libcc1/libcp1plugin.cc +++ b/libcc1/libcp1plugin.cc @@ -2653,7 +2653,7 @@ plugin_build_dependent_expr (cc1_plugin::connection *self, tree res = identifier; if (!scope) res = lookup_name_real (res, LOOK_where::BLOCK_NAMESPACE, - LOOK_want::NORMAL, 0); + LOOK_want::NORMAL); else if (!TYPE_P (scope) || !dependent_scope_p (scope)) { res = lookup_qualified_name (scope, res, LOOK_want::NORMAL, true); -- 2.30.2