diff options
author | John McCall <rjmccall@apple.com> | 2011-10-06 23:25:11 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-10-06 23:25:11 +0000 |
commit | a180f04c091bf3ede4fe292ba6a29d61da09e936 (patch) | |
tree | 2e2c705d8b775c223bac52046b5c1ce556792c19 /lib/Sema/SemaExpr.cpp | |
parent | c076e37e2223cfe998fa5e657dece30da78fcdc4 (diff) |
Move type-checking for C-style casts in C into the now-misnamed
SemaCXXCast.cpp. Should have no functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141336 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 275 |
1 files changed, 33 insertions, 242 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 96af0e4c8e..de35ec8525 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3896,13 +3896,13 @@ CastKind Sema::PrepareCastToObjCObjectPointer(ExprResult &E) { /// Prepares for a scalar cast, performing all the necessary stages /// except the final cast and returning the kind required. -static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) { +CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { // Both Src and Dest are scalar types, i.e. arithmetic or pointer. // Also, callers should have filtered out the invalid cases with // pointers. Everything else should be possible. QualType SrcTy = Src.get()->getType(); - if (S.Context.hasSameUnqualifiedType(SrcTy, DestTy)) + if (Context.hasSameUnqualifiedType(SrcTy, DestTy)) return CK_NoOp; switch (Type::ScalarTypeKind SrcKind = SrcTy->getScalarTypeKind()) { @@ -3924,7 +3924,7 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) { else if (SrcKind == Type::STK_CPointer) return CK_CPointerToObjCPointerCast; else { - maybeExtendBlockObject(S, Src); + maybeExtendBlockObject(*this, Src); return CK_BlockPointerToObjCPointerCast; } case Type::STK_Bool: @@ -3945,7 +3945,7 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) { case Type::STK_CPointer: case Type::STK_ObjCObjectPointer: case Type::STK_BlockPointer: - if (Src.get()->isNullPointerConstant(S.Context, + if (Src.get()->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) return CK_NullToPointer; return CK_IntegralToPointer; @@ -3956,14 +3956,14 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) { case Type::STK_Floating: return CK_IntegralToFloating; case Type::STK_IntegralComplex: - Src = S.ImpCastExprToType(Src.take(), - DestTy->getAs<ComplexType>()->getElementType(), - CK_IntegralCast); + Src = ImpCastExprToType(Src.take(), + DestTy->castAs<ComplexType>()->getElementType(), + CK_IntegralCast); return CK_IntegralRealToComplex; case Type::STK_FloatingComplex: - Src = S.ImpCastExprToType(Src.take(), - DestTy->getAs<ComplexType>()->getElementType(), - CK_IntegralToFloating); + Src = ImpCastExprToType(Src.take(), + DestTy->castAs<ComplexType>()->getElementType(), + CK_IntegralToFloating); return CK_FloatingRealToComplex; case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); @@ -3979,14 +3979,14 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) { case Type::STK_Integral: return CK_FloatingToIntegral; case Type::STK_FloatingComplex: - Src = S.ImpCastExprToType(Src.take(), - DestTy->getAs<ComplexType>()->getElementType(), - CK_FloatingCast); + Src = ImpCastExprToType(Src.take(), + DestTy->castAs<ComplexType>()->getElementType(), + CK_FloatingCast); return CK_FloatingRealToComplex; case Type::STK_IntegralComplex: - Src = S.ImpCastExprToType(Src.take(), - DestTy->getAs<ComplexType>()->getElementType(), - CK_FloatingToIntegral); + Src = ImpCastExprToType(Src.take(), + DestTy->castAs<ComplexType>()->getElementType(), + CK_FloatingToIntegral); return CK_IntegralRealToComplex; case Type::STK_CPointer: case Type::STK_ObjCObjectPointer: @@ -4004,18 +4004,18 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) { case Type::STK_IntegralComplex: return CK_FloatingComplexToIntegralComplex; case Type::STK_Floating: { - QualType ET = SrcTy->getAs<ComplexType>()->getElementType(); - if (S.Context.hasSameType(ET, DestTy)) + QualType ET = SrcTy->castAs<ComplexType>()->getElementType(); + if (Context.hasSameType(ET, DestTy)) return CK_FloatingComplexToReal; - Src = S.ImpCastExprToType(Src.take(), ET, CK_FloatingComplexToReal); + Src = ImpCastExprToType(Src.take(), ET, CK_FloatingComplexToReal); return CK_FloatingCast; } case Type::STK_Bool: return CK_FloatingComplexToBoolean; case Type::STK_Integral: - Src = S.ImpCastExprToType(Src.take(), - SrcTy->getAs<ComplexType>()->getElementType(), - CK_FloatingComplexToReal); + Src = ImpCastExprToType(Src.take(), + SrcTy->castAs<ComplexType>()->getElementType(), + CK_FloatingComplexToReal); return CK_FloatingToIntegral; case Type::STK_CPointer: case Type::STK_ObjCObjectPointer: @@ -4033,18 +4033,18 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) { case Type::STK_IntegralComplex: return CK_IntegralComplexCast; case Type::STK_Integral: { - QualType ET = SrcTy->getAs<ComplexType>()->getElementType(); - if (S.Context.hasSameType(ET, DestTy)) + QualType ET = SrcTy->castAs<ComplexType>()->getElementType(); + if (Context.hasSameType(ET, DestTy)) return CK_IntegralComplexToReal; - Src = S.ImpCastExprToType(Src.take(), ET, CK_IntegralComplexToReal); + Src = ImpCastExprToType(Src.take(), ET, CK_IntegralComplexToReal); return CK_IntegralCast; } case Type::STK_Bool: return CK_IntegralComplexToBoolean; case Type::STK_Floating: - Src = S.ImpCastExprToType(Src.take(), - SrcTy->getAs<ComplexType>()->getElementType(), - CK_IntegralComplexToReal); + Src = ImpCastExprToType(Src.take(), + SrcTy->castAs<ComplexType>()->getElementType(), + CK_IntegralComplexToReal); return CK_IntegralToFloating; case Type::STK_CPointer: case Type::STK_ObjCObjectPointer: @@ -4059,196 +4059,6 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) { llvm_unreachable("Unhandled scalar cast"); } -/// CheckCastTypes - Check type constraints for casting between types in C. -ExprResult Sema::CheckCCastTypes(SourceLocation CastStartLoc, - SourceRange TypeRange, QualType CastType, - Expr *CastExpr, CastKind &Kind) { - assert(!getLangOptions().CPlusPlus); - - if (CastExpr->getType() == Context.UnknownAnyTy) { - // We can safely ignore these here because C never has base paths - // or casts to l-values. - CXXCastPath BasePath; - ExprValueKind VK = VK_RValue; - return checkUnknownAnyCast(TypeRange, CastType, CastExpr, Kind, VK, - BasePath); - } - - ExprResult Result = CheckPlaceholderExpr(CastExpr); - if (Result.isInvalid()) - return ExprError(); - CastExpr = Result.take(); - - assert(!CastExpr->getType()->isPlaceholderType()); - - // C99 6.5.4p2: the cast type needs to be void or scalar and the expression - // type needs to be scalar. - if (CastType->isVoidType()) { - // We don't necessarily do lvalue-to-rvalue conversions on this. - ExprResult castExprRes = IgnoredValueConversions(CastExpr); - if (castExprRes.isInvalid()) - return ExprError(); - CastExpr = castExprRes.take(); - - // Cast to void allows any expr type. - Kind = CK_ToVoid; - return Owned(CastExpr); - } - - ExprResult castExprRes = DefaultFunctionArrayLvalueConversion(CastExpr); - if (castExprRes.isInvalid()) - return ExprError(); - CastExpr = castExprRes.take(); - - if (RequireCompleteType(TypeRange.getBegin(), CastType, - diag::err_typecheck_cast_to_incomplete)) - return ExprError(); - - if (!CastType->isScalarType() && !CastType->isVectorType()) { - if (Context.hasSameUnqualifiedType(CastType, CastExpr->getType()) && - (CastType->isStructureType() || CastType->isUnionType())) { - // GCC struct/union extension: allow cast to self. - // FIXME: Check that the cast destination type is complete. - Diag(TypeRange.getBegin(), diag::ext_typecheck_cast_nonscalar) - << CastType << CastExpr->getSourceRange(); - Kind = CK_NoOp; - return Owned(CastExpr); - } - - if (CastType->isUnionType()) { - // GCC cast to union extension - RecordDecl *RD = CastType->getAs<RecordType>()->getDecl(); - RecordDecl::field_iterator Field, FieldEnd; - for (Field = RD->field_begin(), FieldEnd = RD->field_end(); - Field != FieldEnd; ++Field) { - if (Context.hasSameUnqualifiedType(Field->getType(), - CastExpr->getType()) && - !Field->isUnnamedBitfield()) { - Diag(TypeRange.getBegin(), diag::ext_typecheck_cast_to_union) - << CastExpr->getSourceRange(); - break; - } - } - if (Field == FieldEnd) { - Diag(TypeRange.getBegin(), diag::err_typecheck_cast_to_union_no_type) - << CastExpr->getType() << CastExpr->getSourceRange(); - return ExprError(); - } - Kind = CK_ToUnion; - return Owned(CastExpr); - } - - // Reject any other conversions to non-scalar types. - Diag(TypeRange.getBegin(), diag::err_typecheck_cond_expect_scalar) - << CastType << CastExpr->getSourceRange(); - return ExprError(); - } - - // The type we're casting to is known to be a scalar or vector. - - // Require the operand to be a scalar or vector. - if (!CastExpr->getType()->isScalarType() && - !CastExpr->getType()->isVectorType()) { - Diag(CastExpr->getLocStart(), - diag::err_typecheck_expect_scalar_operand) - << CastExpr->getType() << CastExpr->getSourceRange(); - return ExprError(); - } - - if (CastType->isExtVectorType()) - return CheckExtVectorCast(TypeRange, CastType, CastExpr, Kind); - - if (CastType->isVectorType()) { - if (CastType->getAs<VectorType>()->getVectorKind() == - VectorType::AltiVecVector && - (CastExpr->getType()->isIntegerType() || - CastExpr->getType()->isFloatingType())) { - Kind = CK_VectorSplat; - return Owned(CastExpr); - } else if (CheckVectorCast(TypeRange, CastType, CastExpr->getType(), - Kind)) { - return ExprError(); - } else - return Owned(CastExpr); - } - if (CastExpr->getType()->isVectorType()) { - if (CheckVectorCast(TypeRange, CastExpr->getType(), CastType, Kind)) - return ExprError(); - else - return Owned(CastExpr); - } - - // The source and target types are both scalars, i.e. - // - arithmetic types (fundamental, enum, and complex) - // - all kinds of pointers - // Note that member pointers were filtered out with C++, above. - - if (isa<ObjCSelectorExpr>(CastExpr)) { - Diag(CastExpr->getLocStart(), diag::err_cast_selector_expr); - return ExprError(); - } - - // If either type is a pointer, the other type has to be either an - // integer or a pointer. - QualType CastExprType = CastExpr->getType(); - if (!CastType->isArithmeticType()) { - if (!CastExprType->isIntegralType(Context) && - CastExprType->isArithmeticType()) { - Diag(CastExpr->getLocStart(), - diag::err_cast_pointer_from_non_pointer_int) - << CastExprType << CastExpr->getSourceRange(); - return ExprError(); - } - } else if (!CastExpr->getType()->isArithmeticType()) { - if (!CastType->isIntegralType(Context) && CastType->isArithmeticType()) { - Diag(CastExpr->getLocStart(), diag::err_cast_pointer_to_non_pointer_int) - << CastType << CastExpr->getSourceRange(); - return ExprError(); - } - } - - // ARC imposes extra restrictions on casts. - if (getLangOptions().ObjCAutoRefCount) { - CheckObjCARCConversion(SourceRange(CastStartLoc, CastExpr->getLocEnd()), - CastType, CastExpr, CCK_CStyleCast); - - if (const PointerType *CastPtr = CastType->getAs<PointerType>()) { - if (const PointerType *ExprPtr = CastExprType->getAs<PointerType>()) { - Qualifiers CastQuals = CastPtr->getPointeeType().getQualifiers(); - Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers(); - if (CastPtr->getPointeeType()->isObjCLifetimeType() && - ExprPtr->getPointeeType()->isObjCLifetimeType() && - !CastQuals.compatiblyIncludesObjCLifetime(ExprQuals)) { - Diag(CastExpr->getLocStart(), - diag::err_typecheck_incompatible_ownership) - << CastExprType << CastType << AA_Casting - << CastExpr->getSourceRange(); - - return ExprError(); - } - } - } - else if (!CheckObjCARCUnavailableWeakConversion(CastType, CastExprType)) { - Diag(CastExpr->getLocStart(), - diag::err_arc_convesion_of_weak_unavailable) << 1 - << CastExprType << CastType - << CastExpr->getSourceRange(); - return ExprError(); - } - } - - castExprRes = Owned(CastExpr); - Kind = PrepareScalarCast(*this, castExprRes, CastType); - if (castExprRes.isInvalid()) - return ExprError(); - CastExpr = castExprRes.take(); - - if (Kind == CK_BitCast) - CheckCastAlign(CastExpr, CastType, TypeRange); - - return Owned(CastExpr); -} - bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty, CastKind &Kind) { assert(VectorTy->isVectorType() && "Not a vector type!"); @@ -4301,7 +4111,7 @@ ExprResult Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType DestElemTy = DestTy->getAs<ExtVectorType>()->getElementType(); ExprResult CastExprRes = Owned(CastExpr); - CastKind CK = PrepareScalarCast(*this, CastExprRes, DestElemTy); + CastKind CK = PrepareScalarCast(CastExprRes, DestElemTy); if (CastExprRes.isInvalid()) return ExprError(); CastExpr = ImpCastExprToType(CastExprRes.take(), DestElemTy, CK).take(); @@ -4369,25 +4179,6 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, CastExpr); } -ExprResult -Sema::BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, - SourceLocation RParenLoc, Expr *CastExpr) { - if (getLangOptions().CPlusPlus) - return CXXBuildCStyleCastExpr(LParenLoc, Ty, RParenLoc, CastExpr); - - CastKind Kind = CK_Invalid; - ExprResult CastResult = - CheckCCastTypes(LParenLoc, SourceRange(LParenLoc, RParenLoc), - Ty->getType(), CastExpr, Kind); - if (CastResult.isInvalid()) - return ExprError(); - CastExpr = CastResult.take(); - - return Owned(CStyleCastExpr::Create(Context, Ty->getType(), VK_RValue, Kind, - CastExpr, /*base path*/ 0, Ty, - LParenLoc, RParenLoc)); -} - ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc, SourceLocation RParenLoc, Expr *E, TypeSourceInfo *TInfo) { @@ -4425,7 +4216,7 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc, QualType ElemTy = Ty->getAs<VectorType>()->getElementType(); ExprResult Literal = Owned(exprs[0]); Literal = ImpCastExprToType(Literal.take(), ElemTy, - PrepareScalarCast(*this, Literal, ElemTy)); + PrepareScalarCast(Literal, ElemTy)); return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take()); } else if (numExprs < numElems) { @@ -4446,7 +4237,7 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc, QualType ElemTy = Ty->getAs<VectorType>()->getElementType(); ExprResult Literal = Owned(exprs[0]); Literal = ImpCastExprToType(Literal.take(), ElemTy, - PrepareScalarCast(*this, Literal, ElemTy)); + PrepareScalarCast(Literal, ElemTy)); return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take()); } @@ -5432,7 +5223,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, // element type. QualType elType = cast<ExtVectorType>(LHSType)->getElementType(); if (elType != RHSType) { - Kind = PrepareScalarCast(*this, RHS, elType); + Kind = PrepareScalarCast(RHS, elType); RHS = ImpCastExprToType(RHS.take(), elType, Kind); } Kind = CK_VectorSplat; @@ -5465,7 +5256,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, // Arithmetic conversions. if (LHSType->isArithmeticType() && RHSType->isArithmeticType() && !(getLangOptions().CPlusPlus && LHSType->isEnumeralType())) { - Kind = PrepareScalarCast(*this, RHS, LHSType); + Kind = PrepareScalarCast(RHS, LHSType); return Compatible; } |