Commit 993acb36 by Nathan Froyd Committed by Nathan Froyd

re PR c++/45330 (Suggest likely nested-name-specifiers for undeclared identifiers.)

gcc/cp/
	PR c++/45330
	* cp-tree.h (suggest_alternatives_for): Add location_t parameter.
	* name-lookup.c (suggest_alternatives_for): Likewise.  Adjust.
	* lex.c (unqualified_name_lookup_error): Adjust call to it.
	* semantics.c (qualified_name_lookup_error): Move to...
	* error.c (qualified_name_lookup_error): ...here.  Call.
	suggest_alternatives_for.

gcc/testsuite/
	PR c++/45330
	* g++.dg/lookup/suggestions1.C: New test.

From-SVN: r167814
parent ec047df4
2010-12-14 Nathan Froyd <froydnj@codesourcery.com>
PR c++/45330
* cp-tree.h (suggest_alternatives_for): Add location_t parameter.
* name-lookup.c (suggest_alternatives_for): Likewise. Adjust.
* lex.c (unqualified_name_lookup_error): Adjust call to it.
* semantics.c (qualified_name_lookup_error): Move to...
* error.c (qualified_name_lookup_error): ...here. Call.
suggest_alternatives_for.
2010-12-13 Jason Merrill <jason@redhat.com> 2010-12-13 Jason Merrill <jason@redhat.com>
PR c++/46873 PR c++/46873
......
...@@ -4898,6 +4898,8 @@ extern void maybe_warn_variadic_templates (void); ...@@ -4898,6 +4898,8 @@ extern void maybe_warn_variadic_templates (void);
extern void maybe_warn_cpp0x (cpp0x_warn_str str); extern void maybe_warn_cpp0x (cpp0x_warn_str str);
extern bool pedwarn_cxx98 (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); extern bool pedwarn_cxx98 (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
extern location_t location_of (tree); extern location_t location_of (tree);
extern void qualified_name_lookup_error (tree, tree, tree,
location_t);
/* in except.c */ /* in except.c */
extern void init_exception_processing (void); extern void init_exception_processing (void);
...@@ -5286,8 +5288,6 @@ extern void finish_template_decl (tree); ...@@ -5286,8 +5288,6 @@ extern void finish_template_decl (tree);
extern tree finish_template_type (tree, tree, int); extern tree finish_template_type (tree, tree, int);
extern tree finish_base_specifier (tree, tree, bool); extern tree finish_base_specifier (tree, tree, bool);
extern void finish_member_declaration (tree); extern void finish_member_declaration (tree);
extern void qualified_name_lookup_error (tree, tree, tree,
location_t);
extern tree finish_id_expression (tree, tree, tree, extern tree finish_id_expression (tree, tree, tree,
cp_id_kind *, cp_id_kind *,
bool, bool, bool *, bool, bool, bool *,
...@@ -5631,7 +5631,7 @@ extern void cxx_omp_finish_clause (tree); ...@@ -5631,7 +5631,7 @@ extern void cxx_omp_finish_clause (tree);
extern bool cxx_omp_privatize_by_reference (const_tree); extern bool cxx_omp_privatize_by_reference (const_tree);
/* in name-lookup.c */ /* in name-lookup.c */
extern void suggest_alternatives_for (tree); extern void suggest_alternatives_for (location_t, tree);
/* -- end of C++ */ /* -- end of C++ */
......
...@@ -3167,3 +3167,39 @@ pedwarn_cxx98 (location_t location, int opt, const char *gmsgid, ...) ...@@ -3167,3 +3167,39 @@ pedwarn_cxx98 (location_t location, int opt, const char *gmsgid, ...)
va_end (ap); va_end (ap);
return report_diagnostic (&diagnostic); return report_diagnostic (&diagnostic);
} }
/* Issue a diagnostic that NAME cannot be found in SCOPE. DECL is what
we found when we tried to do the lookup. LOCATION is the location of
the NAME identifier. */
void
qualified_name_lookup_error (tree scope, tree name,
tree decl, location_t location)
{
if (scope == error_mark_node)
; /* We already complained. */
else if (TYPE_P (scope))
{
if (!COMPLETE_TYPE_P (scope))
error_at (location, "incomplete type %qT used in nested name specifier",
scope);
else if (TREE_CODE (decl) == TREE_LIST)
{
error_at (location, "reference to %<%T::%D%> is ambiguous",
scope, name);
print_candidates (decl);
}
else
error_at (location, "%qD is not a member of %qT", name, scope);
}
else if (scope != global_namespace)
{
error_at (location, "%qD is not a member of %qD", name, scope);
suggest_alternatives_for (location, name);
}
else
{
error_at (location, "%<::%D%> has not been declared", name);
suggest_alternatives_for (location, name);
}
}
...@@ -452,7 +452,7 @@ unqualified_name_lookup_error (tree name) ...@@ -452,7 +452,7 @@ unqualified_name_lookup_error (tree name)
if (!objc_diagnose_private_ivar (name)) 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); suggest_alternatives_for (location_of (name), name);
} }
/* Prevent repeated error messages by creating a VAR_DECL with /* Prevent repeated error messages by creating a VAR_DECL with
this NAME in the innermost block scope. */ this NAME in the innermost block scope. */
......
...@@ -3923,7 +3923,7 @@ remove_hidden_names (tree fns) ...@@ -3923,7 +3923,7 @@ remove_hidden_names (tree fns)
possible candidates. */ possible candidates. */
void void
suggest_alternatives_for (tree name) suggest_alternatives_for (location_t location, tree name)
{ {
VEC(tree,heap) *candidates = NULL; VEC(tree,heap) *candidates = NULL;
VEC(tree,heap) *namespaces_to_search = NULL; VEC(tree,heap) *namespaces_to_search = NULL;
...@@ -3931,7 +3931,6 @@ suggest_alternatives_for (tree name) ...@@ -3931,7 +3931,6 @@ suggest_alternatives_for (tree name)
int n_searched = 0; int n_searched = 0;
tree t; tree t;
unsigned ix; unsigned ix;
location_t name_location;
VEC_safe_push (tree, heap, namespaces_to_search, global_namespace); VEC_safe_push (tree, heap, namespaces_to_search, global_namespace);
...@@ -3955,15 +3954,13 @@ suggest_alternatives_for (tree name) ...@@ -3955,15 +3954,13 @@ suggest_alternatives_for (tree name)
VEC_safe_push (tree, heap, namespaces_to_search, 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 /* If we stopped before we could examine all namespaces, inform the
user. Do this even if we don't have any candidates, since there 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 might be more candidates further down that we weren't able to
find. */ find. */
if (n_searched >= max_to_search if (n_searched >= max_to_search
&& !VEC_empty (tree, namespaces_to_search)) && !VEC_empty (tree, namespaces_to_search))
inform (name_location, inform (location,
"maximum limit of %d namespaces searched for %qE", "maximum limit of %d namespaces searched for %qE",
max_to_search, name); max_to_search, name);
...@@ -3973,7 +3970,7 @@ suggest_alternatives_for (tree name) ...@@ -3973,7 +3970,7 @@ suggest_alternatives_for (tree name)
if (VEC_empty (tree, candidates)) if (VEC_empty (tree, candidates))
return; return;
inform_n (name_location, VEC_length (tree, candidates), inform_n (location, VEC_length (tree, candidates),
"suggested alternative:", "suggested alternative:",
"suggested alternatives:"); "suggested alternatives:");
......
...@@ -2646,37 +2646,6 @@ finish_base_specifier (tree base, tree access, bool virtual_p) ...@@ -2646,37 +2646,6 @@ finish_base_specifier (tree base, tree access, bool virtual_p)
return result; return result;
} }
/* Issue a diagnostic that NAME cannot be found in SCOPE. DECL is
what we found when we tried to do the lookup.
LOCATION is the location of the NAME identifier;
The location is used in the error message*/
void
qualified_name_lookup_error (tree scope, tree name,
tree decl, location_t location)
{
if (scope == error_mark_node)
; /* We already complained. */
else if (TYPE_P (scope))
{
if (!COMPLETE_TYPE_P (scope))
error_at (location, "incomplete type %qT used in nested name specifier",
scope);
else if (TREE_CODE (decl) == TREE_LIST)
{
error_at (location, "reference to %<%T::%D%> is ambiguous",
scope, name);
print_candidates (decl);
}
else
error_at (location, "%qD is not a member of %qT", name, scope);
}
else if (scope != global_namespace)
error_at (location, "%qD is not a member of %qD", name, scope);
else
error_at (location, "%<::%D%> has not been declared", name);
}
/* If FNS is a member function, a set of member functions, or a /* If FNS is a member function, a set of member functions, or a
template-id referring to one or more member functions, return a template-id referring to one or more member functions, return a
BASELINK for FNS, incorporating the current access context. BASELINK for FNS, incorporating the current access context.
......
2010-12-14 Nathan Froyd <froydnj@codesourcery.com>
PR c++/45330
* g++.dg/lookup/suggestions1.C: New test.
2010-12-14 Tobias Burnus <burnus@net-b.de> 2010-12-14 Tobias Burnus <burnus@net-b.de>
PR fortran/46937 PR fortran/46937
......
// { dg-do compile }
namespace N { namespace M { int foo; } } // { dg-message "N::M::foo" }
int f (void) { return N::foo; } // { dg-error "not a member" }
// { dg-message "suggested alternative" "missing namespace" { target *-*-* } 4 }
int g (void) { return ::foo; } // { dg-error "not been declared" }
// { dg-message "suggested alternative" "omitted namespace" { target *-*-* } 7 }
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