From 46a523285928aa07bf14803178dc04616ac85994 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Fri, 25 Mar 2011 00:43:55 +0000 Subject: [PATCH] Cleanup integral and vector constant evaluation of casts to use cast kinds. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128250 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ExprConstant.cpp | 192 +++++++++++++++++++++------------------ 1 file changed, 105 insertions(+), 87 deletions(-) diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 345c7fa8c0..c44428b0f1 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -590,7 +590,6 @@ bool PointerExprEvaluator::VisitCastExpr(CastExpr* E) { case CK_NoOp: case CK_BitCast: - case CK_LValueBitCast: case CK_AnyPointerToObjCPointerCast: case CK_AnyPointerToBlockPointerCast: return Visit(SubExpr); @@ -756,68 +755,61 @@ APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { const Expr* SE = E->getSubExpr(); QualType SETy = SE->getType(); - APValue Result = APValue(); - // Check for vector->vector bitcast and scalar->vector splat. - if (SETy->isVectorType()) { - return this->Visit(const_cast(SE)); - } else if (SETy->isIntegerType()) { - APSInt IntResult; - if (!EvaluateInteger(SE, IntResult, Info)) - return APValue(); - Result = APValue(IntResult); - } else if (SETy->isRealFloatingType()) { - APFloat F(0.0); - if (!EvaluateFloat(SE, F, Info)) - return APValue(); - Result = APValue(F); - } else - return APValue(); - - // For casts of a scalar to ExtVector, convert the scalar to the element type - // and splat it to all elements. - if (E->getType()->isExtVectorType()) { - if (EltTy->isIntegerType() && Result.isInt()) - Result = APValue(HandleIntToIntCast(EltTy, SETy, Result.getInt(), - Info.Ctx)); - else if (EltTy->isIntegerType()) - Result = APValue(HandleFloatToIntCast(EltTy, SETy, Result.getFloat(), - Info.Ctx)); - else if (EltTy->isRealFloatingType() && Result.isInt()) - Result = APValue(HandleIntToFloatCast(EltTy, SETy, Result.getInt(), - Info.Ctx)); - else if (EltTy->isRealFloatingType()) - Result = APValue(HandleFloatToFloatCast(EltTy, SETy, Result.getFloat(), - Info.Ctx)); - else - return APValue(); + switch (E->getCastKind()) { + case CK_VectorSplat: { + APValue Result = APValue(); + if (SETy->isIntegerType()) { + APSInt IntResult; + if (!EvaluateInteger(SE, IntResult, Info)) + return APValue(); + Result = APValue(IntResult); + } else if (SETy->isRealFloatingType()) { + APFloat F(0.0); + if (!EvaluateFloat(SE, F, Info)) + return APValue(); + Result = APValue(F); + } else { + return false; + } // Splat and create vector APValue. llvm::SmallVector Elts(NElts, Result); return APValue(&Elts[0], Elts.size()); } + case CK_BitCast: { + if (SETy->isVectorType()) + return Visit(const_cast(SE)); - // For casts of a scalar to regular gcc-style vector type, bitcast the scalar - // to the vector. To construct the APValue vector initializer, bitcast the - // initializing value to an APInt, and shift out the bits pertaining to each - // element. - APSInt Init; - Init = Result.isInt() ? Result.getInt() : Result.getFloat().bitcastToAPInt(); - - llvm::SmallVector Elts; - for (unsigned i = 0; i != NElts; ++i) { - APSInt Tmp = Init.extOrTrunc(EltWidth); + if (!SETy->isIntegerType()) + return false; - if (EltTy->isIntegerType()) - Elts.push_back(APValue(Tmp)); - else if (EltTy->isRealFloatingType()) - Elts.push_back(APValue(APFloat(Tmp))); - else + APSInt Init; + if (!EvaluateInteger(SE, Init, Info)) return APValue(); - Init >>= EltWidth; + assert((EltTy->isIntegerType() || EltTy->isRealFloatingType()) && + "Vectors must be composed of ints or floats"); + + llvm::SmallVector Elts; + for (unsigned i = 0; i != NElts; ++i) { + APSInt Tmp = Init.extOrTrunc(EltWidth); + + if (EltTy->isIntegerType()) + Elts.push_back(APValue(Tmp)); + else + Elts.push_back(APValue(APFloat(Tmp))); + + Init >>= EltWidth; + } + return APValue(&Elts[0], Elts.size()); + } + case CK_LValueToRValue: + case CK_NoOp: + return Visit(const_cast(SE)); + default: + return false; } - return APValue(&Elts[0], Elts.size()); } APValue @@ -1771,15 +1763,60 @@ bool IntExprEvaluator::VisitCastExpr(CastExpr *E) { QualType DestType = E->getType(); QualType SrcType = SubExpr->getType(); - if (DestType->isBooleanType()) { + switch (E->getCastKind()) { + case CK_BitCast: + case CK_BaseToDerived: + case CK_DerivedToBase: + case CK_UncheckedDerivedToBase: + case CK_Dynamic: + case CK_ToUnion: + case CK_ArrayToPointerDecay: + case CK_FunctionToPointerDecay: + case CK_NullToPointer: + case CK_NullToMemberPointer: + case CK_BaseToDerivedMemberPointer: + case CK_DerivedToBaseMemberPointer: + case CK_ConstructorConversion: + case CK_IntegralToPointer: + case CK_ToVoid: + case CK_VectorSplat: + case CK_IntegralToFloating: + case CK_FloatingCast: + case CK_AnyPointerToObjCPointerCast: + case CK_AnyPointerToBlockPointerCast: + case CK_ObjCObjectLValueCast: + case CK_FloatingRealToComplex: + case CK_FloatingComplexToReal: + case CK_FloatingComplexCast: + case CK_FloatingComplexToIntegralComplex: + case CK_IntegralRealToComplex: + case CK_IntegralComplexCast: + case CK_IntegralComplexToFloatingComplex: + llvm_unreachable("invalid cast kind for integral value"); + + case CK_Dependent: + case CK_GetObjCProperty: + case CK_LValueBitCast: + case CK_UserDefinedConversion: + return false; + + case CK_LValueToRValue: + case CK_NoOp: + return Visit(E->getSubExpr()); + + case CK_MemberPointerToBoolean: + case CK_PointerToBoolean: + case CK_IntegralToBoolean: + case CK_FloatingToBoolean: + case CK_FloatingComplexToBoolean: + case CK_IntegralComplexToBoolean: { bool BoolResult; if (!HandleConversionToBool(SubExpr, BoolResult, Info)) return false; return Success(BoolResult, E); } - // Handle simple integer->integer casts. - if (SrcType->isIntegralOrEnumerationType()) { + case CK_IntegralCast: { if (!Visit(SubExpr)) return false; @@ -1792,8 +1829,7 @@ bool IntExprEvaluator::VisitCastExpr(CastExpr *E) { Result.getInt(), Info.Ctx), E); } - // FIXME: Clean this up! - if (SrcType->isPointerType()) { + case CK_PointerToIntegral: { LValue LV; if (!EvaluatePointer(SubExpr, LV, Info)) return false; @@ -1812,42 +1848,24 @@ bool IntExprEvaluator::VisitCastExpr(CastExpr *E) { return Success(HandleIntToIntCast(DestType, SrcType, AsInt, Info.Ctx), E); } - if (SrcType->isArrayType() || SrcType->isFunctionType()) { - // This handles double-conversion cases, where there's both - // an l-value promotion and an implicit conversion to int. - LValue LV; - if (!EvaluateLValue(SubExpr, LV, Info)) - return false; - - if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(Info.Ctx.VoidPtrTy)) - return false; - - LV.moveInto(Result); - return true; - } - - if (SrcType->isAnyComplexType()) { + case CK_IntegralComplexToReal: { ComplexValue C; if (!EvaluateComplex(SubExpr, C, Info)) return false; - if (C.isComplexFloat()) - return Success(HandleFloatToIntCast(DestType, SrcType, - C.getComplexFloatReal(), Info.Ctx), - E); - else - return Success(HandleIntToIntCast(DestType, SrcType, - C.getComplexIntReal(), Info.Ctx), E); + return Success(C.getComplexIntReal(), E); } - // FIXME: Handle vectors - if (!SrcType->isRealFloatingType()) - return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E); + case CK_FloatingToIntegral: { + APFloat F(0.0); + if (!EvaluateFloat(SubExpr, F, Info)) + return false; - APFloat F(0.0); - if (!EvaluateFloat(SubExpr, F, Info)) - return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E); + return Success(HandleFloatToIntCast(DestType, SrcType, F, Info.Ctx), E); + } + } - return Success(HandleFloatToIntCast(DestType, SrcType, F, Info.Ctx), E); + llvm_unreachable("unknown cast resulting in integral value"); + return false; } bool IntExprEvaluator::VisitUnaryReal(const UnaryOperator *E) { @@ -2282,7 +2300,6 @@ bool ComplexExprEvaluator::VisitCastExpr(CastExpr *E) { switch (E->getCastKind()) { case CK_BitCast: - case CK_LValueBitCast: case CK_BaseToDerived: case CK_DerivedToBase: case CK_UncheckedDerivedToBase: @@ -2322,6 +2339,7 @@ bool ComplexExprEvaluator::VisitCastExpr(CastExpr *E) { case CK_Dependent: case CK_GetObjCProperty: + case CK_LValueBitCast: case CK_UserDefinedConversion: return false; -- 2.40.0