aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Sema/TypoCorrection.h8
-rw-r--r--lib/Parse/ParseTentative.cpp1
-rw-r--r--lib/Sema/SemaLookup.cpp18
-rw-r--r--test/SemaCXX/typo-correction.cpp10
4 files changed, 34 insertions, 3 deletions
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<TypeDecl>(*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'$}}
+}