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:
Douglas Gregor 2010-02-19 16:08:35 +00:00
parent cfd70242ca
commit 337caf9e3e
2 changed files with 48 additions and 8 deletions

View File

@ -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

View File

@ -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