[cfe-commits] r51832 - in /cfe/trunk: lib/Sema/SemaExprObjC.cpp test/Sema/compatible-protocol-qualified-types.m

Steve Naroff snaroff at apple.com
Sat May 31 19:43:51 PDT 2008


Author: snaroff
Date: Sat May 31 21:43:50 2008
New Revision: 51832

URL: http://llvm.org/viewvc/llvm-project?rev=51832&view=rev
Log:
Tweak Sema::ObjCQualifiedIdTypesAreCompatible() to handle qualified interface types on the RHS.

This eliminates a bogus warning identified in the test below.

This fixes <rdar://problem/5968256> clang on xcode: error: incompatible type initializing 'NSObject<XCSelectionSource> *', expected 'id<NSObject,XCSelectionSource>'

Added:
    cfe/trunk/test/Sema/compatible-protocol-qualified-types.m
Modified:
    cfe/trunk/lib/Sema/SemaExprObjC.cpp

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=51832&r1=51831&r2=51832&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Sat May 31 21:43:50 2008
@@ -367,14 +367,17 @@
   if (const ObjCQualifiedIdType *lhsQID = lhs->getAsObjCQualifiedIdType()) {
     const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType();
     const ObjCQualifiedInterfaceType *rhsQI = 0;
+    QualType rtype;
+    
     if (!rhsQID) {
       // Not comparing two ObjCQualifiedIdType's?
       if (!rhs->isPointerType()) return false;
-      QualType rtype = rhs->getAsPointerType()->getPointeeType();
-
+      
+      rtype = rhs->getAsPointerType()->getPointeeType();
       rhsQI = rtype->getAsObjCQualifiedInterfaceType();
       if (rhsQI == 0) {
-        // If the RHS is an interface pointer ('NSString*'), handle it.
+        // If the RHS is a unqualified interface pointer "NSString*", 
+        // make sure we check the class hierarchy.
         if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) {
           ObjCInterfaceDecl *rhsID = IT->getDecl();
           for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) {
@@ -390,10 +393,10 @@
     }
     
     ObjCQualifiedIdType::qual_iterator RHSProtoI, RHSProtoE;
-    if (rhsQI) {
+    if (rhsQI) { // We have a qualified interface (e.g. "NSObject<Proto> *").
       RHSProtoI = rhsQI->qual_begin();
       RHSProtoE = rhsQI->qual_end();
-    } else if (rhsQID) {
+    } else if (rhsQID) { // We have a qualified id (e.g. "id<Proto> *").
       RHSProtoI = rhsQID->qual_begin();
       RHSProtoE = rhsQID->qual_end();
     } else {
@@ -415,6 +418,22 @@
           break;
         }
       }
+      if (rhsQI) {
+        // If the RHS is a qualified interface pointer "NSString<P>*", 
+        // make sure we check the class hierarchy.
+        if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) {
+          ObjCInterfaceDecl *rhsID = IT->getDecl();
+          for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) {
+            // when comparing an id<P> on lhs with a static type on rhs,
+            // see if static class implements all of id's protocols, directly or
+            // through its super class and categories.
+            if (ClassImplementsProtocol(lhsQID->getProtocols(i), rhsID, true)) {
+              match = true;
+              break;
+            }
+          }
+        }
+      }
       if (!match)
         return false;
     }

Added: cfe/trunk/test/Sema/compatible-protocol-qualified-types.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/compatible-protocol-qualified-types.m?rev=51832&view=auto

==============================================================================
--- cfe/trunk/test/Sema/compatible-protocol-qualified-types.m (added)
+++ cfe/trunk/test/Sema/compatible-protocol-qualified-types.m Sat May 31 21:43:50 2008
@@ -0,0 +1,40 @@
+// RUN: clang -pedantic -fsyntax-only -verify %s
+typedef signed char BOOL;
+
+ at class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+
+ at protocol NSObject
+- (BOOL)isEqual:(id)object;
+ at end
+
+ at protocol NSCoding
+- (void)encodeWithCoder:(NSCoder *)aCoder;
+ at end
+
+ at interface NSObject <NSObject> {}
+ at end
+
+typedef float CGFloat;
+
+ at interface NSResponder : NSObject <NSCoding> {}
+ at end
+
+ at protocol XCSelectionSource;
+
+ at interface XCSelection : NSResponder {}
+- (NSObject <XCSelectionSource> *) source;
+ at end
+
+extern NSString * const XCActiveSelectionLevel;
+
+ at interface XCActionManager : NSResponder {}
++defaultActionManager;
+-selectionAtLevel:(NSString *const)s;
+ at end
+
+ at implementation XDMenuItemsManager // expected-warning {{cannot find interface declaration for 'XDMenuItemsManager'}}
++ (void)initialize {
+  id<XCSelectionSource, NSObject> source = 
+    [[[XCActionManager defaultActionManager] selectionAtLevel:XCActiveSelectionLevel] source];
+}
+ at end





More information about the cfe-commits mailing list