]> granicus.if.org Git - clang/commitdiff
Patch to type match comparing Objective-C Classes which implement
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 19 Jul 2010 22:02:22 +0000 (22:02 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 19 Jul 2010 22:02:22 +0000 (22:02 +0000)
protocols (Radar 8191774).

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

include/clang/AST/ASTContext.h
lib/AST/ASTContext.cpp
test/SemaObjC/compare-qualified-class.m [new file with mode: 0644]

index 3799451360f414d736f2c9bb338e26e273dc59c2..488cfe0929d1d30986122b09c6674238fbbf4302 100644 (file)
@@ -1235,6 +1235,8 @@ public:
   bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
                                          bool ForCompare);
 
+  bool ObjCQualifiedClassTypesAreCompatible(QualType LHS, QualType RHS);
+  
   // Check the safety of assignment from LHS to RHS
   bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
                                const ObjCObjectPointerType *RHSOPT);
index d41051f5dcad7210ea11018a6f6f4fba8916e294..03e91f101ed78b823640b3981f27f5efe937568e 100644 (file)
@@ -4226,6 +4226,32 @@ bool ASTContext::QualifiedIdConformsQualifiedId(QualType lhs, QualType rhs) {
   return false;
 }
 
+/// ObjCQualifiedClassTypesAreCompatible - compare  Class<p,...> and
+/// Class<p1, ...>.
+bool ASTContext::ObjCQualifiedClassTypesAreCompatible(QualType lhs, 
+                                                      QualType rhs) {
+  const ObjCObjectPointerType *lhsQID = lhs->getAs<ObjCObjectPointerType>();
+  const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
+  assert ((lhsQID && rhsOPT) && "ObjCQualifiedClassTypesAreCompatible");
+  
+  for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
+       E = lhsQID->qual_end(); I != E; ++I) {
+    bool match = false;
+    ObjCProtocolDecl *lhsProto = *I;
+    for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(),
+         E = rhsOPT->qual_end(); J != E; ++J) {
+      ObjCProtocolDecl *rhsProto = *J;
+      if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto)) {
+        match = true;
+        break;
+      }
+    }
+    if (!match)
+      return false;
+  }
+  return true;
+}
+
 /// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an
 /// ObjCQualifiedIDType.
 bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
@@ -4365,7 +4391,11 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
     return ObjCQualifiedIdTypesAreCompatible(QualType(LHSOPT,0),
                                              QualType(RHSOPT,0),
                                              false);
-
+  
+  if (LHS->isObjCQualifiedClass() && RHS->isObjCQualifiedClass())
+    return ObjCQualifiedClassTypesAreCompatible(QualType(LHSOPT,0),
+                                                QualType(RHSOPT,0));
+  
   // If we have 2 user-defined types, fall into that path.
   if (LHS->getInterface() && RHS->getInterface())
     return canAssignObjCInterfaces(LHS, RHS);
diff --git a/test/SemaObjC/compare-qualified-class.m b/test/SemaObjC/compare-qualified-class.m
new file mode 100644 (file)
index 0000000..cb2b26a
--- /dev/null
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar:// 8191774
+
+@protocol SomeProtocol
+@end
+
+@protocol SomeProtocol1
+@end
+
+@interface SomeObject <SomeProtocol>
+@end
+
+int main () {
+    Class <SomeProtocol> classA;
+    Class <SomeProtocol> classB;
+    Class <SomeProtocol, SomeProtocol1> classC;
+    Class <SomeProtocol1> classD;
+    void * pv = 0;
+    Class c = (Class)0;;
+    if (pv)
+      return classA == pv;
+
+    if (c)
+      return classA == c;
+    
+    return classA == classB  || classA == classC ||
+           classC == classA ||
+           classA == classD; // expected-warning {{comparison of distinct pointer types ('Class<SomeProtocol> *' and 'Class<SomeProtocol1> *')}}
+}
+