#include "cp-tree.h"
#include "name-lookup.h"
#include "timevar.h"
-#include "toplev.h"
#include "diagnostic-core.h"
+#include "intl.h"
#include "debug.h"
#include "c-family/c-pragma.h"
+#include "params.h"
/* The bindings for a particular name in a particular scope. */
/* 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
inlining. */
&& (!TYPE_NAME (type)
|| TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x))))
- cp_set_underlying_type (x);
+ set_underlying_type (x);
if (type != error_mark_node
&& TYPE_NAME (type)
/* 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);
}
}
&& 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 ())
|| type == unknown_type_node
/* The declaration of a template specialization does not affect
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);
}
/* 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. */
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;
saw_vis = true;
}
else
-#endif
{
warning (OPT_Wattributes, "%qD attribute directive ignored",
name);
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
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;
+ {
+ ret = false;
+ break;
+ }
}
+
+ release_tree_vector (seen);
+ release_tree_vector (todo);
+
+ return ret;
}
/* Add functions of a namespace to the lookup structure.
case BOOLEAN_TYPE:
case FIXED_POINT_TYPE:
case DECLTYPE_TYPE:
+ case NULLPTR_TYPE:
return false;
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (type))
return false;
case LANG_TYPE:
gcc_assert (type == unknown_type_node
- || NULLPTR_TYPE_P (type)
|| type == init_list_type_node);
return false;
case TYPE_PACK_EXPANSION:
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;
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;
picking up later definitions) in the second stage. */
k.namespaces = make_tree_vector ();
+ if (include_std)
+ arg_assoc_namespace (&k, std_node);
arg_assoc_args_vec (&k, args);
fns = k.functions;
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;