aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/call.c5
-rw-r--r--gcc/cp/name-lookup.c39
-rw-r--r--gcc/cp/name-lookup.h27
-rw-r--r--gcc/cp/parser.c12
-rw-r--r--gcc/cp/pt.c15
-rw-r--r--gcc/cp/semantics.c4
-rw-r--r--libcc1/libcp1plugin.cc2
7 files changed, 71 insertions, 33 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index f164b211c9f..47a368d069d 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 9f30d907a09..4fdac9421d1 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 9a185936853..4368c14d48c 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 981c625a3cd..2c45a3d6f41 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 cb81d8e9229..5fd16bf781c 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 3096fe83433..e979a8b716c 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))
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index 01aecf00735..24582c74a86 100644
--- a/libcc1/libcp1plugin.cc
+++ b/libcc1/libcp1plugin.cc
@@ -2652,7 +2652,7 @@ plugin_build_dependent_expr (cc1_plugin::connection *self,
}
tree res = identifier;
if (!scope)
- res = lookup_name_real (res, 0, 0, true, 0, 0);
+ res = lookup_name_real (res, LOOK_where::BLOCK_NAMESPACE, 0, 0, 0);
else if (!TYPE_P (scope) || !dependent_scope_p (scope))
{
res = lookup_qualified_name (scope, res, false, true);