 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
70.0% |
573 / 818 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
90.5% |
740 / 818 |
| |
|
Line Coverage: |
82.6% |
856 / 1036 |
| |
 |
|
 |
1 : //===--- ExprConstant.cpp - Expression Constant Evaluator -----------------===//
2 : //
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"
16 : #include "clang/AST/CharUnits.h"
17 : #include "clang/AST/RecordLayout.h"
18 : #include "clang/AST/StmtVisitor.h"
19 : #include "clang/AST/ASTDiagnostic.h"
20 : #include "clang/Basic/Builtins.h"
21 : #include "clang/Basic/TargetInfo.h"
22 : #include "llvm/ADT/SmallString.h"
23 : #include <cstring>
24 :
25 : using namespace clang;
26 : using llvm::APSInt;
27 : using llvm::APFloat;
28 :
29 : /// EvalInfo - This is a private struct used by the evaluator to capture
30 : /// information about a subexpression as it is folded. It retains information
31 : /// about the AST context, but also maintains information about the folded
32 : /// expression.
33 : ///
34 : /// If an expression could be evaluated, it is still possible it is not a C
35 : /// "integer constant expression" or constant expression. If not, this struct
36 : /// captures information about how and why not.
37 : ///
38 : /// One bit of information passed *into* the request for constant folding
39 : /// indicates whether the subexpression is "evaluated" or not according to C
40 : /// rules. For example, the RHS of (0 && foo()) is not evaluated. We can
41 : /// evaluate the expression regardless of what the RHS is, but C only allows
42 : /// certain things in certain situations.
43 : struct EvalInfo {
44 : ASTContext &Ctx;
45 :
46 : /// EvalResult - Contains information about the evaluation.
47 : Expr::EvalResult &EvalResult;
48 :
49 : /// AnyLValue - Stack based LValue results are not discarded.
50 : bool AnyLValue;
51 :
52 : EvalInfo(ASTContext &ctx, Expr::EvalResult& evalresult,
53 26184: bool anylvalue = false)
54 26184: : Ctx(ctx), EvalResult(evalresult), AnyLValue(anylvalue) {}
55 : };
56 :
57 :
58 : static bool EvaluateLValue(const Expr *E, APValue &Result, EvalInfo &Info);
59 : static bool EvaluatePointer(const Expr *E, APValue &Result, EvalInfo &Info);
60 : static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info);
61 : static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result,
62 : EvalInfo &Info);
63 : static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
64 : static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info);
65 :
66 : //===----------------------------------------------------------------------===//
67 : // Misc utilities
68 : //===----------------------------------------------------------------------===//
69 :
70 10: static bool EvalPointerValueAsBool(APValue& Value, bool& Result) {
71 : // FIXME: Is this accurate for all kinds of bases? If not, what would
72 : // the check look like?
0: branch 1 not taken
10: branch 2 taken
0: branch 5 not taken
0: branch 6 not taken
73 10: Result = Value.getLValueBase() || !Value.getLValueOffset().isZero();
74 10: return true;
75 : }
76 :
77 : static bool HandleConversionToBool(const Expr* E, bool& Result,
78 1691: EvalInfo &Info) {
1468: branch 3 taken
223: branch 4 taken
79 1691: if (E->getType()->isIntegralType()) {
80 1468: APSInt IntResult;
434: branch 1 taken
1034: branch 2 taken
81 1468: if (!EvaluateInteger(E, IntResult, Info))
82 434: return false;
83 1034: Result = IntResult != 0;
84 1034: return true;
22: branch 3 taken
201: branch 4 taken
85 223: } else if (E->getType()->isRealFloatingType()) {
86 22: APFloat FloatResult(0.0);
16: branch 1 taken
6: branch 2 taken
87 22: if (!EvaluateFloat(E, FloatResult, Info))
88 16: return false;
89 6: Result = !FloatResult.isZero();
90 6: return true;
192: branch 3 taken
9: branch 4 taken
91 201: } else if (E->getType()->hasPointerRepresentation()) {
92 192: APValue PointerResult;
183: branch 1 taken
9: branch 2 taken
93 192: if (!EvaluatePointer(E, PointerResult, Info))
94 183: return false;
95 9: return EvalPointerValueAsBool(PointerResult, Result);
4: branch 3 taken
5: branch 4 taken
96 9: } else if (E->getType()->isAnyComplexType()) {
97 4: APValue ComplexResult;
0: branch 1 not taken
4: branch 2 taken
98 4: if (!EvaluateComplex(E, ComplexResult, Info))
99 0: return false;
2: branch 1 taken
2: branch 2 taken
100 4: if (ComplexResult.isComplexFloat()) {
101 : Result = !ComplexResult.getComplexFloatReal().isZero() ||
1: branch 2 taken
1: branch 3 taken
0: branch 6 not taken
1: branch 7 taken
102 2: !ComplexResult.getComplexFloatImag().isZero();
103 : } else {
104 : Result = ComplexResult.getComplexIntReal().getBoolValue() ||
1: branch 2 taken
1: branch 3 taken
0: branch 6 not taken
1: branch 7 taken
105 2: ComplexResult.getComplexIntImag().getBoolValue();
106 : }
107 4: return true;
108 : }
109 :
110 5: return false;
111 : }
112 :
113 : static APSInt HandleFloatToIntCast(QualType DestType, QualType SrcType,
114 56: APFloat &Value, ASTContext &Ctx) {
115 56: unsigned DestWidth = Ctx.getIntWidth(DestType);
116 : // Determine whether we are converting to unsigned or signed.
117 56: bool DestSigned = DestType->isSignedIntegerType();
118 :
119 : // FIXME: Warning for overflow.
120 : uint64_t Space[4];
121 : bool ignored;
122 : (void)Value.convertToInteger(Space, DestWidth, DestSigned,
123 56: llvm::APFloat::rmTowardZero, &ignored);
124 56: return APSInt(llvm::APInt(DestWidth, 4, Space), !DestSigned);
125 : }
126 :
127 : static APFloat HandleFloatToFloatCast(QualType DestType, QualType SrcType,
128 147: APFloat &Value, ASTContext &Ctx) {
129 : bool ignored;
130 147: APFloat Result = Value;
131 : Result.convert(Ctx.getFloatTypeSemantics(DestType),
132 147: APFloat::rmNearestTiesToEven, &ignored);
133 : return Result;
134 : }
135 :
136 : static APSInt HandleIntToIntCast(QualType DestType, QualType SrcType,
137 2514: APSInt &Value, ASTContext &Ctx) {
138 2514: unsigned DestWidth = Ctx.getIntWidth(DestType);
139 2514: APSInt Result = Value;
140 : // Figure out if this is a truncate, extend or noop cast.
141 : // If the input is signed, do a sign extend, noop, or truncate.
142 2514: Result.extOrTrunc(DestWidth);
143 2514: Result.setIsUnsigned(DestType->isUnsignedIntegerType());
144 : return Result;
145 : }
146 :
147 : static APFloat HandleIntToFloatCast(QualType DestType, QualType SrcType,
148 76: APSInt &Value, ASTContext &Ctx) {
149 :
150 76: APFloat Result(Ctx.getFloatTypeSemantics(DestType), 1);
151 : Result.convertFromAPInt(Value, Value.isSigned(),
152 76: APFloat::rmNearestTiesToEven);
153 : return Result;
154 : }
155 :
156 : namespace {
157 : class HasSideEffect
158 : : public StmtVisitor<HasSideEffect, bool> {
159 : EvalInfo &Info;
160 : public:
161 :
162 65: HasSideEffect(EvalInfo &info) : Info(info) {}
163 :
164 : // Unhandled nodes conservatively default to having side effects.
165 18: bool VisitStmt(Stmt *S) {
166 18: return true;
167 : }
168 :
169 8: bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
170 8: bool VisitDeclRefExpr(DeclRefExpr *E) {
0: branch 3 not taken
8: branch 4 taken
171 8: if (Info.Ctx.getCanonicalType(E->getType()).isVolatileQualified())
172 0: return true;
173 8: return false;
174 : }
175 : // We don't want to evaluate BlockExprs multiple times, as they generate
176 : // a ton of code.
177 0: bool VisitBlockExpr(BlockExpr *E) { return true; }
178 0: bool VisitPredefinedExpr(PredefinedExpr *E) { return false; }
179 0: bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E)
180 0: { return Visit(E->getInitializer()); }
181 0: bool VisitMemberExpr(MemberExpr *E) { return Visit(E->getBase()); }
182 8: bool VisitIntegerLiteral(IntegerLiteral *E) { return false; }
183 0: bool VisitFloatingLiteral(FloatingLiteral *E) { return false; }
184 5: bool VisitStringLiteral(StringLiteral *E) { return false; }
185 0: bool VisitCharacterLiteral(CharacterLiteral *E) { return false; }
186 0: bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { return false; }
187 2: bool VisitArraySubscriptExpr(ArraySubscriptExpr *E)
2: branch 2 taken
0: branch 3 not taken
2: branch 6 taken
0: branch 7 not taken
188 2: { return Visit(E->getLHS()) || Visit(E->getRHS()); }
189 0: bool VisitChooseExpr(ChooseExpr *E)
190 0: { return Visit(E->getChosenSubExpr(Info.Ctx)); }
191 37: bool VisitCastExpr(CastExpr *E) { return Visit(E->getSubExpr()); }
192 2: bool VisitBinAssign(BinaryOperator *E) { return true; }
193 2: bool VisitCompoundAssignOperator(BinaryOperator *E) { return true; }
194 4: bool VisitBinaryOperator(BinaryOperator *E)
0: branch 2 not taken
4: branch 3 taken
0: branch 6 not taken
0: branch 7 not taken
195 4: { return Visit(E->getLHS()) || Visit(E->getRHS()); }
196 10: bool VisitUnaryPreInc(UnaryOperator *E) { return true; }
197 10: bool VisitUnaryPostInc(UnaryOperator *E) { return true; }
198 2: bool VisitUnaryPreDec(UnaryOperator *E) { return true; }
199 2: bool VisitUnaryPostDec(UnaryOperator *E) { return true; }
200 2: bool VisitUnaryDeref(UnaryOperator *E) {
0: branch 3 not taken
2: branch 4 taken
201 2: if (Info.Ctx.getCanonicalType(E->getType()).isVolatileQualified())
202 0: return true;
203 2: return Visit(E->getSubExpr());
204 : }
205 0: bool VisitUnaryOperator(UnaryOperator *E) { return Visit(E->getSubExpr()); }
206 : };
207 :
208 : } // end anonymous namespace
209 :
210 : //===----------------------------------------------------------------------===//
211 : // LValue Evaluation
212 : //===----------------------------------------------------------------------===//
213 : namespace {
214 : class LValueExprEvaluator
215 : : public StmtVisitor<LValueExprEvaluator, APValue> {
216 : EvalInfo &Info;
217 : public:
218 :
219 748: LValueExprEvaluator(EvalInfo &info) : Info(info) {}
220 :
221 0: APValue VisitStmt(Stmt *S) {
222 0: return APValue();
223 : }
224 :
225 4: APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
226 : APValue VisitDeclRefExpr(DeclRefExpr *E);
227 6: APValue VisitPredefinedExpr(PredefinedExpr *E) { return APValue(E); }
228 : APValue VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
229 : APValue VisitMemberExpr(MemberExpr *E);
230 51: APValue VisitStringLiteral(StringLiteral *E) { return APValue(E); }
231 14: APValue VisitObjCEncodeExpr(ObjCEncodeExpr *E) { return APValue(E); }
232 : APValue VisitArraySubscriptExpr(ArraySubscriptExpr *E);
233 : APValue VisitUnaryDeref(UnaryOperator *E);
234 0: APValue VisitUnaryExtension(const UnaryOperator *E)
235 0: { return Visit(E->getSubExpr()); }
236 0: APValue VisitChooseExpr(const ChooseExpr *E)
237 0: { return Visit(E->getChosenSubExpr(Info.Ctx)); }
238 :
239 3: APValue VisitCastExpr(CastExpr *E) {
1: branch 1 taken
2: branch 2 taken
240 3: switch (E->getCastKind()) {
241 : default:
242 1: return APValue();
243 :
244 : case CastExpr::CK_NoOp:
245 2: return Visit(E->getSubExpr());
246 : }
247 : }
248 : // FIXME: Missing: __real__, __imag__
249 : };
250 : } // end anonymous namespace
251 :
252 748: static bool EvaluateLValue(const Expr* E, APValue& Result, EvalInfo &Info) {
253 748: Result = LValueExprEvaluator(Info).Visit(const_cast<Expr*>(E));
254 748: return Result.isLValue();
255 : }
256 :
257 352: APValue LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E) {
73: branch 2 taken
279: branch 3 taken
258 352: if (isa<FunctionDecl>(E->getDecl())) {
259 73: return APValue(E);
279: branch 2 taken
0: branch 3 not taken
260 279: } else if (VarDecl* VD = dyn_cast<VarDecl>(E->getDecl())) {
248: branch 0 taken
31: branch 1 taken
20: branch 3 taken
228: branch 4 taken
20: branch 5 taken
259: branch 6 taken
261 279: if (!Info.AnyLValue && !VD->hasGlobalStorage())
262 20: return APValue();
258: branch 3 taken
1: branch 4 taken
263 259: if (!VD->getType()->isReferenceType())
264 258: return APValue(E);
265 : // FIXME: Check whether VD might be overridden!
1: branch 1 taken
0: branch 2 not taken
266 1: if (const Expr *Init = VD->getAnyInitializer())
267 1: return Visit(const_cast<Expr *>(Init));
268 : }
269 :
270 0: return APValue();
271 : }
272 :
273 12: APValue LValueExprEvaluator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
12: branch 0 taken
0: branch 1 not taken
0: branch 3 not taken
12: branch 4 taken
0: branch 5 not taken
12: branch 6 taken
274 12: if (!Info.AnyLValue && !E->isFileScope())
275 0: return APValue();
276 12: return APValue(E);
277 : }
278 :
279 306: APValue LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) {
280 306: APValue result;
281 306: QualType Ty;
10: branch 1 taken
296: branch 2 taken
282 306: if (E->isArrow()) {
0: branch 2 not taken
10: branch 3 taken
283 10: if (!EvaluatePointer(E->getBase(), result, Info))
284 0: return APValue();
285 10: Ty = E->getBase()->getType()->getAs<PointerType>()->getPointeeType();
286 : } else {
287 296: result = Visit(E->getBase());
5: branch 1 taken
291: branch 2 taken
288 296: if (result.isUninit())
289 5: return APValue();
290 291: Ty = E->getBase()->getType();
291 : }
292 :
293 301: RecordDecl *RD = Ty->getAs<RecordType>()->getDecl();
294 301: const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
295 :
296 301: FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
0: branch 0 not taken
301: branch 1 taken
297 301: if (!FD) // FIXME: deal with other kinds of member expressions
298 0: return APValue();
299 :
2: branch 3 taken
299: branch 4 taken
300 301: if (FD->getType()->isReferenceType())
301 2: return APValue();
302 :
303 : // FIXME: This is linear time.
304 299: unsigned i = 0;
439: branch 3 taken
0: branch 4 not taken
305 738: for (RecordDecl::field_iterator Field = RD->field_begin(),
306 299: FieldEnd = RD->field_end();
307 : Field != FieldEnd; (void)++Field, ++i) {
299: branch 1 taken
140: branch 2 taken
308 439: if (*Field == FD)
309 299: break;
310 : }
311 :
312 : result.setLValue(result.getLValueBase(),
313 : result.getLValueOffset() +
314 299: CharUnits::fromQuantity(RL.getFieldOffset(i) / 8));
315 :
316 299: return result;
317 : }
318 :
319 50: APValue LValueExprEvaluator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
320 50: APValue Result;
321 :
6: branch 2 taken
44: branch 3 taken
322 50: if (!EvaluatePointer(E->getBase(), Result, Info))
323 6: return APValue();
324 :
325 44: APSInt Index;
2: branch 2 taken
42: branch 3 taken
326 44: if (!EvaluateInteger(E->getIdx(), Index, Info))
327 2: return APValue();
328 :
329 42: CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(E->getType());
330 :
331 42: CharUnits Offset = Index.getSExtValue() * ElementSize;
332 : Result.setLValue(Result.getLValueBase(),
333 42: Result.getLValueOffset() + Offset);
334 42: return Result;
335 : }
336 :
337 253: APValue LValueExprEvaluator::VisitUnaryDeref(UnaryOperator *E) {
338 253: APValue Result;
2: branch 2 taken
251: branch 3 taken
339 253: if (!EvaluatePointer(E->getSubExpr(), Result, Info))
340 2: return APValue();
341 251: return Result;
342 : }
343 :
344 : //===----------------------------------------------------------------------===//
345 : // Pointer Evaluation
346 : //===----------------------------------------------------------------------===//
347 :
348 : namespace {
349 : class PointerExprEvaluator
350 : : public StmtVisitor<PointerExprEvaluator, APValue> {
351 : EvalInfo &Info;
352 : public:
353 :
354 2845: PointerExprEvaluator(EvalInfo &info) : Info(info) {}
355 :
356 1642: APValue VisitStmt(Stmt *S) {
357 1642: return APValue();
358 : }
359 :
360 190: APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
361 :
362 : APValue VisitBinaryOperator(const BinaryOperator *E);
363 : APValue VisitCastExpr(CastExpr* E);
364 1: APValue VisitUnaryExtension(const UnaryOperator *E)
365 1: { return Visit(E->getSubExpr()); }
366 : APValue VisitUnaryAddrOf(const UnaryOperator *E);
367 10: APValue VisitObjCStringLiteral(ObjCStringLiteral *E)
368 10: { return APValue(E); }
369 30: APValue VisitAddrLabelExpr(AddrLabelExpr *E)
370 30: { return APValue(E); }
371 : APValue VisitCallExpr(CallExpr *E);
372 16: APValue VisitBlockExpr(BlockExpr *E) {
15: branch 1 taken
1: branch 2 taken
373 16: if (!E->hasBlockDeclRefExprs())
374 15: return APValue(E);
375 1: return APValue();
376 : }
377 250: APValue VisitImplicitValueInitExpr(ImplicitValueInitExpr *E)
378 250: { return APValue((Expr*)0); }
379 : APValue VisitConditionalOperator(ConditionalOperator *E);
380 1: APValue VisitChooseExpr(ChooseExpr *E)
381 1: { return Visit(E->getChosenSubExpr(Info.Ctx)); }
382 1: APValue VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E)
383 1: { return APValue((Expr*)0); }
384 : // FIXME: Missing: @protocol, @selector
385 : };
386 : } // end anonymous namespace
387 :
388 2845: static bool EvaluatePointer(const Expr* E, APValue& Result, EvalInfo &Info) {
0: branch 3 not taken
2845: branch 4 taken
389 2845: if (!E->getType()->hasPointerRepresentation())
390 0: return false;
391 2845: Result = PointerExprEvaluator(Info).Visit(const_cast<Expr*>(E));
392 2845: return Result.isLValue();
393 : }
394 :
395 96: APValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
53: branch 1 taken
43: branch 2 taken
47: branch 4 taken
6: branch 5 taken
47: branch 6 taken
49: branch 7 taken
396 96: if (E->getOpcode() != BinaryOperator::Add &&
397 : E->getOpcode() != BinaryOperator::Sub)
398 47: return APValue();
399 :
400 49: const Expr *PExp = E->getLHS();
401 49: const Expr *IExp = E->getRHS();
1: branch 3 taken
48: branch 4 taken
402 49: if (IExp->getType()->isPointerType())
403 1: std::swap(PExp, IExp);
404 :
405 49: APValue ResultLValue;
5: branch 1 taken
44: branch 2 taken
406 49: if (!EvaluatePointer(PExp, ResultLValue, Info))
407 5: return APValue();
408 :
409 44: llvm::APSInt AdditionalOffset(32);
0: branch 1 not taken
44: branch 2 taken
410 44: if (!EvaluateInteger(IExp, AdditionalOffset, Info))
411 0: return APValue();
412 :
413 44: QualType PointeeType = PExp->getType()->getAs<PointerType>()->getPointeeType();
414 44: CharUnits SizeOfPointee;
415 :
416 : // Explicitly handle GNU void* and function pointer arithmetic extensions.
41: branch 2 taken
3: branch 3 taken
0: branch 6 not taken
41: branch 7 taken
3: branch 8 taken
41: branch 9 taken
417 44: if (PointeeType->isVoidType() || PointeeType->isFunctionType())
418 3: SizeOfPointee = CharUnits::One();
419 : else
420 41: SizeOfPointee = Info.Ctx.getTypeSizeInChars(PointeeType);
421 :
422 44: CharUnits Offset = ResultLValue.getLValueOffset();
423 :
38: branch 1 taken
6: branch 2 taken
424 44: if (E->getOpcode() == BinaryOperator::Add)
425 38: Offset += AdditionalOffset.getLimitedValue() * SizeOfPointee;
426 : else
427 6: Offset -= AdditionalOffset.getLimitedValue() * SizeOfPointee;
428 :
429 44: return APValue(ResultLValue.getLValueBase(), Offset);
430 : }
431 :
432 271: APValue PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) {
433 271: APValue result;
249: branch 2 taken
22: branch 3 taken
434 271: if (EvaluateLValue(E->getSubExpr(), result, Info))
435 249: return result;
436 22: return APValue();
437 : }
438 :
439 :
440 739: APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) {
441 739: Expr* SubExpr = E->getSubExpr();
442 :
22: branch 1 taken
266: branch 2 taken
91: branch 3 taken
142: branch 4 taken
218: branch 5 taken
443 739: switch (E->getCastKind()) {
444 : default:
445 22: break;
446 :
447 : case CastExpr::CK_Unknown: {
448 : // FIXME: The handling for CK_Unknown is ugly/shouldn't be necessary!
449 :
450 : // Check for pointer->pointer cast
88: branch 3 taken
178: branch 4 taken
68: branch 8 taken
20: branch 9 taken
67: branch 13 taken
1: branch 14 taken
8: branch 18 taken
59: branch 19 taken
207: branch 20 taken
59: branch 21 taken
451 266: if (SubExpr->getType()->isPointerType() ||
452 : SubExpr->getType()->isObjCObjectPointerType() ||
453 : SubExpr->getType()->isNullPtrType() ||
454 : SubExpr->getType()->isBlockPointerType())
455 207: return Visit(SubExpr);
456 :
59: branch 3 taken
0: branch 4 not taken
457 59: if (SubExpr->getType()->isIntegralType()) {
458 59: APValue Result;
0: branch 1 not taken
59: branch 2 taken
459 59: if (!EvaluateIntegerOrLValue(SubExpr, Result, Info))
460 0: break;
461 :
59: branch 1 taken
0: branch 2 not taken
462 59: if (Result.isInt()) {
463 59: Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
464 : return APValue(0,
465 118: CharUnits::fromQuantity(Result.getInt().getZExtValue()));
466 : }
467 :
468 : // Cast is of an lvalue, no need to change value.
0: branch 2 not taken
59: branch 3 taken
469 0: return Result;
470 : }
471 0: break;
472 : }
473 :
474 : case CastExpr::CK_NoOp:
475 : case CastExpr::CK_BitCast:
476 : case CastExpr::CK_AnyPointerToObjCPointerCast:
477 : case CastExpr::CK_AnyPointerToBlockPointerCast:
478 91: return Visit(SubExpr);
479 :
480 : case CastExpr::CK_IntegralToPointer: {
481 142: APValue Result;
2: branch 1 taken
140: branch 2 taken
482 142: if (!EvaluateIntegerOrLValue(SubExpr, Result, Info))
483 2: break;
484 :
137: branch 1 taken
3: branch 2 taken
485 140: if (Result.isInt()) {
486 137: Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
487 : return APValue(0,
488 277: CharUnits::fromQuantity(Result.getInt().getZExtValue()));
489 : }
490 :
491 : // Cast is of an lvalue, no need to change value.
2: branch 2 taken
140: branch 3 taken
492 3: return Result;
493 : }
494 : case CastExpr::CK_ArrayToPointerDecay:
495 : case CastExpr::CK_FunctionToPointerDecay: {
496 218: APValue Result;
212: branch 1 taken
6: branch 2 taken
497 218: if (EvaluateLValue(SubExpr, Result, Info))
498 424: return Result;
212: branch 1 taken
6: branch 2 taken
499 224: break;
500 : }
501 : }
502 :
503 30: return APValue();
504 : }
505 :
506 72: APValue PointerExprEvaluator::VisitCallExpr(CallExpr *E) {
50: branch 1 taken
22: branch 2 taken
0: branch 4 not taken
50: branch 5 taken
22: branch 6 taken
50: branch 7 taken
507 72: if (E->isBuiltinCall(Info.Ctx) ==
508 : Builtin::BI__builtin___CFStringMakeConstantString ||
509 : E->isBuiltinCall(Info.Ctx) ==
510 : Builtin::BI__builtin___NSStringMakeConstantString)
511 22: return APValue(E);
512 50: return APValue();
513 : }
514 :
515 16: APValue PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) {
516 : bool BoolResult;
0: branch 2 not taken
16: branch 3 taken
517 16: if (!HandleConversionToBool(E->getCond(), BoolResult, Info))
518 0: return APValue();
519 :
6: branch 0 taken
10: branch 1 taken
520 16: Expr* EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr();
521 :
522 16: APValue Result;
16: branch 1 taken
0: branch 2 not taken
523 16: if (EvaluatePointer(EvalExpr, Result, Info))
524 16: return Result;
525 0: return APValue();
526 : }
527 :
528 : //===----------------------------------------------------------------------===//
529 : // Vector Evaluation
530 : //===----------------------------------------------------------------------===//
531 :
532 : namespace {
533 : class VectorExprEvaluator
534 : : public StmtVisitor<VectorExprEvaluator, APValue> {
535 : EvalInfo &Info;
536 : APValue GetZeroVector(QualType VecType);
537 : public:
538 :
539 744: VectorExprEvaluator(EvalInfo &info) : Info(info) {}
540 :
541 732: APValue VisitStmt(Stmt *S) {
542 732: return APValue();
543 : }
544 :
545 0: APValue VisitParenExpr(ParenExpr *E)
546 0: { return Visit(E->getSubExpr()); }
547 0: APValue VisitUnaryExtension(const UnaryOperator *E)
548 0: { return Visit(E->getSubExpr()); }
549 0: APValue VisitUnaryPlus(const UnaryOperator *E)
550 0: { return Visit(E->getSubExpr()); }
551 1: APValue VisitUnaryReal(const UnaryOperator *E)
552 1: { return Visit(E->getSubExpr()); }
553 0: APValue VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
554 0: { return GetZeroVector(E->getType()); }
555 : APValue VisitCastExpr(const CastExpr* E);
556 : APValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
557 : APValue VisitInitListExpr(const InitListExpr *E);
558 : APValue VisitConditionalOperator(const ConditionalOperator *E);
559 1: APValue VisitChooseExpr(const ChooseExpr *E)
560 1: { return Visit(E->getChosenSubExpr(Info.Ctx)); }
561 : APValue VisitUnaryImag(const UnaryOperator *E);
562 : // FIXME: Missing: unary -, unary ~, binary add/sub/mul/div,
563 : // binary comparisons, binary and/or/xor,
564 : // shufflevector, ExtVectorElementExpr
565 : // (Note that these require implementing conversions
566 : // between vector types.)
567 : };
568 : } // end anonymous namespace
569 :
570 744: static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) {
0: branch 3 not taken
744: branch 4 taken
571 744: if (!E->getType()->isVectorType())
572 0: return false;
573 744: Result = VectorExprEvaluator(Info).Visit(const_cast<Expr*>(E));
574 744: return !Result.isUninit();
575 : }
576 :
577 3: APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
578 3: const VectorType *VTy = E->getType()->getAs<VectorType>();
579 3: QualType EltTy = VTy->getElementType();
580 3: unsigned NElts = VTy->getNumElements();
581 3: unsigned EltWidth = Info.Ctx.getTypeSize(EltTy);
582 :
583 3: const Expr* SE = E->getSubExpr();
584 3: QualType SETy = SE->getType();
585 3: APValue Result = APValue();
586 :
587 : // Check for vector->vector bitcast and scalar->vector splat.
2: branch 2 taken
1: branch 3 taken
588 3: if (SETy->isVectorType()) {
589 2: return this->Visit(const_cast<Expr*>(SE));
0: branch 2 not taken
1: branch 3 taken
590 1: } else if (SETy->isIntegerType()) {
591 0: APSInt IntResult;
0: branch 1 not taken
0: branch 2 not taken
592 0: if (!EvaluateInteger(SE, IntResult, Info))
593 0: return APValue();
0: branch 4 not taken
0: branch 5 not taken
594 0: Result = APValue(IntResult);
1: branch 2 taken
0: branch 3 not taken
595 1: } else if (SETy->isRealFloatingType()) {
596 1: APFloat F(0.0);
0: branch 1 not taken
1: branch 2 taken
597 1: if (!EvaluateFloat(SE, F, Info))
598 0: return APValue();
1: branch 4 taken
0: branch 5 not taken
599 1: Result = APValue(F);
600 : } else
601 0: return APValue();
602 :
603 : // For casts of a scalar to ExtVector, convert the scalar to the element type
604 : // and splat it to all elements.
1: branch 3 taken
0: branch 4 not taken
605 1: if (E->getType()->isExtVectorType()) {
0: branch 2 not taken
1: branch 3 taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
1: branch 8 taken
606 1: if (EltTy->isIntegerType() && Result.isInt())
607 : Result = APValue(HandleIntToIntCast(EltTy, SETy, Result.getInt(),
608 0: Info.Ctx));
0: branch 2 not taken
1: branch 3 taken
609 1: else if (EltTy->isIntegerType())
610 : Result = APValue(HandleFloatToIntCast(EltTy, SETy, Result.getFloat(),
611 0: Info.Ctx));
1: branch 2 taken
0: branch 3 not taken
0: branch 5 not taken
1: branch 6 taken
0: branch 7 not taken
1: branch 8 taken
612 1: else if (EltTy->isRealFloatingType() && Result.isInt())
613 : Result = APValue(HandleIntToFloatCast(EltTy, SETy, Result.getInt(),
614 0: Info.Ctx));
1: branch 2 taken
0: branch 3 not taken
615 1: else if (EltTy->isRealFloatingType())
616 : Result = APValue(HandleFloatToFloatCast(EltTy, SETy, Result.getFloat(),
617 1: Info.Ctx));
618 : else
619 0: return APValue();
620 :
621 : // Splat and create vector APValue.
622 1: llvm::SmallVector<APValue, 4> Elts(NElts, Result);
623 1: return APValue(&Elts[0], Elts.size());
624 : }
625 :
626 : // For casts of a scalar to regular gcc-style vector type, bitcast the scalar
627 : // to the vector. To construct the APValue vector initializer, bitcast the
628 : // initializing value to an APInt, and shift out the bits pertaining to each
629 : // element.
630 0: APSInt Init;
0: branch 1 not taken
0: branch 2 not taken
631 0: Init = Result.isInt() ? Result.getInt() : Result.getFloat().bitcastToAPInt();
632 :
633 0: llvm::SmallVector<APValue, 4> Elts;
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
634 0: for (unsigned i = 0; i != NElts; ++i) {
635 0: APSInt Tmp = Init;
636 0: Tmp.extOrTrunc(EltWidth);
637 :
0: branch 2 not taken
0: branch 3 not taken
638 0: if (EltTy->isIntegerType())
639 0: Elts.push_back(APValue(Tmp));
0: branch 2 not taken
0: branch 3 not taken
640 0: else if (EltTy->isRealFloatingType())
641 0: Elts.push_back(APValue(APFloat(Tmp)));
642 : else
643 0: return APValue();
644 :
645 0: Init >>= EltWidth;
646 : }
647 0: return APValue(&Elts[0], Elts.size());
648 : }
649 :
650 : APValue
651 7: VectorExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
652 7: return this->Visit(const_cast<Expr*>(E->getInitializer()));
653 : }
654 :
655 : APValue
656 9: VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
657 9: const VectorType *VT = E->getType()->getAs<VectorType>();
658 9: unsigned NumInits = E->getNumInits();
659 9: unsigned NumElements = VT->getNumElements();
660 :
661 9: QualType EltTy = VT->getElementType();
662 9: llvm::SmallVector<APValue, 4> Elements;
663 :
36: branch 0 taken
9: branch 1 taken
664 45: for (unsigned i = 0; i < NumElements; i++) {
24: branch 2 taken
12: branch 3 taken
665 36: if (EltTy->isIntegerType()) {
666 24: llvm::APSInt sInt(32);
11: branch 0 taken
13: branch 1 taken
667 24: if (i < NumInits) {
0: branch 2 not taken
11: branch 3 taken
668 11: if (!EvaluateInteger(E->getInit(i), sInt, Info))
669 0: return APValue();
670 : } else {
671 13: sInt = Info.Ctx.MakeIntValue(0, EltTy);
672 : }
24: branch 4 taken
0: branch 5 not taken
673 24: Elements.push_back(APValue(sInt));
674 : } else {
675 12: llvm::APFloat f(0.0);
12: branch 0 taken
0: branch 1 not taken
676 12: if (i < NumInits) {
0: branch 2 not taken
12: branch 3 taken
677 12: if (!EvaluateFloat(E->getInit(i), f, Info))
678 0: return APValue();
679 : } else {
680 0: f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
681 : }
12: branch 4 taken
0: branch 5 not taken
682 12: Elements.push_back(APValue(f));
683 : }
684 : }
685 9: return APValue(&Elements[0], Elements.size());
686 : }
687 :
688 : APValue
689 1: VectorExprEvaluator::GetZeroVector(QualType T) {
690 1: const VectorType *VT = T->getAs<VectorType>();
691 1: QualType EltTy = VT->getElementType();
692 1: APValue ZeroElement;
1: branch 2 taken
0: branch 3 not taken
693 1: if (EltTy->isIntegerType())
694 1: ZeroElement = APValue(Info.Ctx.MakeIntValue(0, EltTy));
695 : else
696 : ZeroElement =
697 0: APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
698 :
699 1: llvm::SmallVector<APValue, 4> Elements(VT->getNumElements(), ZeroElement);
700 1: return APValue(&Elements[0], Elements.size());
701 : }
702 :
703 1: APValue VectorExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) {
704 : bool BoolResult;
0: branch 2 not taken
1: branch 3 taken
705 1: if (!HandleConversionToBool(E->getCond(), BoolResult, Info))
706 0: return APValue();
707 :
1: branch 0 taken
0: branch 1 not taken
708 1: Expr* EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr();
709 :
710 1: APValue Result;
1: branch 1 taken
0: branch 2 not taken
711 1: if (EvaluateVector(EvalExpr, Result, Info))
712 1: return Result;
713 0: return APValue();
714 : }
715 :
716 1: APValue VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
0: branch 2 not taken
1: branch 3 taken
717 1: if (!E->getSubExpr()->isEvaluatable(Info.Ctx))
718 0: Info.EvalResult.HasSideEffects = true;
719 1: return GetZeroVector(E->getType());
720 : }
721 :
722 : //===----------------------------------------------------------------------===//
723 : // Integer Evaluation
724 : //===----------------------------------------------------------------------===//
725 :
726 : namespace {
727 : class IntExprEvaluator
728 : : public StmtVisitor<IntExprEvaluator, bool> {
729 : EvalInfo &Info;
730 : APValue &Result;
731 : public:
732 26549: IntExprEvaluator(EvalInfo &info, APValue &result)
733 26549: : Info(info), Result(result) {}
734 :
735 5887: bool Success(const llvm::APSInt &SI, const Expr *E) {
5887: branch 3 taken
0: branch 4 not taken
736 5887: assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
737 : assert(SI.isSigned() == E->getType()->isSignedIntegerType() &&
5887: branch 4 taken
0: branch 5 not taken
738 5887: "Invalid evaluation result.");
739 : assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
5887: branch 3 taken
0: branch 4 not taken
740 5887: "Invalid evaluation result.");
741 5887: Result = APValue(SI);
742 5887: return true;
743 : }
744 :
745 16527: bool Success(const llvm::APInt &I, const Expr *E) {
16527: branch 3 taken
0: branch 4 not taken
746 16527: assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
747 : assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
16527: branch 3 taken
0: branch 4 not taken
748 16527: "Invalid evaluation result.");
749 16527: Result = APValue(APSInt(I));
750 16527: Result.getInt().setIsUnsigned(E->getType()->isUnsignedIntegerType());
751 16527: return true;
752 : }
753 :
754 2734: bool Success(uint64_t Value, const Expr *E) {
2734: branch 3 taken
0: branch 4 not taken
755 2734: assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
756 2734: Result = APValue(Info.Ctx.MakeIntValue(Value, E->getType()));
757 2734: return true;
758 : }
759 :
760 5029: bool Error(SourceLocation L, diag::kind D, const Expr *E) {
761 : // Take the first error.
4998: branch 0 taken
31: branch 1 taken
762 5029: if (Info.EvalResult.Diag == 0) {
763 4998: Info.EvalResult.DiagLoc = L;
764 4998: Info.EvalResult.Diag = D;
765 4998: Info.EvalResult.DiagExpr = E;
766 : }
767 5029: return false;
768 : }
769 :
770 : //===--------------------------------------------------------------------===//
771 : // Visitor Methods
772 : //===--------------------------------------------------------------------===//
773 :
774 0: bool VisitStmt(Stmt *) {
775 0: assert(0 && "This should be called on integers, stmts are not integers");
776 : return false;
777 : }
778 :
779 410: bool VisitExpr(Expr *E) {
780 410: return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
781 : }
782 :
783 1375: bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
784 :
785 16527: bool VisitIntegerLiteral(const IntegerLiteral *E) {
786 16527: return Success(E->getValue(), E);
787 : }
788 195: bool VisitCharacterLiteral(const CharacterLiteral *E) {
789 195: return Success(E->getValue(), E);
790 : }
791 12: bool VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
792 : // Per gcc docs "this built-in function ignores top level
793 : // qualifiers". We need to use the canonical version to properly
794 : // be able to strip CRV qualifiers from the type.
795 12: QualType T0 = Info.Ctx.getCanonicalType(E->getArgType1());
796 12: QualType T1 = Info.Ctx.getCanonicalType(E->getArgType2());
797 : return Success(Info.Ctx.typesAreCompatible(T0.getUnqualifiedType(),
798 : T1.getUnqualifiedType()),
799 12: E);
800 : }
801 :
802 : bool CheckReferencedDecl(const Expr *E, const Decl *D);
803 5113: bool VisitDeclRefExpr(const DeclRefExpr *E) {
804 5113: return CheckReferencedDecl(E, E->getDecl());
805 : }
806 457: bool VisitMemberExpr(const MemberExpr *E) {
5: branch 2 taken
452: branch 3 taken
807 457: if (CheckReferencedDecl(E, E->getMemberDecl())) {
808 : // Conservatively assume a MemberExpr will have side-effects
809 5: Info.EvalResult.HasSideEffects = true;
810 5: return true;
811 : }
812 452: return false;
813 : }
814 :
815 : bool VisitCallExpr(const CallExpr *E);
816 : bool VisitBinaryOperator(const BinaryOperator *E);
817 : bool VisitUnaryOperator(const UnaryOperator *E);
818 : bool VisitConditionalOperator(const ConditionalOperator *E);
819 :
820 : bool VisitCastExpr(CastExpr* E);
821 : bool VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
822 :
823 302: bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
824 302: return Success(E->getValue(), E);
825 : }
826 :
827 7: bool VisitGNUNullExpr(const GNUNullExpr *E) {
828 7: return Success(0, E);
829 : }
830 :
831 4: bool VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
832 4: return Success(0, E);
833 : }
834 :
835 6: bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
836 6: return Success(0, E);
837 : }
838 :
839 334: bool VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
840 334: return Success(E->EvaluateTrait(Info.Ctx), E);
841 : }
842 :
843 1: bool VisitChooseExpr(const ChooseExpr *E) {
844 1: return Visit(E->getChosenSubExpr(Info.Ctx));
845 : }
846 :
847 : bool VisitUnaryReal(const UnaryOperator *E);
848 : bool VisitUnaryImag(const UnaryOperator *E);
849 :
850 : private:
851 : CharUnits GetAlignOfExpr(const Expr *E);
852 : CharUnits GetAlignOfType(QualType T);
853 : // FIXME: Missing: array subscript of vector, member of vector
854 : };
855 : } // end anonymous namespace
856 :
857 4141: static bool EvaluateIntegerOrLValue(const Expr* E, APValue &Result, EvalInfo &Info) {
0: branch 3 not taken
4141: branch 4 taken
858 4141: if (!E->getType()->isIntegralType())
859 0: return false;
860 :
861 4141: return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
862 : }
863 :
864 1700: static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {
865 1700: APValue Val;
1260: branch 1 taken
440: branch 2 taken
1: branch 4 taken
1259: branch 5 taken
441: branch 6 taken
1259: branch 7 taken
866 1700: if (!EvaluateIntegerOrLValue(E, Val, Info) || !Val.isInt())
867 441: return false;
868 1259: Result = Val.getInt();
869 1259: return true;
870 : }
871 :
872 5570: bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) {
873 : // Enums are integer constant exprs.
1196: branch 1 taken
4374: branch 2 taken
874 5570: if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
875 1196: return Success(ECD->getInitVal(), E);
876 :
877 : // In C++, const, non-volatile integers initialized with ICEs are ICEs.
878 : // In C, they can also be folded, although they are not ICEs.
637: branch 3 taken
3737: branch 4 taken
879 4374: if (Info.Ctx.getCanonicalType(E->getType()).getCVRQualifiers()
880 : == Qualifiers::Const) {
881 :
15: branch 1 taken
622: branch 2 taken
882 637: if (isa<ParmVarDecl>(D))
883 15: return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
884 :
509: branch 1 taken
113: branch 2 taken
885 622: if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
496: branch 1 taken
13: branch 2 taken
886 509: if (const Expr *Init = VD->getAnyInitializer()) {
290: branch 1 taken
206: branch 2 taken
887 496: if (APValue *V = VD->getEvaluatedValue()) {
271: branch 1 taken
19: branch 2 taken
888 290: if (V->isInt())
889 271: return Success(V->getInt(), E);
890 19: return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
891 : }
892 :
2: branch 1 taken
204: branch 2 taken
893 206: if (VD->isEvaluatingValue())
894 2: return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
895 :
896 204: VD->setEvaluatingValue();
897 :
199: branch 1 taken
5: branch 2 taken
898 204: if (Visit(const_cast<Expr*>(Init))) {
899 : // Cache the evaluated value in the variable declaration.
900 199: VD->setEvaluatedValue(Result);
901 199: return true;
902 : }
903 :
904 5: VD->setEvaluatedValue(APValue());
905 5: return false;
906 : }
907 : }
908 : }
909 :
910 : // Otherwise, random variable references are not constants.
911 3863: return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
912 : }
913 :
914 : /// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way
915 : /// as GCC.
916 25: static int EvaluateBuiltinClassifyType(const CallExpr *E) {
917 : // The following enum mimics the values returned by GCC.
918 : // FIXME: Does GCC differ between lvalue and rvalue references here?
919 : enum gcc_type_class {
920 : no_type_class = -1,
921 : void_type_class, integer_type_class, char_type_class,
922 : enumeral_type_class, boolean_type_class,
923 : pointer_type_class, reference_type_class, offset_type_class,
924 : real_type_class, complex_type_class,
925 : function_type_class, method_type_class,
926 : record_type_class, union_type_class,
927 : array_type_class, string_type_class,
928 : lang_type_class
929 : };
930 :
931 : // If no argument was supplied, default to "no_type_class". This isn't
932 : // ideal, however it is what gcc does.
0: branch 1 not taken
25: branch 2 taken
933 25: if (E->getNumArgs() == 0)
934 0: return no_type_class;
935 :
936 25: QualType ArgTy = E->getArg(0)->getType();
0: branch 2 not taken
25: branch 3 taken
937 25: if (ArgTy->isVoidType())
938 0: return void_type_class;
0: branch 2 not taken
25: branch 3 taken
939 25: else if (ArgTy->isEnumeralType())
940 0: return enumeral_type_class;
0: branch 2 not taken
25: branch 3 taken
941 25: else if (ArgTy->isBooleanType())
942 0: return boolean_type_class;
0: branch 2 not taken
25: branch 3 taken
943 25: else if (ArgTy->isCharType())
944 0: return string_type_class; // gcc doesn't appear to use char_type_class
7: branch 2 taken
18: branch 3 taken
945 25: else if (ArgTy->isIntegerType())
946 7: return integer_type_class;
0: branch 2 not taken
18: branch 3 taken
947 18: else if (ArgTy->isPointerType())
948 0: return pointer_type_class;
0: branch 2 not taken
18: branch 3 taken
949 18: else if (ArgTy->isReferenceType())
950 0: return reference_type_class;
5: branch 2 taken
13: branch 3 taken
951 18: else if (ArgTy->isRealType())
952 5: return real_type_class;
8: branch 2 taken
5: branch 3 taken
953 13: else if (ArgTy->isComplexType())
954 8: return complex_type_class;
0: branch 2 not taken
5: branch 3 taken
955 5: else if (ArgTy->isFunctionType())
956 0: return function_type_class;
5: branch 2 taken
0: branch 3 not taken
957 5: else if (ArgTy->isStructureType())
958 5: return record_type_class;
0: branch 2 not taken
0: branch 3 not taken
959 0: else if (ArgTy->isUnionType())
960 0: return union_type_class;
0: branch 2 not taken
0: branch 3 not taken
961 0: else if (ArgTy->isArrayType())
962 0: return array_type_class;
0: branch 2 not taken
0: branch 3 not taken
963 0: else if (ArgTy->isUnionType())
964 0: return union_type_class;
965 : else // FIXME: offset_type_class, method_type_class, & lang_type_class?
966 0: assert(0 && "CallExpr::isBuiltinClassifyType(): unimplemented type");
967 : return -1;
968 : }
969 :
970 817: bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
701: branch 1 taken
64: branch 2 taken
25: branch 3 taken
24: branch 4 taken
3: branch 5 taken
971 817: switch (E->isBuiltinCall(Info.Ctx)) {
972 : default:
973 701: return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
974 :
975 : case Builtin::BI__builtin_object_size: {
976 64: const Expr *Arg = E->getArg(0)->IgnoreParens();
977 64: Expr::EvalResult Base;
978 :
979 : // TODO: Perhaps we should let LLVM lower this?
31: branch 1 taken
33: branch 2 taken
31: branch 4 taken
0: branch 5 not taken
31: branch 6 taken
0: branch 7 not taken
31: branch 8 taken
33: branch 9 taken
980 64: if (Arg->EvaluateAsAny(Base, Info.Ctx)
981 : && Base.Val.getKind() == APValue::LValue
982 : && !Base.HasSideEffects)
31: branch 1 taken
0: branch 2 not taken
983 31: if (const Expr *LVBase = Base.Val.getLValueBase())
31: branch 1 taken
0: branch 2 not taken
984 31: if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LVBase)) {
31: branch 2 taken
0: branch 3 not taken
985 31: if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
31: branch 3 taken
0: branch 4 not taken
31: branch 8 taken
0: branch 9 not taken
31: branch 13 taken
0: branch 14 not taken
31: branch 18 taken
0: branch 19 not taken
31: branch 20 taken
0: branch 21 not taken
986 31: if (!VD->getType()->isIncompleteType()
987 : && VD->getType()->isObjectType()
988 : && !VD->getType()->isVariablyModifiedType()
989 : && !VD->getType()->isDependentType()) {
990 31: CharUnits Size = Info.Ctx.getTypeSizeInChars(VD->getType());
991 31: CharUnits Offset = Base.Val.getLValueOffset();
28: branch 1 taken
3: branch 2 taken
25: branch 4 taken
3: branch 5 taken
25: branch 6 taken
6: branch 7 taken
992 31: if (!Offset.isNegative() && Offset <= Size)
993 25: Size -= Offset;
994 : else
995 6: Size = CharUnits::Zero();
996 31: return Success(Size.getQuantity(), E);
997 : }
998 : }
999 : }
1000 :
1001 : // If evaluating the argument has side-effects we can't determine
1002 : // the size of the object and lower it to unknown now.
28: branch 2 taken
5: branch 3 taken
1003 33: if (E->getArg(0)->HasSideEffects(Info.Ctx)) {
24: branch 4 taken
4: branch 5 taken
1004 28: if (E->getArg(1)->EvaluateAsInt(Info.Ctx).getZExtValue() <= 1)
1005 24: return Success(-1ULL, E);
1006 4: return Success(0, E);
1007 : }
1008 :
1009 5: return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
1010 : }
1011 :
1012 : case Builtin::BI__builtin_classify_type:
1013 25: return Success(EvaluateBuiltinClassifyType(E), E);
1014 :
1015 : case Builtin::BI__builtin_constant_p:
1016 : // __builtin_constant_p always has one operand: it returns true if that
1017 : // operand can be folded, false otherwise.
1018 24: return Success(E->getArg(0)->isEvaluatable(Info.Ctx), E);
1019 :
1020 : case Builtin::BI__builtin_eh_return_data_regno: {
1021 3: int Operand = E->getArg(0)->EvaluateAsInt(Info.Ctx).getZExtValue();
1022 3: Operand = Info.Ctx.Target.getEHDataRegisterNumber(Operand);
1023 3: return Success(Operand, E);
1024 : }
1025 : }
1026 : }
1027 :
1028 3751: bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
6: branch 1 taken
3745: branch 2 taken
1029 3751: if (E->getOpcode() == BinaryOperator::Comma) {
2: branch 2 taken
4: branch 3 taken
1030 6: if (!Visit(E->getRHS()))
1031 2: return false;
1032 :
1033 : // If we can't evaluate the LHS, it might have side effects;
1034 : // conservatively mark it.
3: branch 2 taken
1: branch 3 taken
1035 4: if (!E->getLHS()->isEvaluatable(Info.Ctx))
1036 3: Info.EvalResult.HasSideEffects = true;
1037 :
1038 4: return true;
1039 : }
1040 :
81: branch 1 taken
3664: branch 2 taken
1041 3745: if (E->isLogicalOp()) {
1042 : // These need to be handled specially because the operands aren't
1043 : // necessarily integral
1044 : bool lhsResult, rhsResult;
1045 :
11: branch 2 taken
70: branch 3 taken
1046 81: if (HandleConversionToBool(E->getLHS(), lhsResult, Info)) {
1047 : // We were able to evaluate the LHS, see if we can get away with not
1048 : // evaluating the RHS: 0 && X -> 0, 1 || X -> 1
10: branch 1 taken
1: branch 2 taken
1049 11: if (lhsResult == (E->getOpcode() == BinaryOperator::LOr))
1050 10: return Success(lhsResult, E);
1051 :
1: branch 2 taken
0: branch 3 not taken
1052 1: if (HandleConversionToBool(E->getRHS(), rhsResult, Info)) {
0: branch 1 not taken
1: branch 2 taken
1053 1: if (E->getOpcode() == BinaryOperator::LOr)
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
1054 0: return Success(lhsResult || rhsResult, E);
1055 : else
1: branch 0 taken
0: branch 1 not taken
1: branch 2 taken
0: branch 3 not taken
1056 1: return Success(lhsResult && rhsResult, E);
1057 : }
1058 : } else {
11: branch 2 taken
59: branch 3 taken
1059 70: if (HandleConversionToBool(E->getRHS(), rhsResult, Info)) {
1060 : // We can't evaluate the LHS; however, sometimes the result
1061 : // is determined by the RHS: X && 0 -> 0, X || 1 -> 1.
2: branch 1 taken
9: branch 2 taken
0: branch 4 not taken
2: branch 5 taken
9: branch 6 taken
2: branch 7 taken
1062 11: if (rhsResult == (E->getOpcode() == BinaryOperator::LOr) ||
1063 : !rhsResult == (E->getOpcode() == BinaryOperator::LAnd)) {
1064 : // Since we weren't able to evaluate the left hand side, it
1065 : // must have had side effects.
1066 9: Info.EvalResult.HasSideEffects = true;
1067 :
1068 9: return Success(rhsResult, E);
1069 : }
1070 : }
1071 : }
1072 :
1073 61: return false;
1074 : }
1075 :
1076 3664: QualType LHSTy = E->getLHS()->getType();
1077 3664: QualType RHSTy = E->getRHS()->getType();
1078 :
10: branch 2 taken
3654: branch 3 taken
1079 3664: if (LHSTy->isAnyComplexType()) {
10: branch 2 taken
0: branch 3 not taken
1080 10: assert(RHSTy->isAnyComplexType() && "Invalid comparison");
1081 10: APValue LHS, RHS;
1082 :
0: branch 2 not taken
10: branch 3 taken
1083 10: if (!EvaluateComplex(E->getLHS(), LHS, Info))
1084 0: return false;
1085 :
0: branch 2 not taken
10: branch 3 taken
1086 10: if (!EvaluateComplex(E->getRHS(), RHS, Info))
1087 0: return false;
1088 :
4: branch 1 taken
6: branch 2 taken
1089 10: if (LHS.isComplexFloat()) {
1090 : APFloat::cmpResult CR_r =
1091 4: LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
1092 : APFloat::cmpResult CR_i =
1093 4: LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
1094 :
2: branch 1 taken
2: branch 2 taken
1095 4: if (E->getOpcode() == BinaryOperator::EQ)
1096 : return Success((CR_r == APFloat::cmpEqual &&
2: branch 0 taken
0: branch 1 not taken
2: branch 2 taken
0: branch 3 not taken
1097 2: CR_i == APFloat::cmpEqual), E);
1098 : else {
1099 : assert(E->getOpcode() == BinaryOperator::NE &&
2: branch 1 taken
0: branch 2 not taken
1100 2: "Invalid complex comparison.");
1101 : return Success(((CR_r == APFloat::cmpGreaterThan ||
1102 : CR_r == APFloat::cmpLessThan) &&
1103 : (CR_i == APFloat::cmpGreaterThan ||
2: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
2: branch 3 taken
2: branch 4 taken
2: branch 5 taken
2: branch 6 taken
2: branch 7 taken
1104 4: CR_i == APFloat::cmpLessThan)), E);
1105 : }
1106 : } else {
4: branch 1 taken
2: branch 2 taken
1107 6: if (E->getOpcode() == BinaryOperator::EQ)
1108 : return Success((LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
2: branch 3 taken
2: branch 4 taken
2: branch 8 taken
0: branch 9 not taken
1109 4: LHS.getComplexIntImag() == RHS.getComplexIntImag()), E);
1110 : else {
1111 : assert(E->getOpcode() == BinaryOperator::NE &&
2: branch 1 taken
0: branch 2 not taken
1112 2: "Invalid compex comparison.");
1113 : return Success((LHS.getComplexIntReal() != RHS.getComplexIntReal() ||
2: branch 3 taken
0: branch 4 not taken
0: branch 8 not taken
2: branch 9 taken
1114 4: LHS.getComplexIntImag() != RHS.getComplexIntImag()), E);
1115 : }
1116 10: }
1117 : }
1118 :
6: branch 2 taken
3648: branch 3 taken
6: branch 6 taken
0: branch 7 not taken
6: branch 8 taken
3648: branch 9 taken
1119 3654: if (LHSTy->isRealFloatingType() &&
1120 : RHSTy->isRealFloatingType()) {
1121 6: APFloat RHS(0.0), LHS(0.0);
1122 :
0: branch 2 not taken
6: branch 3 taken
1123 6: if (!EvaluateFloat(E->getRHS(), RHS, Info))
1124 0: return false;
1125 :
0: branch 2 not taken
6: branch 3 taken
1126 6: if (!EvaluateFloat(E->getLHS(), LHS, Info))
1127 0: return false;
1128 :
1129 6: APFloat::cmpResult CR = LHS.compare(RHS);
1130 :
0: branch 1 not taken
1: branch 2 taken
0: branch 3 not taken
4: branch 4 taken
0: branch 5 not taken
1: branch 6 taken
0: branch 7 not taken
1131 6: switch (E->getOpcode()) {
1132 : default:
1133 0: assert(0 && "Invalid binary operator!");
1134 : case BinaryOperator::LT:
1135 1: return Success(CR == APFloat::cmpLessThan, E);
1136 : case BinaryOperator::GT:
1137 0: return Success(CR == APFloat::cmpGreaterThan, E);
1138 : case BinaryOperator::LE:
0: branch 0 not taken
4: branch 1 taken
4: branch 2 taken
4: branch 3 taken
1139 4: return Success(CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual, E);
1140 : case BinaryOperator::GE:
1141 : return Success(CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual,
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
1142 0: E);
1143 : case BinaryOperator::EQ:
1144 1: return Success(CR == APFloat::cmpEqual, E);
1145 : case BinaryOperator::NE:
1146 : return Success(CR == APFloat::cmpGreaterThan
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
1147 0: || CR == APFloat::cmpLessThan, E);
1148 6: }
1149 : }
1150 :
284: branch 2 taken
3364: branch 3 taken
284: branch 6 taken
0: branch 7 not taken
284: branch 8 taken
3364: branch 9 taken
1151 3648: if (LHSTy->isPointerType() && RHSTy->isPointerType()) {
260: branch 1 taken
24: branch 2 taken
251: branch 4 taken
9: branch 5 taken
275: branch 6 taken
9: branch 7 taken
1152 284: if (E->getOpcode() == BinaryOperator::Sub || E->isEqualityOp()) {
1153 275: APValue LHSValue;
171: branch 2 taken
104: branch 3 taken
1154 275: if (!EvaluatePointer(E->getLHS(), LHSValue, Info))
1155 171: return false;
1156 :
1157 104: APValue RHSValue;
96: branch 2 taken
8: branch 3 taken
1158 104: if (!EvaluatePointer(E->getRHS(), RHSValue, Info))
1159 96: return false;
1160 :
1161 : // Reject any bases from the normal codepath; we special-case comparisons
1162 : // to null.
3: branch 1 taken
5: branch 2 taken
1163 8: if (LHSValue.getLValueBase()) {
2: branch 1 taken
1: branch 2 taken
1164 3: if (!E->isEqualityOp())
1165 2: return false;
1: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
1: branch 6 taken
0: branch 7 not taken
1: branch 8 taken
1166 1: if (RHSValue.getLValueBase() || !RHSValue.getLValueOffset().isZero())
1167 0: return false;
1168 : bool bres;
0: branch 1 not taken
1: branch 2 taken
1169 1: if (!EvalPointerValueAsBool(LHSValue, bres))
1170 0: return false;
1171 1: return Success(bres ^ (E->getOpcode() == BinaryOperator::EQ), E);
0: branch 1 not taken
5: branch 2 taken
1172 5: } else if (RHSValue.getLValueBase()) {
0: branch 1 not taken
0: branch 2 not taken
1173 0: if (!E->isEqualityOp())
1174 0: return false;
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
0: branch 8 not taken
1175 0: if (LHSValue.getLValueBase() || !LHSValue.getLValueOffset().isZero())
1176 0: return false;
1177 : bool bres;
0: branch 1 not taken
0: branch 2 not taken
1178 0: if (!EvalPointerValueAsBool(RHSValue, bres))
1179 0: return false;
1180 0: return Success(bres ^ (E->getOpcode() == BinaryOperator::EQ), E);
1181 : }
1182 :
3: branch 1 taken
2: branch 2 taken
1183 5: if (E->getOpcode() == BinaryOperator::Sub) {
1184 3: const QualType Type = E->getLHS()->getType();
1185 3: const QualType ElementType = Type->getAs<PointerType>()->getPointeeType();
1186 :
1187 3: CharUnits ElementSize = CharUnits::One();
2: branch 2 taken
1: branch 3 taken
2: branch 6 taken
0: branch 7 not taken
2: branch 8 taken
1: branch 9 taken
1188 3: if (!ElementType->isVoidType() && !ElementType->isFunctionType())
1189 2: ElementSize = Info.Ctx.getTypeSizeInChars(ElementType);
1190 :
1191 : CharUnits Diff = LHSValue.getLValueOffset() -
1192 3: RHSValue.getLValueOffset();
1193 3: return Success(Diff / ElementSize, E);
1194 : }
1195 : bool Result;
1: branch 1 taken
1: branch 2 taken
1196 2: if (E->getOpcode() == BinaryOperator::EQ) {
1197 1: Result = LHSValue.getLValueOffset() == RHSValue.getLValueOffset();
1198 : } else {
1199 1: Result = LHSValue.getLValueOffset() != RHSValue.getLValueOffset();
1200 : }
1201 2: return Success(Result, E);
1202 : }
1203 : }
3257: branch 2 taken
116: branch 3 taken
0: branch 6 not taken
3257: branch 7 taken
116: branch 8 taken
3257: branch 9 taken
1204 3373: if (!LHSTy->isIntegralType() ||
1205 : !RHSTy->isIntegralType()) {
1206 : // We can't continue from here for non-integral types, and they
1207 : // could potentially confuse the following operations.
1208 116: return false;
1209 : }
1210 :
1211 : // The LHS of a constant expr is always evaluated and needed.
1017: branch 2 taken
2240: branch 3 taken
1212 3257: if (!Visit(E->getLHS()))
1213 1017: return false; // error in subexpression.
1214 :
1215 2240: APValue RHSVal;
104: branch 2 taken
2136: branch 3 taken
1216 2240: if (!EvaluateIntegerOrLValue(E->getRHS(), RHSVal, Info))
1217 104: return false;
1218 :
1219 : // Handle cases like (unsigned long)&a + 4.
936: branch 1 taken
1200: branch 2 taken
2: branch 4 taken
934: branch 5 taken
2: branch 7 taken
0: branch 8 not taken
2: branch 9 taken
2134: branch 10 taken
1220 2136: if (E->isAdditiveOp() && Result.isLValue() && RHSVal.isInt()) {
1221 2: CharUnits Offset = Result.getLValueOffset();
1222 : CharUnits AdditionalOffset = CharUnits::fromQuantity(
1223 2: RHSVal.getInt().getZExtValue());
1: branch 1 taken
1: branch 2 taken
1224 2: if (E->getOpcode() == BinaryOperator::Add)
1225 1: Offset += AdditionalOffset;
1226 : else
1227 1: Offset -= AdditionalOffset;
1228 2: Result = APValue(Result.getLValueBase(), Offset);
1229 2: return true;
1230 : }
1231 :
1232 : // Handle cases like 4 + (unsigned long)&a
435: branch 1 taken
1699: branch 2 taken
1: branch 4 taken
434: branch 5 taken
1: branch 7 taken
0: branch 8 not taken
1: branch 9 taken
2133: branch 10 taken
1233 2134: if (E->getOpcode() == BinaryOperator::Add &&
1234 : RHSVal.isLValue() && Result.isInt()) {
1235 1: CharUnits Offset = RHSVal.getLValueOffset();
1236 1: Offset += CharUnits::fromQuantity(Result.getInt().getZExtValue());
1237 1: Result = APValue(RHSVal.getLValueBase(), Offset);
1238 1: return true;
1239 : }
1240 :
1241 : // All the following cases expect both operands to be an integer
2133: branch 1 taken
0: branch 2 not taken
0: branch 4 not taken
2133: branch 5 taken
0: branch 6 not taken
2133: branch 7 taken
1242 2133: if (!Result.isInt() || !RHSVal.isInt())
1243 0: return false;
1244 :
1245 2133: APSInt& RHS = RHSVal.getInt();
1246 :
0: branch 1 not taken
104: branch 2 taken
434: branch 3 taken
499: branch 4 taken
147: branch 5 taken
7: branch 6 taken
170: branch 7 taken
59: branch 8 taken
4: branch 9 taken
245: branch 10 taken
8: branch 11 taken
18: branch 12 taken
13: branch 13 taken
11: branch 14 taken
7: branch 15 taken
382: branch 16 taken
25: branch 17 taken
1247 2133: switch (E->getOpcode()) {
1248 : default:
1249 0: return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E);
1250 104: case BinaryOperator::Mul: return Success(Result.getInt() * RHS, E);
1251 434: case BinaryOperator::Add: return Success(Result.getInt() + RHS, E);
1252 499: case BinaryOperator::Sub: return Success(Result.getInt() - RHS, E);
1253 147: case BinaryOperator::And: return Success(Result.getInt() & RHS, E);
1254 7: case BinaryOperator::Xor: return Success(Result.getInt() ^ RHS, E);
1255 170: case BinaryOperator::Or: return Success(Result.getInt() | RHS, E);
1256 : case BinaryOperator::Div:
2: branch 1 taken
57: branch 2 taken
1257 59: if (RHS == 0)
1258 2: return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E);
1259 57: return Success(Result.getInt() / RHS, E);
1260 : case BinaryOperator::Rem:
0: branch 1 not taken
4: branch 2 taken
1261 4: if (RHS == 0)
1262 0: return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E);
1263 4: return Success(Result.getInt() % RHS, E);
1264 : case BinaryOperator::Shl: {
1265 : // FIXME: Warn about out of range shift amounts!
1266 : unsigned SA =
1267 245: (unsigned) RHS.getLimitedValue(Result.getInt().getBitWidth()-1);
1268 245: return Success(Result.getInt() << SA, E);
1269 : }
1270 : case BinaryOperator::Shr: {
1271 : unsigned SA =
1272 8: (unsigned) RHS.getLimitedValue(Result.getInt().getBitWidth()-1);
1273 8: return Success(Result.getInt() >> SA, E);
1274 : }
1275 :
1276 18: case BinaryOperator::LT: return Success(Result.getInt() < RHS, E);
1277 13: case BinaryOperator::GT: return Success(Result.getInt() > RHS, E);
1278 11: case BinaryOperator::LE: return Success(Result.getInt() <= RHS, E);
1279 7: case BinaryOperator::GE: return Success(Result.getInt() >= RHS, E);
1280 382: case BinaryOperator::EQ: return Success(Result.getInt() == RHS, E);
1281 25: case BinaryOperator::NE: return Success(Result.getInt() != RHS, E);
1282 2240: }
1283 : }
1284 :
1285 861: bool IntExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) {
1286 : bool Cond;
11: branch 2 taken
850: branch 3 taken
1287 861: if (!HandleConversionToBool(E->getCond(), Cond, Info))
1288 11: return false;
1289 :
638: branch 0 taken
212: branch 1 taken
1290 850: return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr());
1291 : }
1292 :
1293 63: CharUnits IntExprEvaluator::GetAlignOfType(QualType T) {
1294 : // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
1295 : // the result is the size of the referenced type."
1296 : // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
1297 : // result shall be the alignment of the referenced type."
0: branch 2 not taken
63: branch 3 taken
1298 63: if (const ReferenceType *Ref = T->getAs<ReferenceType>())
1299 0: T = Ref->getPointeeType();
1300 :
1301 : // Get information about the alignment.
1302 63: unsigned CharSize = Info.Ctx.Target.getCharWidth();
1303 :
1304 : // __alignof is defined to return the preferred alignment.
1305 : return CharUnits::fromQuantity(
1306 63: Info.Ctx.getPreferredTypeAlign(T.getTypePtr()) / CharSize);
1307 : }
1308 :
1309 31: CharUnits IntExprEvaluator::GetAlignOfExpr(const Expr *E) {
1310 31: E = E->IgnoreParens();
1311 :
1312 : // alignof decl is always accepted, even if it doesn't make sense: we default
1313 : // to 1 in those cases.
28: branch 1 taken
3: branch 2 taken
1314 31: if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
1315 : return Info.Ctx.getDeclAlign(DRE->getDecl(),
1316 28: /*RefAsPointee*/true);
1317 :
1: branch 1 taken
2: branch 2 taken
1318 3: if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
1319 : return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
1320 1: /*RefAsPointee*/true);
1321 :
1322 2: return GetAlignOfType(E->getType());
1323 : }
1324 :
1325 :
1326 : /// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the
1327 : /// expression's type.
1328 881: bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
1329 : // Handle alignof separately.
92: branch 1 taken
789: branch 2 taken
1330 881: if (!E->isSizeOf()) {
61: branch 1 taken
31: branch 2 taken
1331 92: if (E->isArgumentType())
1332 61: return Success(GetAlignOfType(E->getArgumentType()).getQuantity(), E);
1333 : else
1334 31: return Success(GetAlignOfExpr(E->getArgumentExpr()).getQuantity(), E);
1335 : }
1336 :
1337 789: QualType SrcTy = E->getTypeOfArgument();
1338 : // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
1339 : // the result is the size of the referenced type."
1340 : // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
1341 : // result shall be the alignment of the referenced type."
0: branch 2 not taken
789: branch 3 taken
1342 789: if (const ReferenceType *Ref = SrcTy->getAs<ReferenceType>())
1343 0: SrcTy = Ref->getPointeeType();
1344 :
1345 : // sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc
1346 : // extension.
750: branch 2 taken
39: branch 3 taken
12: branch 6 taken
738: branch 7 taken
51: branch 8 taken
738: branch 9 taken
1347 789: if (SrcTy->isVoidType() || SrcTy->isFunctionType())
1348 51: return Success(1, E);
1349 :
1350 : // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
30: branch 2 taken
708: branch 3 taken
1351 738: if (!SrcTy->isConstantSizeType())
1352 30: return false;
1353 :
1354 : // Get information about the size.
1355 708: return Success(Info.Ctx.getTypeSizeInChars(SrcTy).getQuantity(), E);
1356 : }
1357 :
1358 1055: bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
1359 : // Special case unary operators that do not need their subexpression
1360 : // evaluated. offsetof/sizeof/alignof are all special.
250: branch 1 taken
805: branch 2 taken
1361 1055: if (E->isOffsetOfOp()) {
1362 : // The AST for offsetof is defined in such a way that we can just
1363 : // directly Evaluate it as an l-value.
1364 250: APValue LV;
3: branch 2 taken
247: branch 3 taken
1365 250: if (!EvaluateLValue(E->getSubExpr(), LV, Info))
1366 3: return false;
0: branch 1 not taken
247: branch 2 taken
1367 247: if (LV.getLValueBase())
1368 0: return false;
1369 247: return Success(LV.getLValueOffset().getQuantity(), E);
1370 : }
1371 :
455: branch 1 taken
350: branch 2 taken
1372 805: if (E->getOpcode() == UnaryOperator::LNot) {
1373 : // LNot's operand isn't necessarily an integer, so we handle it specially.
1374 : bool bres;
430: branch 2 taken
25: branch 3 taken
1375 455: if (!HandleConversionToBool(E->getSubExpr(), bres, Info))
1376 430: return false;
1377 25: return Success(!bres, E);
1378 : }
1379 :
1380 : // Only handle integral operations...
123: branch 4 taken
227: branch 5 taken
1381 350: if (!E->getSubExpr()->getType()->isIntegralType())
1382 123: return false;
1383 :
1384 : // Get the operand value into 'Result'.
17: branch 2 taken
210: branch 3 taken
1385 227: if (!Visit(E->getSubExpr()))
1386 17: return false;
1387 :
0: branch 1 not taken
0: branch 2 not taken
4: branch 3 taken
190: branch 4 taken
16: branch 5 taken
1388 210: switch (E->getOpcode()) {
1389 : default:
1390 : // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
1391 : // See C99 6.6p3.
1392 0: return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E);
1393 : case UnaryOperator::Extension:
1394 : // FIXME: Should extension allow i-c-e extension expressions in its scope?
1395 : // If so, we could clear the diagnostic ID.
1396 0: return true;
1397 : case UnaryOperator::Plus:
1398 : // The result is always just the subexpr.
1399 4: return true;
1400 : case UnaryOperator::Minus:
0: branch 1 not taken
190: branch 2 taken
1401 190: if (!Result.isInt()) return false;
1402 190: return Success(-Result.getInt(), E);
1403 : case UnaryOperator::Not:
0: branch 1 not taken
16: branch 2 taken
1404 16: if (!Result.isInt()) return false;
1405 16: return Success(~Result.getInt(), E);
1406 : }
1407 : }
1408 :
1409 : /// HandleCast - This is used to evaluate implicit or explicit casts where the
1410 : /// result type is integer.
1411 4035: bool IntExprEvaluator::VisitCastExpr(CastExpr *E) {
1412 4035: Expr *SubExpr = E->getSubExpr();
1413 4035: QualType DestType = E->getType();
1414 4035: QualType SrcType = SubExpr->getType();
1415 :
196: branch 2 taken
3839: branch 3 taken
1416 4035: if (DestType->isBooleanType()) {
1417 : bool BoolResult;
59: branch 1 taken
137: branch 2 taken
1418 196: if (!HandleConversionToBool(SubExpr, BoolResult, Info))
1419 59: return false;
1420 137: return Success(BoolResult, E);
1421 : }
1422 :
1423 : // Handle simple integer->integer casts.
3681: branch 2 taken
158: branch 3 taken
1424 3839: if (SrcType->isIntegralType()) {
1230: branch 1 taken
2451: branch 2 taken
1425 3681: if (!Visit(SubExpr))
1426 1230: return false;
1427 :
1: branch 1 taken
2450: branch 2 taken
1428 2451: if (!Result.isInt()) {
1429 : // Only allow casts of lvalues if they are lossless.
1430 1: return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
1431 : }
1432 :
1433 : return Success(HandleIntToIntCast(DestType, SrcType,
1434 2450: Result.getInt(), Info.Ctx), E);
1435 : }
1436 :
1437 : // FIXME: Clean this up!
90: branch 2 taken
68: branch 3 taken
1438 158: if (SrcType->isPointerType()) {
1439 90: APValue LV;
18: branch 1 taken
72: branch 2 taken
1440 90: if (!EvaluatePointer(SubExpr, LV, Info))
1441 18: return false;
1442 :
41: branch 1 taken
31: branch 2 taken
1443 72: if (LV.getLValueBase()) {
1444 : // Only allow based lvalue casts if they are lossless.
4: branch 2 taken
37: branch 3 taken
1445 41: if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
1446 4: return false;
1447 :
1448 37: Result = LV;
1449 37: return true;
1450 : }
1451 :
1452 : APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset().getQuantity(),
1453 31: SrcType);
1454 31: return Success(HandleIntToIntCast(DestType, SrcType, AsInt, Info.Ctx), E);
1455 : }
1456 :
68: branch 2 taken
0: branch 3 not taken
0: branch 6 not taken
68: branch 7 taken
0: branch 8 not taken
68: branch 9 taken
1457 68: if (SrcType->isArrayType() || SrcType->isFunctionType()) {
1458 : // This handles double-conversion cases, where there's both
1459 : // an l-value promotion and an implicit conversion to int.
1460 0: APValue LV;
0: branch 1 not taken
0: branch 2 not taken
1461 0: if (!EvaluateLValue(SubExpr, LV, Info))
1462 0: return false;
1463 :
0: branch 3 not taken
0: branch 4 not taken
1464 0: if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(Info.Ctx.VoidPtrTy))
1465 0: return false;
1466 :
1467 0: Result = LV;
1468 0: return true;
1469 : }
1470 :
1: branch 2 taken
67: branch 3 taken
1471 68: if (SrcType->isAnyComplexType()) {
1472 1: APValue C;
0: branch 1 not taken
1: branch 2 taken
1473 1: if (!EvaluateComplex(SubExpr, C, Info))
1474 0: return false;
1: branch 1 taken
0: branch 2 not taken
1475 1: if (C.isComplexFloat())
1476 : return Success(HandleFloatToIntCast(DestType, SrcType,
1477 : C.getComplexFloatReal(), Info.Ctx),
1478 1: E);
1479 : else
1480 : return Success(HandleIntToIntCast(DestType, SrcType,
1481 0: C.getComplexIntReal(), Info.Ctx), E);
1482 : }
1483 : // FIXME: Handle vectors
1484 :
9: branch 2 taken
58: branch 3 taken
1485 67: if (!SrcType->isRealFloatingType())
1486 9: return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
1487 :
1488 58: APFloat F(0.0);
3: branch 1 taken
55: branch 2 taken
1489 58: if (!EvaluateFloat(SubExpr, F, Info))
1490 3: return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
1491 :
1492 55: return Success(HandleFloatToIntCast(DestType, SrcType, F, Info.Ctx), E);
1493 : }
1494 :
1495 6: bool IntExprEvaluator::VisitUnaryReal(const UnaryOperator *E) {
1: branch 4 taken
5: branch 5 taken
1496 6: if (E->getSubExpr()->getType()->isAnyComplexType()) {
1497 1: APValue LV;
1: branch 2 taken
0: branch 3 not taken
0: branch 5 not taken
1: branch 6 taken
0: branch 7 not taken
1: branch 8 taken
1498 1: if (!EvaluateComplex(E->getSubExpr(), LV, Info) || !LV.isComplexInt())
1499 0: return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
1500 1: return Success(LV.getComplexIntReal(), E);
1501 : }
1502 :
1503 5: return Visit(E->getSubExpr());
1504 : }
1505 :
1506 6: bool IntExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
1: branch 4 taken
5: branch 5 taken
1507 6: if (E->getSubExpr()->getType()->isComplexIntegerType()) {
1508 1: APValue LV;
1: branch 2 taken
0: branch 3 not taken
0: branch 5 not taken
1: branch 6 taken
0: branch 7 not taken
1: branch 8 taken
1509 1: if (!EvaluateComplex(E->getSubExpr(), LV, Info) || !LV.isComplexInt())
1510 0: return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
1511 1: return Success(LV.getComplexIntImag(), E);
1512 : }
1513 :
4: branch 2 taken
1: branch 3 taken
1514 5: if (!E->getSubExpr()->isEvaluatable(Info.Ctx))
1515 4: Info.EvalResult.HasSideEffects = true;
1516 5: return Success(0, E);
1517 : }
1518 :
1519 : //===----------------------------------------------------------------------===//
1520 : // Float Evaluation
1521 : //===----------------------------------------------------------------------===//
1522 :
1523 : namespace {
1524 : class FloatExprEvaluator
1525 : : public StmtVisitor<FloatExprEvaluator, bool> {
1526 : EvalInfo &Info;
1527 : APFloat &Result;
1528 : public:
1529 872: FloatExprEvaluator(EvalInfo &info, APFloat &result)
1530 872: : Info(info), Result(result) {}
1531 :
1532 207: bool VisitStmt(Stmt *S) {
1533 207: return false;
1534 : }
1535 :
1536 28: bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
1537 : bool VisitCallExpr(const CallExpr *E);
1538 :
1539 : bool VisitUnaryOperator(const UnaryOperator *E);
1540 : bool VisitBinaryOperator(const BinaryOperator *E);
1541 : bool VisitFloatingLiteral(const FloatingLiteral *E);
1542 : bool VisitCastExpr(CastExpr *E);
1543 : bool VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
1544 : bool VisitConditionalOperator(ConditionalOperator *E);
1545 :
1546 0: bool VisitChooseExpr(const ChooseExpr *E)
1547 0: { return Visit(E->getChosenSubExpr(Info.Ctx)); }
1548 0: bool VisitUnaryExtension(const UnaryOperator *E)
1549 0: { return Visit(E->getSubExpr()); }
1550 :
1551 : // FIXME: Missing: __real__/__imag__, array subscript of vector,
1552 : // member of vector, ImplicitValueInitExpr
1553 : };
1554 : } // end anonymous namespace
1555 :
1556 872: static bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) {
1557 872: return FloatExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
1558 : }
1559 :
1560 84: bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
19: branch 1 taken
26: branch 2 taken
31: branch 3 taken
4: branch 4 taken
4: branch 5 taken
1561 84: switch (E->isBuiltinCall(Info.Ctx)) {
1562 19: default: return false;
1563 : case Builtin::BI__builtin_huge_val:
1564 : case Builtin::BI__builtin_huge_valf:
1565 : case Builtin::BI__builtin_huge_vall:
1566 : case Builtin::BI__builtin_inf:
1567 : case Builtin::BI__builtin_inff:
1568 : case Builtin::BI__builtin_infl: {
1569 : const llvm::fltSemantics &Sem =
1570 26: Info.Ctx.getFloatTypeSemantics(E->getType());
1571 26: Result = llvm::APFloat::getInf(Sem);
1572 26: return true;
1573 : }
1574 :
1575 : case Builtin::BI__builtin_nan:
1576 : case Builtin::BI__builtin_nanf:
1577 : case Builtin::BI__builtin_nanl:
1578 : // If this is __builtin_nan() turn this into a nan, otherwise we
1579 : // can't constant fold it.
31: branch 0 taken
0: branch 1 not taken
1580 31: if (const StringLiteral *S =
1581 31: dyn_cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts())) {
31: branch 1 taken
0: branch 2 not taken
1582 31: if (!S->isWide()) {
1583 : const llvm::fltSemantics &Sem =
1584 31: Info.Ctx.getFloatTypeSemantics(E->getType());
1585 31: unsigned Type = 0;
22: branch 2 taken
9: branch 3 taken
0: branch 6 not taken
22: branch 7 taken
0: branch 8 not taken
31: branch 9 taken
1586 31: if (!S->getString().empty() && S->getString().getAsInteger(0, Type))
1587 0: return false;
1588 31: Result = llvm::APFloat::getNaN(Sem, false, Type);
1589 31: return true;
1590 : }
1591 : }
1592 0: return false;
1593 :
1594 : case Builtin::BI__builtin_fabs:
1595 : case Builtin::BI__builtin_fabsf:
1596 : case Builtin::BI__builtin_fabsl:
0: branch 2 not taken
4: branch 3 taken
1597 4: if (!EvaluateFloat(E->getArg(0), Result, Info))
1598 0: return false;
1599 :
4: branch 1 taken
0: branch 2 not taken
1600 4: if (Result.isNegative())
1601 4: Result.changeSign();
1602 4: return true;
1603 :
1604 : case Builtin::BI__builtin_copysign:
1605 : case Builtin::BI__builtin_copysignf:
1606 : case Builtin::BI__builtin_copysignl: {
1607 4: APFloat RHS(0.);
4: branch 2 taken
0: branch 3 not taken
0: branch 6 not taken
4: branch 7 taken
0: branch 8 not taken
4: branch 9 taken
1608 4: if (!EvaluateFloat(E->getArg(0), Result, Info) ||
1609 : !EvaluateFloat(E->getArg(1), RHS, Info))
1610 0: return false;
1611 4: Result.copySign(RHS);
1612 4: return true;
1613 : }
1614 : }
1615 : }
1616 :
1617 23: bool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
1: branch 1 taken
22: branch 2 taken
1618 23: if (E->getOpcode() == UnaryOperator::Deref)
1619 1: return false;
1620 :
0: branch 2 not taken
22: branch 3 taken
1621 22: if (!EvaluateFloat(E->getSubExpr(), Result, Info))
1622 0: return false;
1623 :
0: branch 1 not taken
0: branch 2 not taken
22: branch 3 taken
1624 22: switch (E->getOpcode()) {
1625 0: default: return false;
1626 : case UnaryOperator::Plus:
1627 0: return true;
1628 : case UnaryOperator::Minus:
1629 22: Result.changeSign();
1630 22: return true;
1631 : }
1632 : }
1633 :
1634 34: bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
1: branch 1 taken
33: branch 2 taken
1635 34: if (E->getOpcode() == BinaryOperator::Comma) {
0: branch 2 not taken
1: branch 3 taken
1636 1: if (!EvaluateFloat(E->getRHS(), Result, Info))
1637 0: return false;
1638 :
1639 : // If we can't evaluate the LHS, it might have side effects;
1640 : // conservatively mark it.
0: branch 2 not taken
1: branch 3 taken
1641 1: if (!E->getLHS()->isEvaluatable(Info.Ctx))
1642 0: Info.EvalResult.HasSideEffects = true;
1643 :
1644 1: return true;
1645 : }
1646 :
1647 : // FIXME: Diagnostics? I really don't understand how the warnings
1648 : // and errors are supposed to work.
1649 33: APFloat RHS(0.0);
8: branch 2 taken
25: branch 3 taken
1650 33: if (!EvaluateFloat(E->getLHS(), Result, Info))
1651 8: return false;
3: branch 2 taken
22: branch 3 taken
1652 25: if (!EvaluateFloat(E->getRHS(), RHS, Info))
1653 3: return false;
1654 :
0: branch 1 not taken
3: branch 2 taken
15: branch 3 taken
1: branch 4 taken
3: branch 5 taken
1655 22: switch (E->getOpcode()) {
1656 0: default: return false;
1657 : case BinaryOperator::Mul:
1658 3: Result.multiply(RHS, APFloat::rmNearestTiesToEven);
1659 3: return true;
1660 : case BinaryOperator::Add:
1661 15: Result.add(RHS, APFloat::rmNearestTiesToEven);
1662 15: return true;
1663 : case BinaryOperator::Sub:
1664 1: Result.subtract(RHS, APFloat::rmNearestTiesToEven);
1665 1: return true;
1666 : case BinaryOperator::Div:
1667 3: Result.divide(RHS, APFloat::rmNearestTiesToEven);
1668 3: return true;
1669 33: }
1670 : }
1671 :
1672 447: bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) {
1673 447: Result = E->getValue();
1674 447: return true;
1675 : }
1676 :
1677 197: bool FloatExprEvaluator::VisitCastExpr(CastExpr *E) {
1678 197: Expr* SubExpr = E->getSubExpr();
1679 :
76: branch 3 taken
121: branch 4 taken
1680 197: if (SubExpr->getType()->isIntegralType()) {
1681 76: APSInt IntResult;
3: branch 1 taken
73: branch 2 taken
1682 76: if (!EvaluateInteger(SubExpr, IntResult, Info))
1683 3: return false;
1684 : Result = HandleIntToFloatCast(E->getType(), SubExpr->getType(),
1685 73: IntResult, Info.Ctx);
1686 73: return true;
1687 : }
121: branch 3 taken
0: branch 4 not taken
1688 121: if (SubExpr->getType()->isRealFloatingType()) {
9: branch 1 taken
112: branch 2 taken
1689 121: if (!Visit(SubExpr))
1690 9: return false;
1691 : Result = HandleFloatToFloatCast(E->getType(), SubExpr->getType(),
1692 112: Result, Info.Ctx);
1693 112: return true;
1694 : }
1695 : // FIXME: Handle complex types
1696 :
1697 0: return false;
1698 : }
1699 :
1700 1: bool FloatExprEvaluator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
1701 1: Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->getType()));
1702 1: return true;
1703 : }
1704 :
1705 1: bool FloatExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) {
1706 : bool Cond;
0: branch 2 not taken
1: branch 3 taken
1707 1: if (!HandleConversionToBool(E->getCond(), Cond, Info))
1708 0: return false;
1709 :
0: branch 0 not taken
1: branch 1 taken
1710 1: return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr());
1711 : }
1712 :
1713 : //===----------------------------------------------------------------------===//
1714 : // Complex Evaluation (for float and integer)
1715 : //===----------------------------------------------------------------------===//
1716 :
1717 : namespace {
1718 : class ComplexExprEvaluator
1719 : : public StmtVisitor<ComplexExprEvaluator, APValue> {
1720 : EvalInfo &Info;
1721 :
1722 : public:
1723 255: ComplexExprEvaluator(EvalInfo &info) : Info(info) {}
1724 :
1725 : //===--------------------------------------------------------------------===//
1726 : // Visitor Methods
1727 : //===--------------------------------------------------------------------===//
1728 :
1729 52: APValue VisitStmt(Stmt *S) {
1730 52: return APValue();
1731 : }
1732 :
1733 33: APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
1734 :
1735 50: APValue VisitImaginaryLiteral(ImaginaryLiteral *E) {
1736 50: Expr* SubExpr = E->getSubExpr();
1737 :
27: branch 3 taken
23: branch 4 taken
1738 50: if (SubExpr->getType()->isRealFloatingType()) {
1739 27: APFloat Result(0.0);
1740 :
0: branch 1 not taken
27: branch 2 taken
1741 27: if (!EvaluateFloat(SubExpr, Result, Info))
1742 0: return APValue();
1743 :
1744 : return APValue(APFloat(Result.getSemantics(), APFloat::fcZero, false),
1745 27: Result);
1746 : } else {
1747 : assert(SubExpr->getType()->isIntegerType() &&
23: branch 3 taken
0: branch 4 not taken
1748 23: "Unexpected imaginary literal.");
1749 :
1750 23: llvm::APSInt Result;
0: branch 1 not taken
23: branch 2 taken
1751 23: if (!EvaluateInteger(SubExpr, Result, Info))
1752 0: return APValue();
1753 :
1754 23: llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
1755 23: Zero = 0;
1756 23: return APValue(Zero, Result);
1757 : }
1758 : }
1759 :
1760 83: APValue VisitCastExpr(CastExpr *E) {
1761 83: Expr* SubExpr = E->getSubExpr();
1762 83: QualType EltType = E->getType()->getAs<ComplexType>()->getElementType();
1763 83: QualType SubType = SubExpr->getType();
1764 :
26: branch 2 taken
57: branch 3 taken
1765 83: if (SubType->isRealFloatingType()) {
1766 26: APFloat Result(0.0);
1767 :
0: branch 1 not taken
26: branch 2 taken
1768 26: if (!EvaluateFloat(SubExpr, Result, Info))
1769 0: return APValue();
1770 :
26: branch 2 taken
0: branch 3 not taken
1771 26: if (EltType->isRealFloatingType()) {
1772 26: Result = HandleFloatToFloatCast(EltType, SubType, Result, Info.Ctx);
1773 : return APValue(Result,
1774 26: APFloat(Result.getSemantics(), APFloat::fcZero, false));
1775 : } else {
1776 0: llvm::APSInt IResult;
1777 0: IResult = HandleFloatToIntCast(EltType, SubType, Result, Info.Ctx);
1778 0: llvm::APSInt Zero(IResult.getBitWidth(), !IResult.isSigned());
1779 0: Zero = 0;
1780 0: return APValue(IResult, Zero);
1781 26: }
34: branch 2 taken
23: branch 3 taken
1782 57: } else if (SubType->isIntegerType()) {
1783 34: APSInt Result;
1784 :
2: branch 1 taken
32: branch 2 taken
1785 34: if (!EvaluateInteger(SubExpr, Result, Info))
1786 2: return APValue();
1787 :
3: branch 2 taken
29: branch 3 taken
1788 32: if (EltType->isRealFloatingType()) {
1789 : APFloat FResult =
1790 3: HandleIntToFloatCast(EltType, SubType, Result, Info.Ctx);
1791 : return APValue(FResult,
1792 3: APFloat(FResult.getSemantics(), APFloat::fcZero, false));
1793 : } else {
1794 29: Result = HandleIntToIntCast(EltType, SubType, Result, Info.Ctx);
1795 29: llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
1796 29: Zero = 0;
1797 29: return APValue(Result, Zero);
1798 34: }
23: branch 2 taken
0: branch 3 not taken
1799 23: } else if (const ComplexType *CT = SubType->getAs<ComplexType>()) {
1800 23: APValue Src;
1801 :
17: branch 1 taken
6: branch 2 taken
1802 23: if (!EvaluateComplex(SubExpr, Src, Info))
1803 17: return APValue();
1804 :
1805 6: QualType SrcType = CT->getElementType();
1806 :
4: branch 1 taken
2: branch 2 taken
1807 6: if (Src.isComplexFloat()) {
4: branch 2 taken
0: branch 3 not taken
1808 4: if (EltType->isRealFloatingType()) {
1809 : return APValue(HandleFloatToFloatCast(EltType, SrcType,
1810 : Src.getComplexFloatReal(),
1811 : Info.Ctx),
1812 : HandleFloatToFloatCast(EltType, SrcType,
1813 : Src.getComplexFloatImag(),
1814 4: Info.Ctx));
1815 : } else {
1816 : return APValue(HandleFloatToIntCast(EltType, SrcType,
1817 : Src.getComplexFloatReal(),
1818 : Info.Ctx),
1819 : HandleFloatToIntCast(EltType, SrcType,
1820 : Src.getComplexFloatImag(),
1821 0: Info.Ctx));
1822 : }
1823 : } else {
2: branch 1 taken
0: branch 2 not taken
1824 2: assert(Src.isComplexInt() && "Invalid evaluate result.");
0: branch 2 not taken
2: branch 3 taken
1825 2: if (EltType->isRealFloatingType()) {
1826 : return APValue(HandleIntToFloatCast(EltType, SrcType,
1827 : Src.getComplexIntReal(),
1828 : Info.Ctx),
1829 : HandleIntToFloatCast(EltType, SrcType,
1830 : Src.getComplexIntImag(),
1831 0: Info.Ctx));
1832 : } else {
1833 : return APValue(HandleIntToIntCast(EltType, SrcType,
1834 : Src.getComplexIntReal(),
1835 : Info.Ctx),
1836 : HandleIntToIntCast(EltType, SrcType,
1837 : Src.getComplexIntImag(),
1838 2: Info.Ctx));
1839 : }
1840 23: }
1841 : }
1842 :
1843 : // FIXME: Handle more casts.
1844 0: return APValue();
1845 : }
1846 :
1847 : APValue VisitBinaryOperator(const BinaryOperator *E);
1848 0: APValue VisitChooseExpr(const ChooseExpr *E)
1849 0: { return Visit(E->getChosenSubExpr(Info.Ctx)); }
1850 0: APValue VisitUnaryExtension(const UnaryOperator *E)
1851 0: { return Visit(E->getSubExpr()); }
1852 : // FIXME Missing: unary +/-/~, binary div, ImplicitValueInitExpr,
1853 : // conditional ?:, comma
1854 : };
1855 : } // end anonymous namespace
1856 :
1857 255: static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info) {
1858 255: Result = ComplexExprEvaluator(Info).Visit(const_cast<Expr*>(E));
1859 : assert((!Result.isComplexFloat() ||
1860 : (&Result.getComplexFloatReal().getSemantics() ==
1861 : &Result.getComplexFloatImag().getSemantics())) &&
90: branch 1 taken
165: branch 2 taken
90: branch 7 taken
0: branch 8 not taken
1862 255: "Invalid complex evaluation.");
165: branch 1 taken
90: branch 2 taken
83: branch 4 taken
82: branch 5 taken
1863 420: return Result.isComplexFloat() || Result.isComplexInt();
1864 : }
1865 :
1866 70: APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
1867 70: APValue Result, RHS;
1868 :
11: branch 2 taken
59: branch 3 taken
1869 70: if (!EvaluateComplex(E->getLHS(), Result, Info))
1870 11: return APValue();
1871 :
0: branch 2 not taken
59: branch 3 taken
1872 59: if (!EvaluateComplex(E->getRHS(), RHS, Info))
1873 0: return APValue();
1874 :
1875 : assert(Result.isComplexFloat() == RHS.isComplexFloat() &&
59: branch 2 taken
0: branch 3 not taken
1876 59: "Invalid operands to binary operator.");
0: branch 1 not taken
46: branch 2 taken
0: branch 3 not taken
13: branch 4 taken
1877 59: switch (E->getOpcode()) {
1878 0: default: return APValue();
1879 : case BinaryOperator::Add:
24: branch 1 taken
22: branch 2 taken
1880 46: if (Result.isComplexFloat()) {
1881 : Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
1882 24: APFloat::rmNearestTiesToEven);
1883 : Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
1884 24: APFloat::rmNearestTiesToEven);
1885 : } else {
1886 22: Result.getComplexIntReal() += RHS.getComplexIntReal();
1887 22: Result.getComplexIntImag() += RHS.getComplexIntImag();
1888 : }
1889 46: break;
1890 : case BinaryOperator::Sub:
0: branch 1 not taken
0: branch 2 not taken
1891 0: if (Result.isComplexFloat()) {
1892 : Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
1893 0: APFloat::rmNearestTiesToEven);
1894 : Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
1895 0: APFloat::rmNearestTiesToEven);
1896 : } else {
1897 0: Result.getComplexIntReal() -= RHS.getComplexIntReal();
1898 0: Result.getComplexIntImag() -= RHS.getComplexIntImag();
1899 : }
1900 0: break;
1901 : case BinaryOperator::Mul:
6: branch 1 taken
7: branch 2 taken
1902 13: if (Result.isComplexFloat()) {
1903 6: APValue LHS = Result;
1904 6: APFloat &LHS_r = LHS.getComplexFloatReal();
1905 6: APFloat &LHS_i = LHS.getComplexFloatImag();
1906 6: APFloat &RHS_r = RHS.getComplexFloatReal();
1907 6: APFloat &RHS_i = RHS.getComplexFloatImag();
1908 :
1909 6: APFloat Tmp = LHS_r;
1910 6: Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven);
1911 6: Result.getComplexFloatReal() = Tmp;
1912 6: Tmp = LHS_i;
1913 6: Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
1914 6: Result.getComplexFloatReal().subtract(Tmp, APFloat::rmNearestTiesToEven);
1915 :
1916 6: Tmp = LHS_r;
1917 6: Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
1918 6: Result.getComplexFloatImag() = Tmp;
1919 6: Tmp = LHS_i;
1920 6: Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven);
1921 6: Result.getComplexFloatImag().add(Tmp, APFloat::rmNearestTiesToEven);
1922 : } else {
1923 7: APValue LHS = Result;
1924 : Result.getComplexIntReal() =
1925 : (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
1926 7: LHS.getComplexIntImag() * RHS.getComplexIntImag());
1927 : Result.getComplexIntImag() =
1928 : (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
1929 7: LHS.getComplexIntImag() * RHS.getComplexIntReal());
1930 : }
1931 : break;
1932 : }
1933 :
1934 59: return Result;
1935 : }
1936 :
1937 : //===----------------------------------------------------------------------===//
1938 : // Top level Expr::Evaluate method.
1939 : //===----------------------------------------------------------------------===//
1940 :
1941 : /// Evaluate - Return true if this is a constant which we can fold using
1942 : /// any crazy technique (that has nothing to do with language standards) that
1943 : /// we want to. If this function returns true, it returns the folded constant
1944 : /// in Result.
1945 26037: bool Expr::Evaluate(EvalResult &Result, ASTContext &Ctx) const {
1946 26037: EvalInfo Info(Ctx, Result);
1947 :
743: branch 3 taken
25294: branch 4 taken
1948 26037: if (getType()->isVectorType()) {
732: branch 1 taken
11: branch 2 taken
1949 743: if (!EvaluateVector(this, Result.Val, Info))
1950 732: return false;
22408: branch 3 taken
2886: branch 4 taken
1951 25294: } else if (getType()->isIntegerType()) {
5711: branch 2 taken
16697: branch 3 taken
1952 22408: if (!IntExprEvaluator(Info, Result.Val).Visit(const_cast<Expr*>(this)))
1953 5711: return false;
1742: branch 3 taken
1144: branch 4 taken
1954 2886: } else if (getType()->hasPointerRepresentation()) {
1283: branch 1 taken
459: branch 2 taken
1955 1742: if (!EvaluatePointer(this, Result.Val, Info))
1956 1283: return false;
621: branch 3 taken
523: branch 4 taken
1957 1144: } else if (getType()->isRealFloatingType()) {
1958 621: llvm::APFloat f(0.0);
211: branch 1 taken
410: branch 2 taken
1959 621: if (!EvaluateFloat(this, f, Info))
1960 422: return false;
1961 :
410: branch 4 taken
211: branch 5 taken
1962 410: Result.Val = APValue(f);
76: branch 3 taken
447: branch 4 taken
1963 523: } else if (getType()->isAnyComplexType()) {
54: branch 1 taken
22: branch 2 taken
1964 76: if (!EvaluateComplex(this, Result.Val, Info))
1965 54: return false;
1966 : } else
1967 447: return false;
1968 :
1969 17599: return true;
1970 : }
1971 :
1972 64: bool Expr::EvaluateAsAny(EvalResult &Result, ASTContext &Ctx) const {
1973 64: EvalInfo Info(Ctx, Result, true);
1974 :
0: branch 3 not taken
64: branch 4 taken
1975 64: if (getType()->isVectorType()) {
0: branch 1 not taken
0: branch 2 not taken
1976 0: if (!EvaluateVector(this, Result.Val, Info))
1977 0: return false;
0: branch 3 not taken
64: branch 4 taken
1978 64: } else if (getType()->isIntegerType()) {
0: branch 2 not taken
0: branch 3 not taken
1979 0: if (!IntExprEvaluator(Info, Result.Val).Visit(const_cast<Expr*>(this)))
1980 0: return false;
64: branch 3 taken
0: branch 4 not taken
1981 64: } else if (getType()->hasPointerRepresentation()) {
33: branch 1 taken
31: branch 2 taken
1982 64: if (!EvaluatePointer(this, Result.Val, Info))
1983 33: return false;
0: branch 3 not taken
0: branch 4 not taken
1984 0: } else if (getType()->isRealFloatingType()) {
1985 0: llvm::APFloat f(0.0);
0: branch 1 not taken
0: branch 2 not taken
1986 0: if (!EvaluateFloat(this, f, Info))
1987 0: return false;
1988 :
0: branch 4 not taken
0: branch 5 not taken
1989 0: Result.Val = APValue(f);
0: branch 3 not taken
0: branch 4 not taken
1990 0: } else if (getType()->isAnyComplexType()) {
0: branch 1 not taken
0: branch 2 not taken
1991 0: if (!EvaluateComplex(this, Result.Val, Info))
1992 0: return false;
1993 : } else
1994 0: return false;
1995 :
1996 31: return true;
1997 : }
1998 :
1999 9: bool Expr::EvaluateAsBooleanCondition(bool &Result, ASTContext &Ctx) const {
2000 9: EvalResult Scratch;
2001 9: EvalInfo Info(Ctx, Scratch);
2002 :
2003 9: return HandleConversionToBool(this, Result, Info);
2004 : }
2005 :
2006 9: bool Expr::EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const {
2007 9: EvalInfo Info(Ctx, Result);
2008 :
7: branch 1 taken
2: branch 2 taken
7: branch 3 taken
0: branch 4 not taken
2009 9: return EvaluateLValue(this, Result.Val, Info) && !Result.HasSideEffects;
2010 : }
2011 :
2012 0: bool Expr::EvaluateAsAnyLValue(EvalResult &Result, ASTContext &Ctx) const {
2013 0: EvalInfo Info(Ctx, Result, true);
2014 :
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
2015 0: return EvaluateLValue(this, Result.Val, Info) && !Result.HasSideEffects;
2016 : }
2017 :
2018 : /// isEvaluatable - Call Evaluate to see if this expression can be constant
2019 : /// folded, but discard the result.
2020 1264: bool Expr::isEvaluatable(ASTContext &Ctx) const {
2021 1264: EvalResult Result;
1153: branch 1 taken
111: branch 2 taken
1153: branch 3 taken
0: branch 4 not taken
2022 1264: return Evaluate(Result, Ctx) && !Result.HasSideEffects;
2023 : }
2024 :
2025 65: bool Expr::HasSideEffects(ASTContext &Ctx) const {
2026 65: Expr::EvalResult Result;
2027 65: EvalInfo Info(Ctx, Result);
2028 65: return HasSideEffect(Info).Visit(const_cast<Expr*>(this));
2029 : }
2030 :
2031 1204: APSInt Expr::EvaluateAsInt(ASTContext &Ctx) const {
2032 1204: EvalResult EvalResult;
2033 1204: bool Result = Evaluate(EvalResult, Ctx);
2034 1204: Result = Result;
0: branch 0 not taken
1204: branch 1 taken
2035 1204: assert(Result && "Could not evaluate expression");
1204: branch 1 taken
0: branch 2 not taken
2036 1204: assert(EvalResult.Val.isInt() && "Expression did not evaluate to integer");
2037 :
2038 1204: return EvalResult.Val.getInt();
2039 : }
Generated: 2010-02-10 01:31 by zcov