blob: 6be72681e382992f2d7f34824c7f0d91cd509eca [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"
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
119APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E)
120{
121 const Expr* SubExpr = E->getSubExpr();
122
123 // Check for pointer->pointer cast
124 if (SubExpr->getType()->isPointerType()) {
125 APValue Result;
126 if (EvaluatePointer(SubExpr, Result, Ctx))
127 return Result;
128 return APValue();
129 }
130
131 if (SubExpr->getType()->isArithmeticType()) {
132 llvm::APSInt Result(32);
133 if (EvaluateInteger(SubExpr, Result, Ctx)) {
134 Result.extOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(E->getType())));
135 return APValue(0, Result.getZExtValue());
136 }
137 }
138
139 assert(0 && "Unhandled cast");
140 return APValue();
141}
142
143
144//===----------------------------------------------------------------------===//
145// Integer Evaluation
146//===----------------------------------------------------------------------===//
147
148
149namespace {
Anders Carlssoncad17b52008-07-08 05:13:58 +0000150class VISIBILITY_HIDDEN IntExprEvaluator
151 : public StmtVisitor<IntExprEvaluator, APValue> {
152 ASTContext &Ctx;
153
Anders Carlssoncad17b52008-07-08 05:13:58 +0000154public:
Chris Lattnera823ccf2008-07-11 18:11:29 +0000155 IntExprEvaluator(ASTContext &ctx) : Ctx(ctx) {}
156
Anders Carlssoncad17b52008-07-08 05:13:58 +0000157 //===--------------------------------------------------------------------===//
158 // Visitor Methods
159 //===--------------------------------------------------------------------===//
160 APValue VisitStmt(Stmt *S) {
161 // FIXME: Remove this when we support more expressions.
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000162 printf("unhandled int expression");
Anders Carlssoncad17b52008-07-08 05:13:58 +0000163 S->dump();
164 return APValue();
165 }
166
Anders Carlssonc0328012008-07-08 05:49:43 +0000167 APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
Anders Carlssoncad17b52008-07-08 05:13:58 +0000168
Anders Carlssond1aa5812008-07-08 14:35:21 +0000169 APValue VisitBinaryOperator(const BinaryOperator *E);
170 APValue VisitUnaryOperator(const UnaryOperator *E);
Anders Carlssonc0328012008-07-08 05:49:43 +0000171
Anders Carlssond1aa5812008-07-08 14:35:21 +0000172 APValue HandleCast(const Expr* SubExpr, QualType DestType);
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000173 APValue VisitCastExpr(const CastExpr* E) {
174 return HandleCast(E->getSubExpr(), E->getType());
175 }
176 APValue VisitImplicitCastExpr(const ImplicitCastExpr* E) {
177 return HandleCast(E->getSubExpr(), E->getType());
178 }
179 APValue VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E);
180
181 APValue VisitIntegerLiteral(const IntegerLiteral *E) {
182 llvm::APSInt Result(Ctx.getTypeSize(E->getType()));
183
184 Result = E->getValue();
185 return APValue(Result);
186 }
Anders Carlssond1aa5812008-07-08 14:35:21 +0000187};
Chris Lattnera823ccf2008-07-11 18:11:29 +0000188} // end anonymous namespace
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000189
Chris Lattnera823ccf2008-07-11 18:11:29 +0000190static bool EvaluateInteger(const Expr* E, APSInt &Result, ASTContext &Ctx) {
191 APValue Value = IntExprEvaluator(Ctx).Visit(const_cast<Expr*>(E));
192 if (!Value.isSInt())
193 return false;
194
195 Result = Value.getSInt();
196 return true;
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000197}
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000198
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000199
Anders Carlssond1aa5812008-07-08 14:35:21 +0000200APValue IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
201 // The LHS of a constant expr is always evaluated and needed.
202 llvm::APSInt Result(32);
Chris Lattnera823ccf2008-07-11 18:11:29 +0000203 if (!EvaluateInteger(E->getLHS(), Result, Ctx))
Anders Carlssond1aa5812008-07-08 14:35:21 +0000204 return APValue();
205
206 llvm::APSInt RHS(32);
Chris Lattnera823ccf2008-07-11 18:11:29 +0000207 if (!EvaluateInteger(E->getRHS(), RHS, Ctx))
Anders Carlssond1aa5812008-07-08 14:35:21 +0000208 return APValue();
209
210 switch (E->getOpcode()) {
211 default:
212 return APValue();
213 case BinaryOperator::Mul:
214 Result *= RHS;
215 break;
216 case BinaryOperator::Div:
217 if (RHS == 0)
Anders Carlssonc0328012008-07-08 05:49:43 +0000218 return APValue();
Anders Carlssond1aa5812008-07-08 14:35:21 +0000219 Result /= RHS;
220 break;
221 case BinaryOperator::Rem:
222 if (RHS == 0)
223 return APValue();
224 Result %= RHS;
225 break;
226 case BinaryOperator::Add: Result += RHS; break;
227 case BinaryOperator::Sub: Result -= RHS; break;
228 case BinaryOperator::Shl:
229 Result <<=
230 static_cast<uint32_t>(RHS.getLimitedValue(Result.getBitWidth()-1));
231 break;
232 case BinaryOperator::Shr:
233 Result >>=
234 static_cast<uint32_t>(RHS.getLimitedValue(Result.getBitWidth()-1));
235 break;
236 case BinaryOperator::LT: Result = Result < RHS; break;
237 case BinaryOperator::GT: Result = Result > RHS; break;
238 case BinaryOperator::LE: Result = Result <= RHS; break;
239 case BinaryOperator::GE: Result = Result >= RHS; break;
240 case BinaryOperator::EQ: Result = Result == RHS; break;
241 case BinaryOperator::NE: Result = Result != RHS; break;
242 case BinaryOperator::And: Result &= RHS; break;
243 case BinaryOperator::Xor: Result ^= RHS; break;
244 case BinaryOperator::Or: Result |= RHS; break;
Anders Carlssonc0328012008-07-08 05:49:43 +0000245
Anders Carlssond1aa5812008-07-08 14:35:21 +0000246 case BinaryOperator::Comma:
247 // C99 6.6p3: "shall not contain assignment, ..., or comma operators,
248 // *except* when they are contained within a subexpression that is not
249 // evaluated". Note that Assignment can never happen due to constraints
250 // on the LHS subexpr, so we don't need to check it here.
251 // FIXME: Need to come up with an efficient way to deal with the C99
252 // rules on evaluation while still evaluating this. Maybe a
253 // "evaluated comma" out parameter?
254 return APValue();
255 }
256
257 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
258
259 return APValue(Result);
260}
261
262APValue IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
263 llvm::APSInt Result(32);
264
265 if (E->isOffsetOfOp())
266 Result = E->evaluateOffsetOf(Ctx);
267 else if (E->isSizeOfAlignOfOp()) {
268 // Return the result in the right width.
269 Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(E->getType())));
270
271 // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
272 if (E->getSubExpr()->getType()->isVoidType())
273 Result = 1;
274
275 // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
276 if (!E->getSubExpr()->getType()->isConstantSizeType()) {
277 // FIXME: Should we attempt to evaluate this?
278 return APValue();
279 }
280
281 // Get information about the size or align.
282 if (E->getSubExpr()->getType()->isFunctionType()) {
283 // GCC extension: sizeof(function) = 1.
284 // FIXME: AlignOf shouldn't be unconditionally 4!
285 Result = E->getOpcode() == UnaryOperator::AlignOf ? 4 : 1;
286 } else {
287 unsigned CharSize = Ctx.Target.getCharWidth();
288 if (E->getOpcode() == UnaryOperator::AlignOf)
289 Result = Ctx.getTypeAlign(E->getSubExpr()->getType()) / CharSize;
290 else
291 Result = Ctx.getTypeSize(E->getSubExpr()->getType()) / CharSize;
292 }
293 } else {
294 // Get the operand value. If this is sizeof/alignof, do not evalute the
295 // operand. This affects C99 6.6p3.
Chris Lattnera823ccf2008-07-11 18:11:29 +0000296 if (!EvaluateInteger(E->getSubExpr(), Result, Ctx))
Anders Carlssond1aa5812008-07-08 14:35:21 +0000297 return APValue();
298
Anders Carlssonc0328012008-07-08 05:49:43 +0000299 switch (E->getOpcode()) {
Anders Carlssond1aa5812008-07-08 14:35:21 +0000300 // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
301 // See C99 6.6p3.
Anders Carlssonc0328012008-07-08 05:49:43 +0000302 default:
303 return APValue();
Anders Carlssond1aa5812008-07-08 14:35:21 +0000304 case UnaryOperator::Extension:
305 assert(0 && "Handle UnaryOperator::Extension");
306 return APValue();
307 case UnaryOperator::LNot: {
308 bool Val = Result == 0;
309 uint32_t typeSize = Ctx.getTypeSize(E->getType());
310 Result.zextOrTrunc(typeSize);
311 Result = Val;
Anders Carlssonc0328012008-07-08 05:49:43 +0000312 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000313 }
314 case UnaryOperator::Plus:
Anders Carlssonc0328012008-07-08 05:49:43 +0000315 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000316 case UnaryOperator::Minus:
317 Result = -Result;
Anders Carlssonc0328012008-07-08 05:49:43 +0000318 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000319 case UnaryOperator::Not:
320 Result = ~Result;
Anders Carlssonc0328012008-07-08 05:49:43 +0000321 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000322 }
323 }
324
325 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
326 return APValue(Result);
327}
328
329APValue IntExprEvaluator::HandleCast(const Expr* SubExpr, QualType DestType) {
330 llvm::APSInt Result(32);
331
332 uint32_t DestWidth = static_cast<uint32_t>(Ctx.getTypeSize(DestType));
333
334 // Handle simple integer->integer casts.
335 if (SubExpr->getType()->isIntegerType()) {
Chris Lattnera823ccf2008-07-11 18:11:29 +0000336 if (!EvaluateInteger(SubExpr, Result, Ctx))
Anders Carlssonc0328012008-07-08 05:49:43 +0000337 return APValue();
Anders Carlssond1aa5812008-07-08 14:35:21 +0000338
339 // Figure out if this is a truncate, extend or noop cast.
340 // If the input is signed, do a sign extend, noop, or truncate.
341 if (DestType->isBooleanType()) {
342 // Conversion to bool compares against zero.
343 Result = Result != 0;
344 Result.zextOrTrunc(DestWidth);
Anders Carlssonc0328012008-07-08 05:49:43 +0000345 }
Anders Carlssond1aa5812008-07-08 14:35:21 +0000346 else
347 Result.extOrTrunc(DestWidth);
348 } else if (SubExpr->getType()->isPointerType()) {
349 APValue LV;
Chris Lattnera823ccf2008-07-11 18:11:29 +0000350 if (!EvaluatePointer(SubExpr, LV, Ctx))
Anders Carlssond1aa5812008-07-08 14:35:21 +0000351 return APValue();
352 if (LV.getLValueBase())
353 return APValue();
Anders Carlssonc0328012008-07-08 05:49:43 +0000354
Anders Carlsson8ab15c82008-07-08 16:49:00 +0000355 Result.extOrTrunc(DestWidth);
356 Result = LV.getLValueOffset();
Anders Carlssond1aa5812008-07-08 14:35:21 +0000357 } else {
358 assert(0 && "Unhandled cast!");
Anders Carlsson02a34c32008-07-08 14:30:00 +0000359 }
360
Anders Carlssond1aa5812008-07-08 14:35:21 +0000361 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
362 return APValue(Result);
363}
Anders Carlsson02a34c32008-07-08 14:30:00 +0000364
Chris Lattnera823ccf2008-07-11 18:11:29 +0000365APValue IntExprEvaluator::
366 VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) {
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000367 llvm::APSInt Result(32);
368
369 // Return the result in the right width.
370 Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(E->getType())));
371
372 // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
373 if (E->getArgumentType()->isVoidType()) {
374 Result = 1;
375 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
376 return APValue(Result);
377 }
378
379 // alignof always evaluates to a constant, sizeof does if arg is not VLA.
380 if (E->isSizeOf() && !E->getArgumentType()->isConstantSizeType())
381 return APValue();
382
383 // Get information about the size or align.
384 if (E->getArgumentType()->isFunctionType()) {
385 // GCC extension: sizeof(function) = 1.
386 Result = E->isSizeOf() ? 1 : 4;
387 } else {
388 unsigned CharSize = Ctx.Target.getCharWidth();
389 if (E->isSizeOf())
390 Result = Ctx.getTypeSize(E->getArgumentType()) / CharSize;
391 else
392 Result = Ctx.getTypeAlign(E->getArgumentType()) / CharSize;
393 }
394
395 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
396 return APValue(Result);
397}
398
Chris Lattnera823ccf2008-07-11 18:11:29 +0000399//===----------------------------------------------------------------------===//
400// Top level TryEvaluate.
401//===----------------------------------------------------------------------===//
402
403bool Expr::tryEvaluate(APValue& Result, ASTContext &Ctx) const {
Anders Carlssonc7436af2008-07-03 04:20:39 +0000404 llvm::APSInt sInt(1);
405
Anders Carlssoncad17b52008-07-08 05:13:58 +0000406#if USE_NEW_EVALUATOR
Anders Carlssonc0328012008-07-08 05:49:43 +0000407 if (getType()->isIntegerType()) {
408 if (IntExprEvaluator::Evaluate(this, sInt, Ctx)) {
409 Result = APValue(sInt);
410 return true;
411 }
412 } else
Anders Carlssoncad17b52008-07-08 05:13:58 +0000413 return false;
414
415#else
Anders Carlssonc7436af2008-07-03 04:20:39 +0000416 if (CalcFakeICEVal(this, sInt, Ctx)) {
417 Result = APValue(sInt);
418 return true;
419 }
Anders Carlssoncad17b52008-07-08 05:13:58 +0000420#endif
Anders Carlssonc7436af2008-07-03 04:20:39 +0000421
422 return false;
423}