blob: c20cf4c0c5acc21985bfb7c12b685fc54213d8e8 [file] [log] [blame]
Chris Lattnerb542afe2008-07-11 19:10:17 +00001//===--- ExprConstant.cpp - Expression Constant Evaluator -----------------===//
Anders Carlssonc44eec62008-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"
Seo Sanghyeon0fe52e12008-07-08 07:23:12 +000016#include "clang/AST/StmtVisitor.h"
Chris Lattner54176fd2008-07-12 00:14:42 +000017#include "clang/Basic/Diagnostic.h"
Anders Carlsson06a36752008-07-08 05:49:43 +000018#include "clang/Basic/TargetInfo.h"
Anders Carlssonc754aa62008-07-08 05:13:58 +000019#include "llvm/Support/Compiler.h"
Anders Carlssonc44eec62008-07-03 04:20:39 +000020using namespace clang;
Chris Lattnerf5eeb052008-07-11 18:11:29 +000021using llvm::APSInt;
Eli Friedmand8bfe7f2008-08-22 00:06:13 +000022using llvm::APFloat;
Anders Carlssonc44eec62008-07-03 04:20:39 +000023
Chris Lattner87eae5e2008-07-11 22:52:41 +000024/// EvalInfo - This is a private struct used by the evaluator to capture
25/// information about a subexpression as it is folded. It retains information
26/// about the AST context, but also maintains information about the folded
27/// expression.
28///
29/// If an expression could be evaluated, it is still possible it is not a C
30/// "integer constant expression" or constant expression. If not, this struct
31/// captures information about how and why not.
32///
33/// One bit of information passed *into* the request for constant folding
34/// indicates whether the subexpression is "evaluated" or not according to C
35/// rules. For example, the RHS of (0 && foo()) is not evaluated. We can
36/// evaluate the expression regardless of what the RHS is, but C only allows
37/// certain things in certain situations.
38struct EvalInfo {
39 ASTContext &Ctx;
40
41 /// isEvaluated - True if the subexpression is required to be evaluated, false
42 /// if it is short-circuited (according to C rules).
43 bool isEvaluated;
44
Chris Lattner54176fd2008-07-12 00:14:42 +000045 /// ICEDiag - If the expression is unfoldable, then ICEDiag contains the
46 /// error diagnostic indicating why it is not foldable and DiagLoc indicates a
47 /// caret position for the error. If it is foldable, but the expression is
48 /// not an integer constant expression, ICEDiag contains the extension
49 /// diagnostic to emit which describes why it isn't an integer constant
50 /// expression. If this expression *is* an integer-constant-expr, then
51 /// ICEDiag is zero.
Chris Lattner87eae5e2008-07-11 22:52:41 +000052 ///
Chris Lattner54176fd2008-07-12 00:14:42 +000053 /// The caller can choose to emit this diagnostic or not, depending on whether
54 /// they require an i-c-e or a constant or not. DiagLoc indicates the caret
55 /// position for the report.
56 ///
57 /// If ICEDiag is zero, then this expression is an i-c-e.
Chris Lattner87eae5e2008-07-11 22:52:41 +000058 unsigned ICEDiag;
59 SourceLocation DiagLoc;
60
61 EvalInfo(ASTContext &ctx) : Ctx(ctx), isEvaluated(true), ICEDiag(0) {}
62};
63
64
65static bool EvaluatePointer(const Expr *E, APValue &Result, EvalInfo &Info);
66static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info);
Eli Friedmand8bfe7f2008-08-22 00:06:13 +000067static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
Chris Lattnerf5eeb052008-07-11 18:11:29 +000068
69//===----------------------------------------------------------------------===//
70// Pointer Evaluation
71//===----------------------------------------------------------------------===//
72
Anders Carlssonc754aa62008-07-08 05:13:58 +000073namespace {
Anders Carlsson2bad1682008-07-08 14:30:00 +000074class VISIBILITY_HIDDEN PointerExprEvaluator
75 : public StmtVisitor<PointerExprEvaluator, APValue> {
Chris Lattner87eae5e2008-07-11 22:52:41 +000076 EvalInfo &Info;
Anders Carlsson2bad1682008-07-08 14:30:00 +000077public:
Anders Carlsson2bad1682008-07-08 14:30:00 +000078
Chris Lattner87eae5e2008-07-11 22:52:41 +000079 PointerExprEvaluator(EvalInfo &info) : Info(info) {}
Chris Lattnerf5eeb052008-07-11 18:11:29 +000080
Anders Carlsson2bad1682008-07-08 14:30:00 +000081 APValue VisitStmt(Stmt *S) {
82 // FIXME: Remove this when we support more expressions.
Anders Carlsson650c92f2008-07-08 15:34:11 +000083 printf("Unhandled pointer statement\n");
Anders Carlsson2bad1682008-07-08 14:30:00 +000084 S->dump();
85 return APValue();
86 }
87
88 APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
89
Anders Carlsson650c92f2008-07-08 15:34:11 +000090 APValue VisitBinaryOperator(const BinaryOperator *E);
91 APValue VisitCastExpr(const CastExpr* E);
Anders Carlsson650c92f2008-07-08 15:34:11 +000092};
Chris Lattnerf5eeb052008-07-11 18:11:29 +000093} // end anonymous namespace
Anders Carlsson650c92f2008-07-08 15:34:11 +000094
Chris Lattner87eae5e2008-07-11 22:52:41 +000095static bool EvaluatePointer(const Expr* E, APValue& Result, EvalInfo &Info) {
Chris Lattnerf5eeb052008-07-11 18:11:29 +000096 if (!E->getType()->isPointerType())
97 return false;
Chris Lattner87eae5e2008-07-11 22:52:41 +000098 Result = PointerExprEvaluator(Info).Visit(const_cast<Expr*>(E));
Chris Lattnerf5eeb052008-07-11 18:11:29 +000099 return Result.isLValue();
100}
101
102APValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
103 if (E->getOpcode() != BinaryOperator::Add &&
104 E->getOpcode() != BinaryOperator::Sub)
105 return APValue();
106
107 const Expr *PExp = E->getLHS();
108 const Expr *IExp = E->getRHS();
109 if (IExp->getType()->isPointerType())
110 std::swap(PExp, IExp);
111
112 APValue ResultLValue;
Chris Lattner87eae5e2008-07-11 22:52:41 +0000113 if (!EvaluatePointer(PExp, ResultLValue, Info))
Chris Lattnerf5eeb052008-07-11 18:11:29 +0000114 return APValue();
115
116 llvm::APSInt AdditionalOffset(32);
Chris Lattner87eae5e2008-07-11 22:52:41 +0000117 if (!EvaluateInteger(IExp, AdditionalOffset, Info))
Chris Lattnerf5eeb052008-07-11 18:11:29 +0000118 return APValue();
119
120 uint64_t Offset = ResultLValue.getLValueOffset();
121 if (E->getOpcode() == BinaryOperator::Add)
122 Offset += AdditionalOffset.getZExtValue();
123 else
124 Offset -= AdditionalOffset.getZExtValue();
125
126 return APValue(ResultLValue.getLValueBase(), Offset);
127}
128
129
Chris Lattnerb542afe2008-07-11 19:10:17 +0000130APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
Chris Lattnerf5eeb052008-07-11 18:11:29 +0000131 const Expr* SubExpr = E->getSubExpr();
132
133 // Check for pointer->pointer cast
134 if (SubExpr->getType()->isPointerType()) {
135 APValue Result;
Chris Lattner87eae5e2008-07-11 22:52:41 +0000136 if (EvaluatePointer(SubExpr, Result, Info))
Chris Lattnerf5eeb052008-07-11 18:11:29 +0000137 return Result;
138 return APValue();
139 }
140
Eli Friedmand9f4bcd2008-07-27 05:46:18 +0000141 if (SubExpr->getType()->isIntegralType()) {
Chris Lattnerf5eeb052008-07-11 18:11:29 +0000142 llvm::APSInt Result(32);
Chris Lattner87eae5e2008-07-11 22:52:41 +0000143 if (EvaluateInteger(SubExpr, Result, Info)) {
144 Result.extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
Chris Lattnerf5eeb052008-07-11 18:11:29 +0000145 return APValue(0, Result.getZExtValue());
146 }
147 }
148
149 assert(0 && "Unhandled cast");
150 return APValue();
151}
152
153
154//===----------------------------------------------------------------------===//
155// Integer Evaluation
156//===----------------------------------------------------------------------===//
Chris Lattnerf5eeb052008-07-11 18:11:29 +0000157
158namespace {
Anders Carlssonc754aa62008-07-08 05:13:58 +0000159class VISIBILITY_HIDDEN IntExprEvaluator
Chris Lattnerb542afe2008-07-11 19:10:17 +0000160 : public StmtVisitor<IntExprEvaluator, bool> {
Chris Lattner87eae5e2008-07-11 22:52:41 +0000161 EvalInfo &Info;
Chris Lattnerb542afe2008-07-11 19:10:17 +0000162 APSInt &Result;
Anders Carlssonc754aa62008-07-08 05:13:58 +0000163public:
Chris Lattner87eae5e2008-07-11 22:52:41 +0000164 IntExprEvaluator(EvalInfo &info, APSInt &result)
165 : Info(info), Result(result) {}
Chris Lattnerf5eeb052008-07-11 18:11:29 +0000166
Chris Lattner7a767782008-07-11 19:24:49 +0000167 unsigned getIntTypeSizeInBits(QualType T) const {
Chris Lattner54176fd2008-07-12 00:14:42 +0000168 return (unsigned)Info.Ctx.getIntWidth(T);
169 }
170
171 bool Extension(SourceLocation L, diag::kind D) {
172 Info.DiagLoc = L;
173 Info.ICEDiag = D;
174 return true; // still a constant.
175 }
176
177 bool Error(SourceLocation L, diag::kind D) {
178 // If this is in an unevaluated portion of the subexpression, ignore the
179 // error.
180 if (!Info.isEvaluated)
181 return true;
182
183 Info.DiagLoc = L;
184 Info.ICEDiag = D;
185 return false;
Chris Lattner7a767782008-07-11 19:24:49 +0000186 }
187
Anders Carlssonc754aa62008-07-08 05:13:58 +0000188 //===--------------------------------------------------------------------===//
189 // Visitor Methods
190 //===--------------------------------------------------------------------===//
Chris Lattner7a767782008-07-11 19:24:49 +0000191
Chris Lattnerb542afe2008-07-11 19:10:17 +0000192 bool VisitStmt(Stmt *S) {
Chris Lattner54176fd2008-07-12 00:14:42 +0000193 return Error(S->getLocStart(), diag::err_expr_not_constant);
Anders Carlssonc754aa62008-07-08 05:13:58 +0000194 }
195
Chris Lattnerb542afe2008-07-11 19:10:17 +0000196 bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
Anders Carlssonc754aa62008-07-08 05:13:58 +0000197
Chris Lattner4c4867e2008-07-12 00:38:25 +0000198 bool VisitIntegerLiteral(const IntegerLiteral *E) {
199 Result = E->getValue();
200 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
201 return true;
202 }
203 bool VisitCharacterLiteral(const CharacterLiteral *E) {
204 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
205 Result = E->getValue();
206 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
207 return true;
208 }
209 bool VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
210 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
211 Result = Info.Ctx.typesAreCompatible(E->getArgType1(), E->getArgType2());
212 return true;
213 }
214 bool VisitDeclRefExpr(const DeclRefExpr *E);
215 bool VisitCallExpr(const CallExpr *E);
Chris Lattnerb542afe2008-07-11 19:10:17 +0000216 bool VisitBinaryOperator(const BinaryOperator *E);
217 bool VisitUnaryOperator(const UnaryOperator *E);
Anders Carlsson06a36752008-07-08 05:49:43 +0000218
Chris Lattner732b2232008-07-12 01:15:53 +0000219 bool VisitCastExpr(CastExpr* E) {
Chris Lattner732b2232008-07-12 01:15:53 +0000220 return HandleCast(E->getLocStart(), E->getSubExpr(), E->getType());
Anders Carlsson650c92f2008-07-08 15:34:11 +0000221 }
Chris Lattnerfcee0012008-07-11 21:24:13 +0000222 bool VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) {
Chris Lattner54176fd2008-07-12 00:14:42 +0000223 return EvaluateSizeAlignOf(E->isSizeOf(), E->getArgumentType(),
224 E->getType());
Chris Lattnerfcee0012008-07-11 21:24:13 +0000225 }
Chris Lattner4c4867e2008-07-12 00:38:25 +0000226
Chris Lattnerfcee0012008-07-11 21:24:13 +0000227private:
Chris Lattner732b2232008-07-12 01:15:53 +0000228 bool HandleCast(SourceLocation CastLoc, Expr *SubExpr, QualType DestType);
Chris Lattnerfcee0012008-07-11 21:24:13 +0000229 bool EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy, QualType DstTy);
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000230};
Chris Lattnerf5eeb052008-07-11 18:11:29 +0000231} // end anonymous namespace
Anders Carlsson650c92f2008-07-08 15:34:11 +0000232
Chris Lattner87eae5e2008-07-11 22:52:41 +0000233static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {
234 return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
Anders Carlsson650c92f2008-07-08 15:34:11 +0000235}
Anders Carlsson650c92f2008-07-08 15:34:11 +0000236
Chris Lattner4c4867e2008-07-12 00:38:25 +0000237bool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
238 // Enums are integer constant exprs.
239 if (const EnumConstantDecl *D = dyn_cast<EnumConstantDecl>(E->getDecl())) {
240 Result = D->getInitVal();
241 return true;
242 }
243
244 // Otherwise, random variable references are not constants.
245 return Error(E->getLocStart(), diag::err_expr_not_constant);
246}
247
Chris Lattner4c4867e2008-07-12 00:38:25 +0000248bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
249 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Chris Lattner4c4867e2008-07-12 00:38:25 +0000250
Chris Lattner019f4e82008-10-06 05:28:25 +0000251 switch (E->isBuiltinCall()) {
252 default:
253 return Error(E->getLocStart(), diag::err_expr_not_constant);
254 case Builtin::BI__builtin_classify_type:
255 // __builtin_type_compatible_p is a constant. Return its value.
256 E->isBuiltinClassifyType(Result);
257 return true;
258
259 case Builtin::BI__builtin_constant_p: {
260 // __builtin_constant_p always has one operand: it returns true if that
261 // operand can be folded, false otherwise.
262 APValue Res;
263 Result = E->getArg(0)->tryEvaluate(Res, Info.Ctx);
264 return true;
265 }
266 }
Chris Lattner4c4867e2008-07-12 00:38:25 +0000267}
Anders Carlsson650c92f2008-07-08 15:34:11 +0000268
Chris Lattnerb542afe2008-07-11 19:10:17 +0000269bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000270 // The LHS of a constant expr is always evaluated and needed.
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000271 llvm::APSInt RHS(32);
Chris Lattner54176fd2008-07-12 00:14:42 +0000272 if (!Visit(E->getLHS()))
273 return false; // error in subexpression.
274
275 bool OldEval = Info.isEvaluated;
276
277 // The short-circuiting &&/|| operators don't necessarily evaluate their
278 // RHS. Make sure to pass isEvaluated down correctly.
279 if ((E->getOpcode() == BinaryOperator::LAnd && Result == 0) ||
280 (E->getOpcode() == BinaryOperator::LOr && Result != 0))
281 Info.isEvaluated = false;
Eli Friedmand9f4bcd2008-07-27 05:46:18 +0000282
283 // FIXME: Handle pointer subtraction
284
285 // FIXME Maybe we want to succeed even where we can't evaluate the
286 // right side of LAnd/LOr?
287 // For example, see http://llvm.org/bugs/show_bug.cgi?id=2525
Chris Lattner54176fd2008-07-12 00:14:42 +0000288 if (!EvaluateInteger(E->getRHS(), RHS, Info))
Chris Lattnerb542afe2008-07-11 19:10:17 +0000289 return false;
Chris Lattner54176fd2008-07-12 00:14:42 +0000290 Info.isEvaluated = OldEval;
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000291
292 switch (E->getOpcode()) {
Chris Lattner54176fd2008-07-12 00:14:42 +0000293 default: return Error(E->getOperatorLoc(), diag::err_expr_not_constant);
294 case BinaryOperator::Mul: Result *= RHS; return true;
295 case BinaryOperator::Add: Result += RHS; return true;
296 case BinaryOperator::Sub: Result -= RHS; return true;
297 case BinaryOperator::And: Result &= RHS; return true;
298 case BinaryOperator::Xor: Result ^= RHS; return true;
299 case BinaryOperator::Or: Result |= RHS; return true;
Chris Lattner75a48812008-07-11 22:15:16 +0000300 case BinaryOperator::Div:
Chris Lattner54176fd2008-07-12 00:14:42 +0000301 if (RHS == 0)
302 return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero);
Chris Lattner75a48812008-07-11 22:15:16 +0000303 Result /= RHS;
Chris Lattner54176fd2008-07-12 00:14:42 +0000304 return true;
Chris Lattner75a48812008-07-11 22:15:16 +0000305 case BinaryOperator::Rem:
Chris Lattner54176fd2008-07-12 00:14:42 +0000306 if (RHS == 0)
307 return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero);
Chris Lattner75a48812008-07-11 22:15:16 +0000308 Result %= RHS;
Chris Lattner54176fd2008-07-12 00:14:42 +0000309 return true;
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000310 case BinaryOperator::Shl:
Chris Lattner54176fd2008-07-12 00:14:42 +0000311 // FIXME: Warn about out of range shift amounts!
Chris Lattnerb542afe2008-07-11 19:10:17 +0000312 Result <<= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000313 break;
314 case BinaryOperator::Shr:
Chris Lattnerb542afe2008-07-11 19:10:17 +0000315 Result >>= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000316 break;
Chris Lattnerb542afe2008-07-11 19:10:17 +0000317
Chris Lattnerac7cb602008-07-11 19:29:32 +0000318 case BinaryOperator::LT:
319 Result = Result < RHS;
320 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
321 break;
322 case BinaryOperator::GT:
323 Result = Result > RHS;
324 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
325 break;
326 case BinaryOperator::LE:
327 Result = Result <= RHS;
328 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
329 break;
330 case BinaryOperator::GE:
331 Result = Result >= RHS;
332 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
333 break;
334 case BinaryOperator::EQ:
335 Result = Result == RHS;
336 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
337 break;
338 case BinaryOperator::NE:
339 Result = Result != RHS;
340 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
341 break;
Chris Lattner54176fd2008-07-12 00:14:42 +0000342 case BinaryOperator::LAnd:
343 Result = Result != 0 && RHS != 0;
344 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
345 break;
346 case BinaryOperator::LOr:
347 Result = Result != 0 || RHS != 0;
348 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
349 break;
350
Anders Carlsson06a36752008-07-08 05:49:43 +0000351
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000352 case BinaryOperator::Comma:
Chris Lattner54176fd2008-07-12 00:14:42 +0000353 // Result of the comma is just the result of the RHS.
354 Result = RHS;
355
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000356 // C99 6.6p3: "shall not contain assignment, ..., or comma operators,
357 // *except* when they are contained within a subexpression that is not
358 // evaluated". Note that Assignment can never happen due to constraints
359 // on the LHS subexpr, so we don't need to check it here.
Chris Lattner54176fd2008-07-12 00:14:42 +0000360 if (!Info.isEvaluated)
361 return true;
362
363 // If the value is evaluated, we can accept it as an extension.
364 return Extension(E->getOperatorLoc(), diag::ext_comma_in_constant_expr);
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000365 }
366
367 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnerb542afe2008-07-11 19:10:17 +0000368 return true;
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000369}
370
Chris Lattnerfcee0012008-07-11 21:24:13 +0000371/// EvaluateSizeAlignOf - Evaluate sizeof(SrcTy) or alignof(SrcTy) with a result
372/// as a DstTy type.
373bool IntExprEvaluator::EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy,
374 QualType DstTy) {
375 // Return the result in the right width.
376 Result.zextOrTrunc(getIntTypeSizeInBits(DstTy));
377 Result.setIsUnsigned(DstTy->isUnsignedIntegerType());
378
379 // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
380 if (SrcTy->isVoidType())
381 Result = 1;
382
383 // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
384 if (!SrcTy->isConstantSizeType()) {
385 // FIXME: Should we attempt to evaluate this?
386 return false;
387 }
388
389 // GCC extension: sizeof(function) = 1.
390 if (SrcTy->isFunctionType()) {
391 // FIXME: AlignOf shouldn't be unconditionally 4!
392 Result = isSizeOf ? 1 : 4;
393 return true;
394 }
395
396 // Get information about the size or align.
Chris Lattner87eae5e2008-07-11 22:52:41 +0000397 unsigned CharSize = Info.Ctx.Target.getCharWidth();
Chris Lattnerfcee0012008-07-11 21:24:13 +0000398 if (isSizeOf)
399 Result = getIntTypeSizeInBits(SrcTy) / CharSize;
400 else
Chris Lattner87eae5e2008-07-11 22:52:41 +0000401 Result = Info.Ctx.getTypeAlign(SrcTy) / CharSize;
Chris Lattnerfcee0012008-07-11 21:24:13 +0000402 return true;
403}
404
Chris Lattnerb542afe2008-07-11 19:10:17 +0000405bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
Chris Lattner4c4867e2008-07-12 00:38:25 +0000406 // Special case unary operators that do not need their subexpression
407 // evaluated. offsetof/sizeof/alignof are all special.
Chris Lattner75a48812008-07-11 22:15:16 +0000408 if (E->isOffsetOfOp()) {
Chris Lattner4c4867e2008-07-12 00:38:25 +0000409 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Chris Lattner87eae5e2008-07-11 22:52:41 +0000410 Result = E->evaluateOffsetOf(Info.Ctx);
Chris Lattner75a48812008-07-11 22:15:16 +0000411 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
412 return true;
413 }
414
415 if (E->isSizeOfAlignOfOp())
Chris Lattnerfcee0012008-07-11 21:24:13 +0000416 return EvaluateSizeAlignOf(E->getOpcode() == UnaryOperator::SizeOf,
417 E->getSubExpr()->getType(), E->getType());
Chris Lattner75a48812008-07-11 22:15:16 +0000418
Chris Lattner87eae5e2008-07-11 22:52:41 +0000419 // Get the operand value into 'Result'.
420 if (!Visit(E->getSubExpr()))
Chris Lattner75a48812008-07-11 22:15:16 +0000421 return false;
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000422
Chris Lattner75a48812008-07-11 22:15:16 +0000423 switch (E->getOpcode()) {
Chris Lattner4c4867e2008-07-12 00:38:25 +0000424 default:
Chris Lattner75a48812008-07-11 22:15:16 +0000425 // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
426 // See C99 6.6p3.
Chris Lattner4c4867e2008-07-12 00:38:25 +0000427 return Error(E->getOperatorLoc(), diag::err_expr_not_constant);
Chris Lattner75a48812008-07-11 22:15:16 +0000428 case UnaryOperator::LNot: {
429 bool Val = Result == 0;
430 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
431 Result = Val;
432 break;
433 }
434 case UnaryOperator::Extension:
Chris Lattner4c4867e2008-07-12 00:38:25 +0000435 // FIXME: Should extension allow i-c-e extension expressions in its scope?
436 // If so, we could clear the diagnostic ID.
Chris Lattner75a48812008-07-11 22:15:16 +0000437 case UnaryOperator::Plus:
Chris Lattner4c4867e2008-07-12 00:38:25 +0000438 // The result is always just the subexpr.
Chris Lattner75a48812008-07-11 22:15:16 +0000439 break;
440 case UnaryOperator::Minus:
441 Result = -Result;
442 break;
443 case UnaryOperator::Not:
444 Result = ~Result;
445 break;
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000446 }
447
448 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnerb542afe2008-07-11 19:10:17 +0000449 return true;
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000450}
451
Chris Lattner732b2232008-07-12 01:15:53 +0000452/// HandleCast - This is used to evaluate implicit or explicit casts where the
453/// result type is integer.
454bool IntExprEvaluator::HandleCast(SourceLocation CastLoc,
455 Expr *SubExpr, QualType DestType) {
Chris Lattner7a767782008-07-11 19:24:49 +0000456 unsigned DestWidth = getIntTypeSizeInBits(DestType);
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000457
458 // Handle simple integer->integer casts.
459 if (SubExpr->getType()->isIntegerType()) {
Chris Lattner732b2232008-07-12 01:15:53 +0000460 if (!Visit(SubExpr))
Chris Lattnerb542afe2008-07-11 19:10:17 +0000461 return false;
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000462
463 // Figure out if this is a truncate, extend or noop cast.
464 // If the input is signed, do a sign extend, noop, or truncate.
465 if (DestType->isBooleanType()) {
466 // Conversion to bool compares against zero.
467 Result = Result != 0;
468 Result.zextOrTrunc(DestWidth);
Chris Lattner7a767782008-07-11 19:24:49 +0000469 } else
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000470 Result.extOrTrunc(DestWidth);
Chris Lattner732b2232008-07-12 01:15:53 +0000471 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
472 return true;
473 }
474
475 // FIXME: Clean this up!
476 if (SubExpr->getType()->isPointerType()) {
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000477 APValue LV;
Chris Lattner87eae5e2008-07-11 22:52:41 +0000478 if (!EvaluatePointer(SubExpr, LV, Info))
Chris Lattnerb542afe2008-07-11 19:10:17 +0000479 return false;
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000480 if (LV.getLValueBase())
Chris Lattnerb542afe2008-07-11 19:10:17 +0000481 return false;
Anders Carlsson06a36752008-07-08 05:49:43 +0000482
Anders Carlsson559e56b2008-07-08 16:49:00 +0000483 Result.extOrTrunc(DestWidth);
484 Result = LV.getLValueOffset();
Chris Lattner732b2232008-07-12 01:15:53 +0000485 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
486 return true;
Anders Carlsson2bad1682008-07-08 14:30:00 +0000487 }
488
Chris Lattner732b2232008-07-12 01:15:53 +0000489 if (!SubExpr->getType()->isRealFloatingType())
490 return Error(CastLoc, diag::err_expr_not_constant);
491
Eli Friedmand8bfe7f2008-08-22 00:06:13 +0000492 APFloat F(0.0);
493 if (!EvaluateFloat(SubExpr, F, Info))
Chris Lattner732b2232008-07-12 01:15:53 +0000494 return Error(CastLoc, diag::err_expr_not_constant);
Eli Friedmand8bfe7f2008-08-22 00:06:13 +0000495
Chris Lattner732b2232008-07-12 01:15:53 +0000496 // If the destination is boolean, compare against zero.
497 if (DestType->isBooleanType()) {
Eli Friedmand8bfe7f2008-08-22 00:06:13 +0000498 Result = !F.isZero();
Chris Lattner732b2232008-07-12 01:15:53 +0000499 Result.zextOrTrunc(DestWidth);
500 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
501 return true;
502 }
503
504 // Determine whether we are converting to unsigned or signed.
505 bool DestSigned = DestType->isSignedIntegerType();
506
507 // FIXME: Warning for overflow.
508 uint64_t Space[4];
Eli Friedmand8bfe7f2008-08-22 00:06:13 +0000509 (void)F.convertToInteger(Space, DestWidth, DestSigned,
510 llvm::APFloat::rmTowardZero);
Chris Lattner732b2232008-07-12 01:15:53 +0000511 Result = llvm::APInt(DestWidth, 4, Space);
512 Result.setIsUnsigned(!DestSigned);
Chris Lattnerb542afe2008-07-11 19:10:17 +0000513 return true;
Anders Carlssona25ae3d2008-07-08 14:35:21 +0000514}
Anders Carlsson2bad1682008-07-08 14:30:00 +0000515
Chris Lattnerf5eeb052008-07-11 18:11:29 +0000516//===----------------------------------------------------------------------===//
Eli Friedmand8bfe7f2008-08-22 00:06:13 +0000517// Float Evaluation
518//===----------------------------------------------------------------------===//
519
520namespace {
521class VISIBILITY_HIDDEN FloatExprEvaluator
522 : public StmtVisitor<FloatExprEvaluator, bool> {
523 EvalInfo &Info;
524 APFloat &Result;
525public:
526 FloatExprEvaluator(EvalInfo &info, APFloat &result)
527 : Info(info), Result(result) {}
528
529 bool VisitStmt(Stmt *S) {
530 return false;
531 }
532
533 bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
Chris Lattner019f4e82008-10-06 05:28:25 +0000534 bool VisitCallExpr(const CallExpr *E);
Eli Friedmand8bfe7f2008-08-22 00:06:13 +0000535
536 bool VisitBinaryOperator(const BinaryOperator *E);
537 bool VisitFloatingLiteral(const FloatingLiteral *E);
538};
539} // end anonymous namespace
540
541static bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) {
542 return FloatExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
543}
544
Chris Lattner019f4e82008-10-06 05:28:25 +0000545bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
Chris Lattner34a74ab2008-10-06 05:53:16 +0000546 const llvm::fltSemantics &Sem =
547 Info.Ctx.getFloatTypeSemantics(E->getType());
Chris Lattner019f4e82008-10-06 05:28:25 +0000548
549 switch (E->isBuiltinCall()) {
Chris Lattner34a74ab2008-10-06 05:53:16 +0000550 default: return false;
Chris Lattner019f4e82008-10-06 05:28:25 +0000551 case Builtin::BI__builtin_huge_val:
552 case Builtin::BI__builtin_huge_valf:
553 case Builtin::BI__builtin_huge_vall:
554 case Builtin::BI__builtin_inf:
555 case Builtin::BI__builtin_inff:
556 case Builtin::BI__builtin_infl:
Chris Lattner34a74ab2008-10-06 05:53:16 +0000557 Result = llvm::APFloat::getInf(Sem);
558 return true;
Chris Lattner019f4e82008-10-06 05:28:25 +0000559 }
560}
561
562
Eli Friedmand8bfe7f2008-08-22 00:06:13 +0000563bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
564 // FIXME: Diagnostics? I really don't understand how the warnings
565 // and errors are supposed to work.
566 APFloat LHS(0.0), RHS(0.0);
567 if (!EvaluateFloat(E->getLHS(), Result, Info))
568 return false;
569 if (!EvaluateFloat(E->getRHS(), RHS, Info))
570 return false;
571
572 switch (E->getOpcode()) {
573 default: return false;
574 case BinaryOperator::Mul:
575 Result.multiply(RHS, APFloat::rmNearestTiesToEven);
576 return true;
577 case BinaryOperator::Add:
578 Result.add(RHS, APFloat::rmNearestTiesToEven);
579 return true;
580 case BinaryOperator::Sub:
581 Result.subtract(RHS, APFloat::rmNearestTiesToEven);
582 return true;
583 case BinaryOperator::Div:
584 Result.divide(RHS, APFloat::rmNearestTiesToEven);
585 return true;
586 case BinaryOperator::Rem:
587 Result.mod(RHS, APFloat::rmNearestTiesToEven);
588 return true;
589 }
590}
591
592bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) {
593 Result = E->getValue();
594 return true;
595}
596
597//===----------------------------------------------------------------------===//
Chris Lattnerf5eeb052008-07-11 18:11:29 +0000598// Top level TryEvaluate.
599//===----------------------------------------------------------------------===//
600
Chris Lattner019f4e82008-10-06 05:28:25 +0000601/// tryEvaluate - Return true if this is a constant which we can fold using
602/// any crazy technique (that has nothing to do with language standards) that
603/// we want to. If this function returns true, it returns the folded constant
604/// in Result.
Chris Lattnerb542afe2008-07-11 19:10:17 +0000605bool Expr::tryEvaluate(APValue &Result, ASTContext &Ctx) const {
Chris Lattner87eae5e2008-07-11 22:52:41 +0000606 EvalInfo Info(Ctx);
Anders Carlsson06a36752008-07-08 05:49:43 +0000607 if (getType()->isIntegerType()) {
Eli Friedmand8bfe7f2008-08-22 00:06:13 +0000608 llvm::APSInt sInt(32);
Chris Lattner87eae5e2008-07-11 22:52:41 +0000609 if (EvaluateInteger(this, sInt, Info)) {
Anders Carlsson06a36752008-07-08 05:49:43 +0000610 Result = APValue(sInt);
611 return true;
612 }
Eli Friedmand8bfe7f2008-08-22 00:06:13 +0000613 } else if (getType()->isPointerType()) {
614 if (EvaluatePointer(this, Result, Info)) {
615 return true;
616 }
617 } else if (getType()->isRealFloatingType()) {
618 llvm::APFloat f(0.0);
619 if (EvaluateFloat(this, f, Info)) {
620 Result = APValue(f);
621 return true;
622 }
623 }
Anders Carlsson165a70f2008-08-10 17:03:01 +0000624
Anders Carlssonc44eec62008-07-03 04:20:39 +0000625 return false;
626}