]> granicus.if.org Git - clang/commitdiff
Minor cleanup for choose expressions: add a helper that returns the
authorEli Friedman <eli.friedman@gmail.com>
Wed, 4 Mar 2009 05:52:32 +0000 (05:52 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Wed, 4 Mar 2009 05:52:32 +0000 (05:52 +0000)
chosen sub-expression, rather than just evaluating the condition.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66018 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
lib/AST/Expr.cpp
lib/AST/ExprConstant.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprComplex.cpp
lib/CodeGen/CGExprScalar.cpp

index e7c970285265206a36f1df2268b5657491ed0966..48c2ad0cefc41157e587425c0e9a730770abd930 100644 (file)
@@ -1493,9 +1493,12 @@ public:
 /// ChooseExpr - GNU builtin-in function __builtin_choose_expr.
 /// This AST node is similar to the conditional operator (?:) in C, with 
 /// the following exceptions:
-/// - the test expression must be a constant expression.
-/// - the expression returned has it's type unaltered by promotion rules.
-/// - does not evaluate the expression that was not chosen.
+/// - the test expression must be a integer constant expression.
+/// - the expression returned acts like the chosen subexpression in every
+///   visible way: the type is the same as that of the chosen subexpression,
+///   and all predicates (whether it's an l-value, whether it's an integer
+///   constant expression, etc.) return the same result as for the chosen
+///   sub-expression.
 class ChooseExpr : public Expr {
   enum { COND, LHS, RHS, END_EXPR };
   Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
@@ -1509,11 +1512,17 @@ public:
       SubExprs[LHS] = lhs;
       SubExprs[RHS] = rhs;
     }        
-  
-  /// isConditionTrue - Return true if the condition is true.  This is always
-  /// statically knowable for a well-formed choosexpr.
+
+  /// isConditionTrue - Return whether the condition is true (i.e. not
+  /// equal to zero).
   bool isConditionTrue(ASTContext &C) const;
-  
+
+  /// getChosenSubExpr - Return the subexpression chosen according to the
+  /// condition.
+  Expr *getChosenSubExpr(ASTContext &C) const {
+    return isConditionTrue(C) ? getLHS() : getRHS();
+  }
+
   Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
   Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
   Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
index d0d14f2b7af95ff102c23a3f5ed6acd7a8b7bd60..38bcc9bf3153564fdb9083d9f00740a026bd74dc 100644 (file)
@@ -603,11 +603,7 @@ Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
     return LV_Valid;
   case ChooseExprClass:
     // __builtin_choose_expr is an lvalue if the selected operand is.
-    if (cast<ChooseExpr>(this)->isConditionTrue(Ctx))
-      return cast<ChooseExpr>(this)->getLHS()->isLvalue(Ctx);
-    else
-      return cast<ChooseExpr>(this)->getRHS()->isLvalue(Ctx);
-
+    return cast<ChooseExpr>(this)->getChosenSubExpr(Ctx)->isLvalue(Ctx);
   case ExtVectorElementExprClass:
     if (cast<ExtVectorElementExpr>(this)->containsDuplicateElements())
       return LV_DuplicateVectorComponents;
@@ -1110,9 +1106,7 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
   case Expr::CXXDefaultArgExprClass:
     return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx);
   case Expr::ChooseExprClass: {
-    const ChooseExpr *CE = cast<ChooseExpr>(E);
-    Expr *SubExpr = CE->isConditionTrue(Ctx) ? CE->getLHS() : CE->getRHS();
-    return CheckICE(SubExpr, Ctx);
+    return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(Ctx), Ctx);
   }
   }
 }
index 86a7e8217f73821ba1a121aa1821b32807232a35..6fb2abe7cd7f02f553eea33aeea38c06739fc804 100644 (file)
@@ -389,10 +389,8 @@ APValue PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) {
 }
 
 APValue PointerExprEvaluator::VisitChooseExpr(ChooseExpr *E) {
-  Expr* EvalExpr = E->isConditionTrue(Info.Ctx) ? E->getLHS() : E->getRHS();
-
   APValue Result;
-  if (EvaluatePointer(EvalExpr, Result, Info))
+  if (EvaluatePointer(E->getChosenSubExpr(Info.Ctx), Result, Info))
     return Result;
   return APValue();
 }
@@ -522,10 +520,8 @@ APValue VectorExprEvaluator::VisitConditionalOperator(const ConditionalOperator
 }
 
 APValue VectorExprEvaluator::VisitChooseExpr(const ChooseExpr *E) {
-  Expr* EvalExpr = E->isConditionTrue(Info.Ctx) ? E->getLHS() : E->getRHS();
-
   APValue Result;
-  if (EvaluateVector(EvalExpr, Result, Info))
+  if (EvaluateVector(E->getChosenSubExpr(Info.Ctx), Result, Info))
     return Result;
   return APValue();
 }
@@ -1185,9 +1181,7 @@ bool IntExprEvaluator::VisitCastExpr(CastExpr *E) {
 }
 
 bool IntExprEvaluator::VisitChooseExpr(const ChooseExpr *E) {
-  Expr* EvalExpr = E->isConditionTrue(Info.Ctx) ? E->getLHS() : E->getRHS();
-
-  return Visit(EvalExpr);
+  return Visit(E->getChosenSubExpr(Info.Ctx));
 }
 
 bool IntExprEvaluator::VisitUnaryReal(const UnaryOperator *E) {
index d54c6954fb26cb6803a13c87bd55fe1b78dda35e..3ab85686752cbd3ef9b864af179d5ca0be726f5b 100644 (file)
@@ -178,11 +178,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
   case Expr::CompoundLiteralExprClass:
     return EmitCompoundLiteralLValue(cast<CompoundLiteralExpr>(E));
   case Expr::ChooseExprClass:
-    // __builtin_choose_expr is the lvalue of the selected operand.
-    if (cast<ChooseExpr>(E)->isConditionTrue(getContext()))
-      return EmitLValue(cast<ChooseExpr>(E)->getLHS());
-    else
-      return EmitLValue(cast<ChooseExpr>(E)->getRHS());
+    return EmitLValue(cast<ChooseExpr>(E)->getChosenSubExpr(getContext()));
   }
 }
 
index c676b579e6522febc1bd1cdca38ce0d21ec887c3..e970ba2561c9b01b06c2626db9cf94700572f99c 100644 (file)
@@ -509,8 +509,7 @@ VisitConditionalOperator(const ConditionalOperator *E) {
 }
 
 ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) {
-  // Emit the LHS or RHS as appropriate.
-  return Visit(E->isConditionTrue(CGF.getContext()) ? E->getLHS() :E->getRHS());
+  return Visit(E->getChosenSubExpr(CGF.getContext()));
 }
 
 ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) {
index 38cc3eec5dc760338df473a046f6c3875fe571d8..9951d8794b8992b93138bdcc10998f847db6511e 100644 (file)
@@ -1307,9 +1307,7 @@ VisitConditionalOperator(const ConditionalOperator *E) {
 }
 
 Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
-  // Emit the LHS or RHS as appropriate.
-  return
-    Visit(E->isConditionTrue(CGF.getContext()) ? E->getLHS() : E->getRHS());
+  return Visit(E->getChosenSubExpr(CGF.getContext()));
 }
 
 Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {