blob: 3dadb63c69628dc4d09db559be66de06490dc2b1 [file] [log] [blame]
Chris Lattnera42f09a2008-07-11 19:10:17 +00001//===--- ExprConstant.cpp - Expression Constant Evaluator -----------------===//
Anders Carlssonc7436af2008-07-03 04:20:39 +00002//
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"
Seo Sanghyeonefddb9c2008-07-08 07:23:12 +000017#include "clang/AST/StmtVisitor.h"
Anders Carlssonc0328012008-07-08 05:49:43 +000018#include "clang/Basic/TargetInfo.h"
Anders Carlssoncad17b52008-07-08 05:13:58 +000019#include "llvm/Support/Compiler.h"
Anders Carlssonc7436af2008-07-03 04:20:39 +000020using namespace clang;
Chris Lattnera823ccf2008-07-11 18:11:29 +000021using llvm::APSInt;
Anders Carlssonc7436af2008-07-03 04:20:39 +000022
Anders Carlssoncad17b52008-07-08 05:13:58 +000023#define USE_NEW_EVALUATOR 0
Anders Carlssonc7436af2008-07-03 04:20:39 +000024
Chris Lattnera823ccf2008-07-11 18:11:29 +000025static bool CalcFakeICEVal(const Expr *Expr,
26 llvm::APSInt &Result,
27 ASTContext &Context) {
Anders Carlssonc7436af2008-07-03 04:20:39 +000028 // Calculate the value of an expression that has a calculatable
29 // value, but isn't an ICE. Currently, this only supports
30 // a very narrow set of extensions, but it can be expanded if needed.
31 if (const ParenExpr *PE = dyn_cast<ParenExpr>(Expr))
32 return CalcFakeICEVal(PE->getSubExpr(), Result, Context);
33
34 if (const CastExpr *CE = dyn_cast<CastExpr>(Expr)) {
35 QualType CETy = CE->getType();
36 if ((CETy->isIntegralType() && !CETy->isBooleanType()) ||
37 CETy->isPointerType()) {
38 if (CalcFakeICEVal(CE->getSubExpr(), Result, Context)) {
39 Result.extOrTrunc(Context.getTypeSize(CETy));
40 // FIXME: This assumes pointers are signed.
41 Result.setIsSigned(CETy->isSignedIntegerType() ||
42 CETy->isPointerType());
43 return true;
44 }
45 }
46 }
47
48 if (Expr->getType()->isIntegralType())
49 return Expr->isIntegerConstantExpr(Result, Context);
50
51 return false;
52}
53
Chris Lattner422373c2008-07-11 22:52:41 +000054/// EvalInfo - This is a private struct used by the evaluator to capture
55/// information about a subexpression as it is folded. It retains information
56/// about the AST context, but also maintains information about the folded
57/// expression.
58///
59/// If an expression could be evaluated, it is still possible it is not a C
60/// "integer constant expression" or constant expression. If not, this struct
61/// captures information about how and why not.
62///
63/// One bit of information passed *into* the request for constant folding
64/// indicates whether the subexpression is "evaluated" or not according to C
65/// rules. For example, the RHS of (0 && foo()) is not evaluated. We can
66/// evaluate the expression regardless of what the RHS is, but C only allows
67/// certain things in certain situations.
68struct EvalInfo {
69 ASTContext &Ctx;
70
71 /// isEvaluated - True if the subexpression is required to be evaluated, false
72 /// if it is short-circuited (according to C rules).
73 bool isEvaluated;
74
75 /// ICEDiag - If the expression is foldable, but the expression is not an
76 /// integer constant expression, this contains the extension diagnostic to
77 /// emit which describes why it isn't an integer constant expression. The
78 /// caller can choose to emit this or not, depending on whether they require
79 /// an i-c-e or not. DiagLoc indicates the caret position for the report.
80 ///
81 /// If ICEDiag is zero, then this expression is an i-c-e.
82 unsigned ICEDiag;
83 SourceLocation DiagLoc;
84
85 EvalInfo(ASTContext &ctx) : Ctx(ctx), isEvaluated(true), ICEDiag(0) {}
86};
87
88
89static bool EvaluatePointer(const Expr *E, APValue &Result, EvalInfo &Info);
90static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info);
Chris Lattnera823ccf2008-07-11 18:11:29 +000091
92
93//===----------------------------------------------------------------------===//
94// Pointer Evaluation
95//===----------------------------------------------------------------------===//
96
Anders Carlssoncad17b52008-07-08 05:13:58 +000097namespace {
Anders Carlsson02a34c32008-07-08 14:30:00 +000098class VISIBILITY_HIDDEN PointerExprEvaluator
99 : public StmtVisitor<PointerExprEvaluator, APValue> {
Chris Lattner422373c2008-07-11 22:52:41 +0000100 EvalInfo &Info;
Anders Carlsson02a34c32008-07-08 14:30:00 +0000101public:
Anders Carlsson02a34c32008-07-08 14:30:00 +0000102
Chris Lattner422373c2008-07-11 22:52:41 +0000103 PointerExprEvaluator(EvalInfo &info) : Info(info) {}
Chris Lattnera823ccf2008-07-11 18:11:29 +0000104
Anders Carlsson02a34c32008-07-08 14:30:00 +0000105 APValue VisitStmt(Stmt *S) {
106 // FIXME: Remove this when we support more expressions.
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000107 printf("Unhandled pointer statement\n");
Anders Carlsson02a34c32008-07-08 14:30:00 +0000108 S->dump();
109 return APValue();
110 }
111
112 APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
113
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000114 APValue VisitBinaryOperator(const BinaryOperator *E);
115 APValue VisitCastExpr(const CastExpr* E);
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000116};
Chris Lattnera823ccf2008-07-11 18:11:29 +0000117} // end anonymous namespace
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000118
Chris Lattner422373c2008-07-11 22:52:41 +0000119static bool EvaluatePointer(const Expr* E, APValue& Result, EvalInfo &Info) {
Chris Lattnera823ccf2008-07-11 18:11:29 +0000120 if (!E->getType()->isPointerType())
121 return false;
Chris Lattner422373c2008-07-11 22:52:41 +0000122 Result = PointerExprEvaluator(Info).Visit(const_cast<Expr*>(E));
Chris Lattnera823ccf2008-07-11 18:11:29 +0000123 return Result.isLValue();
124}
125
126APValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
127 if (E->getOpcode() != BinaryOperator::Add &&
128 E->getOpcode() != BinaryOperator::Sub)
129 return APValue();
130
131 const Expr *PExp = E->getLHS();
132 const Expr *IExp = E->getRHS();
133 if (IExp->getType()->isPointerType())
134 std::swap(PExp, IExp);
135
136 APValue ResultLValue;
Chris Lattner422373c2008-07-11 22:52:41 +0000137 if (!EvaluatePointer(PExp, ResultLValue, Info))
Chris Lattnera823ccf2008-07-11 18:11:29 +0000138 return APValue();
139
140 llvm::APSInt AdditionalOffset(32);
Chris Lattner422373c2008-07-11 22:52:41 +0000141 if (!EvaluateInteger(IExp, AdditionalOffset, Info))
Chris Lattnera823ccf2008-07-11 18:11:29 +0000142 return APValue();
143
144 uint64_t Offset = ResultLValue.getLValueOffset();
145 if (E->getOpcode() == BinaryOperator::Add)
146 Offset += AdditionalOffset.getZExtValue();
147 else
148 Offset -= AdditionalOffset.getZExtValue();
149
150 return APValue(ResultLValue.getLValueBase(), Offset);
151}
152
153
Chris Lattnera42f09a2008-07-11 19:10:17 +0000154APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
Chris Lattnera823ccf2008-07-11 18:11:29 +0000155 const Expr* SubExpr = E->getSubExpr();
156
157 // Check for pointer->pointer cast
158 if (SubExpr->getType()->isPointerType()) {
159 APValue Result;
Chris Lattner422373c2008-07-11 22:52:41 +0000160 if (EvaluatePointer(SubExpr, Result, Info))
Chris Lattnera823ccf2008-07-11 18:11:29 +0000161 return Result;
162 return APValue();
163 }
164
165 if (SubExpr->getType()->isArithmeticType()) {
166 llvm::APSInt Result(32);
Chris Lattner422373c2008-07-11 22:52:41 +0000167 if (EvaluateInteger(SubExpr, Result, Info)) {
168 Result.extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
Chris Lattnera823ccf2008-07-11 18:11:29 +0000169 return APValue(0, Result.getZExtValue());
170 }
171 }
172
173 assert(0 && "Unhandled cast");
174 return APValue();
175}
176
177
178//===----------------------------------------------------------------------===//
179// Integer Evaluation
180//===----------------------------------------------------------------------===//
Chris Lattnera823ccf2008-07-11 18:11:29 +0000181
182namespace {
Anders Carlssoncad17b52008-07-08 05:13:58 +0000183class VISIBILITY_HIDDEN IntExprEvaluator
Chris Lattnera42f09a2008-07-11 19:10:17 +0000184 : public StmtVisitor<IntExprEvaluator, bool> {
Chris Lattner422373c2008-07-11 22:52:41 +0000185 EvalInfo &Info;
Chris Lattnera42f09a2008-07-11 19:10:17 +0000186 APSInt &Result;
Anders Carlssoncad17b52008-07-08 05:13:58 +0000187public:
Chris Lattner422373c2008-07-11 22:52:41 +0000188 IntExprEvaluator(EvalInfo &info, APSInt &result)
189 : Info(info), Result(result) {}
Chris Lattnera823ccf2008-07-11 18:11:29 +0000190
Chris Lattner2c99c712008-07-11 19:24:49 +0000191 unsigned getIntTypeSizeInBits(QualType T) const {
Chris Lattner422373c2008-07-11 22:52:41 +0000192 return (unsigned)Info.Ctx.getTypeSize(T);
Chris Lattner2c99c712008-07-11 19:24:49 +0000193 }
194
Anders Carlssoncad17b52008-07-08 05:13:58 +0000195 //===--------------------------------------------------------------------===//
196 // Visitor Methods
197 //===--------------------------------------------------------------------===//
Chris Lattner2c99c712008-07-11 19:24:49 +0000198
Chris Lattnera42f09a2008-07-11 19:10:17 +0000199 bool VisitStmt(Stmt *S) {
Anders Carlssoncad17b52008-07-08 05:13:58 +0000200 // FIXME: Remove this when we support more expressions.
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000201 printf("unhandled int expression");
Anders Carlssoncad17b52008-07-08 05:13:58 +0000202 S->dump();
Chris Lattnera42f09a2008-07-11 19:10:17 +0000203 return false;
Anders Carlssoncad17b52008-07-08 05:13:58 +0000204 }
205
Chris Lattnera42f09a2008-07-11 19:10:17 +0000206 bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
Anders Carlssoncad17b52008-07-08 05:13:58 +0000207
Chris Lattnera42f09a2008-07-11 19:10:17 +0000208 bool VisitBinaryOperator(const BinaryOperator *E);
Chris Lattner400d7402008-07-11 22:15:16 +0000209
Chris Lattnera42f09a2008-07-11 19:10:17 +0000210 bool VisitUnaryOperator(const UnaryOperator *E);
Anders Carlssonc0328012008-07-08 05:49:43 +0000211
Chris Lattnera42f09a2008-07-11 19:10:17 +0000212 bool VisitCastExpr(const CastExpr* E) {
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000213 return HandleCast(E->getSubExpr(), E->getType());
214 }
Chris Lattnera42f09a2008-07-11 19:10:17 +0000215 bool VisitImplicitCastExpr(const ImplicitCastExpr* E) {
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000216 return HandleCast(E->getSubExpr(), E->getType());
217 }
Chris Lattner265a0892008-07-11 21:24:13 +0000218 bool VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) {
219 return EvaluateSizeAlignOf(E->isSizeOf(),E->getArgumentType(),E->getType());
220 }
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000221
Chris Lattnera42f09a2008-07-11 19:10:17 +0000222 bool VisitIntegerLiteral(const IntegerLiteral *E) {
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000223 Result = E->getValue();
Chris Lattnera42f09a2008-07-11 19:10:17 +0000224 return true;
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000225 }
Chris Lattner265a0892008-07-11 21:24:13 +0000226private:
227 bool HandleCast(const Expr* SubExpr, QualType DestType);
228 bool EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy, QualType DstTy);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000229};
Chris Lattnera823ccf2008-07-11 18:11:29 +0000230} // end anonymous namespace
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000231
Chris Lattner422373c2008-07-11 22:52:41 +0000232static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {
233 return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000234}
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000235
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000236
Chris Lattnera42f09a2008-07-11 19:10:17 +0000237bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
Anders Carlssond1aa5812008-07-08 14:35:21 +0000238 // The LHS of a constant expr is always evaluated and needed.
Anders Carlssond1aa5812008-07-08 14:35:21 +0000239 llvm::APSInt RHS(32);
Chris Lattner422373c2008-07-11 22:52:41 +0000240 if (!Visit(E->getLHS()) || !EvaluateInteger(E->getRHS(), RHS, Info))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000241 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000242
243 switch (E->getOpcode()) {
Chris Lattner400d7402008-07-11 22:15:16 +0000244 default: return false;
245 case BinaryOperator::Mul: Result *= RHS; break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000246 case BinaryOperator::Add: Result += RHS; break;
247 case BinaryOperator::Sub: Result -= RHS; break;
Chris Lattner045502c2008-07-11 19:29:32 +0000248 case BinaryOperator::And: Result &= RHS; break;
249 case BinaryOperator::Xor: Result ^= RHS; break;
250 case BinaryOperator::Or: Result |= RHS; break;
Chris Lattner400d7402008-07-11 22:15:16 +0000251 case BinaryOperator::Div:
252 if (RHS == 0) return false;
253 Result /= RHS;
254 break;
255 case BinaryOperator::Rem:
256 if (RHS == 0) return false;
257 Result %= RHS;
258 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000259 case BinaryOperator::Shl:
Chris Lattnera42f09a2008-07-11 19:10:17 +0000260 Result <<= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000261 break;
262 case BinaryOperator::Shr:
Chris Lattnera42f09a2008-07-11 19:10:17 +0000263 Result >>= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000264 break;
Chris Lattnera42f09a2008-07-11 19:10:17 +0000265
Chris Lattner045502c2008-07-11 19:29:32 +0000266 case BinaryOperator::LT:
267 Result = Result < RHS;
268 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
269 break;
270 case BinaryOperator::GT:
271 Result = Result > RHS;
272 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
273 break;
274 case BinaryOperator::LE:
275 Result = Result <= RHS;
276 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
277 break;
278 case BinaryOperator::GE:
279 Result = Result >= RHS;
280 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
281 break;
282 case BinaryOperator::EQ:
283 Result = Result == RHS;
284 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
285 break;
286 case BinaryOperator::NE:
287 Result = Result != RHS;
288 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
289 break;
Anders Carlssonc0328012008-07-08 05:49:43 +0000290
Anders Carlssond1aa5812008-07-08 14:35:21 +0000291 case BinaryOperator::Comma:
292 // C99 6.6p3: "shall not contain assignment, ..., or comma operators,
293 // *except* when they are contained within a subexpression that is not
294 // evaluated". Note that Assignment can never happen due to constraints
295 // on the LHS subexpr, so we don't need to check it here.
296 // FIXME: Need to come up with an efficient way to deal with the C99
297 // rules on evaluation while still evaluating this. Maybe a
298 // "evaluated comma" out parameter?
Chris Lattnera42f09a2008-07-11 19:10:17 +0000299 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000300 }
301
302 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000303 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000304}
305
Chris Lattner265a0892008-07-11 21:24:13 +0000306/// EvaluateSizeAlignOf - Evaluate sizeof(SrcTy) or alignof(SrcTy) with a result
307/// as a DstTy type.
308bool IntExprEvaluator::EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy,
309 QualType DstTy) {
310 // Return the result in the right width.
311 Result.zextOrTrunc(getIntTypeSizeInBits(DstTy));
312 Result.setIsUnsigned(DstTy->isUnsignedIntegerType());
313
314 // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
315 if (SrcTy->isVoidType())
316 Result = 1;
317
318 // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
319 if (!SrcTy->isConstantSizeType()) {
320 // FIXME: Should we attempt to evaluate this?
321 return false;
322 }
323
324 // GCC extension: sizeof(function) = 1.
325 if (SrcTy->isFunctionType()) {
326 // FIXME: AlignOf shouldn't be unconditionally 4!
327 Result = isSizeOf ? 1 : 4;
328 return true;
329 }
330
331 // Get information about the size or align.
Chris Lattner422373c2008-07-11 22:52:41 +0000332 unsigned CharSize = Info.Ctx.Target.getCharWidth();
Chris Lattner265a0892008-07-11 21:24:13 +0000333 if (isSizeOf)
334 Result = getIntTypeSizeInBits(SrcTy) / CharSize;
335 else
Chris Lattner422373c2008-07-11 22:52:41 +0000336 Result = Info.Ctx.getTypeAlign(SrcTy) / CharSize;
Chris Lattner265a0892008-07-11 21:24:13 +0000337 return true;
338}
339
Chris Lattnera42f09a2008-07-11 19:10:17 +0000340bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
Chris Lattner400d7402008-07-11 22:15:16 +0000341 if (E->isOffsetOfOp()) {
Chris Lattner422373c2008-07-11 22:52:41 +0000342 Result = E->evaluateOffsetOf(Info.Ctx);
Chris Lattner400d7402008-07-11 22:15:16 +0000343 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
344 return true;
345 }
346
347 if (E->isSizeOfAlignOfOp())
Chris Lattner265a0892008-07-11 21:24:13 +0000348 return EvaluateSizeAlignOf(E->getOpcode() == UnaryOperator::SizeOf,
349 E->getSubExpr()->getType(), E->getType());
Chris Lattner400d7402008-07-11 22:15:16 +0000350
Chris Lattner422373c2008-07-11 22:52:41 +0000351 // Get the operand value into 'Result'.
352 if (!Visit(E->getSubExpr()))
Chris Lattner400d7402008-07-11 22:15:16 +0000353 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000354
Chris Lattner400d7402008-07-11 22:15:16 +0000355 switch (E->getOpcode()) {
356 // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
357 // See C99 6.6p3.
358 default:
359 return false;
360 case UnaryOperator::LNot: {
361 bool Val = Result == 0;
362 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
363 Result = Val;
364 break;
365 }
366 case UnaryOperator::Extension:
367 case UnaryOperator::Plus:
368 // The result is always just the subexpr
369 break;
370 case UnaryOperator::Minus:
371 Result = -Result;
372 break;
373 case UnaryOperator::Not:
374 Result = ~Result;
375 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000376 }
377
378 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000379 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000380}
381
Chris Lattnera42f09a2008-07-11 19:10:17 +0000382bool IntExprEvaluator::HandleCast(const Expr* SubExpr, QualType DestType) {
Chris Lattner2c99c712008-07-11 19:24:49 +0000383 unsigned DestWidth = getIntTypeSizeInBits(DestType);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000384
385 // Handle simple integer->integer casts.
386 if (SubExpr->getType()->isIntegerType()) {
Chris Lattner422373c2008-07-11 22:52:41 +0000387 if (!EvaluateInteger(SubExpr, Result, Info))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000388 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000389
390 // Figure out if this is a truncate, extend or noop cast.
391 // If the input is signed, do a sign extend, noop, or truncate.
392 if (DestType->isBooleanType()) {
393 // Conversion to bool compares against zero.
394 Result = Result != 0;
395 Result.zextOrTrunc(DestWidth);
Chris Lattner2c99c712008-07-11 19:24:49 +0000396 } else
Anders Carlssond1aa5812008-07-08 14:35:21 +0000397 Result.extOrTrunc(DestWidth);
398 } else if (SubExpr->getType()->isPointerType()) {
399 APValue LV;
Chris Lattner422373c2008-07-11 22:52:41 +0000400 if (!EvaluatePointer(SubExpr, LV, Info))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000401 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000402 if (LV.getLValueBase())
Chris Lattnera42f09a2008-07-11 19:10:17 +0000403 return false;
Anders Carlssonc0328012008-07-08 05:49:43 +0000404
Anders Carlsson8ab15c82008-07-08 16:49:00 +0000405 Result.extOrTrunc(DestWidth);
406 Result = LV.getLValueOffset();
Anders Carlssond1aa5812008-07-08 14:35:21 +0000407 } else {
408 assert(0 && "Unhandled cast!");
Anders Carlsson02a34c32008-07-08 14:30:00 +0000409 }
410
Anders Carlssond1aa5812008-07-08 14:35:21 +0000411 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000412 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000413}
Anders Carlsson02a34c32008-07-08 14:30:00 +0000414
Chris Lattnera823ccf2008-07-11 18:11:29 +0000415//===----------------------------------------------------------------------===//
416// Top level TryEvaluate.
417//===----------------------------------------------------------------------===//
418
Chris Lattnera42f09a2008-07-11 19:10:17 +0000419bool Expr::tryEvaluate(APValue &Result, ASTContext &Ctx) const {
Chris Lattner334b1942008-07-11 19:19:21 +0000420 llvm::APSInt sInt(32);
Anders Carlssoncad17b52008-07-08 05:13:58 +0000421#if USE_NEW_EVALUATOR
Chris Lattner422373c2008-07-11 22:52:41 +0000422 EvalInfo Info(Ctx);
Anders Carlssonc0328012008-07-08 05:49:43 +0000423 if (getType()->isIntegerType()) {
Chris Lattner422373c2008-07-11 22:52:41 +0000424 if (EvaluateInteger(this, sInt, Info)) {
Anders Carlssonc0328012008-07-08 05:49:43 +0000425 Result = APValue(sInt);
426 return true;
427 }
428 } else
Anders Carlssoncad17b52008-07-08 05:13:58 +0000429 return false;
430
431#else
Anders Carlssonc7436af2008-07-03 04:20:39 +0000432 if (CalcFakeICEVal(this, sInt, Ctx)) {
433 Result = APValue(sInt);
434 return true;
435 }
Anders Carlssoncad17b52008-07-08 05:13:58 +0000436#endif
Anders Carlssonc7436af2008-07-03 04:20:39 +0000437
438 return false;
439}