diff options
author | Steve Naroff <snaroff@apple.com> | 2008-06-01 02:43:50 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2008-06-01 02:43:50 +0000 |
commit | 289d9f243d9074513368d27eef3b647f72a38324 (patch) | |
tree | af6035eded4d2cb0ee10d21fb5ac2881d61f7428 /lib | |
parent | 19b87d28317f260192d91d723b80b079711d7356 (diff) |
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>'
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51832 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index dd90b9ca19..2f3949fe60 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -367,14 +367,17 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, 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 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, } 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 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, 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; } |