blob: 8ba27f01334545f7d1c48cbec4f708bc3f790e19 [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"
Seo Sanghyeonefddb9c2008-07-08 07:23:12 +000016#include "clang/AST/StmtVisitor.h"
Chris Lattner82437da2008-07-12 00:14:42 +000017#include "clang/Basic/Diagnostic.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
Chris Lattner422373c2008-07-11 22:52:41 +000023/// EvalInfo - This is a private struct used by the evaluator to capture
24/// information about a subexpression as it is folded. It retains information
25/// about the AST context, but also maintains information about the folded
26/// expression.
27///
28/// If an expression could be evaluated, it is still possible it is not a C
29/// "integer constant expression" or constant expression. If not, this struct
30/// captures information about how and why not.
31///
32/// One bit of information passed *into* the request for constant folding
33/// indicates whether the subexpression is "evaluated" or not according to C
34/// rules. For example, the RHS of (0 && foo()) is not evaluated. We can
35/// evaluate the expression regardless of what the RHS is, but C only allows
36/// certain things in certain situations.
37struct EvalInfo {
38 ASTContext &Ctx;
39
40 /// isEvaluated - True if the subexpression is required to be evaluated, false
41 /// if it is short-circuited (according to C rules).
42 bool isEvaluated;
43
Chris Lattner82437da2008-07-12 00:14:42 +000044 /// ICEDiag - If the expression is unfoldable, then ICEDiag contains the
45 /// error diagnostic indicating why it is not foldable and DiagLoc indicates a
46 /// caret position for the error. If it is foldable, but the expression is
47 /// not an integer constant expression, ICEDiag contains the extension
48 /// diagnostic to emit which describes why it isn't an integer constant
49 /// expression. If this expression *is* an integer-constant-expr, then
50 /// ICEDiag is zero.
Chris Lattner422373c2008-07-11 22:52:41 +000051 ///
Chris Lattner82437da2008-07-12 00:14:42 +000052 /// The caller can choose to emit this diagnostic or not, depending on whether
53 /// they require an i-c-e or a constant or not. DiagLoc indicates the caret
54 /// position for the report.
55 ///
56 /// If ICEDiag is zero, then this expression is an i-c-e.
Chris Lattner422373c2008-07-11 22:52:41 +000057 unsigned ICEDiag;
58 SourceLocation DiagLoc;
59
60 EvalInfo(ASTContext &ctx) : Ctx(ctx), isEvaluated(true), ICEDiag(0) {}
61};
62
63
64static bool EvaluatePointer(const Expr *E, APValue &Result, EvalInfo &Info);
65static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info);
Chris Lattnera823ccf2008-07-11 18:11:29 +000066
67
68//===----------------------------------------------------------------------===//
69// Pointer Evaluation
70//===----------------------------------------------------------------------===//
71
Anders Carlssoncad17b52008-07-08 05:13:58 +000072namespace {
Anders Carlsson02a34c32008-07-08 14:30:00 +000073class VISIBILITY_HIDDEN PointerExprEvaluator
74 : public StmtVisitor<PointerExprEvaluator, APValue> {
Chris Lattner422373c2008-07-11 22:52:41 +000075 EvalInfo &Info;
Anders Carlsson02a34c32008-07-08 14:30:00 +000076public:
Anders Carlsson02a34c32008-07-08 14:30:00 +000077
Chris Lattner422373c2008-07-11 22:52:41 +000078 PointerExprEvaluator(EvalInfo &info) : Info(info) {}
Chris Lattnera823ccf2008-07-11 18:11:29 +000079
Anders Carlsson02a34c32008-07-08 14:30:00 +000080 APValue VisitStmt(Stmt *S) {
81 // FIXME: Remove this when we support more expressions.
Anders Carlssonc43f44b2008-07-08 15:34:11 +000082 printf("Unhandled pointer statement\n");
Anders Carlsson02a34c32008-07-08 14:30:00 +000083 S->dump();
84 return APValue();
85 }
86
87 APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
88
Anders Carlssonc43f44b2008-07-08 15:34:11 +000089 APValue VisitBinaryOperator(const BinaryOperator *E);
90 APValue VisitCastExpr(const CastExpr* E);
Anders Carlssonc43f44b2008-07-08 15:34:11 +000091};
Chris Lattnera823ccf2008-07-11 18:11:29 +000092} // end anonymous namespace
Anders Carlssonc43f44b2008-07-08 15:34:11 +000093
Chris Lattner422373c2008-07-11 22:52:41 +000094static bool EvaluatePointer(const Expr* E, APValue& Result, EvalInfo &Info) {
Chris Lattnera823ccf2008-07-11 18:11:29 +000095 if (!E->getType()->isPointerType())
96 return false;
Chris Lattner422373c2008-07-11 22:52:41 +000097 Result = PointerExprEvaluator(Info).Visit(const_cast<Expr*>(E));
Chris Lattnera823ccf2008-07-11 18:11:29 +000098 return Result.isLValue();
99}
100
101APValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
102 if (E->getOpcode() != BinaryOperator::Add &&
103 E->getOpcode() != BinaryOperator::Sub)
104 return APValue();
105
106 const Expr *PExp = E->getLHS();
107 const Expr *IExp = E->getRHS();
108 if (IExp->getType()->isPointerType())
109 std::swap(PExp, IExp);
110
111 APValue ResultLValue;
Chris Lattner422373c2008-07-11 22:52:41 +0000112 if (!EvaluatePointer(PExp, ResultLValue, Info))
Chris Lattnera823ccf2008-07-11 18:11:29 +0000113 return APValue();
114
115 llvm::APSInt AdditionalOffset(32);
Chris Lattner422373c2008-07-11 22:52:41 +0000116 if (!EvaluateInteger(IExp, AdditionalOffset, Info))
Chris Lattnera823ccf2008-07-11 18:11:29 +0000117 return APValue();
118
119 uint64_t Offset = ResultLValue.getLValueOffset();
120 if (E->getOpcode() == BinaryOperator::Add)
121 Offset += AdditionalOffset.getZExtValue();
122 else
123 Offset -= AdditionalOffset.getZExtValue();
124
125 return APValue(ResultLValue.getLValueBase(), Offset);
126}
127
128
Chris Lattnera42f09a2008-07-11 19:10:17 +0000129APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
Chris Lattnera823ccf2008-07-11 18:11:29 +0000130 const Expr* SubExpr = E->getSubExpr();
131
132 // Check for pointer->pointer cast
133 if (SubExpr->getType()->isPointerType()) {
134 APValue Result;
Chris Lattner422373c2008-07-11 22:52:41 +0000135 if (EvaluatePointer(SubExpr, Result, Info))
Chris Lattnera823ccf2008-07-11 18:11:29 +0000136 return Result;
137 return APValue();
138 }
139
Eli Friedman3e64dd72008-07-27 05:46:18 +0000140 if (SubExpr->getType()->isIntegralType()) {
Chris Lattnera823ccf2008-07-11 18:11:29 +0000141 llvm::APSInt Result(32);
Chris Lattner422373c2008-07-11 22:52:41 +0000142 if (EvaluateInteger(SubExpr, Result, Info)) {
143 Result.extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
Chris Lattnera823ccf2008-07-11 18:11:29 +0000144 return APValue(0, Result.getZExtValue());
145 }
146 }
147
148 assert(0 && "Unhandled cast");
149 return APValue();
150}
151
152
153//===----------------------------------------------------------------------===//
154// Integer Evaluation
155//===----------------------------------------------------------------------===//
Chris Lattnera823ccf2008-07-11 18:11:29 +0000156
157namespace {
Anders Carlssoncad17b52008-07-08 05:13:58 +0000158class VISIBILITY_HIDDEN IntExprEvaluator
Chris Lattnera42f09a2008-07-11 19:10:17 +0000159 : public StmtVisitor<IntExprEvaluator, bool> {
Chris Lattner422373c2008-07-11 22:52:41 +0000160 EvalInfo &Info;
Chris Lattnera42f09a2008-07-11 19:10:17 +0000161 APSInt &Result;
Anders Carlssoncad17b52008-07-08 05:13:58 +0000162public:
Chris Lattner422373c2008-07-11 22:52:41 +0000163 IntExprEvaluator(EvalInfo &info, APSInt &result)
164 : Info(info), Result(result) {}
Chris Lattnera823ccf2008-07-11 18:11:29 +0000165
Chris Lattner2c99c712008-07-11 19:24:49 +0000166 unsigned getIntTypeSizeInBits(QualType T) const {
Chris Lattner82437da2008-07-12 00:14:42 +0000167 return (unsigned)Info.Ctx.getIntWidth(T);
168 }
169
170 bool Extension(SourceLocation L, diag::kind D) {
171 Info.DiagLoc = L;
172 Info.ICEDiag = D;
173 return true; // still a constant.
174 }
175
176 bool Error(SourceLocation L, diag::kind D) {
177 // If this is in an unevaluated portion of the subexpression, ignore the
178 // error.
179 if (!Info.isEvaluated)
180 return true;
181
182 Info.DiagLoc = L;
183 Info.ICEDiag = D;
184 return false;
Chris Lattner2c99c712008-07-11 19:24:49 +0000185 }
186
Anders Carlssoncad17b52008-07-08 05:13:58 +0000187 //===--------------------------------------------------------------------===//
188 // Visitor Methods
189 //===--------------------------------------------------------------------===//
Chris Lattner2c99c712008-07-11 19:24:49 +0000190
Chris Lattnera42f09a2008-07-11 19:10:17 +0000191 bool VisitStmt(Stmt *S) {
Chris Lattner82437da2008-07-12 00:14:42 +0000192 return Error(S->getLocStart(), diag::err_expr_not_constant);
Anders Carlssoncad17b52008-07-08 05:13:58 +0000193 }
194
Chris Lattnera42f09a2008-07-11 19:10:17 +0000195 bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
Anders Carlssoncad17b52008-07-08 05:13:58 +0000196
Chris Lattner15e59112008-07-12 00:38:25 +0000197 bool VisitIntegerLiteral(const IntegerLiteral *E) {
198 Result = E->getValue();
199 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
200 return true;
201 }
202 bool VisitCharacterLiteral(const CharacterLiteral *E) {
203 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
204 Result = E->getValue();
205 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
206 return true;
207 }
208 bool VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
209 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
210 Result = Info.Ctx.typesAreCompatible(E->getArgType1(), E->getArgType2());
211 return true;
212 }
213 bool VisitDeclRefExpr(const DeclRefExpr *E);
214 bool VisitCallExpr(const CallExpr *E);
Chris Lattnera42f09a2008-07-11 19:10:17 +0000215 bool VisitBinaryOperator(const BinaryOperator *E);
216 bool VisitUnaryOperator(const UnaryOperator *E);
Anders Carlssonc0328012008-07-08 05:49:43 +0000217
Chris Lattnerff579ff2008-07-12 01:15:53 +0000218 bool VisitCastExpr(CastExpr* E) {
Chris Lattnerff579ff2008-07-12 01:15:53 +0000219 return HandleCast(E->getLocStart(), E->getSubExpr(), E->getType());
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000220 }
Chris Lattner265a0892008-07-11 21:24:13 +0000221 bool VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) {
Chris Lattner82437da2008-07-12 00:14:42 +0000222 return EvaluateSizeAlignOf(E->isSizeOf(), E->getArgumentType(),
223 E->getType());
Chris Lattner265a0892008-07-11 21:24:13 +0000224 }
Chris Lattner15e59112008-07-12 00:38:25 +0000225
Chris Lattner265a0892008-07-11 21:24:13 +0000226private:
Chris Lattnerff579ff2008-07-12 01:15:53 +0000227 bool HandleCast(SourceLocation CastLoc, Expr *SubExpr, QualType DestType);
Chris Lattner265a0892008-07-11 21:24:13 +0000228 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
Chris Lattner15e59112008-07-12 00:38:25 +0000236bool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
237 // Enums are integer constant exprs.
238 if (const EnumConstantDecl *D = dyn_cast<EnumConstantDecl>(E->getDecl())) {
239 Result = D->getInitVal();
240 return true;
241 }
242
243 // Otherwise, random variable references are not constants.
244 return Error(E->getLocStart(), diag::err_expr_not_constant);
245}
246
247
248bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
249 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
250 // __builtin_type_compatible_p is a constant.
251 if (E->isBuiltinClassifyType(Result))
252 return true;
253
254 return Error(E->getLocStart(), diag::err_expr_not_constant);
255}
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000256
Chris Lattnera42f09a2008-07-11 19:10:17 +0000257bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
Anders Carlssond1aa5812008-07-08 14:35:21 +0000258 // The LHS of a constant expr is always evaluated and needed.
Anders Carlssond1aa5812008-07-08 14:35:21 +0000259 llvm::APSInt RHS(32);
Chris Lattner82437da2008-07-12 00:14:42 +0000260 if (!Visit(E->getLHS()))
261 return false; // error in subexpression.
262
263 bool OldEval = Info.isEvaluated;
264
265 // The short-circuiting &&/|| operators don't necessarily evaluate their
266 // RHS. Make sure to pass isEvaluated down correctly.
267 if ((E->getOpcode() == BinaryOperator::LAnd && Result == 0) ||
268 (E->getOpcode() == BinaryOperator::LOr && Result != 0))
269 Info.isEvaluated = false;
Eli Friedman3e64dd72008-07-27 05:46:18 +0000270
271 // FIXME: Handle pointer subtraction
272
273 // FIXME Maybe we want to succeed even where we can't evaluate the
274 // right side of LAnd/LOr?
275 // For example, see http://llvm.org/bugs/show_bug.cgi?id=2525
Chris Lattner82437da2008-07-12 00:14:42 +0000276 if (!EvaluateInteger(E->getRHS(), RHS, Info))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000277 return false;
Chris Lattner82437da2008-07-12 00:14:42 +0000278 Info.isEvaluated = OldEval;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000279
280 switch (E->getOpcode()) {
Chris Lattner82437da2008-07-12 00:14:42 +0000281 default: return Error(E->getOperatorLoc(), diag::err_expr_not_constant);
282 case BinaryOperator::Mul: Result *= RHS; return true;
283 case BinaryOperator::Add: Result += RHS; return true;
284 case BinaryOperator::Sub: Result -= RHS; return true;
285 case BinaryOperator::And: Result &= RHS; return true;
286 case BinaryOperator::Xor: Result ^= RHS; return true;
287 case BinaryOperator::Or: Result |= RHS; return true;
Chris Lattner400d7402008-07-11 22:15:16 +0000288 case BinaryOperator::Div:
Chris Lattner82437da2008-07-12 00:14:42 +0000289 if (RHS == 0)
290 return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero);
Chris Lattner400d7402008-07-11 22:15:16 +0000291 Result /= RHS;
Chris Lattner82437da2008-07-12 00:14:42 +0000292 return true;
Chris Lattner400d7402008-07-11 22:15:16 +0000293 case BinaryOperator::Rem:
Chris Lattner82437da2008-07-12 00:14:42 +0000294 if (RHS == 0)
295 return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero);
Chris Lattner400d7402008-07-11 22:15:16 +0000296 Result %= RHS;
Chris Lattner82437da2008-07-12 00:14:42 +0000297 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000298 case BinaryOperator::Shl:
Chris Lattner82437da2008-07-12 00:14:42 +0000299 // FIXME: Warn about out of range shift amounts!
Chris Lattnera42f09a2008-07-11 19:10:17 +0000300 Result <<= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000301 break;
302 case BinaryOperator::Shr:
Chris Lattnera42f09a2008-07-11 19:10:17 +0000303 Result >>= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000304 break;
Chris Lattnera42f09a2008-07-11 19:10:17 +0000305
Chris Lattner045502c2008-07-11 19:29:32 +0000306 case BinaryOperator::LT:
307 Result = Result < RHS;
308 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
309 break;
310 case BinaryOperator::GT:
311 Result = Result > RHS;
312 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
313 break;
314 case BinaryOperator::LE:
315 Result = Result <= RHS;
316 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
317 break;
318 case BinaryOperator::GE:
319 Result = Result >= RHS;
320 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
321 break;
322 case BinaryOperator::EQ:
323 Result = Result == RHS;
324 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
325 break;
326 case BinaryOperator::NE:
327 Result = Result != RHS;
328 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
329 break;
Chris Lattner82437da2008-07-12 00:14:42 +0000330 case BinaryOperator::LAnd:
331 Result = Result != 0 && RHS != 0;
332 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
333 break;
334 case BinaryOperator::LOr:
335 Result = Result != 0 || RHS != 0;
336 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
337 break;
338
Anders Carlssonc0328012008-07-08 05:49:43 +0000339
Anders Carlssond1aa5812008-07-08 14:35:21 +0000340 case BinaryOperator::Comma:
Chris Lattner82437da2008-07-12 00:14:42 +0000341 // Result of the comma is just the result of the RHS.
342 Result = RHS;
343
Anders Carlssond1aa5812008-07-08 14:35:21 +0000344 // C99 6.6p3: "shall not contain assignment, ..., or comma operators,
345 // *except* when they are contained within a subexpression that is not
346 // evaluated". Note that Assignment can never happen due to constraints
347 // on the LHS subexpr, so we don't need to check it here.
Chris Lattner82437da2008-07-12 00:14:42 +0000348 if (!Info.isEvaluated)
349 return true;
350
351 // If the value is evaluated, we can accept it as an extension.
352 return Extension(E->getOperatorLoc(), diag::ext_comma_in_constant_expr);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000353 }
354
355 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000356 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000357}
358
Chris Lattner265a0892008-07-11 21:24:13 +0000359/// EvaluateSizeAlignOf - Evaluate sizeof(SrcTy) or alignof(SrcTy) with a result
360/// as a DstTy type.
361bool IntExprEvaluator::EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy,
362 QualType DstTy) {
363 // Return the result in the right width.
364 Result.zextOrTrunc(getIntTypeSizeInBits(DstTy));
365 Result.setIsUnsigned(DstTy->isUnsignedIntegerType());
366
367 // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
368 if (SrcTy->isVoidType())
369 Result = 1;
370
371 // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
372 if (!SrcTy->isConstantSizeType()) {
373 // FIXME: Should we attempt to evaluate this?
374 return false;
375 }
376
377 // GCC extension: sizeof(function) = 1.
378 if (SrcTy->isFunctionType()) {
379 // FIXME: AlignOf shouldn't be unconditionally 4!
380 Result = isSizeOf ? 1 : 4;
381 return true;
382 }
383
384 // Get information about the size or align.
Chris Lattner422373c2008-07-11 22:52:41 +0000385 unsigned CharSize = Info.Ctx.Target.getCharWidth();
Chris Lattner265a0892008-07-11 21:24:13 +0000386 if (isSizeOf)
387 Result = getIntTypeSizeInBits(SrcTy) / CharSize;
388 else
Chris Lattner422373c2008-07-11 22:52:41 +0000389 Result = Info.Ctx.getTypeAlign(SrcTy) / CharSize;
Chris Lattner265a0892008-07-11 21:24:13 +0000390 return true;
391}
392
Chris Lattnera42f09a2008-07-11 19:10:17 +0000393bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
Chris Lattner15e59112008-07-12 00:38:25 +0000394 // Special case unary operators that do not need their subexpression
395 // evaluated. offsetof/sizeof/alignof are all special.
Chris Lattner400d7402008-07-11 22:15:16 +0000396 if (E->isOffsetOfOp()) {
Chris Lattner15e59112008-07-12 00:38:25 +0000397 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Chris Lattner422373c2008-07-11 22:52:41 +0000398 Result = E->evaluateOffsetOf(Info.Ctx);
Chris Lattner400d7402008-07-11 22:15:16 +0000399 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
400 return true;
401 }
402
403 if (E->isSizeOfAlignOfOp())
Chris Lattner265a0892008-07-11 21:24:13 +0000404 return EvaluateSizeAlignOf(E->getOpcode() == UnaryOperator::SizeOf,
405 E->getSubExpr()->getType(), E->getType());
Chris Lattner400d7402008-07-11 22:15:16 +0000406
Chris Lattner422373c2008-07-11 22:52:41 +0000407 // Get the operand value into 'Result'.
408 if (!Visit(E->getSubExpr()))
Chris Lattner400d7402008-07-11 22:15:16 +0000409 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000410
Chris Lattner400d7402008-07-11 22:15:16 +0000411 switch (E->getOpcode()) {
Chris Lattner15e59112008-07-12 00:38:25 +0000412 default:
Chris Lattner400d7402008-07-11 22:15:16 +0000413 // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
414 // See C99 6.6p3.
Chris Lattner15e59112008-07-12 00:38:25 +0000415 return Error(E->getOperatorLoc(), diag::err_expr_not_constant);
Chris Lattner400d7402008-07-11 22:15:16 +0000416 case UnaryOperator::LNot: {
417 bool Val = Result == 0;
418 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
419 Result = Val;
420 break;
421 }
422 case UnaryOperator::Extension:
Chris Lattner15e59112008-07-12 00:38:25 +0000423 // FIXME: Should extension allow i-c-e extension expressions in its scope?
424 // If so, we could clear the diagnostic ID.
Chris Lattner400d7402008-07-11 22:15:16 +0000425 case UnaryOperator::Plus:
Chris Lattner15e59112008-07-12 00:38:25 +0000426 // The result is always just the subexpr.
Chris Lattner400d7402008-07-11 22:15:16 +0000427 break;
428 case UnaryOperator::Minus:
429 Result = -Result;
430 break;
431 case UnaryOperator::Not:
432 Result = ~Result;
433 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000434 }
435
436 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000437 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000438}
439
Chris Lattnerff579ff2008-07-12 01:15:53 +0000440/// HandleCast - This is used to evaluate implicit or explicit casts where the
441/// result type is integer.
442bool IntExprEvaluator::HandleCast(SourceLocation CastLoc,
443 Expr *SubExpr, QualType DestType) {
Chris Lattner2c99c712008-07-11 19:24:49 +0000444 unsigned DestWidth = getIntTypeSizeInBits(DestType);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000445
446 // Handle simple integer->integer casts.
447 if (SubExpr->getType()->isIntegerType()) {
Chris Lattnerff579ff2008-07-12 01:15:53 +0000448 if (!Visit(SubExpr))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000449 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000450
451 // Figure out if this is a truncate, extend or noop cast.
452 // If the input is signed, do a sign extend, noop, or truncate.
453 if (DestType->isBooleanType()) {
454 // Conversion to bool compares against zero.
455 Result = Result != 0;
456 Result.zextOrTrunc(DestWidth);
Chris Lattner2c99c712008-07-11 19:24:49 +0000457 } else
Anders Carlssond1aa5812008-07-08 14:35:21 +0000458 Result.extOrTrunc(DestWidth);
Chris Lattnerff579ff2008-07-12 01:15:53 +0000459 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
460 return true;
461 }
462
463 // FIXME: Clean this up!
464 if (SubExpr->getType()->isPointerType()) {
Anders Carlssond1aa5812008-07-08 14:35:21 +0000465 APValue LV;
Chris Lattner422373c2008-07-11 22:52:41 +0000466 if (!EvaluatePointer(SubExpr, LV, Info))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000467 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000468 if (LV.getLValueBase())
Chris Lattnera42f09a2008-07-11 19:10:17 +0000469 return false;
Anders Carlssonc0328012008-07-08 05:49:43 +0000470
Anders Carlsson8ab15c82008-07-08 16:49:00 +0000471 Result.extOrTrunc(DestWidth);
472 Result = LV.getLValueOffset();
Chris Lattnerff579ff2008-07-12 01:15:53 +0000473 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
474 return true;
Anders Carlsson02a34c32008-07-08 14:30:00 +0000475 }
476
Chris Lattnerff579ff2008-07-12 01:15:53 +0000477 if (!SubExpr->getType()->isRealFloatingType())
478 return Error(CastLoc, diag::err_expr_not_constant);
479
480 // FIXME: Generalize floating point constant folding! For now we just permit
481 // which is allowed by integer constant expressions.
482
483 // Allow floating constants that are the immediate operands of casts or that
484 // are parenthesized.
485 const Expr *Operand = SubExpr;
486 while (const ParenExpr *PE = dyn_cast<ParenExpr>(Operand))
487 Operand = PE->getSubExpr();
488
489 // If this isn't a floating literal, we can't handle it.
490 const FloatingLiteral *FL = dyn_cast<FloatingLiteral>(Operand);
491 if (!FL)
492 return Error(CastLoc, diag::err_expr_not_constant);
493
494 // If the destination is boolean, compare against zero.
495 if (DestType->isBooleanType()) {
496 Result = !FL->getValue().isZero();
497 Result.zextOrTrunc(DestWidth);
498 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
499 return true;
500 }
501
502 // Determine whether we are converting to unsigned or signed.
503 bool DestSigned = DestType->isSignedIntegerType();
504
505 // FIXME: Warning for overflow.
506 uint64_t Space[4];
507 (void)FL->getValue().convertToInteger(Space, DestWidth, DestSigned,
508 llvm::APFloat::rmTowardZero);
509 Result = llvm::APInt(DestWidth, 4, Space);
510 Result.setIsUnsigned(!DestSigned);
Chris Lattnera42f09a2008-07-11 19:10:17 +0000511 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000512}
Anders Carlsson02a34c32008-07-08 14:30:00 +0000513
Chris Lattnera823ccf2008-07-11 18:11:29 +0000514//===----------------------------------------------------------------------===//
515// Top level TryEvaluate.
516//===----------------------------------------------------------------------===//
517
Chris Lattnera42f09a2008-07-11 19:10:17 +0000518bool Expr::tryEvaluate(APValue &Result, ASTContext &Ctx) const {
Chris Lattner334b1942008-07-11 19:19:21 +0000519 llvm::APSInt sInt(32);
Anders Carlsson47968a92008-08-10 17:03:01 +0000520
Chris Lattner422373c2008-07-11 22:52:41 +0000521 EvalInfo Info(Ctx);
Anders Carlssonc0328012008-07-08 05:49:43 +0000522 if (getType()->isIntegerType()) {
Chris Lattner422373c2008-07-11 22:52:41 +0000523 if (EvaluateInteger(this, sInt, Info)) {
Anders Carlssonc0328012008-07-08 05:49:43 +0000524 Result = APValue(sInt);
525 return true;
526 }
527 } else
Anders Carlssoncad17b52008-07-08 05:13:58 +0000528 return false;
Anders Carlsson47968a92008-08-10 17:03:01 +0000529
Anders Carlssonc7436af2008-07-03 04:20:39 +0000530 return false;
531}