diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Expr.cpp | 22 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 32 |
2 files changed, 14 insertions, 40 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index c2880a0ad1..08611c32c6 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -2541,23 +2541,27 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef) const { case CXXFunctionalCastExprClass: case CXXStaticCastExprClass: case ImplicitCastExprClass: - case CStyleCastExprClass: + case CStyleCastExprClass: { + const CastExpr *CE = cast<CastExpr>(this); + + // Handle bitcasts of vector constants. + if (getType()->isVectorType() && CE->getCastKind() == CK_BitCast) + return CE->getSubExpr()->isConstantInitializer(Ctx, false); + // Handle casts with a destination that's a struct or union; this // deals with both the gcc no-op struct cast extension and the // cast-to-union extension. if (getType()->isRecordType()) - return cast<CastExpr>(this)->getSubExpr() - ->isConstantInitializer(Ctx, false); - + return CE->getSubExpr()->isConstantInitializer(Ctx, false); + // Integer->integer casts can be handled here, which is important for // things like (int)(&&x-&&y). Scary but true. if (getType()->isIntegerType() && - cast<CastExpr>(this)->getSubExpr()->getType()->isIntegerType()) - return cast<CastExpr>(this)->getSubExpr() - ->isConstantInitializer(Ctx, false); - + CE->getSubExpr()->getType()->isIntegerType()) + return CE->getSubExpr()->isConstantInitializer(Ctx, false); + break; - + } case MaterializeTemporaryExprClass: return cast<MaterializeTemporaryExpr>(this)->GetTemporaryExpr() ->isConstantInitializer(Ctx, false); diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 438bef5de8..6a290a6c83 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -2502,11 +2502,9 @@ static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) { bool VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { const VectorType *VTy = E->getType()->castAs<VectorType>(); - QualType EltTy = VTy->getElementType(); unsigned NElts = VTy->getNumElements(); - unsigned EltWidth = Info.Ctx.getTypeSize(EltTy); - const Expr* SE = E->getSubExpr(); + const Expr *SE = E->getSubExpr(); QualType SETy = SE->getType(); switch (E->getCastKind()) { @@ -2530,34 +2528,6 @@ bool VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { SmallVector<APValue, 4> Elts(NElts, Val); return Success(Elts, E); } - case CK_BitCast: { - // FIXME: this is wrong for any cast other than a no-op cast. - if (SETy->isVectorType()) - return Visit(SE); - - if (!SETy->isIntegerType()) - return Error(E); - - APSInt Init; - if (!EvaluateInteger(SE, Init, Info)) - return Error(E); - - assert((EltTy->isIntegerType() || EltTy->isRealFloatingType()) && - "Vectors must be composed of ints or floats"); - - SmallVector<APValue, 4> 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 Success(Elts, E); - } default: return ExprEvaluatorBaseTy::VisitCastExpr(E); } |