Improve diagnostics for typo correction via Sema::ClassifyName(), by
looking at the context and the correction and using a custom
diagnostic. Also, enable some Fix-It tests that were somewhat lamely
disabled.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130283 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 6c25ddf..200082f 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -510,12 +510,29 @@
// close to this name.
if (!SecondTry) {
if (DeclarationName Corrected = CorrectTypo(Result, S, &SS)) {
+ unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest;
+ unsigned QualifiedDiag = diag::err_no_member_suggest;
+
+ NamedDecl *FirstDecl = Result.empty()? 0 : *Result.begin();
+
+ if (getLangOptions().CPlusPlus && NextToken.is(tok::less) &&
+ FirstDecl && isa<TemplateDecl>(FirstDecl)) {
+ UnqualifiedDiag = diag::err_no_template_suggest;
+ QualifiedDiag = diag::err_no_member_template_suggest;
+ } else if (FirstDecl &&
+ (isa<TypeDecl>(FirstDecl) ||
+ isa<ObjCInterfaceDecl>(FirstDecl) ||
+ isa<ObjCCompatibleAliasDecl>(FirstDecl))) {
+ UnqualifiedDiag = diag::err_unknown_typename_suggest;
+ QualifiedDiag = diag::err_unknown_nested_typename_suggest;
+ }
+
if (SS.isEmpty())
- Diag(NameLoc, diag::err_undeclared_var_use_suggest)
+ Diag(NameLoc, UnqualifiedDiag)
<< Name << Corrected
<< FixItHint::CreateReplacement(NameLoc, Corrected.getAsString());
else
- Diag(NameLoc, diag::err_no_member_suggest)
+ Diag(NameLoc, QualifiedDiag)
<< Name << computeDeclContext(SS, false) << Corrected
<< SS.getRange()
<< FixItHint::CreateReplacement(NameLoc, Corrected.getAsString());
@@ -527,7 +544,6 @@
if (Result.empty())
return Corrected.getAsIdentifierInfo();
- NamedDecl *FirstDecl = *Result.begin();
Diag(FirstDecl->getLocation(), diag::note_previous_decl)
<< FirstDecl->getDeclName();
diff --git a/test/FixIt/typo.c b/test/FixIt/typo.c
index 8a277c7..88d9dc6 100644
--- a/test/FixIt/typo.c
+++ b/test/FixIt/typo.c
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: cp %s %t
-// RUN: %clang_cc1 -fsyntax-only -fixit -x c %t || true
+// RUN: not %clang_cc1 -fsyntax-only -fixit -x c %t
// RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -x c %t
// RUN: grep "Rectangle" %t
struct Point {
@@ -30,7 +30,7 @@
r1.top_left.x = 0;
typedef struct Rectangle Rectangle; // expected-note{{'Rectangle' declared here}}
- rectangle *r2 = &r1; // expected-error{{use of undeclared identifier 'rectangle'; did you mean 'Rectangle'?}}
+ rectangle *r2 = &r1; // expected-error{{ unknown type name 'rectangle'; did you mean 'Rectangle'?}}
r2->top_left.y = 0;
unsinged *ptr = 0; // expected-error{{use of undeclared identifier 'unsinged'; did you mean 'unsigned'?}}
*ptr = 17;
diff --git a/test/FixIt/typo.cpp b/test/FixIt/typo.cpp
index d1e732f..440db45 100644
--- a/test/FixIt/typo.cpp
+++ b/test/FixIt/typo.cpp
@@ -1,7 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: cp %s %t
-// RUN: %clang_cc1 -fsyntax-only -fixit -x c++ %t || true
+// RUN: not %clang_cc1 -fsyntax-only -fixit -x c++ %t
// RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -x c++ %t
+// RUN: grep test_string %t
namespace std {
template<typename T> class basic_string { // expected-note 2{{'basic_string' declared here}}