diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-07-13 17:21:42 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-07-13 17:21:42 +0000 |
commit | 1928da94b55683957759d5c5ff4593a118773394 (patch) | |
tree | 48b44512b5db8ced345df4a1a56b5065cf2a14d9 /lib/Sema/SemaCXXCast.cpp | |
parent | 53992adde3eda3ccf9da63bc7e45673f043de18f (diff) | |
download | FreeBSD-src-1928da94b55683957759d5c5ff4593a118773394.zip FreeBSD-src-1928da94b55683957759d5c5ff4593a118773394.tar.gz |
Update clang to r108243.
Diffstat (limited to 'lib/Sema/SemaCXXCast.cpp')
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 62 |
1 files changed, 43 insertions, 19 deletions
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index 9b95552..b7e855f 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -233,6 +233,15 @@ bool UnwrapDissimilarPointerTypes(QualType& T1, QualType& T2) { T2 = T2MPType->getPointeeType(); return true; } + + const BlockPointerType *T1BPType = T1->getAs<BlockPointerType>(), + *T2BPType = T2->getAs<BlockPointerType>(); + if (T1BPType && T2BPType) { + T1 = T1BPType->getPointeeType(); + T2 = T2BPType->getPointeeType(); + return true; + } + return false; } @@ -246,9 +255,11 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType) { // C++ 4.4. We piggyback on Sema::IsQualificationConversion for this, since // the rules are non-trivial. So first we construct Tcv *...cv* as described // in C++ 5.2.11p8. - assert((SrcType->isAnyPointerType() || SrcType->isMemberPointerType()) && + assert((SrcType->isAnyPointerType() || SrcType->isMemberPointerType() || + SrcType->isBlockPointerType()) && "Source type is not pointer or pointer to member."); - assert((DestType->isAnyPointerType() || DestType->isMemberPointerType()) && + assert((DestType->isAnyPointerType() || DestType->isMemberPointerType() || + DestType->isBlockPointerType()) && "Destination type is not pointer or pointer to member."); QualType UnwrappedSrcType = Self.Context.getCanonicalType(SrcType), @@ -257,10 +268,16 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType) { // Find the qualifications. while (UnwrapDissimilarPointerTypes(UnwrappedSrcType, UnwrappedDestType)) { - cv1.push_back(UnwrappedSrcType.getQualifiers()); - cv2.push_back(UnwrappedDestType.getQualifiers()); + Qualifiers SrcQuals; + Self.Context.getUnqualifiedArrayType(UnwrappedSrcType, SrcQuals); + cv1.push_back(SrcQuals); + + Qualifiers DestQuals; + Self.Context.getUnqualifiedArrayType(UnwrappedDestType, DestQuals); + cv2.push_back(DestQuals); } - assert(cv1.size() > 0 && "Must have at least one pointer level."); + if (cv1.empty()) + return false; // Construct void pointers with those qualifiers (in reverse order of // unwrapping, of course). @@ -1014,7 +1031,7 @@ static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType, // in multi-level pointers may change, but the level count must be the same, // as must be the final pointee type. while (SrcType != DestType && - Self.UnwrapSimilarPointerTypes(SrcType, DestType)) { + Self.Context.UnwrapSimilarPointerTypes(SrcType, DestType)) { Qualifiers Quals; SrcType = Self.Context.getUnqualifiedArrayType(SrcType, Quals); DestType = Self.Context.getUnqualifiedArrayType(DestType, Quals); @@ -1080,8 +1097,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, } // See below for the enumeral issue. - if (SrcType->isNullPtrType() && DestType->isIntegralType() && - !DestType->isEnumeralType()) { + if (SrcType->isNullPtrType() && DestType->isIntegralType(Self.Context)) { // C++0x 5.2.10p4: A pointer can be explicitly converted to any integral // type large enough to hold it. A value of std::nullptr_t can be // converted to an integral type; the conversion has the same meaning @@ -1098,9 +1114,9 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, bool destIsVector = DestType->isVectorType(); bool srcIsVector = SrcType->isVectorType(); if (srcIsVector || destIsVector) { - bool srcIsScalar = SrcType->isIntegralType() && !SrcType->isEnumeralType(); - bool destIsScalar = - DestType->isIntegralType() && !DestType->isEnumeralType(); + // FIXME: Should this also apply to floating point types? + bool srcIsScalar = SrcType->isIntegralType(Self.Context); + bool destIsScalar = DestType->isIntegralType(Self.Context); // Check if this is a cast between a vector and something else. if (!(srcIsScalar && destIsVector) && !(srcIsVector && destIsScalar) && @@ -1124,8 +1140,10 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, return TC_Failed; } - bool destIsPtr = DestType->isAnyPointerType(); - bool srcIsPtr = SrcType->isAnyPointerType(); + bool destIsPtr = DestType->isAnyPointerType() || + DestType->isBlockPointerType(); + bool srcIsPtr = SrcType->isAnyPointerType() || + SrcType->isBlockPointerType(); if (!destIsPtr && !srcIsPtr) { // Except for std::nullptr_t->integer and lvalue->reference, which are // handled above, at least one of the two arguments must be a pointer. @@ -1143,9 +1161,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, return TC_Success; } - // Note: Clang treats enumeration types as integral types. If this is ever - // changed for C++, the additional check here will be redundant. - if (DestType->isIntegralType() && !DestType->isEnumeralType()) { + if (DestType->isIntegralType(Self.Context)) { assert(srcIsPtr && "One type must be a pointer"); // C++ 5.2.10p4: A pointer can be explicitly converted to any integral // type large enough to hold it. @@ -1158,7 +1174,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, return TC_Success; } - if (SrcType->isIntegralType() || SrcType->isEnumeralType()) { + if (SrcType->isIntegralOrEnumerationType()) { assert(destIsPtr && "One type must be a pointer"); // C++ 5.2.10p5: A value of integral or enumeration type can be explicitly // converted to a pointer. @@ -1178,11 +1194,19 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, msg = diag::err_bad_cxx_cast_const_away; return TC_Failed; } + + // Cannot convert between block pointers and Objective-C object pointers. + if ((SrcType->isBlockPointerType() && DestType->isObjCObjectPointerType()) || + (DestType->isBlockPointerType() && SrcType->isObjCObjectPointerType())) + return TC_NotApplicable; + + // Any pointer can be cast to an Objective-C pointer type with a C-style + // cast. if (CStyle && DestType->isObjCObjectPointerType()) { Kind = CastExpr::CK_AnyPointerToObjCPointerCast; return TC_Success; } - + // Not casting away constness, so the only remaining check is for compatible // pointer categories. Kind = CastExpr::CK_BitCast; @@ -1211,7 +1235,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, Self.Diag(OpRange.getBegin(), diag::ext_cast_fn_obj) << OpRange; return TC_Success; } - + // C++ 5.2.10p7: A pointer to an object can be explicitly converted to // a pointer to an object of different type. // Void pointers are not specified, but supported by every compiler out there. |