aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-08-13 10:59:00 -0700
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-17 15:08:10 -0300
commitc491a6e17b94f42c9b5ef3b3840a0d7c2ffb7102 (patch)
treed8d2c4228b60e2bebdb111dbb1fb776f1c4e90d6
parent27aeb71c04eaa1a2125777d230057fbd0508af15 (diff)
downloadgcc-c491a6e17b94f42c9b5ef3b3840a0d7c2ffb7102.zip
gcc-c491a6e17b94f42c9b5ef3b3840a0d7c2ffb7102.tar.gz
gcc-c491a6e17b94f42c9b5ef3b3840a0d7c2ffb7102.tar.bz2
[c++]: Unconfuse lookup_name_real API a bit
The API for lookup_name_real is really confusing. This addresses the part where we have NONCLASS to say DON'T search class scopes, and BLOCK_P to say DO search block scopes. I've added a single bitmask to explicitly say which scopes to search. I used an enum class so one can't accidentally misorder it. It's also reordered so we don't mix it up with the parameters that say what kind of thing we're looking for. gcc/cp/ * name-lookup.h (enum class LOOK_where): New. (operator|, operator&): Overloads for it. (lookup_name_real): Replace NONCLASS & BLOCK_P parms with WHERE. * name-lookup.c (identifier_type_value_w): Adjust lookup_name_real call. (lookup_name_real_1): Replace NONCLASS and BLOCK_P parameters with WHERE bitmask. Don't search namespaces if not asked to. (lookup_name_real): Adjust lookup_name_real_1 call. (lookup_name_nonclass, lookup_name) (lookup_name_prefer_type): Likewise. * call.c (build_operator_new_call) (add_operator_candidates): Adjust lookup_name_real calls. * parser.c (cp_parser_lookup_name): Likewise. * pt.c (tsubst_friend_class, lookup_init_capture_pack) (tsubst_expr): Likewise. * semantics.c (capture_decltype): Likewise. libcc1/ * libcp1plugin.cc (plugin_build_dependent_expr): Likewise.
-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 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))
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index 01aecf0..24582c7 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);