]> granicus.if.org Git - clang/commitdiff
Implement C++ name lookup for instance variables of Objective-C classes
authorDouglas Gregor <dgregor@apple.com>
Fri, 19 Feb 2010 16:08:35 +0000 (16:08 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 19 Feb 2010 16:08:35 +0000 (16:08 +0000)
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>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96677 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaLookup.cpp
test/SemaObjCXX/message.mm

index c7569d6eda25ff6d76435a5670223820ffbb46ac..8d93eed0dcf7fffbb4579af883edae6756455979 100644 (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
index 6aa62c88ea6d7f1d626ea24b836bd33d1760cd75..93a600aef32e937dcb8aaa47a35a55fa4d3dd229 100644 (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