blob: 99fa8d5813dd54d96df4fb6b3447e22e99d86081 [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;
Eli Friedman2f445492008-08-22 00:06:13 +000022using llvm::APFloat;
Anders Carlssonc7436af2008-07-03 04:20:39 +000023
Chris Lattner422373c2008-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 Lattner82437da2008-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 Lattner422373c2008-07-11 22:52:41 +000052 ///
Chris Lattner82437da2008-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 Lattner422373c2008-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 Friedman2f445492008-08-22 00:06:13 +000067static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
Chris Lattnera823ccf2008-07-11 18:11:29 +000068
69//===----------------------------------------------------------------------===//
70// Pointer Evaluation
71//===----------------------------------------------------------------------===//
72
Anders Carlssoncad17b52008-07-08 05:13:58 +000073namespace {
Anders Carlsson02a34c32008-07-08 14:30:00 +000074class VISIBILITY_HIDDEN PointerExprEvaluator
75 : public StmtVisitor<PointerExprEvaluator, APValue> {
Chris Lattner422373c2008-07-11 22:52:41 +000076 EvalInfo &Info;
Anders Carlsson02a34c32008-07-08 14:30:00 +000077public:
Anders Carlsson02a34c32008-07-08 14:30:00 +000078
Chris Lattner422373c2008-07-11 22:52:41 +000079 PointerExprEvaluator(EvalInfo &info) : Info(info) {}
Chris Lattnera823ccf2008-07-11 18:11:29 +000080
Anders Carlsson02a34c32008-07-08 14:30:00 +000081 APValue VisitStmt(Stmt *S) {
Anders Carlsson02a34c32008-07-08 14:30:00 +000082 return APValue();
83 }
84
85 APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
86
Anders Carlssonc43f44b2008-07-08 15:34:11 +000087 APValue VisitBinaryOperator(const BinaryOperator *E);
88 APValue VisitCastExpr(const CastExpr* E);
Anders Carlssonc43f44b2008-07-08 15:34:11 +000089};
Chris Lattnera823ccf2008-07-11 18:11:29 +000090} // end anonymous namespace
Anders Carlssonc43f44b2008-07-08 15:34:11 +000091
Chris Lattner422373c2008-07-11 22:52:41 +000092static bool EvaluatePointer(const Expr* E, APValue& Result, EvalInfo &Info) {
Chris Lattnera823ccf2008-07-11 18:11:29 +000093 if (!E->getType()->isPointerType())
94 return false;
Chris Lattner422373c2008-07-11 22:52:41 +000095 Result = PointerExprEvaluator(Info).Visit(const_cast<Expr*>(E));
Chris Lattnera823ccf2008-07-11 18:11:29 +000096 return Result.isLValue();
97}
98
99APValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
100 if (E->getOpcode() != BinaryOperator::Add &&
101 E->getOpcode() != BinaryOperator::Sub)
102 return APValue();
103
104 const Expr *PExp = E->getLHS();
105 const Expr *IExp = E->getRHS();
106 if (IExp->getType()->isPointerType())
107 std::swap(PExp, IExp);
108
109 APValue ResultLValue;
Chris Lattner422373c2008-07-11 22:52:41 +0000110 if (!EvaluatePointer(PExp, ResultLValue, Info))
Chris Lattnera823ccf2008-07-11 18:11:29 +0000111 return APValue();
112
113 llvm::APSInt AdditionalOffset(32);
Chris Lattner422373c2008-07-11 22:52:41 +0000114 if (!EvaluateInteger(IExp, AdditionalOffset, Info))
Chris Lattnera823ccf2008-07-11 18:11:29 +0000115 return APValue();
116
117 uint64_t Offset = ResultLValue.getLValueOffset();
118 if (E->getOpcode() == BinaryOperator::Add)
119 Offset += AdditionalOffset.getZExtValue();
120 else
121 Offset -= AdditionalOffset.getZExtValue();
122
123 return APValue(ResultLValue.getLValueBase(), Offset);
124}
125
126
Chris Lattnera42f09a2008-07-11 19:10:17 +0000127APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
Chris Lattnera823ccf2008-07-11 18:11:29 +0000128 const Expr* SubExpr = E->getSubExpr();
129
130 // Check for pointer->pointer cast
131 if (SubExpr->getType()->isPointerType()) {
132 APValue Result;
Chris Lattner422373c2008-07-11 22:52:41 +0000133 if (EvaluatePointer(SubExpr, Result, Info))
Chris Lattnera823ccf2008-07-11 18:11:29 +0000134 return Result;
135 return APValue();
136 }
137
Eli Friedman3e64dd72008-07-27 05:46:18 +0000138 if (SubExpr->getType()->isIntegralType()) {
Chris Lattnera823ccf2008-07-11 18:11:29 +0000139 llvm::APSInt Result(32);
Chris Lattner422373c2008-07-11 22:52:41 +0000140 if (EvaluateInteger(SubExpr, Result, Info)) {
141 Result.extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
Chris Lattnera823ccf2008-07-11 18:11:29 +0000142 return APValue(0, Result.getZExtValue());
143 }
144 }
145
146 assert(0 && "Unhandled cast");
147 return APValue();
148}
149
150
151//===----------------------------------------------------------------------===//
152// Integer Evaluation
153//===----------------------------------------------------------------------===//
Chris Lattnera823ccf2008-07-11 18:11:29 +0000154
155namespace {
Anders Carlssoncad17b52008-07-08 05:13:58 +0000156class VISIBILITY_HIDDEN IntExprEvaluator
Chris Lattnera42f09a2008-07-11 19:10:17 +0000157 : public StmtVisitor<IntExprEvaluator, bool> {
Chris Lattner422373c2008-07-11 22:52:41 +0000158 EvalInfo &Info;
Chris Lattnera42f09a2008-07-11 19:10:17 +0000159 APSInt &Result;
Anders Carlssoncad17b52008-07-08 05:13:58 +0000160public:
Chris Lattner422373c2008-07-11 22:52:41 +0000161 IntExprEvaluator(EvalInfo &info, APSInt &result)
162 : Info(info), Result(result) {}
Chris Lattnera823ccf2008-07-11 18:11:29 +0000163
Chris Lattner2c99c712008-07-11 19:24:49 +0000164 unsigned getIntTypeSizeInBits(QualType T) const {
Chris Lattner82437da2008-07-12 00:14:42 +0000165 return (unsigned)Info.Ctx.getIntWidth(T);
166 }
167
168 bool Extension(SourceLocation L, diag::kind D) {
169 Info.DiagLoc = L;
170 Info.ICEDiag = D;
171 return true; // still a constant.
172 }
173
174 bool Error(SourceLocation L, diag::kind D) {
175 // If this is in an unevaluated portion of the subexpression, ignore the
176 // error.
177 if (!Info.isEvaluated)
178 return true;
179
180 Info.DiagLoc = L;
181 Info.ICEDiag = D;
182 return false;
Chris Lattner2c99c712008-07-11 19:24:49 +0000183 }
184
Anders Carlssoncad17b52008-07-08 05:13:58 +0000185 //===--------------------------------------------------------------------===//
186 // Visitor Methods
187 //===--------------------------------------------------------------------===//
Chris Lattner2c99c712008-07-11 19:24:49 +0000188
Chris Lattnera42f09a2008-07-11 19:10:17 +0000189 bool VisitStmt(Stmt *S) {
Chris Lattner82437da2008-07-12 00:14:42 +0000190 return Error(S->getLocStart(), diag::err_expr_not_constant);
Anders Carlssoncad17b52008-07-08 05:13:58 +0000191 }
192
Chris Lattnera42f09a2008-07-11 19:10:17 +0000193 bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
Anders Carlssoncad17b52008-07-08 05:13:58 +0000194
Chris Lattner15e59112008-07-12 00:38:25 +0000195 bool VisitIntegerLiteral(const IntegerLiteral *E) {
196 Result = E->getValue();
197 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
198 return true;
199 }
200 bool VisitCharacterLiteral(const CharacterLiteral *E) {
201 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
202 Result = E->getValue();
203 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
204 return true;
205 }
206 bool VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
207 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Daniel Dunbarda8ebd22008-10-24 08:07:57 +0000208 // Per gcc docs "this built-in function ignores top level
209 // qualifiers". We need to use the canonical version to properly
210 // be able to strip CRV qualifiers from the type.
211 QualType T0 = Info.Ctx.getCanonicalType(E->getArgType1());
212 QualType T1 = Info.Ctx.getCanonicalType(E->getArgType2());
213 Result = Info.Ctx.typesAreCompatible(T0.getUnqualifiedType(),
214 T1.getUnqualifiedType());
Chris Lattner15e59112008-07-12 00:38:25 +0000215 return true;
216 }
217 bool VisitDeclRefExpr(const DeclRefExpr *E);
218 bool VisitCallExpr(const CallExpr *E);
Chris Lattnera42f09a2008-07-11 19:10:17 +0000219 bool VisitBinaryOperator(const BinaryOperator *E);
220 bool VisitUnaryOperator(const UnaryOperator *E);
Anders Carlssonc0328012008-07-08 05:49:43 +0000221
Chris Lattnerff579ff2008-07-12 01:15:53 +0000222 bool VisitCastExpr(CastExpr* E) {
Chris Lattnerff579ff2008-07-12 01:15:53 +0000223 return HandleCast(E->getLocStart(), E->getSubExpr(), E->getType());
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000224 }
Sebastian Redl0cb7c872008-11-11 17:56:53 +0000225 bool VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
226
Chris Lattner265a0892008-07-11 21:24:13 +0000227private:
Chris Lattnerff579ff2008-07-12 01:15:53 +0000228 bool HandleCast(SourceLocation CastLoc, Expr *SubExpr, QualType DestType);
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
Chris Lattner1eee9402008-10-06 06:40:35 +0000247/// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way
248/// as GCC.
249static int EvaluateBuiltinClassifyType(const CallExpr *E) {
250 // The following enum mimics the values returned by GCC.
251 enum gcc_type_class {
252 no_type_class = -1,
253 void_type_class, integer_type_class, char_type_class,
254 enumeral_type_class, boolean_type_class,
255 pointer_type_class, reference_type_class, offset_type_class,
256 real_type_class, complex_type_class,
257 function_type_class, method_type_class,
258 record_type_class, union_type_class,
259 array_type_class, string_type_class,
260 lang_type_class
261 };
262
263 // If no argument was supplied, default to "no_type_class". This isn't
264 // ideal, however it is what gcc does.
265 if (E->getNumArgs() == 0)
266 return no_type_class;
267
268 QualType ArgTy = E->getArg(0)->getType();
269 if (ArgTy->isVoidType())
270 return void_type_class;
271 else if (ArgTy->isEnumeralType())
272 return enumeral_type_class;
273 else if (ArgTy->isBooleanType())
274 return boolean_type_class;
275 else if (ArgTy->isCharType())
276 return string_type_class; // gcc doesn't appear to use char_type_class
277 else if (ArgTy->isIntegerType())
278 return integer_type_class;
279 else if (ArgTy->isPointerType())
280 return pointer_type_class;
281 else if (ArgTy->isReferenceType())
282 return reference_type_class;
283 else if (ArgTy->isRealType())
284 return real_type_class;
285 else if (ArgTy->isComplexType())
286 return complex_type_class;
287 else if (ArgTy->isFunctionType())
288 return function_type_class;
289 else if (ArgTy->isStructureType())
290 return record_type_class;
291 else if (ArgTy->isUnionType())
292 return union_type_class;
293 else if (ArgTy->isArrayType())
294 return array_type_class;
295 else if (ArgTy->isUnionType())
296 return union_type_class;
297 else // FIXME: offset_type_class, method_type_class, & lang_type_class?
298 assert(0 && "CallExpr::isBuiltinClassifyType(): unimplemented type");
299 return -1;
300}
301
Chris Lattner15e59112008-07-12 00:38:25 +0000302bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
303 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Chris Lattner15e59112008-07-12 00:38:25 +0000304
Chris Lattner87293782008-10-06 05:28:25 +0000305 switch (E->isBuiltinCall()) {
306 default:
307 return Error(E->getLocStart(), diag::err_expr_not_constant);
308 case Builtin::BI__builtin_classify_type:
Chris Lattner1eee9402008-10-06 06:40:35 +0000309 Result.setIsSigned(true);
310 Result = EvaluateBuiltinClassifyType(E);
Chris Lattner87293782008-10-06 05:28:25 +0000311 return true;
312
313 case Builtin::BI__builtin_constant_p: {
314 // __builtin_constant_p always has one operand: it returns true if that
315 // operand can be folded, false otherwise.
316 APValue Res;
317 Result = E->getArg(0)->tryEvaluate(Res, Info.Ctx);
318 return true;
319 }
320 }
Chris Lattner15e59112008-07-12 00:38:25 +0000321}
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000322
Chris Lattnera42f09a2008-07-11 19:10:17 +0000323bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
Anders Carlssond1aa5812008-07-08 14:35:21 +0000324 // The LHS of a constant expr is always evaluated and needed.
Anders Carlssond1aa5812008-07-08 14:35:21 +0000325 llvm::APSInt RHS(32);
Chris Lattner82437da2008-07-12 00:14:42 +0000326 if (!Visit(E->getLHS()))
327 return false; // error in subexpression.
328
329 bool OldEval = Info.isEvaluated;
330
331 // The short-circuiting &&/|| operators don't necessarily evaluate their
332 // RHS. Make sure to pass isEvaluated down correctly.
333 if ((E->getOpcode() == BinaryOperator::LAnd && Result == 0) ||
334 (E->getOpcode() == BinaryOperator::LOr && Result != 0))
335 Info.isEvaluated = false;
Eli Friedman3e64dd72008-07-27 05:46:18 +0000336
337 // FIXME: Handle pointer subtraction
338
339 // FIXME Maybe we want to succeed even where we can't evaluate the
340 // right side of LAnd/LOr?
341 // For example, see http://llvm.org/bugs/show_bug.cgi?id=2525
Chris Lattner82437da2008-07-12 00:14:42 +0000342 if (!EvaluateInteger(E->getRHS(), RHS, Info))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000343 return false;
Chris Lattner82437da2008-07-12 00:14:42 +0000344 Info.isEvaluated = OldEval;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000345
346 switch (E->getOpcode()) {
Chris Lattner82437da2008-07-12 00:14:42 +0000347 default: return Error(E->getOperatorLoc(), diag::err_expr_not_constant);
348 case BinaryOperator::Mul: Result *= RHS; return true;
349 case BinaryOperator::Add: Result += RHS; return true;
350 case BinaryOperator::Sub: Result -= RHS; return true;
351 case BinaryOperator::And: Result &= RHS; return true;
352 case BinaryOperator::Xor: Result ^= RHS; return true;
353 case BinaryOperator::Or: Result |= RHS; return true;
Chris Lattner400d7402008-07-11 22:15:16 +0000354 case BinaryOperator::Div:
Chris Lattner82437da2008-07-12 00:14:42 +0000355 if (RHS == 0)
356 return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero);
Chris Lattner400d7402008-07-11 22:15:16 +0000357 Result /= RHS;
Chris Lattner82437da2008-07-12 00:14:42 +0000358 return true;
Chris Lattner400d7402008-07-11 22:15:16 +0000359 case BinaryOperator::Rem:
Chris Lattner82437da2008-07-12 00:14:42 +0000360 if (RHS == 0)
361 return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero);
Chris Lattner400d7402008-07-11 22:15:16 +0000362 Result %= RHS;
Chris Lattner82437da2008-07-12 00:14:42 +0000363 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000364 case BinaryOperator::Shl:
Chris Lattner82437da2008-07-12 00:14:42 +0000365 // FIXME: Warn about out of range shift amounts!
Chris Lattnera42f09a2008-07-11 19:10:17 +0000366 Result <<= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000367 break;
368 case BinaryOperator::Shr:
Chris Lattnera42f09a2008-07-11 19:10:17 +0000369 Result >>= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000370 break;
Chris Lattnera42f09a2008-07-11 19:10:17 +0000371
Chris Lattner045502c2008-07-11 19:29:32 +0000372 case BinaryOperator::LT:
373 Result = Result < RHS;
374 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
375 break;
376 case BinaryOperator::GT:
377 Result = Result > RHS;
378 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
379 break;
380 case BinaryOperator::LE:
381 Result = Result <= RHS;
382 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
383 break;
384 case BinaryOperator::GE:
385 Result = Result >= RHS;
386 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
387 break;
388 case BinaryOperator::EQ:
389 Result = Result == RHS;
390 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
391 break;
392 case BinaryOperator::NE:
393 Result = Result != RHS;
394 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
395 break;
Chris Lattner82437da2008-07-12 00:14:42 +0000396 case BinaryOperator::LAnd:
397 Result = Result != 0 && RHS != 0;
398 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
399 break;
400 case BinaryOperator::LOr:
401 Result = Result != 0 || RHS != 0;
402 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
403 break;
404
Anders Carlssonc0328012008-07-08 05:49:43 +0000405
Anders Carlssond1aa5812008-07-08 14:35:21 +0000406 case BinaryOperator::Comma:
Chris Lattner82437da2008-07-12 00:14:42 +0000407 // Result of the comma is just the result of the RHS.
408 Result = RHS;
409
Anders Carlssond1aa5812008-07-08 14:35:21 +0000410 // C99 6.6p3: "shall not contain assignment, ..., or comma operators,
411 // *except* when they are contained within a subexpression that is not
412 // evaluated". Note that Assignment can never happen due to constraints
413 // on the LHS subexpr, so we don't need to check it here.
Chris Lattner82437da2008-07-12 00:14:42 +0000414 if (!Info.isEvaluated)
415 return true;
416
417 // If the value is evaluated, we can accept it as an extension.
418 return Extension(E->getOperatorLoc(), diag::ext_comma_in_constant_expr);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000419 }
420
421 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000422 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000423}
424
Sebastian Redl0cb7c872008-11-11 17:56:53 +0000425/// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the
426/// expression's type.
427bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
428 QualType DstTy = E->getType();
Chris Lattner265a0892008-07-11 21:24:13 +0000429 // Return the result in the right width.
430 Result.zextOrTrunc(getIntTypeSizeInBits(DstTy));
431 Result.setIsUnsigned(DstTy->isUnsignedIntegerType());
432
Sebastian Redl0cb7c872008-11-11 17:56:53 +0000433 QualType SrcTy = E->getTypeOfArgument();
434
Chris Lattner265a0892008-07-11 21:24:13 +0000435 // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
436 if (SrcTy->isVoidType())
437 Result = 1;
438
439 // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
440 if (!SrcTy->isConstantSizeType()) {
441 // FIXME: Should we attempt to evaluate this?
442 return false;
443 }
Sebastian Redl0cb7c872008-11-11 17:56:53 +0000444
445 bool isSizeOf = E->isSizeOf();
Chris Lattner265a0892008-07-11 21:24:13 +0000446
447 // GCC extension: sizeof(function) = 1.
448 if (SrcTy->isFunctionType()) {
449 // FIXME: AlignOf shouldn't be unconditionally 4!
450 Result = isSizeOf ? 1 : 4;
451 return true;
452 }
453
454 // Get information about the size or align.
Chris Lattner422373c2008-07-11 22:52:41 +0000455 unsigned CharSize = Info.Ctx.Target.getCharWidth();
Chris Lattner265a0892008-07-11 21:24:13 +0000456 if (isSizeOf)
457 Result = getIntTypeSizeInBits(SrcTy) / CharSize;
458 else
Chris Lattner422373c2008-07-11 22:52:41 +0000459 Result = Info.Ctx.getTypeAlign(SrcTy) / CharSize;
Chris Lattner265a0892008-07-11 21:24:13 +0000460 return true;
461}
462
Chris Lattnera42f09a2008-07-11 19:10:17 +0000463bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
Chris Lattner15e59112008-07-12 00:38:25 +0000464 // Special case unary operators that do not need their subexpression
465 // evaluated. offsetof/sizeof/alignof are all special.
Chris Lattner400d7402008-07-11 22:15:16 +0000466 if (E->isOffsetOfOp()) {
Chris Lattner15e59112008-07-12 00:38:25 +0000467 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Chris Lattner422373c2008-07-11 22:52:41 +0000468 Result = E->evaluateOffsetOf(Info.Ctx);
Chris Lattner400d7402008-07-11 22:15:16 +0000469 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
470 return true;
471 }
472
Chris Lattner422373c2008-07-11 22:52:41 +0000473 // Get the operand value into 'Result'.
474 if (!Visit(E->getSubExpr()))
Chris Lattner400d7402008-07-11 22:15:16 +0000475 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000476
Chris Lattner400d7402008-07-11 22:15:16 +0000477 switch (E->getOpcode()) {
Chris Lattner15e59112008-07-12 00:38:25 +0000478 default:
Chris Lattner400d7402008-07-11 22:15:16 +0000479 // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
480 // See C99 6.6p3.
Chris Lattner15e59112008-07-12 00:38:25 +0000481 return Error(E->getOperatorLoc(), diag::err_expr_not_constant);
Chris Lattner400d7402008-07-11 22:15:16 +0000482 case UnaryOperator::LNot: {
483 bool Val = Result == 0;
484 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
485 Result = Val;
486 break;
487 }
488 case UnaryOperator::Extension:
Chris Lattner15e59112008-07-12 00:38:25 +0000489 // FIXME: Should extension allow i-c-e extension expressions in its scope?
490 // If so, we could clear the diagnostic ID.
Chris Lattner400d7402008-07-11 22:15:16 +0000491 case UnaryOperator::Plus:
Chris Lattner15e59112008-07-12 00:38:25 +0000492 // The result is always just the subexpr.
Chris Lattner400d7402008-07-11 22:15:16 +0000493 break;
494 case UnaryOperator::Minus:
495 Result = -Result;
496 break;
497 case UnaryOperator::Not:
498 Result = ~Result;
499 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000500 }
501
502 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000503 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000504}
505
Chris Lattnerff579ff2008-07-12 01:15:53 +0000506/// HandleCast - This is used to evaluate implicit or explicit casts where the
507/// result type is integer.
508bool IntExprEvaluator::HandleCast(SourceLocation CastLoc,
509 Expr *SubExpr, QualType DestType) {
Chris Lattner2c99c712008-07-11 19:24:49 +0000510 unsigned DestWidth = getIntTypeSizeInBits(DestType);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000511
512 // Handle simple integer->integer casts.
513 if (SubExpr->getType()->isIntegerType()) {
Chris Lattnerff579ff2008-07-12 01:15:53 +0000514 if (!Visit(SubExpr))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000515 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000516
517 // Figure out if this is a truncate, extend or noop cast.
518 // If the input is signed, do a sign extend, noop, or truncate.
519 if (DestType->isBooleanType()) {
520 // Conversion to bool compares against zero.
521 Result = Result != 0;
522 Result.zextOrTrunc(DestWidth);
Chris Lattner2c99c712008-07-11 19:24:49 +0000523 } else
Anders Carlssond1aa5812008-07-08 14:35:21 +0000524 Result.extOrTrunc(DestWidth);
Chris Lattnerff579ff2008-07-12 01:15:53 +0000525 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
526 return true;
527 }
528
529 // FIXME: Clean this up!
530 if (SubExpr->getType()->isPointerType()) {
Anders Carlssond1aa5812008-07-08 14:35:21 +0000531 APValue LV;
Chris Lattner422373c2008-07-11 22:52:41 +0000532 if (!EvaluatePointer(SubExpr, LV, Info))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000533 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000534 if (LV.getLValueBase())
Chris Lattnera42f09a2008-07-11 19:10:17 +0000535 return false;
Anders Carlssonc0328012008-07-08 05:49:43 +0000536
Anders Carlsson8ab15c82008-07-08 16:49:00 +0000537 Result.extOrTrunc(DestWidth);
538 Result = LV.getLValueOffset();
Chris Lattnerff579ff2008-07-12 01:15:53 +0000539 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
540 return true;
Anders Carlsson02a34c32008-07-08 14:30:00 +0000541 }
542
Chris Lattnerff579ff2008-07-12 01:15:53 +0000543 if (!SubExpr->getType()->isRealFloatingType())
544 return Error(CastLoc, diag::err_expr_not_constant);
545
Eli Friedman2f445492008-08-22 00:06:13 +0000546 APFloat F(0.0);
547 if (!EvaluateFloat(SubExpr, F, Info))
Chris Lattnerff579ff2008-07-12 01:15:53 +0000548 return Error(CastLoc, diag::err_expr_not_constant);
Eli Friedman2f445492008-08-22 00:06:13 +0000549
Chris Lattnerff579ff2008-07-12 01:15:53 +0000550 // If the destination is boolean, compare against zero.
551 if (DestType->isBooleanType()) {
Eli Friedman2f445492008-08-22 00:06:13 +0000552 Result = !F.isZero();
Chris Lattnerff579ff2008-07-12 01:15:53 +0000553 Result.zextOrTrunc(DestWidth);
554 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
555 return true;
556 }
557
558 // Determine whether we are converting to unsigned or signed.
559 bool DestSigned = DestType->isSignedIntegerType();
560
561 // FIXME: Warning for overflow.
Dale Johannesen2461f612008-10-09 23:02:32 +0000562 uint64_t Space[4];
563 bool ignored;
Eli Friedman2f445492008-08-22 00:06:13 +0000564 (void)F.convertToInteger(Space, DestWidth, DestSigned,
Dale Johannesen2461f612008-10-09 23:02:32 +0000565 llvm::APFloat::rmTowardZero, &ignored);
Chris Lattnerff579ff2008-07-12 01:15:53 +0000566 Result = llvm::APInt(DestWidth, 4, Space);
567 Result.setIsUnsigned(!DestSigned);
Chris Lattnera42f09a2008-07-11 19:10:17 +0000568 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000569}
Anders Carlsson02a34c32008-07-08 14:30:00 +0000570
Chris Lattnera823ccf2008-07-11 18:11:29 +0000571//===----------------------------------------------------------------------===//
Eli Friedman2f445492008-08-22 00:06:13 +0000572// Float Evaluation
573//===----------------------------------------------------------------------===//
574
575namespace {
576class VISIBILITY_HIDDEN FloatExprEvaluator
577 : public StmtVisitor<FloatExprEvaluator, bool> {
578 EvalInfo &Info;
579 APFloat &Result;
580public:
581 FloatExprEvaluator(EvalInfo &info, APFloat &result)
582 : Info(info), Result(result) {}
583
584 bool VisitStmt(Stmt *S) {
585 return false;
586 }
587
588 bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
Chris Lattner87293782008-10-06 05:28:25 +0000589 bool VisitCallExpr(const CallExpr *E);
Eli Friedman2f445492008-08-22 00:06:13 +0000590
Daniel Dunbar804ead02008-10-16 03:51:50 +0000591 bool VisitUnaryOperator(const UnaryOperator *E);
Eli Friedman2f445492008-08-22 00:06:13 +0000592 bool VisitBinaryOperator(const BinaryOperator *E);
593 bool VisitFloatingLiteral(const FloatingLiteral *E);
594};
595} // end anonymous namespace
596
597static bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) {
598 return FloatExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
599}
600
Chris Lattner87293782008-10-06 05:28:25 +0000601bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
Chris Lattner87293782008-10-06 05:28:25 +0000602 switch (E->isBuiltinCall()) {
Chris Lattner27cde262008-10-06 05:53:16 +0000603 default: return false;
Chris Lattner87293782008-10-06 05:28:25 +0000604 case Builtin::BI__builtin_huge_val:
605 case Builtin::BI__builtin_huge_valf:
606 case Builtin::BI__builtin_huge_vall:
607 case Builtin::BI__builtin_inf:
608 case Builtin::BI__builtin_inff:
Daniel Dunbar0b3efb42008-10-14 05:41:12 +0000609 case Builtin::BI__builtin_infl: {
610 const llvm::fltSemantics &Sem =
611 Info.Ctx.getFloatTypeSemantics(E->getType());
Chris Lattner27cde262008-10-06 05:53:16 +0000612 Result = llvm::APFloat::getInf(Sem);
613 return true;
Daniel Dunbar0b3efb42008-10-14 05:41:12 +0000614 }
Chris Lattner667e1ee2008-10-06 06:31:58 +0000615
616 case Builtin::BI__builtin_nan:
617 case Builtin::BI__builtin_nanf:
618 case Builtin::BI__builtin_nanl:
619 // If this is __builtin_nan("") turn this into a simple nan, otherwise we
620 // can't constant fold it.
621 if (const StringLiteral *S =
622 dyn_cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts())) {
623 if (!S->isWide() && S->getByteLength() == 0) { // empty string.
Daniel Dunbar0b3efb42008-10-14 05:41:12 +0000624 const llvm::fltSemantics &Sem =
625 Info.Ctx.getFloatTypeSemantics(E->getType());
Chris Lattner667e1ee2008-10-06 06:31:58 +0000626 Result = llvm::APFloat::getNaN(Sem);
627 return true;
628 }
629 }
630 return false;
Daniel Dunbar804ead02008-10-16 03:51:50 +0000631
632 case Builtin::BI__builtin_fabs:
633 case Builtin::BI__builtin_fabsf:
634 case Builtin::BI__builtin_fabsl:
635 if (!EvaluateFloat(E->getArg(0), Result, Info))
636 return false;
637
638 if (Result.isNegative())
639 Result.changeSign();
640 return true;
641
642 case Builtin::BI__builtin_copysign:
643 case Builtin::BI__builtin_copysignf:
644 case Builtin::BI__builtin_copysignl: {
645 APFloat RHS(0.);
646 if (!EvaluateFloat(E->getArg(0), Result, Info) ||
647 !EvaluateFloat(E->getArg(1), RHS, Info))
648 return false;
649 Result.copySign(RHS);
650 return true;
651 }
Chris Lattner87293782008-10-06 05:28:25 +0000652 }
653}
654
Daniel Dunbar804ead02008-10-16 03:51:50 +0000655bool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
656 if (!EvaluateFloat(E->getSubExpr(), Result, Info))
657 return false;
658
659 switch (E->getOpcode()) {
660 default: return false;
661 case UnaryOperator::Plus:
662 return true;
663 case UnaryOperator::Minus:
664 Result.changeSign();
665 return true;
666 }
667}
Chris Lattner87293782008-10-06 05:28:25 +0000668
Eli Friedman2f445492008-08-22 00:06:13 +0000669bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
670 // FIXME: Diagnostics? I really don't understand how the warnings
671 // and errors are supposed to work.
Daniel Dunbar804ead02008-10-16 03:51:50 +0000672 APFloat RHS(0.0);
Eli Friedman2f445492008-08-22 00:06:13 +0000673 if (!EvaluateFloat(E->getLHS(), Result, Info))
674 return false;
675 if (!EvaluateFloat(E->getRHS(), RHS, Info))
676 return false;
677
678 switch (E->getOpcode()) {
679 default: return false;
680 case BinaryOperator::Mul:
681 Result.multiply(RHS, APFloat::rmNearestTiesToEven);
682 return true;
683 case BinaryOperator::Add:
684 Result.add(RHS, APFloat::rmNearestTiesToEven);
685 return true;
686 case BinaryOperator::Sub:
687 Result.subtract(RHS, APFloat::rmNearestTiesToEven);
688 return true;
689 case BinaryOperator::Div:
690 Result.divide(RHS, APFloat::rmNearestTiesToEven);
691 return true;
692 case BinaryOperator::Rem:
693 Result.mod(RHS, APFloat::rmNearestTiesToEven);
694 return true;
695 }
696}
697
698bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) {
699 Result = E->getValue();
700 return true;
701}
702
703//===----------------------------------------------------------------------===//
Chris Lattnera823ccf2008-07-11 18:11:29 +0000704// Top level TryEvaluate.
705//===----------------------------------------------------------------------===//
706
Chris Lattner87293782008-10-06 05:28:25 +0000707/// tryEvaluate - Return true if this is a constant which we can fold using
708/// any crazy technique (that has nothing to do with language standards) that
709/// we want to. If this function returns true, it returns the folded constant
710/// in Result.
Chris Lattnera42f09a2008-07-11 19:10:17 +0000711bool Expr::tryEvaluate(APValue &Result, ASTContext &Ctx) const {
Chris Lattner422373c2008-07-11 22:52:41 +0000712 EvalInfo Info(Ctx);
Anders Carlssonc0328012008-07-08 05:49:43 +0000713 if (getType()->isIntegerType()) {
Eli Friedman2f445492008-08-22 00:06:13 +0000714 llvm::APSInt sInt(32);
Chris Lattner422373c2008-07-11 22:52:41 +0000715 if (EvaluateInteger(this, sInt, Info)) {
Anders Carlssonc0328012008-07-08 05:49:43 +0000716 Result = APValue(sInt);
717 return true;
718 }
Eli Friedman2f445492008-08-22 00:06:13 +0000719 } else if (getType()->isPointerType()) {
720 if (EvaluatePointer(this, Result, Info)) {
721 return true;
722 }
723 } else if (getType()->isRealFloatingType()) {
724 llvm::APFloat f(0.0);
725 if (EvaluateFloat(this, f, Info)) {
726 Result = APValue(f);
727 return true;
728 }
729 }
Anders Carlsson47968a92008-08-10 17:03:01 +0000730
Anders Carlssonc7436af2008-07-03 04:20:39 +0000731 return false;
732}
Chris Lattner2d9a3f62008-10-06 06:49:02 +0000733
734/// isEvaluatable - Call tryEvaluate to see if this expression can be constant
735/// folded, but discard the result.
736bool Expr::isEvaluatable(ASTContext &Ctx) const {
737 APValue V;
738 return tryEvaluate(V, Ctx);
739}