[cfe-commits] r65063 - /cfe/trunk/lib/AST/ExprConstant.cpp

Daniel Dunbar daniel at zuster.org
Thu Feb 19 12:17:33 PST 2009


Author: ddunbar
Date: Thu Feb 19 14:17:33 2009
New Revision: 65063

URL: http://llvm.org/viewvc/llvm-project?rev=65063&view=rev
Log:
Change IntExprEvaluator to operate on an APValue not an APSInt.
 - Prep for handling lvalues, no intended functionality change.

Modified:
    cfe/trunk/lib/AST/ExprConstant.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=65063&r1=65062&r2=65063&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Feb 19 14:17:33 2009
@@ -457,9 +457,9 @@
 class VISIBILITY_HIDDEN IntExprEvaluator
   : public StmtVisitor<IntExprEvaluator, bool> {
   EvalInfo &Info;
-  APSInt &Result;
+  APValue &Result;
 public:
-  IntExprEvaluator(EvalInfo &info, APSInt &result)
+  IntExprEvaluator(EvalInfo &info, APValue &result)
     : Info(info), Result(result) {}
 
   bool Extension(SourceLocation L, diag::kind D, const Expr *E) {
@@ -470,24 +470,24 @@
   }
 
   bool Success(const llvm::APSInt &SI, const Expr *E) {
-    Result = SI;
-    assert(Result.isSigned() == E->getType()->isSignedIntegerType() &&
+    assert(SI.isSigned() == E->getType()->isSignedIntegerType() &&
            "Invalid evaluation result.");
-    assert(Result.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
+    assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
            "Invalid evaluation result.");
+    Result = APValue(SI);
     return true;
   }
 
   bool Success(const llvm::APInt &I, const Expr *E) {
-    Result = I;
-    Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
-    assert(Result.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
+    assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
            "Invalid evaluation result.");
+    Result = APValue(APSInt(I));
+    Result.getInt().setIsUnsigned(E->getType()->isUnsignedIntegerType());
     return true;
   }
 
   bool Success(uint64_t Value, const Expr *E) {
-    Result = Info.Ctx.MakeIntValue(Value, E->getType());
+    Result = APValue(Info.Ctx.MakeIntValue(Value, E->getType()));
     return true;
   }
 
@@ -501,6 +501,9 @@
     }
     
     // Take the first error.
+
+    // FIXME: This is wrong if we happen to have already emitted an
+    // extension diagnostic; in that case we should report this error.
     if (Info.EvalResult.Diag == 0) {
       Info.EvalResult.DiagLoc = L;
       Info.EvalResult.Diag = D;
@@ -574,7 +577,14 @@
 static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {
   if (!E->getType()->isIntegralType())
     return false;
-  return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
+  
+  APValue Val;
+  if (!IntExprEvaluator(Info, Val).Visit(const_cast<Expr*>(E)) ||
+      !Val.isInt())
+    return false;
+
+  Result = Val.getInt();
+  return true;
 }
 
 bool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
@@ -842,10 +852,13 @@
   }
 
   // The LHS of a constant expr is always evaluated and needed.
-  if (!Visit(E->getLHS())) {
+  if (!Visit(E->getLHS()))
     return false; // error in subexpression.
-  }
 
+  // Only support arithmetic on integers for now.
+  if (!Result.isInt())
+    return false;
+  
   llvm::APSInt RHS;
   if (!EvaluateInteger(E->getRHS(), RHS, Info))
     return false;
@@ -853,36 +866,38 @@
   switch (E->getOpcode()) {
   default:
     return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E);
-  case BinaryOperator::Mul: return Success(Result * RHS, E);
-  case BinaryOperator::Add: return Success(Result + RHS, E);
-  case BinaryOperator::Sub: return Success(Result - RHS, E);
-  case BinaryOperator::And: return Success(Result & RHS, E);
-  case BinaryOperator::Xor: return Success(Result ^ RHS, E);
-  case BinaryOperator::Or:  return Success(Result | RHS, E);
+  case BinaryOperator::Mul: return Success(Result.getInt() * RHS, E);
+  case BinaryOperator::Add: return Success(Result.getInt() + RHS, E);
+  case BinaryOperator::Sub: return Success(Result.getInt() - RHS, E);
+  case BinaryOperator::And: return Success(Result.getInt() & RHS, E);
+  case BinaryOperator::Xor: return Success(Result.getInt() ^ RHS, E);
+  case BinaryOperator::Or:  return Success(Result.getInt() | RHS, E);
   case BinaryOperator::Div:
     if (RHS == 0)
       return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E);
-    return Success(Result / RHS, E);
+    return Success(Result.getInt() / RHS, E);
   case BinaryOperator::Rem:
     if (RHS == 0)
       return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E);
-    return Success(Result % RHS, E);
+    return Success(Result.getInt() % RHS, E);
   case BinaryOperator::Shl: {
     // FIXME: Warn about out of range shift amounts!
-    unsigned SA = (unsigned) RHS.getLimitedValue(Result.getBitWidth()-1);
-    return Success(Result << SA, E);
+    unsigned SA = 
+      (unsigned) RHS.getLimitedValue(Result.getInt().getBitWidth()-1);
+    return Success(Result.getInt() << SA, E);
   }
   case BinaryOperator::Shr: {
-    unsigned SA = (unsigned) RHS.getLimitedValue(Result.getBitWidth()-1);
-    return Success(Result >> SA, E);
+    unsigned SA = 
+      (unsigned) RHS.getLimitedValue(Result.getInt().getBitWidth()-1);
+    return Success(Result.getInt() >> SA, E);
   }
       
-  case BinaryOperator::LT: return Success(Result < RHS, E);
-  case BinaryOperator::GT: return Success(Result > RHS, E);
-  case BinaryOperator::LE: return Success(Result <= RHS, E);
-  case BinaryOperator::GE: return Success(Result >= RHS, E);
-  case BinaryOperator::EQ: return Success(Result == RHS, E);
-  case BinaryOperator::NE: return Success(Result != RHS, E);
+  case BinaryOperator::LT: return Success(Result.getInt() < RHS, E);
+  case BinaryOperator::GT: return Success(Result.getInt() > RHS, E);
+  case BinaryOperator::LE: return Success(Result.getInt() <= RHS, E);
+  case BinaryOperator::GE: return Success(Result.getInt() >= RHS, E);
+  case BinaryOperator::EQ: return Success(Result.getInt() == RHS, E);
+  case BinaryOperator::NE: return Success(Result.getInt() != RHS, E);
   }
 }
 
@@ -1007,9 +1022,11 @@
     // The result is always just the subexpr. 
     return true;
   case UnaryOperator::Minus:
-    return Success(-Result, E);
+    if (!Result.isInt()) return false;
+    return Success(-Result.getInt(), E);
   case UnaryOperator::Not:
-    return Success(~Result, E);
+    if (!Result.isInt()) return false;
+    return Success(~Result.getInt(), E);
   }
 }
   
@@ -1031,8 +1048,12 @@
     if (!Visit(SubExpr))
       return false;
 
+    // FIXME: Support cast on LValue results.
+    if (!Result.isInt())
+      return false;
+
     return Success(HandleIntToIntCast(DestType, SubExpr->getType(), 
-                                      Result, Info.Ctx), E);
+                                      Result.getInt(), Info.Ctx), E);
   }
   
   // FIXME: Clean this up!
@@ -1445,11 +1466,8 @@
     if (!EvaluateVector(this, Result.Val, Info))
       return false;
   } else if (getType()->isIntegerType()) {
-    llvm::APSInt sInt(32);
-    if (!EvaluateInteger(this, sInt, Info))
+    if (!IntExprEvaluator(Info, Result.Val).Visit(const_cast<Expr*>(this)))
       return false;
-    
-    Result.Val = APValue(sInt);
   } else if (getType()->isPointerType()
              || getType()->isBlockPointerType()) {
     if (!EvaluatePointer(this, Result.Val, Info))





More information about the cfe-commits mailing list