From: Kaelyn Uhrain Date: Wed, 3 Apr 2013 16:59:49 +0000 (+0000) Subject: Give the default CorrectionCandidateCallback::ValidateCandidate some X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=20a7cf4d782e32b2752e651a11ed3712d2debd65;p=clang Give the default CorrectionCandidateCallback::ValidateCandidate some smarts so that it doesn't approve of keywords and/or type names when it knows (based on its flags) that those kinds of corrections are not wanted. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178668 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h index 0b897b55cc..cdd71c8fa9 100644 --- a/include/clang/Sema/TypoCorrection.h +++ b/include/clang/Sema/TypoCorrection.h @@ -228,9 +228,11 @@ class CorrectionCandidateCallback { /// candidate is viable, without ranking potentially viable candidates. /// Only ValidateCandidate or RankCandidate need to be overriden by a /// callback wishing to check the viability of correction candidates. - virtual bool ValidateCandidate(const TypoCorrection &candidate) { - return true; - } + /// The default predicate always returns true if the candidate is not a type + /// name or keyword, true for types if WantTypeSpecifiers is true, and true + /// for keywords if WantTypeSpecifiers, WantExpressionKeywords, + /// WantCXXNamedCasts, WantRemainingKeywords, or WantObjCSuper is true. + virtual bool ValidateCandidate(const TypoCorrection &candidate); /// \brief Method used by Sema::CorrectTypo to assign an "edit distance" rank /// to a candidate (where a lower value represents a better candidate), or diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp index fe602f6b65..5e0ef2b83f 100644 --- a/lib/Parse/ParseTentative.cpp +++ b/lib/Parse/ParseTentative.cpp @@ -999,6 +999,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult, // to types and identifiers, in order to try to recover from errors. CorrectionCandidateCallback TypoCorrection; TypoCorrection.WantRemainingKeywords = false; + TypoCorrection.WantTypeSpecifiers = Next.isNot(tok::arrow); switch (TryAnnotateName(false /* no nested name specifier */, &TypoCorrection)) { case ANK_Error: diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 0fe3db1901..2b3ca3f0ef 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -4139,3 +4139,21 @@ std::string TypoCorrection::getAsString(const LangOptions &LO) const { return CorrectionName.getAsString(); } + +bool CorrectionCandidateCallback::ValidateCandidate(const TypoCorrection &candidate) { + if (!candidate.isResolved()) + return true; + + if (candidate.isKeyword()) + return WantTypeSpecifiers || WantExpressionKeywords || WantCXXNamedCasts || + WantRemainingKeywords || WantObjCSuper; + + for (TypoCorrection::const_decl_iterator CDecl = candidate.begin(), + CDeclEnd = candidate.end(); + CDecl != CDeclEnd; ++CDecl) { + if (!isa(*CDecl)) + return true; + } + + return WantTypeSpecifiers; +} diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp index 4a3f0f6b29..caa6355fe9 100644 --- a/test/SemaCXX/typo-correction.cpp +++ b/test/SemaCXX/typo-correction.cpp @@ -250,3 +250,13 @@ void f(B &x) { x.Createfoo(0,0); // expected-error {{no member named 'Createfoo' in 'PR13387::B'; did you mean 'CreateFoo'?}} } } + +struct DataStruct {void foo();}; +struct T { + DataStruct data_struct; + void f(); +}; +// should be void T::f(); +void f() { + data_struct->foo(); // expected-error-re{{use of undeclared identifier 'data_struct'$}} +}