Patch to implemented objective-c's dynamic object pointer qualified with
the protocol list (id<P,...> types).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45121 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp
index dae5325..45d0470 100644
--- a/Sema/SemaExpr.cpp
+++ b/Sema/SemaExpr.cpp
@@ -2292,13 +2292,16 @@
           return true;
     }
   } else {
+    bool receiverIsQualId = 
+           dyn_cast<ObjcQualifiedIdType>(RExpr->getType()) != 0;
     // FIXME (snaroff): checking in this code from Patrick. Needs to be
     // revisited. how do we get the ClassDecl from the receiver expression?
-    while (receiverType->isPointerType()) {
-      PointerType *pointerType =
-        static_cast<PointerType*>(receiverType.getTypePtr());
-      receiverType = pointerType->getPointeeType();
-    }
+    if (!receiverIsQualId)
+      while (receiverType->isPointerType()) {
+        PointerType *pointerType =
+          static_cast<PointerType*>(receiverType.getTypePtr());
+        receiverType = pointerType->getPointeeType();
+      }
     ObjcInterfaceDecl* ClassDecl;
     if (ObjcQualifiedInterfaceType *QIT = 
         dyn_cast<ObjcQualifiedInterfaceType>(receiverType)) {
@@ -2312,6 +2315,23 @@
             break;
         }
       }
+      if (!Method)
+        Diag(lbrac, diag::warn_method_not_found_in_protocol, 
+             std::string("-"), Sel.getName(),
+             SourceRange(lbrac, rbrac));
+    }
+    else if (ObjcQualifiedIdType *QIT = 
+             dyn_cast<ObjcQualifiedIdType>(receiverType)) {
+      // search protocols
+      for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
+        ObjcProtocolDecl *PDecl = QIT->getProtocols(i);
+        if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
+          break;
+      }
+      if (!Method)
+        Diag(lbrac, diag::warn_method_not_found_in_protocol, 
+             std::string("-"), Sel.getName(),
+             SourceRange(lbrac, rbrac));
     }
     else {
       assert(ObjcInterfaceType::classof(receiverType.getTypePtr()) &&
diff --git a/Sema/SemaType.cpp b/Sema/SemaType.cpp
index 4eefabf..c89018a 100644
--- a/Sema/SemaType.cpp
+++ b/Sema/SemaType.cpp
@@ -113,6 +113,16 @@
                reinterpret_cast<ObjcProtocolDecl**>(PPDecl),
               DS.NumProtocolQualifiers());
     }
+    else if (TypedefDecl *typeDecl = dyn_cast<TypedefDecl>(D)) {
+      if (Ctx.getObjcIdType() == Ctx.getTypedefType(typeDecl)
+          && DS.getProtocolQualifiers()) {
+          // id<protocol-list>
+        Action::DeclTy **PPDecl = &(*DS.getProtocolQualifiers())[0];
+        return Ctx.getObjcQualifiedIdType(typeDecl,
+                 reinterpret_cast<ObjcProtocolDecl**>(PPDecl),
+                 DS.NumProtocolQualifiers());
+      }
+    }
     // TypeQuals handled by caller.
     return Ctx.getTypedefType(cast<TypedefDecl>(D));
   }