@@ -5639,6 +5639,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 */
@@ -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)
@@ -1700,6 +1700,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;
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "timevar.h"
#include "toplev.h"
#include "diagnostic-core.h"
+#include "intl.h"
#include "debug.h"
#include "c-family/c-pragma.h"
@@ -3919,6 +3920,62 @@ remove_hidden_names (tree fns)
return fns;
}
+/* Helper function for suggest_alternatives_for: lookup NAME in
+ namespace SCOPE and record any matches in CANDIDATES. */
+
+static VEC(tree,heap) *
+suggest_alternatives_for_1 (tree name, tree scope,
+ VEC(tree,heap) *candidates)
+{
+ struct scope_binding binding = EMPTY_SCOPE_BINDING;
+ struct cp_binding_level *level = NAMESPACE_LEVEL (scope);
+ tree t;
+
+ /* Look in this namespace. */
+ qualified_lookup_using_namespace (name, scope, &binding, 0);
+
+ if (binding.value)
+ VEC_safe_push (tree, heap, candidates, binding.value);
+
+ /* Lookup in child namespaces. */
+ for (t = level->namespaces; t; t = DECL_CHAIN (t))
+ candidates = suggest_alternatives_for_1 (name, t, candidates);
+
+ return candidates;
+}
+
+/* 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
+ = suggest_alternatives_for_1 (name, global_namespace, NULL);
+ const char *str;
+ char *spaces;
+ tree t;
+ unsigned ix;
+
+ /* Nothing useful to report. */
+ if (VEC_empty (tree, candidates))
+ return;
+
+ str = (VEC_length(tree, candidates) > 1
+ ? _("suggested alternatives:")
+ : _("suggested alternative:"));
+ spaces = NULL;
+
+ FOR_EACH_VEC_ELT (tree, candidates, ix, t)
+ {
+ inform (input_location, "%s %qE", (spaces ? spaces : str), t);
+ spaces = spaces ? spaces : get_spaces (str);
+ }
+
+ VEC_free (tree, heap, candidates);
+}
+
/* Unscoped lookup of a global: iterate over current namespaces,
considering using-directives. */
@@ -10,4 +10,5 @@ extern "C" int printf(char*, ...);
void foo() {
printf("abc"); // { dg-error "not declared" }
+ // { dg-message "note" "suggested alternative" { target *-*-* } 12 }
}
@@ -4,6 +4,7 @@
namespace N { int i; }
void foo() { i; } // { dg-error "not declared" }
+ // { dg-message "note" "suggested alternative" { target *-*-* } 6 }
using namespace N;
void bar() { i; }
@@ -32,10 +32,12 @@ void g (N::A *a, M::B *b, O::C *c)
One (a); // ok
One (a, b); // ok
One (b); // { dg-error "not declared" }
+ // { dg-message "note" "suggested alternative" { target *-*-* } 34 }
Two (c); // ok
Two (a, c); // ok
Two (a); // { dg-error "not declared" }
+ // { dg-message "note" "suggested alternative" { target *-*-* } 39 }
Two (a, a); // error masked by earlier error
Two (b); // error masked by earlier error
Two (a, b); // error masked by earlier error
@@ -43,4 +45,5 @@ void g (N::A *a, M::B *b, O::C *c)
Three (b); // ok
Three (a, b); // ok
Three (a); // { dg-error "not declared" }
+ // { dg-message "note" "suggested alternative" { target *-*-* } 47 }
}
@@ -14,5 +14,6 @@ void g ()
B *bp;
N::A *ap;
f (bp); // { dg-error "not declared" }
+ // { dg-message "note" "suggested alternative" { target *-*-* } 16 }
f (ap);
}
@@ -13,4 +13,5 @@ N::X X; // { dg-error "" "" }
int main()
{
return sizeof(X); // { dg-error "" "" }
+ // { dg-message "note" "suggested alternative" { target *-*-* } 15 }
}
@@ -20,4 +20,5 @@ namespace std
{
template<> void
vector<int, allocator<int> >::swap(vector<int, allocator<int> >&) { } // { dg-error "" }
+ // { dg-message "note" "suggested alternative" { target *-*-* } 22 }
}
@@ -4,3 +4,4 @@ namespace A {
}
int j = i; // { dg-error "" }
+ // { dg-message "note" "suggested alternative" { target *-*-* } 6 }
@@ -6,4 +6,5 @@ namespace A {
namespace B {
int j = i; // { dg-error "" }
+ // { dg-message "note" "suggested alternative" { target *-*-* } 8 }
}
@@ -15,4 +15,5 @@ void g()
// foo variable first, and therefore do not
// perform argument-dependent lookup.
bar(new X); // { dg-error "not declared" }
+ // { dg-message "note" "suggested alternative" { target *-*-* } 17 }
}
@@ -10,4 +10,5 @@ void foo(const char*,...);
inline void
bar() {
foo("",count); // { dg-error "" } multiple overloaded count functions
+ // { dg-message "note" "suggested alternative" { target *-*-* } 12 }
}
@@ -16,4 +16,5 @@ namespace tmp {
class A {
public:
int kaka(tmp::B = b); // { dg-error "" } no b in scope
+ // { dg-message "note" "suggested alternative" { target *-*-* } 18 }
};