clang 19.0.0git
ByteCodeExprGen.cpp
Go to the documentation of this file.
1//===--- ByteCodeExprGen.cpp - Code generator for expressions ---*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "ByteCodeExprGen.h"
10#include "ByteCodeEmitter.h"
11#include "ByteCodeGenError.h"
12#include "ByteCodeStmtGen.h"
13#include "Context.h"
14#include "Floating.h"
15#include "Function.h"
16#include "PrimType.h"
17#include "Program.h"
18
19using namespace clang;
20using namespace clang::interp;
21
22using APSInt = llvm::APSInt;
23
24namespace clang {
25namespace interp {
26
27/// Scope used to handle temporaries in toplevel variable declarations.
28template <class Emitter> class DeclScope final : public VariableScope<Emitter> {
29public:
32 OldGlobalDecl(Ctx->GlobalDecl) {
33 Ctx->GlobalDecl = Context::shouldBeGloballyIndexed(VD);
34 }
35
36 void addExtended(const Scope::Local &Local) override {
37 return this->addLocal(Local);
38 }
39
40 ~DeclScope() { this->Ctx->GlobalDecl = OldGlobalDecl; }
41
42private:
44 bool OldGlobalDecl;
45};
46
47/// Scope used to handle initialization methods.
48template <class Emitter> class OptionScope final {
49public:
50 /// Root constructor, compiling or discarding primitives.
51 OptionScope(ByteCodeExprGen<Emitter> *Ctx, bool NewDiscardResult,
52 bool NewInitializing)
53 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
54 OldInitializing(Ctx->Initializing) {
55 Ctx->DiscardResult = NewDiscardResult;
56 Ctx->Initializing = NewInitializing;
57 }
58
60 Ctx->DiscardResult = OldDiscardResult;
61 Ctx->Initializing = OldInitializing;
62 }
63
64private:
65 /// Parent context.
67 /// Old discard flag to restore.
68 bool OldDiscardResult;
69 bool OldInitializing;
70};
71
72} // namespace interp
73} // namespace clang
74
75template <class Emitter>
77 const Expr *SubExpr = CE->getSubExpr();
78 switch (CE->getCastKind()) {
79
80 case CK_LValueToRValue: {
81 if (DiscardResult)
82 return this->discard(SubExpr);
83
84 return dereference(
85 SubExpr, DerefKind::Read,
86 [](PrimType) {
87 // Value loaded - nothing to do here.
88 return true;
89 },
90 [this, CE](PrimType T) {
91 // Pointer on stack - dereference it.
92 return this->emitLoadPop(T, CE);
93 });
94 }
95
96 case CK_UncheckedDerivedToBase:
97 case CK_DerivedToBase: {
98 if (!this->visit(SubExpr))
99 return false;
100
101 unsigned DerivedOffset = collectBaseOffset(getRecordTy(CE->getType()),
102 getRecordTy(SubExpr->getType()));
103
104 return this->emitGetPtrBasePop(DerivedOffset, CE);
105 }
106
107 case CK_BaseToDerived: {
108 if (!this->visit(SubExpr))
109 return false;
110
111 unsigned DerivedOffset = collectBaseOffset(getRecordTy(SubExpr->getType()),
112 getRecordTy(CE->getType()));
113
114 return this->emitGetPtrDerivedPop(DerivedOffset, CE);
115 }
116
117 case CK_FloatingCast: {
118 if (DiscardResult)
119 return this->discard(SubExpr);
120 if (!this->visit(SubExpr))
121 return false;
122 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
123 return this->emitCastFP(TargetSemantics, getRoundingMode(CE), CE);
124 }
125
126 case CK_IntegralToFloating: {
127 if (DiscardResult)
128 return this->discard(SubExpr);
129 std::optional<PrimType> FromT = classify(SubExpr->getType());
130 if (!FromT)
131 return false;
132
133 if (!this->visit(SubExpr))
134 return false;
135
136 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
137 llvm::RoundingMode RM = getRoundingMode(CE);
138 return this->emitCastIntegralFloating(*FromT, TargetSemantics, RM, CE);
139 }
140
141 case CK_FloatingToBoolean:
142 case CK_FloatingToIntegral: {
143 if (DiscardResult)
144 return this->discard(SubExpr);
145
146 std::optional<PrimType> ToT = classify(CE->getType());
147
148 if (!ToT)
149 return false;
150
151 if (!this->visit(SubExpr))
152 return false;
153
154 if (ToT == PT_IntAP)
155 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->getType()),
156 CE);
157 if (ToT == PT_IntAPS)
158 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->getType()),
159 CE);
160
161 return this->emitCastFloatingIntegral(*ToT, CE);
162 }
163
164 case CK_NullToPointer:
165 if (DiscardResult)
166 return true;
167 return this->emitNull(classifyPrim(CE->getType()), CE);
168
169 case CK_PointerToIntegral: {
170 if (DiscardResult)
171 return this->discard(SubExpr);
172
173 if (!this->visit(SubExpr))
174 return false;
175
176 PrimType T = classifyPrim(CE->getType());
177 return this->emitCastPointerIntegral(T, CE);
178 }
179
180 case CK_ArrayToPointerDecay: {
181 if (!this->visit(SubExpr))
182 return false;
183 if (!this->emitArrayDecay(CE))
184 return false;
185 if (DiscardResult)
186 return this->emitPopPtr(CE);
187 return true;
188 }
189
190 case CK_AtomicToNonAtomic:
191 case CK_ConstructorConversion:
192 case CK_FunctionToPointerDecay:
193 case CK_NonAtomicToAtomic:
194 case CK_NoOp:
195 case CK_UserDefinedConversion:
196 return this->delegate(SubExpr);
197
198 case CK_BitCast:
199 if (CE->getType()->isAtomicType()) {
200 if (!this->discard(SubExpr))
201 return false;
202 return this->emitInvalidCast(CastKind::Reinterpret, CE);
203 }
204 return this->delegate(SubExpr);
205
206 case CK_IntegralToBoolean:
207 case CK_IntegralCast: {
208 if (DiscardResult)
209 return this->discard(SubExpr);
210 std::optional<PrimType> FromT = classify(SubExpr->getType());
211 std::optional<PrimType> ToT = classify(CE->getType());
212
213 if (!FromT || !ToT)
214 return false;
215
216 if (!this->visit(SubExpr))
217 return false;
218
219 if (ToT == PT_IntAP)
220 return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->getType()), CE);
221 if (ToT == PT_IntAPS)
222 return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->getType()), CE);
223
224 if (FromT == ToT)
225 return true;
226 return this->emitCast(*FromT, *ToT, CE);
227 }
228
229 case CK_PointerToBoolean: {
230 PrimType PtrT = classifyPrim(SubExpr->getType());
231
232 // Just emit p != nullptr for this.
233 if (!this->visit(SubExpr))
234 return false;
235
236 if (!this->emitNull(PtrT, CE))
237 return false;
238
239 return this->emitNE(PtrT, CE);
240 }
241
242 case CK_IntegralComplexToBoolean:
243 case CK_FloatingComplexToBoolean: {
244 PrimType ElemT = classifyComplexElementType(SubExpr->getType());
245 // We emit the expression (__real(E) != 0 || __imag(E) != 0)
246 // for us, that means (bool)E[0] || (bool)E[1]
247 if (!this->visit(SubExpr))
248 return false;
249 if (!this->emitConstUint8(0, CE))
250 return false;
251 if (!this->emitArrayElemPtrUint8(CE))
252 return false;
253 if (!this->emitLoadPop(ElemT, CE))
254 return false;
255 if (ElemT == PT_Float) {
256 if (!this->emitCastFloatingIntegral(PT_Bool, CE))
257 return false;
258 } else {
259 if (!this->emitCast(ElemT, PT_Bool, CE))
260 return false;
261 }
262
263 // We now have the bool value of E[0] on the stack.
264 LabelTy LabelTrue = this->getLabel();
265 if (!this->jumpTrue(LabelTrue))
266 return false;
267
268 if (!this->emitConstUint8(1, CE))
269 return false;
270 if (!this->emitArrayElemPtrPopUint8(CE))
271 return false;
272 if (!this->emitLoadPop(ElemT, CE))
273 return false;
274 if (ElemT == PT_Float) {
275 if (!this->emitCastFloatingIntegral(PT_Bool, CE))
276 return false;
277 } else {
278 if (!this->emitCast(ElemT, PT_Bool, CE))
279 return false;
280 }
281 // Leave the boolean value of E[1] on the stack.
282 LabelTy EndLabel = this->getLabel();
283 this->jump(EndLabel);
284
285 this->emitLabel(LabelTrue);
286 if (!this->emitPopPtr(CE))
287 return false;
288 if (!this->emitConstBool(true, CE))
289 return false;
290
291 this->fallthrough(EndLabel);
292 this->emitLabel(EndLabel);
293
294 return true;
295 }
296
297 case CK_IntegralComplexToReal:
298 case CK_FloatingComplexToReal:
299 return this->emitComplexReal(SubExpr);
300
301 case CK_IntegralRealToComplex:
302 case CK_FloatingRealToComplex: {
303 // We're creating a complex value here, so we need to
304 // allocate storage for it.
305 if (!Initializing) {
306 std::optional<unsigned> LocalIndex =
307 allocateLocal(CE, /*IsExtended=*/true);
308 if (!LocalIndex)
309 return false;
310 if (!this->emitGetPtrLocal(*LocalIndex, CE))
311 return false;
312 }
313
314 // Init the complex value to {SubExpr, 0}.
315 if (!this->visitArrayElemInit(0, SubExpr))
316 return false;
317 // Zero-init the second element.
318 PrimType T = classifyPrim(SubExpr->getType());
319 if (!this->visitZeroInitializer(T, SubExpr->getType(), SubExpr))
320 return false;
321 return this->emitInitElem(T, 1, SubExpr);
322 }
323
324 case CK_IntegralComplexCast:
325 case CK_FloatingComplexCast:
326 case CK_IntegralComplexToFloatingComplex:
327 case CK_FloatingComplexToIntegralComplex: {
328 assert(CE->getType()->isAnyComplexType());
329 assert(SubExpr->getType()->isAnyComplexType());
330 if (DiscardResult)
331 return this->discard(SubExpr);
332
333 if (!Initializing) {
334 std::optional<unsigned> LocalIndex =
335 allocateLocal(CE, /*IsExtended=*/true);
336 if (!LocalIndex)
337 return false;
338 if (!this->emitGetPtrLocal(*LocalIndex, CE))
339 return false;
340 }
341
342 // Location for the SubExpr.
343 // Since SubExpr is of complex type, visiting it results in a pointer
344 // anyway, so we just create a temporary pointer variable.
345 std::optional<unsigned> SubExprOffset = allocateLocalPrimitive(
346 SubExpr, PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false);
347 if (!SubExprOffset)
348 return false;
349
350 if (!this->visit(SubExpr))
351 return false;
352 if (!this->emitSetLocal(PT_Ptr, *SubExprOffset, CE))
353 return false;
354
355 PrimType SourceElemT = classifyComplexElementType(SubExpr->getType());
356 QualType DestElemType =
357 CE->getType()->getAs<ComplexType>()->getElementType();
358 PrimType DestElemT = classifyPrim(DestElemType);
359 // Cast both elements individually.
360 for (unsigned I = 0; I != 2; ++I) {
361 if (!this->emitGetLocal(PT_Ptr, *SubExprOffset, CE))
362 return false;
363 if (!this->emitConstUint8(I, CE))
364 return false;
365 if (!this->emitArrayElemPtrPopUint8(CE))
366 return false;
367 if (!this->emitLoadPop(SourceElemT, CE))
368 return false;
369
370 // Do the cast.
371 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
372 return false;
373
374 // Save the value.
375 if (!this->emitInitElem(DestElemT, I, CE))
376 return false;
377 }
378 return true;
379 }
380
381 case CK_ToVoid:
382 return discard(SubExpr);
383
384 default:
385 assert(false && "Cast not implemented");
386 }
387 llvm_unreachable("Unhandled clang::CastKind enum");
388}
389
390template <class Emitter>
392 if (DiscardResult)
393 return true;
394
395 return this->emitConst(LE->getValue(), LE);
396}
397
398template <class Emitter>
400 if (DiscardResult)
401 return true;
402
403 return this->emitConstFloat(E->getValue(), E);
404}
405
406template <class Emitter>
408 const ImaginaryLiteral *E) {
409 assert(E->getType()->isAnyComplexType());
410 if (DiscardResult)
411 return true;
412
413 if (!Initializing) {
414 std::optional<unsigned> LocalIndex = allocateLocal(E, /*IsExtended=*/false);
415 if (!LocalIndex)
416 return false;
417 if (!this->emitGetPtrLocal(*LocalIndex, E))
418 return false;
419 }
420
421 const Expr *SubExpr = E->getSubExpr();
422 PrimType SubExprT = classifyPrim(SubExpr->getType());
423
424 if (!this->visitZeroInitializer(SubExprT, SubExpr->getType(), SubExpr))
425 return false;
426 if (!this->emitInitElem(SubExprT, 0, SubExpr))
427 return false;
428 return this->visitArrayElemInit(1, SubExpr);
429}
430
431template <class Emitter>
433 return this->delegate(E->getSubExpr());
434}
435
436template <class Emitter>
438 // Need short-circuiting for these.
439 if (BO->isLogicalOp())
440 return this->VisitLogicalBinOp(BO);
441
442 if (BO->getType()->isAnyComplexType())
443 return this->VisitComplexBinOp(BO);
444
445 const Expr *LHS = BO->getLHS();
446 const Expr *RHS = BO->getRHS();
447
448 if (BO->isPtrMemOp())
449 return this->visit(RHS);
450
451 // Typecheck the args.
452 std::optional<PrimType> LT = classify(LHS->getType());
453 std::optional<PrimType> RT = classify(RHS->getType());
454 std::optional<PrimType> T = classify(BO->getType());
455
456 // Deal with operations which have composite or void types.
457 if (BO->isCommaOp()) {
458 if (!this->discard(LHS))
459 return false;
460 if (RHS->getType()->isVoidType())
461 return this->discard(RHS);
462
463 return this->delegate(RHS);
464 }
465
466 // Special case for C++'s three-way/spaceship operator <=>, which
467 // returns a std::{strong,weak,partial}_ordering (which is a class, so doesn't
468 // have a PrimType).
469 if (!T && BO->getOpcode() == BO_Cmp) {
470 if (DiscardResult)
471 return true;
472 const ComparisonCategoryInfo *CmpInfo =
473 Ctx.getASTContext().CompCategories.lookupInfoForType(BO->getType());
474 assert(CmpInfo);
475
476 // We need a temporary variable holding our return value.
477 if (!Initializing) {
478 std::optional<unsigned> ResultIndex = this->allocateLocal(BO, false);
479 if (!this->emitGetPtrLocal(*ResultIndex, BO))
480 return false;
481 }
482
483 if (!visit(LHS) || !visit(RHS))
484 return false;
485
486 return this->emitCMP3(*LT, CmpInfo, BO);
487 }
488
489 if (!LT || !RT || !T)
490 return false;
491
492 // Pointer arithmetic special case.
493 if (BO->getOpcode() == BO_Add || BO->getOpcode() == BO_Sub) {
494 if (T == PT_Ptr || (LT == PT_Ptr && RT == PT_Ptr))
495 return this->VisitPointerArithBinOp(BO);
496 }
497
498 if (!visit(LHS) || !visit(RHS))
499 return false;
500
501 // For languages such as C, cast the result of one
502 // of our comparision opcodes to T (which is usually int).
503 auto MaybeCastToBool = [this, T, BO](bool Result) {
504 if (!Result)
505 return false;
506 if (DiscardResult)
507 return this->emitPop(*T, BO);
508 if (T != PT_Bool)
509 return this->emitCast(PT_Bool, *T, BO);
510 return true;
511 };
512
513 auto Discard = [this, T, BO](bool Result) {
514 if (!Result)
515 return false;
516 return DiscardResult ? this->emitPop(*T, BO) : true;
517 };
518
519 switch (BO->getOpcode()) {
520 case BO_EQ:
521 return MaybeCastToBool(this->emitEQ(*LT, BO));
522 case BO_NE:
523 return MaybeCastToBool(this->emitNE(*LT, BO));
524 case BO_LT:
525 return MaybeCastToBool(this->emitLT(*LT, BO));
526 case BO_LE:
527 return MaybeCastToBool(this->emitLE(*LT, BO));
528 case BO_GT:
529 return MaybeCastToBool(this->emitGT(*LT, BO));
530 case BO_GE:
531 return MaybeCastToBool(this->emitGE(*LT, BO));
532 case BO_Sub:
533 if (BO->getType()->isFloatingType())
534 return Discard(this->emitSubf(getRoundingMode(BO), BO));
535 return Discard(this->emitSub(*T, BO));
536 case BO_Add:
537 if (BO->getType()->isFloatingType())
538 return Discard(this->emitAddf(getRoundingMode(BO), BO));
539 return Discard(this->emitAdd(*T, BO));
540 case BO_Mul:
541 if (BO->getType()->isFloatingType())
542 return Discard(this->emitMulf(getRoundingMode(BO), BO));
543 return Discard(this->emitMul(*T, BO));
544 case BO_Rem:
545 return Discard(this->emitRem(*T, BO));
546 case BO_Div:
547 if (BO->getType()->isFloatingType())
548 return Discard(this->emitDivf(getRoundingMode(BO), BO));
549 return Discard(this->emitDiv(*T, BO));
550 case BO_Assign:
551 if (DiscardResult)
552 return LHS->refersToBitField() ? this->emitStoreBitFieldPop(*T, BO)
553 : this->emitStorePop(*T, BO);
554 return LHS->refersToBitField() ? this->emitStoreBitField(*T, BO)
555 : this->emitStore(*T, BO);
556 case BO_And:
557 return Discard(this->emitBitAnd(*T, BO));
558 case BO_Or:
559 return Discard(this->emitBitOr(*T, BO));
560 case BO_Shl:
561 return Discard(this->emitShl(*LT, *RT, BO));
562 case BO_Shr:
563 return Discard(this->emitShr(*LT, *RT, BO));
564 case BO_Xor:
565 return Discard(this->emitBitXor(*T, BO));
566 case BO_LOr:
567 case BO_LAnd:
568 llvm_unreachable("Already handled earlier");
569 default:
570 return false;
571 }
572
573 llvm_unreachable("Unhandled binary op");
574}
575
576/// Perform addition/subtraction of a pointer and an integer or
577/// subtraction of two pointers.
578template <class Emitter>
581 const Expr *LHS = E->getLHS();
582 const Expr *RHS = E->getRHS();
583
584 if ((Op != BO_Add && Op != BO_Sub) ||
585 (!LHS->getType()->isPointerType() && !RHS->getType()->isPointerType()))
586 return false;
587
588 std::optional<PrimType> LT = classify(LHS);
589 std::optional<PrimType> RT = classify(RHS);
590
591 if (!LT || !RT)
592 return false;
593
594 if (LHS->getType()->isPointerType() && RHS->getType()->isPointerType()) {
595 if (Op != BO_Sub)
596 return false;
597
598 assert(E->getType()->isIntegerType());
599 if (!visit(RHS) || !visit(LHS))
600 return false;
601
602 return this->emitSubPtr(classifyPrim(E->getType()), E);
603 }
604
605 PrimType OffsetType;
606 if (LHS->getType()->isIntegerType()) {
607 if (!visit(RHS) || !visit(LHS))
608 return false;
609 OffsetType = *LT;
610 } else if (RHS->getType()->isIntegerType()) {
611 if (!visit(LHS) || !visit(RHS))
612 return false;
613 OffsetType = *RT;
614 } else {
615 return false;
616 }
617
618 if (Op == BO_Add)
619 return this->emitAddOffset(OffsetType, E);
620 else if (Op == BO_Sub)
621 return this->emitSubOffset(OffsetType, E);
622
623 return false;
624}
625
626template <class Emitter>
628 assert(E->isLogicalOp());
630 const Expr *LHS = E->getLHS();
631 const Expr *RHS = E->getRHS();
632 std::optional<PrimType> T = classify(E->getType());
633
634 if (Op == BO_LOr) {
635 // Logical OR. Visit LHS and only evaluate RHS if LHS was FALSE.
636 LabelTy LabelTrue = this->getLabel();
637 LabelTy LabelEnd = this->getLabel();
638
639 if (!this->visitBool(LHS))
640 return false;
641 if (!this->jumpTrue(LabelTrue))
642 return false;
643
644 if (!this->visitBool(RHS))
645 return false;
646 if (!this->jump(LabelEnd))
647 return false;
648
649 this->emitLabel(LabelTrue);
650 this->emitConstBool(true, E);
651 this->fallthrough(LabelEnd);
652 this->emitLabel(LabelEnd);
653
654 } else {
655 assert(Op == BO_LAnd);
656 // Logical AND.
657 // Visit LHS. Only visit RHS if LHS was TRUE.
658 LabelTy LabelFalse = this->getLabel();
659 LabelTy LabelEnd = this->getLabel();
660
661 if (!this->visitBool(LHS))
662 return false;
663 if (!this->jumpFalse(LabelFalse))
664 return false;
665
666 if (!this->visitBool(RHS))
667 return false;
668 if (!this->jump(LabelEnd))
669 return false;
670
671 this->emitLabel(LabelFalse);
672 this->emitConstBool(false, E);
673 this->fallthrough(LabelEnd);
674 this->emitLabel(LabelEnd);
675 }
676
677 if (DiscardResult)
678 return this->emitPopBool(E);
679
680 // For C, cast back to integer type.
681 assert(T);
682 if (T != PT_Bool)
683 return this->emitCast(PT_Bool, *T, E);
684 return true;
685}
686
687template <class Emitter>
689 // Prepare storage for result.
690 if (!Initializing) {
691 std::optional<unsigned> LocalIndex = allocateLocal(E, /*IsExtended=*/false);
692 if (!LocalIndex)
693 return false;
694 if (!this->emitGetPtrLocal(*LocalIndex, E))
695 return false;
696 }
697
698 const Expr *LHS = E->getLHS();
699 const Expr *RHS = E->getRHS();
700 PrimType LHSElemT = this->classifyComplexElementType(LHS->getType());
701 PrimType RHSElemT = this->classifyComplexElementType(RHS->getType());
702
703 unsigned LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false);
704 unsigned RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false);
705 unsigned ResultOffset = ~0u;
706 if (!this->DiscardResult)
707 ResultOffset = this->allocateLocalPrimitive(E, PT_Ptr, true, false);
708
709 assert(LHSElemT == RHSElemT);
710
711 // Save result pointer in ResultOffset
712 if (!this->DiscardResult) {
713 if (!this->emitDupPtr(E))
714 return false;
715 if (!this->emitSetLocal(PT_Ptr, ResultOffset, E))
716 return false;
717 }
718
719 // Evaluate LHS and save value to LHSOffset.
720 if (!this->visit(LHS))
721 return false;
722 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
723 return false;
724
725 // Same with RHS.
726 if (!this->visit(RHS))
727 return false;
728 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
729 return false;
730
731 // Now we can get pointers to the LHS and RHS from the offsets above.
733 for (unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
734 // Result pointer for the store later.
735 if (!this->DiscardResult) {
736 if (!this->emitGetLocal(PT_Ptr, ResultOffset, E))
737 return false;
738 }
739
740 if (!this->emitGetLocal(PT_Ptr, LHSOffset, E))
741 return false;
742 if (!this->emitConstUint8(ElemIndex, E))
743 return false;
744 if (!this->emitArrayElemPtrPopUint8(E))
745 return false;
746 if (!this->emitLoadPop(LHSElemT, E))
747 return false;
748
749 if (!this->emitGetLocal(PT_Ptr, RHSOffset, E))
750 return false;
751 if (!this->emitConstUint8(ElemIndex, E))
752 return false;
753 if (!this->emitArrayElemPtrPopUint8(E))
754 return false;
755 if (!this->emitLoadPop(RHSElemT, E))
756 return false;
757
758 // The actual operation.
759 switch (Op) {
760 case BO_Add:
761 if (LHSElemT == PT_Float) {
762 if (!this->emitAddf(getRoundingMode(E), E))
763 return false;
764 } else {
765 if (!this->emitAdd(LHSElemT, E))
766 return false;
767 }
768 break;
769 case BO_Sub:
770 if (LHSElemT == PT_Float) {
771 if (!this->emitSubf(getRoundingMode(E), E))
772 return false;
773 } else {
774 if (!this->emitSub(LHSElemT, E))
775 return false;
776 }
777 break;
778
779 default:
780 return false;
781 }
782
783 if (!this->DiscardResult) {
784 // Initialize array element with the value we just computed.
785 if (!this->emitInitElemPop(LHSElemT, ElemIndex, E))
786 return false;
787 } else {
788 if (!this->emitPop(LHSElemT, E))
789 return false;
790 }
791 }
792 return true;
793}
794
795template <class Emitter>
797 QualType QT = E->getType();
798
799 if (std::optional<PrimType> T = classify(QT))
800 return this->visitZeroInitializer(*T, QT, E);
801
802 if (QT->isRecordType())
803 return false;
804
805 if (QT->isIncompleteArrayType())
806 return true;
807
808 if (QT->isArrayType()) {
809 const ArrayType *AT = QT->getAsArrayTypeUnsafe();
810 assert(AT);
811 const auto *CAT = cast<ConstantArrayType>(AT);
812 size_t NumElems = CAT->getSize().getZExtValue();
813 PrimType ElemT = classifyPrim(CAT->getElementType());
814
815 for (size_t I = 0; I != NumElems; ++I) {
816 if (!this->visitZeroInitializer(ElemT, CAT->getElementType(), E))
817 return false;
818 if (!this->emitInitElem(ElemT, I, E))
819 return false;
820 }
821
822 return true;
823 }
824
825 if (QT->isAnyComplexType()) {
826 assert(Initializing);
827 QualType ElemQT = QT->getAs<ComplexType>()->getElementType();
828 PrimType ElemT = classifyPrim(ElemQT);
829 for (unsigned I = 0; I < 2; ++I) {
830 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
831 return false;
832 if (!this->emitInitElem(ElemT, I, E))
833 return false;
834 }
835 return true;
836 }
837
838 return false;
839}
840
841template <class Emitter>
843 const ArraySubscriptExpr *E) {
844 const Expr *Base = E->getBase();
845 const Expr *Index = E->getIdx();
846
847 if (DiscardResult)
848 return this->discard(Base) && this->discard(Index);
849
850 // Take pointer of LHS, add offset from RHS.
851 // What's left on the stack after this is a pointer.
852 if (!this->visit(Base))
853 return false;
854
855 if (!this->visit(Index))
856 return false;
857
858 PrimType IndexT = classifyPrim(Index->getType());
859 return this->emitArrayElemPtrPop(IndexT, E);
860}
861
862template <class Emitter>
864 const Expr *E) {
865 assert(E->getType()->isRecordType());
866 const Record *R = getRecord(E->getType());
867
868 if (Inits.size() == 1 && E->getType() == Inits[0]->getType()) {
869 return this->visitInitializer(Inits[0]);
870 }
871
872 unsigned InitIndex = 0;
873 for (const Expr *Init : Inits) {
874 if (!this->emitDupPtr(E))
875 return false;
876
877 if (std::optional<PrimType> T = classify(Init)) {
878 const Record::Field *FieldToInit = R->getField(InitIndex);
879 if (!this->visit(Init))
880 return false;
881
882 if (FieldToInit->isBitField()) {
883 if (!this->emitInitBitField(*T, FieldToInit, E))
884 return false;
885 } else {
886 if (!this->emitInitField(*T, FieldToInit->Offset, E))
887 return false;
888 }
889
890 if (!this->emitPopPtr(E))
891 return false;
892 ++InitIndex;
893 } else {
894 // Initializer for a direct base class.
895 if (const Record::Base *B = R->getBase(Init->getType())) {
896 if (!this->emitGetPtrBasePop(B->Offset, Init))
897 return false;
898
899 if (!this->visitInitializer(Init))
900 return false;
901
902 if (!this->emitInitPtrPop(E))
903 return false;
904 // Base initializers don't increase InitIndex, since they don't count
905 // into the Record's fields.
906 } else {
907 const Record::Field *FieldToInit = R->getField(InitIndex);
908 // Non-primitive case. Get a pointer to the field-to-initialize
909 // on the stack and recurse into visitInitializer().
910 if (!this->emitGetPtrField(FieldToInit->Offset, Init))
911 return false;
912
913 if (!this->visitInitializer(Init))
914 return false;
915
916 if (!this->emitPopPtr(E))
917 return false;
918 ++InitIndex;
919 }
920 }
921 }
922 return true;
923}
924
925/// Pointer to the array(not the element!) must be on the stack when calling
926/// this.
927template <class Emitter>
929 const Expr *Init) {
930 if (std::optional<PrimType> T = classify(Init->getType())) {
931 // Visit the primitive element like normal.
932 if (!this->visit(Init))
933 return false;
934 return this->emitInitElem(*T, ElemIndex, Init);
935 }
936
937 // Advance the pointer currently on the stack to the given
938 // dimension.
939 if (!this->emitConstUint32(ElemIndex, Init))
940 return false;
941 if (!this->emitArrayElemPtrUint32(Init))
942 return false;
943 if (!this->visitInitializer(Init))
944 return false;
945 return this->emitInitPtrPop(Init);
946}
947
948template <class Emitter>
950 // Handle discarding first.
951 if (DiscardResult) {
952 for (const Expr *Init : E->inits()) {
953 if (!this->discard(Init))
954 return false;
955 }
956 return true;
957 }
958
959 // Primitive values.
960 if (std::optional<PrimType> T = classify(E->getType())) {
961 assert(!DiscardResult);
962 if (E->getNumInits() == 0)
963 return this->visitZeroInitializer(*T, E->getType(), E);
964 assert(E->getNumInits() == 1);
965 return this->delegate(E->inits()[0]);
966 }
967
968 QualType T = E->getType();
969 if (T->isRecordType())
970 return this->visitInitList(E->inits(), E);
971
972 if (T->isArrayType()) {
973 unsigned ElementIndex = 0;
974 for (const Expr *Init : E->inits()) {
975 if (!this->visitArrayElemInit(ElementIndex, Init))
976 return false;
977 ++ElementIndex;
978 }
979
980 // Expand the filler expression.
981 // FIXME: This should go away.
982 if (const Expr *Filler = E->getArrayFiller()) {
983 const ConstantArrayType *CAT =
984 Ctx.getASTContext().getAsConstantArrayType(E->getType());
985 uint64_t NumElems = CAT->getSize().getZExtValue();
986
987 for (; ElementIndex != NumElems; ++ElementIndex) {
988 if (!this->visitArrayElemInit(ElementIndex, Filler))
989 return false;
990 }
991 }
992
993 return true;
994 }
995
996 if (T->isAnyComplexType()) {
997 unsigned NumInits = E->getNumInits();
998
999 if (NumInits == 1)
1000 return this->delegate(E->inits()[0]);
1001
1002 QualType ElemQT = E->getType()->getAs<ComplexType>()->getElementType();
1003 PrimType ElemT = classifyPrim(ElemQT);
1004 if (NumInits == 0) {
1005 // Zero-initialize both elements.
1006 for (unsigned I = 0; I < 2; ++I) {
1007 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1008 return false;
1009 if (!this->emitInitElem(ElemT, I, E))
1010 return false;
1011 }
1012 } else if (NumInits == 2) {
1013 unsigned InitIndex = 0;
1014 for (const Expr *Init : E->inits()) {
1015 if (!this->visit(Init))
1016 return false;
1017
1018 if (!this->emitInitElem(ElemT, InitIndex, E))
1019 return false;
1020 ++InitIndex;
1021 }
1022 }
1023 return true;
1024 }
1025
1026 return false;
1027}
1028
1029template <class Emitter>
1031 const CXXParenListInitExpr *E) {
1032 if (DiscardResult) {
1033 for (const Expr *Init : E->getInitExprs()) {
1034 if (!this->discard(Init))
1035 return false;
1036 }
1037 return true;
1038 }
1039
1040 assert(E->getType()->isRecordType());
1041 return this->visitInitList(E->getInitExprs(), E);
1042}
1043
1044template <class Emitter>
1047 return this->delegate(E->getReplacement());
1048}
1049
1050template <class Emitter>
1052 std::optional<PrimType> T = classify(E->getType());
1053 if (T && E->hasAPValueResult()) {
1054 // Try to emit the APValue directly, without visiting the subexpr.
1055 // This will only fail if we can't emit the APValue, so won't emit any
1056 // diagnostics or any double values.
1057 if (DiscardResult)
1058 return true;
1059
1060 if (this->visitAPValue(E->getAPValueResult(), *T, E))
1061 return true;
1062 }
1063 return this->delegate(E->getSubExpr());
1064}
1065
1067 UnaryExprOrTypeTrait Kind) {
1068 bool AlignOfReturnsPreferred =
1069 ASTCtx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
1070
1071 // C++ [expr.alignof]p3:
1072 // When alignof is applied to a reference type, the result is the
1073 // alignment of the referenced type.
1074 if (const auto *Ref = T->getAs<ReferenceType>())
1075 T = Ref->getPointeeType();
1076
1077 // __alignof is defined to return the preferred alignment.
1078 // Before 8, clang returned the preferred alignment for alignof and
1079 // _Alignof as well.
1080 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
1081 return ASTCtx.toCharUnitsFromBits(ASTCtx.getPreferredTypeAlign(T));
1082
1083 return ASTCtx.getTypeAlignInChars(T);
1084}
1085
1086template <class Emitter>
1088 const UnaryExprOrTypeTraitExpr *E) {
1089 UnaryExprOrTypeTrait Kind = E->getKind();
1090 ASTContext &ASTCtx = Ctx.getASTContext();
1091
1092 if (Kind == UETT_SizeOf) {
1093 QualType ArgType = E->getTypeOfArgument();
1094
1095 // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
1096 // the result is the size of the referenced type."
1097 if (const auto *Ref = ArgType->getAs<ReferenceType>())
1098 ArgType = Ref->getPointeeType();
1099
1100 CharUnits Size;
1101 if (ArgType->isVoidType() || ArgType->isFunctionType())
1102 Size = CharUnits::One();
1103 else {
1104 if (ArgType->isDependentType() || !ArgType->isConstantSizeType())
1105 return false;
1106
1107 Size = ASTCtx.getTypeSizeInChars(ArgType);
1108 }
1109
1110 if (DiscardResult)
1111 return true;
1112
1113 return this->emitConst(Size.getQuantity(), E);
1114 }
1115
1116 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
1117 CharUnits Size;
1118
1119 if (E->isArgumentType()) {
1120 QualType ArgType = E->getTypeOfArgument();
1121
1122 Size = AlignOfType(ArgType, ASTCtx, Kind);
1123 } else {
1124 // Argument is an expression, not a type.
1125 const Expr *Arg = E->getArgumentExpr()->IgnoreParens();
1126
1127 // The kinds of expressions that we have special-case logic here for
1128 // should be kept up to date with the special checks for those
1129 // expressions in Sema.
1130
1131 // alignof decl is always accepted, even if it doesn't make sense: we
1132 // default to 1 in those cases.
1133 if (const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
1134 Size = ASTCtx.getDeclAlign(DRE->getDecl(),
1135 /*RefAsPointee*/ true);
1136 else if (const auto *ME = dyn_cast<MemberExpr>(Arg))
1137 Size = ASTCtx.getDeclAlign(ME->getMemberDecl(),
1138 /*RefAsPointee*/ true);
1139 else
1140 Size = AlignOfType(Arg->getType(), ASTCtx, Kind);
1141 }
1142
1143 if (DiscardResult)
1144 return true;
1145
1146 return this->emitConst(Size.getQuantity(), E);
1147 }
1148
1149 return false;
1150}
1151
1152template <class Emitter>
1154 // 'Base.Member'
1155 const Expr *Base = E->getBase();
1156
1157 if (DiscardResult)
1158 return this->discard(Base);
1159
1160 if (Initializing) {
1161 if (!this->delegate(Base))
1162 return false;
1163 } else {
1164 if (!this->visit(Base))
1165 return false;
1166 }
1167
1168 // Base above gives us a pointer on the stack.
1169 // TODO: Implement non-FieldDecl members.
1170 const ValueDecl *Member = E->getMemberDecl();
1171 if (const auto *FD = dyn_cast<FieldDecl>(Member)) {
1172 const RecordDecl *RD = FD->getParent();
1173 const Record *R = getRecord(RD);
1174 const Record::Field *F = R->getField(FD);
1175 // Leave a pointer to the field on the stack.
1176 if (F->Decl->getType()->isReferenceType())
1177 return this->emitGetFieldPop(PT_Ptr, F->Offset, E);
1178 return this->emitGetPtrField(F->Offset, E);
1179 }
1180
1181 return false;
1182}
1183
1184template <class Emitter>
1186 const ArrayInitIndexExpr *E) {
1187 // ArrayIndex might not be set if a ArrayInitIndexExpr is being evaluated
1188 // stand-alone, e.g. via EvaluateAsInt().
1189 if (!ArrayIndex)
1190 return false;
1191 return this->emitConst(*ArrayIndex, E);
1192}
1193
1194template <class Emitter>
1196 const ArrayInitLoopExpr *E) {
1197 assert(Initializing);
1198 assert(!DiscardResult);
1199
1200 // We visit the common opaque expression here once so we have its value
1201 // cached.
1202 if (!this->discard(E->getCommonExpr()))
1203 return false;
1204
1205 // TODO: This compiles to quite a lot of bytecode if the array is larger.
1206 // Investigate compiling this to a loop.
1207 const Expr *SubExpr = E->getSubExpr();
1208 size_t Size = E->getArraySize().getZExtValue();
1209
1210 // So, every iteration, we execute an assignment here
1211 // where the LHS is on the stack (the target array)
1212 // and the RHS is our SubExpr.
1213 for (size_t I = 0; I != Size; ++I) {
1214 ArrayIndexScope<Emitter> IndexScope(this, I);
1215 BlockScope<Emitter> BS(this);
1216
1217 if (!this->visitArrayElemInit(I, SubExpr))
1218 return false;
1219 }
1220 return true;
1221}
1222
1223template <class Emitter>
1225 if (Initializing)
1226 return this->visitInitializer(E->getSourceExpr());
1227
1228 PrimType SubExprT = classify(E->getSourceExpr()).value_or(PT_Ptr);
1229 if (auto It = OpaqueExprs.find(E); It != OpaqueExprs.end())
1230 return this->emitGetLocal(SubExprT, It->second, E);
1231
1232 if (!this->visit(E->getSourceExpr()))
1233 return false;
1234
1235 // At this point we either have the evaluated source expression or a pointer
1236 // to an object on the stack. We want to create a local variable that stores
1237 // this value.
1238 std::optional<unsigned> LocalIndex =
1239 allocateLocalPrimitive(E, SubExprT, /*IsConst=*/true);
1240 if (!LocalIndex)
1241 return false;
1242 if (!this->emitSetLocal(SubExprT, *LocalIndex, E))
1243 return false;
1244
1245 // Here the local variable is created but the value is removed from the stack,
1246 // so we put it back if the caller needs it.
1247 if (!DiscardResult) {
1248 if (!this->emitGetLocal(SubExprT, *LocalIndex, E))
1249 return false;
1250 }
1251
1252 // This is cleaned up when the local variable is destroyed.
1253 OpaqueExprs.insert({E, *LocalIndex});
1254
1255 return true;
1256}
1257
1258template <class Emitter>
1260 const AbstractConditionalOperator *E) {
1261 const Expr *Condition = E->getCond();
1262 const Expr *TrueExpr = E->getTrueExpr();
1263 const Expr *FalseExpr = E->getFalseExpr();
1264
1265 LabelTy LabelEnd = this->getLabel(); // Label after the operator.
1266 LabelTy LabelFalse = this->getLabel(); // Label for the false expr.
1267
1268 if (!this->visitBool(Condition))
1269 return false;
1270
1271 if (!this->jumpFalse(LabelFalse))
1272 return false;
1273
1274 if (!this->delegate(TrueExpr))
1275 return false;
1276 if (!this->jump(LabelEnd))
1277 return false;
1278
1279 this->emitLabel(LabelFalse);
1280
1281 if (!this->delegate(FalseExpr))
1282 return false;
1283
1284 this->fallthrough(LabelEnd);
1285 this->emitLabel(LabelEnd);
1286
1287 return true;
1288}
1289
1290template <class Emitter>
1292 if (DiscardResult)
1293 return true;
1294
1295 if (!Initializing) {
1296 unsigned StringIndex = P.createGlobalString(E);
1297 return this->emitGetPtrGlobal(StringIndex, E);
1298 }
1299
1300 // We are initializing an array on the stack.
1301 const ConstantArrayType *CAT =
1302 Ctx.getASTContext().getAsConstantArrayType(E->getType());
1303 assert(CAT && "a string literal that's not a constant array?");
1304
1305 // If the initializer string is too long, a diagnostic has already been
1306 // emitted. Read only the array length from the string literal.
1307 unsigned ArraySize = CAT->getSize().getZExtValue();
1308 unsigned N = std::min(ArraySize, E->getLength());
1309 size_t CharWidth = E->getCharByteWidth();
1310
1311 for (unsigned I = 0; I != N; ++I) {
1312 uint32_t CodeUnit = E->getCodeUnit(I);
1313
1314 if (CharWidth == 1) {
1315 this->emitConstSint8(CodeUnit, E);
1316 this->emitInitElemSint8(I, E);
1317 } else if (CharWidth == 2) {
1318 this->emitConstUint16(CodeUnit, E);
1319 this->emitInitElemUint16(I, E);
1320 } else if (CharWidth == 4) {
1321 this->emitConstUint32(CodeUnit, E);
1322 this->emitInitElemUint32(I, E);
1323 } else {
1324 llvm_unreachable("unsupported character width");
1325 }
1326 }
1327
1328 // Fill up the rest of the char array with NUL bytes.
1329 for (unsigned I = N; I != ArraySize; ++I) {
1330 if (CharWidth == 1) {
1331 this->emitConstSint8(0, E);
1332 this->emitInitElemSint8(I, E);
1333 } else if (CharWidth == 2) {
1334 this->emitConstUint16(0, E);
1335 this->emitInitElemUint16(I, E);
1336 } else if (CharWidth == 4) {
1337 this->emitConstUint32(0, E);
1338 this->emitInitElemUint32(I, E);
1339 } else {
1340 llvm_unreachable("unsupported character width");
1341 }
1342 }
1343
1344 return true;
1345}
1346
1347template <class Emitter>
1349 const CharacterLiteral *E) {
1350 if (DiscardResult)
1351 return true;
1352 return this->emitConst(E->getValue(), E);
1353}
1354
1355template <class Emitter>
1357 const CompoundAssignOperator *E) {
1358
1359 const Expr *LHS = E->getLHS();
1360 const Expr *RHS = E->getRHS();
1361 QualType LHSType = LHS->getType();
1362 QualType LHSComputationType = E->getComputationLHSType();
1363 QualType ResultType = E->getComputationResultType();
1364 std::optional<PrimType> LT = classify(LHSComputationType);
1365 std::optional<PrimType> RT = classify(ResultType);
1366
1367 assert(ResultType->isFloatingType());
1368
1369 if (!LT || !RT)
1370 return false;
1371
1372 PrimType LHST = classifyPrim(LHSType);
1373
1374 // C++17 onwards require that we evaluate the RHS first.
1375 // Compute RHS and save it in a temporary variable so we can
1376 // load it again later.
1377 if (!visit(RHS))
1378 return false;
1379
1380 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
1381 if (!this->emitSetLocal(*RT, TempOffset, E))
1382 return false;
1383
1384 // First, visit LHS.
1385 if (!visit(LHS))
1386 return false;
1387 if (!this->emitLoad(LHST, E))
1388 return false;
1389
1390 // If necessary, convert LHS to its computation type.
1391 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
1392 LHSComputationType, E))
1393 return false;
1394
1395 // Now load RHS.
1396 if (!this->emitGetLocal(*RT, TempOffset, E))
1397 return false;
1398
1399 llvm::RoundingMode RM = getRoundingMode(E);
1400 switch (E->getOpcode()) {
1401 case BO_AddAssign:
1402 if (!this->emitAddf(RM, E))
1403 return false;
1404 break;
1405 case BO_SubAssign:
1406 if (!this->emitSubf(RM, E))
1407 return false;
1408 break;
1409 case BO_MulAssign:
1410 if (!this->emitMulf(RM, E))
1411 return false;
1412 break;
1413 case BO_DivAssign:
1414 if (!this->emitDivf(RM, E))
1415 return false;
1416 break;
1417 default:
1418 return false;
1419 }
1420
1421 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->getType(), E))
1422 return false;
1423
1424 if (DiscardResult)
1425 return this->emitStorePop(LHST, E);
1426 return this->emitStore(LHST, E);
1427}
1428
1429template <class Emitter>
1431 const CompoundAssignOperator *E) {
1432 BinaryOperatorKind Op = E->getOpcode();
1433 const Expr *LHS = E->getLHS();
1434 const Expr *RHS = E->getRHS();
1435 std::optional<PrimType> LT = classify(LHS->getType());
1436 std::optional<PrimType> RT = classify(RHS->getType());
1437
1438 if (Op != BO_AddAssign && Op != BO_SubAssign)
1439 return false;
1440
1441 if (!LT || !RT)
1442 return false;
1443 assert(*LT == PT_Ptr);
1444
1445 if (!visit(LHS))
1446 return false;
1447
1448 if (!this->emitLoadPtr(LHS))
1449 return false;
1450
1451 if (!visit(RHS))
1452 return false;
1453
1454 if (Op == BO_AddAssign) {
1455 if (!this->emitAddOffset(*RT, E))
1456 return false;
1457 } else {
1458 if (!this->emitSubOffset(*RT, E))
1459 return false;
1460 }
1461
1462 if (DiscardResult)
1463 return this->emitStorePopPtr(E);
1464 return this->emitStorePtr(E);
1465}
1466
1467template <class Emitter>
1469 const CompoundAssignOperator *E) {
1470
1471 const Expr *LHS = E->getLHS();
1472 const Expr *RHS = E->getRHS();
1473 std::optional<PrimType> LHSComputationT =
1474 classify(E->getComputationLHSType());
1475 std::optional<PrimType> LT = classify(LHS->getType());
1476 std::optional<PrimType> RT = classify(RHS->getType());
1477 std::optional<PrimType> ResultT = classify(E->getType());
1478
1479 if (!LT || !RT || !ResultT || !LHSComputationT)
1480 return false;
1481
1482 // Handle floating point operations separately here, since they
1483 // require special care.
1484
1485 if (ResultT == PT_Float || RT == PT_Float)
1486 return VisitFloatCompoundAssignOperator(E);
1487
1488 if (E->getType()->isPointerType())
1489 return VisitPointerCompoundAssignOperator(E);
1490
1491 assert(!E->getType()->isPointerType() && "Handled above");
1492 assert(!E->getType()->isFloatingType() && "Handled above");
1493
1494 // C++17 onwards require that we evaluate the RHS first.
1495 // Compute RHS and save it in a temporary variable so we can
1496 // load it again later.
1497 // FIXME: Compound assignments are unsequenced in C, so we might
1498 // have to figure out how to reject them.
1499 if (!visit(RHS))
1500 return false;
1501
1502 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
1503
1504 if (!this->emitSetLocal(*RT, TempOffset, E))
1505 return false;
1506
1507 // Get LHS pointer, load its value and cast it to the
1508 // computation type if necessary.
1509 if (!visit(LHS))
1510 return false;
1511 if (!this->emitLoad(*LT, E))
1512 return false;
1513 if (*LT != *LHSComputationT) {
1514 if (!this->emitCast(*LT, *LHSComputationT, E))
1515 return false;
1516 }
1517
1518 // Get the RHS value on the stack.
1519 if (!this->emitGetLocal(*RT, TempOffset, E))
1520 return false;
1521
1522 // Perform operation.
1523 switch (E->getOpcode()) {
1524 case BO_AddAssign:
1525 if (!this->emitAdd(*LHSComputationT, E))
1526 return false;
1527 break;
1528 case BO_SubAssign:
1529 if (!this->emitSub(*LHSComputationT, E))
1530 return false;
1531 break;
1532 case BO_MulAssign:
1533 if (!this->emitMul(*LHSComputationT, E))
1534 return false;
1535 break;
1536 case BO_DivAssign:
1537 if (!this->emitDiv(*LHSComputationT, E))
1538 return false;
1539 break;
1540 case BO_RemAssign:
1541 if (!this->emitRem(*LHSComputationT, E))
1542 return false;
1543 break;
1544 case BO_ShlAssign:
1545 if (!this->emitShl(*LHSComputationT, *RT, E))
1546 return false;
1547 break;
1548 case BO_ShrAssign:
1549 if (!this->emitShr(*LHSComputationT, *RT, E))
1550 return false;
1551 break;
1552 case BO_AndAssign:
1553 if (!this->emitBitAnd(*LHSComputationT, E))
1554 return false;
1555 break;
1556 case BO_XorAssign:
1557 if (!this->emitBitXor(*LHSComputationT, E))
1558 return false;
1559 break;
1560 case BO_OrAssign:
1561 if (!this->emitBitOr(*LHSComputationT, E))
1562 return false;
1563 break;
1564 default:
1565 llvm_unreachable("Unimplemented compound assign operator");
1566 }
1567
1568 // And now cast from LHSComputationT to ResultT.
1569 if (*ResultT != *LHSComputationT) {
1570 if (!this->emitCast(*LHSComputationT, *ResultT, E))
1571 return false;
1572 }
1573
1574 // And store the result in LHS.
1575 if (DiscardResult) {
1576 if (LHS->refersToBitField())
1577 return this->emitStoreBitFieldPop(*ResultT, E);
1578 return this->emitStorePop(*ResultT, E);
1579 }
1580 if (LHS->refersToBitField())
1581 return this->emitStoreBitField(*ResultT, E);
1582 return this->emitStore(*ResultT, E);
1583}
1584
1585template <class Emitter>
1587 const ExprWithCleanups *E) {
1588 const Expr *SubExpr = E->getSubExpr();
1589
1590 assert(E->getNumObjects() == 0 && "TODO: Implement cleanups");
1591
1592 return this->delegate(SubExpr);
1593}
1594
1595template <class Emitter>
1597 const MaterializeTemporaryExpr *E) {
1598 const Expr *SubExpr = E->getSubExpr();
1599
1600 if (Initializing) {
1601 // We already have a value, just initialize that.
1602 return this->visitInitializer(SubExpr);
1603 }
1604 // If we don't end up using the materialized temporary anyway, don't
1605 // bother creating it.
1606 if (DiscardResult)
1607 return this->discard(SubExpr);
1608
1609 // When we're initializing a global variable *or* the storage duration of
1610 // the temporary is explicitly static, create a global variable.
1611 std::optional<PrimType> SubExprT = classify(SubExpr);
1612 bool IsStatic = E->getStorageDuration() == SD_Static;
1613 if (GlobalDecl || IsStatic) {
1614 std::optional<unsigned> GlobalIndex = P.createGlobal(E);
1615 if (!GlobalIndex)
1616 return false;
1617
1618 const LifetimeExtendedTemporaryDecl *TempDecl =
1620 if (IsStatic)
1621 assert(TempDecl);
1622
1623 if (SubExprT) {
1624 if (!this->visit(SubExpr))
1625 return false;
1626 if (IsStatic) {
1627 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl, E))
1628 return false;
1629 } else {
1630 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex, E))
1631 return false;
1632 }
1633 return this->emitGetPtrGlobal(*GlobalIndex, E);
1634 }
1635
1636 // Non-primitive values.
1637 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1638 return false;
1639 if (!this->visitInitializer(SubExpr))
1640 return false;
1641 if (IsStatic)
1642 return this->emitInitGlobalTempComp(TempDecl, E);
1643 return true;
1644 }
1645
1646 // For everyhing else, use local variables.
1647 if (SubExprT) {
1648 if (std::optional<unsigned> LocalIndex = allocateLocalPrimitive(
1649 SubExpr, *SubExprT, /*IsConst=*/true, /*IsExtended=*/true)) {
1650 if (!this->visit(SubExpr))
1651 return false;
1652 this->emitSetLocal(*SubExprT, *LocalIndex, E);
1653 return this->emitGetPtrLocal(*LocalIndex, E);
1654 }
1655 } else {
1656 const Expr *Inner = E->getSubExpr()->skipRValueSubobjectAdjustments();
1657
1658 if (std::optional<unsigned> LocalIndex =
1659 allocateLocal(Inner, /*IsExtended=*/true)) {
1660 if (!this->emitGetPtrLocal(*LocalIndex, E))
1661 return false;
1662 return this->visitInitializer(SubExpr);
1663 }
1664 }
1665 return false;
1666}
1667
1668template <class Emitter>
1670 const CXXBindTemporaryExpr *E) {
1671 return this->delegate(E->getSubExpr());
1672}
1673
1674template <class Emitter>
1676 const CompoundLiteralExpr *E) {
1677 const Expr *Init = E->getInitializer();
1678 if (Initializing) {
1679 // We already have a value, just initialize that.
1680 return this->visitInitializer(Init);
1681 }
1682
1683 std::optional<PrimType> T = classify(E->getType());
1684 if (E->isFileScope()) {
1685 if (std::optional<unsigned> GlobalIndex = P.createGlobal(E)) {
1686 if (classify(E->getType()))
1687 return this->visit(Init);
1688 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1689 return false;
1690 return this->visitInitializer(Init);
1691 }
1692 }
1693
1694 // Otherwise, use a local variable.
1695 if (T) {
1696 // For primitive types, we just visit the initializer.
1697 return this->delegate(Init);
1698 } else {
1699 if (std::optional<unsigned> LocalIndex = allocateLocal(Init)) {
1700 if (!this->emitGetPtrLocal(*LocalIndex, E))
1701 return false;
1702 if (!this->visitInitializer(Init))
1703 return false;
1704 if (DiscardResult)
1705 return this->emitPopPtr(E);
1706 return true;
1707 }
1708 }
1709
1710 return false;
1711}
1712
1713template <class Emitter>
1715 if (DiscardResult)
1716 return true;
1717 if (E->getType()->isBooleanType())
1718 return this->emitConstBool(E->getValue(), E);
1719 return this->emitConst(E->getValue(), E);
1720}
1721
1722template <class Emitter>
1724 if (DiscardResult)
1725 return true;
1726
1727 assert(Initializing);
1728 const Record *R = P.getOrCreateRecord(E->getLambdaClass());
1729
1730 auto *CaptureInitIt = E->capture_init_begin();
1731 // Initialize all fields (which represent lambda captures) of the
1732 // record with their initializers.
1733 for (const Record::Field &F : R->fields()) {
1734 const Expr *Init = *CaptureInitIt;
1735 ++CaptureInitIt;
1736
1737 if (std::optional<PrimType> T = classify(Init)) {
1738 if (!this->visit(Init))
1739 return false;
1740
1741 if (!this->emitSetField(*T, F.Offset, E))
1742 return false;
1743 } else {
1744 if (!this->emitDupPtr(E))
1745 return false;
1746
1747 if (!this->emitGetPtrField(F.Offset, E))
1748 return false;
1749
1750 if (!this->visitInitializer(Init))
1751 return false;
1752
1753 if (!this->emitPopPtr(E))
1754 return false;
1755 }
1756 }
1757
1758 return true;
1759}
1760
1761template <class Emitter>
1763 if (DiscardResult)
1764 return true;
1765
1766 return this->delegate(E->getFunctionName());
1767}
1768
1769template <class Emitter>
1771 if (E->getSubExpr() && !this->discard(E->getSubExpr()))
1772 return false;
1773
1774 return this->emitInvalid(E);
1775}
1776
1777template <class Emitter>
1779 const CXXReinterpretCastExpr *E) {
1780 if (!this->discard(E->getSubExpr()))
1781 return false;
1782
1783 return this->emitInvalidCast(CastKind::Reinterpret, E);
1784}
1785
1786template <class Emitter>
1788 assert(E->getType()->isBooleanType());
1789
1790 if (DiscardResult)
1791 return true;
1792 return this->emitConstBool(E->getValue(), E);
1793}
1794
1795template <class Emitter>
1797 const CXXConstructExpr *E) {
1798 QualType T = E->getType();
1799 assert(!classify(T));
1800
1801 if (T->isRecordType()) {
1802 const CXXConstructorDecl *Ctor = E->getConstructor();
1803
1804 // Trivial zero initialization.
1805 if (E->requiresZeroInitialization() && Ctor->isTrivial()) {
1806 const Record *R = getRecord(E->getType());
1807 return this->visitZeroRecordInitializer(R, E);
1808 }
1809
1810 const Function *Func = getFunction(Ctor);
1811
1812 if (!Func)
1813 return false;
1814
1815 assert(Func->hasThisPointer());
1816 assert(!Func->hasRVO());
1817
1818 // If we're discarding a construct expression, we still need
1819 // to allocate a variable and call the constructor and destructor.
1820 if (DiscardResult) {
1821 assert(!Initializing);
1822 std::optional<unsigned> LocalIndex =
1823 allocateLocal(E, /*IsExtended=*/true);
1824
1825 if (!LocalIndex)
1826 return false;
1827
1828 if (!this->emitGetPtrLocal(*LocalIndex, E))
1829 return false;
1830 }
1831
1832 // The This pointer is already on the stack because this is an initializer,
1833 // but we need to dup() so the call() below has its own copy.
1834 if (!this->emitDupPtr(E))
1835 return false;
1836
1837 // Constructor arguments.
1838 for (const auto *Arg : E->arguments()) {
1839 if (!this->visit(Arg))
1840 return false;
1841 }
1842
1843 if (Func->isVariadic()) {
1844 uint32_t VarArgSize = 0;
1845 unsigned NumParams = Func->getNumWrittenParams();
1846 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I) {
1847 VarArgSize +=
1848 align(primSize(classify(E->getArg(I)->getType()).value_or(PT_Ptr)));
1849 }
1850 if (!this->emitCallVar(Func, VarArgSize, E))
1851 return false;
1852 } else {
1853 if (!this->emitCall(Func, 0, E))
1854 return false;
1855 }
1856
1857 // Immediately call the destructor if we have to.
1858 if (DiscardResult) {
1859 if (!this->emitRecordDestruction(getRecord(E->getType())))
1860 return false;
1861 if (!this->emitPopPtr(E))
1862 return false;
1863 }
1864 return true;
1865 }
1866
1867 if (T->isArrayType()) {
1868 const ConstantArrayType *CAT =
1869 Ctx.getASTContext().getAsConstantArrayType(E->getType());
1870 assert(CAT);
1871 size_t NumElems = CAT->getSize().getZExtValue();
1872 const Function *Func = getFunction(E->getConstructor());
1873 if (!Func || !Func->isConstexpr())
1874 return false;
1875
1876 // FIXME(perf): We're calling the constructor once per array element here,
1877 // in the old intepreter we had a special-case for trivial constructors.
1878 for (size_t I = 0; I != NumElems; ++I) {
1879 if (!this->emitConstUint64(I, E))
1880 return false;
1881 if (!this->emitArrayElemPtrUint64(E))
1882 return false;
1883
1884 // Constructor arguments.
1885 for (const auto *Arg : E->arguments()) {
1886 if (!this->visit(Arg))
1887 return false;
1888 }
1889
1890 if (!this->emitCall(Func, 0, E))
1891 return false;
1892 }
1893 return true;
1894 }
1895
1896 return false;
1897}
1898
1899template <class Emitter>
1901 if (DiscardResult)
1902 return true;
1903
1904 const APValue Val =
1905 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
1906
1907 // Things like __builtin_LINE().
1908 if (E->getType()->isIntegerType()) {
1909 assert(Val.isInt());
1910 const APSInt &I = Val.getInt();
1911 return this->emitConst(I, E);
1912 }
1913 // Otherwise, the APValue is an LValue, with only one element.
1914 // Theoretically, we don't need the APValue at all of course.
1915 assert(E->getType()->isPointerType());
1916 assert(Val.isLValue());
1917 const APValue::LValueBase &Base = Val.getLValueBase();
1918 if (const Expr *LValueExpr = Base.dyn_cast<const Expr *>())
1919 return this->visit(LValueExpr);
1920
1921 // Otherwise, we have a decl (which is the case for
1922 // __builtin_source_location).
1923 assert(Base.is<const ValueDecl *>());
1924 assert(Val.getLValuePath().size() == 0);
1925 const auto *BaseDecl = Base.dyn_cast<const ValueDecl *>();
1926 assert(BaseDecl);
1927
1928 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
1929
1930 std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(UGCD);
1931 if (!GlobalIndex)
1932 return false;
1933
1934 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1935 return false;
1936
1937 const Record *R = getRecord(E->getType());
1938 const APValue &V = UGCD->getValue();
1939 for (unsigned I = 0, N = R->getNumFields(); I != N; ++I) {
1940 const Record::Field *F = R->getField(I);
1941 const APValue &FieldValue = V.getStructField(I);
1942
1943 PrimType FieldT = classifyPrim(F->Decl->getType());
1944
1945 if (!this->visitAPValue(FieldValue, FieldT, E))
1946 return false;
1947 if (!this->emitInitField(FieldT, F->Offset, E))
1948 return false;
1949 }
1950
1951 // Leave the pointer to the global on the stack.
1952 return true;
1953}
1954
1955template <class Emitter>
1957 unsigned N = E->getNumComponents();
1958 if (N == 0)
1959 return false;
1960
1961 for (unsigned I = 0; I != N; ++I) {
1962 const OffsetOfNode &Node = E->getComponent(I);
1963 if (Node.getKind() == OffsetOfNode::Array) {
1964 const Expr *ArrayIndexExpr = E->getIndexExpr(Node.getArrayExprIndex());
1965 PrimType IndexT = classifyPrim(ArrayIndexExpr->getType());
1966
1967 if (DiscardResult) {
1968 if (!this->discard(ArrayIndexExpr))
1969 return false;
1970 continue;
1971 }
1972
1973 if (!this->visit(ArrayIndexExpr))
1974 return false;
1975 // Cast to Sint64.
1976 if (IndexT != PT_Sint64) {
1977 if (!this->emitCast(IndexT, PT_Sint64, E))
1978 return false;
1979 }
1980 }
1981 }
1982
1983 if (DiscardResult)
1984 return true;
1985
1986 PrimType T = classifyPrim(E->getType());
1987 return this->emitOffsetOf(T, E, E);
1988}
1989
1990template <class Emitter>
1992 const CXXScalarValueInitExpr *E) {
1993 QualType Ty = E->getType();
1994
1995 if (DiscardResult || Ty->isVoidType())
1996 return true;
1997
1998 if (std::optional<PrimType> T = classify(Ty))
1999 return this->visitZeroInitializer(*T, Ty, E);
2000
2001 assert(Ty->isAnyComplexType());
2002 if (!Initializing) {
2003 std::optional<unsigned> LocalIndex = allocateLocal(E, /*IsExtended=*/false);
2004 if (!LocalIndex)
2005 return false;
2006 if (!this->emitGetPtrLocal(*LocalIndex, E))
2007 return false;
2008 }
2009
2010 // Initialize both fields to 0.
2011 QualType ElemQT = Ty->getAs<ComplexType>()->getElementType();
2012 PrimType ElemT = classifyPrim(ElemQT);
2013
2014 for (unsigned I = 0; I != 2; ++I) {
2015 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2016 return false;
2017 if (!this->emitInitElem(ElemT, I, E))
2018 return false;
2019 }
2020 return true;
2021}
2022
2023template <class Emitter>
2025 return this->emitConst(E->getPackLength(), E);
2026}
2027
2028template <class Emitter>
2030 const GenericSelectionExpr *E) {
2031 return this->delegate(E->getResultExpr());
2032}
2033
2034template <class Emitter>
2036 return this->delegate(E->getChosenSubExpr());
2037}
2038
2039template <class Emitter>
2041 const ObjCBoolLiteralExpr *E) {
2042 if (DiscardResult)
2043 return true;
2044
2045 return this->emitConst(E->getValue(), E);
2046}
2047
2048template <class Emitter>
2050 const CXXInheritedCtorInitExpr *E) {
2051 const CXXConstructorDecl *Ctor = E->getConstructor();
2052 assert(!Ctor->isTrivial() &&
2053 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
2054 const Function *F = this->getFunction(Ctor);
2055 assert(F);
2056 assert(!F->hasRVO());
2057 assert(F->hasThisPointer());
2058
2059 if (!this->emitDupPtr(SourceInfo{}))
2060 return false;
2061
2062 // Forward all arguments of the current function (which should be a
2063 // constructor itself) to the inherited ctor.
2064 // This is necessary because the calling code has pushed the pointer
2065 // of the correct base for us already, but the arguments need
2066 // to come after.
2067 unsigned Offset = align(primSize(PT_Ptr)); // instance pointer.
2068 for (const ParmVarDecl *PD : Ctor->parameters()) {
2069 PrimType PT = this->classify(PD->getType()).value_or(PT_Ptr);
2070
2071 if (!this->emitGetParam(PT, Offset, E))
2072 return false;
2073 Offset += align(primSize(PT));
2074 }
2075
2076 return this->emitCall(F, 0, E);
2077}
2078
2079template <class Emitter>
2081 const ExpressionTraitExpr *E) {
2082 assert(Ctx.getLangOpts().CPlusPlus);
2083 return this->emitConstBool(E->getValue(), E);
2084}
2085
2086template <class Emitter>
2088 if (DiscardResult)
2089 return true;
2090 assert(!Initializing);
2091
2092 std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(E->getGuidDecl());
2093 if (!GlobalIndex)
2094 return false;
2095 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2096 return false;
2097
2098 const Record *R = this->getRecord(E->getType());
2099 assert(R);
2100
2101 const APValue &V = E->getGuidDecl()->getAsAPValue();
2102 if (V.getKind() == APValue::None)
2103 return true;
2104
2105 assert(V.isStruct());
2106 assert(V.getStructNumBases() == 0);
2107 // FIXME: This could be useful in visitAPValue, too.
2108 for (unsigned I = 0, N = V.getStructNumFields(); I != N; ++I) {
2109 const APValue &F = V.getStructField(I);
2110 const Record::Field *RF = R->getField(I);
2111
2112 if (F.isInt()) {
2113 PrimType T = classifyPrim(RF->Decl->getType());
2114 if (!this->visitAPValue(F, T, E))
2115 return false;
2116 if (!this->emitInitField(T, RF->Offset, E))
2117 return false;
2118 } else if (F.isArray()) {
2119 assert(RF->Desc->isPrimitiveArray());
2120 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
2121 PrimType ElemT = classifyPrim(ArrType->getElementType());
2122 assert(ArrType);
2123
2124 if (!this->emitDupPtr(E))
2125 return false;
2126 if (!this->emitGetPtrField(RF->Offset, E))
2127 return false;
2128
2129 for (unsigned A = 0, AN = F.getArraySize(); A != AN; ++A) {
2130 if (!this->visitAPValue(F.getArrayInitializedElt(A), ElemT, E))
2131 return false;
2132 if (!this->emitInitElem(ElemT, A, E))
2133 return false;
2134 }
2135
2136 if (!this->emitPopPtr(E))
2137 return false;
2138 } else {
2139 assert(false && "I don't think this should be possible");
2140 }
2141 }
2142
2143 return this->emitInitPtr(E);
2144}
2145
2146template <class Emitter>
2148 assert(classifyPrim(E->getType()) == PT_Bool);
2149 return this->emitConstBool(E->isSatisfied(), E);
2150}
2151
2152template <class Emitter>
2154 const ConceptSpecializationExpr *E) {
2155 assert(classifyPrim(E->getType()) == PT_Bool);
2156 return this->emitConstBool(E->isSatisfied(), E);
2157}
2158
2159template <class Emitter>
2161 const CXXRewrittenBinaryOperator *E) {
2162 return this->delegate(E->getSemanticForm());
2163}
2164
2165template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) {
2166 if (E->containsErrors())
2167 return false;
2168
2169 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
2170 /*NewInitializing=*/false);
2171 return this->Visit(E);
2172}
2173
2174template <class Emitter>
2176 if (E->containsErrors())
2177 return false;
2178
2179 // We're basically doing:
2180 // OptionScope<Emitter> Scope(this, DicardResult, Initializing);
2181 // but that's unnecessary of course.
2182 return this->Visit(E);
2183}
2184
2185template <class Emitter> bool ByteCodeExprGen<Emitter>::visit(const Expr *E) {
2186 if (E->containsErrors())
2187 return false;
2188
2189 if (E->getType()->isVoidType())
2190 return this->discard(E);
2191
2192 // Create local variable to hold the return value.
2193 if (!E->isGLValue() && !E->getType()->isAnyComplexType() &&
2194 !classify(E->getType())) {
2195 std::optional<unsigned> LocalIndex = allocateLocal(E, /*IsExtended=*/true);
2196 if (!LocalIndex)
2197 return false;
2198
2199 if (!this->emitGetPtrLocal(*LocalIndex, E))
2200 return false;
2201 return this->visitInitializer(E);
2202 }
2203
2204 // Otherwise,we have a primitive return value, produce the value directly
2205 // and push it on the stack.
2206 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
2207 /*NewInitializing=*/false);
2208 return this->Visit(E);
2209}
2210
2211template <class Emitter>
2213 assert(!classify(E->getType()));
2214
2215 if (E->containsErrors())
2216 return false;
2217
2218 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
2219 /*NewInitializing=*/true);
2220 return this->Visit(E);
2221}
2222
2223template <class Emitter>
2225 std::optional<PrimType> T = classify(E->getType());
2226 if (!T)
2227 return false;
2228
2229 if (!this->visit(E))
2230 return false;
2231
2232 if (T == PT_Bool)
2233 return true;
2234
2235 // Convert pointers to bool.
2236 if (T == PT_Ptr || T == PT_FnPtr) {
2237 if (!this->emitNull(*T, E))
2238 return false;
2239 return this->emitNE(*T, E);
2240 }
2241
2242 // Or Floats.
2243 if (T == PT_Float)
2244 return this->emitCastFloatingIntegralBool(E);
2245
2246 // Or anything else we can.
2247 return this->emitCast(*T, PT_Bool, E);
2248}
2249
2250template <class Emitter>
2252 const Expr *E) {
2253 switch (T) {
2254 case PT_Bool:
2255 return this->emitZeroBool(E);
2256 case PT_Sint8:
2257 return this->emitZeroSint8(E);
2258 case PT_Uint8:
2259 return this->emitZeroUint8(E);
2260 case PT_Sint16:
2261 return this->emitZeroSint16(E);
2262 case PT_Uint16:
2263 return this->emitZeroUint16(E);
2264 case PT_Sint32:
2265 return this->emitZeroSint32(E);
2266 case PT_Uint32:
2267 return this->emitZeroUint32(E);
2268 case PT_Sint64:
2269 return this->emitZeroSint64(E);
2270 case PT_Uint64:
2271 return this->emitZeroUint64(E);
2272 case PT_IntAP:
2273 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
2274 case PT_IntAPS:
2275 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
2276 case PT_Ptr:
2277 return this->emitNullPtr(E);
2278 case PT_FnPtr:
2279 return this->emitNullFnPtr(E);
2280 case PT_Float: {
2281 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E);
2282 }
2283 }
2284 llvm_unreachable("unknown primitive type");
2285}
2286
2287template <class Emitter>
2289 const Expr *E) {
2290 assert(E);
2291 assert(R);
2292 // Fields
2293 for (const Record::Field &Field : R->fields()) {
2294 const Descriptor *D = Field.Desc;
2295 if (D->isPrimitive()) {
2296 QualType QT = D->getType();
2297 PrimType T = classifyPrim(D->getType());
2298 if (!this->visitZeroInitializer(T, QT, E))
2299 return false;
2300 if (!this->emitInitField(T, Field.Offset, E))
2301 return false;
2302 continue;
2303 }
2304
2305 // TODO: Add GetPtrFieldPop and get rid of this dup.
2306 if (!this->emitDupPtr(E))
2307 return false;
2308 if (!this->emitGetPtrField(Field.Offset, E))
2309 return false;
2310
2311 if (D->isPrimitiveArray()) {
2312 QualType ET = D->getElemQualType();
2313 PrimType T = classifyPrim(ET);
2314 for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
2315 if (!this->visitZeroInitializer(T, ET, E))
2316 return false;
2317 if (!this->emitInitElem(T, I, E))
2318 return false;
2319 }
2320 } else if (D->isCompositeArray()) {
2321 const Record *ElemRecord = D->ElemDesc->ElemRecord;
2322 assert(D->ElemDesc->ElemRecord);
2323 for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
2324 if (!this->emitConstUint32(I, E))
2325 return false;
2326 if (!this->emitArrayElemPtr(PT_Uint32, E))
2327 return false;
2328 if (!this->visitZeroRecordInitializer(ElemRecord, E))
2329 return false;
2330 if (!this->emitPopPtr(E))
2331 return false;
2332 }
2333 } else if (D->isRecord()) {
2334 if (!this->visitZeroRecordInitializer(D->ElemRecord, E))
2335 return false;
2336 } else {
2337 assert(false);
2338 }
2339
2340 if (!this->emitPopPtr(E))
2341 return false;
2342 }
2343
2344 for (const Record::Base &B : R->bases()) {
2345 if (!this->emitGetPtrBase(B.Offset, E))
2346 return false;
2347 if (!this->visitZeroRecordInitializer(B.R, E))
2348 return false;
2349 if (!this->emitInitPtrPop(E))
2350 return false;
2351 }
2352
2353 // FIXME: Virtual bases.
2354
2355 return true;
2356}
2357
2358template <class Emitter>
2360 const Expr *LV, DerefKind AK, llvm::function_ref<bool(PrimType)> Direct,
2361 llvm::function_ref<bool(PrimType)> Indirect) {
2362 if (std::optional<PrimType> T = classify(LV->getType())) {
2363 if (!LV->refersToBitField()) {
2364 // Only primitive, non bit-field types can be dereferenced directly.
2365 if (const auto *DE = dyn_cast<DeclRefExpr>(LV)) {
2366 if (!DE->getDecl()->getType()->isReferenceType()) {
2367 if (const auto *PD = dyn_cast<ParmVarDecl>(DE->getDecl()))
2368 return dereferenceParam(LV, *T, PD, AK, Direct, Indirect);
2369 if (const auto *VD = dyn_cast<VarDecl>(DE->getDecl()))
2370 return dereferenceVar(LV, *T, VD, AK, Direct, Indirect);
2371 }
2372 }
2373 }
2374
2375 if (!visit(LV))
2376 return false;
2377 return Indirect(*T);
2378 }
2379
2380 if (LV->getType()->isAnyComplexType())
2381 return this->delegate(LV);
2382
2383 return false;
2384}
2385
2386template <class Emitter>
2388 const Expr *LV, PrimType T, const ParmVarDecl *PD, DerefKind AK,
2389 llvm::function_ref<bool(PrimType)> Direct,
2390 llvm::function_ref<bool(PrimType)> Indirect) {
2391 if (auto It = this->Params.find(PD); It != this->Params.end()) {
2392 unsigned Idx = It->second.Offset;
2393 switch (AK) {
2394 case DerefKind::Read:
2395 return DiscardResult ? true : this->emitGetParam(T, Idx, LV);
2396
2397 case DerefKind::Write:
2398 if (!Direct(T))
2399 return false;
2400 if (!this->emitSetParam(T, Idx, LV))
2401 return false;
2402 return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
2403
2404 case DerefKind::ReadWrite:
2405 if (!this->emitGetParam(T, Idx, LV))
2406 return false;
2407 if (!Direct(T))
2408 return false;
2409 if (!this->emitSetParam(T, Idx, LV))
2410 return false;
2411 return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
2412 }
2413 return true;
2414 }
2415
2416 // If the param is a pointer, we can dereference a dummy value.
2417 if (!DiscardResult && T == PT_Ptr && AK == DerefKind::Read) {
2418 if (auto Idx = P.getOrCreateDummy(PD))
2419 return this->emitGetPtrGlobal(*Idx, PD);
2420 return false;
2421 }
2422
2423 // Value cannot be produced - try to emit pointer and do stuff with it.
2424 return visit(LV) && Indirect(T);
2425}
2426
2427template <class Emitter>
2429 const Expr *LV, PrimType T, const VarDecl *VD, DerefKind AK,
2430 llvm::function_ref<bool(PrimType)> Direct,
2431 llvm::function_ref<bool(PrimType)> Indirect) {
2432 auto It = Locals.find(VD);
2433 if (It != Locals.end()) {
2434 const auto &L = It->second;
2435 switch (AK) {
2436 case DerefKind::Read:
2437 if (!this->emitGetLocal(T, L.Offset, LV))
2438 return false;
2439 return DiscardResult ? this->emitPop(T, LV) : true;
2440
2441 case DerefKind::Write:
2442 if (!Direct(T))
2443 return false;
2444 if (!this->emitSetLocal(T, L.Offset, LV))
2445 return false;
2446 return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV);
2447
2448 case DerefKind::ReadWrite:
2449 if (!this->emitGetLocal(T, L.Offset, LV))
2450 return false;
2451 if (!Direct(T))
2452 return false;
2453 if (!this->emitSetLocal(T, L.Offset, LV))
2454 return false;
2455 return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV);
2456 }
2457 } else if (auto Idx = P.getGlobal(VD)) {
2458 switch (AK) {
2459 case DerefKind::Read:
2460 if (!this->emitGetGlobal(T, *Idx, LV))
2461 return false;
2462 return DiscardResult ? this->emitPop(T, LV) : true;
2463
2464 case DerefKind::Write:
2465 if (!Direct(T))
2466 return false;
2467 if (!this->emitSetGlobal(T, *Idx, LV))
2468 return false;
2469 return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV);
2470
2471 case DerefKind::ReadWrite:
2472 if (!this->emitGetGlobal(T, *Idx, LV))
2473 return false;
2474 if (!Direct(T))
2475 return false;
2476 if (!this->emitSetGlobal(T, *Idx, LV))
2477 return false;
2478 return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV);
2479 }
2480 }
2481
2482 // Value cannot be produced - try to emit pointer.
2483 return visit(LV) && Indirect(T);
2484}
2485
2486template <class Emitter>
2487template <typename T>
2489 switch (Ty) {
2490 case PT_Sint8:
2491 return this->emitConstSint8(Value, E);
2492 case PT_Uint8:
2493 return this->emitConstUint8(Value, E);
2494 case PT_Sint16:
2495 return this->emitConstSint16(Value, E);
2496 case PT_Uint16:
2497 return this->emitConstUint16(Value, E);
2498 case PT_Sint32:
2499 return this->emitConstSint32(Value, E);
2500 case PT_Uint32:
2501 return this->emitConstUint32(Value, E);
2502 case PT_Sint64:
2503 return this->emitConstSint64(Value, E);
2504 case PT_Uint64:
2505 return this->emitConstUint64(Value, E);
2506 case PT_Bool:
2507 return this->emitConstBool(Value, E);
2508 case PT_Ptr:
2509 case PT_FnPtr:
2510 case PT_Float:
2511 case PT_IntAP:
2512 case PT_IntAPS:
2513 llvm_unreachable("Invalid integral type");
2514 break;
2515 }
2516 llvm_unreachable("unknown primitive type");
2517}
2518
2519template <class Emitter>
2520template <typename T>
2522 return this->emitConst(Value, classifyPrim(E->getType()), E);
2523}
2524
2525template <class Emitter>
2527 const Expr *E) {
2528 if (Ty == PT_IntAPS)
2529 return this->emitConstIntAPS(Value, E);
2530 if (Ty == PT_IntAP)
2531 return this->emitConstIntAP(Value, E);
2532
2533 if (Value.isSigned())
2534 return this->emitConst(Value.getSExtValue(), Ty, E);
2535 return this->emitConst(Value.getZExtValue(), Ty, E);
2536}
2537
2538template <class Emitter>
2540 return this->emitConst(Value, classifyPrim(E->getType()), E);
2541}
2542
2543template <class Emitter>
2545 PrimType Ty,
2546 bool IsConst,
2547 bool IsExtended) {
2548 // Make sure we don't accidentally register the same decl twice.
2549 if (const auto *VD =
2550 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
2551 assert(!P.getGlobal(VD));
2552 assert(!Locals.contains(VD));
2553 }
2554
2555 // FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
2556 // (int){12} in C. Consider using Expr::isTemporaryObject() instead
2557 // or isa<MaterializeTemporaryExpr>().
2558 Descriptor *D = P.createDescriptor(Src, Ty, Descriptor::InlineDescMD, IsConst,
2559 Src.is<const Expr *>());
2560 Scope::Local Local = this->createLocal(D);
2561 if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>()))
2562 Locals.insert({VD, Local});
2563 VarScope->add(Local, IsExtended);
2564 return Local.Offset;
2565}
2566
2567template <class Emitter>
2568std::optional<unsigned>
2570 // Make sure we don't accidentally register the same decl twice.
2571 if ([[maybe_unused]] const auto *VD =
2572 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
2573 assert(!P.getGlobal(VD));
2574 assert(!Locals.contains(VD));
2575 }
2576
2577 QualType Ty;
2578 const ValueDecl *Key = nullptr;
2579 const Expr *Init = nullptr;
2580 bool IsTemporary = false;
2581 if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
2582 Key = VD;
2583 Ty = VD->getType();
2584
2585 if (const auto *VarD = dyn_cast<VarDecl>(VD))
2586 Init = VarD->getInit();
2587 }
2588 if (auto *E = Src.dyn_cast<const Expr *>()) {
2589 IsTemporary = true;
2590 Ty = E->getType();
2591 }
2592
2593 Descriptor *D = P.createDescriptor(
2595 IsTemporary, /*IsMutable=*/false, Init);
2596 if (!D)
2597 return std::nullopt;
2598
2599 Scope::Local Local = this->createLocal(D);
2600 if (Key)
2601 Locals.insert({Key, Local});
2602 VarScope->add(Local, IsExtended);
2603 return Local.Offset;
2604}
2605
2606template <class Emitter>
2608 if (const PointerType *PT = dyn_cast<PointerType>(Ty))
2609 return PT->getPointeeType()->getAs<RecordType>();
2610 return Ty->getAs<RecordType>();
2611}
2612
2613template <class Emitter>
2615 if (const auto *RecordTy = getRecordTy(Ty))
2616 return getRecord(RecordTy->getDecl());
2617 return nullptr;
2618}
2619
2620template <class Emitter>
2622 return P.getOrCreateRecord(RD);
2623}
2624
2625template <class Emitter>
2627 return Ctx.getOrCreateFunction(FD);
2628}
2629
2630template <class Emitter>
2632 ExprScope<Emitter> RootScope(this);
2633 // Void expressions.
2634 if (E->getType()->isVoidType()) {
2635 if (!visit(E))
2636 return false;
2637 return this->emitRetVoid(E);
2638 }
2639
2640 // Expressions with a primitive return type.
2641 if (std::optional<PrimType> T = classify(E)) {
2642 if (!visit(E))
2643 return false;
2644 return this->emitRet(*T, E);
2645 }
2646
2647 // Expressions with a composite return type.
2648 // For us, that means everything we don't
2649 // have a PrimType for.
2650 if (std::optional<unsigned> LocalOffset = this->allocateLocal(E)) {
2651 if (!this->emitGetPtrLocal(*LocalOffset, E))
2652 return false;
2653
2654 if (!visitInitializer(E))
2655 return false;
2656
2657 if (!this->emitInitPtr(E))
2658 return false;
2659 return this->emitRetValue(E);
2660 }
2661
2662 return false;
2663}
2664
2665/// Toplevel visitDecl().
2666/// We get here from evaluateAsInitializer().
2667/// We need to evaluate the initializer and return its value.
2668template <class Emitter>
2670 assert(!VD->isInvalidDecl() && "Trying to constant evaluate an invalid decl");
2671
2672 // Create and initialize the variable.
2673 if (!this->visitVarDecl(VD))
2674 return false;
2675
2676 std::optional<PrimType> VarT = classify(VD->getType());
2677 // Get a pointer to the variable
2679 auto GlobalIndex = P.getGlobal(VD);
2680 assert(GlobalIndex); // visitVarDecl() didn't return false.
2681 if (VarT) {
2682 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
2683 return false;
2684 } else {
2685 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
2686 return false;
2687 }
2688 } else {
2689 auto Local = Locals.find(VD);
2690 assert(Local != Locals.end()); // Same here.
2691 if (VarT) {
2692 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
2693 return false;
2694 } else {
2695 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
2696 return false;
2697 }
2698 }
2699
2700 // Return the value
2701 if (VarT)
2702 return this->emitRet(*VarT, VD);
2703
2704 // Return non-primitive values as pointers here.
2705 return this->emitRet(PT_Ptr, VD);
2706}
2707
2708template <class Emitter>
2710 // We don't know what to do with these, so just return false.
2711 if (VD->getType().isNull())
2712 return false;
2713
2714 const Expr *Init = VD->getInit();
2715 std::optional<PrimType> VarT = classify(VD->getType());
2716
2718 // We've already seen and initialized this global.
2719 if (P.getGlobal(VD))
2720 return true;
2721
2722 std::optional<unsigned> GlobalIndex = P.createGlobal(VD, Init);
2723
2724 if (!GlobalIndex)
2725 return false;
2726
2727 assert(Init);
2728 {
2730
2731 if (VarT) {
2732 if (!this->visit(Init))
2733 return false;
2734 return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
2735 }
2736 return this->visitGlobalInitializer(Init, *GlobalIndex);
2737 }
2738 } else {
2740 if (VarT) {
2741 unsigned Offset = this->allocateLocalPrimitive(
2742 VD, *VarT, VD->getType().isConstQualified());
2743 if (Init) {
2744 // Compile the initializer in its own scope.
2746 if (!this->visit(Init))
2747 return false;
2748
2749 return this->emitSetLocal(*VarT, Offset, VD);
2750 }
2751 } else {
2752 if (std::optional<unsigned> Offset = this->allocateLocal(VD))
2753 return !Init || this->visitLocalInitializer(Init, *Offset);
2754 return false;
2755 }
2756 return true;
2757 }
2758
2759 return false;
2760}
2761
2762template <class Emitter>
2764 PrimType ValType, const Expr *E) {
2765 assert(!DiscardResult);
2766 if (Val.isInt())
2767 return this->emitConst(Val.getInt(), ValType, E);
2768
2769 if (Val.isLValue()) {
2771 if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>())
2772 return this->visit(BaseExpr);
2773 }
2774
2775 return false;
2776}
2777
2778template <class Emitter>
2780 const Function *Func = getFunction(E->getDirectCallee());
2781 if (!Func)
2782 return false;
2783
2784 if (!Func->isUnevaluatedBuiltin()) {
2785 // Put arguments on the stack.
2786 for (const auto *Arg : E->arguments()) {
2787 if (!this->visit(Arg))
2788 return false;
2789 }
2790 }
2791
2792 if (!this->emitCallBI(Func, E, E))
2793 return false;
2794
2795 QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
2796 if (DiscardResult && !ReturnType->isVoidType()) {
2797 PrimType T = classifyPrim(ReturnType);
2798 return this->emitPop(T, E);
2799 }
2800
2801 return true;
2802}
2803
2804template <class Emitter>
2806 if (E->getBuiltinCallee())
2807 return VisitBuiltinCallExpr(E);
2808
2809 QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
2810 std::optional<PrimType> T = classify(ReturnType);
2811 bool HasRVO = !ReturnType->isVoidType() && !T;
2812
2813 if (HasRVO) {
2814 if (DiscardResult) {
2815 // If we need to discard the return value but the function returns its
2816 // value via an RVO pointer, we need to create one such pointer just
2817 // for this call.
2818 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
2819 if (!this->emitGetPtrLocal(*LocalIndex, E))
2820 return false;
2821 }
2822 } else {
2823 assert(Initializing);
2824 if (!this->emitDupPtr(E))
2825 return false;
2826 }
2827 }
2828
2829 auto Args = E->arguments();
2830 // Calling a static operator will still
2831 // pass the instance, but we don't need it.
2832 // Discard it here.
2833 if (isa<CXXOperatorCallExpr>(E)) {
2834 if (const auto *MD =
2835 dyn_cast_if_present<CXXMethodDecl>(E->getDirectCallee());
2836 MD && MD->isStatic()) {
2837 if (!this->discard(E->getArg(0)))
2838 return false;
2839 Args = drop_begin(Args, 1);
2840 }
2841 }
2842
2843 // Add the (optional, implicit) This pointer.
2844 if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
2845 if (!this->visit(MC->getImplicitObjectArgument()))
2846 return false;
2847 }
2848
2849 // Put arguments on the stack.
2850 for (const auto *Arg : Args) {
2851 if (!this->visit(Arg))
2852 return false;
2853 }
2854
2855 if (const FunctionDecl *FuncDecl = E->getDirectCallee()) {
2856 const Function *Func = getFunction(FuncDecl);
2857 if (!Func)
2858 return false;
2859 assert(HasRVO == Func->hasRVO());
2860
2861 bool HasQualifier = false;
2862 if (const auto *ME = dyn_cast<MemberExpr>(E->getCallee()))
2863 HasQualifier = ME->hasQualifier();
2864
2865 bool IsVirtual = false;
2866 if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
2867 IsVirtual = MD->isVirtual();
2868
2869 // In any case call the function. The return value will end up on the stack
2870 // and if the function has RVO, we already have the pointer on the stack to
2871 // write the result into.
2872 if (IsVirtual && !HasQualifier) {
2873 uint32_t VarArgSize = 0;
2874 unsigned NumParams = Func->getNumWrittenParams();
2875 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
2876 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
2877
2878 if (!this->emitCallVirt(Func, VarArgSize, E))
2879 return false;
2880 } else if (Func->isVariadic()) {
2881 uint32_t VarArgSize = 0;
2882 unsigned NumParams = Func->getNumWrittenParams();
2883 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
2884 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
2885 if (!this->emitCallVar(Func, VarArgSize, E))
2886 return false;
2887 } else {
2888 if (!this->emitCall(Func, 0, E))
2889 return false;
2890 }
2891 } else {
2892 // Indirect call. Visit the callee, which will leave a FunctionPointer on
2893 // the stack. Cleanup of the returned value if necessary will be done after
2894 // the function call completed.
2895
2896 // Sum the size of all args from the call expr.
2897 uint32_t ArgSize = 0;
2898 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
2899 ArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
2900
2901 if (!this->visit(E->getCallee()))
2902 return false;
2903
2904 if (!this->emitCallPtr(ArgSize, E))
2905 return false;
2906 }
2907
2908 // Cleanup for discarded return values.
2909 if (DiscardResult && !ReturnType->isVoidType() && T)
2910 return this->emitPop(*T, E);
2911
2912 return true;
2913}
2914
2915template <class Emitter>
2917 const CXXDefaultInitExpr *E) {
2918 SourceLocScope<Emitter> SLS(this, E);
2919 if (Initializing)
2920 return this->visitInitializer(E->getExpr());
2921
2922 assert(classify(E->getType()));
2923 return this->visit(E->getExpr());
2924}
2925
2926template <class Emitter>
2928 const CXXDefaultArgExpr *E) {
2929 SourceLocScope<Emitter> SLS(this, E);
2930
2931 const Expr *SubExpr = E->getExpr();
2932 if (std::optional<PrimType> T = classify(E->getExpr()))
2933 return this->visit(SubExpr);
2934
2935 assert(Initializing);
2936 return this->visitInitializer(SubExpr);
2937}
2938
2939template <class Emitter>
2941 const CXXBoolLiteralExpr *E) {
2942 if (DiscardResult)
2943 return true;
2944
2945 return this->emitConstBool(E->getValue(), E);
2946}
2947
2948template <class Emitter>
2950 const CXXNullPtrLiteralExpr *E) {
2951 if (DiscardResult)
2952 return true;
2953
2954 return this->emitNullPtr(E);
2955}
2956
2957template <class Emitter>
2959 if (DiscardResult)
2960 return true;
2961
2962 assert(E->getType()->isIntegerType());
2963
2964 PrimType T = classifyPrim(E->getType());
2965 return this->emitZero(T, E);
2966}
2967
2968template <class Emitter>
2970 if (DiscardResult)
2971 return true;
2972
2973 if (this->LambdaThisCapture > 0)
2974 return this->emitGetThisFieldPtr(this->LambdaThisCapture, E);
2975
2976 return this->emitThis(E);
2977}
2978
2979template <class Emitter>
2981 const Expr *SubExpr = E->getSubExpr();
2982 std::optional<PrimType> T = classify(SubExpr->getType());
2983
2984 switch (E->getOpcode()) {
2985 case UO_PostInc: { // x++
2986 if (!this->visit(SubExpr))
2987 return false;
2988
2989 if (T == PT_Ptr) {
2990 if (!this->emitIncPtr(E))
2991 return false;
2992
2993 return DiscardResult ? this->emitPopPtr(E) : true;
2994 }
2995
2996 if (T == PT_Float) {
2997 return DiscardResult ? this->emitIncfPop(getRoundingMode(E), E)
2998 : this->emitIncf(getRoundingMode(E), E);
2999 }
3000
3001 return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E);
3002 }
3003 case UO_PostDec: { // x--
3004 if (!this->visit(SubExpr))
3005 return false;
3006
3007 if (T == PT_Ptr) {
3008 if (!this->emitDecPtr(E))
3009 return false;
3010
3011 return DiscardResult ? this->emitPopPtr(E) : true;
3012 }
3013
3014 if (T == PT_Float) {
3015 return DiscardResult ? this->emitDecfPop(getRoundingMode(E), E)
3016 : this->emitDecf(getRoundingMode(E), E);
3017 }
3018
3019 return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E);
3020 }
3021 case UO_PreInc: { // ++x
3022 if (!this->visit(SubExpr))
3023 return false;
3024
3025 if (T == PT_Ptr) {
3026 if (!this->emitLoadPtr(E))
3027 return false;
3028 if (!this->emitConstUint8(1, E))
3029 return false;
3030 if (!this->emitAddOffsetUint8(E))
3031 return false;
3032 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
3033 }
3034
3035 // Post-inc and pre-inc are the same if the value is to be discarded.
3036 if (DiscardResult) {
3037 if (T == PT_Float)
3038 return this->emitIncfPop(getRoundingMode(E), E);
3039 return this->emitIncPop(*T, E);
3040 }
3041
3042 if (T == PT_Float) {
3043 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
3044 if (!this->emitLoadFloat(E))
3045 return false;
3046 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
3047 return false;
3048 if (!this->emitAddf(getRoundingMode(E), E))
3049 return false;
3050 return this->emitStoreFloat(E);
3051 }
3052 if (!this->emitLoad(*T, E))
3053 return false;
3054 if (!this->emitConst(1, E))
3055 return false;
3056 if (!this->emitAdd(*T, E))
3057 return false;
3058 return this->emitStore(*T, E);
3059 }
3060 case UO_PreDec: { // --x
3061 if (!this->visit(SubExpr))
3062 return false;
3063
3064 if (T == PT_Ptr) {
3065 if (!this->emitLoadPtr(E))
3066 return false;
3067 if (!this->emitConstUint8(1, E))
3068 return false;
3069 if (!this->emitSubOffsetUint8(E))
3070 return false;
3071 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
3072 }
3073
3074 // Post-dec and pre-dec are the same if the value is to be discarded.
3075 if (DiscardResult) {
3076 if (T == PT_Float)
3077 return this->emitDecfPop(getRoundingMode(E), E);
3078 return this->emitDecPop(*T, E);
3079 }
3080
3081 if (T == PT_Float) {
3082 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
3083 if (!this->emitLoadFloat(E))
3084 return false;
3085 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
3086 return false;
3087 if (!this->emitSubf(getRoundingMode(E), E))
3088 return false;
3089 return this->emitStoreFloat(E);
3090 }
3091 if (!this->emitLoad(*T, E))
3092 return false;
3093 if (!this->emitConst(1, E))
3094 return false;
3095 if (!this->emitSub(*T, E))
3096 return false;
3097 return this->emitStore(*T, E);
3098 }
3099 case UO_LNot: // !x
3100 if (DiscardResult)
3101 return this->discard(SubExpr);
3102
3103 if (!this->visitBool(SubExpr))
3104 return false;
3105
3106 if (!this->emitInvBool(E))
3107 return false;
3108
3109 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
3110 return this->emitCast(PT_Bool, ET, E);
3111 return true;
3112 case UO_Minus: // -x
3113 if (!this->visit(SubExpr))
3114 return false;
3115 return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
3116 case UO_Plus: // +x
3117 if (!this->visit(SubExpr)) // noop
3118 return false;
3119 return DiscardResult ? this->emitPop(*T, E) : true;
3120 case UO_AddrOf: // &x
3121 // We should already have a pointer when we get here.
3122 return this->delegate(SubExpr);
3123 case UO_Deref: // *x
3124 return dereference(
3125 SubExpr, DerefKind::Read,
3126 [](PrimType) {
3127 llvm_unreachable("Dereferencing requires a pointer");
3128 return false;
3129 },
3130 [this, E](PrimType T) {
3131 return DiscardResult ? this->emitPop(T, E) : true;
3132 });
3133 case UO_Not: // ~x
3134 if (!this->visit(SubExpr))
3135 return false;
3136 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
3137 case UO_Real: // __real x
3138 if (T)
3139 return this->delegate(SubExpr);
3140 return this->emitComplexReal(SubExpr);
3141 case UO_Imag: { // __imag x
3142 if (T) {
3143 if (!this->discard(SubExpr))
3144 return false;
3145 return this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);
3146 }
3147
3148 if (!this->visit(SubExpr))
3149 return false;
3150 if (!this->emitConstUint8(1, E))
3151 return false;
3152 if (!this->emitArrayElemPtrPopUint8(E))
3153 return false;
3154
3155 // Since our _Complex implementation does not map to a primitive type,
3156 // we sometimes have to do the lvalue-to-rvalue conversion here manually.
3157 if (!SubExpr->isLValue())
3158 return this->emitLoadPop(classifyPrim(E->getType()), E);
3159 return true;
3160 }
3161 case UO_Extension:
3162 return this->delegate(SubExpr);
3163 case UO_Coawait:
3164 assert(false && "Unhandled opcode");
3165 }
3166
3167 return false;
3168}
3169
3170template <class Emitter>
3172 if (DiscardResult)
3173 return true;
3174
3175 const auto *D = E->getDecl();
3176
3177 if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
3178 return this->emitConst(ECD->getInitVal(), E);
3179 } else if (const auto *BD = dyn_cast<BindingDecl>(D)) {
3180 return this->visit(BD->getBinding());
3181 } else if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
3182 const Function *F = getFunction(FuncDecl);
3183 return F && this->emitGetFnPtr(F, E);
3184 } else if (isa<TemplateParamObjectDecl>(D)) {
3185 if (std::optional<unsigned> Index = P.getOrCreateGlobal(D))
3186 return this->emitGetPtrGlobal(*Index, E);
3187 return false;
3188 }
3189
3190 // References are implemented via pointers, so when we see a DeclRefExpr
3191 // pointing to a reference, we need to get its value directly (i.e. the
3192 // pointer to the actual value) instead of a pointer to the pointer to the
3193 // value.
3194 bool IsReference = D->getType()->isReferenceType();
3195 // Complex values are copied in the AST via a simply assignment or
3196 // ltor cast. But we represent them as two-element arrays, which means
3197 // we pass them around as pointers. So, to assignm from them, we will
3198 // have to copy both (primitive) elements instead.
3199 bool IsComplex = D->getType()->isAnyComplexType();
3200
3201 // Check for local/global variables and parameters.
3202 if (auto It = Locals.find(D); It != Locals.end()) {
3203 const unsigned Offset = It->second.Offset;
3204 // FIXME: Fix the code duplication here with the code in the global case.
3205 if (Initializing && IsComplex) {
3206 PrimType ElemT = classifyComplexElementType(D->getType());
3207 for (unsigned I = 0; I != 2; ++I) {
3208 if (!this->emitGetPtrLocal(Offset, E))
3209 return false;
3210 if (!this->emitArrayElemPop(ElemT, I, E))
3211 return false;
3212 if (!this->emitInitElem(ElemT, I, E))
3213 return false;
3214 }
3215 return true;
3216 }
3217
3218 if (IsReference)
3219 return this->emitGetLocal(PT_Ptr, Offset, E);
3220 return this->emitGetPtrLocal(Offset, E);
3221 } else if (auto GlobalIndex = P.getGlobal(D)) {
3222 if (Initializing && IsComplex) {
3223 PrimType ElemT = classifyComplexElementType(D->getType());
3224 for (unsigned I = 0; I != 2; ++I) {
3225 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3226 return false;
3227 if (!this->emitArrayElemPop(ElemT, I, E))
3228 return false;
3229 if (!this->emitInitElem(ElemT, I, E))
3230 return false;
3231 }
3232 return true;
3233 }
3234
3235 if (IsReference)
3236 return this->emitGetGlobalPtr(*GlobalIndex, E);
3237
3238 return this->emitGetPtrGlobal(*GlobalIndex, E);
3239 } else if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
3240 if (auto It = this->Params.find(PVD); It != this->Params.end()) {
3241 // FIXME: _Complex initializing case?
3242 if (IsReference || !It->second.IsPtr)
3243 return this->emitGetParamPtr(It->second.Offset, E);
3244
3245 return this->emitGetPtrParam(It->second.Offset, E);
3246 }
3247 }
3248
3249 // Handle lambda captures.
3250 if (auto It = this->LambdaCaptures.find(D);
3251 It != this->LambdaCaptures.end()) {
3252 auto [Offset, IsPtr] = It->second;
3253
3254 if (IsPtr)
3255 return this->emitGetThisFieldPtr(Offset, E);
3256 return this->emitGetPtrThisField(Offset, E);
3257 }
3258
3259 // Try to lazily visit (or emit dummy pointers for) declarations
3260 // we haven't seen yet.
3261 if (Ctx.getLangOpts().CPlusPlus) {
3262 if (const auto *VD = dyn_cast<VarDecl>(D)) {
3263 // Dummy for static locals
3264 if (VD->isStaticLocal()) {
3265 if (std::optional<unsigned> I = P.getOrCreateDummy(D))
3266 return this->emitGetPtrGlobal(*I, E);
3267 return false;
3268 }
3269 // Visit local const variables like normal.
3270 if (VD->isLocalVarDecl() && VD->getType().isConstQualified()) {
3271 if (!this->visitVarDecl(VD))
3272 return false;
3273 // Retry.
3274 return this->VisitDeclRefExpr(E);
3275 }
3276 }
3277 } else {
3278 if (const auto *VD = dyn_cast<VarDecl>(D);
3279 VD && VD->getAnyInitializer() && VD->getType().isConstQualified()) {
3280 if (!this->visitVarDecl(VD))
3281 return false;
3282 // Retry.
3283 return this->VisitDeclRefExpr(E);
3284 }
3285
3286 if (std::optional<unsigned> I = P.getOrCreateDummy(D))
3287 return this->emitGetPtrGlobal(*I, E);
3288 }
3289
3290 return this->emitInvalidDeclRef(E, E);
3291}
3292
3293template <class Emitter>
3295 for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent())
3296 C->emitDestruction();
3297}
3298
3299template <class Emitter>
3300unsigned
3302 const RecordType *DerivedType) {
3303 const auto *FinalDecl = cast<CXXRecordDecl>(BaseType->getDecl());
3304 const RecordDecl *CurDecl = DerivedType->getDecl();
3305 const Record *CurRecord = getRecord(CurDecl);
3306 assert(CurDecl && FinalDecl);
3307
3308 unsigned OffsetSum = 0;
3309 for (;;) {
3310 assert(CurRecord->getNumBases() > 0);
3311 // One level up
3312 for (const Record::Base &B : CurRecord->bases()) {
3313 const auto *BaseDecl = cast<CXXRecordDecl>(B.Decl);
3314
3315 if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) {
3316 OffsetSum += B.Offset;
3317 CurRecord = B.R;
3318 CurDecl = BaseDecl;
3319 break;
3320 }
3321 }
3322 if (CurDecl == FinalDecl)
3323 break;
3324 }
3325
3326 assert(OffsetSum > 0);
3327 return OffsetSum;
3328}
3329
3330/// Emit casts from a PrimType to another PrimType.
3331template <class Emitter>
3333 QualType ToQT, const Expr *E) {
3334
3335 if (FromT == PT_Float) {
3336 // Floating to floating.
3337 if (ToT == PT_Float) {
3338 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
3339 return this->emitCastFP(ToSem, getRoundingMode(E), E);
3340 }
3341
3342 // Float to integral.
3343 if (isIntegralType(ToT) || ToT == PT_Bool)
3344 return this->emitCastFloatingIntegral(ToT, E);
3345 }
3346
3347 if (isIntegralType(FromT) || FromT == PT_Bool) {
3348 // Integral to integral.
3349 if (isIntegralType(ToT) || ToT == PT_Bool)
3350 return FromT != ToT ? this->emitCast(FromT, ToT, E) : true;
3351
3352 if (ToT == PT_Float) {
3353 // Integral to floating.
3354 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
3355 return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(E),
3356 E);
3357 }
3358 }
3359
3360 return false;
3361}
3362
3363/// Emits __real(SubExpr)
3364template <class Emitter>
3366 assert(SubExpr->getType()->isAnyComplexType());
3367
3368 if (DiscardResult)
3369 return this->discard(SubExpr);
3370
3371 if (!this->visit(SubExpr))
3372 return false;
3373 if (!this->emitConstUint8(0, SubExpr))
3374 return false;
3375 if (!this->emitArrayElemPtrPopUint8(SubExpr))
3376 return false;
3377
3378 // Since our _Complex implementation does not map to a primitive type,
3379 // we sometimes have to do the lvalue-to-rvalue conversion here manually.
3380 if (!SubExpr->isLValue())
3381 return this->emitLoadPop(classifyComplexElementType(SubExpr->getType()),
3382 SubExpr);
3383 return true;
3384}
3385
3386template <class Emitter>
3388 assert(R);
3389 // First, destroy all fields.
3390 for (const Record::Field &Field : llvm::reverse(R->fields())) {
3391 const Descriptor *D = Field.Desc;
3392 if (!D->isPrimitive() && !D->isPrimitiveArray()) {
3393 if (!this->emitDupPtr(SourceInfo{}))
3394 return false;
3395 if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
3396 return false;
3397 if (!this->emitDestruction(D))
3398 return false;
3399 if (!this->emitPopPtr(SourceInfo{}))
3400 return false;
3401 }
3402 }
3403
3404 // FIXME: Unions need to be handled differently here. We don't want to
3405 // call the destructor of its members.
3406
3407 // Now emit the destructor and recurse into base classes.
3408 if (const CXXDestructorDecl *Dtor = R->getDestructor();
3409 Dtor && !Dtor->isTrivial()) {
3410 if (const Function *DtorFunc = getFunction(Dtor)) {
3411 assert(DtorFunc->hasThisPointer());
3412 assert(DtorFunc->getNumParams() == 1);
3413 if (!this->emitDupPtr(SourceInfo{}))
3414 return false;
3415 if (!this->emitCall(DtorFunc, 0, SourceInfo{}))
3416 return false;
3417 }
3418 }
3419
3420 for (const Record::Base &Base : llvm::reverse(R->bases())) {
3421 if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
3422 return false;
3423 if (!this->emitRecordDestruction(Base.R))
3424 return false;
3425 if (!this->emitPopPtr(SourceInfo{}))
3426 return false;
3427 }
3428
3429 // FIXME: Virtual bases.
3430 return true;
3431}
3432/// When calling this, we have a pointer of the local-to-destroy
3433/// on the stack.
3434/// Emit destruction of record types (or arrays of record types).
3435template <class Emitter>
3437 assert(Desc);
3438 assert(!Desc->isPrimitive());
3439 assert(!Desc->isPrimitiveArray());
3440
3441 // Arrays.
3442 if (Desc->isArray()) {
3443 const Descriptor *ElemDesc = Desc->ElemDesc;
3444 assert(ElemDesc);
3445
3446 // Don't need to do anything for these.
3447 if (ElemDesc->isPrimitiveArray())
3448 return true;
3449
3450 // If this is an array of record types, check if we need
3451 // to call the element destructors at all. If not, try
3452 // to save the work.
3453 if (const Record *ElemRecord = ElemDesc->ElemRecord) {
3454 if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
3455 !Dtor || Dtor->isTrivial())
3456 return true;
3457 }
3458
3459 for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) {
3460 if (!this->emitConstUint64(I, SourceInfo{}))
3461 return false;
3462 if (!this->emitArrayElemPtrUint64(SourceInfo{}))
3463 return false;
3464 if (!this->emitDestruction(ElemDesc))
3465 return false;
3466 if (!this->emitPopPtr(SourceInfo{}))
3467 return false;
3468 }
3469 return true;
3470 }
3471
3472 assert(Desc->ElemRecord);
3473 return this->emitRecordDestruction(Desc->ElemRecord);
3474}
3475
3476namespace clang {
3477namespace interp {
3478
3480template class ByteCodeExprGen<EvalEmitter>;
3481
3482} // namespace interp
3483} // namespace clang
#define V(N, I)
Definition: ASTContext.h:3255
ASTImporterLookupTable & LT
DynTypedNode Node
StringRef P
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
llvm::APSInt APSInt
bool IsStatic
Definition: Format.cpp:2974
static std::optional< DereferenceInfo > dereference(ProgramStateRef State, const FieldRegion *FR)
Dereferences FR and returns with the pointee's region, and whether it needs to be casted back to it's...
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
const LValueBase getLValueBase() const
Definition: APValue.cpp:970
APValue & getArrayInitializedElt(unsigned I)
Definition: APValue.h:510
ArrayRef< LValuePathEntry > getLValuePath() const
Definition: APValue.cpp:990
APSInt & getInt()
Definition: APValue.h:423
bool isArray() const
Definition: APValue.h:408
bool isLValue() const
Definition: APValue.h:406
bool isInt() const
Definition: APValue.h:401
unsigned getArraySize() const
Definition: APValue.h:533
@ None
There is no such object (it's outside its lifetime).
Definition: APValue.h:129
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
Definition: ASTContext.h:2406
const LangOptions & getLangOpts() const
Definition: ASTContext.h:770
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Definition: Expr.h:4111
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Definition: Expr.h:4289
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Definition: Expr.h:4295
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Definition: Expr.h:4301
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition: Expr.h:5534
Represents a loop initializing the elements of an array.
Definition: Expr.h:5481
llvm::APInt getArraySize() const
Definition: Expr.h:5503
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Definition: Expr.h:5496
Expr * getSubExpr() const
Get the initializer to use for each array element.
Definition: Expr.h:5501
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2639
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3146
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3810
static bool isLogicalOp(Opcode Opc)
Definition: Expr.h:3942
Expr * getLHS() const
Definition: Expr.h:3859
static bool isCommaOp(Opcode Opc)
Definition: Expr.h:3912
Expr * getRHS() const
Definition: Expr.h:3861
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
Definition: Expr.h:3886
Opcode getOpcode() const
Definition: Expr.h:3854
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1475
const Expr * getSubExpr() const
Definition: ExprCXX.h:1497
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition: ExprCXX.h:720
bool getValue() const
Definition: ExprCXX.h:737
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1530
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition: ExprCXX.h:1673
arg_range arguments()
Definition: ExprCXX.h:1654
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
Definition: ExprCXX.h:1632
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition: ExprCXX.h:1593
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Definition: ExprCXX.h:1670
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2528
A default argument (C++ [dcl.fct.default]).
Definition: ExprCXX.h:1254
A use of a default initializer in a constructor or in aggregate initialization.
Definition: ExprCXX.h:1361
Expr * getExpr()
Get the initialization expression that will be used.
Definition: ExprCXX.cpp:1035
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2792
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition: ExprCXX.h:1721
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Definition: ExprCXX.h:1758
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition: ExprCXX.h:4088
bool getValue() const
Definition: ExprCXX.h:4111
The null pointer literal (C++11 [lex.nullptr])
Definition: ExprCXX.h:765
Represents a list-initialization with parenthesis.
Definition: ExprCXX.h:4913
ArrayRef< Expr * > getInitExprs()
Definition: ExprCXX.h:4953
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
Definition: ExprCXX.h:523
A rewritten comparison expression that was originally written using operator syntax.
Definition: ExprCXX.h:283
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
Definition: ExprCXX.h:301
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type.
Definition: ExprCXX.h:2165
Represents the this expression in C++.
Definition: ExprCXX.h:1148
A C++ throw-expression (C++ [except.throw]).
Definition: ExprCXX.h:1192
const Expr * getSubExpr() const
Definition: ExprCXX.h:1212
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Definition: ExprCXX.h:1062
MSGuidDecl * getGuidDecl() const
Definition: ExprCXX.h:1108
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2795
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: Expr.h:2986
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
Definition: Expr.cpp:1548
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition: Expr.h:2965
Expr * getCallee()
Definition: Expr.h:2945
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition: Expr.h:2973
arg_range arguments()
Definition: Expr.h:3034
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition: Expr.cpp:1559
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3465
CastKind getCastKind() const
Definition: Expr.h:3509
Expr * getSubExpr()
Definition: Expr.h:3515
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
static CharUnits One()
One - Construct a CharUnits quantity of one.
Definition: CharUnits.h:58
unsigned getValue() const
Definition: Expr.h:1597
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition: Expr.h:4528
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Definition: Expr.h:4564
Complex values, per C99 6.2.5p11.
Definition: Type.h:2844
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4058
QualType getComputationLHSType() const
Definition: Expr.h:4092
QualType getComputationResultType() const
Definition: Expr.h:4095
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3395
bool isFileScope() const
Definition: Expr.h:3422
const Expr * getInitializer() const
Definition: Expr.h:3418
Represents the specialization of a concept - evaluates to a prvalue of type bool.
Definition: ExprConcepts.h:42
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
Definition: ExprConcepts.h:124
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3185
const llvm::APInt & getSize() const
Definition: Type.h:3206
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition: Expr.h:1059
APValue getAPValueResult() const
Definition: Expr.cpp:402
bool hasAPValueResult() const
Definition: Expr.h:1134
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2066
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1247
ValueDecl * getDecl()
Definition: Expr.h:1315
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:85
bool isInvalidDecl() const
Definition: DeclBase.h:593
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3436
unsigned getNumObjects() const
Definition: ExprCXX.h:3464
This represents one expression.
Definition: Expr.h:110
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
Definition: Expr.cpp:82
bool isGLValue() const
Definition: Expr.h:274
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
Definition: Expr.h:239
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3030
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
Definition: Expr.h:271
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
Definition: Expr.h:463
QualType getType() const
Definition: Expr.h:142
An expression trait intrinsic.
Definition: ExprCXX.h:2907
llvm::APFloat getValue() const
Definition: Expr.h:1634
const Expr * getSubExpr() const
Definition: Expr.h:1039
Represents a function declaration or definition.
Definition: Decl.h:1959
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2651
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition: Decl.h:2314
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition: Expr.h:4603
Represents a C11 generic selection.
Definition: Expr.h:5695
Expr * getResultExpr()
Return the result expression of this controlling expression.
Definition: Expr.h:5979
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:56
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition: Expr.h:1699
const Expr * getSubExpr() const
Definition: Expr.h:1711
Represents an implicitly-generated value initialization of an object of a given type.
Definition: Expr.h:5570
Describes an C or C++ initializer list.
Definition: Expr.h:4817
unsigned getNumInits() const
Definition: Expr.h:4847
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
Definition: Expr.h:4911
ArrayRef< Expr * > inits()
Definition: Expr.h:4857
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1938
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
Definition: ExprCXX.h:2064
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Definition: ExprCXX.cpp:1332
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
Definition: DeclCXX.h:3222
APValue & getAsAPValue() const
Get the value of this MSGuidDecl as an APValue.
Definition: DeclCXX.cpp:3473
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition: ExprCXX.h:4679
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Definition: ExprCXX.h:4704
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition: ExprCXX.h:4696
LifetimeExtendedTemporaryDecl * getLifetimeExtendedTemporaryDecl()
Definition: ExprCXX.h:4719
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3158
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition: Expr.h:3237
Expr * getBase() const
Definition: Expr.h:3231
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition: ExprObjC.h:87
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition: Expr.h:2440
Expr * getIndexExpr(unsigned Idx)
Definition: Expr.h:2501
const OffsetOfNode & getComponent(unsigned Idx) const
Definition: Expr.h:2487
unsigned getNumComponents() const
Definition: Expr.h:2497
Helper class for OffsetOfExpr.
Definition: Expr.h:2334
@ Array
An index into an array.
Definition: Expr.h:2339
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1155
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition: Expr.h:1205
ParenExpr - This represents a parethesized expression, e.g.
Definition: Expr.h:2105
const Expr * getSubExpr() const
Definition: Expr.h:2120
Represents a parameter to a function.
Definition: Decl.h:1749
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2897
[C99 6.4.2.2] - A predefined identifier such as func.
Definition: Expr.h:1962
StringLiteral * getFunctionName()
Definition: Expr.h:2006
A (possibly-)qualified type.
Definition: Type.h:737
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:804
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6901
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:6973
Represents a struct/union/class.
Definition: Decl.h:4133
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5091
RecordDecl * getDecl() const
Definition: Type.h:5101
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3008
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Definition: ExprConcepts.h:510
bool isSatisfied() const
Whether or not the requires clause is satisfied.
Definition: ExprConcepts.h:562
Represents an expression that computes the length of a parameter pack.
Definition: ExprCXX.h:4220
unsigned getPackLength() const
Retrieve the length of the parameter pack.
Definition: ExprCXX.h:4295
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition: Expr.h:4697
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Definition: Expr.cpp:2248
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1760
unsigned getLength() const
Definition: Expr.h:1866
uint32_t getCodeUnit(size_t i) const
Definition: Expr.h:1852
unsigned getCharByteWidth() const
Definition: Expr.h:1867
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4435
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition: ExprCXX.h:2751
bool getValue() const
Definition: ExprCXX.h:2792
bool isVoidType() const
Definition: Type.h:7442
bool isBooleanType() const
Definition: Type.h:7562
bool isIncompleteArrayType() const
Definition: Type.h:7227
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
Definition: Type.cpp:2289
bool isArrayType() const
Definition: Type.h:7219
bool isPointerType() const
Definition: Type.h:7153
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:7474
bool isReferenceType() const
Definition: Type.h:7165
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:651
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2419
bool isAnyComplexType() const
Definition: Type.h:7251
bool isAtomicType() const
Definition: Type.h:7294
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition: Type.h:7705
bool isFunctionType() const
Definition: Type.h:7149
bool isFloatingType() const
Definition: Type.cpp:2186
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7652
bool isRecordType() const
Definition: Type.h:7243
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2543
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
Definition: Expr.h:2612
bool isArgumentType() const
Definition: Expr.h:2585
UnaryExprOrTypeTrait getKind() const
Definition: Expr.h:2575
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2158
Expr * getSubExpr() const
Definition: Expr.h:2203
Opcode getOpcode() const
Definition: Expr.h:2198
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:706
QualType getType() const
Definition: Decl.h:717
Represents a variable declaration or definition.
Definition: Decl.h:918
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition: Decl.h:1192
const Expr * getInit() const
Definition: Decl.h:1352
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
Definition: Decl.h:1237
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Definition: Decl.h:1342
Scope for storage declared in a compound statement.
Compilation context for expressions.
bool visitExpr(const Expr *E) override
std::optional< unsigned > allocateLocal(DeclTy &&Decl, bool IsExtended=false)
Allocates a space storing a local given its type.
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsExtended=false)
Creates a local primitive value.
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool VisitDeclRefExpr(const DeclRefExpr *E)
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool VisitComplexBinOp(const BinaryOperator *E)
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
bool VisitMemberExpr(const MemberExpr *E)
bool VisitOffsetOfExpr(const OffsetOfExpr *E)
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
bool discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
bool visitDecl(const VarDecl *VD) override
Toplevel visitDecl().
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E)
bool visitInitializer(const Expr *E)
Compiles an initializer.
bool VisitParenExpr(const ParenExpr *E)
bool Initializing
Flag inidicating if we're initializing an already created variable.
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool VisitImaginaryLiteral(const ImaginaryLiteral *E)
bool VisitLambdaExpr(const LambdaExpr *E)
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
bool VisitRequiresExpr(const RequiresExpr *E)
bool VisitBuiltinCallExpr(const CallExpr *E)
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E)
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init)
Pointer to the array(not the element!) must be on the stack when calling this.
void emitCleanup()
Emits scope cleanup instructions.
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitPredefinedExpr(const PredefinedExpr *E)
bool VisitBinaryOperator(const BinaryOperator *E)
bool VisitTypeTraitExpr(const TypeTraitExpr *E)
bool visit(const Expr *E)
Evaluates an expression and places the result on the stack.
bool VisitInitListExpr(const InitListExpr *E)
bool VisitFloatingLiteral(const FloatingLiteral *E)
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool visitInitList(ArrayRef< const Expr * > Inits, const Expr *E)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
bool DiscardResult
Flag indicating if return value is to be discarded.
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
const Function * getFunction(const FunctionDecl *FD)
bool VisitLogicalBinOp(const BinaryOperator *E)
bool visitVarDecl(const VarDecl *VD)
Creates and initializes a variable from the given decl.
bool VisitStringLiteral(const StringLiteral *E)
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E)
bool VisitGNUNullExpr(const GNUNullExpr *E)
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
bool VisitSourceLocExpr(const SourceLocExpr *E)
bool VisitOpaqueValueExpr(const OpaqueValueExpr *E)
bool VisitCXXThisExpr(const CXXThisExpr *E)
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
typename Emitter::LabelTy LabelTy
bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E)
Visit an APValue.
bool VisitPointerArithBinOp(const BinaryOperator *E)
Perform addition/subtraction of a pointer and an integer or subtraction of two pointers.
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitCompoundAssignOperator(const CompoundAssignOperator *E)
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E)
bool VisitCallExpr(const CallExpr *E)
const RecordType * getRecordTy(QualType Ty)
Returns a record type from a record or pointer type.
bool delegate(const Expr *E)
Just pass evaluation on to E.
bool VisitConstantExpr(const ConstantExpr *E)
bool VisitChooseExpr(const ChooseExpr *E)
bool VisitCastExpr(const CastExpr *E)
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E)
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Definition: Context.h:96
Scope used to handle temporaries in toplevel variable declarations.
void addExtended(const Scope::Local &Local) override
DeclScope(ByteCodeExprGen< Emitter > *Ctx, const ValueDecl *VD)
Expression scope which tracks potentially lifetime extended temporaries which are hoisted to the pare...
Bytecode function.
Definition: Function.h:76
bool hasThisPointer() const
Definition: Function.h:168
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Definition: Function.h:109
Generic scope for local variables.
Scope used to handle initialization methods.
OptionScope(ByteCodeExprGen< Emitter > *Ctx, bool NewDiscardResult, bool NewInitializing)
Root constructor, compiling or discarding primitives.
Context to manage declaration lifetimes.
Definition: Program.h:132
Structure/Class descriptor.
Definition: Record.h:25
unsigned getNumBases() const
Definition: Record.h:89
const CXXDestructorDecl * getDestructor() const
Returns the destructor of the record, if any.
Definition: Record.h:70
const Field * getField(const FieldDecl *FD) const
Returns a field.
Definition: Record.cpp:30
llvm::iterator_range< const_base_iter > bases() const
Definition: Record.h:85
unsigned getNumFields() const
Definition: Record.h:81
llvm::iterator_range< const_field_iter > fields() const
Definition: Record.h:77
const Base * getBase(const RecordDecl *FD) const
Returns a base descriptor.
Definition: Record.cpp:36
Describes a scope block.
Definition: Function.h:34
Describes the statement/declaration an opcode was generated from.
Definition: Source.h:72
Scope chain managing the variable lifetimes.
virtual void addLocal(const Scope::Local &Local)
ByteCodeExprGen< Emitter > * Ctx
ByteCodeExprGen instance.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition: PrimType.h:95
bool LE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:829
PrimType
Enumeration of the primitive types of the VM.
Definition: PrimType.h:32
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
Definition: PrimType.cpp:22
llvm::APSInt APSInt
Definition: Floating.h:24
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
Definition: Descriptor.h:27
constexpr bool isIntegralType(PrimType T)
Definition: PrimType.h:66
BinaryOperatorKind
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
Definition: TypeTraits.h:51
@ SD_Static
Static storage duration.
Definition: Specifiers.h:327
#define true
Definition: stdbool.h:21
Describes a memory block created by an allocation site.
Definition: Descriptor.h:88
unsigned getNumElems() const
Returns the number of elements stored in the block.
Definition: Descriptor.h:190
bool isPrimitive() const
Checks if the descriptor is of a primitive.
Definition: Descriptor.h:204
QualType getElemQualType() const
Definition: Descriptor.cpp:320
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
Definition: Descriptor.h:197
QualType getType() const
Definition: Descriptor.cpp:310
const Descriptor *const ElemDesc
Descriptor of the array element.
Definition: Descriptor.h:114
static constexpr MetadataSize InlineDescMD
Definition: Descriptor.h:109
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
Definition: Descriptor.h:195
bool isRecord() const
Checks if the descriptor is of a record.
Definition: Descriptor.h:209
const Record *const ElemRecord
Pointer to the record, if block contains records.
Definition: Descriptor.h:112
bool isArray() const
Checks if the descriptor is of an array.
Definition: Descriptor.h:207
Describes a base class.
Definition: Record.h:36
Describes a record field.
Definition: Record.h:28
const Descriptor * Desc
Definition: Record.h:31
const FieldDecl * Decl
Definition: Record.h:29
bool isBitField() const
Definition: Record.h:32
Information about a local's storage.
Definition: Function.h:37