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