forked from OSchip/llvm-project
Implement C++ name lookup for instance variables of Objective-C classes
from an instance method. Previously, we were following the Objective-C name lookup rules for ivars, which are of course completely different from and incompatible with the Objective-C++ rules. For the record, the Objective-C++ rules are the sane ones. This is another part of <rdar://problem/7660386>. llvm-svn: 96677
This commit is contained in:
parent
cfd70242ca
commit
337caf9e3e
|
@ -644,14 +644,37 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
|
|||
DeclContext *OuterCtx = findOuterContext(S);
|
||||
for (; Ctx && Ctx->getPrimaryContext() != OuterCtx;
|
||||
Ctx = Ctx->getLookupParent()) {
|
||||
// We do not directly look into function or method contexts
|
||||
// (since all local variables are found via the identifier
|
||||
// changes) or in transparent contexts (since those entities
|
||||
// will be found in the nearest enclosing non-transparent
|
||||
// context).
|
||||
if (Ctx->isFunctionOrMethod() || Ctx->isTransparentContext())
|
||||
// We do not directly look into transparent contexts, since
|
||||
// those entities will be found in the nearest enclosing
|
||||
// non-transparent context.
|
||||
if (Ctx->isTransparentContext())
|
||||
continue;
|
||||
|
||||
|
||||
// We do not look directly into function or method contexts,
|
||||
// since all of the local variables and parameters of the
|
||||
// function/method are present within the Scope.
|
||||
if (Ctx->isFunctionOrMethod()) {
|
||||
// If we have an Objective-C instance method, look for ivars
|
||||
// in the corresponding interface.
|
||||
if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(Ctx)) {
|
||||
if (Method->isInstanceMethod() && Name.getAsIdentifierInfo())
|
||||
if (ObjCInterfaceDecl *Class = Method->getClassInterface()) {
|
||||
ObjCInterfaceDecl *ClassDeclared;
|
||||
if (ObjCIvarDecl *Ivar = Class->lookupInstanceVariable(
|
||||
Name.getAsIdentifierInfo(),
|
||||
ClassDeclared)) {
|
||||
if (R.isAcceptableDecl(Ivar)) {
|
||||
R.addDecl(Ivar);
|
||||
R.resolveKind();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Perform qualified name lookup into this context.
|
||||
// FIXME: In some cases, we know that every name that could be found by
|
||||
// this qualified name lookup will also be on the identifier chain. For
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
@interface I1
|
||||
- (void)method;
|
||||
@end
|
||||
|
@ -10,3 +9,21 @@
|
|||
[x method]; // expected-error{{invalid receiver to message expression}}
|
||||
}
|
||||
@end
|
||||
|
||||
typedef struct { int x; } ivar;
|
||||
|
||||
@interface I2 {
|
||||
id ivar;
|
||||
}
|
||||
- (void)method;
|
||||
+ (void)method;
|
||||
@end
|
||||
|
||||
@implementation I2
|
||||
- (void)method {
|
||||
[ivar method];
|
||||
}
|
||||
+ (void)method {
|
||||
[ivar method]; // expected-error{{invalid receiver to message expression}}
|
||||
}
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue