diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/call.c | 5 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 39 | ||||
-rw-r--r-- | gcc/cp/name-lookup.h | 27 | ||||
-rw-r--r-- | gcc/cp/parser.c | 12 | ||||
-rw-r--r-- | gcc/cp/pt.c | 15 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 4 |
6 files changed, 70 insertions, 32 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f164b21..47a368d 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4704,7 +4704,7 @@ build_operator_new_call (tree fnname, vec<tree, va_gc> **args, up in the global scope. we disregard block-scope declarations of "operator new". */ - fns = lookup_name_real (fnname, 0, 1, /*block_p=*/false, 0, 0); + fns = lookup_name_real (fnname, LOOK_where::NAMESPACE, 0, 0, 0); fns = lookup_arg_dependent (fnname, fns, *args); if (align_arg) @@ -5982,7 +5982,8 @@ add_operator_candidates (z_candidate **candidates, consider. */ if (!memonly) { - tree fns = lookup_name_real (fnname, 0, 1, /*block_p=*/true, 0, 0); + tree fns = lookup_name_real (fnname, LOOK_where::BLOCK_NAMESPACE, + 0, 0, 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/name-lookup.c b/gcc/cp/name-lookup.c index 9f30d90..4fdac94 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3741,7 +3741,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, 2, 1, /*block_p=*/true, 0, 0); + id = lookup_name_real (id, LOOK_where::BLOCK_NAMESPACE, 2, 0, 0); if (id) return TREE_TYPE (id); return NULL_TREE; @@ -6413,10 +6413,16 @@ innermost_non_namespace_value (tree name) namespace of variables, functions and typedefs. Return a ..._DECL node of some kind representing its definition if there is only one such declaration, or return a TREE_LIST with all the overloaded - definitions if there are many, or return 0 if it is undefined. + definitions if there are many, or return NULL_TREE if it is undefined. Hidden name, either friend declaration or built-in function, are 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 + 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. @@ -6425,12 +6431,14 @@ innermost_non_namespace_value (tree name) BLOCK_P is false, bindings in block scopes are ignored. */ static tree -lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p, +lookup_name_real_1 (tree name, LOOK_where where, int prefer_type, int namespaces_only, int flags) { cxx_binding *iter; tree val = NULL_TREE; + gcc_checking_assert (unsigned (where) != 0); + query_oracle (name); /* Conversion operators are handled specially because ordinary @@ -6468,17 +6476,19 @@ lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p, /* First, look in non-namespace scopes. */ if (current_class_type == NULL_TREE) - nonclass = 1; + /* Maybe avoid searching the binding stack at all. */ + where = LOOK_where (unsigned (where) & ~unsigned (LOOK_where::CLASS)); - if (block_p || !nonclass) - for (iter = outer_binding (name, NULL, !nonclass); + if (where & (LOOK_where::BLOCK | LOOK_where::CLASS)) + for (iter = outer_binding (name, NULL, where & LOOK_where::CLASS); iter; - iter = outer_binding (name, iter, !nonclass)) + iter = outer_binding (name, iter, where & LOOK_where::CLASS)) { tree binding; /* Skip entities we don't want. */ - if (LOCAL_BINDING_P (iter) ? !block_p : nonclass) + if (!(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. */ @@ -6548,7 +6558,7 @@ lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p, } /* Now lookup in namespace scopes. */ - if (!val) + if (!val && (where & LOOK_where::NAMESPACE)) { name_lookup lookup (name, flags); if (lookup.search_unqualified @@ -6566,12 +6576,12 @@ lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p, /* Wrapper for lookup_name_real_1. */ tree -lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, +lookup_name_real (tree name, LOOK_where where, int prefer_type, int namespaces_only, int flags) { tree ret; bool subtime = timevar_cond_start (TV_NAME_LOOKUP); - ret = lookup_name_real_1 (name, prefer_type, nonclass, block_p, + ret = lookup_name_real_1 (name, where, prefer_type, namespaces_only, flags); timevar_cond_stop (TV_NAME_LOOKUP, subtime); return ret; @@ -6580,19 +6590,20 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, tree lookup_name_nonclass (tree name) { - return lookup_name_real (name, 0, 1, /*block_p=*/true, 0, 0); + return lookup_name_real (name, LOOK_where::BLOCK_NAMESPACE, + 0, 0, 0); } tree lookup_name (tree name) { - return lookup_name_real (name, 0, 0, /*block_p=*/true, 0, 0); + return lookup_name_real (name, LOOK_where::ALL, 0, 0, 0); } tree lookup_name_prefer_type (tree name, int prefer_type) { - return lookup_name_real (name, prefer_type, 0, /*block_p=*/true, 0, 0); + return lookup_name_real (name, LOOK_where::ALL, prefer_type, 0, 0); } /* Look up NAME for type used in elaborated name specifier in diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 9a18593..4368c14 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -278,8 +278,33 @@ extern void push_binding_level (cp_binding_level *); extern bool handle_namespace_attrs (tree, tree); extern void pushlevel_class (void); extern void poplevel_class (void); + +/* What kind of scopes name lookup looks in. An enum class so we + don't accidentally mix integers. */ +enum class LOOK_where +{ + BLOCK = 1 << 0, /* Consider block scopes. */ + CLASS = 1 << 1, /* Consider class scopes. */ + NAMESPACE = 1 << 2, /* Consider namespace scopes. */ + + ALL = BLOCK | CLASS | NAMESPACE, + BLOCK_NAMESPACE = BLOCK | NAMESPACE, + CLASS_NAMESPACE = CLASS | NAMESPACE, +}; +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) +{ + return 0 != (unsigned (a) & unsigned (b)); +} + extern tree lookup_name_prefer_type (tree, int); -extern tree lookup_name_real (tree, int, int, bool, int, int); + + +extern tree lookup_name_real (tree, LOOK_where, int prefer_type, + int namespaces_only, 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); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 981c625..2c45a3d 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -28459,17 +28459,17 @@ cp_parser_lookup_name (cp_parser *parser, tree name, if (!decl) /* 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, prefer_type_arg (tag_type, is_template), - /*nonclass=*/0, - /*block_p=*/true, is_namespace, 0); + decl = lookup_name_real (name, LOOK_where::ALL, + prefer_type_arg (tag_type, is_template), + is_namespace, 0); parser->object_scope = object_type; parser->qualifying_scope = NULL_TREE; } else { - decl = lookup_name_real (name, prefer_type_arg (tag_type), - /*nonclass=*/0, - /*block_p=*/true, is_namespace, 0); + decl = lookup_name_real (name, LOOK_where::ALL, + prefer_type_arg (tag_type), + is_namespace, 0); parser->qualifying_scope = NULL_TREE; parser->object_scope = NULL_TREE; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index cb81d8e..5fd16bf 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11183,9 +11183,9 @@ tsubst_friend_class (tree friend_tmpl, tree args) push_nested_class (context); } - tmpl = lookup_name_real (DECL_NAME (friend_tmpl), /*prefer_type=*/false, - /*non_class=*/false, /*block_p=*/false, - /*namespaces_only=*/false, LOOKUP_HIDDEN); + tmpl = lookup_name_real (DECL_NAME (friend_tmpl), LOOK_where::CLASS_NAMESPACE, + /*prefer_type=*/0, /*namespaces_only=*/false, + LOOKUP_HIDDEN); if (tmpl && DECL_CLASS_TEMPLATE_P (tmpl)) { @@ -17835,7 +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, 0, 0, true, 0, LOOKUP_NORMAL); + tree elt = lookup_name_real (ename, LOOK_where::ALL, 0, 0, LOOKUP_NORMAL); if (vec) TREE_VEC_ELT (vec, i) = elt; else @@ -17940,9 +17940,10 @@ 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), /*prefer_type*/0, - /*nonclass*/1, /*block_p=*/true, - /*ns_only*/0, LOOKUP_HIDDEN); + inst = lookup_name_real (DECL_NAME (decl), + LOOK_where::BLOCK_NAMESPACE, + /*prefer_type*/0, /*ns_only*/0, + LOOKUP_HIDDEN); gcc_assert (inst != decl && is_capture_proxy (inst)); } else if (is_normal_capture_proxy (decl)) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 3096fe8..e979a8b 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), /*type*/0, /*nonclass*/1, - /*block_p=*/true, /*ns*/0, LOOKUP_HIDDEN); + tree cap = lookup_name_real (DECL_NAME (decl), LOOK_where::BLOCK_NAMESPACE, + /*type*/0, /*ns*/false, LOOKUP_HIDDEN); tree type; if (cap && is_capture_proxy (cap)) |