From c1fb54265614845ee1e09856af6e46961c6209f4 Mon Sep 17 00:00:00 2001 From: Kaelyn Uhrain Date: Fri, 22 Jun 2012 23:37:05 +0000 Subject: [PATCH] Perform typo correction for base class specifiers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159046 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Parse/ParseDeclCXX.cpp | 4 +++- lib/Sema/SemaDecl.cpp | 12 +++++++----- test/SemaCXX/typo-correction.cpp | 8 ++++++++ 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 16429ab6dd..3a4c7feefc 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -5550,6 +5550,8 @@ def warn_missing_method_return_type : Warning< InGroup, DefaultIgnore; // Spell-checking diagnostics +def err_unknown_type_or_class_name_suggest : Error< + "unknown %select{type|class}2 name %0; did you mean %1?">; def err_unknown_typename_suggest : Error< "unknown type name %0; did you mean %1?">; def err_unknown_nested_typename_suggest : Error< diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 6e391c9022..67d1f2c9e1 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -874,10 +874,12 @@ Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc, } // We have an identifier; check whether it is actually a type. + IdentifierInfo *CorrectedII = 0; ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true, false, ParsedType(), /*IsCtorOrDtorName=*/false, - /*NonTrivialTypeSourceInfo=*/true); + /*NonTrivialTypeSourceInfo=*/true, + &CorrectedII); if (!Type) { Diag(IdLoc, diag::err_expected_class_name); return true; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index bee6557c2f..1b0a0abdb2 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -60,7 +60,8 @@ namespace { class TypeNameValidatorCCC : public CorrectionCandidateCallback { public: - TypeNameValidatorCCC(bool AllowInvalid) : AllowInvalidDecl(AllowInvalid) { + TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false) + : AllowInvalidDecl(AllowInvalid), WantClassName(WantClass) { WantExpressionKeywords = false; WantCXXNamedCasts = false; WantRemainingKeywords = false; @@ -71,11 +72,12 @@ class TypeNameValidatorCCC : public CorrectionCandidateCallback { return (isa(ND) || isa(ND)) && (AllowInvalidDecl || !ND->isInvalidDecl()); else - return candidate.isKeyword(); + return !WantClassName && candidate.isKeyword(); } private: bool AllowInvalidDecl; + bool WantClassName; }; } @@ -209,7 +211,7 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, case LookupResult::NotFound: case LookupResult::NotFoundInCurrentInstantiation: if (CorrectedII) { - TypeNameValidatorCCC Validator(true); + TypeNameValidatorCCC Validator(true, isClassName); TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(), Kind, S, SS, Validator); IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo(); @@ -238,8 +240,8 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, std::string CorrectedStr(Correction.getAsString(getLangOpts())); std::string CorrectedQuotedStr( Correction.getQuoted(getLangOpts())); - Diag(NameLoc, diag::err_unknown_typename_suggest) - << Result.getLookupName() << CorrectedQuotedStr + Diag(NameLoc, diag::err_unknown_type_or_class_name_suggest) + << Result.getLookupName() << CorrectedQuotedStr << isClassName << FixItHint::CreateReplacement(SourceRange(NameLoc), CorrectedStr); if (NamedDecl *FirstDecl = Correction.getCorrectionDecl()) diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp index 90fdb221f9..77fca74440 100644 --- a/test/SemaCXX/typo-correction.cpp +++ b/test/SemaCXX/typo-correction.cpp @@ -219,3 +219,11 @@ namespace PR13051 { f(&S::foo); // expected-error-re{{no member named 'foo' in 'PR13051::S'$}} } } + +namespace PR6325 { +class foo { }; // expected-note{{'foo' declared here}} +// Note that for this example (pulled from the PR), if keywords are not excluded +// as correction candidates then no suggestion would be given; correcting +// 'boo' to 'bool' is the same edit distance as correcting 'boo' to 'foo'. +class bar : boo { }; // expected-error{{unknown class name 'boo'; did you mean 'foo'?}} +} -- 2.40.0