diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaCXXCast.cpp | 24 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 96 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 13 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 19 |
6 files changed, 112 insertions, 51 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 7bd0a4a3308..4e4f80bd0bc 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -261,7 +261,9 @@ ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty, CastKind Sema::ScalarTypeToBooleanCastKind(QualType ScalarTy) { switch (ScalarTy->getScalarTypeKind()) { case Type::STK_Bool: return CK_NoOp; - case Type::STK_Pointer: return CK_PointerToBoolean; + case Type::STK_CPointer: return CK_PointerToBoolean; + case Type::STK_BlockPointer: return CK_PointerToBoolean; + case Type::STK_ObjCObjectPointer: return CK_PointerToBoolean; case Type::STK_MemberPointer: return CK_MemberPointerToBoolean; case Type::STK_Integral: return CK_IntegralToBoolean; case Type::STK_Floating: return CK_FloatingToBoolean; diff --git a/clang/lib/Sema/SemaCXXCast.cpp b/clang/lib/Sema/SemaCXXCast.cpp index 708433f62ca..48f022063ad 100644 --- a/clang/lib/Sema/SemaCXXCast.cpp +++ b/clang/lib/Sema/SemaCXXCast.cpp @@ -871,7 +871,7 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, else if (DestType->isObjCObjectPointerType()) { // allow both c-style cast and static_cast of objective-c pointers as // they are pervasive. - Kind = CK_AnyPointerToObjCPointerCast; + Kind = CK_CPointerToObjCPointerCast; return TC_Success; } else if (CStyle && DestType->isBlockPointerType()) { @@ -1630,16 +1630,34 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, (DestType->isBlockPointerType() && SrcType->isObjCObjectPointerType())) return TC_NotApplicable; + if (IsLValueCast) { + Kind = CK_LValueBitCast; + } else if (DestType->isObjCObjectPointerType()) { + if (SrcType->isObjCObjectPointerType()) { + Kind = CK_BitCast; + } else if (SrcType->isBlockPointerType()) { + Kind = CK_BlockPointerToObjCPointerCast; + } else { + Kind = CK_CPointerToObjCPointerCast; + } + } else if (DestType->isBlockPointerType()) { + if (!SrcType->isBlockPointerType()) { + Kind = CK_AnyPointerToBlockPointerCast; + } else { + Kind = CK_BitCast; + } + } else { + Kind = CK_BitCast; + } + // Any pointer can be cast to an Objective-C pointer type with a C-style // cast. if (CStyle && DestType->isObjCObjectPointerType()) { - Kind = CK_AnyPointerToObjCPointerCast; return TC_Success; } // Not casting away constness, so the only remaining check is for compatible // pointer categories. - Kind = IsLValueCast? CK_LValueBitCast : CK_BitCast; if (SrcType->isFunctionPointerType()) { if (DestType->isFunctionPointerType()) { diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 8dfdeb4b607..94de7992ba1 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1767,11 +1767,16 @@ static bool matchTypes(ASTContext &Context, Sema::MethodMatchStrategy strategy, if (!left->isScalarType() || !right->isScalarType()) return tryMatchRecordTypes(Context, strategy, left, right); - // Make scalars agree in kind, except count bools as chars. + // Make scalars agree in kind, except count bools as chars, and group + // all non-member pointers together. Type::ScalarTypeKind leftSK = left->getScalarTypeKind(); Type::ScalarTypeKind rightSK = right->getScalarTypeKind(); if (leftSK == Type::STK_Bool) leftSK = Type::STK_Integral; if (rightSK == Type::STK_Bool) rightSK = Type::STK_Integral; + if (leftSK == Type::STK_CPointer || leftSK == Type::STK_BlockPointer) + leftSK = Type::STK_ObjCObjectPointer; + if (rightSK == Type::STK_CPointer || rightSK == Type::STK_BlockPointer) + rightSK = Type::STK_ObjCObjectPointer; // Note that data member pointers and function member pointers don't // intermix because of the size differences. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index d20dee44d3d..f10bb3413cb 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3808,16 +3808,26 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) { if (S.Context.hasSameUnqualifiedType(SrcTy, DestTy)) return CK_NoOp; - switch (SrcTy->getScalarTypeKind()) { + switch (Type::ScalarTypeKind SrcKind = SrcTy->getScalarTypeKind()) { case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); - case Type::STK_Pointer: + case Type::STK_CPointer: + case Type::STK_BlockPointer: + case Type::STK_ObjCObjectPointer: switch (DestTy->getScalarTypeKind()) { - case Type::STK_Pointer: - return DestTy->isObjCObjectPointerType() ? - CK_AnyPointerToObjCPointerCast : - CK_BitCast; + case Type::STK_CPointer: + return CK_BitCast; + case Type::STK_BlockPointer: + return (SrcKind == Type::STK_BlockPointer + ? CK_BitCast : CK_AnyPointerToBlockPointerCast); + case Type::STK_ObjCObjectPointer: + if (SrcKind == Type::STK_ObjCObjectPointer) + return CK_BitCast; + else if (SrcKind == Type::STK_CPointer) + return CK_CPointerToObjCPointerCast; + else + return CK_BlockPointerToObjCPointerCast; case Type::STK_Bool: return CK_PointerToBoolean; case Type::STK_Integral: @@ -3833,7 +3843,9 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) { case Type::STK_Bool: // casting from bool is like casting from an integer case Type::STK_Integral: switch (DestTy->getScalarTypeKind()) { - case Type::STK_Pointer: + case Type::STK_CPointer: + case Type::STK_ObjCObjectPointer: + case Type::STK_BlockPointer: if (Src.get()->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) return CK_NullToPointer; @@ -3877,7 +3889,9 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) { DestTy->getAs<ComplexType>()->getElementType(), CK_FloatingToIntegral); return CK_IntegralRealToComplex; - case Type::STK_Pointer: + case Type::STK_CPointer: + case Type::STK_ObjCObjectPointer: + case Type::STK_BlockPointer: llvm_unreachable("valid float->pointer cast?"); case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); @@ -3904,7 +3918,9 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) { SrcTy->getAs<ComplexType>()->getElementType(), CK_FloatingComplexToReal); return CK_FloatingToIntegral; - case Type::STK_Pointer: + case Type::STK_CPointer: + case Type::STK_ObjCObjectPointer: + case Type::STK_BlockPointer: llvm_unreachable("valid complex float->pointer cast?"); case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); @@ -3931,7 +3947,9 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) { SrcTy->getAs<ComplexType>()->getElementType(), CK_IntegralComplexToReal); return CK_IntegralToFloating; - case Type::STK_Pointer: + case Type::STK_CPointer: + case Type::STK_ObjCObjectPointer: + case Type::STK_BlockPointer: llvm_unreachable("valid complex int->pointer cast?"); case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); @@ -3940,7 +3958,6 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) { } llvm_unreachable("Unhandled scalar cast"); - return CK_BitCast; } /// CheckCastTypes - Check type constraints for casting between types. @@ -4497,12 +4514,12 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS, QualType lhptee, rhptee; // Get the pointee types. - if (LHSTy->isBlockPointerType()) { - lhptee = LHSTy->getAs<BlockPointerType>()->getPointeeType(); - rhptee = RHSTy->getAs<BlockPointerType>()->getPointeeType(); + if (const BlockPointerType *LHSBTy = LHSTy->getAs<BlockPointerType>()) { + lhptee = LHSBTy->getPointeeType(); + rhptee = RHSTy->castAs<BlockPointerType>()->getPointeeType(); } else { - lhptee = LHSTy->getAs<PointerType>()->getPointeeType(); - rhptee = RHSTy->getAs<PointerType>()->getPointeeType(); + lhptee = LHSTy->castAs<PointerType>()->getPointeeType(); + rhptee = RHSTy->castAs<PointerType>()->getPointeeType(); } if (!S.Context.typesAreCompatible(lhptee.getUnqualifiedType(), @@ -4752,23 +4769,23 @@ QualType Sema::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, // redefinition type if an attempt is made to access its fields. if (LHSTy->isObjCClassType() && (Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) { - RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_BitCast); + RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_CPointerToObjCPointerCast); return LHSTy; } if (RHSTy->isObjCClassType() && (Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) { - LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_BitCast); + LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_CPointerToObjCPointerCast); return RHSTy; } // And the same for struct objc_object* / id if (LHSTy->isObjCIdType() && (Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) { - RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_BitCast); + RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_CPointerToObjCPointerCast); return LHSTy; } if (RHSTy->isObjCIdType() && (Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) { - LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_BitCast); + LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_CPointerToObjCPointerCast); return RHSTy; } // And the same for struct objc_selector* / SEL @@ -4789,8 +4806,8 @@ QualType Sema::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, // Two identical object pointer types are always compatible. return LHSTy; } - const ObjCObjectPointerType *LHSOPT = LHSTy->getAs<ObjCObjectPointerType>(); - const ObjCObjectPointerType *RHSOPT = RHSTy->getAs<ObjCObjectPointerType>(); + const ObjCObjectPointerType *LHSOPT = LHSTy->castAs<ObjCObjectPointerType>(); + const ObjCObjectPointerType *RHSOPT = RHSTy->castAs<ObjCObjectPointerType>(); QualType compositeType = LHSTy; // If both operands are interfaces and either operand can be @@ -5356,7 +5373,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, if (isa<ObjCObjectPointerType>(RHSType)) { // - conversions to void* if (LHSPointer->getPointeeType()->isVoidType()) { - Kind = CK_AnyPointerToObjCPointerCast; + Kind = CK_BitCast; return Compatible; } @@ -5387,7 +5404,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, if (isa<BlockPointerType>(LHSType)) { // U^ -> T^ if (RHSType->isBlockPointerType()) { - Kind = CK_AnyPointerToBlockPointerCast; + Kind = CK_BitCast; return checkBlockPointerTypesForAssignment(*this, LHSType, RHSType); } @@ -5436,9 +5453,10 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, // In general, C pointers are not compatible with ObjC object pointers, // with two exceptions: if (isa<PointerType>(RHSType)) { + Kind = CK_CPointerToObjCPointerCast; + // - conversions from 'void*' if (RHSType->isVoidPointerType()) { - Kind = CK_AnyPointerToObjCPointerCast; return Compatible; } @@ -5446,17 +5464,15 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, if (LHSType->isObjCClassType() && Context.hasSameType(RHSType, Context.getObjCClassRedefinitionType())) { - Kind = CK_BitCast; return Compatible; } - Kind = CK_AnyPointerToObjCPointerCast; return IncompatiblePointer; } // T^ -> A* if (RHSType->isBlockPointerType()) { - Kind = CK_AnyPointerToObjCPointerCast; + Kind = CK_BlockPointerToObjCPointerCast; return Compatible; } @@ -5553,7 +5569,7 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, // 1) void pointer // 2) null pointer constant if (RHSType->isPointerType()) - if (RHSType->getAs<PointerType>()->getPointeeType()->isVoidType()) { + if (RHSType->castAs<PointerType>()->getPointeeType()->isVoidType()) { RHS = ImpCastExprToType(RHS.take(), it->getType(), CK_BitCast); InitField = *it; break; @@ -6452,9 +6468,9 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, // when handling null pointer constants. if (LHSType->isPointerType() && RHSType->isPointerType()) { // C99 6.5.8p2 QualType LCanPointeeTy = - Context.getCanonicalType(LHSType->getAs<PointerType>()->getPointeeType()); + LHSType->castAs<PointerType>()->getPointeeType().getCanonicalType(); QualType RCanPointeeTy = - Context.getCanonicalType(RHSType->getAs<PointerType>()->getPointeeType()); + RHSType->castAs<PointerType>()->getPointeeType().getCanonicalType(); if (getLangOptions().CPlusPlus) { if (LCanPointeeTy == RCanPointeeTy) @@ -6560,8 +6576,8 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, // Handle block pointer types. if (!IsRelational && LHSType->isBlockPointerType() && RHSType->isBlockPointerType()) { - QualType lpointee = LHSType->getAs<BlockPointerType>()->getPointeeType(); - QualType rpointee = RHSType->getAs<BlockPointerType>()->getPointeeType(); + QualType lpointee = LHSType->castAs<BlockPointerType>()->getPointeeType(); + QualType rpointee = RHSType->castAs<BlockPointerType>()->getPointeeType(); if (!LHSIsNull && !RHSIsNull && !Context.typesAreCompatible(lpointee, rpointee)) { @@ -6587,9 +6603,13 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, << RHS.get()->getSourceRange(); } if (LHSIsNull && !RHSIsNull) - LHS = ImpCastExprToType(LHS.take(), RHSType, CK_BitCast); + LHS = ImpCastExprToType(LHS.take(), RHSType, + RHSType->isPointerType() ? CK_BitCast + : CK_AnyPointerToBlockPointerCast); else - RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast); + RHS = ImpCastExprToType(RHS.take(), LHSType, + LHSType->isPointerType() ? CK_BitCast + : CK_AnyPointerToBlockPointerCast); return ResultTy; } @@ -6607,9 +6627,11 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, /*isError*/false); } if (LHSIsNull && !RHSIsNull) - LHS = ImpCastExprToType(LHS.take(), RHSType, CK_BitCast); + LHS = ImpCastExprToType(LHS.take(), RHSType, + RPT ? CK_BitCast :CK_CPointerToObjCPointerCast); else - RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast); + RHS = ImpCastExprToType(RHS.take(), LHSType, + LPT ? CK_BitCast :CK_CPointerToObjCPointerCast); return ResultTy; } if (LHSType->isObjCObjectPointerType() && diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 9f2696e1288..f6ace99bf6c 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -1357,7 +1357,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, << Receiver->getSourceRange(); if (ReceiverType->isPointerType()) Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(), - CK_BitCast).take(); + CK_CPointerToObjCPointerCast).take(); else { // TODO: specialized warning on null receivers? bool IsNull = Receiver->isNullPointerConstant(Context, @@ -1594,7 +1594,8 @@ namespace { case CK_NoOp: case CK_LValueToRValue: case CK_BitCast: - case CK_AnyPointerToObjCPointerCast: + case CK_CPointerToObjCPointerCast: + case CK_BlockPointerToObjCPointerCast: case CK_AnyPointerToBlockPointerCast: return Visit(e->getSubExpr()); default: @@ -1836,11 +1837,16 @@ ExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc, QualType T = TSInfo->getType(); QualType FromType = SubExpr->getType(); + CastKind CK; + bool MustConsume = false; if (T->isDependentType() || SubExpr->isTypeDependent()) { // Okay: we'll build a dependent expression type. + CK = CK_Dependent; } else if (T->isObjCARCBridgableType() && FromType->isCARCBridgableType()) { // Casting CF -> id + CK = (T->isBlockPointerType() ? CK_AnyPointerToBlockPointerCast + : CK_CPointerToObjCPointerCast); switch (Kind) { case OBC_Bridge: break; @@ -1870,6 +1876,7 @@ ExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc, } } else if (T->isCARCBridgableType() && FromType->isObjCARCBridgableType()) { // Okay: id -> CF + CK = CK_BitCast; switch (Kind) { case OBC_Bridge: // Reclaiming a value that's going to be __bridge-casted to CF @@ -1910,7 +1917,7 @@ ExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc, return ExprError(); } - Expr *Result = new (Context) ObjCBridgedCastExpr(LParenLoc, Kind, + Expr *Result = new (Context) ObjCBridgedCastExpr(LParenLoc, Kind, CK, BridgeKeywordLoc, TSInfo, SubExpr); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 4f36189ce56..c0b83d9b47a 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -2133,8 +2133,8 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType, PDiag(diag::warn_impcast_bool_to_null_pointer) << ToType << From->getSourceRange()); - if (const PointerType *FromPtrType = FromType->getAs<PointerType>()) - if (const PointerType *ToPtrType = ToType->getAs<PointerType>()) { + if (const PointerType *ToPtrType = ToType->getAs<PointerType>()) { + if (const PointerType *FromPtrType = FromType->getAs<PointerType>()) { QualType FromPointeeType = FromPtrType->getPointeeType(), ToPointeeType = ToPtrType->getPointeeType(); @@ -2152,16 +2152,23 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType, Kind = CK_DerivedToBase; } } - if (const ObjCObjectPointerType *FromPtrType = - FromType->getAs<ObjCObjectPointerType>()) { - if (const ObjCObjectPointerType *ToPtrType = - ToType->getAs<ObjCObjectPointerType>()) { + } else if (const ObjCObjectPointerType *ToPtrType = + ToType->getAs<ObjCObjectPointerType>()) { + if (const ObjCObjectPointerType *FromPtrType = + FromType->getAs<ObjCObjectPointerType>()) { // Objective-C++ conversions are always okay. // FIXME: We should have a different class of conversions for the // Objective-C++ implicit conversions. if (FromPtrType->isObjCBuiltinType() || ToPtrType->isObjCBuiltinType()) return false; + } else if (FromType->isBlockPointerType()) { + Kind = CK_BlockPointerToObjCPointerCast; + } else { + Kind = CK_CPointerToObjCPointerCast; } + } else if (ToType->isBlockPointerType()) { + if (!FromType->isBlockPointerType()) + Kind = CK_AnyPointerToBlockPointerCast; } // We shouldn't fall into this case unless it's valid for other |

