From: Douglas Gregor Date: Wed, 27 Apr 2011 03:47:06 +0000 (+0000) Subject: Improve diagnostics for typo correction via Sema::ClassifyName(), by X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=27766d2501259c7b12b1056e0c491a927b304e10;p=clang 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 6c25ddfca5..200082f17b 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -510,12 +510,29 @@ Corrected: // 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(FirstDecl)) { + UnqualifiedDiag = diag::err_no_template_suggest; + QualifiedDiag = diag::err_no_member_template_suggest; + } else if (FirstDecl && + (isa(FirstDecl) || + isa(FirstDecl) || + isa(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 @@ Corrected: 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 8a277c75f0..88d9dc62a1 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 @@ void test() { 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 d1e732fd1d..440db45518 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 class basic_string { // expected-note 2{{'basic_string' declared here}}