/* 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>
#include "cp-tree.h"
#include "name-lookup.h"
#include "timevar.h"
-#include "toplev.h"
-#include "diagnostic.h"
+#include "diagnostic-core.h"
+#include "intl.h"
#include "debug.h"
-#include "c-pragma.h"
+#include "c-family/c-pragma.h"
+#include "params.h"
/* The bindings for a particular name in a particular scope. */
free_binding_entry = entry->chain;
}
else
- entry = GGC_NEW (struct binding_entry_s);
+ entry = ggc_alloc_binding_entry_s ();
entry->name = name;
entry->type = type;
{
table->chain_count = chain_count;
table->entry_count = 0;
- table->chain = GGC_CNEWVEC (binding_entry, table->chain_count);
+ table->chain = ggc_alloc_cleared_vec_binding_entry (table->chain_count);
}
/* Make TABLE's entries ready for reuse. */
static inline binding_table
binding_table_new (size_t chain_count)
{
- binding_table table = GGC_NEW (struct binding_table_s);
+ binding_table table = ggc_alloc_binding_table_s ();
table->chain = NULL;
binding_table_construct (table, chain_count);
return table;
free_bindings = binding->previous;
}
else
- binding = GGC_NEW (cxx_binding);
+ binding = ggc_alloc_cxx_binding ();
cxx_binding_init (binding, value, type);
/* Fixup the current bindings, as they might have moved. */
size_t i;
- for (i = 0;
- VEC_iterate (cp_class_binding, scope->class_shadowed, i, cb);
- i++)
+ FOR_EACH_VEC_ELT (cp_class_binding, scope->class_shadowed, i, cb)
{
cxx_binding **b;
b = &IDENTIFIER_BINDING (cb->identifier);
if (TREE_CODE (decl) == NAMESPACE_DECL
&& !DECL_NAMESPACE_ALIAS (decl))
{
- TREE_CHAIN (decl) = b->namespaces;
+ DECL_CHAIN (decl) = b->namespaces;
b->namespaces = decl;
}
else
= htab_create_ggc (20, cxx_int_tree_map_hash,
cxx_int_tree_map_eq, NULL);
- h = GGC_NEW (struct cxx_int_tree_map);
+ h = ggc_alloc_cxx_int_tree_map ();
h->uid = DECL_UID (x);
h->to = t;
loc = htab_find_slot_with_hash
TYPE_RAISES_EXCEPTIONS (TREE_TYPE (previous));
if (!comp_except_specs (previous_exception_spec,
x_exception_spec,
- true))
+ ce_normal))
{
pedwarn (input_location, 0, "declaration of %q#D with C language linkage",
x);
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);
/* OK */;
else
{
- warning (0, "extern declaration of %q#D doesn't match", x);
+ warning (0, "extern declaration of %q#D doesn%'t match", x);
warning (0, "global declaration %q+#D", oldglobal);
}
}
else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
/* Inline decls shadow nothing. */
&& !DECL_FROM_INLINE (x)
- && TREE_CODE (oldlocal) == PARM_DECL
- /* Don't check the `this' parameter. */
- && !DECL_ARTIFICIAL (oldlocal))
+ && (TREE_CODE (oldlocal) == PARM_DECL
+ || TREE_CODE (oldlocal) == VAR_DECL
+ /* If the old decl is a type decl, only warn if the
+ old decl is an explicit typedef or if both the old
+ and new decls are type decls. */
+ || (TREE_CODE (oldlocal) == TYPE_DECL
+ && (!DECL_ARTIFICIAL (oldlocal)
+ || TREE_CODE (x) == TYPE_DECL)))
+ /* Don't check the `this' parameter or internally generated
+ vars unless it's an implicit typedef (see
+ create_implicit_typedef in decl.c). */
+ && (!DECL_ARTIFICIAL (oldlocal)
+ || DECL_IMPLICIT_TYPEDEF_P (oldlocal))
+ /* Don't check for internally generated vars unless
+ it's an implicit typedef (see create_implicit_typedef
+ in decl.c). */
+ && (!DECL_ARTIFICIAL (x) || DECL_IMPLICIT_TYPEDEF_P (x)))
{
- bool err = false;
+ bool nowarn = false;
/* Don't complain if it's from an enclosing function. */
if (DECL_CONTEXT (oldlocal) == current_function_decl
- && TREE_CODE (x) != PARM_DECL)
+ && TREE_CODE (x) != PARM_DECL
+ && TREE_CODE (oldlocal) == PARM_DECL)
{
/* Go to where the parms should be and see if we find
them there. */
if (b->kind == sk_function_parms)
{
error ("declaration of %q#D shadows a parameter", x);
- err = true;
+ nowarn = true;
}
}
- if (warn_shadow && !err)
+ /* The local structure or class can't use parameters of
+ the containing function anyway. */
+ if (DECL_CONTEXT (oldlocal) != current_function_decl)
{
- warning_at (input_location, OPT_Wshadow,
- "declaration of %q#D shadows a parameter", x);
- warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
- "shadowed declaration is here");
+ cxx_scope *scope = current_binding_level;
+ tree context = DECL_CONTEXT (oldlocal);
+ for (; scope; scope = scope->level_chain)
+ {
+ if (scope->kind == sk_function_parms
+ && scope->this_entity == context)
+ break;
+ if (scope->kind == sk_class
+ && !LAMBDA_TYPE_P (scope->this_entity))
+ {
+ nowarn = true;
+ break;
+ }
+ }
+ }
+
+ if (warn_shadow && !nowarn)
+ {
+ if (TREE_CODE (oldlocal) == PARM_DECL)
+ warning_at (input_location, OPT_Wshadow,
+ "declaration of %q#D shadows a parameter", x);
+ else
+ warning_at (input_location, OPT_Wshadow,
+ "declaration of %qD shadows a previous local",
+ x);
+ warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
+ "shadowed declaration is here");
}
}
/* Maybe warn if shadowing something else. */
else if (warn_shadow && !DECL_EXTERNAL (x)
- /* No shadow warnings for internally generated vars. */
- && ! DECL_ARTIFICIAL (x)
- /* No shadow warnings for vars made for inlining. */
- && ! DECL_FROM_INLINE (x))
+ /* No shadow warnings for internally generated vars unless
+ it's an implicit typedef (see create_implicit_typedef
+ in decl.c). */
+ && (! DECL_ARTIFICIAL (x) || DECL_IMPLICIT_TYPEDEF_P (x))
+ /* No shadow warnings for vars made for inlining. */
+ && ! DECL_FROM_INLINE (x))
{
tree member;
warning (OPT_Wshadow, "declaration of %qD shadows a member of 'this'",
x);
}
- else if (oldlocal != NULL_TREE
- && TREE_CODE (oldlocal) == VAR_DECL)
- {
- warning_at (input_location, OPT_Wshadow,
- "declaration of %qD shadows a previous local", x);
- warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
- "shadowed declaration is here");
- }
else if (oldglobal != NULL_TREE
- && TREE_CODE (oldglobal) == VAR_DECL)
+ && (TREE_CODE (oldglobal) == VAR_DECL
+ /* If the old decl is a type decl, only warn if the
+ old decl is an explicit typedef or if both the
+ old and new decls are type decls. */
+ || (TREE_CODE (oldglobal) == TYPE_DECL
+ && (!DECL_ARTIFICIAL (oldglobal)
+ || TREE_CODE (x) == TYPE_DECL))))
/* XXX shadow warnings in outer-more namespaces */
{
warning_at (input_location, OPT_Wshadow,
&& DECL_CONTEXT (decl) != NULL_TREE
/* Definitions of namespace members outside their namespace are
possible. */
- && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL)
+ && !DECL_NAMESPACE_SCOPE_P (decl))
|| (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ())
- || TREE_CODE (type) == UNKNOWN_TYPE
+ || type == unknown_type_node
/* The declaration of a template specialization does not affect
the functions available for overload resolution, so we do not
call pushdecl. */
free_binding_level = scope->level_chain;
}
else
- scope = GGC_CNEW (cxx_scope);
+ scope = ggc_alloc_cleared_cxx_scope ();
scope->this_entity = entity;
scope->more_cleanups_ok = true;
return current_binding_level->names;
}
+/* Return how many function prototypes we are currently nested inside. */
+
+int
+function_parm_depth (void)
+{
+ int level = 0;
+ struct cp_binding_level *b;
+
+ for (b = current_binding_level;
+ b->kind == sk_function_parms;
+ b = b->level_chain)
+ ++level;
+
+ return level;
+}
+
/* For debugging. */
static int no_print_functions = 0;
static int no_print_builtins = 0;
size_t i;
cp_class_binding *b;
fprintf (stderr, " class-shadowed:");
- for (i = 0;
- VEC_iterate(cp_class_binding, lvl->class_shadowed, i, b);
- ++i)
+ FOR_EACH_VEC_ELT (cp_class_binding, lvl->class_shadowed, i, b)
fprintf (stderr, " %s ", IDENTIFIER_POINTER (b->identifier));
fprintf (stderr, "\n");
}
timevar_push (TV_NAME_LOOKUP);
gcc_assert (TREE_CODE (scope) == NAMESPACE_DECL);
gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
- for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
+ for (decl = current_binding_level->usings; decl; decl = DECL_CHAIN (decl))
if (USING_DECL_SCOPE (decl) == scope && DECL_NAME (decl) == name)
break;
if (decl)
namespace_bindings_p () ? decl : NULL_TREE);
decl = build_lang_decl (USING_DECL, name, NULL_TREE);
USING_DECL_SCOPE (decl) = scope;
- TREE_CHAIN (decl) = current_binding_level->usings;
+ DECL_CHAIN (decl) = current_binding_level->usings;
current_binding_level->usings = decl;
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
}
void
pop_scope (tree t)
{
+ if (t == NULL_TREE)
+ return;
if (TREE_CODE (t) == NAMESPACE_DECL)
pop_decl_namespace ();
else if CLASS_TYPE_P (t)
/* Remove the bindings for all of the class-level declarations. */
if (level->class_shadowed)
{
- for (i = 0;
- VEC_iterate (cp_class_binding, level->class_shadowed, i, cb);
- ++i)
+ FOR_EACH_VEC_ELT (cp_class_binding, level->class_shadowed, i, cb)
IDENTIFIER_BINDING (cb->identifier) = cb->base.previous;
ggc_free (level->class_shadowed);
level->class_shadowed = NULL;
aggregate, for naming purposes. */
tree f;
- for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f))
+ for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = DECL_CHAIN (f))
{
location_t save_location = input_location;
input_location = DECL_SOURCE_LOCATION (f);
{
cxx_binding *binding;
- if (scope == NULL)
+ if (SCOPE_FILE_SCOPE_P (scope))
scope = global_namespace;
else
/* Unnecessary for the global namespace because it can't be an alias. */
if (!is_overloaded_fn (decl))
{
/* We might have found OLD in an inline namespace inside SCOPE. */
- DECL_CONTEXT (decl) = DECL_CONTEXT (old);
+ 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 the namespace where the current declaration is declared. */
-static tree
+tree
current_decl_namespace (void)
{
tree result;
/* If we have been pushed into a different namespace, use it. */
- if (decl_namespace_list)
- return TREE_PURPOSE (decl_namespace_list);
+ if (!VEC_empty (tree, decl_namespace_list))
+ return VEC_last (tree, decl_namespace_list);
if (current_class_type)
result = decl_namespace_context (current_class_type);
tree name = TREE_PURPOSE (d);
tree args = TREE_VALUE (d);
-#ifdef HANDLE_PRAGMA_VISIBILITY
if (is_attribute_p ("visibility", name))
{
tree x = args ? TREE_VALUE (args) : NULL_TREE;
"%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
-#endif
{
warning (OPT_Wattributes, "%qD attribute directive ignored",
name);
pop_nested_namespace (tree ns)
{
timevar_push (TV_NAME_LOOKUP);
+ gcc_assert (current_namespace == ns);
while (ns != global_namespace)
{
pop_namespace ();
{
if (TREE_CODE (decl) != NAMESPACE_DECL)
decl = decl_namespace_context (decl);
- decl_namespace_list = tree_cons (ORIGINAL_NAMESPACE (decl),
- NULL_TREE, decl_namespace_list);
+ VEC_safe_push (tree, gc, decl_namespace_list, ORIGINAL_NAMESPACE (decl));
}
/* [namespace.memdef]/2 */
void
pop_decl_namespace (void)
{
- decl_namespace_list = TREE_CHAIN (decl_namespace_list);
+ VEC_pop (tree, decl_namespace_list);
}
/* Return the namespace that is the common ancestor
return s1;
}
+/* Returns TRUE iff OLD and NEW are the same entity.
+
+ 3 [basic]/3: An entity is a value, object, reference, function,
+ enumerator, type, class member, template, template specialization,
+ namespace, parameter pack, or this.
+
+ 7.3.4 [namespace.udir]/4: If name lookup finds a declaration for a name
+ in two different namespaces, and the declarations do not declare the
+ same entity and do not declare functions, the use of the name is
+ ill-formed. */
+
+static bool
+same_entity_p (tree one, tree two)
+{
+ if (one == two)
+ return true;
+ if (!one || !two)
+ return false;
+ if (TREE_CODE (one) == TYPE_DECL
+ && TREE_CODE (two) == TYPE_DECL
+ && same_type_p (TREE_TYPE (one), TREE_TYPE (two)))
+ return true;
+ return false;
+}
+
/* This should return an error not all definitions define functions.
It is not an error if we find two functions with exactly the
same signature, only if these are selected in overload resolution.
if (!old->value)
old->value = val;
- else if (val && val != old->value)
+ else if (val && !same_entity_p (val, old->value))
{
if (is_overloaded_fn (old->value) && is_overloaded_fn (val))
old->value = merge_functions (old->value, val);
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;
}
return fns;
}
+/* Suggest alternatives for NAME, an IDENTIFIER_NODE for which name
+ lookup failed. Search through all available namespaces and print out
+ possible candidates. */
+
+void
+suggest_alternatives_for (location_t location, tree name)
+{
+ VEC(tree,heap) *candidates = NULL;
+ VEC(tree,heap) *namespaces_to_search = NULL;
+ int max_to_search = PARAM_VALUE (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP);
+ int n_searched = 0;
+ tree t;
+ unsigned ix;
+
+ VEC_safe_push (tree, heap, namespaces_to_search, global_namespace);
+
+ while (!VEC_empty (tree, namespaces_to_search)
+ && n_searched < max_to_search)
+ {
+ tree scope = VEC_pop (tree, namespaces_to_search);
+ struct scope_binding binding = EMPTY_SCOPE_BINDING;
+ struct cp_binding_level *level = NAMESPACE_LEVEL (scope);
+
+ /* Look in this namespace. */
+ qualified_lookup_using_namespace (name, scope, &binding, 0);
+
+ n_searched++;
+
+ if (binding.value)
+ VEC_safe_push (tree, heap, candidates, binding.value);
+
+ /* Add child namespaces. */
+ for (t = level->namespaces; t; t = DECL_CHAIN (t))
+ VEC_safe_push (tree, heap, namespaces_to_search, t);
+ }
+
+ /* If we stopped before we could examine all namespaces, inform the
+ user. Do this even if we don't have any candidates, since there
+ might be more candidates further down that we weren't able to
+ find. */
+ if (n_searched >= max_to_search
+ && !VEC_empty (tree, namespaces_to_search))
+ inform (location,
+ "maximum limit of %d namespaces searched for %qE",
+ max_to_search, name);
+
+ VEC_free (tree, heap, namespaces_to_search);
+
+ /* Nothing useful to report. */
+ if (VEC_empty (tree, candidates))
+ return;
+
+ inform_n (location, VEC_length (tree, candidates),
+ "suggested alternative:",
+ "suggested alternatives:");
+
+ FOR_EACH_VEC_ELT (tree, candidates, ix, t)
+ inform (location_of (t), " %qE", t);
+
+ VEC_free (tree, heap, candidates);
+}
+
/* Unscoped lookup of a global: iterate over current namespaces,
considering using-directives. */
{
unsigned int i;
tree elt;
- for (i = 0; VEC_iterate(tree,vec,i,elt); ++i)
+ FOR_EACH_VEC_ELT (tree,vec,i,elt)
if (elt == target)
return true;
return false;
}
/* Subroutine of outer_binding.
- Returns TRUE if BINDING is a binding to a template parameter of SCOPE,
- FALSE otherwise. */
+
+ Returns TRUE if BINDING is a binding to a template parameter of
+ SCOPE. In that case SCOPE is the scope of a primary template
+ parameter -- in the sense of G++, i.e, a template that has its own
+ template header.
+
+ Returns FALSE otherwise. */
static bool
binding_to_template_parms_of_scope_p (cxx_binding *binding,
return (scope
&& scope->this_entity
&& get_template_info (scope->this_entity)
+ && PRIMARY_TEMPLATE_P (TI_TEMPLATE
+ (get_template_info (scope->this_entity)))
&& parameter_of_template_p (binding_value,
TI_TEMPLATE (get_template_info \
(scope->this_entity))));
lookup_arg_dependent (name,
lookup_name_real (name, 0, 1, block_p, 0,
LOOKUP_COMPLAIN),
- args);
+ args, false);
}
tree
{
tree name;
VEC(tree,gc) *args;
- tree namespaces;
- tree classes;
+ VEC(tree,gc) *namespaces;
+ VEC(tree,gc) *classes;
tree functions;
};
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);
+ if (TREE_CODE (k->functions) == OVERLOAD)
+ OVL_ARG_DEPENDENT (k->functions) = true;
}
return false;
bool
is_associated_namespace (tree current, tree scope)
{
- tree seen = NULL_TREE;
- tree todo = NULL_TREE;
+ VEC(tree,gc) *seen = make_tree_vector ();
+ VEC(tree,gc) *todo = make_tree_vector ();
tree t;
+ bool ret;
+
while (1)
{
if (scope == current)
- return true;
- seen = tree_cons (scope, NULL_TREE, seen);
+ {
+ ret = true;
+ break;
+ }
+ VEC_safe_push (tree, gc, seen, scope);
for (t = DECL_NAMESPACE_ASSOCIATIONS (scope); t; t = TREE_CHAIN (t))
- if (!purpose_member (TREE_PURPOSE (t), seen))
- todo = tree_cons (TREE_PURPOSE (t), NULL_TREE, todo);
- if (todo)
+ if (!vec_member (TREE_PURPOSE (t), seen))
+ VEC_safe_push (tree, gc, todo, TREE_PURPOSE (t));
+ if (!VEC_empty (tree, todo))
{
- scope = TREE_PURPOSE (todo);
- todo = TREE_CHAIN (todo);
+ scope = VEC_last (tree, todo);
+ VEC_pop (tree, todo);
}
else
- 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;
+ ret = false;
+ break;
}
}
- /* 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;
+ release_tree_vector (seen);
+ release_tree_vector (todo);
- return false;
+ return ret;
}
/* Add functions of a namespace to the lookup structure.
{
tree value;
- if (purpose_member (scope, k->namespaces))
- return 0;
- k->namespaces = tree_cons (scope, NULL_TREE, k->namespaces);
+ if (vec_member (scope, k->namespaces))
+ return false;
+ VEC_safe_push (tree, gc, k->namespaces, scope);
/* Check out our super-users. */
for (value = DECL_NAMESPACE_ASSOCIATIONS (scope); value;
{
/* 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 (vec_member (type, k->classes))
+ return false;
+ VEC_safe_push (tree, gc, k->classes, type);
+
+ 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
unsigned int ix;
tree arg;
- for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
+ FOR_EACH_VEC_ELT (tree, args, ix, arg)
if (arg_assoc (k, arg))
return true;
return false;
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. */
}
else if (TREE_CODE (n) == OVERLOAD)
{
- for (; n; n = OVL_CHAIN (n))
- if (arg_assoc_type (k, TREE_TYPE (OVL_FUNCTION (n))))
+ for (; n; n = OVL_NEXT (n))
+ if (arg_assoc_type (k, TREE_TYPE (OVL_CURRENT (n))))
return true;
}
are the functions found in normal lookup. */
tree
-lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args)
+lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args,
+ bool include_std)
{
struct arg_lookup k;
k.name = name;
k.args = args;
k.functions = fns;
- k.classes = NULL_TREE;
+ k.classes = make_tree_vector ();
/* We previously performed an optimization here by setting
NAMESPACES to the current namespace when it was safe. However, DR
164 says that namespaces that were already searched in the first
stage of template processing are searched again (potentially
picking up later definitions) in the second stage. */
- k.namespaces = NULL_TREE;
+ k.namespaces = make_tree_vector ();
+ if (include_std)
+ arg_assoc_namespace (&k, std_node);
arg_assoc_args_vec (&k, args);
fns = k.functions;
error (" in call to %qD", name);
fns = error_mark_node;
}
+
+ release_tree_vector (k.classes);
+ release_tree_vector (k.namespaces);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fns);
}
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;
bool need_pop;
timevar_push (TV_NAME_LOOKUP);
- s = GGC_CNEW (struct saved_scope);
+ s = ggc_alloc_cleared_saved_scope ();
b = scope_chain ? current_binding_level : 0;
SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t));
}
- for (i = 0; VEC_iterate (cxx_saved_binding, s->old_bindings, i, sb); ++i)
+ FOR_EACH_VEC_ELT (cxx_saved_binding, s->old_bindings, i, sb)
IDENTIFIER_MARKED (sb->identifier) = 0;
s->prev = scope_chain;
current_lang_base = 0;
scope_chain = s->prev;
- for (i = 0; VEC_iterate (cxx_saved_binding, s->old_bindings, i, saved); ++i)
+ FOR_EACH_VEC_ELT (cxx_saved_binding, s->old_bindings, i, saved)
{
tree id = saved->identifier;
cp_emit_debug_info_for_using (tree t, tree context)
{
/* Don't try to emit any debug information if we have errors. */
- if (sorrycount || errorcount)
+ if (seen_error ())
return;
/* Ignore this FUNCTION_DECL if it refers to a builtin declaration