make the new evaluator avoid conversions APValue<->APSInt in some cases.
Add some accessors to APValue.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53465 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 6be7268..5826fab 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -1,4 +1,4 @@
-//===--- Expr.cpp - Expression Constant Evaluator -------------------------===//
+//===--- ExprConstant.cpp - Expression Constant Evaluator -----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -116,8 +116,7 @@
}
-APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E)
-{
+APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
const Expr* SubExpr = E->getSubExpr();
// Check for pointer->pointer cast
@@ -144,95 +143,86 @@
//===----------------------------------------------------------------------===//
// Integer Evaluation
//===----------------------------------------------------------------------===//
-
namespace {
class VISIBILITY_HIDDEN IntExprEvaluator
- : public StmtVisitor<IntExprEvaluator, APValue> {
+ : public StmtVisitor<IntExprEvaluator, bool> {
ASTContext &Ctx;
-
+ APSInt &Result;
public:
- IntExprEvaluator(ASTContext &ctx) : Ctx(ctx) {}
+ IntExprEvaluator(ASTContext &ctx, APSInt &result) : Ctx(ctx), Result(result){}
//===--------------------------------------------------------------------===//
// Visitor Methods
//===--------------------------------------------------------------------===//
- APValue VisitStmt(Stmt *S) {
+ bool VisitStmt(Stmt *S) {
// FIXME: Remove this when we support more expressions.
printf("unhandled int expression");
S->dump();
- return APValue();
+ return false;
}
- APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
+ bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
- APValue VisitBinaryOperator(const BinaryOperator *E);
- APValue VisitUnaryOperator(const UnaryOperator *E);
+ bool VisitBinaryOperator(const BinaryOperator *E);
+ bool VisitUnaryOperator(const UnaryOperator *E);
- APValue HandleCast(const Expr* SubExpr, QualType DestType);
- APValue VisitCastExpr(const CastExpr* E) {
+ bool HandleCast(const Expr* SubExpr, QualType DestType);
+ bool VisitCastExpr(const CastExpr* E) {
return HandleCast(E->getSubExpr(), E->getType());
}
- APValue VisitImplicitCastExpr(const ImplicitCastExpr* E) {
+ bool VisitImplicitCastExpr(const ImplicitCastExpr* E) {
return HandleCast(E->getSubExpr(), E->getType());
}
- APValue VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E);
+ bool VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E);
- APValue VisitIntegerLiteral(const IntegerLiteral *E) {
- llvm::APSInt Result(Ctx.getTypeSize(E->getType()));
-
+ bool VisitIntegerLiteral(const IntegerLiteral *E) {
Result = E->getValue();
- return APValue(Result);
+ return true;
}
};
} // end anonymous namespace
static bool EvaluateInteger(const Expr* E, APSInt &Result, ASTContext &Ctx) {
- APValue Value = IntExprEvaluator(Ctx).Visit(const_cast<Expr*>(E));
- if (!Value.isSInt())
- return false;
-
- Result = Value.getSInt();
- return true;
+ return IntExprEvaluator(Ctx, Result).Visit(const_cast<Expr*>(E));
}
-APValue IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
// The LHS of a constant expr is always evaluated and needed.
- llvm::APSInt Result(32);
- if (!EvaluateInteger(E->getLHS(), Result, Ctx))
- return APValue();
+ if (!Visit(E->getLHS()))
+ return false;
llvm::APSInt RHS(32);
if (!EvaluateInteger(E->getRHS(), RHS, Ctx))
- return APValue();
+ return false;
switch (E->getOpcode()) {
default:
- return APValue();
+ return false;
case BinaryOperator::Mul:
Result *= RHS;
break;
case BinaryOperator::Div:
if (RHS == 0)
- return APValue();
- Result /= RHS;
- break;
+ return false;
+ Result /= RHS;
+ break;
case BinaryOperator::Rem:
if (RHS == 0)
- return APValue();
+ return false;
Result %= RHS;
break;
case BinaryOperator::Add: Result += RHS; break;
case BinaryOperator::Sub: Result -= RHS; break;
case BinaryOperator::Shl:
- Result <<=
- static_cast<uint32_t>(RHS.getLimitedValue(Result.getBitWidth()-1));
+ Result <<= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
break;
case BinaryOperator::Shr:
- Result >>=
- static_cast<uint32_t>(RHS.getLimitedValue(Result.getBitWidth()-1));
+ Result >>= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
break;
+
+ // FIXME: Need to set the result width?
case BinaryOperator::LT: Result = Result < RHS; break;
case BinaryOperator::GT: Result = Result > RHS; break;
case BinaryOperator::LE: Result = Result <= RHS; break;
@@ -251,17 +241,14 @@
// FIXME: Need to come up with an efficient way to deal with the C99
// rules on evaluation while still evaluating this. Maybe a
// "evaluated comma" out parameter?
- return APValue();
+ return false;
}
Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
-
- return APValue(Result);
+ return true;
}
-APValue IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
- llvm::APSInt Result(32);
-
+bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
if (E->isOffsetOfOp())
Result = E->evaluateOffsetOf(Ctx);
else if (E->isSizeOfAlignOfOp()) {
@@ -275,7 +262,7 @@
// sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
if (!E->getSubExpr()->getType()->isConstantSizeType()) {
// FIXME: Should we attempt to evaluate this?
- return APValue();
+ return false;
}
// Get information about the size or align.
@@ -294,16 +281,16 @@
// Get the operand value. If this is sizeof/alignof, do not evalute the
// operand. This affects C99 6.6p3.
if (!EvaluateInteger(E->getSubExpr(), Result, Ctx))
- return APValue();
+ return false;
switch (E->getOpcode()) {
// Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
// See C99 6.6p3.
default:
- return APValue();
+ return false;
case UnaryOperator::Extension:
assert(0 && "Handle UnaryOperator::Extension");
- return APValue();
+ return false;
case UnaryOperator::LNot: {
bool Val = Result == 0;
uint32_t typeSize = Ctx.getTypeSize(E->getType());
@@ -323,10 +310,10 @@
}
Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return APValue(Result);
+ return true;
}
-APValue IntExprEvaluator::HandleCast(const Expr* SubExpr, QualType DestType) {
+bool IntExprEvaluator::HandleCast(const Expr* SubExpr, QualType DestType) {
llvm::APSInt Result(32);
uint32_t DestWidth = static_cast<uint32_t>(Ctx.getTypeSize(DestType));
@@ -334,7 +321,7 @@
// Handle simple integer->integer casts.
if (SubExpr->getType()->isIntegerType()) {
if (!EvaluateInteger(SubExpr, Result, Ctx))
- return APValue();
+ return false;
// Figure out if this is a truncate, extend or noop cast.
// If the input is signed, do a sign extend, noop, or truncate.
@@ -348,9 +335,9 @@
} else if (SubExpr->getType()->isPointerType()) {
APValue LV;
if (!EvaluatePointer(SubExpr, LV, Ctx))
- return APValue();
+ return false;
if (LV.getLValueBase())
- return APValue();
+ return false;
Result.extOrTrunc(DestWidth);
Result = LV.getLValueOffset();
@@ -359,13 +346,11 @@
}
Result.setIsUnsigned(DestType->isUnsignedIntegerType());
- return APValue(Result);
+ return true;
}
-APValue IntExprEvaluator::
- VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) {
- llvm::APSInt Result(32);
-
+bool IntExprEvaluator::
+VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) {
// Return the result in the right width.
Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(E->getType())));
@@ -373,12 +358,12 @@
if (E->getArgumentType()->isVoidType()) {
Result = 1;
Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return APValue(Result);
+ return true;
}
// alignof always evaluates to a constant, sizeof does if arg is not VLA.
if (E->isSizeOf() && !E->getArgumentType()->isConstantSizeType())
- return APValue();
+ return false;
// Get information about the size or align.
if (E->getArgumentType()->isFunctionType()) {
@@ -393,19 +378,18 @@
}
Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return APValue(Result);
+ return true;
}
//===----------------------------------------------------------------------===//
// Top level TryEvaluate.
//===----------------------------------------------------------------------===//
-bool Expr::tryEvaluate(APValue& Result, ASTContext &Ctx) const {
- llvm::APSInt sInt(1);
-
+bool Expr::tryEvaluate(APValue &Result, ASTContext &Ctx) const {
#if USE_NEW_EVALUATOR
if (getType()->isIntegerType()) {
- if (IntExprEvaluator::Evaluate(this, sInt, Ctx)) {
+ llvm::APSInt sInt(32);
+ if (EvaluateInteger(this, sInt, Ctx)) {
Result = APValue(sInt);
return true;
}