From f8ec8c9935acf77ff929b0aa51428d70c37c232a Mon Sep 17 00:00:00 2001 From: Kaelyn Uhrain Date: Fri, 13 Jan 2012 23:10:36 +0000 Subject: [PATCH] Convert SemaTemplate*.cpp to pass a callback object to CorrectTypo. The change to SemaTemplateVariadic.cpp improves the typo correction results in certain situations, while the change to SemaTemplate.cpp does not change existing behavior. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148155 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplate.cpp | 9 ++++++-- lib/Sema/SemaTemplateVariadic.cpp | 37 ++++++++++++++++++++----------- test/SemaCXX/typo-correction.cpp | 11 ++++++++- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 6c2a94aa9c..d8aab823f7 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -301,10 +301,15 @@ void Sema::LookupTemplateName(LookupResult &Found, // If we did not find any names, attempt to correct any typos. DeclarationName Name = Found.getLookupName(); Found.clear(); + // Simple filter callback that, for keywords, only accepts the C++ *_cast + CorrectionCandidateCallback FilterCCC; + FilterCCC.WantTypeSpecifiers = false; + FilterCCC.WantExpressionKeywords = false; + FilterCCC.WantRemainingKeywords = false; + FilterCCC.WantCXXNamedCasts = true; if (TypoCorrection Corrected = CorrectTypo(Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS, - LookupCtx, false, - CTC_CXXCasts)) { + &FilterCCC, LookupCtx)) { Found.setLookupName(Corrected.getCorrection()); if (Corrected.getCorrectionDecl()) Found.addDecl(Corrected.getCorrectionDecl()); diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index b219c20459..44242f1c13 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -708,6 +708,19 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) { return false; } +namespace { + +// Callback to only accept typo corrections that refer to parameter packs. +class ParameterPackValidatorCCC : public CorrectionCandidateCallback { + public: + virtual bool ValidateCandidate(const TypoCorrection &candidate) { + NamedDecl *ND = candidate.getCorrectionDecl(); + return ND && ND->isParameterPack(); + } +}; + +} + /// \brief Called when an expression computing the size of a parameter pack /// is parsed. /// @@ -733,6 +746,7 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, LookupName(R, S); NamedDecl *ParameterPack = 0; + ParameterPackValidatorCCC Validator; switch (R.getResultKind()) { case LookupResult::Found: ParameterPack = R.getFoundDecl(); @@ -741,19 +755,16 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, case LookupResult::NotFound: case LookupResult::NotFoundInCurrentInstantiation: if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(), - R.getLookupKind(), S, 0, 0, - false, CTC_NoKeywords)) { - if (NamedDecl *CorrectedResult = Corrected.getCorrectionDecl()) - if (CorrectedResult->isParameterPack()) { - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions())); - ParameterPack = CorrectedResult; - Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest) - << &Name << CorrectedQuotedStr - << FixItHint::CreateReplacement( - NameLoc, Corrected.getAsString(getLangOptions())); - Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here) - << CorrectedQuotedStr; - } + R.getLookupKind(), S, 0, + &Validator)) { + std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions())); + ParameterPack = Corrected.getCorrectionDecl(); + Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest) + << &Name << CorrectedQuotedStr + << FixItHint::CreateReplacement( + NameLoc, Corrected.getAsString(getLangOptions())); + Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here) + << CorrectedQuotedStr; } case LookupResult::FoundOverloaded: diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp index bc3433b598..618e30a25a 100644 --- a/test/SemaCXX/typo-correction.cpp +++ b/test/SemaCXX/typo-correction.cpp @@ -41,6 +41,8 @@ struct Derived : public BaseType { // expected-note {{base class 'BaseType' spec Derived() : basetype() {} // expected-error{{initializer 'basetype' does not name a non-static data member or base class; did you mean the base class 'BaseType'?}} }; +// Test the improvement from passing a callback object to CorrectTypo in +// the helper function LookupMemberExprInRecord. int get_type(struct Derived *st) { return st->Base_Type; // expected-error{{no member named 'Base_Type' in 'Derived'; did you mean 'base_type'?}} } @@ -64,10 +66,17 @@ struct st { }; st var = { .fielda = 0.0 }; // expected-error{{field designator 'fielda' does not refer to any field in type 'st'; did you mean 'FieldA'?}} -// Test the improvement from passing a callback object to CorrectTypo in +// Test the improvement from passing a callback object to CorrectTypo in // Sema::BuildCXXNestedNameSpecifier. typedef char* another_str; namespace AnotherStd { // expected-note{{'AnotherStd' declared here}} class string {}; } another_std::string str; // expected-error{{use of undeclared identifier 'another_std'; did you mean 'AnotherStd'?}} + +// Test the improvement from passing a callback object to CorrectTypo in +// Sema::ActOnSizeofParameterPackExpr. +char* TireNames; +template struct count { // expected-note{{parameter pack 'TypeNames' declared here}} + static const unsigned value = sizeof...(TyreNames); // expected-error{{'TyreNames' does not refer to the name of a parameter pack; did you mean 'TypeNames'?}} +}; -- 2.40.0