blob: ea9b106b69d9eaf02aad1ce2801a28807e43255a [file] [log] [blame]
Anders Carlssonc7436af2008-07-03 04:20:39 +00001//===--- Expr.cpp - Expression Constant Evaluator -------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Expr constant evaluator.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/APValue.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Expr.h"
17
18using namespace clang;
19
20
21static bool CalcFakeICEVal(const Expr* Expr,
22 llvm::APSInt& Result,
23 ASTContext& Context) {
24 // Calculate the value of an expression that has a calculatable
25 // value, but isn't an ICE. Currently, this only supports
26 // a very narrow set of extensions, but it can be expanded if needed.
27 if (const ParenExpr *PE = dyn_cast<ParenExpr>(Expr))
28 return CalcFakeICEVal(PE->getSubExpr(), Result, Context);
29
30 if (const CastExpr *CE = dyn_cast<CastExpr>(Expr)) {
31 QualType CETy = CE->getType();
32 if ((CETy->isIntegralType() && !CETy->isBooleanType()) ||
33 CETy->isPointerType()) {
34 if (CalcFakeICEVal(CE->getSubExpr(), Result, Context)) {
35 Result.extOrTrunc(Context.getTypeSize(CETy));
36 // FIXME: This assumes pointers are signed.
37 Result.setIsSigned(CETy->isSignedIntegerType() ||
38 CETy->isPointerType());
39 return true;
40 }
41 }
42 }
43
44 if (Expr->getType()->isIntegralType())
45 return Expr->isIntegerConstantExpr(Result, Context);
46
47 return false;
48}
49
50bool Expr::tryEvaluate(APValue& Result, ASTContext &Ctx) const
51{
52 llvm::APSInt sInt(1);
53
54 if (CalcFakeICEVal(this, sInt, Ctx)) {
55 Result = APValue(sInt);
56 return true;
57 }
58
59 return false;
60}