aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2008-07-03 04:20:39 +0000
committerAnders Carlsson <andersca@mac.com>2008-07-03 04:20:39 +0000
commitc44eec6dd29ee9415cbd38a35deff4c8b67abb6a (patch)
treeb3cac552b6f65c3a5124309a82853842e4f0f03a /lib/AST/ExprConstant.cpp
parent2e478080f83f90728d8d56099cd32180c57debbc (diff)
Shuffle things around in preparation for integrating Eli's constant evaluator.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53074 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r--lib/AST/ExprConstant.cpp60
1 files changed, 60 insertions, 0 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
new file mode 100644
index 0000000000..ea9b106b69
--- /dev/null
+++ b/lib/AST/ExprConstant.cpp
@@ -0,0 +1,60 @@
+//===--- Expr.cpp - Expression Constant Evaluator -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Expr constant evaluator.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/APValue.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+
+using namespace clang;
+
+
+static bool CalcFakeICEVal(const Expr* Expr,
+ llvm::APSInt& Result,
+ ASTContext& Context) {
+ // Calculate the value of an expression that has a calculatable
+ // value, but isn't an ICE. Currently, this only supports
+ // a very narrow set of extensions, but it can be expanded if needed.
+ if (const ParenExpr *PE = dyn_cast<ParenExpr>(Expr))
+ return CalcFakeICEVal(PE->getSubExpr(), Result, Context);
+
+ if (const CastExpr *CE = dyn_cast<CastExpr>(Expr)) {
+ QualType CETy = CE->getType();
+ if ((CETy->isIntegralType() && !CETy->isBooleanType()) ||
+ CETy->isPointerType()) {
+ if (CalcFakeICEVal(CE->getSubExpr(), Result, Context)) {
+ Result.extOrTrunc(Context.getTypeSize(CETy));
+ // FIXME: This assumes pointers are signed.
+ Result.setIsSigned(CETy->isSignedIntegerType() ||
+ CETy->isPointerType());
+ return true;
+ }
+ }
+ }
+
+ if (Expr->getType()->isIntegralType())
+ return Expr->isIntegerConstantExpr(Result, Context);
+
+ return false;
+}
+
+bool Expr::tryEvaluate(APValue& Result, ASTContext &Ctx) const
+{
+ llvm::APSInt sInt(1);
+
+ if (CalcFakeICEVal(this, sInt, Ctx)) {
+ Result = APValue(sInt);
+ return true;
+ }
+
+ return false;
+}