aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2008-07-08 14:30:00 +0000
committerAnders Carlsson <andersca@mac.com>2008-07-08 14:30:00 +0000
commit2bad1687fe6f00e10767a691a33b070b151902b6 (patch)
treea215e96d58309cf5aced0c25fc680ccceca5a790 /lib/AST/ExprConstant.cpp
parent0fe52e1bcaa69ba127f1bda036f057fec1f478de (diff)
More work.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53233 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r--lib/AST/ExprConstant.cpp79
1 files changed, 78 insertions, 1 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 3be2f94f23..5307a56fab 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -52,6 +52,32 @@ static bool CalcFakeICEVal(const Expr* Expr,
}
namespace {
+class VISIBILITY_HIDDEN PointerExprEvaluator
+ : public StmtVisitor<PointerExprEvaluator, APValue> {
+ ASTContext &Ctx;
+
+ PointerExprEvaluator(ASTContext &ctx)
+ : Ctx(ctx) {}
+
+public:
+ static bool Evaluate(const Expr* E, APValue& Result, ASTContext &Ctx) {
+ Result = PointerExprEvaluator(Ctx).Visit(const_cast<Expr*>(E));
+ return Result.isLValue();
+ }
+
+ APValue VisitStmt(Stmt *S) {
+ // FIXME: Remove this when we support more expressions.
+ printf("Unhandled statement\n");
+ S->dump();
+ return APValue();
+ }
+
+ APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
+
+};
+}
+
+namespace {
class VISIBILITY_HIDDEN IntExprEvaluator
: public StmtVisitor<IntExprEvaluator, APValue> {
ASTContext &Ctx;
@@ -84,7 +110,7 @@ public:
APValue VisitBinaryOperator(const BinaryOperator *E) {
// The LHS of a constant expr is always evaluated and needed.
llvm::APSInt Result(32);
- if (!Evaluate(E->getRHS(), Result, Ctx))
+ if (!Evaluate(E->getLHS(), Result, Ctx))
return APValue();
llvm::APSInt RHS(32);
@@ -209,6 +235,57 @@ public:
Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
return APValue(Result);
}
+
+ APValue HandleCast(const Expr* SubExpr, QualType DestType) {
+ llvm::APSInt Result(32);
+
+ uint32_t DestWidth = static_cast<uint32_t>(Ctx.getTypeSize(DestType));
+
+ // Handle simple integer->integer casts.
+ if (SubExpr->getType()->isIntegerType()) {
+ if (!Evaluate(SubExpr, Result, Ctx))
+ return APValue();
+
+ // Figure out if this is a truncate, extend or noop cast.
+ // If the input is signed, do a sign extend, noop, or truncate.
+ if (DestType->isBooleanType()) {
+ // Conversion to bool compares against zero.
+ Result = Result != 0;
+ Result.zextOrTrunc(DestWidth);
+ }
+ else
+ Result.extOrTrunc(DestWidth);
+ } else if (SubExpr->getType()->isPointerType()) {
+ APValue LV;
+ if (!PointerExprEvaluator::Evaluate(SubExpr, LV, Ctx))
+ return APValue();
+ if (LV.getLValueBase())
+ return APValue();
+
+ Result = llvm::APSInt(DestWidth, LV.getLValueOffset());
+ } else {
+ assert(0 && "Unhandled cast!");
+ }
+
+ Result.setIsUnsigned(DestType->isUnsignedIntegerType());
+ return APValue(Result);
+ }
+
+ APValue VisitImplicitCastExpr(const ImplicitCastExpr *E) {
+ return HandleCast(E->getSubExpr(), E->getType());
+ }
+
+ APValue VisitCastExpr(const CastExpr *E) {
+ return HandleCast(E->getSubExpr(), E->getType());
+ }
+
+ APValue VisitIntegerLiteral(const IntegerLiteral *E) {
+ llvm::APSInt Result(Ctx.getTypeSize(E->getType()));
+
+ Result = E->getValue();
+ return APValue(Result);
+ }
+
};
}