Commit c957e9c0 by Nathan Sidwell Committed by Nathan Sidwell

name-lookup.h (cp_binding_level): Lose namespaces field.

	* name-lookup.h (cp_binding_level): Lose namespaces field.
	* name-lookup.c (add_decl_to_level): Chain namespaces on the names
	list.
	(suggest_alternatives_for): Adjust for namespace list.  Do
	breadth-first search.
	* decl2.c (collect_source_refs): Namespaces are on the regulr
	list.
	(collect_ada_namespace): Likewise.

	* g++.dg/pr45330.C: Adjust.  Check breadth-firstness.

From-SVN: r248821
parent 643a9684
2017-06-02 Nathan Sidwell <nathan@acm.org>
* name-lookup.h (cp_binding_level): Lose namespaces field.
* name-lookup.c (add_decl_to_level): Chain namespaces on the names
list.
(suggest_alternatives_for): Adjust for namespace list. Do
breadth-first search.
* decl2.c (collect_source_refs): Namespaces are on the regulr
list.
(collect_ada_namespace): Likewise.
2017-06-02 Bernd Edlinger <bernd.edlinger@hotmail.de> 2017-06-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
* typeck.c (cp_build_binary_op): Implement the -Wsizeof_pointer_div * typeck.c (cp_build_binary_op): Implement the -Wsizeof_pointer_div
......
...@@ -4052,21 +4052,14 @@ cpp_check (tree t, cpp_operation op) ...@@ -4052,21 +4052,14 @@ cpp_check (tree t, cpp_operation op)
static void static void
collect_source_refs (tree namespc) collect_source_refs (tree namespc)
{ {
tree t;
if (!namespc)
return;
/* Iterate over names in this name space. */ /* Iterate over names in this name space. */
for (t = NAMESPACE_LEVEL (namespc)->names; t; t = TREE_CHAIN (t)) for (tree t = NAMESPACE_LEVEL (namespc)->names; t; t = TREE_CHAIN (t))
if (!DECL_IS_BUILTIN (t) ) if (DECL_IS_BUILTIN (t))
;
else if (TREE_CODE (t) == NAMESPACE_DECL && !DECL_NAMESPACE_ALIAS (t))
collect_source_refs (t);
else
collect_source_ref (DECL_SOURCE_FILE (t)); collect_source_ref (DECL_SOURCE_FILE (t));
/* Dump siblings, if any */
collect_source_refs (TREE_CHAIN (namespc));
/* Dump children, if any */
collect_source_refs (NAMESPACE_LEVEL (namespc)->namespaces);
} }
/* Collect decls relevant to SOURCE_FILE from all namespaces recursively, /* Collect decls relevant to SOURCE_FILE from all namespaces recursively,
...@@ -4075,17 +4068,16 @@ collect_source_refs (tree namespc) ...@@ -4075,17 +4068,16 @@ collect_source_refs (tree namespc)
static void static void
collect_ada_namespace (tree namespc, const char *source_file) collect_ada_namespace (tree namespc, const char *source_file)
{ {
if (!namespc) tree decl = NAMESPACE_LEVEL (namespc)->names;
return;
/* Collect decls from this namespace */
collect_ada_nodes (NAMESPACE_LEVEL (namespc)->names, source_file);
/* Collect siblings, if any */ /* Collect decls from this namespace. This will skip
collect_ada_namespace (TREE_CHAIN (namespc), source_file); NAMESPACE_DECLs (both aliases and regular, it cannot tell). */
collect_ada_nodes (decl, source_file);
/* Collect children, if any */ /* Now scan for namespace children, and dump them. */
collect_ada_namespace (NAMESPACE_LEVEL (namespc)->namespaces, source_file); for (; decl; decl = TREE_CHAIN (decl))
if (TREE_CODE (decl) == NAMESPACE_DECL && !DECL_NAMESPACE_ALIAS (decl))
collect_ada_namespace (decl, source_file);
} }
/* Returns true iff there is a definition available for variable or /* Returns true iff there is a definition available for variable or
......
...@@ -115,15 +115,6 @@ add_decl_to_level (cp_binding_level *b, tree decl) ...@@ -115,15 +115,6 @@ add_decl_to_level (cp_binding_level *b, tree decl)
{ {
gcc_assert (b->kind != sk_class); gcc_assert (b->kind != sk_class);
if (TREE_CODE (decl) == NAMESPACE_DECL && !DECL_NAMESPACE_ALIAS (decl))
{
/* Inner namespaces get their own chain, to make walking
simpler. */
DECL_CHAIN (decl) = b->namespaces;
b->namespaces = decl;
}
else
{
/* Make sure we don't create a circular list. xref_tag can end /* Make sure we don't create a circular list. xref_tag can end
up pushing the same artificial decl more than once. We up pushing the same artificial decl more than once. We
should have already detected that in update_binding. */ should have already detected that in update_binding. */
...@@ -138,15 +129,14 @@ add_decl_to_level (cp_binding_level *b, tree decl) ...@@ -138,15 +129,14 @@ add_decl_to_level (cp_binding_level *b, tree decl)
include extern variables because they might turn out to be include extern variables because they might turn out to be
static later. It's OK for this list to contain a few false static later. It's OK for this list to contain a few false
positives. */ positives. */
if (b->kind == sk_namespace) if (b->kind == sk_namespace
if ((VAR_P (decl) && ((VAR_P (decl)
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
|| (TREE_CODE (decl) == FUNCTION_DECL || (TREE_CODE (decl) == FUNCTION_DECL
&& (!TREE_PUBLIC (decl) && (!TREE_PUBLIC (decl)
|| decl_anon_ns_mem_p (decl) || decl_anon_ns_mem_p (decl)
|| DECL_DECLARED_INLINE_P (decl)))) || DECL_DECLARED_INLINE_P (decl)))))
vec_safe_push (static_decls, decl); vec_safe_push (static_decls, decl);
}
} }
/* Find the binding for NAME in the local binding level B. */ /* Find the binding for NAME in the local binding level B. */
...@@ -4708,70 +4698,74 @@ suggest_alternatives_for (location_t location, tree name, ...@@ -4708,70 +4698,74 @@ suggest_alternatives_for (location_t location, tree name,
bool suggest_misspellings) bool suggest_misspellings)
{ {
vec<tree> candidates = vNULL; vec<tree> candidates = vNULL;
vec<tree> namespaces_to_search = vNULL; vec<tree> worklist = vNULL;
int max_to_search = PARAM_VALUE (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP); unsigned limit = PARAM_VALUE (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP);
int n_searched = 0; bool limited = false;
tree t;
unsigned ix;
namespaces_to_search.safe_push (global_namespace);
while (!namespaces_to_search.is_empty () /* Breadth-first search of namespaces. Up to limit namespaces
&& n_searched < max_to_search) searched (limit zero == unlimited). */
worklist.safe_push (global_namespace);
for (unsigned ix = 0; ix != worklist.length (); ix++)
{ {
tree scope = namespaces_to_search.pop (); tree ns = worklist[ix];
name_lookup lookup (name, 0);
cp_binding_level *level = NAMESPACE_LEVEL (scope);
n_searched++; if (tree value = ovl_skip_hidden (find_namespace_value (ns, name)))
candidates.safe_push (value);
/* Look in this namespace. */ if (!limited)
if (qualified_namespace_lookup (scope, &lookup)) {
candidates.safe_push (lookup.value); /* Look for child namespaces. We have to do this
indirectly because they are chained in reverse order,
/* Add child namespaces. */ which is confusing to the user. */
for (t = level->namespaces; t; t = DECL_CHAIN (t)) vec<tree> children = vNULL;
namespaces_to_search.safe_push (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
&& !namespaces_to_search.is_empty ())
inform (location,
"maximum limit of %d namespaces searched for %qE",
max_to_search, name);
namespaces_to_search.release (); for (tree decl = NAMESPACE_LEVEL (ns)->names;
decl; decl = TREE_CHAIN (decl))
if (TREE_CODE (decl) == NAMESPACE_DECL
&& !DECL_NAMESPACE_ALIAS (decl))
children.safe_push (decl);
/* Nothing useful to report for NAME. Report on likely misspellings, while (!limited && !children.is_empty ())
or do nothing. */
if (candidates.is_empty ())
{ {
if (suggest_misspellings) if (worklist.length () == limit)
{
const char *fuzzy_name = lookup_name_fuzzy (name, FUZZY_LOOKUP_NAME);
if (fuzzy_name)
{ {
gcc_rich_location richloc (location); /* Unconditionally warn that the search was truncated. */
richloc.add_fixit_replace (fuzzy_name); inform (location,
inform_at_rich_loc (&richloc, "suggested alternative: %qs", "maximum limit of %d namespaces searched for %qE",
fuzzy_name); limit, name);
limited = true;
} }
else
worklist.safe_push (children.pop ());
} }
return; children.release ();
} }
}
worklist.release ();
if (candidates.length ())
{
inform_n (location, candidates.length (), inform_n (location, candidates.length (),
"suggested alternative:", "suggested alternative:",
"suggested alternatives:"); "suggested alternatives:");
for (unsigned ix = 0; ix != candidates.length (); ix++)
{
tree val = candidates[ix];
FOR_EACH_VEC_ELT (candidates, ix, t) inform (location_of (val), " %qE", val);
inform (location_of (t), " %qE", t); }
candidates.release (); candidates.release ();
}
else if (!suggest_misspellings)
;
else if (const char *fuzzy = lookup_name_fuzzy (name, FUZZY_LOOKUP_NAME))
{
/* Show a spelling correction. */
gcc_rich_location richloc (location);
richloc.add_fixit_replace (fuzzy);
inform_at_rich_loc (&richloc, "suggested alternative: %qs", fuzzy);
}
} }
/* Subroutine of maybe_suggest_missing_header for handling unrecognized names /* Subroutine of maybe_suggest_missing_header for handling unrecognized names
......
...@@ -188,9 +188,6 @@ struct GTY(()) cp_binding_level { ...@@ -188,9 +188,6 @@ struct GTY(()) cp_binding_level {
are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */ are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */
tree names; tree names;
/* A chain of NAMESPACE_DECL nodes. */
tree namespaces;
/* A list of USING_DECL nodes. */ /* A list of USING_DECL nodes. */
tree usings; tree usings;
......
2017-06-02 Nathan Sidwell <nathan@acm.org>
* g++.dg/pr45330.C: Adjust. Check breadth-firstness.
2017-06-02 Jakub Jelinek <jakub@redhat.com> 2017-06-02 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/80903 PR rtl-optimization/80903
......
// { dg-do compile } // { dg-do compile }
// Search std, __cxxabiv1, and global namespaces, plus one more. // Search std, __cxxabiv1, and global namespaces, plus two more,
// { dg-options "--param cxx-max-namespaces-for-diagnostic-help=4" } // breadth first
#define NSPACE(NAME) namespace NAME { int foo; } // { dg-options "--param cxx-max-namespaces-for-diagnostic-help=5" }
// ::, std and __cxxabiv1
namespace A namespace A
{ {
int foo; // { dg-message "A::foo" "suggested alternative" } int foo; // { dg-message "A::foo" "suggested alternative" }
namespace A0
{
int foo; // not me
}
} }
namespace B namespace B
{ {
int foo; int foo; // { dg-message "B::foo" "suggested alternative" }
} }
namespace C namespace C
...@@ -32,6 +38,6 @@ namespace E ...@@ -32,6 +38,6 @@ namespace E
int bar() int bar()
{ {
return foo; // { dg-error "was not declared" } return foo; // { dg-error "was not declared" }
// { dg-message "maximum limit of 4 namespaces" "maximum limit" { target *-*-* } .-1 } // { dg-message "maximum limit of 5 namespaces" "maximum limit" { target *-*-* } .-1 }
// { dg-message "suggested alternative" "suggested alternative" { target *-*-* } .-2 } // { dg-message "suggested alternative" "suggested alternative" { target *-*-* } .-2 }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment