]> granicus.if.org Git - clang/commitdiff
Fix ObjCInterfaceDecl::lookupInstanceMethod()/lookupClassMethod() to search in inheri...
authorSteve Naroff <snaroff@apple.com>
Thu, 26 Feb 2009 11:32:02 +0000 (11:32 +0000)
committerSteve Naroff <snaroff@apple.com>
Thu, 26 Feb 2009 11:32:02 +0000 (11:32 +0000)
Also changed ObjCInterfaceDecl::lookupClassMethod() to look through a categories protocols.

Test/patch submitted by Jean-Daniel Dupas (thanks!).

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

lib/AST/DeclObjC.cpp
test/SemaObjC/protocol-lookup-2.m [new file with mode: 0644]

index a9f7922ed04921b19f2073d54d9f7457a495b195..1d2ad16479c3a05552accdc74c64fe6d4e4f8e41 100644 (file)
@@ -157,7 +157,7 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
       ClassDecl->getReferencedProtocols();
     for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
          E = Protocols.end(); I != E; ++I)
-      if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
+      if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
         return MethodDecl;
     
     // Didn't find one yet - now look through categories.
@@ -171,7 +171,7 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
         CatDecl->getReferencedProtocols();
       for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
            E = Protocols.end(); I != E; ++I)
-        if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
+        if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
           return MethodDecl;
       CatDecl = CatDecl->getNextClassCategory();
     }
@@ -193,7 +193,7 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
     // Didn't find one yet - look through protocols.
     for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
          E = ClassDecl->protocol_end(); I != E; ++I)
-      if ((MethodDecl = (*I)->getClassMethod(Sel)))
+      if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
         return MethodDecl;
     
     // Didn't find one yet - now look through categories.
@@ -201,6 +201,14 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
     while (CatDecl) {
       if ((MethodDecl = CatDecl->getClassMethod(Sel)))
         return MethodDecl;
+        
+      // Didn't find one yet - look through protocols.
+      const ObjCList<ObjCProtocolDecl> &Protocols =
+        CatDecl->getReferencedProtocols();
+      for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+           E = Protocols.end(); I != E; ++I)
+        if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
+          return MethodDecl;
       CatDecl = CatDecl->getNextClassCategory();
     }
     ClassDecl = ClassDecl->getSuperClass();
diff --git a/test/SemaObjC/protocol-lookup-2.m b/test/SemaObjC/protocol-lookup-2.m
new file mode 100644 (file)
index 0000000..5d721e5
--- /dev/null
@@ -0,0 +1,33 @@
+// RUN: clang -fsyntax-only -verify %s
+@interface NSObject @end
+
+@protocol ProtocolA
+
++ (id)classMethod;
+- (id)instanceMethod;
+
+@end
+
+@protocol ProtocolB <ProtocolA>
+
+@end
+
+@interface Foo : NSObject <ProtocolB>
+
+@end
+
+@interface SubFoo : Foo
+
+@end
+
+@implementation SubFoo
+
++ (id)method {
+  return [super classMethod];
+}
+
+- (id)method {
+  return [super instanceMethod];
+}
+
+@end