diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 9 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 15 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 193 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 3 |
5 files changed, 10 insertions, 214 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 3bb763a13f8..9f3eff9f1db 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1201,7 +1201,6 @@ public: bool &IncompleteImpl); void WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethod, ObjCMethodDecl *IntfMethod); - bool QualifiedIdConformsQualifiedId(QualType LHS, QualType RHS); NamespaceDecl *GetStdNamespace(); @@ -3197,9 +3196,6 @@ public: unsigned NewWidth, bool NewSign, SourceLocation Loc, unsigned DiagID); - bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS, - bool ForCompare); - /// Checks that the Objective-C declaration is declared in the global scope. /// Emits an error and marks the declaration as invalid if it's not declared /// in the global scope. diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 19cbf091b5f..8bd2f530e40 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -369,7 +369,7 @@ Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, if (!Context.typesAreCompatible(LHSType, RHSType)) { // FIXME: Incorporate this test with typesAreCompatible. if (LHSType->isObjCQualifiedIdType() && RHSType->isObjCQualifiedIdType()) - if (ObjCQualifiedIdTypesAreCompatible(LHSType, RHSType, false)) + if (Context.ObjCQualifiedIdTypesAreCompatible(LHSType, RHSType, false)) return; Diag(Property->getLocation(), diag::warn_property_types_are_incompatible) << Property->getType() << SuperProperty->getType() << inheritedName; @@ -804,8 +804,8 @@ void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl, ObjCMethodDecl *IntfMethodDecl) { if (!Context.typesAreCompatible(IntfMethodDecl->getResultType(), ImpMethodDecl->getResultType()) && - !QualifiedIdConformsQualifiedId(IntfMethodDecl->getResultType(), - ImpMethodDecl->getResultType())) { + !Context.QualifiedIdConformsQualifiedId(IntfMethodDecl->getResultType(), + ImpMethodDecl->getResultType())) { Diag(ImpMethodDecl->getLocation(), diag::warn_conflicting_ret_types) << ImpMethodDecl->getDeclName() << IntfMethodDecl->getResultType() << ImpMethodDecl->getResultType(); @@ -816,7 +816,8 @@ void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl, IF = IntfMethodDecl->param_begin(), EM = ImpMethodDecl->param_end(); IM != EM; ++IM, ++IF) { if (Context.typesAreCompatible((*IF)->getType(), (*IM)->getType()) || - QualifiedIdConformsQualifiedId((*IF)->getType(), (*IM)->getType())) + Context.QualifiedIdConformsQualifiedId((*IF)->getType(), + (*IM)->getType())) continue; Diag((*IM)->getLocation(), diag::warn_conflicting_param_types) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 5d4fbd8080e..bfde991555a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3171,7 +3171,7 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, compositeType = RHSTy; } else if ((LHSTy->isObjCQualifiedIdType() || RHSTy->isObjCQualifiedIdType()) && - ObjCQualifiedIdTypesAreCompatible(LHSTy, RHSTy, true)) { + Context.ObjCQualifiedIdTypesAreCompatible(LHSTy, RHSTy, true)) { // Need to handle "id<xx>" explicitly. // GCC allows qualified id and any Objective-C type to devolve to // id. Currently localizing to here until clear this should be @@ -3436,17 +3436,6 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { return Compatible; return Incompatible; } - // FIXME: Look into removing. With ObjCObjectPointerType, I don't see a need. - if (lhsType->isObjCQualifiedIdType() || rhsType->isObjCQualifiedIdType()) { - if (ObjCQualifiedIdTypesAreCompatible(lhsType, rhsType, false)) - return Compatible; - // Relax integer conversions like we do for pointers below. - if (rhsType->isIntegerType()) - return IntToPointer; - if (lhsType->isIntegerType()) - return PointerToInt; - return IncompatibleObjCQualifiedId; - } // Allow scalar to ExtVector assignments, and assignments of an ExtVector type // to the same ExtVector type. if (lhsType->isExtVectorType()) { @@ -3528,6 +3517,8 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { return Compatible; if (Context.typesAreCompatible(lhsType, rhsType)) return Compatible; + if (lhsType->isObjCQualifiedIdType() || rhsType->isObjCQualifiedIdType()) + return IncompatibleObjCQualifiedId; return IncompatiblePointer; } if (const PointerType *RHSPT = rhsType->getAsPointerType()) { diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 2d144100e5d..47ce949d020 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -651,196 +651,3 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, rbrac, ArgExprs, NumArgs); } -//===----------------------------------------------------------------------===// -// ObjCQualifiedIdTypesAreCompatible - Compatibility testing for qualified id's. -//===----------------------------------------------------------------------===// - -/// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the -/// inheritance hierarchy of 'rProto'. -static bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto, - ObjCProtocolDecl *rProto) { - if (lProto == rProto) - return true; - for (ObjCProtocolDecl::protocol_iterator PI = rProto->protocol_begin(), - E = rProto->protocol_end(); PI != E; ++PI) - if (ProtocolCompatibleWithProtocol(lProto, *PI)) - return true; - return false; -} - -/// ClassImplementsProtocol - Checks that 'lProto' protocol -/// has been implemented in IDecl class, its super class or categories (if -/// lookupCategory is true). -static bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, - ObjCInterfaceDecl *IDecl, - bool lookupCategory, - bool RHSIsQualifiedID = false) { - - // 1st, look up the class. - const ObjCList<ObjCProtocolDecl> &Protocols = - IDecl->getReferencedProtocols(); - - for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(), - E = Protocols.end(); PI != E; ++PI) { - if (ProtocolCompatibleWithProtocol(lProto, *PI)) - return true; - // This is dubious and is added to be compatible with gcc. In gcc, it is - // also allowed assigning a protocol-qualified 'id' type to a LHS object - // when protocol in qualified LHS is in list of protocols in the rhs 'id' - // object. This IMO, should be a bug. - // FIXME: Treat this as an extension, and flag this as an error when GCC - // extensions are not enabled. - if (RHSIsQualifiedID && ProtocolCompatibleWithProtocol(*PI, lProto)) - return true; - } - - // 2nd, look up the category. - if (lookupCategory) - for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl; - CDecl = CDecl->getNextClassCategory()) { - for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(), - E = CDecl->protocol_end(); PI != E; ++PI) - if (ProtocolCompatibleWithProtocol(lProto, *PI)) - return true; - } - - // 3rd, look up the super class(s) - if (IDecl->getSuperClass()) - return - ClassImplementsProtocol(lProto, IDecl->getSuperClass(), lookupCategory, - RHSIsQualifiedID); - - return false; -} - -/// QualifiedIdConformsQualifiedId - compare id<p,...> with id<p1,...> -/// return true if lhs's protocols conform to rhs's protocol; false -/// otherwise. -bool Sema::QualifiedIdConformsQualifiedId(QualType lhs, QualType rhs) { - if (lhs->isObjCQualifiedIdType() && rhs->isObjCQualifiedIdType()) - return ObjCQualifiedIdTypesAreCompatible(lhs, rhs, false); - return false; -} - -/// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an -/// ObjCQualifiedIDType. -/// FIXME: Move to ASTContext::typesAreCompatible() and friends. -bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, - bool compare) { - // Allow id<P..> and an 'id' or void* type in all cases. - if (lhs->isVoidPointerType() || - lhs->isObjCIdType() || lhs->isObjCClassType()) - return true; - else if (rhs->isVoidPointerType() || - rhs->isObjCIdType() || rhs->isObjCClassType()) - return true; - - if (const ObjCObjectPointerType *lhsQID = lhs->getAsObjCQualifiedIdType()) { - const ObjCObjectPointerType *rhsOPT = rhs->getAsObjCObjectPointerType(); - - if (!rhsOPT) return false; - - if (rhsOPT->qual_empty()) { - // If the RHS is a unqualified interface pointer "NSString*", - // make sure we check the class hierarchy. - if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) { - for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(), - E = lhsQID->qual_end(); I != E; ++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(*I, rhsID, true)) - return false; - } - } - // If there are no qualifiers and no interface, we have an 'id'. - return true; - } - // Both the right and left sides have qualifiers. - for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(), - E = lhsQID->qual_end(); I != E; ++I) { - ObjCProtocolDecl *lhsProto = *I; - bool match = false; - - // 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. - for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(), - E = rhsOPT->qual_end(); J != E; ++J) { - ObjCProtocolDecl *rhsProto = *J; - if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || - (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { - match = true; - break; - } - } - // If the RHS is a qualified interface pointer "NSString<P>*", - // make sure we check the class hierarchy. - if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) { - for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(), - E = lhsQID->qual_end(); I != E; ++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(*I, rhsID, true)) { - match = true; - break; - } - } - } - if (!match) - return false; - } - - return true; - } - - const ObjCObjectPointerType *rhsQID = rhs->getAsObjCQualifiedIdType(); - assert(rhsQID && "One of the LHS/RHS should be id<x>"); - - if (const ObjCObjectPointerType *lhsOPT = - lhs->getAsObjCInterfacePointerType()) { - if (lhsOPT->qual_empty()) { - bool match = false; - if (ObjCInterfaceDecl *lhsID = lhsOPT->getInterfaceDecl()) { - for (ObjCObjectPointerType::qual_iterator I = rhsQID->qual_begin(), - E = rhsQID->qual_end(); I != E; ++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(*I, lhsID, true)) { - match = true; - break; - } - } - if (!match) - return false; - } - return true; - } - // Both the right and left sides have qualifiers. - for (ObjCObjectPointerType::qual_iterator I = lhsOPT->qual_begin(), - E = lhsOPT->qual_end(); I != E; ++I) { - ObjCProtocolDecl *lhsProto = *I; - bool match = false; - - // 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. - for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(), - E = rhsQID->qual_end(); J != E; ++J) { - ObjCProtocolDecl *rhsProto = *J; - if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || - (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { - match = true; - break; - } - } - if (!match) - return false; - } - return true; - } - return false; -} - diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 503f226fd66..dc5f3e8e734 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1020,7 +1020,8 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType, // Conversions with Objective-C's id<...>. if ((FromObjCPtr->isObjCQualifiedIdType() || ToObjCPtr->isObjCQualifiedIdType()) && - ObjCQualifiedIdTypesAreCompatible(ToType, FromType, /*compare=*/false)) { + Context.ObjCQualifiedIdTypesAreCompatible(ToType, FromType, + /*compare=*/false)) { ConvertedType = ToType; return true; } |

