More objective-c type analysis. This time involving objective types

of conforming protocols (or not).

llvm-svn: 45276
This commit is contained in:
Fariborz Jahanian 2007-12-21 00:33:59 +00:00
parent 1cf6c7aa5b
commit ff7d2bf255
3 changed files with 23 additions and 6 deletions

View File

@ -1278,10 +1278,25 @@ bool ASTContext::QualifiedInterfaceTypesAreCompatible(QualType lhs,
return true; return true;
} }
/// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the
/// inheritance hierarchy of 'rProto'.
static bool ProtocolCompatibleWithProtocol(ObjcProtocolDecl *lProto,
ObjcProtocolDecl *rProto) {
if (lProto == rProto)
return true;
ObjcProtocolDecl** RefPDecl = rProto->getReferencedProtocols();
for (unsigned i = 0; i < rProto->getNumReferencedProtocols(); i++)
if (ProtocolCompatibleWithProtocol(lProto, RefPDecl[i]))
return true;
return false;
}
/// ObjcQualifiedIdTypesAreCompatible - Compares two types, at least /// ObjcQualifiedIdTypesAreCompatible - Compares two types, at least
/// one of which is a protocol qualified 'id' type. /// one of which is a protocol qualified 'id' type. When 'compare'
/// is true it is for comparison; when false, for assignment/initialization.
bool ASTContext::ObjcQualifiedIdTypesAreCompatible(QualType lhs, bool ASTContext::ObjcQualifiedIdTypesAreCompatible(QualType lhs,
QualType rhs) { QualType rhs,
bool compare) {
// match id<P..> with an 'id' type in all cases. // match id<P..> with an 'id' type in all cases.
if (const PointerType *PT = lhs->getAsPointerType()) { if (const PointerType *PT = lhs->getAsPointerType()) {
QualType PointeeTy = PT->getPointeeType(); QualType PointeeTy = PT->getPointeeType();
@ -1339,7 +1354,8 @@ bool ASTContext::ObjcQualifiedIdTypesAreCompatible(QualType lhs,
} }
for (unsigned j = 0; j < numRhsProtocols; j++) { for (unsigned j = 0; j < numRhsProtocols; j++) {
ObjcProtocolDecl *rhsProto = rhsProtoList[j]; ObjcProtocolDecl *rhsProto = rhsProtoList[j];
if (lhsProto == rhsProto) { if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto)) {
match = true; match = true;
break; break;
} }
@ -1385,7 +1401,8 @@ bool ASTContext::ObjcQualifiedIdTypesAreCompatible(QualType lhs,
ObjcProtocolDecl *lhsProto = lhsProtoList[i]; ObjcProtocolDecl *lhsProto = lhsProtoList[i];
for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) { for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) {
ObjcProtocolDecl *rhsProto = rhsQID->getProtocols(j); ObjcProtocolDecl *rhsProto = rhsQID->getProtocols(j);
if (lhsProto == rhsProto) { if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto)) {
match = true; match = true;
break; break;
} }

View File

@ -1400,7 +1400,7 @@ inline QualType Sema::CheckCompareOperands( // C99 6.5.8
return Context.IntTy; return Context.IntTy;
} }
if ((lType->isObjcQualifiedIdType() || rType->isObjcQualifiedIdType()) if ((lType->isObjcQualifiedIdType() || rType->isObjcQualifiedIdType())
&& Context.ObjcQualifiedIdTypesAreCompatible(lType, rType)) { && Context.ObjcQualifiedIdTypesAreCompatible(lType, rType, true)) {
promoteExprToType(rex, lType); promoteExprToType(rex, lType);
return Context.IntTy; return Context.IntTy;
} }

View File

@ -297,7 +297,7 @@ public:
/// Objective-C specific type checking. /// Objective-C specific type checking.
bool interfaceTypesAreCompatible(QualType, QualType); bool interfaceTypesAreCompatible(QualType, QualType);
bool QualifiedInterfaceTypesAreCompatible(QualType, QualType); bool QualifiedInterfaceTypesAreCompatible(QualType, QualType);
bool ObjcQualifiedIdTypesAreCompatible(QualType, QualType); bool ObjcQualifiedIdTypesAreCompatible(QualType, QualType, bool = false);
bool objcTypesAreCompatible(QualType, QualType); bool objcTypesAreCompatible(QualType, QualType);
bool isObjcIdType(QualType T) const { bool isObjcIdType(QualType T) const {
if (!IdStructType) // ObjC isn't enabled if (!IdStructType) // ObjC isn't enabled