Implemented type checking for pointer of objects of protocol-qualified types.
Note that incompatible-protocol-qualified-types.m is currently failing. This is
unrelated to this patch and Steve is looking at the general problem of not reporting
incompitible pointer types in return stetement..


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44897 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp
index e8ed9a2..4a40f83 100644
--- a/AST/ASTContext.cpp
+++ b/AST/ASTContext.cpp
@@ -1168,6 +1168,34 @@
   return true; // FIXME: IMPLEMENT.
 }
 
+bool ASTContext::QualifiedInterfaceTypesAreCompatible(QualType lhs, 
+                                                      QualType rhs) {
+  ObjcQualifiedInterfaceType *lhsQI = 
+    dyn_cast<ObjcQualifiedInterfaceType>(lhs.getCanonicalType().getTypePtr());
+  assert(lhsQI && "QualifiedInterfaceTypesAreCompatible - bad lhs type");
+  ObjcQualifiedInterfaceType *rhsQI = 
+    dyn_cast<ObjcQualifiedInterfaceType>(rhs.getCanonicalType().getTypePtr());
+  assert(rhsQI && "QualifiedInterfaceTypesAreCompatible - bad rhs type");
+  if (!interfaceTypesAreCompatible(QualType(lhsQI->getInterfaceType(), 0), 
+			           QualType(rhsQI->getInterfaceType(), 0)))
+    return false;
+  /* All protocols in lhs must have a presense in rhs. */
+  for (unsigned i =0; i < lhsQI->getNumProtocols(); i++) {
+    bool match = false;
+    ObjcProtocolDecl *lhsProto = lhsQI->getProtocols(i);
+    for (unsigned j = 0; j < rhsQI->getNumProtocols(); j++) {
+      ObjcProtocolDecl *rhsProto = rhsQI->getProtocols(j);
+      if (lhsProto == rhsProto) {
+        match = true;
+        break;
+      }
+    }
+    if (!match)
+      return false;
+  }
+  return true;
+}
+
 bool ASTContext::vectorTypesAreCompatible(QualType lhs, QualType rhs) {
   const VectorType *lVector = lhs->getAsVectorType();
   const VectorType *rVector = rhs->getAsVectorType();
@@ -1331,6 +1359,8 @@
     case Type::Vector:
     case Type::OCUVector:
       return vectorTypesAreCompatible(lcanon, rcanon);
+    case Type::ObjcQualifiedInterface:
+      return QualifiedInterfaceTypesAreCompatible(lcanon, rcanon);
     default:
       assert(0 && "unexpected type");
   }