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)
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,
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;
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.
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
/* 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. */
}
/* Now lookup in namespace scopes. */
- if (!val)
+ if (!val && (where & LOOK_where::NAMESPACE))
{
name_lookup lookup (name, flags);
if (lookup.search_unqualified
/* 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;
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
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);
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;
}
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))
{
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
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))
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))
}
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);