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