From: Chris Lattner Date: Sun, 20 Apr 2008 02:09:31 +0000 (+0000) Subject: Restructure and simplify Sema::ObjCQualifiedIdTypesAreCompatible, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b1698cf972be75084d760c82389ab5b49a386c31;p=clang Restructure and simplify Sema::ObjCQualifiedIdTypesAreCompatible, deleting dead code, making other code more obvious, and fixing a bug. This fixes these (bogus) warnings in release mode: SemaExprObjC.cpp:383: warning: 'RHSProtoE' may be used uninitialized in this function SemaExprObjC.cpp:383: warning: 'RHSProtoI' may be used uninitialized in this function git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49984 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 63dd0d780f..62d43616b5 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -348,6 +348,8 @@ static bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, return false; } +/// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an +/// ObjCQualifiedIDType. bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, bool compare) { // Allow id and an 'id' or void* type in all cases. @@ -361,24 +363,30 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, return true; } - const ObjCQualifiedInterfaceType *lhsQI = 0; - const ObjCQualifiedInterfaceType *rhsQI = 0; - ObjCInterfaceDecl *lhsID = 0; - ObjCInterfaceDecl *rhsID = 0; - const ObjCQualifiedIdType *lhsQID = lhs->getAsObjCQualifiedIdType(); - const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType(); - - if (lhsQID) { - if (!rhsQID && rhs->isPointerType()) { + if (const ObjCQualifiedIdType *lhsQID = lhs->getAsObjCQualifiedIdType()) { + const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType(); + const ObjCQualifiedInterfaceType *rhsQI = 0; + if (!rhsQID) { + // Not comparing two ObjCQualifiedIdType's? + if (!rhs->isPointerType()) return false; QualType rtype = rhs->getAsPointerType()->getPointeeType(); + rhsQI = rtype->getAsObjCQualifiedInterfaceType(); - if (!rhsQI) { - if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) - rhsID = IT->getDecl(); - } + if (rhsQI == 0) { + // If the RHS is an interface pointer ('NSString*'), handle it. + if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) { + ObjCInterfaceDecl *rhsID = IT->getDecl(); + for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) { + // when comparing an id

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)) + return false; + } + return true; + } + } } - if (!rhsQI && !rhsQID && !rhsID) - return false; ObjCQualifiedIdType::qual_iterator RHSProtoI, RHSProtoE; if (rhsQI) { @@ -387,6 +395,8 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, } else if (rhsQID) { RHSProtoI = rhsQID->qual_begin(); RHSProtoE = rhsQID->qual_end(); + } else { + return false; } for (unsigned i =0; i < lhsQID->getNumProtocols(); i++) { @@ -396,71 +406,60 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, // when comparing an id

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 (rhsID) { - if (ClassImplementsProtocol(lhsProto, rhsID, true)) + for (; RHSProtoI != RHSProtoE; ++RHSProtoI) { + ObjCProtocolDecl *rhsProto = *RHSProtoI; + if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || + compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto)) { match = true; - } else { - for (; RHSProtoI != RHSProtoE; ++RHSProtoI) { - ObjCProtocolDecl *rhsProto = *RHSProtoI; - if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || - compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto)) { - match = true; - break; - } + break; } } if (!match) return false; - } - } else if (rhsQID) { - if (!lhsQID && lhs->isPointerType()) { - QualType ltype = lhs->getAsPointerType()->getPointeeType(); - lhsQI = ltype->getAsObjCQualifiedInterfaceType(); - if (!lhsQI) { - if (const ObjCInterfaceType *IT = ltype->getAsObjCInterfaceType()) - lhsID = IT->getDecl(); - } } - if (!lhsQI && !lhsQID && !lhsID) - return false; - ObjCQualifiedIdType::qual_iterator LHSProtoI, LHSProtoE; - if (lhsQI) { - LHSProtoI = lhsQI->qual_begin(); - LHSProtoE = lhsQI->qual_end(); - } else if (lhsQID) { - LHSProtoI = lhsQID->qual_begin(); - LHSProtoE = lhsQID->qual_end(); - } + return true; + } + + const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType(); + assert(rhsQID && "One of the LHS/RHS should be id"); - bool match = false; - // for static type vs. qualified 'id' type, check that class implements - // one of 'id's protocols. - if (lhsID) { + if (!lhs->isPointerType()) + return false; + + QualType ltype = lhs->getAsPointerType()->getPointeeType(); + if (const ObjCQualifiedInterfaceType *lhsQI = + ltype->getAsObjCQualifiedInterfaceType()) { + ObjCQualifiedIdType::qual_iterator LHSProtoI = lhsQI->qual_begin(); + ObjCQualifiedIdType::qual_iterator LHSProtoE = lhsQI->qual_end(); + for (; LHSProtoI != LHSProtoE; ++LHSProtoI) { + bool match = false; + ObjCProtocolDecl *lhsProto = *LHSProtoI; for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) { ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j); - if (ClassImplementsProtocol(rhsProto, lhsID, compare)) { + if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || + compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto)) { match = true; break; } } - } else { - for (; LHSProtoI != LHSProtoE; ++LHSProtoI) { - match = false; - ObjCProtocolDecl *lhsProto = *LHSProtoI; - for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) { - ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j); - if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || - compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto)) { - match = true; - break; - } - } - } + if (!match) + return false; } - if (!match) - return false; + return true; + } + + if (const ObjCInterfaceType *IT = ltype->getAsObjCInterfaceType()) { + // for static type vs. qualified 'id' type, check that class implements + // all of 'id's protocols. + ObjCInterfaceDecl *lhsID = IT->getDecl(); + for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) { + ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j); + if (!ClassImplementsProtocol(rhsProto, lhsID, compare)) + return false; + } + return true; } - return true; + return false; }