mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
643a9684fa
commit
c957e9c052
|
|
@ -1,3 +1,14 @@
|
||||||
|
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)
|
||||||
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)
|
||||||
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 decls from this namespace. This will skip
|
||||||
collect_ada_nodes (NAMESPACE_LEVEL (namespc)->names, source_file);
|
NAMESPACE_DECLs (both aliases and regular, it cannot tell). */
|
||||||
|
collect_ada_nodes (decl, source_file);
|
||||||
|
|
||||||
/* Collect siblings, if any */
|
/* Now scan for namespace children, and dump them. */
|
||||||
collect_ada_namespace (TREE_CHAIN (namespc), source_file);
|
for (; decl; decl = TREE_CHAIN (decl))
|
||||||
|
if (TREE_CODE (decl) == NAMESPACE_DECL && !DECL_NAMESPACE_ALIAS (decl))
|
||||||
/* Collect children, if any */
|
collect_ada_namespace (decl, source_file);
|
||||||
collect_ada_namespace (NAMESPACE_LEVEL (namespc)->namespaces, 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,38 +115,28 @@ 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))
|
/* Make sure we don't create a circular list. xref_tag can end
|
||||||
{
|
up pushing the same artificial decl more than once. We
|
||||||
/* Inner namespaces get their own chain, to make walking
|
should have already detected that in update_binding. */
|
||||||
simpler. */
|
gcc_assert (b->names != decl);
|
||||||
DECL_CHAIN (decl) = b->namespaces;
|
|
||||||
b->namespaces = decl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Make sure we don't create a circular list. xref_tag can end
|
|
||||||
up pushing the same artificial decl more than once. We
|
|
||||||
should have already detected that in update_binding. */
|
|
||||||
gcc_assert (b->names != decl);
|
|
||||||
|
|
||||||
/* We build up the list in reverse order, and reverse it later if
|
/* We build up the list in reverse order, and reverse it later if
|
||||||
necessary. */
|
necessary. */
|
||||||
TREE_CHAIN (decl) = b->names;
|
TREE_CHAIN (decl) = b->names;
|
||||||
b->names = decl;
|
b->names = decl;
|
||||||
|
|
||||||
/* If appropriate, add decl to separate list of statics. We
|
/* If appropriate, add decl to separate list of statics. We
|
||||||
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,
|
||||||
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);
|
/* Breadth-first search of namespaces. Up to limit namespaces
|
||||||
|
searched (limit zero == unlimited). */
|
||||||
while (!namespaces_to_search.is_empty ()
|
worklist.safe_push (global_namespace);
|
||||||
&& n_searched < max_to_search)
|
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);
|
|
||||||
|
|
||||||
/* Add child namespaces. */
|
|
||||||
for (t = level->namespaces; t; t = DECL_CHAIN (t))
|
|
||||||
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 ();
|
|
||||||
|
|
||||||
/* Nothing useful to report for NAME. Report on likely misspellings,
|
|
||||||
or do nothing. */
|
|
||||||
if (candidates.is_empty ())
|
|
||||||
{
|
|
||||||
if (suggest_misspellings)
|
|
||||||
{
|
{
|
||||||
const char *fuzzy_name = lookup_name_fuzzy (name, FUZZY_LOOKUP_NAME);
|
/* Look for child namespaces. We have to do this
|
||||||
if (fuzzy_name)
|
indirectly because they are chained in reverse order,
|
||||||
|
which is confusing to the user. */
|
||||||
|
vec<tree> children = vNULL;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
while (!limited && !children.is_empty ())
|
||||||
{
|
{
|
||||||
gcc_rich_location richloc (location);
|
if (worklist.length () == limit)
|
||||||
richloc.add_fixit_replace (fuzzy_name);
|
{
|
||||||
inform_at_rich_loc (&richloc, "suggested alternative: %qs",
|
/* Unconditionally warn that the search was truncated. */
|
||||||
fuzzy_name);
|
inform (location,
|
||||||
|
"maximum limit of %d namespaces searched for %qE",
|
||||||
|
limit, name);
|
||||||
|
limited = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
worklist.safe_push (children.pop ());
|
||||||
}
|
}
|
||||||
|
children.release ();
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
worklist.release ();
|
||||||
|
|
||||||
inform_n (location, candidates.length (),
|
if (candidates.length ())
|
||||||
"suggested alternative:",
|
{
|
||||||
"suggested alternatives:");
|
inform_n (location, candidates.length (),
|
||||||
|
"suggested alternative:",
|
||||||
|
"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 ();
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
candidates.release ();
|
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 {
|
||||||
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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
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
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,23 @@
|
||||||
// { 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
|
||||||
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 }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue