From 3ae59110424522e3b577d89371f07d79068d66bf Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Mon, 23 Feb 2009 04:23:56 +0000 Subject: [PATCH] A few small improvements to Evaluate for stuff I noted in FIXMEs. llvm-svn: 65305 --- clang/lib/AST/ExprConstant.cpp | 105 +++++++++++++++++++++++++++------ clang/test/Sema/init.c | 9 +++ 2 files changed, 97 insertions(+), 17 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 6ce06e9dddde..d868cba9eb01 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -274,9 +274,11 @@ public: return APValue(E, 0); return APValue(); } + APValue VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) + { return APValue((Expr*)0, 0); } APValue VisitConditionalOperator(ConditionalOperator *E); - // FIXME: Missing: __builtin_choose_expr, ImplicitValueInitExpr, comma, - // @encode, @protocol, @selector + APValue VisitChooseExpr(ChooseExpr *E); + // FIXME: Missing: @encode, @protocol, @selector }; } // end anonymous namespace @@ -396,6 +398,15 @@ APValue PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) { return APValue(); } +APValue PointerExprEvaluator::VisitChooseExpr(ChooseExpr *E) { + Expr* EvalExpr = E->isConditionTrue(Info.Ctx) ? E->getLHS() : E->getRHS(); + + APValue Result; + if (EvaluatePointer(EvalExpr, Result, Info)) + return Result; + return APValue(); +} + //===----------------------------------------------------------------------===// // Vector Evaluation //===----------------------------------------------------------------------===// @@ -404,6 +415,7 @@ namespace { class VISIBILITY_HIDDEN VectorExprEvaluator : public StmtVisitor { EvalInfo &Info; + APValue GetZeroVector(QualType VecType); public: VectorExprEvaluator(EvalInfo &info) : Info(info) {} @@ -412,17 +424,27 @@ namespace { return APValue(); } - APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } + APValue VisitParenExpr(ParenExpr *E) + { return Visit(E->getSubExpr()); } + APValue VisitUnaryExtension(const UnaryOperator *E) + { return Visit(E->getSubExpr()); } + APValue VisitUnaryPlus(const UnaryOperator *E) + { return Visit(E->getSubExpr()); } + APValue VisitUnaryReal(const UnaryOperator *E) + { return Visit(E->getSubExpr()); } + APValue VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) + { return GetZeroVector(E->getType()); } APValue VisitCastExpr(const CastExpr* E); APValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); APValue VisitInitListExpr(const InitListExpr *E); - // FIXME: Missing: __builtin_choose_expr, ImplicitValueInitExpr, - // __extension__, unary +/-, unary ~, - // __real__/__imag__, binary add/sub/mul/div, + APValue VisitConditionalOperator(const ConditionalOperator *E); + APValue VisitChooseExpr(const ChooseExpr *E); + APValue VisitUnaryImag(const UnaryOperator *E); + // FIXME: Missing: unary -, unary ~, binary add/sub/mul/div, // binary comparisons, binary and/or/xor, - // conditional ?:, shufflevector, ExtVectorElementExpr - // (Note that some of these would require acutually implementing - // conversions between vector types.) + // shufflevector, ExtVectorElementExpr + // (Note that these require implementing conversions + // between vector types.) }; } // end anonymous namespace @@ -452,29 +474,78 @@ APValue VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) { const VectorType *VT = E->getType()->getAsVectorType(); unsigned NumInits = E->getNumInits(); - - if (!VT || VT->getNumElements() != NumInits) - return APValue(); + unsigned NumElements = VT->getNumElements(); QualType EltTy = VT->getElementType(); llvm::SmallVector Elements; - for (unsigned i = 0; i < NumInits; i++) { + for (unsigned i = 0; i < NumElements; i++) { if (EltTy->isIntegerType()) { llvm::APSInt sInt(32); - if (!EvaluateInteger(E->getInit(i), sInt, Info)) - return APValue(); + if (i < NumInits) { + if (!EvaluateInteger(E->getInit(i), sInt, Info)) + return APValue(); + } else { + sInt = Info.Ctx.MakeIntValue(0, EltTy); + } Elements.push_back(APValue(sInt)); } else { llvm::APFloat f(0.0); - if (!EvaluateFloat(E->getInit(i), f, Info)) - return APValue(); + if (i < NumInits) { + if (!EvaluateFloat(E->getInit(i), f, Info)) + return APValue(); + } else { + f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)); + } Elements.push_back(APValue(f)); } } return APValue(&Elements[0], Elements.size()); } +APValue +VectorExprEvaluator::GetZeroVector(QualType T) { + const VectorType *VT = T->getAsVectorType(); + QualType EltTy = VT->getElementType(); + APValue ZeroElement; + if (EltTy->isIntegerType()) + ZeroElement = APValue(Info.Ctx.MakeIntValue(0, EltTy)); + else + ZeroElement = + APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy))); + + llvm::SmallVector Elements(VT->getNumElements(), ZeroElement); + return APValue(&Elements[0], Elements.size()); +} + +APValue VectorExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) { + bool BoolResult; + if (!HandleConversionToBool(E->getCond(), BoolResult, Info)) + return APValue(); + + Expr* EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr(); + + APValue Result; + if (EvaluateVector(EvalExpr, Result, Info)) + return Result; + return APValue(); +} + +APValue VectorExprEvaluator::VisitChooseExpr(const ChooseExpr *E) { + Expr* EvalExpr = E->isConditionTrue(Info.Ctx) ? E->getLHS() : E->getRHS(); + + APValue Result; + if (EvaluateVector(EvalExpr, Result, Info)) + return Result; + return APValue(); +} + +APValue VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { + if (!E->getSubExpr()->isEvaluatable(Info.Ctx)) + Info.EvalResult.HasSideEffects = true; + return GetZeroVector(E->getType()); +} + //===----------------------------------------------------------------------===// // Integer Evaluation //===----------------------------------------------------------------------===// diff --git a/clang/test/Sema/init.c b/clang/test/Sema/init.c index e77cbfcdcfe8..1f84e41eabf2 100644 --- a/clang/test/Sema/init.c +++ b/clang/test/Sema/init.c @@ -110,3 +110,12 @@ struct foo2 bar2[] = { }; struct foo2 bar3 = { 1, 2 }; // expected-warning{{excess elements in struct initializer}} + +int* ptest1 = __builtin_choose_expr(1, (int*)0, (int*)0); + +typedef int32_t ivector4 __attribute((vector_size(16))); +ivector4 vtest1 = 1 ? (ivector4){1} : (ivector4){1}; +ivector4 vtest2 = __builtin_choose_expr(1, (ivector4){1}, (ivector4){1}); +ivector4 vtest3 = __real__ (ivector4){1}; +ivector4 vtest4 = __imag__ (ivector4){1}; +