]> granicus.if.org Git - clang/commitdiff
Implemented when static typing is combined with protocols and use as receiver
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 7 Dec 2007 21:21:21 +0000 (21:21 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 7 Dec 2007 21:21:21 +0000 (21:21 +0000)
type.

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

AST/Decl.cpp
Driver/RewriteTest.cpp
Sema/SemaExpr.cpp
include/clang/AST/DeclObjC.h

index cebd29525d52b25902dd7d73d8c6bae17c5daf4c..188f3255dee02a02a644febdfdb8c61ac7121c46 100644 (file)
@@ -543,3 +543,45 @@ ObjcMethodDecl *ObjcCategoryImplDecl::lookupClassMethod(Selector &Sel) {
   }
   return NULL;
 }
+
+// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
+// it inherited.
+ObjcMethodDecl *ObjcProtocolDecl::lookupInstanceMethod(Selector &Sel) {
+  ObjcMethodDecl *const*methods = getInstanceMethods();
+  int methodCount = getNumInstanceMethods();
+  for (int i = 0; i < methodCount; ++i) {
+    if (methods[i]->getSelector() == Sel) {
+      return methods[i];
+    }
+  }
+  if (getNumReferencedProtocols() > 0) {
+    ObjcProtocolDecl **RefPDecl = getReferencedProtocols();
+    
+    for (int i = 0; i < getNumReferencedProtocols(); i++) {
+      if (ObjcMethodDecl *Method = RefPDecl[i]->lookupInstanceMethod(Sel))
+        return Method;
+    }
+  }
+  return NULL;
+}
+
+// lookupInstanceMethod - Lookup a class method in the protocol and protocols
+// it inherited.
+ObjcMethodDecl *ObjcProtocolDecl::lookupClassMethod(Selector &Sel) {
+  ObjcMethodDecl *const*methods = getClassMethods();
+  int methodCount = getNumClassMethods();
+  for (int i = 0; i < methodCount; ++i) {
+    if (methods[i]->getSelector() == Sel) {
+      return methods[i];
+    }
+  }
+  if (getNumReferencedProtocols() > 0) {
+    ObjcProtocolDecl **RefPDecl = getReferencedProtocols();
+    
+    for (int i = 0; i < getNumReferencedProtocols(); i++) {
+      if (ObjcMethodDecl *Method = RefPDecl[i]->lookupClassMethod(Sel))
+        return Method;
+    }
+  }
+  return NULL;
+}
index 9c845a4473369ed5e12e5ae03b7130a3da6ae43e..2a189ad85b34c682d9c966167ab204ef673e1571 100644 (file)
@@ -1446,6 +1446,10 @@ Stmt *RewriteTest::RewriteMessageExpr(ObjCMessageExpr *Exp) {
                                SourceLocation());
       MsgExprs.push_back(Unop);
     } else {
+      // Remove all type-casts because it may contain objc-style types; e.g.
+      // Foo<Proto> *.
+      while (CastExpr *CE = dyn_cast<CastExpr>(recExpr))
+        recExpr = CE->getSubExpr();
       recExpr = new CastExpr(Context->getObjcIdType(), recExpr, SourceLocation());
       MsgExprs.push_back(recExpr);
     }
index e7102aa0a2613173b10fc8a3f465f15c560eadd5..8c5ef43f4c5638173c66c019844144861f2715f8 100644 (file)
@@ -2232,14 +2232,32 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
         static_cast<PointerType*>(receiverType.getTypePtr());
       receiverType = pointerType->getPointeeType();
     }
-    assert(ObjcInterfaceType::classof(receiverType.getTypePtr()) &&
-           "bad receiver type");
-    ObjcInterfaceDecl* ClassDecl = static_cast<ObjcInterfaceType*>(
-                                     receiverType.getTypePtr())->getDecl();
-    // FIXME: consider using InstanceMethodPool, since it will be faster
-    // than the following method (which can do *many* linear searches). The
-    // idea is to add class info to InstanceMethodPool...
-    Method = ClassDecl->lookupInstanceMethod(Sel);
+    ObjcInterfaceDecl* ClassDecl;
+    if (ObjcQualifiedInterfaceType *QIT = 
+        dyn_cast<ObjcQualifiedInterfaceType>(receiverType)) {
+      ObjcInterfaceType * OITypePtr = QIT->getInterfaceType();
+      
+      ClassDecl = OITypePtr->getDecl();
+      Method = ClassDecl->lookupInstanceMethod(Sel);
+      if (!Method) {
+        // search protocols
+        for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
+          ObjcProtocolDecl *PDecl = QIT->getProtocols(i);
+          if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
+            break;
+        }
+      }
+    }
+    else {
+      assert(ObjcInterfaceType::classof(receiverType.getTypePtr()) &&
+             "bad receiver type");
+      ClassDecl = static_cast<ObjcInterfaceType*>(
+                    receiverType.getTypePtr())->getDecl();
+      // FIXME: consider using InstanceMethodPool, since it will be faster
+      // than the following method (which can do *many* linear searches). The
+      // idea is to add class info to InstanceMethodPool...
+      Method = ClassDecl->lookupInstanceMethod(Sel);
+    }
     if (!Method) {
       // If we have an implementation in scope, check "private" methods.
       if (ObjcImplementationDecl *ImpDecl = 
index 5432a4c2a46a607b61e83418fa26e72be42e1ba1..4a4bcf10db7efed832239eff8f1a83936129e02a 100644 (file)
@@ -283,6 +283,9 @@ public:
   ObjcMethodDecl** getClassMethods() const { return ClassMethods; }
   int getNumClassMethods() const { return NumClassMethods; }
   
+  ObjcMethodDecl *lookupInstanceMethod(Selector &Sel);
+  ObjcMethodDecl *lookupClassMethod(Selector &Sel);
+  
   bool isForwardDecl() const { return isForwardProtoDecl; }
   void setForwardDecl(bool val) { isForwardProtoDecl = val; }