mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-04 17:24:15 +08:00
[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.
This commit is contained in:
parent
55484a0f81
commit
0c5f6bbfe2
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
15
gcc/cp/pt.c
15
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))
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user