aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaelyn Uhrain <rikka@google.com>2012-01-13 21:28:55 +0000
committerKaelyn Uhrain <rikka@google.com>2012-01-13 21:28:55 +0000
commite4c7f90da208ed2caeab784b32f416a50eed8da3 (patch)
tree8346b0b73153434caf5fcc8976a3a5d4e51cb81c
parent43115d4904431917ef6852ee089a8520b9940ba5 (diff)
Convert SemaExprMember.cpp to pass a callback object to CorrectTypo,
improving the typo correction results in certain situations. This is also the first typo correction callback conversion to affect an existing unit test. :) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148140 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaExprMember.cpp35
-rw-r--r--test/SemaCXX/member-expr.cpp4
-rw-r--r--test/SemaCXX/typo-correction.cpp6
3 files changed, 30 insertions, 15 deletions
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index 478b2dd436..0080156376 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -509,6 +509,20 @@ bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr,
return true;
}
+namespace {
+
+// Callback to only accept typo corrections that are either a ValueDecl or a
+// FunctionTemplateDecl.
+class RecordMemberExprValidatorCCC : public CorrectionCandidateCallback {
+ public:
+ virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+ NamedDecl *ND = candidate.getCorrectionDecl();
+ return ND && (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND));
+ }
+};
+
+}
+
static bool
LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
SourceRange BaseRange, const RecordType *RTy,
@@ -559,13 +573,12 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
// We didn't find anything with the given name, so try to correct
// for typos.
DeclarationName Name = R.getLookupName();
+ RecordMemberExprValidatorCCC Validator;
TypoCorrection Corrected = SemaRef.CorrectTypo(R.getLookupNameInfo(),
R.getLookupKind(), NULL,
- &SS, DC, false,
- Sema::CTC_MemberLookup);
- NamedDecl *ND = Corrected.getCorrectionDecl();
+ &SS, &Validator, DC);
R.clear();
- if (ND && (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND))) {
+ if (NamedDecl *ND = Corrected.getCorrectionDecl()) {
std::string CorrectedStr(
Corrected.getAsString(SemaRef.getLangOptions()));
std::string CorrectedQuotedStr(
@@ -1094,12 +1107,12 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
if (!IV) {
// Attempt to correct for typos in ivar names.
- LookupResult Res(*this, R.getLookupName(), R.getNameLoc(),
- LookupMemberName);
- TypoCorrection Corrected = CorrectTypo(
- R.getLookupNameInfo(), LookupMemberName, NULL, NULL, IDecl, false,
- IsArrow ? CTC_ObjCIvarLookup : CTC_ObjCPropertyLookup);
- if ((IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>())) {
+ DeclFilterCCC<ObjCIvarDecl> Validator;
+ Validator.IsObjCIvarLookup = IsArrow;
+ if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(),
+ LookupMemberName, NULL, NULL,
+ &Validator, IDecl)) {
+ IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>();
Diag(R.getNameLoc(),
diag::err_typecheck_member_reference_ivar_suggest)
<< IDecl->getDeclName() << MemberName << IV->getDeclName()
@@ -1115,8 +1128,6 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
<< FixItHint::CreateReplacement(OpLoc, ".");
return ExprError();
}
- Res.clear();
- Res.setLookupName(Member);
Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
<< IDecl->getDeclName() << MemberName
diff --git a/test/SemaCXX/member-expr.cpp b/test/SemaCXX/member-expr.cpp
index db5a051826..dbddd1c2e3 100644
--- a/test/SemaCXX/member-expr.cpp
+++ b/test/SemaCXX/member-expr.cpp
@@ -94,11 +94,11 @@ namespace test5 {
namespace PR7508 {
struct A {
struct CleanupScope {};
- void PopCleanupBlock();
+ void PopCleanupBlock(); // expected-note{{'PopCleanupBlock' declared here}}
};
void foo(A &a) {
- a.PopCleanupScope(); // expected-error{{no member named 'PopCleanupScope' in 'PR7508::A'}}
+ a.PopCleanupScope(); // expected-error{{no member named 'PopCleanupScope' in 'PR7508::A'; did you mean 'PopCleanupBlock'?}}
}
}
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index a4cbbb85e6..bc3433b598 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -37,10 +37,14 @@ inline error_condition make_error_condition(errc _e) {
// refer to a base class or non-static data member.
struct BaseType { };
struct Derived : public BaseType { // expected-note {{base class 'BaseType' specified here}}
- static int base_type;
+ static int base_type; // expected-note {{'base_type' declared here}}
Derived() : basetype() {} // expected-error{{initializer 'basetype' does not name a non-static data member or base class; did you mean the base class 'BaseType'?}}
};
+int get_type(struct Derived *st) {
+ return st->Base_Type; // expected-error{{no member named 'Base_Type' in 'Derived'; did you mean 'base_type'?}}
+}
+
// In this example, somename should not be corrected to the cached correction
// "some_name" since "some_name" is a class and a namespace name is needed.
class some_name {}; // expected-note {{'some_name' declared here}}