blob: 887a3aac5ded0e74710d7f86723e2a1473a24da1 [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
Chris Lattner438f3b12008-11-12 07:43:42 +0000174 bool Error(SourceLocation L, diag::kind D, QualType ExprTy) {
Chris Lattner82437da2008-07-12 00:14:42 +0000175 // If this is in an unevaluated portion of the subexpression, ignore the
176 // error.
Chris Lattner438f3b12008-11-12 07:43:42 +0000177 if (!Info.isEvaluated) {
178 // If error is ignored because the value isn't evaluated, get the real
179 // type at least to prevent errors downstream.
180 Result.zextOrTrunc(getIntTypeSizeInBits(ExprTy));
181 Result.setIsUnsigned(ExprTy->isUnsignedIntegerType());
Chris Lattner82437da2008-07-12 00:14:42 +0000182 return true;
Chris Lattner438f3b12008-11-12 07:43:42 +0000183 }
Chris Lattner82437da2008-07-12 00:14:42 +0000184
Chris Lattner438f3b12008-11-12 07:43:42 +0000185 // Take the first error.
186 if (Info.ICEDiag == 0) {
187 Info.DiagLoc = L;
188 Info.ICEDiag = D;
189 }
Chris Lattner82437da2008-07-12 00:14:42 +0000190 return false;
Chris Lattner2c99c712008-07-11 19:24:49 +0000191 }
192
Anders Carlssoncad17b52008-07-08 05:13:58 +0000193 //===--------------------------------------------------------------------===//
194 // Visitor Methods
195 //===--------------------------------------------------------------------===//
Chris Lattner438f3b12008-11-12 07:43:42 +0000196
197 bool VisitStmt(Stmt *) {
198 assert(0 && "This should be called on integers, stmts are not integers");
199 return false;
200 }
Chris Lattner2c99c712008-07-11 19:24:49 +0000201
Chris Lattner438f3b12008-11-12 07:43:42 +0000202 bool VisitExpr(Expr *E) {
203 return Error(E->getLocStart(), diag::err_expr_not_constant, E->getType());
Anders Carlssoncad17b52008-07-08 05:13:58 +0000204 }
205
Chris Lattnera42f09a2008-07-11 19:10:17 +0000206 bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
Anders Carlssoncad17b52008-07-08 05:13:58 +0000207
Chris Lattner15e59112008-07-12 00:38:25 +0000208 bool VisitIntegerLiteral(const IntegerLiteral *E) {
209 Result = E->getValue();
210 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
211 return true;
212 }
213 bool VisitCharacterLiteral(const CharacterLiteral *E) {
214 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
215 Result = E->getValue();
216 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
217 return true;
218 }
219 bool VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
220 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Daniel Dunbarda8ebd22008-10-24 08:07:57 +0000221 // Per gcc docs "this built-in function ignores top level
222 // qualifiers". We need to use the canonical version to properly
223 // be able to strip CRV qualifiers from the type.
224 QualType T0 = Info.Ctx.getCanonicalType(E->getArgType1());
225 QualType T1 = Info.Ctx.getCanonicalType(E->getArgType2());
226 Result = Info.Ctx.typesAreCompatible(T0.getUnqualifiedType(),
227 T1.getUnqualifiedType());
Chris Lattner15e59112008-07-12 00:38:25 +0000228 return true;
229 }
230 bool VisitDeclRefExpr(const DeclRefExpr *E);
231 bool VisitCallExpr(const CallExpr *E);
Chris Lattnera42f09a2008-07-11 19:10:17 +0000232 bool VisitBinaryOperator(const BinaryOperator *E);
233 bool VisitUnaryOperator(const UnaryOperator *E);
Anders Carlssonc0328012008-07-08 05:49:43 +0000234
Chris Lattnerff579ff2008-07-12 01:15:53 +0000235 bool VisitCastExpr(CastExpr* E) {
Chris Lattnerff579ff2008-07-12 01:15:53 +0000236 return HandleCast(E->getLocStart(), E->getSubExpr(), E->getType());
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000237 }
Sebastian Redl0cb7c872008-11-11 17:56:53 +0000238 bool VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
239
Chris Lattner265a0892008-07-11 21:24:13 +0000240private:
Chris Lattnerff579ff2008-07-12 01:15:53 +0000241 bool HandleCast(SourceLocation CastLoc, Expr *SubExpr, QualType DestType);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000242};
Chris Lattnera823ccf2008-07-11 18:11:29 +0000243} // end anonymous namespace
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000244
Chris Lattner422373c2008-07-11 22:52:41 +0000245static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {
246 return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000247}
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000248
Chris Lattner15e59112008-07-12 00:38:25 +0000249bool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
250 // Enums are integer constant exprs.
251 if (const EnumConstantDecl *D = dyn_cast<EnumConstantDecl>(E->getDecl())) {
252 Result = D->getInitVal();
253 return true;
254 }
255
256 // Otherwise, random variable references are not constants.
Chris Lattner438f3b12008-11-12 07:43:42 +0000257 return Error(E->getLocStart(), diag::err_expr_not_constant, E->getType());
Chris Lattner15e59112008-07-12 00:38:25 +0000258}
259
Chris Lattner1eee9402008-10-06 06:40:35 +0000260/// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way
261/// as GCC.
262static int EvaluateBuiltinClassifyType(const CallExpr *E) {
263 // The following enum mimics the values returned by GCC.
264 enum gcc_type_class {
265 no_type_class = -1,
266 void_type_class, integer_type_class, char_type_class,
267 enumeral_type_class, boolean_type_class,
268 pointer_type_class, reference_type_class, offset_type_class,
269 real_type_class, complex_type_class,
270 function_type_class, method_type_class,
271 record_type_class, union_type_class,
272 array_type_class, string_type_class,
273 lang_type_class
274 };
275
276 // If no argument was supplied, default to "no_type_class". This isn't
277 // ideal, however it is what gcc does.
278 if (E->getNumArgs() == 0)
279 return no_type_class;
280
281 QualType ArgTy = E->getArg(0)->getType();
282 if (ArgTy->isVoidType())
283 return void_type_class;
284 else if (ArgTy->isEnumeralType())
285 return enumeral_type_class;
286 else if (ArgTy->isBooleanType())
287 return boolean_type_class;
288 else if (ArgTy->isCharType())
289 return string_type_class; // gcc doesn't appear to use char_type_class
290 else if (ArgTy->isIntegerType())
291 return integer_type_class;
292 else if (ArgTy->isPointerType())
293 return pointer_type_class;
294 else if (ArgTy->isReferenceType())
295 return reference_type_class;
296 else if (ArgTy->isRealType())
297 return real_type_class;
298 else if (ArgTy->isComplexType())
299 return complex_type_class;
300 else if (ArgTy->isFunctionType())
301 return function_type_class;
302 else if (ArgTy->isStructureType())
303 return record_type_class;
304 else if (ArgTy->isUnionType())
305 return union_type_class;
306 else if (ArgTy->isArrayType())
307 return array_type_class;
308 else if (ArgTy->isUnionType())
309 return union_type_class;
310 else // FIXME: offset_type_class, method_type_class, & lang_type_class?
311 assert(0 && "CallExpr::isBuiltinClassifyType(): unimplemented type");
312 return -1;
313}
314
Chris Lattner15e59112008-07-12 00:38:25 +0000315bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
316 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Chris Lattner15e59112008-07-12 00:38:25 +0000317
Chris Lattner87293782008-10-06 05:28:25 +0000318 switch (E->isBuiltinCall()) {
319 default:
Chris Lattner438f3b12008-11-12 07:43:42 +0000320 return Error(E->getLocStart(), diag::err_expr_not_constant, E->getType());
Chris Lattner87293782008-10-06 05:28:25 +0000321 case Builtin::BI__builtin_classify_type:
Chris Lattner1eee9402008-10-06 06:40:35 +0000322 Result.setIsSigned(true);
323 Result = EvaluateBuiltinClassifyType(E);
Chris Lattner87293782008-10-06 05:28:25 +0000324 return true;
325
326 case Builtin::BI__builtin_constant_p: {
327 // __builtin_constant_p always has one operand: it returns true if that
328 // operand can be folded, false otherwise.
329 APValue Res;
330 Result = E->getArg(0)->tryEvaluate(Res, Info.Ctx);
331 return true;
332 }
333 }
Chris Lattner15e59112008-07-12 00:38:25 +0000334}
Anders Carlssonc43f44b2008-07-08 15:34:11 +0000335
Chris Lattnera42f09a2008-07-11 19:10:17 +0000336bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
Anders Carlssond1aa5812008-07-08 14:35:21 +0000337 // The LHS of a constant expr is always evaluated and needed.
Anders Carlssond1aa5812008-07-08 14:35:21 +0000338 llvm::APSInt RHS(32);
Chris Lattner40d2ae82008-11-12 07:04:29 +0000339 if (!Visit(E->getLHS())) {
340 // If the LHS is unfoldable, we generally can't fold this. However, if this
341 // is a logical operator like &&/||, and if we know that the RHS determines
342 // the outcome of the result (e.g. X && 0), return the outcome.
343 if (!E->isLogicalOp())
344 return false;
345
346 // If this is a logical op, see if the RHS determines the outcome.
347 EvalInfo Info2(Info.Ctx);
348 if (!EvaluateInteger(E->getRHS(), RHS, Info2))
349 return false;
350
351 // X && 0 -> 0, X || 1 -> 1.
352 if (E->getOpcode() == BinaryOperator::LAnd && RHS == 0 ||
353 E->getOpcode() == BinaryOperator::LOr && RHS != 0) {
354 Result = RHS != 0;
355 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Chris Lattner438f3b12008-11-12 07:43:42 +0000356 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattner40d2ae82008-11-12 07:04:29 +0000357 return true;
358 }
359
Chris Lattner82437da2008-07-12 00:14:42 +0000360 return false; // error in subexpression.
Chris Lattner40d2ae82008-11-12 07:04:29 +0000361 }
Chris Lattner82437da2008-07-12 00:14:42 +0000362
363 bool OldEval = Info.isEvaluated;
364
365 // The short-circuiting &&/|| operators don't necessarily evaluate their
366 // RHS. Make sure to pass isEvaluated down correctly.
367 if ((E->getOpcode() == BinaryOperator::LAnd && Result == 0) ||
368 (E->getOpcode() == BinaryOperator::LOr && Result != 0))
369 Info.isEvaluated = false;
Eli Friedman3e64dd72008-07-27 05:46:18 +0000370
371 // FIXME: Handle pointer subtraction
372
373 // FIXME Maybe we want to succeed even where we can't evaluate the
374 // right side of LAnd/LOr?
375 // For example, see http://llvm.org/bugs/show_bug.cgi?id=2525
Chris Lattner82437da2008-07-12 00:14:42 +0000376 if (!EvaluateInteger(E->getRHS(), RHS, Info))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000377 return false;
Chris Lattner82437da2008-07-12 00:14:42 +0000378 Info.isEvaluated = OldEval;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000379
380 switch (E->getOpcode()) {
Chris Lattner438f3b12008-11-12 07:43:42 +0000381 default:
382 return Error(E->getOperatorLoc(), diag::err_expr_not_constant,E->getType());
Chris Lattner82437da2008-07-12 00:14:42 +0000383 case BinaryOperator::Mul: Result *= RHS; return true;
384 case BinaryOperator::Add: Result += RHS; return true;
385 case BinaryOperator::Sub: Result -= RHS; return true;
386 case BinaryOperator::And: Result &= RHS; return true;
387 case BinaryOperator::Xor: Result ^= RHS; return true;
388 case BinaryOperator::Or: Result |= RHS; return true;
Chris Lattner400d7402008-07-11 22:15:16 +0000389 case BinaryOperator::Div:
Chris Lattner82437da2008-07-12 00:14:42 +0000390 if (RHS == 0)
Chris Lattner438f3b12008-11-12 07:43:42 +0000391 return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero,
392 E->getType());
Chris Lattner400d7402008-07-11 22:15:16 +0000393 Result /= RHS;
Chris Lattner438f3b12008-11-12 07:43:42 +0000394 break;
Chris Lattner400d7402008-07-11 22:15:16 +0000395 case BinaryOperator::Rem:
Chris Lattner82437da2008-07-12 00:14:42 +0000396 if (RHS == 0)
Chris Lattner438f3b12008-11-12 07:43:42 +0000397 return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero,
398 E->getType());
Chris Lattner400d7402008-07-11 22:15:16 +0000399 Result %= RHS;
Chris Lattner438f3b12008-11-12 07:43:42 +0000400 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000401 case BinaryOperator::Shl:
Chris Lattner82437da2008-07-12 00:14:42 +0000402 // FIXME: Warn about out of range shift amounts!
Chris Lattnera42f09a2008-07-11 19:10:17 +0000403 Result <<= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000404 break;
405 case BinaryOperator::Shr:
Chris Lattnera42f09a2008-07-11 19:10:17 +0000406 Result >>= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000407 break;
Chris Lattnera42f09a2008-07-11 19:10:17 +0000408
Chris Lattner045502c2008-07-11 19:29:32 +0000409 case BinaryOperator::LT:
410 Result = Result < RHS;
411 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
412 break;
413 case BinaryOperator::GT:
414 Result = Result > RHS;
415 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
416 break;
417 case BinaryOperator::LE:
418 Result = Result <= RHS;
419 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
420 break;
421 case BinaryOperator::GE:
422 Result = Result >= RHS;
423 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
424 break;
425 case BinaryOperator::EQ:
426 Result = Result == RHS;
427 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
428 break;
429 case BinaryOperator::NE:
430 Result = Result != RHS;
431 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
432 break;
Chris Lattner82437da2008-07-12 00:14:42 +0000433 case BinaryOperator::LAnd:
434 Result = Result != 0 && RHS != 0;
435 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
436 break;
437 case BinaryOperator::LOr:
438 Result = Result != 0 || RHS != 0;
439 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
440 break;
441
Anders Carlssonc0328012008-07-08 05:49:43 +0000442
Anders Carlssond1aa5812008-07-08 14:35:21 +0000443 case BinaryOperator::Comma:
Chris Lattner82437da2008-07-12 00:14:42 +0000444 // Result of the comma is just the result of the RHS.
445 Result = RHS;
446
Anders Carlssond1aa5812008-07-08 14:35:21 +0000447 // C99 6.6p3: "shall not contain assignment, ..., or comma operators,
448 // *except* when they are contained within a subexpression that is not
449 // evaluated". Note that Assignment can never happen due to constraints
450 // on the LHS subexpr, so we don't need to check it here.
Chris Lattner82437da2008-07-12 00:14:42 +0000451 if (!Info.isEvaluated)
452 return true;
453
454 // If the value is evaluated, we can accept it as an extension.
455 return Extension(E->getOperatorLoc(), diag::ext_comma_in_constant_expr);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000456 }
457
458 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000459 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000460}
461
Sebastian Redl0cb7c872008-11-11 17:56:53 +0000462/// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the
463/// expression's type.
464bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
465 QualType DstTy = E->getType();
Chris Lattner265a0892008-07-11 21:24:13 +0000466 // Return the result in the right width.
467 Result.zextOrTrunc(getIntTypeSizeInBits(DstTy));
468 Result.setIsUnsigned(DstTy->isUnsignedIntegerType());
469
Sebastian Redl0cb7c872008-11-11 17:56:53 +0000470 QualType SrcTy = E->getTypeOfArgument();
471
Chris Lattner265a0892008-07-11 21:24:13 +0000472 // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
473 if (SrcTy->isVoidType())
474 Result = 1;
475
476 // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
477 if (!SrcTy->isConstantSizeType()) {
478 // FIXME: Should we attempt to evaluate this?
479 return false;
480 }
Sebastian Redl0cb7c872008-11-11 17:56:53 +0000481
482 bool isSizeOf = E->isSizeOf();
Chris Lattner265a0892008-07-11 21:24:13 +0000483
484 // GCC extension: sizeof(function) = 1.
485 if (SrcTy->isFunctionType()) {
486 // FIXME: AlignOf shouldn't be unconditionally 4!
487 Result = isSizeOf ? 1 : 4;
488 return true;
489 }
490
491 // Get information about the size or align.
Chris Lattner422373c2008-07-11 22:52:41 +0000492 unsigned CharSize = Info.Ctx.Target.getCharWidth();
Chris Lattner265a0892008-07-11 21:24:13 +0000493 if (isSizeOf)
494 Result = getIntTypeSizeInBits(SrcTy) / CharSize;
495 else
Chris Lattner422373c2008-07-11 22:52:41 +0000496 Result = Info.Ctx.getTypeAlign(SrcTy) / CharSize;
Chris Lattner265a0892008-07-11 21:24:13 +0000497 return true;
498}
499
Chris Lattnera42f09a2008-07-11 19:10:17 +0000500bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
Chris Lattner15e59112008-07-12 00:38:25 +0000501 // Special case unary operators that do not need their subexpression
502 // evaluated. offsetof/sizeof/alignof are all special.
Chris Lattner400d7402008-07-11 22:15:16 +0000503 if (E->isOffsetOfOp()) {
Chris Lattner15e59112008-07-12 00:38:25 +0000504 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Chris Lattner422373c2008-07-11 22:52:41 +0000505 Result = E->evaluateOffsetOf(Info.Ctx);
Chris Lattner400d7402008-07-11 22:15:16 +0000506 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
507 return true;
508 }
509
Chris Lattner422373c2008-07-11 22:52:41 +0000510 // Get the operand value into 'Result'.
511 if (!Visit(E->getSubExpr()))
Chris Lattner400d7402008-07-11 22:15:16 +0000512 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000513
Chris Lattner400d7402008-07-11 22:15:16 +0000514 switch (E->getOpcode()) {
Chris Lattner15e59112008-07-12 00:38:25 +0000515 default:
Chris Lattner400d7402008-07-11 22:15:16 +0000516 // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
517 // See C99 6.6p3.
Chris Lattner438f3b12008-11-12 07:43:42 +0000518 return Error(E->getOperatorLoc(), diag::err_expr_not_constant,
519 E->getType());
Chris Lattner400d7402008-07-11 22:15:16 +0000520 case UnaryOperator::LNot: {
521 bool Val = Result == 0;
522 Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
523 Result = Val;
524 break;
525 }
526 case UnaryOperator::Extension:
Chris Lattner15e59112008-07-12 00:38:25 +0000527 // FIXME: Should extension allow i-c-e extension expressions in its scope?
528 // If so, we could clear the diagnostic ID.
Chris Lattner400d7402008-07-11 22:15:16 +0000529 case UnaryOperator::Plus:
Chris Lattner15e59112008-07-12 00:38:25 +0000530 // The result is always just the subexpr.
Chris Lattner400d7402008-07-11 22:15:16 +0000531 break;
532 case UnaryOperator::Minus:
533 Result = -Result;
534 break;
535 case UnaryOperator::Not:
536 Result = ~Result;
537 break;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000538 }
539
540 Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Chris Lattnera42f09a2008-07-11 19:10:17 +0000541 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000542}
543
Chris Lattnerff579ff2008-07-12 01:15:53 +0000544/// HandleCast - This is used to evaluate implicit or explicit casts where the
545/// result type is integer.
546bool IntExprEvaluator::HandleCast(SourceLocation CastLoc,
547 Expr *SubExpr, QualType DestType) {
Chris Lattner2c99c712008-07-11 19:24:49 +0000548 unsigned DestWidth = getIntTypeSizeInBits(DestType);
Anders Carlssond1aa5812008-07-08 14:35:21 +0000549
550 // Handle simple integer->integer casts.
551 if (SubExpr->getType()->isIntegerType()) {
Chris Lattnerff579ff2008-07-12 01:15:53 +0000552 if (!Visit(SubExpr))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000553 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000554
555 // Figure out if this is a truncate, extend or noop cast.
556 // If the input is signed, do a sign extend, noop, or truncate.
557 if (DestType->isBooleanType()) {
558 // Conversion to bool compares against zero.
559 Result = Result != 0;
560 Result.zextOrTrunc(DestWidth);
Chris Lattner2c99c712008-07-11 19:24:49 +0000561 } else
Anders Carlssond1aa5812008-07-08 14:35:21 +0000562 Result.extOrTrunc(DestWidth);
Chris Lattnerff579ff2008-07-12 01:15:53 +0000563 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
564 return true;
565 }
566
567 // FIXME: Clean this up!
568 if (SubExpr->getType()->isPointerType()) {
Anders Carlssond1aa5812008-07-08 14:35:21 +0000569 APValue LV;
Chris Lattner422373c2008-07-11 22:52:41 +0000570 if (!EvaluatePointer(SubExpr, LV, Info))
Chris Lattnera42f09a2008-07-11 19:10:17 +0000571 return false;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000572 if (LV.getLValueBase())
Chris Lattnera42f09a2008-07-11 19:10:17 +0000573 return false;
Anders Carlssonc0328012008-07-08 05:49:43 +0000574
Anders Carlsson8ab15c82008-07-08 16:49:00 +0000575 Result.extOrTrunc(DestWidth);
576 Result = LV.getLValueOffset();
Chris Lattnerff579ff2008-07-12 01:15:53 +0000577 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
578 return true;
Anders Carlsson02a34c32008-07-08 14:30:00 +0000579 }
580
Chris Lattnerff579ff2008-07-12 01:15:53 +0000581 if (!SubExpr->getType()->isRealFloatingType())
Chris Lattner438f3b12008-11-12 07:43:42 +0000582 return Error(CastLoc, diag::err_expr_not_constant, DestType);
Chris Lattnerff579ff2008-07-12 01:15:53 +0000583
Eli Friedman2f445492008-08-22 00:06:13 +0000584 APFloat F(0.0);
585 if (!EvaluateFloat(SubExpr, F, Info))
Chris Lattner438f3b12008-11-12 07:43:42 +0000586 return Error(CastLoc, diag::err_expr_not_constant, DestType);
Eli Friedman2f445492008-08-22 00:06:13 +0000587
Chris Lattnerff579ff2008-07-12 01:15:53 +0000588 // If the destination is boolean, compare against zero.
589 if (DestType->isBooleanType()) {
Eli Friedman2f445492008-08-22 00:06:13 +0000590 Result = !F.isZero();
Chris Lattnerff579ff2008-07-12 01:15:53 +0000591 Result.zextOrTrunc(DestWidth);
592 Result.setIsUnsigned(DestType->isUnsignedIntegerType());
593 return true;
594 }
595
596 // Determine whether we are converting to unsigned or signed.
597 bool DestSigned = DestType->isSignedIntegerType();
598
599 // FIXME: Warning for overflow.
Dale Johannesen2461f612008-10-09 23:02:32 +0000600 uint64_t Space[4];
601 bool ignored;
Eli Friedman2f445492008-08-22 00:06:13 +0000602 (void)F.convertToInteger(Space, DestWidth, DestSigned,
Dale Johannesen2461f612008-10-09 23:02:32 +0000603 llvm::APFloat::rmTowardZero, &ignored);
Chris Lattnerff579ff2008-07-12 01:15:53 +0000604 Result = llvm::APInt(DestWidth, 4, Space);
605 Result.setIsUnsigned(!DestSigned);
Chris Lattnera42f09a2008-07-11 19:10:17 +0000606 return true;
Anders Carlssond1aa5812008-07-08 14:35:21 +0000607}
Anders Carlsson02a34c32008-07-08 14:30:00 +0000608
Chris Lattnera823ccf2008-07-11 18:11:29 +0000609//===----------------------------------------------------------------------===//
Eli Friedman2f445492008-08-22 00:06:13 +0000610// Float Evaluation
611//===----------------------------------------------------------------------===//
612
613namespace {
614class VISIBILITY_HIDDEN FloatExprEvaluator
615 : public StmtVisitor<FloatExprEvaluator, bool> {
616 EvalInfo &Info;
617 APFloat &Result;
618public:
619 FloatExprEvaluator(EvalInfo &info, APFloat &result)
620 : Info(info), Result(result) {}
621
622 bool VisitStmt(Stmt *S) {
623 return false;
624 }
625
626 bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
Chris Lattner87293782008-10-06 05:28:25 +0000627 bool VisitCallExpr(const CallExpr *E);
Eli Friedman2f445492008-08-22 00:06:13 +0000628
Daniel Dunbar804ead02008-10-16 03:51:50 +0000629 bool VisitUnaryOperator(const UnaryOperator *E);
Eli Friedman2f445492008-08-22 00:06:13 +0000630 bool VisitBinaryOperator(const BinaryOperator *E);
631 bool VisitFloatingLiteral(const FloatingLiteral *E);
632};
633} // end anonymous namespace
634
635static bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) {
636 return FloatExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
637}
638
Chris Lattner87293782008-10-06 05:28:25 +0000639bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
Chris Lattner87293782008-10-06 05:28:25 +0000640 switch (E->isBuiltinCall()) {
Chris Lattner27cde262008-10-06 05:53:16 +0000641 default: return false;
Chris Lattner87293782008-10-06 05:28:25 +0000642 case Builtin::BI__builtin_huge_val:
643 case Builtin::BI__builtin_huge_valf:
644 case Builtin::BI__builtin_huge_vall:
645 case Builtin::BI__builtin_inf:
646 case Builtin::BI__builtin_inff:
Daniel Dunbar0b3efb42008-10-14 05:41:12 +0000647 case Builtin::BI__builtin_infl: {
648 const llvm::fltSemantics &Sem =
649 Info.Ctx.getFloatTypeSemantics(E->getType());
Chris Lattner27cde262008-10-06 05:53:16 +0000650 Result = llvm::APFloat::getInf(Sem);
651 return true;
Daniel Dunbar0b3efb42008-10-14 05:41:12 +0000652 }
Chris Lattner667e1ee2008-10-06 06:31:58 +0000653
654 case Builtin::BI__builtin_nan:
655 case Builtin::BI__builtin_nanf:
656 case Builtin::BI__builtin_nanl:
657 // If this is __builtin_nan("") turn this into a simple nan, otherwise we
658 // can't constant fold it.
659 if (const StringLiteral *S =
660 dyn_cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts())) {
661 if (!S->isWide() && S->getByteLength() == 0) { // empty string.
Daniel Dunbar0b3efb42008-10-14 05:41:12 +0000662 const llvm::fltSemantics &Sem =
663 Info.Ctx.getFloatTypeSemantics(E->getType());
Chris Lattner667e1ee2008-10-06 06:31:58 +0000664 Result = llvm::APFloat::getNaN(Sem);
665 return true;
666 }
667 }
668 return false;
Daniel Dunbar804ead02008-10-16 03:51:50 +0000669
670 case Builtin::BI__builtin_fabs:
671 case Builtin::BI__builtin_fabsf:
672 case Builtin::BI__builtin_fabsl:
673 if (!EvaluateFloat(E->getArg(0), Result, Info))
674 return false;
675
676 if (Result.isNegative())
677 Result.changeSign();
678 return true;
679
680 case Builtin::BI__builtin_copysign:
681 case Builtin::BI__builtin_copysignf:
682 case Builtin::BI__builtin_copysignl: {
683 APFloat RHS(0.);
684 if (!EvaluateFloat(E->getArg(0), Result, Info) ||
685 !EvaluateFloat(E->getArg(1), RHS, Info))
686 return false;
687 Result.copySign(RHS);
688 return true;
689 }
Chris Lattner87293782008-10-06 05:28:25 +0000690 }
691}
692
Daniel Dunbar804ead02008-10-16 03:51:50 +0000693bool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
694 if (!EvaluateFloat(E->getSubExpr(), Result, Info))
695 return false;
696
697 switch (E->getOpcode()) {
698 default: return false;
699 case UnaryOperator::Plus:
700 return true;
701 case UnaryOperator::Minus:
702 Result.changeSign();
703 return true;
704 }
705}
Chris Lattner87293782008-10-06 05:28:25 +0000706
Eli Friedman2f445492008-08-22 00:06:13 +0000707bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
708 // FIXME: Diagnostics? I really don't understand how the warnings
709 // and errors are supposed to work.
Daniel Dunbar804ead02008-10-16 03:51:50 +0000710 APFloat RHS(0.0);
Eli Friedman2f445492008-08-22 00:06:13 +0000711 if (!EvaluateFloat(E->getLHS(), Result, Info))
712 return false;
713 if (!EvaluateFloat(E->getRHS(), RHS, Info))
714 return false;
715
716 switch (E->getOpcode()) {
717 default: return false;
718 case BinaryOperator::Mul:
719 Result.multiply(RHS, APFloat::rmNearestTiesToEven);
720 return true;
721 case BinaryOperator::Add:
722 Result.add(RHS, APFloat::rmNearestTiesToEven);
723 return true;
724 case BinaryOperator::Sub:
725 Result.subtract(RHS, APFloat::rmNearestTiesToEven);
726 return true;
727 case BinaryOperator::Div:
728 Result.divide(RHS, APFloat::rmNearestTiesToEven);
729 return true;
730 case BinaryOperator::Rem:
731 Result.mod(RHS, APFloat::rmNearestTiesToEven);
732 return true;
733 }
734}
735
736bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) {
737 Result = E->getValue();
738 return true;
739}
740
741//===----------------------------------------------------------------------===//
Chris Lattnera823ccf2008-07-11 18:11:29 +0000742// Top level TryEvaluate.
743//===----------------------------------------------------------------------===//
744
Chris Lattner87293782008-10-06 05:28:25 +0000745/// tryEvaluate - Return true if this is a constant which we can fold using
746/// any crazy technique (that has nothing to do with language standards) that
747/// we want to. If this function returns true, it returns the folded constant
748/// in Result.
Chris Lattnera42f09a2008-07-11 19:10:17 +0000749bool Expr::tryEvaluate(APValue &Result, ASTContext &Ctx) const {
Chris Lattner422373c2008-07-11 22:52:41 +0000750 EvalInfo Info(Ctx);
Anders Carlssonc0328012008-07-08 05:49:43 +0000751 if (getType()->isIntegerType()) {
Eli Friedman2f445492008-08-22 00:06:13 +0000752 llvm::APSInt sInt(32);
Chris Lattner422373c2008-07-11 22:52:41 +0000753 if (EvaluateInteger(this, sInt, Info)) {
Anders Carlssonc0328012008-07-08 05:49:43 +0000754 Result = APValue(sInt);
755 return true;
756 }
Eli Friedman2f445492008-08-22 00:06:13 +0000757 } else if (getType()->isPointerType()) {
758 if (EvaluatePointer(this, Result, Info)) {
759 return true;
760 }
761 } else if (getType()->isRealFloatingType()) {
762 llvm::APFloat f(0.0);
763 if (EvaluateFloat(this, f, Info)) {
764 Result = APValue(f);
765 return true;
766 }
767 }
Anders Carlsson47968a92008-08-10 17:03:01 +0000768
Anders Carlssonc7436af2008-07-03 04:20:39 +0000769 return false;
770}
Chris Lattner2d9a3f62008-10-06 06:49:02 +0000771
772/// isEvaluatable - Call tryEvaluate to see if this expression can be constant
773/// folded, but discard the result.
774bool Expr::isEvaluatable(ASTContext &Ctx) const {
775 APValue V;
776 return tryEvaluate(V, Ctx);
777}