blob: e2be9f16e5e7ac1a386f7c593012631e389229ef [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 Lattner40d2ae82008-11-12 07:04:29 +0000326 if (!Visit(E->getLHS())) {
327 // If the LHS is unfoldable, we generally can't fold this. However, if this
328 // is a logical operator like &&/||, and if we know that the RHS determines
329 // the outcome of the result (e.g. X && 0), return the outcome.
330 if (!E->isLogicalOp())
331 return false;
332
333 // If this is a logical op, see if the RHS determines the outcome.
334 EvalInfo Info2(Info.Ctx);
335 if (!EvaluateInteger(E->getRHS(), RHS, Info2))
336 return false;
337
338 // X && 0 -> 0, X || 1 -> 1.
339 if (E->getOpcode() == BinaryOperator::LAnd && RHS == 0 ||
340 E->getOpcode() == BinaryOperator::LOr && RHS != 0) {
341 Result = RHS != 0;
342 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
343 return true;
344 }
345
Chris Lattner82437da2008-07-12 00:14:42 +0000346 return false; // error in subexpression.
Chris Lattner40d2ae82008-11-12 07:04:29 +0000347 }
Chris Lattner82437da2008-07-12 00:14:42 +0000348
349 bool OldEval = Info.isEvaluated;
350
351 // The short-circuiting &&/|| operators don't necessarily evaluate their
352 // RHS. Make sure to pass isEvaluated down correctly.
353 if ((E->getOpcode() == BinaryOperator::LAnd && Result == 0) ||
354 (E->getOpcode() == BinaryOperator::LOr && Result != 0))
355 Info.isEvaluated = false;
Eli Friedman3e64dd72008-07-27 05:46:18 +0000356
357 // FIXME: Handle pointer subtraction
358
359 // FIXME Maybe we want to succeed even where we can't evaluate the
360 // right side of LAnd/LOr?
361 // For example, see http://llvm.org/bugs/show_bug.cgi?id=2525
Chris Lattner82437da2008-07-12 00:14:42 +0000362 if (!EvaluateInteger(E->getRHS(), RHS, Info))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000363 return false;
Chris Lattner82437da2008-07-12 00:14:42 +0000364 Info.isEvaluated = OldEval;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000365
366 switch (E->getOpcode()) {
Chris Lattner82437da2008-07-12 00:14:42 +0000367 default: return Error(E->getOperatorLoc(), diag::err_expr_not_constant);
368 case BinaryOperator::Mul: Result *= RHS; return true;
369 case BinaryOperator::Add: Result += RHS; return true;
370 case BinaryOperator::Sub: Result -= RHS; return true;
371 case BinaryOperator::And: Result &= RHS; return true;
372 case BinaryOperator::Xor: Result ^= RHS; return true;
373 case BinaryOperator::Or: Result |= RHS; return true;
Chris Lattner400d7402008-07-11 22:15:16 +0000374 case BinaryOperator::Div:
Chris Lattner82437da2008-07-12 00:14:42 +0000375 if (RHS == 0)
376 return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero);
Chris Lattner400d7402008-07-11 22:15:16 +0000377 Result /= RHS;
Chris Lattner82437da2008-07-12 00:14:42 +0000378 return true;
Chris Lattner400d7402008-07-11 22:15:16 +0000379 case BinaryOperator::Rem:
Chris Lattner82437da2008-07-12 00:14:42 +0000380 if (RHS == 0)
381 return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero);
Chris Lattner400d7402008-07-11 22:15:16 +0000382 Result %= RHS;
Chris Lattner82437da2008-07-12 00:14:42 +0000383 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000384 case BinaryOperator::Shl:
Chris Lattner82437da2008-07-12 00:14:42 +0000385 // FIXME: Warn about out of range shift amounts!
Chris Lattnera42f09a2008-07-11 19:10:17 +0000386 Result <<= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000387 break;
388 case BinaryOperator::Shr:
Chris Lattnera42f09a2008-07-11 19:10:17 +0000389 Result >>= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000390 break;
Chris Lattnera42f09a2008-07-11 19:10:17 +0000391
Chris Lattner045502c2008-07-11 19:29:32 +0000392 case BinaryOperator::LT:
393 Result = Result < RHS;
394 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
395 break;
396 case BinaryOperator::GT:
397 Result = Result > RHS;
398 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
399 break;
400 case BinaryOperator::LE:
401 Result = Result <= RHS;
402 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
403 break;
404 case BinaryOperator::GE:
405 Result = Result >= RHS;
406 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
407 break;
408 case BinaryOperator::EQ:
409 Result = Result == RHS;
410 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
411 break;
412 case BinaryOperator::NE:
413 Result = Result != RHS;
414 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
415 break;
Chris Lattner82437da2008-07-12 00:14:42 +0000416 case BinaryOperator::LAnd:
417 Result = Result != 0 && RHS != 0;
418 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
419 break;
420 case BinaryOperator::LOr:
421 Result = Result != 0 || RHS != 0;
422 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
423 break;
424
Anders Carlssonc0328012008-07-08 05:49:43 +0000425
Anders Carlssond1aa5812008-07-08 14:35:21 +0000426 case BinaryOperator::Comma:
Chris Lattner82437da2008-07-12 00:14:42 +0000427 // Result of the comma is just the result of the RHS.
428 Result = RHS;
429
Anders Carlssond1aa5812008-07-08 14:35:21 +0000430 // C99 6.6p3: "shall not contain assignment, ..., or comma operators,
431 // *except* when they are contained within a subexpression that is not
432 // evaluated". Note that Assignment can never happen due to constraints
433 // on the LHS subexpr, so we don't need to check it here.
Chris Lattner82437da2008-07-12 00:14:42 +0000434 if (!Info.isEvaluated)
435 return true;
436
437 // If the value is evaluated, we can accept it as an extension.
438 return Extension(E->getOperatorLoc(), diag::ext_comma_in_constant_expr);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000439 }
440
441 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000442 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000443}
444
Sebastian Redl0cb7c872008-11-11 17:56:53 +0000445/// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the
446/// expression's type.
447bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
448 QualType DstTy = E->getType();
Chris Lattner265a0892008-07-11 21:24:13 +0000449 // Return the result in the right width.
450 Result.zextOrTrunc(getIntTypeSizeInBits(DstTy));
451 Result.setIsUnsigned(DstTy->isUnsignedIntegerType());
452
Sebastian Redl0cb7c872008-11-11 17:56:53 +0000453 QualType SrcTy = E->getTypeOfArgument();
454
Chris Lattner265a0892008-07-11 21:24:13 +0000455 // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
456 if (SrcTy->isVoidType())
457 Result = 1;
458
459 // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
460 if (!SrcTy->isConstantSizeType()) {
461 // FIXME: Should we attempt to evaluate this?
462 return false;
463 }
Sebastian Redl0cb7c872008-11-11 17:56:53 +0000464
465 bool isSizeOf = E->isSizeOf();
Chris Lattner265a0892008-07-11 21:24:13 +0000466
467 // GCC extension: sizeof(function) = 1.
468 if (SrcTy->isFunctionType()) {
469 // FIXME: AlignOf shouldn't be unconditionally 4!
470 Result = isSizeOf ? 1 : 4;
471 return true;
472 }
473
474 // Get information about the size or align.
Chris Lattner422373c2008-07-11 22:52:41 +0000475 unsigned CharSize = Info.Ctx.Target.getCharWidth();
Chris Lattner265a0892008-07-11 21:24:13 +0000476 if (isSizeOf)
477 Result = getIntTypeSizeInBits(SrcTy) / CharSize;
478 else
Chris Lattner422373c2008-07-11 22:52:41 +0000479 Result = Info.Ctx.getTypeAlign(SrcTy) / CharSize;
Chris Lattner265a0892008-07-11 21:24:13 +0000480 return true;
481}
482
Chris Lattnera42f09a2008-07-11 19:10:17 +0000483bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
Chris Lattner15e59112008-07-12 00:38:25 +0000484 // Special case unary operators that do not need their subexpression
485 // evaluated. offsetof/sizeof/alignof are all special.
Chris Lattner400d7402008-07-11 22:15:16 +0000486 if (E->isOffsetOfOp()) {
Chris Lattner15e59112008-07-12 00:38:25 +0000487 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Chris Lattner422373c2008-07-11 22:52:41 +0000488 Result = E->evaluateOffsetOf(Info.Ctx);
Chris Lattner400d7402008-07-11 22:15:16 +0000489 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
490 return true;
491 }
492
Chris Lattner422373c2008-07-11 22:52:41 +0000493 // Get the operand value into 'Result'.
494 if (!Visit(E->getSubExpr()))
Chris Lattner400d7402008-07-11 22:15:16 +0000495 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000496
Chris Lattner400d7402008-07-11 22:15:16 +0000497 switch (E->getOpcode()) {
Chris Lattner15e59112008-07-12 00:38:25 +0000498 default:
Chris Lattner400d7402008-07-11 22:15:16 +0000499 // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
500 // See C99 6.6p3.
Chris Lattner15e59112008-07-12 00:38:25 +0000501 return Error(E->getOperatorLoc(), diag::err_expr_not_constant);
Chris Lattner400d7402008-07-11 22:15:16 +0000502 case UnaryOperator::LNot: {
503 bool Val = Result == 0;
504 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
505 Result = Val;
506 break;
507 }
508 case UnaryOperator::Extension:
Chris Lattner15e59112008-07-12 00:38:25 +0000509 // FIXME: Should extension allow i-c-e extension expressions in its scope?
510 // If so, we could clear the diagnostic ID.
Chris Lattner400d7402008-07-11 22:15:16 +0000511 case UnaryOperator::Plus:
Chris Lattner15e59112008-07-12 00:38:25 +0000512 // The result is always just the subexpr.
Chris Lattner400d7402008-07-11 22:15:16 +0000513 break;
514 case UnaryOperator::Minus:
515 Result = -Result;
516 break;
517 case UnaryOperator::Not:
518 Result = ~Result;
519 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000520 }
521
522 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000523 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000524}
525
Chris Lattnerff579ff2008-07-12 01:15:53 +0000526/// HandleCast - This is used to evaluate implicit or explicit casts where the
527/// result type is integer.
528bool IntExprEvaluator::HandleCast(SourceLocation CastLoc,
529 Expr *SubExpr, QualType DestType) {
Chris Lattner2c99c712008-07-11 19:24:49 +0000530 unsigned DestWidth = getIntTypeSizeInBits(DestType);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000531
532 // Handle simple integer->integer casts.
533 if (SubExpr->getType()->isIntegerType()) {
Chris Lattnerff579ff2008-07-12 01:15:53 +0000534 if (!Visit(SubExpr))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000535 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000536
537 // Figure out if this is a truncate, extend or noop cast.
538 // If the input is signed, do a sign extend, noop, or truncate.
539 if (DestType->isBooleanType()) {
540 // Conversion to bool compares against zero.
541 Result = Result != 0;
542 Result.zextOrTrunc(DestWidth);
Chris Lattner2c99c712008-07-11 19:24:49 +0000543 } else
Anders Carlssond1aa5812008-07-08 14:35:21 +0000544 Result.extOrTrunc(DestWidth);
Chris Lattnerff579ff2008-07-12 01:15:53 +0000545 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
546 return true;
547 }
548
549 // FIXME: Clean this up!
550 if (SubExpr->getType()->isPointerType()) {
Anders Carlssond1aa5812008-07-08 14:35:21 +0000551 APValue LV;
Chris Lattner422373c2008-07-11 22:52:41 +0000552 if (!EvaluatePointer(SubExpr, LV, Info))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000553 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000554 if (LV.getLValueBase())
Chris Lattnera42f09a2008-07-11 19:10:17 +0000555 return false;
Anders Carlssonc0328012008-07-08 05:49:43 +0000556
Anders Carlsson8ab15c82008-07-08 16:49:00 +0000557 Result.extOrTrunc(DestWidth);
558 Result = LV.getLValueOffset();
Chris Lattnerff579ff2008-07-12 01:15:53 +0000559 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
560 return true;
Anders Carlsson02a34c32008-07-08 14:30:00 +0000561 }
562
Chris Lattnerff579ff2008-07-12 01:15:53 +0000563 if (!SubExpr->getType()->isRealFloatingType())
564 return Error(CastLoc, diag::err_expr_not_constant);
565
Eli Friedman2f445492008-08-22 00:06:13 +0000566 APFloat F(0.0);
567 if (!EvaluateFloat(SubExpr, F, Info))
Chris Lattnerff579ff2008-07-12 01:15:53 +0000568 return Error(CastLoc, diag::err_expr_not_constant);
Eli Friedman2f445492008-08-22 00:06:13 +0000569
Chris Lattnerff579ff2008-07-12 01:15:53 +0000570 // If the destination is boolean, compare against zero.
571 if (DestType->isBooleanType()) {
Eli Friedman2f445492008-08-22 00:06:13 +0000572 Result = !F.isZero();
Chris Lattnerff579ff2008-07-12 01:15:53 +0000573 Result.zextOrTrunc(DestWidth);
574 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
575 return true;
576 }
577
578 // Determine whether we are converting to unsigned or signed.
579 bool DestSigned = DestType->isSignedIntegerType();
580
581 // FIXME: Warning for overflow.
Dale Johannesen2461f612008-10-09 23:02:32 +0000582 uint64_t Space[4];
583 bool ignored;
Eli Friedman2f445492008-08-22 00:06:13 +0000584 (void)F.convertToInteger(Space, DestWidth, DestSigned,
Dale Johannesen2461f612008-10-09 23:02:32 +0000585 llvm::APFloat::rmTowardZero, &ignored);
Chris Lattnerff579ff2008-07-12 01:15:53 +0000586 Result = llvm::APInt(DestWidth, 4, Space);
587 Result.setIsUnsigned(!DestSigned);
Chris Lattnera42f09a2008-07-11 19:10:17 +0000588 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000589}
Anders Carlsson02a34c32008-07-08 14:30:00 +0000590
Chris Lattnera823ccf2008-07-11 18:11:29 +0000591//===----------------------------------------------------------------------===//
Eli Friedman2f445492008-08-22 00:06:13 +0000592// Float Evaluation
593//===----------------------------------------------------------------------===//
594
595namespace {
596class VISIBILITY_HIDDEN FloatExprEvaluator
597 : public StmtVisitor<FloatExprEvaluator, bool> {
598 EvalInfo &Info;
599 APFloat &Result;
600public:
601 FloatExprEvaluator(EvalInfo &info, APFloat &result)
602 : Info(info), Result(result) {}
603
604 bool VisitStmt(Stmt *S) {
605 return false;
606 }
607
608 bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
Chris Lattner87293782008-10-06 05:28:25 +0000609 bool VisitCallExpr(const CallExpr *E);
Eli Friedman2f445492008-08-22 00:06:13 +0000610
Daniel Dunbar804ead02008-10-16 03:51:50 +0000611 bool VisitUnaryOperator(const UnaryOperator *E);
Eli Friedman2f445492008-08-22 00:06:13 +0000612 bool VisitBinaryOperator(const BinaryOperator *E);
613 bool VisitFloatingLiteral(const FloatingLiteral *E);
614};
615} // end anonymous namespace
616
617static bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) {
618 return FloatExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
619}
620
Chris Lattner87293782008-10-06 05:28:25 +0000621bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
Chris Lattner87293782008-10-06 05:28:25 +0000622 switch (E->isBuiltinCall()) {
Chris Lattner27cde262008-10-06 05:53:16 +0000623 default: return false;
Chris Lattner87293782008-10-06 05:28:25 +0000624 case Builtin::BI__builtin_huge_val:
625 case Builtin::BI__builtin_huge_valf:
626 case Builtin::BI__builtin_huge_vall:
627 case Builtin::BI__builtin_inf:
628 case Builtin::BI__builtin_inff:
Daniel Dunbar0b3efb42008-10-14 05:41:12 +0000629 case Builtin::BI__builtin_infl: {
630 const llvm::fltSemantics &Sem =
631 Info.Ctx.getFloatTypeSemantics(E->getType());
Chris Lattner27cde262008-10-06 05:53:16 +0000632 Result = llvm::APFloat::getInf(Sem);
633 return true;
Daniel Dunbar0b3efb42008-10-14 05:41:12 +0000634 }
Chris Lattner667e1ee2008-10-06 06:31:58 +0000635
636 case Builtin::BI__builtin_nan:
637 case Builtin::BI__builtin_nanf:
638 case Builtin::BI__builtin_nanl:
639 // If this is __builtin_nan("") turn this into a simple nan, otherwise we
640 // can't constant fold it.
641 if (const StringLiteral *S =
642 dyn_cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts())) {
643 if (!S->isWide() && S->getByteLength() == 0) { // empty string.
Daniel Dunbar0b3efb42008-10-14 05:41:12 +0000644 const llvm::fltSemantics &Sem =
645 Info.Ctx.getFloatTypeSemantics(E->getType());
Chris Lattner667e1ee2008-10-06 06:31:58 +0000646 Result = llvm::APFloat::getNaN(Sem);
647 return true;
648 }
649 }
650 return false;
Daniel Dunbar804ead02008-10-16 03:51:50 +0000651
652 case Builtin::BI__builtin_fabs:
653 case Builtin::BI__builtin_fabsf:
654 case Builtin::BI__builtin_fabsl:
655 if (!EvaluateFloat(E->getArg(0), Result, Info))
656 return false;
657
658 if (Result.isNegative())
659 Result.changeSign();
660 return true;
661
662 case Builtin::BI__builtin_copysign:
663 case Builtin::BI__builtin_copysignf:
664 case Builtin::BI__builtin_copysignl: {
665 APFloat RHS(0.);
666 if (!EvaluateFloat(E->getArg(0), Result, Info) ||
667 !EvaluateFloat(E->getArg(1), RHS, Info))
668 return false;
669 Result.copySign(RHS);
670 return true;
671 }
Chris Lattner87293782008-10-06 05:28:25 +0000672 }
673}
674
Daniel Dunbar804ead02008-10-16 03:51:50 +0000675bool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
676 if (!EvaluateFloat(E->getSubExpr(), Result, Info))
677 return false;
678
679 switch (E->getOpcode()) {
680 default: return false;
681 case UnaryOperator::Plus:
682 return true;
683 case UnaryOperator::Minus:
684 Result.changeSign();
685 return true;
686 }
687}
Chris Lattner87293782008-10-06 05:28:25 +0000688
Eli Friedman2f445492008-08-22 00:06:13 +0000689bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
690 // FIXME: Diagnostics? I really don't understand how the warnings
691 // and errors are supposed to work.
Daniel Dunbar804ead02008-10-16 03:51:50 +0000692 APFloat RHS(0.0);
Eli Friedman2f445492008-08-22 00:06:13 +0000693 if (!EvaluateFloat(E->getLHS(), Result, Info))
694 return false;
695 if (!EvaluateFloat(E->getRHS(), RHS, Info))
696 return false;
697
698 switch (E->getOpcode()) {
699 default: return false;
700 case BinaryOperator::Mul:
701 Result.multiply(RHS, APFloat::rmNearestTiesToEven);
702 return true;
703 case BinaryOperator::Add:
704 Result.add(RHS, APFloat::rmNearestTiesToEven);
705 return true;
706 case BinaryOperator::Sub:
707 Result.subtract(RHS, APFloat::rmNearestTiesToEven);
708 return true;
709 case BinaryOperator::Div:
710 Result.divide(RHS, APFloat::rmNearestTiesToEven);
711 return true;
712 case BinaryOperator::Rem:
713 Result.mod(RHS, APFloat::rmNearestTiesToEven);
714 return true;
715 }
716}
717
718bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) {
719 Result = E->getValue();
720 return true;
721}
722
723//===----------------------------------------------------------------------===//
Chris Lattnera823ccf2008-07-11 18:11:29 +0000724// Top level TryEvaluate.
725//===----------------------------------------------------------------------===//
726
Chris Lattner87293782008-10-06 05:28:25 +0000727/// tryEvaluate - Return true if this is a constant which we can fold using
728/// any crazy technique (that has nothing to do with language standards) that
729/// we want to. If this function returns true, it returns the folded constant
730/// in Result.
Chris Lattnera42f09a2008-07-11 19:10:17 +0000731bool Expr::tryEvaluate(APValue &Result, ASTContext &Ctx) const {
Chris Lattner422373c2008-07-11 22:52:41 +0000732 EvalInfo Info(Ctx);
Anders Carlssonc0328012008-07-08 05:49:43 +0000733 if (getType()->isIntegerType()) {
Eli Friedman2f445492008-08-22 00:06:13 +0000734 llvm::APSInt sInt(32);
Chris Lattner422373c2008-07-11 22:52:41 +0000735 if (EvaluateInteger(this, sInt, Info)) {
Anders Carlssonc0328012008-07-08 05:49:43 +0000736 Result = APValue(sInt);
737 return true;
738 }
Eli Friedman2f445492008-08-22 00:06:13 +0000739 } else if (getType()->isPointerType()) {
740 if (EvaluatePointer(this, Result, Info)) {
741 return true;
742 }
743 } else if (getType()->isRealFloatingType()) {
744 llvm::APFloat f(0.0);
745 if (EvaluateFloat(this, f, Info)) {
746 Result = APValue(f);
747 return true;
748 }
749 }
Anders Carlsson47968a92008-08-10 17:03:01 +0000750
Anders Carlssonc7436af2008-07-03 04:20:39 +0000751 return false;
752}
Chris Lattner2d9a3f62008-10-06 06:49:02 +0000753
754/// isEvaluatable - Call tryEvaluate to see if this expression can be constant
755/// folded, but discard the result.
756bool Expr::isEvaluatable(ASTContext &Ctx) const {
757 APValue V;
758 return tryEvaluate(V, Ctx);
759}