/* Definitions for C++ name lookup routines.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
/* Initialize anonymous_namespace_name if necessary, and return it. */
-tree
+static tree
get_anonymous_namespace_name (void)
{
if (!anonymous_namespace_name)
{
/* The anonymous namespace has to have a unique name
if typeinfo objects are being compared by name. */
- anonymous_namespace_name = get_file_function_name ("N");
+ if (! flag_weak || ! SUPPORTS_ONE_ONLY)
+ anonymous_namespace_name = get_file_function_name ("N");
+ else
+ /* The demangler expects anonymous namespaces to be called
+ something starting with '_GLOBAL__N_'. */
+ anonymous_namespace_name = get_identifier ("_GLOBAL__N_1");
}
return anonymous_namespace_name;
}
add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t)));
}
- if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x))
- check_default_args (x);
+ if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t))
+ check_default_args (t);
if (t != x || DECL_FUNCTION_TEMPLATE_P (t))
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
inlining. */
&& (!TYPE_NAME (type)
|| TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x))))
- set_underlying_type (x);
+ cp_set_underlying_type (x);
if (type != error_mark_node
&& TYPE_NAME (type)
return get_identifier (buf);
}
+/* This code is practically identical to that for creating
+ anonymous names, but is just used for lambdas instead. This is necessary
+ because anonymous names are recognized and cannot be passed to template
+ functions. */
+/* FIXME is this still necessary? */
+
+static GTY(()) int lambda_cnt = 0;
+
+tree
+make_lambda_name (void)
+{
+ char buf[32];
+
+ sprintf (buf, LAMBDANAME_FORMAT, lambda_cnt++);
+ return get_identifier (buf);
+}
+
/* Return (from the stack of) the BINDING, if any, established at SCOPE. */
static inline cxx_binding *
tree name;
bool is_valid = true;
+ /* Do nothing if we're adding to an outer lambda closure type,
+ outer_binding will add it later if it's needed. */
+ if (current_class_type != class_binding_level->this_entity)
+ return true;
+
timevar_push (TV_NAME_LOOKUP);
/* Get the name of X. */
if (TREE_CODE (x) == OVERLOAD)
/* Check for invalid member names. */
gcc_assert (TYPE_BEING_DEFINED (current_class_type));
+ /* Check that we're pushing into the right binding level. */
+ gcc_assert (current_class_type == class_binding_level->this_entity);
+
/* We could have been passed a tree list if this is an ambiguous
declaration. If so, pull the declaration out because
check_template_shadow will not handle a TREE_LIST. */
void
set_decl_namespace (tree decl, tree scope, bool friendp)
{
- tree old, fn;
+ tree old;
/* Get rid of namespace aliases. */
scope = ORIGINAL_NAMESPACE (scope);
if (old == error_mark_node)
/* No old declaration at all. */
goto complain;
+ /* If it's a TREE_LIST, the result of the lookup was ambiguous. */
+ if (TREE_CODE (old) == TREE_LIST)
+ {
+ error ("reference to %qD is ambiguous", decl);
+ print_candidates (old);
+ return;
+ }
if (!is_overloaded_fn (decl))
- /* Don't compare non-function decls with decls_match here, since
- it can't check for the correct constness at this
- point. pushdecl will find those errors later. */
- return;
+ {
+ /* We might have found OLD in an inline namespace inside SCOPE. */
+ if (TREE_CODE (decl) == TREE_CODE (old))
+ DECL_CONTEXT (decl) = DECL_CONTEXT (old);
+ /* Don't compare non-function decls with decls_match here, since
+ it can't check for the correct constness at this
+ point. pushdecl will find those errors later. */
+ return;
+ }
/* Since decl is a function, old should contain a function decl. */
if (!is_overloaded_fn (old))
goto complain;
- fn = OVL_CURRENT (old);
- if (!is_associated_namespace (scope, CP_DECL_CONTEXT (fn)))
- goto complain;
/* A template can be explicitly specialized in any namespace. */
if (processing_explicit_instantiation)
return;
return;
if (is_overloaded_fn (old))
{
- for (; old; old = OVL_NEXT (old))
- if (decls_match (decl, OVL_CURRENT (old)))
+ tree found = NULL_TREE;
+ tree elt = old;
+ for (; elt; elt = OVL_NEXT (elt))
+ {
+ tree ofn = OVL_CURRENT (elt);
+ /* Adjust DECL_CONTEXT first so decls_match will return true
+ if DECL will match a declaration in an inline namespace. */
+ DECL_CONTEXT (decl) = DECL_CONTEXT (ofn);
+ if (decls_match (decl, ofn))
+ {
+ if (found && !decls_match (found, ofn))
+ {
+ DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
+ error ("reference to %qD is ambiguous", decl);
+ print_candidates (old);
+ return;
+ }
+ found = ofn;
+ }
+ }
+ if (found)
+ {
+ if (!is_associated_namespace (scope, CP_DECL_CONTEXT (found)))
+ goto complain;
+ DECL_CONTEXT (decl) = DECL_CONTEXT (found);
return;
+ }
}
- else if (decls_match (decl, old))
- return;
+ else
+ {
+ DECL_CONTEXT (decl) = DECL_CONTEXT (old);
+ if (decls_match (decl, old))
+ return;
+ }
+
+ /* It didn't work, go back to the explicit scope. */
+ DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
complain:
error ("%qD should have been declared inside %qD", decl, scope);
}
/* Return the namespace where the current declaration is declared. */
-static tree
+tree
current_decl_namespace (void)
{
tree result;
"%qD attribute is meaningless since members of the "
"anonymous namespace get local symbols", name);
- push_visibility (TREE_STRING_POINTER (x));
+ push_visibility (TREE_STRING_POINTER (x), 1);
saw_vis = true;
}
else
pop_nested_namespace (tree ns)
{
timevar_push (TV_NAME_LOOKUP);
+ gcc_assert (current_namespace == ns);
while (ns != global_namespace)
{
pop_namespace ();
return true;
if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
return false;
+ /* In unevaluated context, look past normal capture fields. */
+ if (cp_unevaluated_operand && TREE_CODE (val) == FIELD_DECL
+ && DECL_NORMAL_CAPTURE_P (val))
+ return false;
+ /* None of the lookups that use qualify_lookup want the op() from the
+ lambda; they want the one from the enclosing class. */
+ if (TREE_CODE (val) == FUNCTION_DECL && LAMBDA_FUNCTION_P (val))
+ return false;
return true;
}
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
}
+/* Returns true iff VEC contains TARGET. */
+
+static bool
+tree_vec_contains (VEC(tree,gc)* vec, tree target)
+{
+ unsigned int i;
+ tree elt;
+ for (i = 0; VEC_iterate(tree,vec,i,elt); ++i)
+ if (elt == target)
+ return true;
+ return false;
+}
+
/* [namespace.qual]
Accepts the NAME to lookup and its qualifying SCOPE.
Returns the name/type pair found into the cxx_binding *RESULT,
struct scope_binding *result, int flags)
{
/* Maintain a list of namespaces visited... */
- tree seen = NULL_TREE;
+ VEC(tree,gc) *seen = NULL;
+ VEC(tree,gc) *seen_inline = NULL;
/* ... and a list of namespace yet to see. */
- tree todo = NULL_TREE;
- tree todo_maybe = NULL_TREE;
- tree *todo_weak = &todo_maybe;
+ VEC(tree,gc) *todo = NULL;
+ VEC(tree,gc) *todo_maybe = NULL;
+ VEC(tree,gc) *todo_inline = NULL;
tree usings;
timevar_push (TV_NAME_LOOKUP);
/* Look through namespace aliases. */
scope = ORIGINAL_NAMESPACE (scope);
- while (scope && result->value != error_mark_node)
+
+ /* Algorithm: Starting with SCOPE, walk through the the set of used
+ namespaces. For each used namespace, look through its inline
+ namespace set for any bindings and usings. If no bindings are found,
+ add any usings seen to the set of used namespaces. */
+ VEC_safe_push (tree, gc, todo, scope);
+
+ while (VEC_length (tree, todo))
{
- cxx_binding *binding =
- cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
- seen = tree_cons (scope, NULL_TREE, seen);
- if (binding)
- ambiguous_decl (result, binding, flags);
-
- /* Consider strong using directives always, and non-strong ones
- if we haven't found a binding yet. */
- for (usings = DECL_NAMESPACE_USING (scope); usings;
- usings = TREE_CHAIN (usings))
- /* If this was a real directive, and we have not seen it. */
- if (!TREE_INDIRECT_USING (usings))
- {
- /* Try to avoid queuing the same namespace more than once,
- the exception being when a namespace was already
- enqueued for todo_maybe and then a strong using is
- found for it. We could try to remove it from
- todo_maybe, but it's probably not worth the effort. */
- if (is_associated_namespace (scope, TREE_PURPOSE (usings))
- && !purpose_member (TREE_PURPOSE (usings), seen)
- && !purpose_member (TREE_PURPOSE (usings), todo))
- todo = tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo);
- else if (!binding
- && !purpose_member (TREE_PURPOSE (usings), seen)
- && !purpose_member (TREE_PURPOSE (usings), todo)
- && !purpose_member (TREE_PURPOSE (usings), todo_maybe))
- *todo_weak = tree_cons (TREE_PURPOSE (usings), NULL_TREE,
- *todo_weak);
- }
- if (todo)
+ bool found_here;
+ scope = VEC_pop (tree, todo);
+ if (tree_vec_contains (seen, scope))
+ continue;
+ VEC_safe_push (tree, gc, seen, scope);
+ VEC_safe_push (tree, gc, todo_inline, scope);
+
+ found_here = false;
+ while (VEC_length (tree, todo_inline))
{
- scope = TREE_PURPOSE (todo);
- todo = TREE_CHAIN (todo);
- }
- else if (todo_maybe
- && (!result->value && !result->type))
- {
- scope = TREE_PURPOSE (todo_maybe);
- todo = TREE_CHAIN (todo_maybe);
- todo_maybe = NULL_TREE;
- todo_weak = &todo;
+ cxx_binding *binding;
+
+ scope = VEC_pop (tree, todo_inline);
+ if (tree_vec_contains (seen_inline, scope))
+ continue;
+ VEC_safe_push (tree, gc, seen_inline, scope);
+
+ binding =
+ cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+ if (binding)
+ {
+ found_here = true;
+ ambiguous_decl (result, binding, flags);
+ }
+
+ for (usings = DECL_NAMESPACE_USING (scope); usings;
+ usings = TREE_CHAIN (usings))
+ if (!TREE_INDIRECT_USING (usings))
+ {
+ if (is_associated_namespace (scope, TREE_PURPOSE (usings)))
+ VEC_safe_push (tree, gc, todo_inline, TREE_PURPOSE (usings));
+ else
+ VEC_safe_push (tree, gc, todo_maybe, TREE_PURPOSE (usings));
+ }
}
+
+ if (found_here)
+ VEC_truncate (tree, todo_maybe, 0);
else
- scope = NULL_TREE; /* If there never was a todo list. */
+ while (VEC_length (tree, todo_maybe))
+ VEC_safe_push (tree, gc, todo, VEC_pop (tree, todo_maybe));
}
+ VEC_free (tree,gc,todo);
+ VEC_free (tree,gc,todo_maybe);
+ VEC_free (tree,gc,todo_inline);
+ VEC_free (tree,gc,seen);
+ VEC_free (tree,gc,seen_inline);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
}
static bool arg_assoc_type (struct arg_lookup*, tree);
static bool add_function (struct arg_lookup *, tree);
static bool arg_assoc_namespace (struct arg_lookup *, tree);
+static bool arg_assoc_class_only (struct arg_lookup *, tree);
+static bool arg_assoc_bases (struct arg_lookup *, tree);
static bool arg_assoc_class (struct arg_lookup *, tree);
static bool arg_assoc_template_arg (struct arg_lookup*, tree);
total number of functions being compared, which should usually be the
case. */
- /* We must find only functions, or exactly one non-function. */
- if (!k->functions)
+ if (!is_overloaded_fn (fn))
+ /* All names except those of (possibly overloaded) functions and
+ function templates are ignored. */;
+ else if (!k->functions)
k->functions = fn;
else if (fn == k->functions)
;
- else if (is_overloaded_fn (k->functions) && is_overloaded_fn (fn))
- k->functions = build_overload (fn, k->functions);
else
- {
- tree f1 = OVL_CURRENT (k->functions);
- tree f2 = fn;
- if (is_overloaded_fn (f1))
- {
- fn = f1; f1 = f2; f2 = fn;
- }
- error ("%q+D is not a function,", f1);
- error (" conflict with %q+D", f2);
- error (" in call to %qD", k->name);
- return true;
- }
+ k->functions = build_overload (fn, k->functions);
return false;
}
}
}
-/* Return whether FN is a friend of an associated class of ARG. */
-
-static bool
-friend_of_associated_class_p (tree arg, tree fn)
-{
- tree type;
-
- if (TYPE_P (arg))
- type = arg;
- else if (type_unknown_p (arg))
- return false;
- else
- type = TREE_TYPE (arg);
-
- /* If TYPE is a class, the class itself and all base classes are
- associated classes. */
- if (CLASS_TYPE_P (type))
- {
- if (is_friend (type, fn))
- return true;
-
- if (TYPE_BINFO (type))
- {
- tree binfo, base_binfo;
- int i;
-
- for (binfo = TYPE_BINFO (type), i = 0;
- BINFO_BASE_ITERATE (binfo, i, base_binfo);
- i++)
- if (is_friend (BINFO_TYPE (base_binfo), fn))
- return true;
- }
- }
-
- /* If TYPE is a class member, the class of which it is a member is
- an associated class. */
- if ((CLASS_TYPE_P (type)
- || TREE_CODE (type) == UNION_TYPE
- || TREE_CODE (type) == ENUMERAL_TYPE)
- && TYPE_CONTEXT (type)
- && CLASS_TYPE_P (TYPE_CONTEXT (type))
- && is_friend (TYPE_CONTEXT (type), fn))
- return true;
-
- return false;
-}
-
/* Add functions of a namespace to the lookup structure.
Returns true on error. */
{
/* We don't want to find arbitrary hidden functions via argument
dependent lookup. We only want to find friends of associated
- classes. */
+ classes, which we'll do via arg_assoc_class. */
if (hidden_name_p (OVL_CURRENT (value)))
- {
- unsigned int ix;
- tree arg;
-
- for (ix = 0; VEC_iterate (tree, k->args, ix, arg); ++ix)
- if (friend_of_associated_class_p (arg, OVL_CURRENT (value)))
- break;
- if (ix >= VEC_length (tree, k->args))
- continue;
- }
+ continue;
if (add_function (k, OVL_CURRENT (value)))
return true;
return arg_assoc_namespace (k, ctx);
/* Otherwise, it must be member template. */
else
- return arg_assoc_class (k, ctx);
+ return arg_assoc_class_only (k, ctx);
}
/* It's an argument pack; handle it recursively. */
else if (ARGUMENT_PACK_P (arg))
return false;
}
-/* Adds everything associated with class to the lookup structure.
+/* Adds the class and its friends to the lookup structure.
Returns true on error. */
static bool
-arg_assoc_class (struct arg_lookup *k, tree type)
+arg_assoc_class_only (struct arg_lookup *k, tree type)
{
tree list, friends, context;
- int i;
- /* Backend build structures, such as __builtin_va_list, aren't
+ /* Backend-built structures, such as __builtin_va_list, aren't
affected by all this. */
if (!CLASS_TYPE_P (type))
return false;
- if (purpose_member (type, k->classes))
- return false;
- k->classes = tree_cons (type, NULL_TREE, k->classes);
-
context = decl_namespace_context (type);
if (arg_assoc_namespace (k, context))
return true;
- if (TYPE_BINFO (type))
- {
- /* Process baseclasses. */
- tree binfo, base_binfo;
-
- for (binfo = TYPE_BINFO (type), i = 0;
- BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
- if (arg_assoc_class (k, BINFO_TYPE (base_binfo)))
- return true;
- }
+ complete_type (type);
/* Process friends. */
for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list;
return true;
}
+ return false;
+}
+
+/* Adds the class and its bases to the lookup structure.
+ Returns true on error. */
+
+static bool
+arg_assoc_bases (struct arg_lookup *k, tree type)
+{
+ if (arg_assoc_class_only (k, type))
+ return true;
+
+ if (TYPE_BINFO (type))
+ {
+ /* Process baseclasses. */
+ tree binfo, base_binfo;
+ int i;
+
+ for (binfo = TYPE_BINFO (type), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ if (arg_assoc_bases (k, BINFO_TYPE (base_binfo)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Adds everything associated with a class argument type to the lookup
+ structure. Returns true on error.
+
+ If T is a class type (including unions), its associated classes are: the
+ class itself; the class of which it is a member, if any; and its direct
+ and indirect base classes. Its associated namespaces are the namespaces
+ of which its associated classes are members. Furthermore, if T is a
+ class template specialization, its associated namespaces and classes
+ also include: the namespaces and classes associated with the types of
+ the template arguments provided for template type parameters (excluding
+ template template parameters); the namespaces of which any template
+ template arguments are members; and the classes of which any member
+ templates used as template template arguments are members. [ Note:
+ non-type template arguments do not contribute to the set of associated
+ namespaces. --end note] */
+
+static bool
+arg_assoc_class (struct arg_lookup *k, tree type)
+{
+ tree list;
+ int i;
+
+ /* Backend build structures, such as __builtin_va_list, aren't
+ affected by all this. */
+ if (!CLASS_TYPE_P (type))
+ return false;
+
+ if (purpose_member (type, k->classes))
+ return false;
+ k->classes = tree_cons (type, NULL_TREE, k->classes);
+
+ if (TYPE_CLASS_SCOPE_P (type)
+ && arg_assoc_class_only (k, TYPE_CONTEXT (type)))
+ return true;
+
+ if (arg_assoc_bases (k, type))
+ return true;
+
/* Process template arguments. */
if (CLASSTYPE_TEMPLATE_INFO (type)
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)))
{
list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
for (i = 0; i < TREE_VEC_LENGTH (list); ++i)
- arg_assoc_template_arg (k, TREE_VEC_ELT (list, i));
+ if (arg_assoc_template_arg (k, TREE_VEC_ELT (list, i)))
+ return true;
}
return false;
case BOOLEAN_TYPE:
case FIXED_POINT_TYPE:
case DECLTYPE_TYPE:
+ case NULLPTR_TYPE:
return false;
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (type))
return arg_assoc_type (k, TYPE_PTRMEMFUNC_FN_TYPE (type));
+ case UNION_TYPE:
return arg_assoc_class (k, type);
case POINTER_TYPE:
case REFERENCE_TYPE:
case ARRAY_TYPE:
return arg_assoc_type (k, TREE_TYPE (type));
- case UNION_TYPE:
case ENUMERAL_TYPE:
+ if (TYPE_CLASS_SCOPE_P (type)
+ && arg_assoc_class_only (k, TYPE_CONTEXT (type)))
+ return true;
return arg_assoc_namespace (k, decl_namespace_context (type));
case METHOD_TYPE:
/* The basetype is referenced in the first arg type, so just
return arg_assoc_type (k, TREE_TYPE (n));
if (TREE_CODE (n) == TEMPLATE_ID_EXPR)
{
- /* [basic.lookup.koenig]
-
- If T is a template-id, its associated namespaces and classes
- are the namespace in which the template is defined; for
- member templates, the member template's class... */
+ /* The working paper doesn't currently say how to handle template-id
+ arguments. The sensible thing would seem to be to handle the list
+ of template candidates like a normal overload set, and handle the
+ template arguments like we do for class template
+ specializations. */
tree templ = TREE_OPERAND (n, 0);
tree args = TREE_OPERAND (n, 1);
- tree ctx;
int ix;
- if (TREE_CODE (templ) == COMPONENT_REF)
- templ = TREE_OPERAND (templ, 1);
-
- /* First, the template. There may actually be more than one if
- this is an overloaded function template. But, in that case,
- we only need the first; all the functions will be in the same
- namespace. */
- templ = OVL_CURRENT (templ);
-
- ctx = CP_DECL_CONTEXT (templ);
-
- if (TREE_CODE (ctx) == NAMESPACE_DECL)
- {
- if (arg_assoc_namespace (k, ctx) == 1)
- return true;
- }
- /* It must be a member template. */
- else if (arg_assoc_class (k, ctx) == 1)
+ /* First the templates. */
+ if (arg_assoc (k, templ))
return true;
/* Now the arguments. */
{
tree cs = current_scope ();
- if (scope == ts_current)
+ if (scope == ts_current
+ || (cs && TREE_CODE (cs) == FUNCTION_DECL))
context = cs;
else if (cs != NULL_TREE && TYPE_P (cs))
/* When declaring a friend class of a local class, we want
decl = TYPE_NAME (type);
gcc_assert (TREE_CODE (decl) == TYPE_DECL);
- TYPE_STUB_DECL (type) = decl;
/* Set type visibility now if this is a forward declaration. */
TREE_PUBLIC (decl) = 1;