diff options
author | Anders Carlsson <andersca@mac.com> | 2008-07-03 04:20:39 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2008-07-03 04:20:39 +0000 |
commit | c44eec6dd29ee9415cbd38a35deff4c8b67abb6a (patch) | |
tree | b3cac552b6f65c3a5124309a82853842e4f0f03a /lib/AST/ExprConstant.cpp | |
parent | 2e478080f83f90728d8d56099cd32180c57debbc (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.cpp | 60 |
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; +} |