]> granicus.if.org Git - clang/commitdiff
A few small improvements to Evaluate for stuff I noted in FIXMEs.
authorEli Friedman <eli.friedman@gmail.com>
Mon, 23 Feb 2009 04:23:56 +0000 (04:23 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Mon, 23 Feb 2009 04:23:56 +0000 (04:23 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65305 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprConstant.cpp
test/Sema/init.c

index 6ce06e9dddde3942033c0e7922011358b1ba9a20..d868cba9eb0178bfa4645a60dc55f0048d29bbf9 100644 (file)
@@ -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<VectorExprEvaluator, APValue> {
     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<APValue, 4> 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<APValue, 4> 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
 //===----------------------------------------------------------------------===//
index e77cbfcdcfe89bc45d18f33696f40495ecb907b1..1f84e41eabf2f22d8911a056eafe1c278e847ae0 100644 (file)
@@ -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};
+