diff options
author | Nathan Froyd <froydnj@codesourcery.com> | 2010-12-07 13:46:29 +0000 |
---|---|---|
committer | Nathan Froyd <froydnj@gcc.gnu.org> | 2010-12-07 13:46:29 +0000 |
commit | 501c95ff0546ff1d2632017c6f66fc0cd83566f7 (patch) | |
tree | fe63f288d7fac2d1492b5370bcf38c201cc58251 /gcc/cp | |
parent | 85a47bed9340d25f861b9e2a186a4d443660cc26 (diff) | |
download | gcc-501c95ff0546ff1d2632017c6f66fc0cd83566f7.zip gcc-501c95ff0546ff1d2632017c6f66fc0cd83566f7.tar.gz gcc-501c95ff0546ff1d2632017c6f66fc0cd83566f7.tar.bz2 |
re PR c++/45330 (Suggest likely nested-name-specifiers for undeclared identifiers.)
gcc/
PR c++/45330
* params.def (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP): New parameter.
* doc/invoke.texi (cxx-max-namespaces-for-diagnostic-help): Document.
gcc/cp/
PR c++/45330
* cp-tree.h (suggest_alternatives_for, location_of): Declare.
* error.c (dump_expr): Handle TYPE_DECL.
(location_of): Unstaticize.
* name-lookup.c (suggest_alternatives_for): New function.
* lex.c (unqualified_name_lookup_error): Call it.
gcc/testsuite/
PR c++/45330
* g++.dg/pr45330.C: New test.
* g++.dg/ext/builtin3.C: Adjust.
* g++.dg/lookup/error1.C: Adjust.
* g++.dg/lookup/koenig5.C: Adjust.
* g++.dg/overload/koenig1.C: Adjust.
* g++.dg/parse/decl-specifier-1.C: Adjust.
* g++.dg/template/static10.C: Adjust.
* g++.old-deja/g++.mike/ns5.C: Adjust.
* g++.old-deja/g++.mike/ns7.C: Adjust.
* g++.old-deja/g++.ns/koenig5.C: Adjust.
* g++.old-deja/g++.ns/koenig9.C: Adjust.
* g++.old-deja/g++.other/lineno5.C: Adjust.
From-SVN: r167536
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/error.c | 4 | ||||
-rw-r--r-- | gcc/cp/lex.c | 5 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 67 |
5 files changed, 86 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ef506d1..2bbd7e4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2010-12-07 Nathan Froyd <froydnj@codesourcery.com> + + PR c++/45330 + * cp-tree.h (suggest_alternatives_for, location_of): Declare. + * error.c (dump_expr): Handle TYPE_DECL. + (location_of): Unstaticize. + * name-lookup.c (suggest_alternatives_for): New function. + * lex.c (unqualified_name_lookup_error): Call it. + 2010-12-06 Nicola Pero <nicola.pero@meta-innovation.com> * call.c: Include c-family/c-objc.h. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 59342e3..aba8dfd 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4907,6 +4907,7 @@ extern void print_instantiation_context (void); extern void maybe_warn_variadic_templates (void); extern void maybe_warn_cpp0x (cpp0x_warn_str str); extern bool pedwarn_cxx98 (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); +extern location_t location_of (tree); /* in except.c */ extern void init_exception_processing (void); @@ -5639,6 +5640,9 @@ extern tree cxx_omp_clause_dtor (tree, tree); extern void cxx_omp_finish_clause (tree); extern bool cxx_omp_privatize_by_reference (const_tree); +/* in name-lookup.c */ +extern void suggest_alternatives_for (tree); + /* -- end of C++ */ #endif /* ! GCC_CP_TREE_H */ diff --git a/gcc/cp/error.c b/gcc/cp/error.c index ed168c4..4fb47dc 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -98,7 +98,6 @@ static void cp_print_error_function (diagnostic_context *, diagnostic_info *); static bool cp_printer (pretty_printer *, text_info *, const char *, int, bool, bool, bool); -static location_t location_of (tree); void init_error (void) @@ -1700,6 +1699,7 @@ dump_expr (tree t, int flags) case NAMESPACE_DECL: case LABEL_DECL: case OVERLOAD: + case TYPE_DECL: case IDENTIFIER_NODE: dump_decl (t, (flags & ~TFF_DECL_SPECIFIERS) | TFF_NO_FUNCTION_ARGUMENTS); break; @@ -2487,7 +2487,7 @@ lang_decl_name (tree decl, int v, bool translate) /* Return the location of a tree passed to %+ formats. */ -static location_t +location_t location_of (tree t) { if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t)) diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 684803f..5a2ae41 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -450,7 +450,10 @@ unqualified_name_lookup_error (tree name) else { if (!objc_diagnose_private_ivar (name)) - error ("%qD was not declared in this scope", name); + { + error ("%qD was not declared in this scope", name); + suggest_alternatives_for (name); + } /* Prevent repeated error messages by creating a VAR_DECL with this NAME in the innermost block scope. */ if (current_function_decl) diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 3d19c08..4cf1380 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -29,8 +29,10 @@ along with GCC; see the file COPYING3. If not see #include "name-lookup.h" #include "timevar.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. */ @@ -3916,6 +3918,71 @@ remove_hidden_names (tree fns) 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 (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; + location_t name_location; + + 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); + } + + name_location = location_of (name); + + /* 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 (name_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 (name_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. */ |