forked from OSchip/llvm-project
Fix handling of property and ivar lookup in typo correction; the two
kinds of lookup into Objective-C classes were tangled together, a situation that was compounded by automatically synthesized ivars. llvm-svn: 116907
This commit is contained in:
parent
274a70ed7f
commit
d507d77432
|
@ -1310,6 +1310,10 @@ public:
|
|||
CTC_CXXCasts,
|
||||
/// \brief A member lookup context.
|
||||
CTC_MemberLookup,
|
||||
/// \brief An Objective-C ivar lookup context (e.g., self->ivar).
|
||||
CTC_ObjCIvarLookup,
|
||||
/// \brief An Objective-C property lookup context (e.g., self.prop).
|
||||
CTC_ObjCPropertyLookup,
|
||||
/// \brief The receiver of an Objective-C message send within an
|
||||
/// Objective-C method where 'super' is a valid keyword.
|
||||
CTC_ObjCMessageReceiver
|
||||
|
|
|
@ -3231,7 +3231,9 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
|
|||
// Attempt to correct for typos in ivar names.
|
||||
LookupResult Res(*this, R.getLookupName(), R.getNameLoc(),
|
||||
LookupMemberName);
|
||||
if (CorrectTypo(Res, 0, 0, IDecl, false, CTC_MemberLookup) &&
|
||||
if (CorrectTypo(Res, 0, 0, IDecl, false,
|
||||
IsArrow? CTC_ObjCIvarLookup
|
||||
: CTC_ObjCPropertyLookup) &&
|
||||
(IV = Res.getAsSingle<ObjCIvarDecl>())) {
|
||||
Diag(R.getNameLoc(),
|
||||
diag::err_typecheck_member_reference_ivar_suggest)
|
||||
|
|
|
@ -2785,6 +2785,57 @@ void TypoCorrectionConsumer::addKeywordResult(ASTContext &Context,
|
|||
BestResults[Keyword] = true;
|
||||
}
|
||||
|
||||
/// \brief Perform name lookup for a possible result for typo correction.
|
||||
static void LookupPotentialTypoResult(Sema &SemaRef,
|
||||
LookupResult &Res,
|
||||
IdentifierInfo *Name,
|
||||
Scope *S, CXXScopeSpec *SS,
|
||||
DeclContext *MemberContext,
|
||||
bool EnteringContext,
|
||||
Sema::CorrectTypoContext CTC) {
|
||||
Res.suppressDiagnostics();
|
||||
Res.clear();
|
||||
Res.setLookupName(Name);
|
||||
if (MemberContext) {
|
||||
if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(MemberContext)) {
|
||||
if (CTC == Sema::CTC_ObjCIvarLookup) {
|
||||
if (ObjCIvarDecl *Ivar = Class->lookupInstanceVariable(Name)) {
|
||||
Res.addDecl(Ivar);
|
||||
Res.resolveKind();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ObjCPropertyDecl *Prop = Class->FindPropertyDeclaration(Name)) {
|
||||
Res.addDecl(Prop);
|
||||
Res.resolveKind();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SemaRef.LookupQualifiedName(Res, MemberContext);
|
||||
return;
|
||||
}
|
||||
|
||||
SemaRef.LookupParsedName(Res, S, SS, /*AllowBuiltinCreation=*/false,
|
||||
EnteringContext);
|
||||
|
||||
// Fake ivar lookup; this should really be part of
|
||||
// LookupParsedName.
|
||||
if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
|
||||
if (Method->isInstanceMethod() && Method->getClassInterface() &&
|
||||
(Res.empty() ||
|
||||
(Res.isSingleResult() &&
|
||||
Res.getFoundDecl()->isDefinedOutsideFunctionOrMethod()))) {
|
||||
if (ObjCIvarDecl *IV
|
||||
= Method->getClassInterface()->lookupInstanceVariable(Name)) {
|
||||
Res.addDecl(IV);
|
||||
Res.resolveKind();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Try to "correct" a typo in the source code by finding
|
||||
/// visible declarations whose names are similar to the name that was
|
||||
/// present in the source code.
|
||||
|
@ -2946,10 +2997,17 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
|
|||
WantCXXNamedCasts = true;
|
||||
break;
|
||||
|
||||
case CTC_ObjCPropertyLookup:
|
||||
// FIXME: Add "isa"?
|
||||
break;
|
||||
|
||||
case CTC_MemberLookup:
|
||||
if (getLangOptions().CPlusPlus)
|
||||
Consumer.addKeywordResult(Context, "template");
|
||||
break;
|
||||
|
||||
case CTC_ObjCIvarLookup:
|
||||
break;
|
||||
}
|
||||
|
||||
if (WantTypeSpecifiers) {
|
||||
|
@ -3104,33 +3162,8 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
|
|||
|
||||
// Perform name lookup on this name.
|
||||
IdentifierInfo *Name = &Context.Idents.get(I->getKey());
|
||||
Res.suppressDiagnostics();
|
||||
Res.clear();
|
||||
Res.setLookupName(Name);
|
||||
if (MemberContext)
|
||||
LookupQualifiedName(Res, MemberContext);
|
||||
else {
|
||||
LookupParsedName(Res, S, SS, /*AllowBuiltinCreation=*/false,
|
||||
EnteringContext);
|
||||
|
||||
// Fake ivar lookup; this should really be part of
|
||||
// LookupParsedName.
|
||||
if (ObjCMethodDecl *Method = getCurMethodDecl()) {
|
||||
if (Method->isInstanceMethod() && Method->getClassInterface() &&
|
||||
(Res.empty() ||
|
||||
(Res.isSingleResult() &&
|
||||
Res.getFoundDecl()->isDefinedOutsideFunctionOrMethod()))) {
|
||||
ObjCInterfaceDecl *ClassDeclared = 0;
|
||||
if (ObjCIvarDecl *IV
|
||||
= Method->getClassInterface()->lookupInstanceVariable(Name,
|
||||
ClassDeclared)) {
|
||||
Res.clear();
|
||||
Res.addDecl(IV);
|
||||
Res.resolveKind();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LookupPotentialTypoResult(*this, Res, Name, S, SS, MemberContext,
|
||||
EnteringContext, CTC);
|
||||
|
||||
switch (Res.getResultKind()) {
|
||||
case LookupResult::NotFound:
|
||||
|
@ -3152,7 +3185,7 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
|
|||
case LookupResult::FoundOverloaded:
|
||||
case LookupResult::FoundUnresolvedValue:
|
||||
++I;
|
||||
LastLookupWasAccepted = false;
|
||||
LastLookupWasAccepted = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3172,39 +3205,14 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
|
|||
Res.clear();
|
||||
} else if (!LastLookupWasAccepted) {
|
||||
// Perform name lookup on this name.
|
||||
Res.suppressDiagnostics();
|
||||
Res.clear();
|
||||
Res.setLookupName(Name);
|
||||
if (MemberContext)
|
||||
LookupQualifiedName(Res, MemberContext);
|
||||
else {
|
||||
LookupParsedName(Res, S, SS, /*AllowBuiltinCreation=*/false,
|
||||
EnteringContext);
|
||||
|
||||
// Fake ivar lookup; this should really be part of
|
||||
// LookupParsedName.
|
||||
if (ObjCMethodDecl *Method = getCurMethodDecl()) {
|
||||
if (Method->isInstanceMethod() && Method->getClassInterface() &&
|
||||
(Res.empty() ||
|
||||
(Res.isSingleResult() &&
|
||||
Res.getFoundDecl()->isDefinedOutsideFunctionOrMethod()))) {
|
||||
ObjCInterfaceDecl *ClassDeclared = 0;
|
||||
if (ObjCIvarDecl *IV
|
||||
= Method->getClassInterface()->lookupInstanceVariable(Name,
|
||||
ClassDeclared)) {
|
||||
Res.clear();
|
||||
Res.addDecl(IV);
|
||||
Res.resolveKind();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LookupPotentialTypoResult(*this, Res, Name, S, SS, MemberContext,
|
||||
EnteringContext, CTC);
|
||||
}
|
||||
|
||||
// Record the correction for unqualified lookup.
|
||||
if (IsUnqualifiedLookup)
|
||||
UnqualifiedTyposCorrected[Typo]
|
||||
= std::make_pair(Consumer.begin()->getKey(), Consumer.begin()->second);
|
||||
= std::make_pair(Name->getName(), Consumer.begin()->second);
|
||||
|
||||
return &Context.Idents.get(Consumer.begin()->getKey());
|
||||
}
|
||||
|
@ -3218,7 +3226,7 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
|
|||
// Record the correction for unqualified lookup.
|
||||
if (IsUnqualifiedLookup)
|
||||
UnqualifiedTyposCorrected[Typo]
|
||||
= std::make_pair(Consumer.begin()->getKey(), Consumer.begin()->second);
|
||||
= std::make_pair("super", Consumer.begin()->second);
|
||||
|
||||
return &Context.Idents.get("super");
|
||||
}
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
// RUN: cp %s %t
|
||||
// RUN: %clang_cc1 -fsyntax-only -fixit -x c++ %t || true
|
||||
// RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -x c++ %t
|
||||
//
|
||||
// FIXME: Disabled while we investigate failure.
|
||||
// REQUIRES: disabled
|
||||
|
||||
namespace std {
|
||||
template<typename T> class basic_string { // expected-note 2{{'basic_string' declared here}}
|
||||
public:
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c -E -P %s -o %t
|
||||
// RUN: %clang_cc1 -x objective-c -fsyntax-only -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fixit %t || true
|
||||
// RUN: %clang_cc1 -x objective-c -fsyntax-only -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -pedantic -Werror %t
|
||||
//
|
||||
// FIXME: Disabled while we investigate failure.
|
||||
// REQUIRES: disabled
|
||||
|
||||
@interface NSString // expected-note{{'NSString' declared here}}
|
||||
+ (int)method:(int)x;
|
||||
|
|
|
@ -54,7 +54,7 @@ void f0(int super) {
|
|||
[super m]; // expected-warning{{receiver type 'int' is not 'id'}} \
|
||||
expected-warning {{method '-m' not found (return type defaults to 'id')}}
|
||||
}
|
||||
void f1(id puper) {
|
||||
void f1(id puper) { // expected-note {{'puper' declared here}}
|
||||
[super m]; // expected-error{{use of undeclared identifier 'super'}}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ int bar;
|
|||
@end
|
||||
|
||||
@implementation I
|
||||
- (int) Meth { return PROP; } // expected-note{{'PROP' declared here}}
|
||||
- (int) Meth { return PROP; } // expected-note 2{{'PROP' declared here}}
|
||||
|
||||
@dynamic PROP1;
|
||||
- (int) Meth1 { return PROP1; } // expected-error {{use of undeclared identifier 'PROP1'}}
|
||||
|
|
Loading…
Reference in New Issue