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