blob: 04f1572cb37e20432901037945a157f5e58cf2a1 [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 Lattnera823ccf2008-07-11 18:11:29 +000054static bool EvaluatePointer(const Expr *E, APValue &Result, ASTContext &Ctx);
55static bool EvaluateInteger(const Expr *E, APSInt &Result, ASTContext &Ctx);
56
57
58//===----------------------------------------------------------------------===//
59// Pointer Evaluation
60//===----------------------------------------------------------------------===//
61
Anders Carlssoncad17b52008-07-08 05:13:58 +000062namespace {
Anders Carlsson02a34c32008-07-08 14:30:00 +000063class VISIBILITY_HIDDEN PointerExprEvaluator
64 : public StmtVisitor<PointerExprEvaluator, APValue> {
65 ASTContext &Ctx;
Anders Carlsson02a34c32008-07-08 14:30:00 +000066public:
Anders Carlsson02a34c32008-07-08 14:30:00 +000067
Chris Lattnera823ccf2008-07-11 18:11:29 +000068 PointerExprEvaluator(ASTContext &ctx) : Ctx(ctx) {}
69
Anders Carlsson02a34c32008-07-08 14:30:00 +000070 APValue VisitStmt(Stmt *S) {
71 // FIXME: Remove this when we support more expressions.
Anders Carlssonc43f44b2008-07-08 15:34:11 +000072 printf("Unhandled pointer statement\n");
Anders Carlsson02a34c32008-07-08 14:30:00 +000073 S->dump();
74 return APValue();
75 }
76
77 APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
78
Anders Carlssonc43f44b2008-07-08 15:34:11 +000079 APValue VisitBinaryOperator(const BinaryOperator *E);
80 APValue VisitCastExpr(const CastExpr* E);
Anders Carlssonc43f44b2008-07-08 15:34:11 +000081};
Chris Lattnera823ccf2008-07-11 18:11:29 +000082} // end anonymous namespace
Anders Carlssonc43f44b2008-07-08 15:34:11 +000083
Chris Lattnera823ccf2008-07-11 18:11:29 +000084static bool EvaluatePointer(const Expr* E, APValue& Result, ASTContext &Ctx) {
85 if (!E->getType()->isPointerType())
86 return false;
87 Result = PointerExprEvaluator(Ctx).Visit(const_cast<Expr*>(E));
88 return Result.isLValue();
89}
90
91APValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
92 if (E->getOpcode() != BinaryOperator::Add &&
93 E->getOpcode() != BinaryOperator::Sub)
94 return APValue();
95
96 const Expr *PExp = E->getLHS();
97 const Expr *IExp = E->getRHS();
98 if (IExp->getType()->isPointerType())
99 std::swap(PExp, IExp);
100
101 APValue ResultLValue;
102 if (!EvaluatePointer(PExp, ResultLValue, Ctx))
103 return APValue();
104
105 llvm::APSInt AdditionalOffset(32);
106 if (!EvaluateInteger(IExp, AdditionalOffset, Ctx))
107 return APValue();
108
109 uint64_t Offset = ResultLValue.getLValueOffset();
110 if (E->getOpcode() == BinaryOperator::Add)
111 Offset += AdditionalOffset.getZExtValue();
112 else
113 Offset -= AdditionalOffset.getZExtValue();
114
115 return APValue(ResultLValue.getLValueBase(), Offset);
116}
117
118
Chris Lattnera42f09a2008-07-11 19:10:17 +0000119APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
Chris Lattnera823ccf2008-07-11 18:11:29 +0000120 const Expr* SubExpr = E->getSubExpr();
121
122 // Check for pointer->pointer cast
123 if (SubExpr->getType()->isPointerType()) {
124 APValue Result;
125 if (EvaluatePointer(SubExpr, Result, Ctx))
126 return Result;
127 return APValue();
128 }
129
130 if (SubExpr->getType()->isArithmeticType()) {
131 llvm::APSInt Result(32);
132 if (EvaluateInteger(SubExpr, Result, Ctx)) {
133 Result.extOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(E->getType())));
134 return APValue(0, Result.getZExtValue());
135 }
136 }
137
138 assert(0 && "Unhandled cast");
139 return APValue();
140}
141
142
143//===----------------------------------------------------------------------===//
144// Integer Evaluation
145//===----------------------------------------------------------------------===//
Chris Lattnera823ccf2008-07-11 18:11:29 +0000146
147namespace {
Anders Carlssoncad17b52008-07-08 05:13:58 +0000148class VISIBILITY_HIDDEN IntExprEvaluator
Chris Lattnera42f09a2008-07-11 19:10:17 +0000149 : public StmtVisitor<IntExprEvaluator, bool> {
Anders Carlssoncad17b52008-07-08 05:13:58 +0000150 ASTContext &Ctx;
Chris Lattnera42f09a2008-07-11 19:10:17 +0000151 APSInt &Result;
Anders Carlssoncad17b52008-07-08 05:13:58 +0000152public:
Chris Lattnera42f09a2008-07-11 19:10:17 +0000153 IntExprEvaluator(ASTContext &ctx, APSInt &result) : Ctx(ctx), Result(result){}
Chris Lattnera823ccf2008-07-11 18:11:29 +0000154
Chris Lattner2c99c712008-07-11 19:24:49 +0000155 unsigned getIntTypeSizeInBits(QualType T) const {
156 return (unsigned)Ctx.getTypeSize(T);
157 }
158
Anders Carlssoncad17b52008-07-08 05:13:58 +0000159 //===--------------------------------------------------------------------===//
160 // Visitor Methods
161 //===--------------------------------------------------------------------===//
Chris Lattner2c99c712008-07-11 19:24:49 +0000162
Chris Lattnera42f09a2008-07-11 19:10:17 +0000163 bool VisitStmt(Stmt *S) {
Anders Carlssoncad17b52008-07-08 05:13:58 +0000164 // FIXME: Remove this when we support more expressions.
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000165 printf("unhandled int expression");
Anders Carlssoncad17b52008-07-08 05:13:58 +0000166 S->dump();
Chris Lattnera42f09a2008-07-11 19:10:17 +0000167 return false;
Anders Carlssoncad17b52008-07-08 05:13:58 +0000168 }
169
Chris Lattnera42f09a2008-07-11 19:10:17 +0000170 bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
Anders Carlssoncad17b52008-07-08 05:13:58 +0000171
Chris Lattnera42f09a2008-07-11 19:10:17 +0000172 bool VisitBinaryOperator(const BinaryOperator *E);
173 bool VisitUnaryOperator(const UnaryOperator *E);
Anders Carlssonc0328012008-07-08 05:49:43 +0000174
Chris Lattnera42f09a2008-07-11 19:10:17 +0000175 bool HandleCast(const Expr* SubExpr, QualType DestType);
176 bool VisitCastExpr(const CastExpr* E) {
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000177 return HandleCast(E->getSubExpr(), E->getType());
178 }
Chris Lattnera42f09a2008-07-11 19:10:17 +0000179 bool VisitImplicitCastExpr(const ImplicitCastExpr* E) {
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000180 return HandleCast(E->getSubExpr(), E->getType());
181 }
Chris Lattnera42f09a2008-07-11 19:10:17 +0000182 bool VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E);
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000183
Chris Lattnera42f09a2008-07-11 19:10:17 +0000184 bool VisitIntegerLiteral(const IntegerLiteral *E) {
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000185 Result = E->getValue();
Chris Lattnera42f09a2008-07-11 19:10:17 +0000186 return true;
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000187 }
Anders Carlssond1aa5812008-07-08 14:35:21 +0000188};
Chris Lattnera823ccf2008-07-11 18:11:29 +0000189} // end anonymous namespace
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000190
Chris Lattnera823ccf2008-07-11 18:11:29 +0000191static bool EvaluateInteger(const Expr* E, APSInt &Result, ASTContext &Ctx) {
Chris Lattnera42f09a2008-07-11 19:10:17 +0000192 return IntExprEvaluator(Ctx, Result).Visit(const_cast<Expr*>(E));
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000193}
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000194
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000195
Chris Lattnera42f09a2008-07-11 19:10:17 +0000196bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
Anders Carlssond1aa5812008-07-08 14:35:21 +0000197 // The LHS of a constant expr is always evaluated and needed.
Chris Lattnera42f09a2008-07-11 19:10:17 +0000198 if (!Visit(E->getLHS()))
199 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000200
201 llvm::APSInt RHS(32);
Chris Lattnera823ccf2008-07-11 18:11:29 +0000202 if (!EvaluateInteger(E->getRHS(), RHS, Ctx))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000203 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000204
205 switch (E->getOpcode()) {
206 default:
Chris Lattnera42f09a2008-07-11 19:10:17 +0000207 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000208 case BinaryOperator::Mul:
209 Result *= RHS;
210 break;
211 case BinaryOperator::Div:
212 if (RHS == 0)
Chris Lattnera42f09a2008-07-11 19:10:17 +0000213 return false;
214 Result /= RHS;
215 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000216 case BinaryOperator::Rem:
217 if (RHS == 0)
Chris Lattnera42f09a2008-07-11 19:10:17 +0000218 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000219 Result %= RHS;
220 break;
221 case BinaryOperator::Add: Result += RHS; break;
222 case BinaryOperator::Sub: Result -= RHS; break;
Chris Lattner045502c2008-07-11 19:29:32 +0000223 case BinaryOperator::And: Result &= RHS; break;
224 case BinaryOperator::Xor: Result ^= RHS; break;
225 case BinaryOperator::Or: Result |= RHS; break;
226
Anders Carlssond1aa5812008-07-08 14:35:21 +0000227 case BinaryOperator::Shl:
Chris Lattnera42f09a2008-07-11 19:10:17 +0000228 Result <<= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000229 break;
230 case BinaryOperator::Shr:
Chris Lattnera42f09a2008-07-11 19:10:17 +0000231 Result >>= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000232 break;
Chris Lattnera42f09a2008-07-11 19:10:17 +0000233
Chris Lattner045502c2008-07-11 19:29:32 +0000234 case BinaryOperator::LT:
235 Result = Result < RHS;
236 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
237 break;
238 case BinaryOperator::GT:
239 Result = Result > RHS;
240 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
241 break;
242 case BinaryOperator::LE:
243 Result = Result <= RHS;
244 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
245 break;
246 case BinaryOperator::GE:
247 Result = Result >= RHS;
248 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
249 break;
250 case BinaryOperator::EQ:
251 Result = Result == RHS;
252 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
253 break;
254 case BinaryOperator::NE:
255 Result = Result != RHS;
256 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
257 break;
Anders Carlssonc0328012008-07-08 05:49:43 +0000258
Anders Carlssond1aa5812008-07-08 14:35:21 +0000259 case BinaryOperator::Comma:
260 // C99 6.6p3: "shall not contain assignment, ..., or comma operators,
261 // *except* when they are contained within a subexpression that is not
262 // evaluated". Note that Assignment can never happen due to constraints
263 // on the LHS subexpr, so we don't need to check it here.
264 // FIXME: Need to come up with an efficient way to deal with the C99
265 // rules on evaluation while still evaluating this. Maybe a
266 // "evaluated comma" out parameter?
Chris Lattnera42f09a2008-07-11 19:10:17 +0000267 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000268 }
269
270 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000271 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000272}
273
Chris Lattnera42f09a2008-07-11 19:10:17 +0000274bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
Anders Carlssond1aa5812008-07-08 14:35:21 +0000275 if (E->isOffsetOfOp())
276 Result = E->evaluateOffsetOf(Ctx);
277 else if (E->isSizeOfAlignOfOp()) {
278 // Return the result in the right width.
Chris Lattner2c99c712008-07-11 19:24:49 +0000279 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Anders Carlssond1aa5812008-07-08 14:35:21 +0000280
281 // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
282 if (E->getSubExpr()->getType()->isVoidType())
283 Result = 1;
284
285 // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
286 if (!E->getSubExpr()->getType()->isConstantSizeType()) {
287 // FIXME: Should we attempt to evaluate this?
Chris Lattnera42f09a2008-07-11 19:10:17 +0000288 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000289 }
290
291 // Get information about the size or align.
292 if (E->getSubExpr()->getType()->isFunctionType()) {
293 // GCC extension: sizeof(function) = 1.
294 // FIXME: AlignOf shouldn't be unconditionally 4!
295 Result = E->getOpcode() == UnaryOperator::AlignOf ? 4 : 1;
296 } else {
297 unsigned CharSize = Ctx.Target.getCharWidth();
298 if (E->getOpcode() == UnaryOperator::AlignOf)
299 Result = Ctx.getTypeAlign(E->getSubExpr()->getType()) / CharSize;
300 else
Chris Lattner2c99c712008-07-11 19:24:49 +0000301 Result = getIntTypeSizeInBits(E->getSubExpr()->getType()) / CharSize;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000302 }
303 } else {
304 // Get the operand value. If this is sizeof/alignof, do not evalute the
305 // operand. This affects C99 6.6p3.
Chris Lattnera823ccf2008-07-11 18:11:29 +0000306 if (!EvaluateInteger(E->getSubExpr(), Result, Ctx))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000307 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000308
Anders Carlssonc0328012008-07-08 05:49:43 +0000309 switch (E->getOpcode()) {
Anders Carlssond1aa5812008-07-08 14:35:21 +0000310 // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
311 // See C99 6.6p3.
Anders Carlssonc0328012008-07-08 05:49:43 +0000312 default:
Chris Lattnera42f09a2008-07-11 19:10:17 +0000313 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000314 case UnaryOperator::LNot: {
315 bool Val = Result == 0;
Chris Lattner2c99c712008-07-11 19:24:49 +0000316 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Anders Carlssond1aa5812008-07-08 14:35:21 +0000317 Result = Val;
Anders Carlssonc0328012008-07-08 05:49:43 +0000318 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000319 }
Chris Lattner045502c2008-07-11 19:29:32 +0000320 case UnaryOperator::Extension:
Anders Carlssond1aa5812008-07-08 14:35:21 +0000321 case UnaryOperator::Plus:
Chris Lattner045502c2008-07-11 19:29:32 +0000322 // The result is always just the subexpr
Anders Carlssonc0328012008-07-08 05:49:43 +0000323 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000324 case UnaryOperator::Minus:
325 Result = -Result;
Anders Carlssonc0328012008-07-08 05:49:43 +0000326 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000327 case UnaryOperator::Not:
328 Result = ~Result;
Anders Carlssonc0328012008-07-08 05:49:43 +0000329 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000330 }
331 }
332
333 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000334 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000335}
336
Chris Lattnera42f09a2008-07-11 19:10:17 +0000337bool IntExprEvaluator::HandleCast(const Expr* SubExpr, QualType DestType) {
Chris Lattner2c99c712008-07-11 19:24:49 +0000338 unsigned DestWidth = getIntTypeSizeInBits(DestType);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000339
340 // Handle simple integer->integer casts.
341 if (SubExpr->getType()->isIntegerType()) {
Chris Lattnera823ccf2008-07-11 18:11:29 +0000342 if (!EvaluateInteger(SubExpr, Result, Ctx))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000343 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000344
345 // Figure out if this is a truncate, extend or noop cast.
346 // If the input is signed, do a sign extend, noop, or truncate.
347 if (DestType->isBooleanType()) {
348 // Conversion to bool compares against zero.
349 Result = Result != 0;
350 Result.zextOrTrunc(DestWidth);
Chris Lattner2c99c712008-07-11 19:24:49 +0000351 } else
Anders Carlssond1aa5812008-07-08 14:35:21 +0000352 Result.extOrTrunc(DestWidth);
353 } else if (SubExpr->getType()->isPointerType()) {
354 APValue LV;
Chris Lattnera823ccf2008-07-11 18:11:29 +0000355 if (!EvaluatePointer(SubExpr, LV, Ctx))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000356 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000357 if (LV.getLValueBase())
Chris Lattnera42f09a2008-07-11 19:10:17 +0000358 return false;
Anders Carlssonc0328012008-07-08 05:49:43 +0000359
Anders Carlsson8ab15c82008-07-08 16:49:00 +0000360 Result.extOrTrunc(DestWidth);
361 Result = LV.getLValueOffset();
Anders Carlssond1aa5812008-07-08 14:35:21 +0000362 } else {
363 assert(0 && "Unhandled cast!");
Anders Carlsson02a34c32008-07-08 14:30:00 +0000364 }
365
Anders Carlssond1aa5812008-07-08 14:35:21 +0000366 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000367 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000368}
Anders Carlsson02a34c32008-07-08 14:30:00 +0000369
Chris Lattnera42f09a2008-07-11 19:10:17 +0000370bool IntExprEvaluator::
371VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) {
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000372 // Return the result in the right width.
Chris Lattner2c99c712008-07-11 19:24:49 +0000373 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000374
375 // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
376 if (E->getArgumentType()->isVoidType()) {
377 Result = 1;
378 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000379 return true;
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000380 }
381
382 // alignof always evaluates to a constant, sizeof does if arg is not VLA.
383 if (E->isSizeOf() && !E->getArgumentType()->isConstantSizeType())
Chris Lattnera42f09a2008-07-11 19:10:17 +0000384 return false;
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000385
386 // Get information about the size or align.
387 if (E->getArgumentType()->isFunctionType()) {
388 // GCC extension: sizeof(function) = 1.
389 Result = E->isSizeOf() ? 1 : 4;
390 } else {
391 unsigned CharSize = Ctx.Target.getCharWidth();
392 if (E->isSizeOf())
Chris Lattner2c99c712008-07-11 19:24:49 +0000393 Result = getIntTypeSizeInBits(E->getArgumentType()) / CharSize;
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000394 else
395 Result = Ctx.getTypeAlign(E->getArgumentType()) / CharSize;
396 }
397
398 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000399 return true;
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000400}
401
Chris Lattnera823ccf2008-07-11 18:11:29 +0000402//===----------------------------------------------------------------------===//
403// Top level TryEvaluate.
404//===----------------------------------------------------------------------===//
405
Chris Lattnera42f09a2008-07-11 19:10:17 +0000406bool Expr::tryEvaluate(APValue &Result, ASTContext &Ctx) const {
Chris Lattner334b1942008-07-11 19:19:21 +0000407 llvm::APSInt sInt(32);
Anders Carlssoncad17b52008-07-08 05:13:58 +0000408#if USE_NEW_EVALUATOR
Anders Carlssonc0328012008-07-08 05:49:43 +0000409 if (getType()->isIntegerType()) {
Chris Lattnera42f09a2008-07-11 19:10:17 +0000410 if (EvaluateInteger(this, sInt, Ctx)) {
Anders Carlssonc0328012008-07-08 05:49:43 +0000411 Result = APValue(sInt);
412 return true;
413 }
414 } else
Anders Carlssoncad17b52008-07-08 05:13:58 +0000415 return false;
416
417#else
Anders Carlssonc7436af2008-07-03 04:20:39 +0000418 if (CalcFakeICEVal(this, sInt, Ctx)) {
419 Result = APValue(sInt);
420 return true;
421 }
Anders Carlssoncad17b52008-07-08 05:13:58 +0000422#endif
Anders Carlssonc7436af2008-07-03 04:20:39 +0000423
424 return false;
425}