From: Douglas Gregor Date: Fri, 19 Feb 2010 16:08:35 +0000 (+0000) Subject: Implement C++ name lookup for instance variables of Objective-C classes X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=36262b81559cfce4f67256d052e4fed343a02861;p=clang 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 . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96677 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index c7569d6eda..8d93eed0dc 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -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(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 diff --git a/test/SemaObjCXX/message.mm b/test/SemaObjCXX/message.mm index 6aa62c88ea..93a600aef3 100644 --- a/test/SemaObjCXX/message.mm +++ b/test/SemaObjCXX/message.mm @@ -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