clang 20.0.0git
Compiler.cpp
Go to the documentation of this file.
1//===--- Compiler.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 "Compiler.h"
10#include "ByteCodeEmitter.h"
11#include "Context.h"
12#include "FixedPoint.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 LocalScope<Emitter> {
30public:
32 : LocalScope<Emitter>(Ctx, VD), Scope(Ctx->P, VD),
33 OldInitializingDecl(Ctx->InitializingDecl) {
34 Ctx->InitializingDecl = VD;
35 Ctx->InitStack.push_back(InitLink::Decl(VD));
36 }
37
38 void addExtended(const Scope::Local &Local) override {
39 return this->addLocal(Local);
40 }
41
43 this->Ctx->InitializingDecl = OldInitializingDecl;
44 this->Ctx->InitStack.pop_back();
45 }
46
47private:
49 const ValueDecl *OldInitializingDecl;
50};
51
52/// Scope used to handle initialization methods.
53template <class Emitter> class OptionScope final {
54public:
55 /// Root constructor, compiling or discarding primitives.
56 OptionScope(Compiler<Emitter> *Ctx, bool NewDiscardResult,
57 bool NewInitializing)
58 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
59 OldInitializing(Ctx->Initializing) {
60 Ctx->DiscardResult = NewDiscardResult;
61 Ctx->Initializing = NewInitializing;
62 }
63
65 Ctx->DiscardResult = OldDiscardResult;
66 Ctx->Initializing = OldInitializing;
67 }
68
69private:
70 /// Parent context.
72 /// Old discard flag to restore.
73 bool OldDiscardResult;
74 bool OldInitializing;
75};
76
77template <class Emitter>
78bool InitLink::emit(Compiler<Emitter> *Ctx, const Expr *E) const {
79 switch (Kind) {
80 case K_This:
81 return Ctx->emitThis(E);
82 case K_Field:
83 // We're assuming there's a base pointer on the stack already.
84 return Ctx->emitGetPtrFieldPop(Offset, E);
85 case K_Temp:
86 return Ctx->emitGetPtrLocal(Offset, E);
87 case K_Decl:
88 return Ctx->visitDeclRef(D, E);
89 case K_Elem:
90 if (!Ctx->emitConstUint32(Offset, E))
91 return false;
92 return Ctx->emitArrayElemPtrPopUint32(E);
93 case K_RVO:
94 return Ctx->emitRVOPtr(E);
95 case K_InitList:
96 return true;
97 default:
98 llvm_unreachable("Unhandled InitLink kind");
99 }
100 return true;
101}
102
103/// Scope managing label targets.
104template <class Emitter> class LabelScope {
105public:
106 virtual ~LabelScope() {}
107
108protected:
110 /// Compiler instance.
112};
113
114/// Sets the context for break/continue statements.
115template <class Emitter> class LoopScope final : public LabelScope<Emitter> {
116public:
119
120 LoopScope(Compiler<Emitter> *Ctx, LabelTy BreakLabel, LabelTy ContinueLabel)
121 : LabelScope<Emitter>(Ctx), OldBreakLabel(Ctx->BreakLabel),
122 OldContinueLabel(Ctx->ContinueLabel),
123 OldBreakVarScope(Ctx->BreakVarScope),
124 OldContinueVarScope(Ctx->ContinueVarScope) {
125 this->Ctx->BreakLabel = BreakLabel;
126 this->Ctx->ContinueLabel = ContinueLabel;
127 this->Ctx->BreakVarScope = this->Ctx->VarScope;
128 this->Ctx->ContinueVarScope = this->Ctx->VarScope;
129 }
130
132 this->Ctx->BreakLabel = OldBreakLabel;
133 this->Ctx->ContinueLabel = OldContinueLabel;
134 this->Ctx->ContinueVarScope = OldContinueVarScope;
135 this->Ctx->BreakVarScope = OldBreakVarScope;
136 }
137
138private:
139 OptLabelTy OldBreakLabel;
140 OptLabelTy OldContinueLabel;
141 VariableScope<Emitter> *OldBreakVarScope;
142 VariableScope<Emitter> *OldContinueVarScope;
143};
144
145// Sets the context for a switch scope, mapping labels.
146template <class Emitter> class SwitchScope final : public LabelScope<Emitter> {
147public:
151
152 SwitchScope(Compiler<Emitter> *Ctx, CaseMap &&CaseLabels, LabelTy BreakLabel,
153 OptLabelTy DefaultLabel)
154 : LabelScope<Emitter>(Ctx), OldBreakLabel(Ctx->BreakLabel),
155 OldDefaultLabel(this->Ctx->DefaultLabel),
156 OldCaseLabels(std::move(this->Ctx->CaseLabels)),
157 OldLabelVarScope(Ctx->BreakVarScope) {
158 this->Ctx->BreakLabel = BreakLabel;
159 this->Ctx->DefaultLabel = DefaultLabel;
160 this->Ctx->CaseLabels = std::move(CaseLabels);
161 this->Ctx->BreakVarScope = this->Ctx->VarScope;
162 }
163
165 this->Ctx->BreakLabel = OldBreakLabel;
166 this->Ctx->DefaultLabel = OldDefaultLabel;
167 this->Ctx->CaseLabels = std::move(OldCaseLabels);
168 this->Ctx->BreakVarScope = OldLabelVarScope;
169 }
170
171private:
172 OptLabelTy OldBreakLabel;
173 OptLabelTy OldDefaultLabel;
174 CaseMap OldCaseLabels;
175 VariableScope<Emitter> *OldLabelVarScope;
176};
177
178template <class Emitter> class StmtExprScope final {
179public:
180 StmtExprScope(Compiler<Emitter> *Ctx) : Ctx(Ctx), OldFlag(Ctx->InStmtExpr) {
181 Ctx->InStmtExpr = true;
182 }
183
184 ~StmtExprScope() { Ctx->InStmtExpr = OldFlag; }
185
186private:
188 bool OldFlag;
189};
190
191} // namespace interp
192} // namespace clang
193
194template <class Emitter>
196 const Expr *SubExpr = CE->getSubExpr();
197 switch (CE->getCastKind()) {
198
199 case CK_LValueToRValue: {
200 if (DiscardResult)
201 return this->discard(SubExpr);
202
203 std::optional<PrimType> SubExprT = classify(SubExpr->getType());
204 // Prepare storage for the result.
205 if (!Initializing && !SubExprT) {
206 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
207 if (!LocalIndex)
208 return false;
209 if (!this->emitGetPtrLocal(*LocalIndex, CE))
210 return false;
211 }
212
213 if (!this->visit(SubExpr))
214 return false;
215
216 if (SubExprT)
217 return this->emitLoadPop(*SubExprT, CE);
218
219 // If the subexpr type is not primitive, we need to perform a copy here.
220 // This happens for example in C when dereferencing a pointer of struct
221 // type.
222 return this->emitMemcpy(CE);
223 }
224
225 case CK_DerivedToBaseMemberPointer: {
226 assert(classifyPrim(CE->getType()) == PT_MemberPtr);
227 assert(classifyPrim(SubExpr->getType()) == PT_MemberPtr);
228 const auto *FromMP = SubExpr->getType()->getAs<MemberPointerType>();
229 const auto *ToMP = CE->getType()->getAs<MemberPointerType>();
230
231 unsigned DerivedOffset = collectBaseOffset(QualType(ToMP->getClass(), 0),
232 QualType(FromMP->getClass(), 0));
233
234 if (!this->delegate(SubExpr))
235 return false;
236
237 return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
238 }
239
240 case CK_BaseToDerivedMemberPointer: {
241 assert(classifyPrim(CE) == PT_MemberPtr);
242 assert(classifyPrim(SubExpr) == PT_MemberPtr);
243 const auto *FromMP = SubExpr->getType()->getAs<MemberPointerType>();
244 const auto *ToMP = CE->getType()->getAs<MemberPointerType>();
245
246 unsigned DerivedOffset = collectBaseOffset(QualType(FromMP->getClass(), 0),
247 QualType(ToMP->getClass(), 0));
248
249 if (!this->delegate(SubExpr))
250 return false;
251 return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
252 }
253
254 case CK_UncheckedDerivedToBase:
255 case CK_DerivedToBase: {
256 if (DiscardResult)
257 return this->discard(SubExpr);
258
259 if (!this->delegate(SubExpr))
260 return false;
261
262 const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
263 if (const auto *PT = dyn_cast<PointerType>(Ty))
264 return PT->getPointeeType()->getAsCXXRecordDecl();
265 return Ty->getAsCXXRecordDecl();
266 };
267
268 // FIXME: We can express a series of non-virtual casts as a single
269 // GetPtrBasePop op.
270 QualType CurType = SubExpr->getType();
271 for (const CXXBaseSpecifier *B : CE->path()) {
272 if (B->isVirtual()) {
273 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))
274 return false;
275 CurType = B->getType();
276 } else {
277 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
278 if (!this->emitGetPtrBasePop(DerivedOffset, CE))
279 return false;
280 CurType = B->getType();
281 }
282 }
283
284 return true;
285 }
286
287 case CK_BaseToDerived: {
288 if (DiscardResult)
289 return this->discard(SubExpr);
290
291 if (!this->delegate(SubExpr))
292 return false;
293
294 unsigned DerivedOffset =
295 collectBaseOffset(SubExpr->getType(), CE->getType());
296
297 return this->emitGetPtrDerivedPop(DerivedOffset, CE);
298 }
299
300 case CK_FloatingCast: {
301 // HLSL uses CK_FloatingCast to cast between vectors.
302 if (!SubExpr->getType()->isFloatingType() ||
303 !CE->getType()->isFloatingType())
304 return false;
305 if (DiscardResult)
306 return this->discard(SubExpr);
307 if (!this->visit(SubExpr))
308 return false;
309 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
310 return this->emitCastFP(TargetSemantics, getRoundingMode(CE), CE);
311 }
312
313 case CK_IntegralToFloating: {
314 if (DiscardResult)
315 return this->discard(SubExpr);
316 std::optional<PrimType> FromT = classify(SubExpr->getType());
317 if (!FromT)
318 return false;
319
320 if (!this->visit(SubExpr))
321 return false;
322
323 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
324 return this->emitCastIntegralFloating(*FromT, TargetSemantics,
325 getFPOptions(CE), CE);
326 }
327
328 case CK_FloatingToBoolean:
329 case CK_FloatingToIntegral: {
330 if (DiscardResult)
331 return this->discard(SubExpr);
332
333 std::optional<PrimType> ToT = classify(CE->getType());
334
335 if (!ToT)
336 return false;
337
338 if (!this->visit(SubExpr))
339 return false;
340
341 if (ToT == PT_IntAP)
342 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->getType()),
343 getFPOptions(CE), CE);
344 if (ToT == PT_IntAPS)
345 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->getType()),
346 getFPOptions(CE), CE);
347
348 return this->emitCastFloatingIntegral(*ToT, getFPOptions(CE), CE);
349 }
350
351 case CK_NullToPointer:
352 case CK_NullToMemberPointer: {
353 if (!this->discard(SubExpr))
354 return false;
355 if (DiscardResult)
356 return true;
357
358 const Descriptor *Desc = nullptr;
359 const QualType PointeeType = CE->getType()->getPointeeType();
360 if (!PointeeType.isNull()) {
361 if (std::optional<PrimType> T = classify(PointeeType))
362 Desc = P.createDescriptor(SubExpr, *T);
363 else
364 Desc = P.createDescriptor(SubExpr, PointeeType.getTypePtr(),
365 std::nullopt, true, false,
366 /*IsMutable=*/false, nullptr);
367 }
368
369 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(CE->getType());
370 return this->emitNull(classifyPrim(CE->getType()), Val, Desc, CE);
371 }
372
373 case CK_PointerToIntegral: {
374 if (DiscardResult)
375 return this->discard(SubExpr);
376
377 if (!this->visit(SubExpr))
378 return false;
379
380 // If SubExpr doesn't result in a pointer, make it one.
381 if (PrimType FromT = classifyPrim(SubExpr->getType()); FromT != PT_Ptr) {
382 assert(isPtrType(FromT));
383 if (!this->emitDecayPtr(FromT, PT_Ptr, CE))
384 return false;
385 }
386
387 PrimType T = classifyPrim(CE->getType());
388 if (T == PT_IntAP)
389 return this->emitCastPointerIntegralAP(Ctx.getBitWidth(CE->getType()),
390 CE);
391 if (T == PT_IntAPS)
392 return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(CE->getType()),
393 CE);
394 return this->emitCastPointerIntegral(T, CE);
395 }
396
397 case CK_ArrayToPointerDecay: {
398 if (!this->visit(SubExpr))
399 return false;
400 if (!this->emitArrayDecay(CE))
401 return false;
402 if (DiscardResult)
403 return this->emitPopPtr(CE);
404 return true;
405 }
406
407 case CK_IntegralToPointer: {
408 QualType IntType = SubExpr->getType();
409 assert(IntType->isIntegralOrEnumerationType());
410 if (!this->visit(SubExpr))
411 return false;
412 // FIXME: I think the discard is wrong since the int->ptr cast might cause a
413 // diagnostic.
414 PrimType T = classifyPrim(IntType);
415 if (DiscardResult)
416 return this->emitPop(T, CE);
417
418 QualType PtrType = CE->getType();
419 const Descriptor *Desc;
420 if (std::optional<PrimType> T = classify(PtrType->getPointeeType()))
421 Desc = P.createDescriptor(SubExpr, *T);
422 else if (PtrType->getPointeeType()->isVoidType())
423 Desc = nullptr;
424 else
425 Desc = P.createDescriptor(CE, PtrType->getPointeeType().getTypePtr(),
426 Descriptor::InlineDescMD, true, false,
427 /*IsMutable=*/false, nullptr);
428
429 if (!this->emitGetIntPtr(T, Desc, CE))
430 return false;
431
432 PrimType DestPtrT = classifyPrim(PtrType);
433 if (DestPtrT == PT_Ptr)
434 return true;
435
436 // In case we're converting the integer to a non-Pointer.
437 return this->emitDecayPtr(PT_Ptr, DestPtrT, CE);
438 }
439
440 case CK_AtomicToNonAtomic:
441 case CK_ConstructorConversion:
442 case CK_FunctionToPointerDecay:
443 case CK_NonAtomicToAtomic:
444 case CK_NoOp:
445 case CK_UserDefinedConversion:
446 case CK_AddressSpaceConversion:
447 case CK_CPointerToObjCPointerCast:
448 return this->delegate(SubExpr);
449
450 case CK_BitCast: {
451 // Reject bitcasts to atomic types.
452 if (CE->getType()->isAtomicType()) {
453 if (!this->discard(SubExpr))
454 return false;
455 return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, CE);
456 }
457
458 if (DiscardResult)
459 return this->discard(SubExpr);
460
461 QualType SubExprTy = SubExpr->getType();
462 std::optional<PrimType> FromT = classify(SubExprTy);
463 // Casts from integer/vector to vector.
464 if (CE->getType()->isVectorType())
465 return this->emitBuiltinBitCast(CE);
466
467 std::optional<PrimType> ToT = classify(CE->getType());
468 if (!FromT || !ToT)
469 return false;
470
471 assert(isPtrType(*FromT));
472 assert(isPtrType(*ToT));
473 if (FromT == ToT) {
474 if (CE->getType()->isVoidPointerType())
475 return this->delegate(SubExpr);
476
477 if (!this->visit(SubExpr))
478 return false;
479 if (FromT == PT_Ptr)
480 return this->emitPtrPtrCast(SubExprTy->isVoidPointerType(), CE);
481 return true;
482 }
483
484 if (!this->visit(SubExpr))
485 return false;
486 return this->emitDecayPtr(*FromT, *ToT, CE);
487 }
488
489 case CK_LValueToRValueBitCast:
490 return this->emitBuiltinBitCast(CE);
491
492 case CK_IntegralToBoolean:
493 case CK_FixedPointToBoolean:
494 case CK_BooleanToSignedIntegral:
495 case CK_IntegralCast: {
496 if (DiscardResult)
497 return this->discard(SubExpr);
498 std::optional<PrimType> FromT = classify(SubExpr->getType());
499 std::optional<PrimType> ToT = classify(CE->getType());
500
501 if (!FromT || !ToT)
502 return false;
503
504 if (!this->visit(SubExpr))
505 return false;
506
507 // Possibly diagnose casts to enum types if the target type does not
508 // have a fixed size.
509 if (Ctx.getLangOpts().CPlusPlus && CE->getType()->isEnumeralType()) {
510 if (const auto *ET = CE->getType().getCanonicalType()->getAs<EnumType>();
511 ET && !ET->getDecl()->isFixed()) {
512 if (!this->emitCheckEnumValue(*FromT, ET->getDecl(), CE))
513 return false;
514 }
515 }
516
517 auto maybeNegate = [&]() -> bool {
518 if (CE->getCastKind() == CK_BooleanToSignedIntegral)
519 return this->emitNeg(*ToT, CE);
520 return true;
521 };
522
523 if (ToT == PT_IntAP)
524 return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->getType()), CE) &&
525 maybeNegate();
526 if (ToT == PT_IntAPS)
527 return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->getType()), CE) &&
528 maybeNegate();
529
530 if (FromT == ToT)
531 return true;
532 if (!this->emitCast(*FromT, *ToT, CE))
533 return false;
534
535 return maybeNegate();
536 }
537
538 case CK_PointerToBoolean:
539 case CK_MemberPointerToBoolean: {
540 PrimType PtrT = classifyPrim(SubExpr->getType());
541
542 if (!this->visit(SubExpr))
543 return false;
544 return this->emitIsNonNull(PtrT, CE);
545 }
546
547 case CK_IntegralComplexToBoolean:
548 case CK_FloatingComplexToBoolean: {
549 if (DiscardResult)
550 return this->discard(SubExpr);
551 if (!this->visit(SubExpr))
552 return false;
553 return this->emitComplexBoolCast(SubExpr);
554 }
555
556 case CK_IntegralComplexToReal:
557 case CK_FloatingComplexToReal:
558 return this->emitComplexReal(SubExpr);
559
560 case CK_IntegralRealToComplex:
561 case CK_FloatingRealToComplex: {
562 // We're creating a complex value here, so we need to
563 // allocate storage for it.
564 if (!Initializing) {
565 unsigned LocalIndex = allocateTemporary(CE);
566 if (!this->emitGetPtrLocal(LocalIndex, CE))
567 return false;
568 }
569
570 // Init the complex value to {SubExpr, 0}.
571 if (!this->visitArrayElemInit(0, SubExpr))
572 return false;
573 // Zero-init the second element.
574 PrimType T = classifyPrim(SubExpr->getType());
575 if (!this->visitZeroInitializer(T, SubExpr->getType(), SubExpr))
576 return false;
577 return this->emitInitElem(T, 1, SubExpr);
578 }
579
580 case CK_IntegralComplexCast:
581 case CK_FloatingComplexCast:
582 case CK_IntegralComplexToFloatingComplex:
583 case CK_FloatingComplexToIntegralComplex: {
584 assert(CE->getType()->isAnyComplexType());
585 assert(SubExpr->getType()->isAnyComplexType());
586 if (DiscardResult)
587 return this->discard(SubExpr);
588
589 if (!Initializing) {
590 std::optional<unsigned> LocalIndex = allocateLocal(CE);
591 if (!LocalIndex)
592 return false;
593 if (!this->emitGetPtrLocal(*LocalIndex, CE))
594 return false;
595 }
596
597 // Location for the SubExpr.
598 // Since SubExpr is of complex type, visiting it results in a pointer
599 // anyway, so we just create a temporary pointer variable.
600 unsigned SubExprOffset = allocateLocalPrimitive(
601 SubExpr, PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false);
602 if (!this->visit(SubExpr))
603 return false;
604 if (!this->emitSetLocal(PT_Ptr, SubExprOffset, CE))
605 return false;
606
607 PrimType SourceElemT = classifyComplexElementType(SubExpr->getType());
608 QualType DestElemType =
609 CE->getType()->getAs<ComplexType>()->getElementType();
610 PrimType DestElemT = classifyPrim(DestElemType);
611 // Cast both elements individually.
612 for (unsigned I = 0; I != 2; ++I) {
613 if (!this->emitGetLocal(PT_Ptr, SubExprOffset, CE))
614 return false;
615 if (!this->emitArrayElemPop(SourceElemT, I, CE))
616 return false;
617
618 // Do the cast.
619 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
620 return false;
621
622 // Save the value.
623 if (!this->emitInitElem(DestElemT, I, CE))
624 return false;
625 }
626 return true;
627 }
628
629 case CK_VectorSplat: {
630 assert(!classify(CE->getType()));
631 assert(classify(SubExpr->getType()));
632 assert(CE->getType()->isVectorType());
633
634 if (DiscardResult)
635 return this->discard(SubExpr);
636
637 if (!Initializing) {
638 std::optional<unsigned> LocalIndex = allocateLocal(CE);
639 if (!LocalIndex)
640 return false;
641 if (!this->emitGetPtrLocal(*LocalIndex, CE))
642 return false;
643 }
644
645 const auto *VT = CE->getType()->getAs<VectorType>();
646 PrimType ElemT = classifyPrim(SubExpr->getType());
647 unsigned ElemOffset = allocateLocalPrimitive(
648 SubExpr, ElemT, /*IsConst=*/true, /*IsExtended=*/false);
649
650 // Prepare a local variable for the scalar value.
651 if (!this->visit(SubExpr))
652 return false;
653 if (classifyPrim(SubExpr) == PT_Ptr && !this->emitLoadPop(ElemT, CE))
654 return false;
655
656 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
657 return false;
658
659 for (unsigned I = 0; I != VT->getNumElements(); ++I) {
660 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
661 return false;
662 if (!this->emitInitElem(ElemT, I, CE))
663 return false;
664 }
665
666 return true;
667 }
668
669 case CK_HLSLVectorTruncation: {
670 assert(SubExpr->getType()->isVectorType());
671 if (std::optional<PrimType> ResultT = classify(CE)) {
672 assert(!DiscardResult);
673 // Result must be either a float or integer. Take the first element.
674 if (!this->visit(SubExpr))
675 return false;
676 return this->emitArrayElemPop(*ResultT, 0, CE);
677 }
678 // Otherwise, this truncates from one vector type to another.
679 assert(CE->getType()->isVectorType());
680
681 if (!Initializing) {
682 unsigned LocalIndex = allocateTemporary(CE);
683 if (!this->emitGetPtrLocal(LocalIndex, CE))
684 return false;
685 }
686 unsigned ToSize = CE->getType()->getAs<VectorType>()->getNumElements();
687 assert(SubExpr->getType()->getAs<VectorType>()->getNumElements() > ToSize);
688 if (!this->visit(SubExpr))
689 return false;
690 return this->emitCopyArray(classifyVectorElementType(CE->getType()), 0, 0,
691 ToSize, CE);
692 };
693
694 case CK_IntegralToFixedPoint: {
695 if (!this->visit(SubExpr))
696 return false;
697
698 auto Sem =
699 Ctx.getASTContext().getFixedPointSemantics(CE->getType()).toOpaqueInt();
700 return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->getType()),
701 Sem, CE);
702 }
703 case CK_FloatingToFixedPoint: {
704 if (!this->visit(SubExpr))
705 return false;
706
707 auto Sem =
708 Ctx.getASTContext().getFixedPointSemantics(CE->getType()).toOpaqueInt();
709 return this->emitCastFloatingFixedPoint(Sem, CE);
710 }
711 case CK_FixedPointToFloating: {
712 if (!this->visit(SubExpr))
713 return false;
714 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
715 return this->emitCastFixedPointFloating(TargetSemantics, CE);
716 }
717 case CK_FixedPointToIntegral: {
718 if (!this->visit(SubExpr))
719 return false;
720 return this->emitCastFixedPointIntegral(classifyPrim(CE->getType()), CE);
721 }
722 case CK_FixedPointCast: {
723 if (!this->visit(SubExpr))
724 return false;
725 auto Sem =
726 Ctx.getASTContext().getFixedPointSemantics(CE->getType()).toOpaqueInt();
727 return this->emitCastFixedPoint(Sem, CE);
728 }
729
730 case CK_ToVoid:
731 return discard(SubExpr);
732
733 default:
734 return this->emitInvalid(CE);
735 }
736 llvm_unreachable("Unhandled clang::CastKind enum");
737}
738
739template <class Emitter>
741 if (DiscardResult)
742 return true;
743
744 return this->emitConst(LE->getValue(), LE);
745}
746
747template <class Emitter>
749 if (DiscardResult)
750 return true;
751
752 return this->emitConstFloat(E->getValue(), E);
753}
754
755template <class Emitter>
757 assert(E->getType()->isAnyComplexType());
758 if (DiscardResult)
759 return true;
760
761 if (!Initializing) {
762 unsigned LocalIndex = allocateTemporary(E);
763 if (!this->emitGetPtrLocal(LocalIndex, E))
764 return false;
765 }
766
767 const Expr *SubExpr = E->getSubExpr();
768 PrimType SubExprT = classifyPrim(SubExpr->getType());
769
770 if (!this->visitZeroInitializer(SubExprT, SubExpr->getType(), SubExpr))
771 return false;
772 if (!this->emitInitElem(SubExprT, 0, SubExpr))
773 return false;
774 return this->visitArrayElemInit(1, SubExpr);
775}
776
777template <class Emitter>
779 assert(E->getType()->isFixedPointType());
780 assert(classifyPrim(E) == PT_FixedPoint);
781
782 if (DiscardResult)
783 return true;
784
785 auto Sem = Ctx.getASTContext().getFixedPointSemantics(E->getType());
786 APInt Value = E->getValue();
787 return this->emitConstFixedPoint(FixedPoint(Value, Sem), E);
788}
789
790template <class Emitter>
792 return this->delegate(E->getSubExpr());
793}
794
795template <class Emitter>
797 // Need short-circuiting for these.
798 if (BO->isLogicalOp() && !BO->getType()->isVectorType())
799 return this->VisitLogicalBinOp(BO);
800
801 const Expr *LHS = BO->getLHS();
802 const Expr *RHS = BO->getRHS();
803
804 // Handle comma operators. Just discard the LHS
805 // and delegate to RHS.
806 if (BO->isCommaOp()) {
807 if (!this->discard(LHS))
808 return false;
809 if (RHS->getType()->isVoidType())
810 return this->discard(RHS);
811
812 return this->delegate(RHS);
813 }
814
815 if (BO->getType()->isAnyComplexType())
816 return this->VisitComplexBinOp(BO);
817 if (BO->getType()->isVectorType())
818 return this->VisitVectorBinOp(BO);
819 if ((LHS->getType()->isAnyComplexType() ||
820 RHS->getType()->isAnyComplexType()) &&
821 BO->isComparisonOp())
822 return this->emitComplexComparison(LHS, RHS, BO);
823 if (LHS->getType()->isFixedPointType() || RHS->getType()->isFixedPointType())
824 return this->VisitFixedPointBinOp(BO);
825
826 if (BO->isPtrMemOp()) {
827 if (!this->visit(LHS))
828 return false;
829
830 if (!this->visit(RHS))
831 return false;
832
833 if (!this->emitToMemberPtr(BO))
834 return false;
835
836 if (classifyPrim(BO) == PT_MemberPtr)
837 return true;
838
839 if (!this->emitCastMemberPtrPtr(BO))
840 return false;
841 return DiscardResult ? this->emitPopPtr(BO) : true;
842 }
843
844 // Typecheck the args.
845 std::optional<PrimType> LT = classify(LHS);
846 std::optional<PrimType> RT = classify(RHS);
847 std::optional<PrimType> T = classify(BO->getType());
848
849 // Special case for C++'s three-way/spaceship operator <=>, which
850 // returns a std::{strong,weak,partial}_ordering (which is a class, so doesn't
851 // have a PrimType).
852 if (!T && BO->getOpcode() == BO_Cmp) {
853 if (DiscardResult)
854 return true;
855 const ComparisonCategoryInfo *CmpInfo =
856 Ctx.getASTContext().CompCategories.lookupInfoForType(BO->getType());
857 assert(CmpInfo);
858
859 // We need a temporary variable holding our return value.
860 if (!Initializing) {
861 std::optional<unsigned> ResultIndex = this->allocateLocal(BO);
862 if (!this->emitGetPtrLocal(*ResultIndex, BO))
863 return false;
864 }
865
866 if (!visit(LHS) || !visit(RHS))
867 return false;
868
869 return this->emitCMP3(*LT, CmpInfo, BO);
870 }
871
872 if (!LT || !RT || !T)
873 return false;
874
875 // Pointer arithmetic special case.
876 if (BO->getOpcode() == BO_Add || BO->getOpcode() == BO_Sub) {
877 if (isPtrType(*T) || (isPtrType(*LT) && isPtrType(*RT)))
878 return this->VisitPointerArithBinOp(BO);
879 }
880
881 // Assignmentes require us to evalute the RHS first.
882 if (BO->getOpcode() == BO_Assign) {
883 if (!visit(RHS) || !visit(LHS))
884 return false;
885 if (!this->emitFlip(*LT, *RT, BO))
886 return false;
887 } else {
888 if (!visit(LHS) || !visit(RHS))
889 return false;
890 }
891
892 // For languages such as C, cast the result of one
893 // of our comparision opcodes to T (which is usually int).
894 auto MaybeCastToBool = [this, T, BO](bool Result) {
895 if (!Result)
896 return false;
897 if (DiscardResult)
898 return this->emitPop(*T, BO);
899 if (T != PT_Bool)
900 return this->emitCast(PT_Bool, *T, BO);
901 return true;
902 };
903
904 auto Discard = [this, T, BO](bool Result) {
905 if (!Result)
906 return false;
907 return DiscardResult ? this->emitPop(*T, BO) : true;
908 };
909
910 switch (BO->getOpcode()) {
911 case BO_EQ:
912 return MaybeCastToBool(this->emitEQ(*LT, BO));
913 case BO_NE:
914 return MaybeCastToBool(this->emitNE(*LT, BO));
915 case BO_LT:
916 return MaybeCastToBool(this->emitLT(*LT, BO));
917 case BO_LE:
918 return MaybeCastToBool(this->emitLE(*LT, BO));
919 case BO_GT:
920 return MaybeCastToBool(this->emitGT(*LT, BO));
921 case BO_GE:
922 return MaybeCastToBool(this->emitGE(*LT, BO));
923 case BO_Sub:
924 if (BO->getType()->isFloatingType())
925 return Discard(this->emitSubf(getFPOptions(BO), BO));
926 return Discard(this->emitSub(*T, BO));
927 case BO_Add:
928 if (BO->getType()->isFloatingType())
929 return Discard(this->emitAddf(getFPOptions(BO), BO));
930 return Discard(this->emitAdd(*T, BO));
931 case BO_Mul:
932 if (BO->getType()->isFloatingType())
933 return Discard(this->emitMulf(getFPOptions(BO), BO));
934 return Discard(this->emitMul(*T, BO));
935 case BO_Rem:
936 return Discard(this->emitRem(*T, BO));
937 case BO_Div:
938 if (BO->getType()->isFloatingType())
939 return Discard(this->emitDivf(getFPOptions(BO), BO));
940 return Discard(this->emitDiv(*T, BO));
941 case BO_Assign:
942 if (DiscardResult)
943 return LHS->refersToBitField() ? this->emitStoreBitFieldPop(*T, BO)
944 : this->emitStorePop(*T, BO);
945 if (LHS->refersToBitField()) {
946 if (!this->emitStoreBitField(*T, BO))
947 return false;
948 } else {
949 if (!this->emitStore(*T, BO))
950 return false;
951 }
952 // Assignments aren't necessarily lvalues in C.
953 // Load from them in that case.
954 if (!BO->isLValue())
955 return this->emitLoadPop(*T, BO);
956 return true;
957 case BO_And:
958 return Discard(this->emitBitAnd(*T, BO));
959 case BO_Or:
960 return Discard(this->emitBitOr(*T, BO));
961 case BO_Shl:
962 return Discard(this->emitShl(*LT, *RT, BO));
963 case BO_Shr:
964 return Discard(this->emitShr(*LT, *RT, BO));
965 case BO_Xor:
966 return Discard(this->emitBitXor(*T, BO));
967 case BO_LOr:
968 case BO_LAnd:
969 llvm_unreachable("Already handled earlier");
970 default:
971 return false;
972 }
973
974 llvm_unreachable("Unhandled binary op");
975}
976
977/// Perform addition/subtraction of a pointer and an integer or
978/// subtraction of two pointers.
979template <class Emitter>
981 BinaryOperatorKind Op = E->getOpcode();
982 const Expr *LHS = E->getLHS();
983 const Expr *RHS = E->getRHS();
984
985 if ((Op != BO_Add && Op != BO_Sub) ||
986 (!LHS->getType()->isPointerType() && !RHS->getType()->isPointerType()))
987 return false;
988
989 std::optional<PrimType> LT = classify(LHS);
990 std::optional<PrimType> RT = classify(RHS);
991
992 if (!LT || !RT)
993 return false;
994
995 // Visit the given pointer expression and optionally convert to a PT_Ptr.
996 auto visitAsPointer = [&](const Expr *E, PrimType T) -> bool {
997 if (!this->visit(E))
998 return false;
999 if (T != PT_Ptr)
1000 return this->emitDecayPtr(T, PT_Ptr, E);
1001 return true;
1002 };
1003
1004 if (LHS->getType()->isPointerType() && RHS->getType()->isPointerType()) {
1005 if (Op != BO_Sub)
1006 return false;
1007
1008 assert(E->getType()->isIntegerType());
1009 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *LT))
1010 return false;
1011
1012 PrimType IntT = classifyPrim(E->getType());
1013 if (!this->emitSubPtr(IntT, E))
1014 return false;
1015 return DiscardResult ? this->emitPop(IntT, E) : true;
1016 }
1017
1018 PrimType OffsetType;
1019 if (LHS->getType()->isIntegerType()) {
1020 if (!visitAsPointer(RHS, *RT))
1021 return false;
1022 if (!this->visit(LHS))
1023 return false;
1024 OffsetType = *LT;
1025 } else if (RHS->getType()->isIntegerType()) {
1026 if (!visitAsPointer(LHS, *LT))
1027 return false;
1028 if (!this->visit(RHS))
1029 return false;
1030 OffsetType = *RT;
1031 } else {
1032 return false;
1033 }
1034
1035 // Do the operation and optionally transform to
1036 // result pointer type.
1037 if (Op == BO_Add) {
1038 if (!this->emitAddOffset(OffsetType, E))
1039 return false;
1040
1041 if (classifyPrim(E) != PT_Ptr)
1042 return this->emitDecayPtr(PT_Ptr, classifyPrim(E), E);
1043 return true;
1044 } else if (Op == BO_Sub) {
1045 if (!this->emitSubOffset(OffsetType, E))
1046 return false;
1047
1048 if (classifyPrim(E) != PT_Ptr)
1049 return this->emitDecayPtr(PT_Ptr, classifyPrim(E), E);
1050 return true;
1051 }
1052
1053 return false;
1054}
1055
1056template <class Emitter>
1058 assert(E->isLogicalOp());
1059 BinaryOperatorKind Op = E->getOpcode();
1060 const Expr *LHS = E->getLHS();
1061 const Expr *RHS = E->getRHS();
1062 std::optional<PrimType> T = classify(E->getType());
1063
1064 if (Op == BO_LOr) {
1065 // Logical OR. Visit LHS and only evaluate RHS if LHS was FALSE.
1066 LabelTy LabelTrue = this->getLabel();
1067 LabelTy LabelEnd = this->getLabel();
1068
1069 if (!this->visitBool(LHS))
1070 return false;
1071 if (!this->jumpTrue(LabelTrue))
1072 return false;
1073
1074 if (!this->visitBool(RHS))
1075 return false;
1076 if (!this->jump(LabelEnd))
1077 return false;
1078
1079 this->emitLabel(LabelTrue);
1080 this->emitConstBool(true, E);
1081 this->fallthrough(LabelEnd);
1082 this->emitLabel(LabelEnd);
1083
1084 } else {
1085 assert(Op == BO_LAnd);
1086 // Logical AND.
1087 // Visit LHS. Only visit RHS if LHS was TRUE.
1088 LabelTy LabelFalse = this->getLabel();
1089 LabelTy LabelEnd = this->getLabel();
1090
1091 if (!this->visitBool(LHS))
1092 return false;
1093 if (!this->jumpFalse(LabelFalse))
1094 return false;
1095
1096 if (!this->visitBool(RHS))
1097 return false;
1098 if (!this->jump(LabelEnd))
1099 return false;
1100
1101 this->emitLabel(LabelFalse);
1102 this->emitConstBool(false, E);
1103 this->fallthrough(LabelEnd);
1104 this->emitLabel(LabelEnd);
1105 }
1106
1107 if (DiscardResult)
1108 return this->emitPopBool(E);
1109
1110 // For C, cast back to integer type.
1111 assert(T);
1112 if (T != PT_Bool)
1113 return this->emitCast(PT_Bool, *T, E);
1114 return true;
1115}
1116
1117template <class Emitter>
1119 // Prepare storage for result.
1120 if (!Initializing) {
1121 unsigned LocalIndex = allocateTemporary(E);
1122 if (!this->emitGetPtrLocal(LocalIndex, E))
1123 return false;
1124 }
1125
1126 // Both LHS and RHS might _not_ be of complex type, but one of them
1127 // needs to be.
1128 const Expr *LHS = E->getLHS();
1129 const Expr *RHS = E->getRHS();
1130
1131 PrimType ResultElemT = this->classifyComplexElementType(E->getType());
1132 unsigned ResultOffset = ~0u;
1133 if (!DiscardResult)
1134 ResultOffset = this->allocateLocalPrimitive(E, PT_Ptr, true, false);
1135
1136 // Save result pointer in ResultOffset
1137 if (!this->DiscardResult) {
1138 if (!this->emitDupPtr(E))
1139 return false;
1140 if (!this->emitSetLocal(PT_Ptr, ResultOffset, E))
1141 return false;
1142 }
1143 QualType LHSType = LHS->getType();
1144 if (const auto *AT = LHSType->getAs<AtomicType>())
1145 LHSType = AT->getValueType();
1146 QualType RHSType = RHS->getType();
1147 if (const auto *AT = RHSType->getAs<AtomicType>())
1148 RHSType = AT->getValueType();
1149
1150 bool LHSIsComplex = LHSType->isAnyComplexType();
1151 unsigned LHSOffset;
1152 bool RHSIsComplex = RHSType->isAnyComplexType();
1153
1154 // For ComplexComplex Mul, we have special ops to make their implementation
1155 // easier.
1156 BinaryOperatorKind Op = E->getOpcode();
1157 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1158 assert(classifyPrim(LHSType->getAs<ComplexType>()->getElementType()) ==
1159 classifyPrim(RHSType->getAs<ComplexType>()->getElementType()));
1160 PrimType ElemT =
1161 classifyPrim(LHSType->getAs<ComplexType>()->getElementType());
1162 if (!this->visit(LHS))
1163 return false;
1164 if (!this->visit(RHS))
1165 return false;
1166 return this->emitMulc(ElemT, E);
1167 }
1168
1169 if (Op == BO_Div && RHSIsComplex) {
1170 QualType ElemQT = RHSType->getAs<ComplexType>()->getElementType();
1171 PrimType ElemT = classifyPrim(ElemQT);
1172 // If the LHS is not complex, we still need to do the full complex
1173 // division, so just stub create a complex value and stub it out with
1174 // the LHS and a zero.
1175
1176 if (!LHSIsComplex) {
1177 // This is using the RHS type for the fake-complex LHS.
1178 LHSOffset = allocateTemporary(RHS);
1179
1180 if (!this->emitGetPtrLocal(LHSOffset, E))
1181 return false;
1182
1183 if (!this->visit(LHS))
1184 return false;
1185 // real is LHS
1186 if (!this->emitInitElem(ElemT, 0, E))
1187 return false;
1188 // imag is zero
1189 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1190 return false;
1191 if (!this->emitInitElem(ElemT, 1, E))
1192 return false;
1193 } else {
1194 if (!this->visit(LHS))
1195 return false;
1196 }
1197
1198 if (!this->visit(RHS))
1199 return false;
1200 return this->emitDivc(ElemT, E);
1201 }
1202
1203 // Evaluate LHS and save value to LHSOffset.
1204 if (LHSType->isAnyComplexType()) {
1205 LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false);
1206 if (!this->visit(LHS))
1207 return false;
1208 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
1209 return false;
1210 } else {
1211 PrimType LHST = classifyPrim(LHSType);
1212 LHSOffset = this->allocateLocalPrimitive(LHS, LHST, true, false);
1213 if (!this->visit(LHS))
1214 return false;
1215 if (!this->emitSetLocal(LHST, LHSOffset, E))
1216 return false;
1217 }
1218
1219 // Same with RHS.
1220 unsigned RHSOffset;
1221 if (RHSType->isAnyComplexType()) {
1222 RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false);
1223 if (!this->visit(RHS))
1224 return false;
1225 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
1226 return false;
1227 } else {
1228 PrimType RHST = classifyPrim(RHSType);
1229 RHSOffset = this->allocateLocalPrimitive(RHS, RHST, true, false);
1230 if (!this->visit(RHS))
1231 return false;
1232 if (!this->emitSetLocal(RHST, RHSOffset, E))
1233 return false;
1234 }
1235
1236 // For both LHS and RHS, either load the value from the complex pointer, or
1237 // directly from the local variable. For index 1 (i.e. the imaginary part),
1238 // just load 0 and do the operation anyway.
1239 auto loadComplexValue = [this](bool IsComplex, bool LoadZero,
1240 unsigned ElemIndex, unsigned Offset,
1241 const Expr *E) -> bool {
1242 if (IsComplex) {
1243 if (!this->emitGetLocal(PT_Ptr, Offset, E))
1244 return false;
1245 return this->emitArrayElemPop(classifyComplexElementType(E->getType()),
1246 ElemIndex, E);
1247 }
1248 if (ElemIndex == 0 || !LoadZero)
1249 return this->emitGetLocal(classifyPrim(E->getType()), Offset, E);
1250 return this->visitZeroInitializer(classifyPrim(E->getType()), E->getType(),
1251 E);
1252 };
1253
1254 // Now we can get pointers to the LHS and RHS from the offsets above.
1255 for (unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1256 // Result pointer for the store later.
1257 if (!this->DiscardResult) {
1258 if (!this->emitGetLocal(PT_Ptr, ResultOffset, E))
1259 return false;
1260 }
1261
1262 // The actual operation.
1263 switch (Op) {
1264 case BO_Add:
1265 if (!loadComplexValue(LHSIsComplex, true, ElemIndex, LHSOffset, LHS))
1266 return false;
1267
1268 if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))
1269 return false;
1270 if (ResultElemT == PT_Float) {
1271 if (!this->emitAddf(getFPOptions(E), E))
1272 return false;
1273 } else {
1274 if (!this->emitAdd(ResultElemT, E))
1275 return false;
1276 }
1277 break;
1278 case BO_Sub:
1279 if (!loadComplexValue(LHSIsComplex, true, ElemIndex, LHSOffset, LHS))
1280 return false;
1281
1282 if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))
1283 return false;
1284 if (ResultElemT == PT_Float) {
1285 if (!this->emitSubf(getFPOptions(E), E))
1286 return false;
1287 } else {
1288 if (!this->emitSub(ResultElemT, E))
1289 return false;
1290 }
1291 break;
1292 case BO_Mul:
1293 if (!loadComplexValue(LHSIsComplex, false, ElemIndex, LHSOffset, LHS))
1294 return false;
1295
1296 if (!loadComplexValue(RHSIsComplex, false, ElemIndex, RHSOffset, RHS))
1297 return false;
1298
1299 if (ResultElemT == PT_Float) {
1300 if (!this->emitMulf(getFPOptions(E), E))
1301 return false;
1302 } else {
1303 if (!this->emitMul(ResultElemT, E))
1304 return false;
1305 }
1306 break;
1307 case BO_Div:
1308 assert(!RHSIsComplex);
1309 if (!loadComplexValue(LHSIsComplex, false, ElemIndex, LHSOffset, LHS))
1310 return false;
1311
1312 if (!loadComplexValue(RHSIsComplex, false, ElemIndex, RHSOffset, RHS))
1313 return false;
1314
1315 if (ResultElemT == PT_Float) {
1316 if (!this->emitDivf(getFPOptions(E), E))
1317 return false;
1318 } else {
1319 if (!this->emitDiv(ResultElemT, E))
1320 return false;
1321 }
1322 break;
1323
1324 default:
1325 return false;
1326 }
1327
1328 if (!this->DiscardResult) {
1329 // Initialize array element with the value we just computed.
1330 if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))
1331 return false;
1332 } else {
1333 if (!this->emitPop(ResultElemT, E))
1334 return false;
1335 }
1336 }
1337 return true;
1338}
1339
1340template <class Emitter>
1342 assert(!E->isCommaOp() &&
1343 "Comma op should be handled in VisitBinaryOperator");
1344 assert(E->getType()->isVectorType());
1345 assert(E->getLHS()->getType()->isVectorType());
1346 assert(E->getRHS()->getType()->isVectorType());
1347
1348 // Prepare storage for result.
1349 if (!Initializing && !E->isCompoundAssignmentOp()) {
1350 unsigned LocalIndex = allocateTemporary(E);
1351 if (!this->emitGetPtrLocal(LocalIndex, E))
1352 return false;
1353 }
1354
1355 const Expr *LHS = E->getLHS();
1356 const Expr *RHS = E->getRHS();
1357 const auto *VecTy = E->getType()->getAs<VectorType>();
1358 auto Op = E->isCompoundAssignmentOp()
1360 : E->getOpcode();
1361
1362 PrimType ElemT = this->classifyVectorElementType(LHS->getType());
1363 PrimType RHSElemT = this->classifyVectorElementType(RHS->getType());
1364 PrimType ResultElemT = this->classifyVectorElementType(E->getType());
1365
1366 // Evaluate LHS and save value to LHSOffset.
1367 unsigned LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false);
1368 if (!this->visit(LHS))
1369 return false;
1370 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
1371 return false;
1372
1373 // Evaluate RHS and save value to RHSOffset.
1374 unsigned RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false);
1375 if (!this->visit(RHS))
1376 return false;
1377 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
1378 return false;
1379
1380 if (E->isCompoundAssignmentOp() && !this->emitGetLocal(PT_Ptr, LHSOffset, E))
1381 return false;
1382
1383 // BitAdd/BitOr/BitXor/Shl/Shr doesn't support bool type, we need perform the
1384 // integer promotion.
1385 bool NeedIntPromot = ElemT == PT_Bool && (E->isBitwiseOp() || E->isShiftOp());
1386 QualType PromotTy =
1387 Ctx.getASTContext().getPromotedIntegerType(Ctx.getASTContext().BoolTy);
1388 PrimType PromotT = classifyPrim(PromotTy);
1389 PrimType OpT = NeedIntPromot ? PromotT : ElemT;
1390
1391 auto getElem = [=](unsigned Offset, PrimType ElemT, unsigned Index) {
1392 if (!this->emitGetLocal(PT_Ptr, Offset, E))
1393 return false;
1394 if (!this->emitArrayElemPop(ElemT, Index, E))
1395 return false;
1396 if (E->isLogicalOp()) {
1397 if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E))
1398 return false;
1399 if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E))
1400 return false;
1401 } else if (NeedIntPromot) {
1402 if (!this->emitPrimCast(ElemT, PromotT, PromotTy, E))
1403 return false;
1404 }
1405 return true;
1406 };
1407
1408#define EMIT_ARITH_OP(OP) \
1409 { \
1410 if (ElemT == PT_Float) { \
1411 if (!this->emit##OP##f(getFPOptions(E), E)) \
1412 return false; \
1413 } else { \
1414 if (!this->emit##OP(ElemT, E)) \
1415 return false; \
1416 } \
1417 break; \
1418 }
1419
1420 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
1421 if (!getElem(LHSOffset, ElemT, I))
1422 return false;
1423 if (!getElem(RHSOffset, RHSElemT, I))
1424 return false;
1425 switch (Op) {
1426 case BO_Add:
1428 case BO_Sub:
1430 case BO_Mul:
1432 case BO_Div:
1434 case BO_Rem:
1435 if (!this->emitRem(ElemT, E))
1436 return false;
1437 break;
1438 case BO_And:
1439 if (!this->emitBitAnd(OpT, E))
1440 return false;
1441 break;
1442 case BO_Or:
1443 if (!this->emitBitOr(OpT, E))
1444 return false;
1445 break;
1446 case BO_Xor:
1447 if (!this->emitBitXor(OpT, E))
1448 return false;
1449 break;
1450 case BO_Shl:
1451 if (!this->emitShl(OpT, RHSElemT, E))
1452 return false;
1453 break;
1454 case BO_Shr:
1455 if (!this->emitShr(OpT, RHSElemT, E))
1456 return false;
1457 break;
1458 case BO_EQ:
1459 if (!this->emitEQ(ElemT, E))
1460 return false;
1461 break;
1462 case BO_NE:
1463 if (!this->emitNE(ElemT, E))
1464 return false;
1465 break;
1466 case BO_LE:
1467 if (!this->emitLE(ElemT, E))
1468 return false;
1469 break;
1470 case BO_LT:
1471 if (!this->emitLT(ElemT, E))
1472 return false;
1473 break;
1474 case BO_GE:
1475 if (!this->emitGE(ElemT, E))
1476 return false;
1477 break;
1478 case BO_GT:
1479 if (!this->emitGT(ElemT, E))
1480 return false;
1481 break;
1482 case BO_LAnd:
1483 // a && b is equivalent to a!=0 & b!=0
1484 if (!this->emitBitAnd(ResultElemT, E))
1485 return false;
1486 break;
1487 case BO_LOr:
1488 // a || b is equivalent to a!=0 | b!=0
1489 if (!this->emitBitOr(ResultElemT, E))
1490 return false;
1491 break;
1492 default:
1493 return this->emitInvalid(E);
1494 }
1495
1496 // The result of the comparison is a vector of the same width and number
1497 // of elements as the comparison operands with a signed integral element
1498 // type.
1499 //
1500 // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
1501 if (E->isComparisonOp()) {
1502 if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E))
1503 return false;
1504 if (!this->emitNeg(ResultElemT, E))
1505 return false;
1506 }
1507
1508 // If we performed an integer promotion, we need to cast the compute result
1509 // into result vector element type.
1510 if (NeedIntPromot &&
1511 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(), E))
1512 return false;
1513
1514 // Initialize array element with the value we just computed.
1515 if (!this->emitInitElem(ResultElemT, I, E))
1516 return false;
1517 }
1518
1519 if (DiscardResult && E->isCompoundAssignmentOp() && !this->emitPopPtr(E))
1520 return false;
1521 return true;
1522}
1523
1524template <class Emitter>
1526 const Expr *LHS = E->getLHS();
1527 const Expr *RHS = E->getRHS();
1528 const ASTContext &ASTCtx = Ctx.getASTContext();
1529
1530 assert(LHS->getType()->isFixedPointType() ||
1531 RHS->getType()->isFixedPointType());
1532
1533 auto LHSSema = ASTCtx.getFixedPointSemantics(LHS->getType());
1534 auto LHSSemaInt = LHSSema.toOpaqueInt();
1535 auto RHSSema = ASTCtx.getFixedPointSemantics(RHS->getType());
1536 auto RHSSemaInt = RHSSema.toOpaqueInt();
1537
1538 if (!this->visit(LHS))
1539 return false;
1540 if (!LHS->getType()->isFixedPointType()) {
1541 if (!this->emitCastIntegralFixedPoint(classifyPrim(LHS->getType()),
1542 LHSSemaInt, E))
1543 return false;
1544 }
1545
1546 if (!this->visit(RHS))
1547 return false;
1548 if (!RHS->getType()->isFixedPointType()) {
1549 if (!this->emitCastIntegralFixedPoint(classifyPrim(RHS->getType()),
1550 RHSSemaInt, E))
1551 return false;
1552 }
1553
1554 // Convert the result to the target semantics.
1555 auto ConvertResult = [&](bool R) -> bool {
1556 if (!R)
1557 return false;
1558 auto ResultSema = ASTCtx.getFixedPointSemantics(E->getType()).toOpaqueInt();
1559 auto CommonSema = LHSSema.getCommonSemantics(RHSSema).toOpaqueInt();
1560 if (ResultSema != CommonSema)
1561 return this->emitCastFixedPoint(ResultSema, E);
1562 return true;
1563 };
1564
1565 auto MaybeCastToBool = [&](bool Result) {
1566 if (!Result)
1567 return false;
1568 PrimType T = classifyPrim(E);
1569 if (DiscardResult)
1570 return this->emitPop(T, E);
1571 if (T != PT_Bool)
1572 return this->emitCast(PT_Bool, T, E);
1573 return true;
1574 };
1575
1576 switch (E->getOpcode()) {
1577 case BO_EQ:
1578 return MaybeCastToBool(this->emitEQFixedPoint(E));
1579 case BO_NE:
1580 return MaybeCastToBool(this->emitNEFixedPoint(E));
1581 case BO_LT:
1582 return MaybeCastToBool(this->emitLTFixedPoint(E));
1583 case BO_LE:
1584 return MaybeCastToBool(this->emitLEFixedPoint(E));
1585 case BO_GT:
1586 return MaybeCastToBool(this->emitGTFixedPoint(E));
1587 case BO_GE:
1588 return MaybeCastToBool(this->emitGEFixedPoint(E));
1589 case BO_Add:
1590 return ConvertResult(this->emitAddFixedPoint(E));
1591 case BO_Sub:
1592 return ConvertResult(this->emitSubFixedPoint(E));
1593 case BO_Mul:
1594 return ConvertResult(this->emitMulFixedPoint(E));
1595 case BO_Div:
1596 return ConvertResult(this->emitDivFixedPoint(E));
1597 case BO_Shl:
1598 return ConvertResult(this->emitShiftFixedPoint(/*Left=*/true, E));
1599 case BO_Shr:
1600 return ConvertResult(this->emitShiftFixedPoint(/*Left=*/false, E));
1601
1602 default:
1603 return this->emitInvalid(E);
1604 }
1605
1606 llvm_unreachable("unhandled binop opcode");
1607}
1608
1609template <class Emitter>
1611 const Expr *SubExpr = E->getSubExpr();
1612 assert(SubExpr->getType()->isFixedPointType());
1613
1614 switch (E->getOpcode()) {
1615 case UO_Plus:
1616 return this->delegate(SubExpr);
1617 case UO_Minus:
1618 if (!this->visit(SubExpr))
1619 return false;
1620 return this->emitNegFixedPoint(E);
1621 default:
1622 return false;
1623 }
1624
1625 llvm_unreachable("Unhandled unary opcode");
1626}
1627
1628template <class Emitter>
1630 const ImplicitValueInitExpr *E) {
1631 QualType QT = E->getType();
1632
1633 if (std::optional<PrimType> T = classify(QT))
1634 return this->visitZeroInitializer(*T, QT, E);
1635
1636 if (QT->isRecordType()) {
1637 const RecordDecl *RD = QT->getAsRecordDecl();
1638 assert(RD);
1639 if (RD->isInvalidDecl())
1640 return false;
1641
1642 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1643 CXXRD && CXXRD->getNumVBases() > 0) {
1644 // TODO: Diagnose.
1645 return false;
1646 }
1647
1648 const Record *R = getRecord(QT);
1649 if (!R)
1650 return false;
1651
1652 assert(Initializing);
1653 return this->visitZeroRecordInitializer(R, E);
1654 }
1655
1656 if (QT->isIncompleteArrayType())
1657 return true;
1658
1659 if (QT->isArrayType())
1660 return this->visitZeroArrayInitializer(QT, E);
1661
1662 if (const auto *ComplexTy = E->getType()->getAs<ComplexType>()) {
1663 assert(Initializing);
1664 QualType ElemQT = ComplexTy->getElementType();
1665 PrimType ElemT = classifyPrim(ElemQT);
1666 for (unsigned I = 0; I < 2; ++I) {
1667 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1668 return false;
1669 if (!this->emitInitElem(ElemT, I, E))
1670 return false;
1671 }
1672 return true;
1673 }
1674
1675 if (const auto *VecT = E->getType()->getAs<VectorType>()) {
1676 unsigned NumVecElements = VecT->getNumElements();
1677 QualType ElemQT = VecT->getElementType();
1678 PrimType ElemT = classifyPrim(ElemQT);
1679
1680 for (unsigned I = 0; I < NumVecElements; ++I) {
1681 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1682 return false;
1683 if (!this->emitInitElem(ElemT, I, E))
1684 return false;
1685 }
1686 return true;
1687 }
1688
1689 return false;
1690}
1691
1692template <class Emitter>
1694 const Expr *LHS = E->getLHS();
1695 const Expr *RHS = E->getRHS();
1696 const Expr *Index = E->getIdx();
1697
1698 if (DiscardResult)
1699 return this->discard(LHS) && this->discard(RHS);
1700
1701 // C++17's rules require us to evaluate the LHS first, regardless of which
1702 // side is the base.
1703 bool Success = true;
1704 for (const Expr *SubExpr : {LHS, RHS}) {
1705 if (!this->visit(SubExpr))
1706 Success = false;
1707 }
1708
1709 if (!Success)
1710 return false;
1711
1712 PrimType IndexT = classifyPrim(Index->getType());
1713 // If the index is first, we need to change that.
1714 if (LHS == Index) {
1715 if (!this->emitFlip(PT_Ptr, IndexT, E))
1716 return false;
1717 }
1718
1719 return this->emitArrayElemPtrPop(IndexT, E);
1720}
1721
1722template <class Emitter>
1724 const Expr *ArrayFiller, const Expr *E) {
1726
1727 QualType QT = E->getType();
1728 if (const auto *AT = QT->getAs<AtomicType>())
1729 QT = AT->getValueType();
1730
1731 if (QT->isVoidType()) {
1732 if (Inits.size() == 0)
1733 return true;
1734 return this->emitInvalid(E);
1735 }
1736
1737 // Handle discarding first.
1738 if (DiscardResult) {
1739 for (const Expr *Init : Inits) {
1740 if (!this->discard(Init))
1741 return false;
1742 }
1743 return true;
1744 }
1745
1746 // Primitive values.
1747 if (std::optional<PrimType> T = classify(QT)) {
1748 assert(!DiscardResult);
1749 if (Inits.size() == 0)
1750 return this->visitZeroInitializer(*T, QT, E);
1751 assert(Inits.size() == 1);
1752 return this->delegate(Inits[0]);
1753 }
1754
1755 if (QT->isRecordType()) {
1756 const Record *R = getRecord(QT);
1757
1758 if (Inits.size() == 1 && E->getType() == Inits[0]->getType())
1759 return this->delegate(Inits[0]);
1760
1761 auto initPrimitiveField = [=](const Record::Field *FieldToInit,
1762 const Expr *Init, PrimType T) -> bool {
1763 InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(Init));
1764 InitLinkScope<Emitter> ILS(this, InitLink::Field(FieldToInit->Offset));
1765 if (!this->visit(Init))
1766 return false;
1767
1768 if (FieldToInit->isBitField())
1769 return this->emitInitBitField(T, FieldToInit, E);
1770 return this->emitInitField(T, FieldToInit->Offset, E);
1771 };
1772
1773 auto initCompositeField = [=](const Record::Field *FieldToInit,
1774 const Expr *Init) -> bool {
1775 InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(Init));
1776 InitLinkScope<Emitter> ILS(this, InitLink::Field(FieldToInit->Offset));
1777
1778 // Non-primitive case. Get a pointer to the field-to-initialize
1779 // on the stack and recurse into visitInitializer().
1780 if (!this->emitGetPtrField(FieldToInit->Offset, Init))
1781 return false;
1782 if (!this->visitInitializer(Init))
1783 return false;
1784 return this->emitPopPtr(E);
1785 };
1786
1787 if (R->isUnion()) {
1788 if (Inits.size() == 0) {
1789 if (!this->visitZeroRecordInitializer(R, E))
1790 return false;
1791 } else {
1792 const Expr *Init = Inits[0];
1793 const FieldDecl *FToInit = nullptr;
1794 if (const auto *ILE = dyn_cast<InitListExpr>(E))
1795 FToInit = ILE->getInitializedFieldInUnion();
1796 else
1797 FToInit = cast<CXXParenListInitExpr>(E)->getInitializedFieldInUnion();
1798
1799 const Record::Field *FieldToInit = R->getField(FToInit);
1800 if (std::optional<PrimType> T = classify(Init)) {
1801 if (!initPrimitiveField(FieldToInit, Init, *T))
1802 return false;
1803 } else {
1804 if (!initCompositeField(FieldToInit, Init))
1805 return false;
1806 }
1807 }
1808 return this->emitFinishInit(E);
1809 }
1810
1811 assert(!R->isUnion());
1812 unsigned InitIndex = 0;
1813 for (const Expr *Init : Inits) {
1814 // Skip unnamed bitfields.
1815 while (InitIndex < R->getNumFields() &&
1816 R->getField(InitIndex)->Decl->isUnnamedBitField())
1817 ++InitIndex;
1818
1819 if (std::optional<PrimType> T = classify(Init)) {
1820 const Record::Field *FieldToInit = R->getField(InitIndex);
1821 if (!initPrimitiveField(FieldToInit, Init, *T))
1822 return false;
1823 ++InitIndex;
1824 } else {
1825 // Initializer for a direct base class.
1826 if (const Record::Base *B = R->getBase(Init->getType())) {
1827 if (!this->emitGetPtrBase(B->Offset, Init))
1828 return false;
1829
1830 if (!this->visitInitializer(Init))
1831 return false;
1832
1833 if (!this->emitFinishInitPop(E))
1834 return false;
1835 // Base initializers don't increase InitIndex, since they don't count
1836 // into the Record's fields.
1837 } else {
1838 const Record::Field *FieldToInit = R->getField(InitIndex);
1839 if (!initCompositeField(FieldToInit, Init))
1840 return false;
1841 ++InitIndex;
1842 }
1843 }
1844 }
1845 return this->emitFinishInit(E);
1846 }
1847
1848 if (QT->isArrayType()) {
1849 if (Inits.size() == 1 && QT == Inits[0]->getType())
1850 return this->delegate(Inits[0]);
1851
1852 unsigned ElementIndex = 0;
1853 for (const Expr *Init : Inits) {
1854 if (const auto *EmbedS =
1855 dyn_cast<EmbedExpr>(Init->IgnoreParenImpCasts())) {
1856 PrimType TargetT = classifyPrim(Init->getType());
1857
1858 auto Eval = [&](const Expr *Init, unsigned ElemIndex) {
1859 PrimType InitT = classifyPrim(Init->getType());
1860 if (!this->visit(Init))
1861 return false;
1862 if (InitT != TargetT) {
1863 if (!this->emitCast(InitT, TargetT, E))
1864 return false;
1865 }
1866 return this->emitInitElem(TargetT, ElemIndex, Init);
1867 };
1868 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
1869 return false;
1870 } else {
1871 if (!this->visitArrayElemInit(ElementIndex, Init))
1872 return false;
1873 ++ElementIndex;
1874 }
1875 }
1876
1877 // Expand the filler expression.
1878 // FIXME: This should go away.
1879 if (ArrayFiller) {
1880 const ConstantArrayType *CAT =
1881 Ctx.getASTContext().getAsConstantArrayType(QT);
1882 uint64_t NumElems = CAT->getZExtSize();
1883
1884 for (; ElementIndex != NumElems; ++ElementIndex) {
1885 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller))
1886 return false;
1887 }
1888 }
1889
1890 return this->emitFinishInit(E);
1891 }
1892
1893 if (const auto *ComplexTy = QT->getAs<ComplexType>()) {
1894 unsigned NumInits = Inits.size();
1895
1896 if (NumInits == 1)
1897 return this->delegate(Inits[0]);
1898
1899 QualType ElemQT = ComplexTy->getElementType();
1900 PrimType ElemT = classifyPrim(ElemQT);
1901 if (NumInits == 0) {
1902 // Zero-initialize both elements.
1903 for (unsigned I = 0; I < 2; ++I) {
1904 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1905 return false;
1906 if (!this->emitInitElem(ElemT, I, E))
1907 return false;
1908 }
1909 } else if (NumInits == 2) {
1910 unsigned InitIndex = 0;
1911 for (const Expr *Init : Inits) {
1912 if (!this->visit(Init))
1913 return false;
1914
1915 if (!this->emitInitElem(ElemT, InitIndex, E))
1916 return false;
1917 ++InitIndex;
1918 }
1919 }
1920 return true;
1921 }
1922
1923 if (const auto *VecT = QT->getAs<VectorType>()) {
1924 unsigned NumVecElements = VecT->getNumElements();
1925 assert(NumVecElements >= Inits.size());
1926
1927 QualType ElemQT = VecT->getElementType();
1928 PrimType ElemT = classifyPrim(ElemQT);
1929
1930 // All initializer elements.
1931 unsigned InitIndex = 0;
1932 for (const Expr *Init : Inits) {
1933 if (!this->visit(Init))
1934 return false;
1935
1936 // If the initializer is of vector type itself, we have to deconstruct
1937 // that and initialize all the target fields from the initializer fields.
1938 if (const auto *InitVecT = Init->getType()->getAs<VectorType>()) {
1939 if (!this->emitCopyArray(ElemT, 0, InitIndex,
1940 InitVecT->getNumElements(), E))
1941 return false;
1942 InitIndex += InitVecT->getNumElements();
1943 } else {
1944 if (!this->emitInitElem(ElemT, InitIndex, E))
1945 return false;
1946 ++InitIndex;
1947 }
1948 }
1949
1950 assert(InitIndex <= NumVecElements);
1951
1952 // Fill the rest with zeroes.
1953 for (; InitIndex != NumVecElements; ++InitIndex) {
1954 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1955 return false;
1956 if (!this->emitInitElem(ElemT, InitIndex, E))
1957 return false;
1958 }
1959 return true;
1960 }
1961
1962 return false;
1963}
1964
1965/// Pointer to the array(not the element!) must be on the stack when calling
1966/// this.
1967template <class Emitter>
1969 const Expr *Init) {
1970 if (std::optional<PrimType> T = classify(Init->getType())) {
1971 // Visit the primitive element like normal.
1972 if (!this->visit(Init))
1973 return false;
1974 return this->emitInitElem(*T, ElemIndex, Init);
1975 }
1976
1977 InitLinkScope<Emitter> ILS(this, InitLink::Elem(ElemIndex));
1978 // Advance the pointer currently on the stack to the given
1979 // dimension.
1980 if (!this->emitConstUint32(ElemIndex, Init))
1981 return false;
1982 if (!this->emitArrayElemPtrUint32(Init))
1983 return false;
1984 if (!this->visitInitializer(Init))
1985 return false;
1986 return this->emitFinishInitPop(Init);
1987}
1988
1989template <class Emitter>
1991 return this->visitInitList(E->inits(), E->getArrayFiller(), E);
1992}
1993
1994template <class Emitter>
1996 const CXXParenListInitExpr *E) {
1997 return this->visitInitList(E->getInitExprs(), E->getArrayFiller(), E);
1998}
1999
2000template <class Emitter>
2003 return this->delegate(E->getReplacement());
2004}
2005
2006template <class Emitter>
2008 std::optional<PrimType> T = classify(E->getType());
2009 if (T && E->hasAPValueResult()) {
2010 // Try to emit the APValue directly, without visiting the subexpr.
2011 // This will only fail if we can't emit the APValue, so won't emit any
2012 // diagnostics or any double values.
2013 if (DiscardResult)
2014 return true;
2015
2016 if (this->visitAPValue(E->getAPValueResult(), *T, E))
2017 return true;
2018 }
2019 return this->delegate(E->getSubExpr());
2020}
2021
2022template <class Emitter>
2024 auto It = E->begin();
2025 return this->visit(*It);
2026}
2027
2029 UnaryExprOrTypeTrait Kind) {
2030 bool AlignOfReturnsPreferred =
2031 ASTCtx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
2032
2033 // C++ [expr.alignof]p3:
2034 // When alignof is applied to a reference type, the result is the
2035 // alignment of the referenced type.
2036 if (const auto *Ref = T->getAs<ReferenceType>())
2037 T = Ref->getPointeeType();
2038
2039 if (T.getQualifiers().hasUnaligned())
2040 return CharUnits::One();
2041
2042 // __alignof is defined to return the preferred alignment.
2043 // Before 8, clang returned the preferred alignment for alignof and
2044 // _Alignof as well.
2045 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2046 return ASTCtx.toCharUnitsFromBits(ASTCtx.getPreferredTypeAlign(T));
2047
2048 return ASTCtx.getTypeAlignInChars(T);
2049}
2050
2051template <class Emitter>
2053 const UnaryExprOrTypeTraitExpr *E) {
2054 UnaryExprOrTypeTrait Kind = E->getKind();
2055 const ASTContext &ASTCtx = Ctx.getASTContext();
2056
2057 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2058 QualType ArgType = E->getTypeOfArgument();
2059
2060 // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
2061 // the result is the size of the referenced type."
2062 if (const auto *Ref = ArgType->getAs<ReferenceType>())
2063 ArgType = Ref->getPointeeType();
2064
2065 CharUnits Size;
2066 if (ArgType->isVoidType() || ArgType->isFunctionType())
2067 Size = CharUnits::One();
2068 else {
2069 if (ArgType->isDependentType() || !ArgType->isConstantSizeType())
2070 return this->emitInvalid(E);
2071
2072 if (Kind == UETT_SizeOf)
2073 Size = ASTCtx.getTypeSizeInChars(ArgType);
2074 else
2075 Size = ASTCtx.getTypeInfoDataSizeInChars(ArgType).Width;
2076 }
2077
2078 if (DiscardResult)
2079 return true;
2080
2081 return this->emitConst(Size.getQuantity(), E);
2082 }
2083
2084 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2085 CharUnits Size;
2086
2087 if (E->isArgumentType()) {
2088 QualType ArgType = E->getTypeOfArgument();
2089
2090 Size = AlignOfType(ArgType, ASTCtx, Kind);
2091 } else {
2092 // Argument is an expression, not a type.
2093 const Expr *Arg = E->getArgumentExpr()->IgnoreParens();
2094
2095 // The kinds of expressions that we have special-case logic here for
2096 // should be kept up to date with the special checks for those
2097 // expressions in Sema.
2098
2099 // alignof decl is always accepted, even if it doesn't make sense: we
2100 // default to 1 in those cases.
2101 if (const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2102 Size = ASTCtx.getDeclAlign(DRE->getDecl(),
2103 /*RefAsPointee*/ true);
2104 else if (const auto *ME = dyn_cast<MemberExpr>(Arg))
2105 Size = ASTCtx.getDeclAlign(ME->getMemberDecl(),
2106 /*RefAsPointee*/ true);
2107 else
2108 Size = AlignOfType(Arg->getType(), ASTCtx, Kind);
2109 }
2110
2111 if (DiscardResult)
2112 return true;
2113
2114 return this->emitConst(Size.getQuantity(), E);
2115 }
2116
2117 if (Kind == UETT_VectorElements) {
2118 if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>())
2119 return this->emitConst(VT->getNumElements(), E);
2120 assert(E->getTypeOfArgument()->isSizelessVectorType());
2121 return this->emitSizelessVectorElementSize(E);
2122 }
2123
2124 if (Kind == UETT_VecStep) {
2125 if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>()) {
2126 unsigned N = VT->getNumElements();
2127
2128 // The vec_step built-in functions that take a 3-component
2129 // vector return 4. (OpenCL 1.1 spec 6.11.12)
2130 if (N == 3)
2131 N = 4;
2132
2133 return this->emitConst(N, E);
2134 }
2135 return this->emitConst(1, E);
2136 }
2137
2138 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2139 assert(E->isArgumentType());
2140 unsigned Bits = ASTCtx.getOpenMPDefaultSimdAlign(E->getArgumentType());
2141
2142 return this->emitConst(ASTCtx.toCharUnitsFromBits(Bits).getQuantity(), E);
2143 }
2144
2145 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2146 if (E->getArgumentType()->isDependentType())
2147 return this->emitInvalid(E);
2148
2149 return this->emitConst(
2150 const_cast<ASTContext &>(ASTCtx).getPointerAuthTypeDiscriminator(
2151 E->getArgumentType()),
2152 E);
2153 }
2154
2155 return false;
2156}
2157
2158template <class Emitter>
2160 // 'Base.Member'
2161 const Expr *Base = E->getBase();
2162 const ValueDecl *Member = E->getMemberDecl();
2163
2164 if (DiscardResult)
2165 return this->discard(Base);
2166
2167 // MemberExprs are almost always lvalues, in which case we don't need to
2168 // do the load. But sometimes they aren't.
2169 const auto maybeLoadValue = [&]() -> bool {
2170 if (E->isGLValue())
2171 return true;
2172 if (std::optional<PrimType> T = classify(E))
2173 return this->emitLoadPop(*T, E);
2174 return false;
2175 };
2176
2177 if (const auto *VD = dyn_cast<VarDecl>(Member)) {
2178 // I am almost confident in saying that a var decl must be static
2179 // and therefore registered as a global variable. But this will probably
2180 // turn out to be wrong some time in the future, as always.
2181 if (auto GlobalIndex = P.getGlobal(VD))
2182 return this->emitGetPtrGlobal(*GlobalIndex, E) && maybeLoadValue();
2183 return false;
2184 }
2185
2186 if (!isa<FieldDecl>(Member)) {
2187 if (!this->discard(Base) && !this->emitSideEffect(E))
2188 return false;
2189
2190 return this->visitDeclRef(Member, E);
2191 }
2192
2193 if (Initializing) {
2194 if (!this->delegate(Base))
2195 return false;
2196 } else {
2197 if (!this->visit(Base))
2198 return false;
2199 }
2200
2201 // Base above gives us a pointer on the stack.
2202 const auto *FD = cast<FieldDecl>(Member);
2203 const RecordDecl *RD = FD->getParent();
2204 const Record *R = getRecord(RD);
2205 if (!R)
2206 return false;
2207 const Record::Field *F = R->getField(FD);
2208 // Leave a pointer to the field on the stack.
2209 if (F->Decl->getType()->isReferenceType())
2210 return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue();
2211 return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue();
2212}
2213
2214template <class Emitter>
2216 // ArrayIndex might not be set if a ArrayInitIndexExpr is being evaluated
2217 // stand-alone, e.g. via EvaluateAsInt().
2218 if (!ArrayIndex)
2219 return false;
2220 return this->emitConst(*ArrayIndex, E);
2221}
2222
2223template <class Emitter>
2225 assert(Initializing);
2226 assert(!DiscardResult);
2227
2228 // We visit the common opaque expression here once so we have its value
2229 // cached.
2230 if (!this->discard(E->getCommonExpr()))
2231 return false;
2232
2233 // TODO: This compiles to quite a lot of bytecode if the array is larger.
2234 // Investigate compiling this to a loop.
2235 const Expr *SubExpr = E->getSubExpr();
2236 size_t Size = E->getArraySize().getZExtValue();
2237
2238 // So, every iteration, we execute an assignment here
2239 // where the LHS is on the stack (the target array)
2240 // and the RHS is our SubExpr.
2241 for (size_t I = 0; I != Size; ++I) {
2242 ArrayIndexScope<Emitter> IndexScope(this, I);
2243 BlockScope<Emitter> BS(this);
2244
2245 if (!this->visitArrayElemInit(I, SubExpr))
2246 return false;
2247 if (!BS.destroyLocals())
2248 return false;
2249 }
2250 return true;
2251}
2252
2253template <class Emitter>
2255 const Expr *SourceExpr = E->getSourceExpr();
2256 if (!SourceExpr)
2257 return false;
2258
2259 if (Initializing)
2260 return this->visitInitializer(SourceExpr);
2261
2262 PrimType SubExprT = classify(SourceExpr).value_or(PT_Ptr);
2263 if (auto It = OpaqueExprs.find(E); It != OpaqueExprs.end())
2264 return this->emitGetLocal(SubExprT, It->second, E);
2265
2266 if (!this->visit(SourceExpr))
2267 return false;
2268
2269 // At this point we either have the evaluated source expression or a pointer
2270 // to an object on the stack. We want to create a local variable that stores
2271 // this value.
2272 unsigned LocalIndex = allocateLocalPrimitive(E, SubExprT, /*IsConst=*/true);
2273 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
2274 return false;
2275
2276 // Here the local variable is created but the value is removed from the stack,
2277 // so we put it back if the caller needs it.
2278 if (!DiscardResult) {
2279 if (!this->emitGetLocal(SubExprT, LocalIndex, E))
2280 return false;
2281 }
2282
2283 // This is cleaned up when the local variable is destroyed.
2284 OpaqueExprs.insert({E, LocalIndex});
2285
2286 return true;
2287}
2288
2289template <class Emitter>
2292 const Expr *Condition = E->getCond();
2293 const Expr *TrueExpr = E->getTrueExpr();
2294 const Expr *FalseExpr = E->getFalseExpr();
2295
2296 LabelTy LabelEnd = this->getLabel(); // Label after the operator.
2297 LabelTy LabelFalse = this->getLabel(); // Label for the false expr.
2298
2299 if (!this->visitBool(Condition))
2300 return false;
2301
2302 if (!this->jumpFalse(LabelFalse))
2303 return false;
2304
2305 {
2306 LocalScope<Emitter> S(this);
2307 if (!this->delegate(TrueExpr))
2308 return false;
2309 if (!S.destroyLocals())
2310 return false;
2311 }
2312
2313 if (!this->jump(LabelEnd))
2314 return false;
2315
2316 this->emitLabel(LabelFalse);
2317
2318 {
2319 LocalScope<Emitter> S(this);
2320 if (!this->delegate(FalseExpr))
2321 return false;
2322 if (!S.destroyLocals())
2323 return false;
2324 }
2325
2326 this->fallthrough(LabelEnd);
2327 this->emitLabel(LabelEnd);
2328
2329 return true;
2330}
2331
2332template <class Emitter>
2334 if (DiscardResult)
2335 return true;
2336
2337 if (!Initializing) {
2338 unsigned StringIndex = P.createGlobalString(E);
2339 return this->emitGetPtrGlobal(StringIndex, E);
2340 }
2341
2342 // We are initializing an array on the stack.
2343 const ConstantArrayType *CAT =
2344 Ctx.getASTContext().getAsConstantArrayType(E->getType());
2345 assert(CAT && "a string literal that's not a constant array?");
2346
2347 // If the initializer string is too long, a diagnostic has already been
2348 // emitted. Read only the array length from the string literal.
2349 unsigned ArraySize = CAT->getZExtSize();
2350 unsigned N = std::min(ArraySize, E->getLength());
2351 size_t CharWidth = E->getCharByteWidth();
2352
2353 for (unsigned I = 0; I != N; ++I) {
2354 uint32_t CodeUnit = E->getCodeUnit(I);
2355
2356 if (CharWidth == 1) {
2357 this->emitConstSint8(CodeUnit, E);
2358 this->emitInitElemSint8(I, E);
2359 } else if (CharWidth == 2) {
2360 this->emitConstUint16(CodeUnit, E);
2361 this->emitInitElemUint16(I, E);
2362 } else if (CharWidth == 4) {
2363 this->emitConstUint32(CodeUnit, E);
2364 this->emitInitElemUint32(I, E);
2365 } else {
2366 llvm_unreachable("unsupported character width");
2367 }
2368 }
2369
2370 // Fill up the rest of the char array with NUL bytes.
2371 for (unsigned I = N; I != ArraySize; ++I) {
2372 if (CharWidth == 1) {
2373 this->emitConstSint8(0, E);
2374 this->emitInitElemSint8(I, E);
2375 } else if (CharWidth == 2) {
2376 this->emitConstUint16(0, E);
2377 this->emitInitElemUint16(I, E);
2378 } else if (CharWidth == 4) {
2379 this->emitConstUint32(0, E);
2380 this->emitInitElemUint32(I, E);
2381 } else {
2382 llvm_unreachable("unsupported character width");
2383 }
2384 }
2385
2386 return true;
2387}
2388
2389template <class Emitter>
2391 if (DiscardResult)
2392 return true;
2393 return this->emitDummyPtr(E, E);
2394}
2395
2396template <class Emitter>
2398 auto &A = Ctx.getASTContext();
2399 std::string Str;
2400 A.getObjCEncodingForType(E->getEncodedType(), Str);
2401 StringLiteral *SL =
2402 StringLiteral::Create(A, Str, StringLiteralKind::Ordinary,
2403 /*Pascal=*/false, E->getType(), E->getAtLoc());
2404 return this->delegate(SL);
2405}
2406
2407template <class Emitter>
2409 const SYCLUniqueStableNameExpr *E) {
2410 if (DiscardResult)
2411 return true;
2412
2413 assert(!Initializing);
2414
2415 auto &A = Ctx.getASTContext();
2416 std::string ResultStr = E->ComputeName(A);
2417
2418 QualType CharTy = A.CharTy.withConst();
2419 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
2420 QualType ArrayTy = A.getConstantArrayType(CharTy, Size, nullptr,
2421 ArraySizeModifier::Normal, 0);
2422
2423 StringLiteral *SL =
2424 StringLiteral::Create(A, ResultStr, StringLiteralKind::Ordinary,
2425 /*Pascal=*/false, ArrayTy, E->getLocation());
2426
2427 unsigned StringIndex = P.createGlobalString(SL);
2428 return this->emitGetPtrGlobal(StringIndex, E);
2429}
2430
2431template <class Emitter>
2433 if (DiscardResult)
2434 return true;
2435 return this->emitConst(E->getValue(), E);
2436}
2437
2438template <class Emitter>
2440 const CompoundAssignOperator *E) {
2441
2442 const Expr *LHS = E->getLHS();
2443 const Expr *RHS = E->getRHS();
2444 QualType LHSType = LHS->getType();
2445 QualType LHSComputationType = E->getComputationLHSType();
2446 QualType ResultType = E->getComputationResultType();
2447 std::optional<PrimType> LT = classify(LHSComputationType);
2448 std::optional<PrimType> RT = classify(ResultType);
2449
2450 assert(ResultType->isFloatingType());
2451
2452 if (!LT || !RT)
2453 return false;
2454
2455 PrimType LHST = classifyPrim(LHSType);
2456
2457 // C++17 onwards require that we evaluate the RHS first.
2458 // Compute RHS and save it in a temporary variable so we can
2459 // load it again later.
2460 if (!visit(RHS))
2461 return false;
2462
2463 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
2464 if (!this->emitSetLocal(*RT, TempOffset, E))
2465 return false;
2466
2467 // First, visit LHS.
2468 if (!visit(LHS))
2469 return false;
2470 if (!this->emitLoad(LHST, E))
2471 return false;
2472
2473 // If necessary, convert LHS to its computation type.
2474 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
2475 LHSComputationType, E))
2476 return false;
2477
2478 // Now load RHS.
2479 if (!this->emitGetLocal(*RT, TempOffset, E))
2480 return false;
2481
2482 switch (E->getOpcode()) {
2483 case BO_AddAssign:
2484 if (!this->emitAddf(getFPOptions(E), E))
2485 return false;
2486 break;
2487 case BO_SubAssign:
2488 if (!this->emitSubf(getFPOptions(E), E))
2489 return false;
2490 break;
2491 case BO_MulAssign:
2492 if (!this->emitMulf(getFPOptions(E), E))
2493 return false;
2494 break;
2495 case BO_DivAssign:
2496 if (!this->emitDivf(getFPOptions(E), E))
2497 return false;
2498 break;
2499 default:
2500 return false;
2501 }
2502
2503 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->getType(), E))
2504 return false;
2505
2506 if (DiscardResult)
2507 return this->emitStorePop(LHST, E);
2508 return this->emitStore(LHST, E);
2509}
2510
2511template <class Emitter>
2513 const CompoundAssignOperator *E) {
2514 BinaryOperatorKind Op = E->getOpcode();
2515 const Expr *LHS = E->getLHS();
2516 const Expr *RHS = E->getRHS();
2517 std::optional<PrimType> LT = classify(LHS->getType());
2518 std::optional<PrimType> RT = classify(RHS->getType());
2519
2520 if (Op != BO_AddAssign && Op != BO_SubAssign)
2521 return false;
2522
2523 if (!LT || !RT)
2524 return false;
2525
2526 if (!visit(LHS))
2527 return false;
2528
2529 if (!this->emitLoad(*LT, LHS))
2530 return false;
2531
2532 if (!visit(RHS))
2533 return false;
2534
2535 if (Op == BO_AddAssign) {
2536 if (!this->emitAddOffset(*RT, E))
2537 return false;
2538 } else {
2539 if (!this->emitSubOffset(*RT, E))
2540 return false;
2541 }
2542
2543 if (DiscardResult)
2544 return this->emitStorePopPtr(E);
2545 return this->emitStorePtr(E);
2546}
2547
2548template <class Emitter>
2550 const CompoundAssignOperator *E) {
2551 if (E->getType()->isVectorType())
2552 return VisitVectorBinOp(E);
2553
2554 const Expr *LHS = E->getLHS();
2555 const Expr *RHS = E->getRHS();
2556 std::optional<PrimType> LHSComputationT =
2557 classify(E->getComputationLHSType());
2558 std::optional<PrimType> LT = classify(LHS->getType());
2559 std::optional<PrimType> RT = classify(RHS->getType());
2560 std::optional<PrimType> ResultT = classify(E->getType());
2561
2562 if (!Ctx.getLangOpts().CPlusPlus14)
2563 return this->visit(RHS) && this->visit(LHS) && this->emitError(E);
2564
2565 if (!LT || !RT || !ResultT || !LHSComputationT)
2566 return false;
2567
2568 // Handle floating point operations separately here, since they
2569 // require special care.
2570
2571 if (ResultT == PT_Float || RT == PT_Float)
2572 return VisitFloatCompoundAssignOperator(E);
2573
2574 if (E->getType()->isPointerType())
2575 return VisitPointerCompoundAssignOperator(E);
2576
2577 assert(!E->getType()->isPointerType() && "Handled above");
2578 assert(!E->getType()->isFloatingType() && "Handled above");
2579
2580 // C++17 onwards require that we evaluate the RHS first.
2581 // Compute RHS and save it in a temporary variable so we can
2582 // load it again later.
2583 // FIXME: Compound assignments are unsequenced in C, so we might
2584 // have to figure out how to reject them.
2585 if (!visit(RHS))
2586 return false;
2587
2588 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
2589
2590 if (!this->emitSetLocal(*RT, TempOffset, E))
2591 return false;
2592
2593 // Get LHS pointer, load its value and cast it to the
2594 // computation type if necessary.
2595 if (!visit(LHS))
2596 return false;
2597 if (!this->emitLoad(*LT, E))
2598 return false;
2599 if (LT != LHSComputationT) {
2600 if (!this->emitCast(*LT, *LHSComputationT, E))
2601 return false;
2602 }
2603
2604 // Get the RHS value on the stack.
2605 if (!this->emitGetLocal(*RT, TempOffset, E))
2606 return false;
2607
2608 // Perform operation.
2609 switch (E->getOpcode()) {
2610 case BO_AddAssign:
2611 if (!this->emitAdd(*LHSComputationT, E))
2612 return false;
2613 break;
2614 case BO_SubAssign:
2615 if (!this->emitSub(*LHSComputationT, E))
2616 return false;
2617 break;
2618 case BO_MulAssign:
2619 if (!this->emitMul(*LHSComputationT, E))
2620 return false;
2621 break;
2622 case BO_DivAssign:
2623 if (!this->emitDiv(*LHSComputationT, E))
2624 return false;
2625 break;
2626 case BO_RemAssign:
2627 if (!this->emitRem(*LHSComputationT, E))
2628 return false;
2629 break;
2630 case BO_ShlAssign:
2631 if (!this->emitShl(*LHSComputationT, *RT, E))
2632 return false;
2633 break;
2634 case BO_ShrAssign:
2635 if (!this->emitShr(*LHSComputationT, *RT, E))
2636 return false;
2637 break;
2638 case BO_AndAssign:
2639 if (!this->emitBitAnd(*LHSComputationT, E))
2640 return false;
2641 break;
2642 case BO_XorAssign:
2643 if (!this->emitBitXor(*LHSComputationT, E))
2644 return false;
2645 break;
2646 case BO_OrAssign:
2647 if (!this->emitBitOr(*LHSComputationT, E))
2648 return false;
2649 break;
2650 default:
2651 llvm_unreachable("Unimplemented compound assign operator");
2652 }
2653
2654 // And now cast from LHSComputationT to ResultT.
2655 if (ResultT != LHSComputationT) {
2656 if (!this->emitCast(*LHSComputationT, *ResultT, E))
2657 return false;
2658 }
2659
2660 // And store the result in LHS.
2661 if (DiscardResult) {
2662 if (LHS->refersToBitField())
2663 return this->emitStoreBitFieldPop(*ResultT, E);
2664 return this->emitStorePop(*ResultT, E);
2665 }
2666 if (LHS->refersToBitField())
2667 return this->emitStoreBitField(*ResultT, E);
2668 return this->emitStore(*ResultT, E);
2669}
2670
2671template <class Emitter>
2673 LocalScope<Emitter> ES(this);
2674 const Expr *SubExpr = E->getSubExpr();
2675
2676 return this->delegate(SubExpr) && ES.destroyLocals(E);
2677}
2678
2679template <class Emitter>
2681 const MaterializeTemporaryExpr *E) {
2682 const Expr *SubExpr = E->getSubExpr();
2683
2684 if (Initializing) {
2685 // We already have a value, just initialize that.
2686 return this->delegate(SubExpr);
2687 }
2688 // If we don't end up using the materialized temporary anyway, don't
2689 // bother creating it.
2690 if (DiscardResult)
2691 return this->discard(SubExpr);
2692
2693 // When we're initializing a global variable *or* the storage duration of
2694 // the temporary is explicitly static, create a global variable.
2695 std::optional<PrimType> SubExprT = classify(SubExpr);
2696 bool IsStatic = E->getStorageDuration() == SD_Static;
2697 if (IsStatic) {
2698 std::optional<unsigned> GlobalIndex = P.createGlobal(E);
2699 if (!GlobalIndex)
2700 return false;
2701
2702 const LifetimeExtendedTemporaryDecl *TempDecl =
2703 E->getLifetimeExtendedTemporaryDecl();
2704 if (IsStatic)
2705 assert(TempDecl);
2706
2707 if (SubExprT) {
2708 if (!this->visit(SubExpr))
2709 return false;
2710 if (IsStatic) {
2711 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl, E))
2712 return false;
2713 } else {
2714 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex, E))
2715 return false;
2716 }
2717 return this->emitGetPtrGlobal(*GlobalIndex, E);
2718 }
2719
2720 if (!this->checkLiteralType(SubExpr))
2721 return false;
2722 // Non-primitive values.
2723 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2724 return false;
2725 if (!this->visitInitializer(SubExpr))
2726 return false;
2727 if (IsStatic)
2728 return this->emitInitGlobalTempComp(TempDecl, E);
2729 return true;
2730 }
2731
2732 // For everyhing else, use local variables.
2733 if (SubExprT) {
2734 unsigned LocalIndex = allocateLocalPrimitive(E, *SubExprT, /*IsConst=*/true,
2735 /*IsExtended=*/true);
2736 if (!this->visit(SubExpr))
2737 return false;
2738 if (!this->emitSetLocal(*SubExprT, LocalIndex, E))
2739 return false;
2740 return this->emitGetPtrLocal(LocalIndex, E);
2741 } else {
2742
2743 if (!this->checkLiteralType(SubExpr))
2744 return false;
2745
2746 const Expr *Inner = E->getSubExpr()->skipRValueSubobjectAdjustments();
2747 if (std::optional<unsigned> LocalIndex =
2748 allocateLocal(E, Inner->getType(), E->getExtendingDecl())) {
2749 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
2750 if (!this->emitGetPtrLocal(*LocalIndex, E))
2751 return false;
2752 return this->visitInitializer(SubExpr) && this->emitFinishInit(E);
2753 }
2754 }
2755 return false;
2756}
2757
2758template <class Emitter>
2760 const CXXBindTemporaryExpr *E) {
2761 return this->delegate(E->getSubExpr());
2762}
2763
2764template <class Emitter>
2766 const Expr *Init = E->getInitializer();
2767 if (DiscardResult)
2768 return this->discard(Init);
2769
2770 if (Initializing) {
2771 // We already have a value, just initialize that.
2772 return this->visitInitializer(Init) && this->emitFinishInit(E);
2773 }
2774
2775 std::optional<PrimType> T = classify(E->getType());
2776 if (E->isFileScope()) {
2777 // Avoid creating a variable if this is a primitive RValue anyway.
2778 if (T && !E->isLValue())
2779 return this->delegate(Init);
2780
2781 if (std::optional<unsigned> GlobalIndex = P.createGlobal(E)) {
2782 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2783 return false;
2784
2785 if (T) {
2786 if (!this->visit(Init))
2787 return false;
2788 return this->emitInitGlobal(*T, *GlobalIndex, E);
2789 }
2790
2791 return this->visitInitializer(Init) && this->emitFinishInit(E);
2792 }
2793
2794 return false;
2795 }
2796
2797 // Otherwise, use a local variable.
2798 if (T && !E->isLValue()) {
2799 // For primitive types, we just visit the initializer.
2800 return this->delegate(Init);
2801 } else {
2802 unsigned LocalIndex;
2803
2804 if (T)
2805 LocalIndex = this->allocateLocalPrimitive(Init, *T, false, false);
2806 else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(Init))
2807 LocalIndex = *MaybeIndex;
2808 else
2809 return false;
2810
2811 if (!this->emitGetPtrLocal(LocalIndex, E))
2812 return false;
2813
2814 if (T) {
2815 if (!this->visit(Init)) {
2816 return false;
2817 }
2818 return this->emitInit(*T, E);
2819 } else {
2820 if (!this->visitInitializer(Init) || !this->emitFinishInit(E))
2821 return false;
2822 }
2823 return true;
2824 }
2825
2826 return false;
2827}
2828
2829template <class Emitter>
2831 if (DiscardResult)
2832 return true;
2833 if (E->getType()->isBooleanType())
2834 return this->emitConstBool(E->getValue(), E);
2835 return this->emitConst(E->getValue(), E);
2836}
2837
2838template <class Emitter>
2840 if (DiscardResult)
2841 return true;
2842 return this->emitConst(E->getValue(), E);
2843}
2844
2845template <class Emitter>
2847 if (DiscardResult)
2848 return true;
2849
2850 assert(Initializing);
2851 const Record *R = P.getOrCreateRecord(E->getLambdaClass());
2852
2853 auto *CaptureInitIt = E->capture_init_begin();
2854 // Initialize all fields (which represent lambda captures) of the
2855 // record with their initializers.
2856 for (const Record::Field &F : R->fields()) {
2857 const Expr *Init = *CaptureInitIt;
2858 ++CaptureInitIt;
2859
2860 if (!Init)
2861 continue;
2862
2863 if (std::optional<PrimType> T = classify(Init)) {
2864 if (!this->visit(Init))
2865 return false;
2866
2867 if (!this->emitInitField(*T, F.Offset, E))
2868 return false;
2869 } else {
2870 if (!this->emitGetPtrField(F.Offset, E))
2871 return false;
2872
2873 if (!this->visitInitializer(Init))
2874 return false;
2875
2876 if (!this->emitPopPtr(E))
2877 return false;
2878 }
2879 }
2880
2881 return true;
2882}
2883
2884template <class Emitter>
2886 if (DiscardResult)
2887 return true;
2888
2889 if (!Initializing) {
2890 unsigned StringIndex = P.createGlobalString(E->getFunctionName(), E);
2891 return this->emitGetPtrGlobal(StringIndex, E);
2892 }
2893
2894 return this->delegate(E->getFunctionName());
2895}
2896
2897template <class Emitter>
2899 if (E->getSubExpr() && !this->discard(E->getSubExpr()))
2900 return false;
2901
2902 return this->emitInvalid(E);
2903}
2904
2905template <class Emitter>
2907 const CXXReinterpretCastExpr *E) {
2908 const Expr *SubExpr = E->getSubExpr();
2909
2910 std::optional<PrimType> FromT = classify(SubExpr);
2911 std::optional<PrimType> ToT = classify(E);
2912
2913 if (!FromT || !ToT)
2914 return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, E);
2915
2916 if (FromT == PT_Ptr || ToT == PT_Ptr) {
2917 // Both types could be PT_Ptr because their expressions are glvalues.
2918 std::optional<PrimType> PointeeFromT;
2919 if (SubExpr->getType()->isPointerOrReferenceType())
2920 PointeeFromT = classify(SubExpr->getType()->getPointeeType());
2921 else
2922 PointeeFromT = classify(SubExpr->getType());
2923
2924 std::optional<PrimType> PointeeToT;
2926 PointeeToT = classify(E->getType()->getPointeeType());
2927 else
2928 PointeeToT = classify(E->getType());
2929
2930 bool Fatal = true;
2931 if (PointeeToT && PointeeFromT) {
2932 if (isIntegralType(*PointeeFromT) && isIntegralType(*PointeeToT))
2933 Fatal = false;
2934 }
2935
2936 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal, E))
2937 return false;
2938
2939 if (E->getCastKind() == CK_LValueBitCast)
2940 return this->delegate(SubExpr);
2941 return this->VisitCastExpr(E);
2942 }
2943
2944 // Try to actually do the cast.
2945 bool Fatal = (ToT != FromT);
2946 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal, E))
2947 return false;
2948
2949 return this->VisitCastExpr(E);
2950}
2951
2952template <class Emitter>
2954 assert(E->getType()->isBooleanType());
2955
2956 if (DiscardResult)
2957 return true;
2958 return this->emitConstBool(E->getValue(), E);
2959}
2960
2961template <class Emitter>
2963 QualType T = E->getType();
2964 assert(!classify(T));
2965
2966 if (T->isRecordType()) {
2967 const CXXConstructorDecl *Ctor = E->getConstructor();
2968
2969 // Trivial copy/move constructor. Avoid copy.
2970 if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&
2971 Ctor->isTrivial() &&
2972 E->getArg(0)->isTemporaryObject(Ctx.getASTContext(),
2974 return this->visitInitializer(E->getArg(0));
2975
2976 // If we're discarding a construct expression, we still need
2977 // to allocate a variable and call the constructor and destructor.
2978 if (DiscardResult) {
2979 if (Ctor->isTrivial())
2980 return true;
2981 assert(!Initializing);
2982 std::optional<unsigned> LocalIndex = allocateLocal(E);
2983
2984 if (!LocalIndex)
2985 return false;
2986
2987 if (!this->emitGetPtrLocal(*LocalIndex, E))
2988 return false;
2989 }
2990
2991 // Zero initialization.
2992 if (E->requiresZeroInitialization()) {
2993 const Record *R = getRecord(E->getType());
2994
2995 if (!this->visitZeroRecordInitializer(R, E))
2996 return false;
2997
2998 // If the constructor is trivial anyway, we're done.
2999 if (Ctor->isTrivial())
3000 return true;
3001 }
3002
3003 const Function *Func = getFunction(Ctor);
3004
3005 if (!Func)
3006 return false;
3007
3008 assert(Func->hasThisPointer());
3009 assert(!Func->hasRVO());
3010
3011 // The This pointer is already on the stack because this is an initializer,
3012 // but we need to dup() so the call() below has its own copy.
3013 if (!this->emitDupPtr(E))
3014 return false;
3015
3016 // Constructor arguments.
3017 for (const auto *Arg : E->arguments()) {
3018 if (!this->visit(Arg))
3019 return false;
3020 }
3021
3022 if (Func->isVariadic()) {
3023 uint32_t VarArgSize = 0;
3024 unsigned NumParams = Func->getNumWrittenParams();
3025 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I) {
3026 VarArgSize +=
3027 align(primSize(classify(E->getArg(I)->getType()).value_or(PT_Ptr)));
3028 }
3029 if (!this->emitCallVar(Func, VarArgSize, E))
3030 return false;
3031 } else {
3032 if (!this->emitCall(Func, 0, E)) {
3033 // When discarding, we don't need the result anyway, so clean up
3034 // the instance dup we did earlier in case surrounding code wants
3035 // to keep evaluating.
3036 if (DiscardResult)
3037 (void)this->emitPopPtr(E);
3038 return false;
3039 }
3040 }
3041
3042 if (DiscardResult)
3043 return this->emitPopPtr(E);
3044 return this->emitFinishInit(E);
3045 }
3046
3047 if (T->isArrayType()) {
3048 const ConstantArrayType *CAT =
3049 Ctx.getASTContext().getAsConstantArrayType(E->getType());
3050 if (!CAT)
3051 return false;
3052
3053 size_t NumElems = CAT->getZExtSize();
3054 const Function *Func = getFunction(E->getConstructor());
3055 if (!Func || !Func->isConstexpr())
3056 return false;
3057
3058 // FIXME(perf): We're calling the constructor once per array element here,
3059 // in the old intepreter we had a special-case for trivial constructors.
3060 for (size_t I = 0; I != NumElems; ++I) {
3061 if (!this->emitConstUint64(I, E))
3062 return false;
3063 if (!this->emitArrayElemPtrUint64(E))
3064 return false;
3065
3066 // Constructor arguments.
3067 for (const auto *Arg : E->arguments()) {
3068 if (!this->visit(Arg))
3069 return false;
3070 }
3071
3072 if (!this->emitCall(Func, 0, E))
3073 return false;
3074 }
3075 return true;
3076 }
3077
3078 return false;
3079}
3080
3081template <class Emitter>
3083 if (DiscardResult)
3084 return true;
3085
3086 const APValue Val =
3087 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
3088
3089 // Things like __builtin_LINE().
3090 if (E->getType()->isIntegerType()) {
3091 assert(Val.isInt());
3092 const APSInt &I = Val.getInt();
3093 return this->emitConst(I, E);
3094 }
3095 // Otherwise, the APValue is an LValue, with only one element.
3096 // Theoretically, we don't need the APValue at all of course.
3097 assert(E->getType()->isPointerType());
3098 assert(Val.isLValue());
3099 const APValue::LValueBase &Base = Val.getLValueBase();
3100 if (const Expr *LValueExpr = Base.dyn_cast<const Expr *>())
3101 return this->visit(LValueExpr);
3102
3103 // Otherwise, we have a decl (which is the case for
3104 // __builtin_source_location).
3105 assert(Base.is<const ValueDecl *>());
3106 assert(Val.getLValuePath().size() == 0);
3107 const auto *BaseDecl = Base.dyn_cast<const ValueDecl *>();
3108 assert(BaseDecl);
3109
3110 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
3111
3112 std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(UGCD);
3113 if (!GlobalIndex)
3114 return false;
3115
3116 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3117 return false;
3118
3119 const Record *R = getRecord(E->getType());
3120 const APValue &V = UGCD->getValue();
3121 for (unsigned I = 0, N = R->getNumFields(); I != N; ++I) {
3122 const Record::Field *F = R->getField(I);
3123 const APValue &FieldValue = V.getStructField(I);
3124
3125 PrimType FieldT = classifyPrim(F->Decl->getType());
3126
3127 if (!this->visitAPValue(FieldValue, FieldT, E))
3128 return false;
3129 if (!this->emitInitField(FieldT, F->Offset, E))
3130 return false;
3131 }
3132
3133 // Leave the pointer to the global on the stack.
3134 return true;
3135}
3136
3137template <class Emitter>
3139 unsigned N = E->getNumComponents();
3140 if (N == 0)
3141 return false;
3142
3143 for (unsigned I = 0; I != N; ++I) {
3144 const OffsetOfNode &Node = E->getComponent(I);
3145 if (Node.getKind() == OffsetOfNode::Array) {
3146 const Expr *ArrayIndexExpr = E->getIndexExpr(Node.getArrayExprIndex());
3147 PrimType IndexT = classifyPrim(ArrayIndexExpr->getType());
3148
3149 if (DiscardResult) {
3150 if (!this->discard(ArrayIndexExpr))
3151 return false;
3152 continue;
3153 }
3154
3155 if (!this->visit(ArrayIndexExpr))
3156 return false;
3157 // Cast to Sint64.
3158 if (IndexT != PT_Sint64) {
3159 if (!this->emitCast(IndexT, PT_Sint64, E))
3160 return false;
3161 }
3162 }
3163 }
3164
3165 if (DiscardResult)
3166 return true;
3167
3168 PrimType T = classifyPrim(E->getType());
3169 return this->emitOffsetOf(T, E, E);
3170}
3171
3172template <class Emitter>
3174 const CXXScalarValueInitExpr *E) {
3175 QualType Ty = E->getType();
3176
3177 if (DiscardResult || Ty->isVoidType())
3178 return true;
3179
3180 if (std::optional<PrimType> T = classify(Ty))
3181 return this->visitZeroInitializer(*T, Ty, E);
3182
3183 if (const auto *CT = Ty->getAs<ComplexType>()) {
3184 if (!Initializing) {
3185 std::optional<unsigned> LocalIndex = allocateLocal(E);
3186 if (!LocalIndex)
3187 return false;
3188 if (!this->emitGetPtrLocal(*LocalIndex, E))
3189 return false;
3190 }
3191
3192 // Initialize both fields to 0.
3193 QualType ElemQT = CT->getElementType();
3194 PrimType ElemT = classifyPrim(ElemQT);
3195
3196 for (unsigned I = 0; I != 2; ++I) {
3197 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
3198 return false;
3199 if (!this->emitInitElem(ElemT, I, E))
3200 return false;
3201 }
3202 return true;
3203 }
3204
3205 if (const auto *VT = Ty->getAs<VectorType>()) {
3206 // FIXME: Code duplication with the _Complex case above.
3207 if (!Initializing) {
3208 std::optional<unsigned> LocalIndex = allocateLocal(E);
3209 if (!LocalIndex)
3210 return false;
3211 if (!this->emitGetPtrLocal(*LocalIndex, E))
3212 return false;
3213 }
3214
3215 // Initialize all fields to 0.
3216 QualType ElemQT = VT->getElementType();
3217 PrimType ElemT = classifyPrim(ElemQT);
3218
3219 for (unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
3220 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
3221 return false;
3222 if (!this->emitInitElem(ElemT, I, E))
3223 return false;
3224 }
3225 return true;
3226 }
3227
3228 return false;
3229}
3230
3231template <class Emitter>
3233 return this->emitConst(E->getPackLength(), E);
3234}
3235
3236template <class Emitter>
3238 const GenericSelectionExpr *E) {
3239 return this->delegate(E->getResultExpr());
3240}
3241
3242template <class Emitter>
3244 return this->delegate(E->getChosenSubExpr());
3245}
3246
3247template <class Emitter>
3249 if (DiscardResult)
3250 return true;
3251
3252 return this->emitConst(E->getValue(), E);
3253}
3254
3255template <class Emitter>
3257 const CXXInheritedCtorInitExpr *E) {
3258 const CXXConstructorDecl *Ctor = E->getConstructor();
3259 assert(!Ctor->isTrivial() &&
3260 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
3261 const Function *F = this->getFunction(Ctor);
3262 assert(F);
3263 assert(!F->hasRVO());
3264 assert(F->hasThisPointer());
3265
3266 if (!this->emitDupPtr(SourceInfo{}))
3267 return false;
3268
3269 // Forward all arguments of the current function (which should be a
3270 // constructor itself) to the inherited ctor.
3271 // This is necessary because the calling code has pushed the pointer
3272 // of the correct base for us already, but the arguments need
3273 // to come after.
3274 unsigned Offset = align(primSize(PT_Ptr)); // instance pointer.
3275 for (const ParmVarDecl *PD : Ctor->parameters()) {
3276 PrimType PT = this->classify(PD->getType()).value_or(PT_Ptr);
3277
3278 if (!this->emitGetParam(PT, Offset, E))
3279 return false;
3280 Offset += align(primSize(PT));
3281 }
3282
3283 return this->emitCall(F, 0, E);
3284}
3285
3286template <class Emitter>
3288 assert(classifyPrim(E->getType()) == PT_Ptr);
3289 const Expr *Init = E->getInitializer();
3290 QualType ElementType = E->getAllocatedType();
3291 std::optional<PrimType> ElemT = classify(ElementType);
3292 unsigned PlacementArgs = E->getNumPlacementArgs();
3293 const FunctionDecl *OperatorNew = E->getOperatorNew();
3294 const Expr *PlacementDest = nullptr;
3295 bool IsNoThrow = false;
3296
3297 if (PlacementArgs != 0) {
3298 // FIXME: There is no restriction on this, but it's not clear that any
3299 // other form makes any sense. We get here for cases such as:
3300 //
3301 // new (std::align_val_t{N}) X(int)
3302 //
3303 // (which should presumably be valid only if N is a multiple of
3304 // alignof(int), and in any case can't be deallocated unless N is
3305 // alignof(X) and X has new-extended alignment).
3306 if (PlacementArgs == 1) {
3307 const Expr *Arg1 = E->getPlacementArg(0);
3308 if (Arg1->getType()->isNothrowT()) {
3309 if (!this->discard(Arg1))
3310 return false;
3311 IsNoThrow = true;
3312 } else {
3313 // Invalid unless we have C++26 or are in a std:: function.
3314 if (!this->emitInvalidNewDeleteExpr(E, E))
3315 return false;
3316
3317 // If we have a placement-new destination, we'll later use that instead
3318 // of allocating.
3319 if (OperatorNew->isReservedGlobalPlacementOperator())
3320 PlacementDest = Arg1;
3321 }
3322 } else {
3323 // Always invalid.
3324 return this->emitInvalid(E);
3325 }
3326 } else if (!OperatorNew->isReplaceableGlobalAllocationFunction())
3327 return this->emitInvalidNewDeleteExpr(E, E);
3328
3329 const Descriptor *Desc;
3330 if (!PlacementDest) {
3331 if (ElemT) {
3332 if (E->isArray())
3333 Desc = nullptr; // We're not going to use it in this case.
3334 else
3335 Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,
3336 /*IsConst=*/false, /*IsTemporary=*/false,
3337 /*IsMutable=*/false);
3338 } else {
3339 Desc = P.createDescriptor(
3340 E, ElementType.getTypePtr(),
3341 E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
3342 /*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);
3343 }
3344 }
3345
3346 if (E->isArray()) {
3347 std::optional<const Expr *> ArraySizeExpr = E->getArraySize();
3348 if (!ArraySizeExpr)
3349 return false;
3350
3351 const Expr *Stripped = *ArraySizeExpr;
3352 for (; auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
3353 Stripped = ICE->getSubExpr())
3354 if (ICE->getCastKind() != CK_NoOp &&
3355 ICE->getCastKind() != CK_IntegralCast)
3356 break;
3357
3358 PrimType SizeT = classifyPrim(Stripped->getType());
3359
3360 if (PlacementDest) {
3361 if (!this->visit(PlacementDest))
3362 return false;
3363 if (!this->visit(Stripped))
3364 return false;
3365 if (!this->emitCheckNewTypeMismatchArray(SizeT, E, E))
3366 return false;
3367 } else {
3368 if (!this->visit(Stripped))
3369 return false;
3370
3371 if (ElemT) {
3372 // N primitive elements.
3373 if (!this->emitAllocN(SizeT, *ElemT, E, IsNoThrow, E))
3374 return false;
3375 } else {
3376 // N Composite elements.
3377 if (!this->emitAllocCN(SizeT, Desc, IsNoThrow, E))
3378 return false;
3379 }
3380 }
3381
3382 if (Init && !this->visitInitializer(Init))
3383 return false;
3384
3385 } else {
3386 if (PlacementDest) {
3387 if (!this->visit(PlacementDest))
3388 return false;
3389 if (!this->emitCheckNewTypeMismatch(E, E))
3390 return false;
3391 } else {
3392 // Allocate just one element.
3393 if (!this->emitAlloc(Desc, E))
3394 return false;
3395 }
3396
3397 if (Init) {
3398 if (ElemT) {
3399 if (!this->visit(Init))
3400 return false;
3401
3402 if (!this->emitInit(*ElemT, E))
3403 return false;
3404 } else {
3405 // Composite.
3406 if (!this->visitInitializer(Init))
3407 return false;
3408 }
3409 }
3410 }
3411
3412 if (DiscardResult)
3413 return this->emitPopPtr(E);
3414
3415 return true;
3416}
3417
3418template <class Emitter>
3420 const Expr *Arg = E->getArgument();
3421
3422 const FunctionDecl *OperatorDelete = E->getOperatorDelete();
3423
3424 if (!OperatorDelete->isReplaceableGlobalAllocationFunction())
3425 return this->emitInvalidNewDeleteExpr(E, E);
3426
3427 // Arg must be an lvalue.
3428 if (!this->visit(Arg))
3429 return false;
3430
3431 return this->emitFree(E->isArrayForm(), E->isGlobalDelete(), E);
3432}
3433
3434template <class Emitter>
3436 if (DiscardResult)
3437 return true;
3438
3439 const Function *Func = nullptr;
3440 if (auto F = Compiler<ByteCodeEmitter>(Ctx, P).compileObjCBlock(E))
3441 Func = F;
3442
3443 if (!Func)
3444 return false;
3445 return this->emitGetFnPtr(Func, E);
3446}
3447
3448template <class Emitter>
3450 const Type *TypeInfoType = E->getType().getTypePtr();
3451
3452 if (!E->isPotentiallyEvaluated()) {
3453 if (DiscardResult)
3454 return true;
3455
3456 if (E->isTypeOperand())
3457 return this->emitGetTypeid(
3458 E->getTypeOperand(Ctx.getASTContext()).getTypePtr(), TypeInfoType, E);
3459 return this->emitGetTypeid(E->getExprOperand()->getType().getTypePtr(),
3460 TypeInfoType, E);
3461 }
3462
3463 // Otherwise, we need to evaluate the expression operand.
3464 assert(E->getExprOperand());
3465 assert(E->getExprOperand()->isLValue());
3466
3467 if (!Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(E))
3468 return false;
3469
3470 if (!this->visit(E->getExprOperand()))
3471 return false;
3472
3473 if (!this->emitGetTypeidPtr(TypeInfoType, E))
3474 return false;
3475 if (DiscardResult)
3476 return this->emitPopPtr(E);
3477 return true;
3478}
3479
3480template <class Emitter>
3482 assert(Ctx.getLangOpts().CPlusPlus);
3483 return this->emitConstBool(E->getValue(), E);
3484}
3485
3486template <class Emitter>
3488 if (DiscardResult)
3489 return true;
3490 assert(!Initializing);
3491
3492 const MSGuidDecl *GuidDecl = E->getGuidDecl();
3493 const RecordDecl *RD = GuidDecl->getType()->getAsRecordDecl();
3494 assert(RD);
3495 // If the definiton of the result type is incomplete, just return a dummy.
3496 // If (and when) that is read from, we will fail, but not now.
3497 if (!RD->isCompleteDefinition())
3498 return this->emitDummyPtr(GuidDecl, E);
3499
3500 std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(GuidDecl);
3501 if (!GlobalIndex)
3502 return false;
3503 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3504 return false;
3505
3506 assert(this->getRecord(E->getType()));
3507
3508 const APValue &V = GuidDecl->getAsAPValue();
3509 if (V.getKind() == APValue::None)
3510 return true;
3511
3512 assert(V.isStruct());
3513 assert(V.getStructNumBases() == 0);
3514 if (!this->visitAPValueInitializer(V, E))
3515 return false;
3516
3517 return this->emitFinishInit(E);
3518}
3519
3520template <class Emitter>
3522 assert(classifyPrim(E->getType()) == PT_Bool);
3523 if (DiscardResult)
3524 return true;
3525 return this->emitConstBool(E->isSatisfied(), E);
3526}
3527
3528template <class Emitter>
3531 assert(classifyPrim(E->getType()) == PT_Bool);
3532 if (DiscardResult)
3533 return true;
3534 return this->emitConstBool(E->isSatisfied(), E);
3535}
3536
3537template <class Emitter>
3540 return this->delegate(E->getSemanticForm());
3541}
3542
3543template <class Emitter>
3545
3546 for (const Expr *SemE : E->semantics()) {
3547 if (auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
3548 if (SemE == E->getResultExpr())
3549 return false;
3550
3551 if (OVE->isUnique())
3552 continue;
3553
3554 if (!this->discard(OVE))
3555 return false;
3556 } else if (SemE == E->getResultExpr()) {
3557 if (!this->delegate(SemE))
3558 return false;
3559 } else {
3560 if (!this->discard(SemE))
3561 return false;
3562 }
3563 }
3564 return true;
3565}
3566
3567template <class Emitter>
3569 return this->delegate(E->getSelectedExpr());
3570}
3571
3572template <class Emitter>
3574 return this->emitError(E);
3575}
3576
3577template <class Emitter>
3579 assert(E->getType()->isVoidPointerType());
3580
3581 unsigned Offset = allocateLocalPrimitive(
3582 E->getLabel(), PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false);
3583
3584 return this->emitGetLocal(PT_Ptr, Offset, E);
3585}
3586
3587template <class Emitter>
3589 assert(Initializing);
3590 const auto *VT = E->getType()->castAs<VectorType>();
3591 QualType ElemType = VT->getElementType();
3592 PrimType ElemT = classifyPrim(ElemType);
3593 const Expr *Src = E->getSrcExpr();
3594 QualType SrcType = Src->getType();
3595 PrimType SrcElemT = classifyVectorElementType(SrcType);
3596
3597 unsigned SrcOffset = this->allocateLocalPrimitive(Src, PT_Ptr, true, false);
3598 if (!this->visit(Src))
3599 return false;
3600 if (!this->emitSetLocal(PT_Ptr, SrcOffset, E))
3601 return false;
3602
3603 for (unsigned I = 0; I != VT->getNumElements(); ++I) {
3604 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
3605 return false;
3606 if (!this->emitArrayElemPop(SrcElemT, I, E))
3607 return false;
3608
3609 // Cast to the desired result element type.
3610 if (SrcElemT != ElemT) {
3611 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
3612 return false;
3613 } else if (ElemType->isFloatingType() && SrcType != ElemType) {
3614 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
3615 if (!this->emitCastFP(TargetSemantics, getRoundingMode(E), E))
3616 return false;
3617 }
3618 if (!this->emitInitElem(ElemT, I, E))
3619 return false;
3620 }
3621
3622 return true;
3623}
3624
3625template <class Emitter>
3627 assert(Initializing);
3628 assert(E->getNumSubExprs() > 2);
3629
3630 const Expr *Vecs[] = {E->getExpr(0), E->getExpr(1)};
3631 const VectorType *VT = Vecs[0]->getType()->castAs<VectorType>();
3632 PrimType ElemT = classifyPrim(VT->getElementType());
3633 unsigned NumInputElems = VT->getNumElements();
3634 unsigned NumOutputElems = E->getNumSubExprs() - 2;
3635 assert(NumOutputElems > 0);
3636
3637 // Save both input vectors to a local variable.
3638 unsigned VectorOffsets[2];
3639 for (unsigned I = 0; I != 2; ++I) {
3640 VectorOffsets[I] = this->allocateLocalPrimitive(
3641 Vecs[I], PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false);
3642 if (!this->visit(Vecs[I]))
3643 return false;
3644 if (!this->emitSetLocal(PT_Ptr, VectorOffsets[I], E))
3645 return false;
3646 }
3647 for (unsigned I = 0; I != NumOutputElems; ++I) {
3648 APSInt ShuffleIndex = E->getShuffleMaskIdx(Ctx.getASTContext(), I);
3649 assert(ShuffleIndex >= -1);
3650 if (ShuffleIndex == -1)
3651 return this->emitInvalidShuffleVectorIndex(I, E);
3652
3653 assert(ShuffleIndex < (NumInputElems * 2));
3654 if (!this->emitGetLocal(PT_Ptr,
3655 VectorOffsets[ShuffleIndex >= NumInputElems], E))
3656 return false;
3657 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
3658 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
3659 return false;
3660
3661 if (!this->emitInitElem(ElemT, I, E))
3662 return false;
3663 }
3664
3665 return true;
3666}
3667
3668template <class Emitter>
3670 const ExtVectorElementExpr *E) {
3671 const Expr *Base = E->getBase();
3672 assert(
3673 Base->getType()->isVectorType() ||
3674 Base->getType()->getAs<PointerType>()->getPointeeType()->isVectorType());
3675
3677 E->getEncodedElementAccess(Indices);
3678
3679 if (Indices.size() == 1) {
3680 if (!this->visit(Base))
3681 return false;
3682
3683 if (E->isGLValue()) {
3684 if (!this->emitConstUint32(Indices[0], E))
3685 return false;
3686 return this->emitArrayElemPtrPop(PT_Uint32, E);
3687 }
3688 // Else, also load the value.
3689 return this->emitArrayElemPop(classifyPrim(E->getType()), Indices[0], E);
3690 }
3691
3692 // Create a local variable for the base.
3693 unsigned BaseOffset = allocateLocalPrimitive(Base, PT_Ptr, /*IsConst=*/true,
3694 /*IsExtended=*/false);
3695 if (!this->visit(Base))
3696 return false;
3697 if (!this->emitSetLocal(PT_Ptr, BaseOffset, E))
3698 return false;
3699
3700 // Now the vector variable for the return value.
3701 if (!Initializing) {
3702 std::optional<unsigned> ResultIndex;
3703 ResultIndex = allocateLocal(E);
3704 if (!ResultIndex)
3705 return false;
3706 if (!this->emitGetPtrLocal(*ResultIndex, E))
3707 return false;
3708 }
3709
3710 assert(Indices.size() == E->getType()->getAs<VectorType>()->getNumElements());
3711
3712 PrimType ElemT =
3713 classifyPrim(E->getType()->getAs<VectorType>()->getElementType());
3714 uint32_t DstIndex = 0;
3715 for (uint32_t I : Indices) {
3716 if (!this->emitGetLocal(PT_Ptr, BaseOffset, E))
3717 return false;
3718 if (!this->emitArrayElemPop(ElemT, I, E))
3719 return false;
3720 if (!this->emitInitElem(ElemT, DstIndex, E))
3721 return false;
3722 ++DstIndex;
3723 }
3724
3725 // Leave the result pointer on the stack.
3726 assert(!DiscardResult);
3727 return true;
3728}
3729
3730template <class Emitter>
3732 const Expr *SubExpr = E->getSubExpr();
3733 if (!E->isExpressibleAsConstantInitializer())
3734 return this->discard(SubExpr) && this->emitInvalid(E);
3735
3736 if (DiscardResult)
3737 return true;
3738
3739 assert(classifyPrim(E) == PT_Ptr);
3740 return this->emitDummyPtr(E, E);
3741}
3742
3743template <class Emitter>
3746 const Expr *SubExpr = E->getSubExpr();
3748 Ctx.getASTContext().getAsConstantArrayType(SubExpr->getType());
3749 const Record *R = getRecord(E->getType());
3750 assert(Initializing);
3751 assert(SubExpr->isGLValue());
3752
3753 if (!this->visit(SubExpr))
3754 return false;
3755 if (!this->emitConstUint8(0, E))
3756 return false;
3757 if (!this->emitArrayElemPtrPopUint8(E))
3758 return false;
3759 if (!this->emitInitFieldPtr(R->getField(0u)->Offset, E))
3760 return false;
3761
3762 PrimType SecondFieldT = classifyPrim(R->getField(1u)->Decl->getType());
3763 if (isIntegralType(SecondFieldT)) {
3764 if (!this->emitConst(static_cast<APSInt>(ArrayType->getSize()),
3765 SecondFieldT, E))
3766 return false;
3767 return this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E);
3768 }
3769 assert(SecondFieldT == PT_Ptr);
3770
3771 if (!this->emitGetFieldPtr(R->getField(0u)->Offset, E))
3772 return false;
3773 if (!this->emitExpandPtr(E))
3774 return false;
3775 if (!this->emitConst(static_cast<APSInt>(ArrayType->getSize()), PT_Uint64, E))
3776 return false;
3777 if (!this->emitArrayElemPtrPop(PT_Uint64, E))
3778 return false;
3779 return this->emitInitFieldPtr(R->getField(1u)->Offset, E);
3780}
3781
3782template <class Emitter>
3784 BlockScope<Emitter> BS(this);
3785 StmtExprScope<Emitter> SS(this);
3786
3787 const CompoundStmt *CS = E->getSubStmt();
3788 const Stmt *Result = CS->getStmtExprResult();
3789 for (const Stmt *S : CS->body()) {
3790 if (S != Result) {
3791 if (!this->visitStmt(S))
3792 return false;
3793 continue;
3794 }
3795
3796 assert(S == Result);
3797 if (const Expr *ResultExpr = dyn_cast<Expr>(S))
3798 return this->delegate(ResultExpr);
3799 return this->emitUnsupported(E);
3800 }
3801
3802 return BS.destroyLocals();
3803}
3804
3805template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {
3806 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
3807 /*NewInitializing=*/false);
3808 return this->Visit(E);
3809}
3810
3811template <class Emitter> bool Compiler<Emitter>::delegate(const Expr *E) {
3812 // We're basically doing:
3813 // OptionScope<Emitter> Scope(this, DicardResult, Initializing);
3814 // but that's unnecessary of course.
3815 return this->Visit(E);
3816}
3817
3818template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) {
3819 if (E->getType().isNull())
3820 return false;
3821
3822 if (E->getType()->isVoidType())
3823 return this->discard(E);
3824
3825 // Create local variable to hold the return value.
3826 if (!E->isGLValue() && !E->getType()->isAnyComplexType() &&
3827 !classify(E->getType())) {
3828 std::optional<unsigned> LocalIndex = allocateLocal(E);
3829 if (!LocalIndex)
3830 return false;
3831
3832 if (!this->emitGetPtrLocal(*LocalIndex, E))
3833 return false;
3834 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
3835 return this->visitInitializer(E);
3836 }
3837
3838 // Otherwise,we have a primitive return value, produce the value directly
3839 // and push it on the stack.
3840 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
3841 /*NewInitializing=*/false);
3842 return this->Visit(E);
3843}
3844
3845template <class Emitter>
3847 assert(!classify(E->getType()));
3848
3849 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
3850 /*NewInitializing=*/true);
3851 return this->Visit(E);
3852}
3853
3854template <class Emitter> bool Compiler<Emitter>::visitBool(const Expr *E) {
3855 std::optional<PrimType> T = classify(E->getType());
3856 if (!T) {
3857 // Convert complex values to bool.
3858 if (E->getType()->isAnyComplexType()) {
3859 if (!this->visit(E))
3860 return false;
3861 return this->emitComplexBoolCast(E);
3862 }
3863 return false;
3864 }
3865
3866 if (!this->visit(E))
3867 return false;
3868
3869 if (T == PT_Bool)
3870 return true;
3871
3872 // Convert pointers to bool.
3873 if (T == PT_Ptr || T == PT_FnPtr) {
3874 if (!this->emitNull(*T, 0, nullptr, E))
3875 return false;
3876 return this->emitNE(*T, E);
3877 }
3878
3879 // Or Floats.
3880 if (T == PT_Float)
3881 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
3882
3883 // Or anything else we can.
3884 return this->emitCast(*T, PT_Bool, E);
3885}
3886
3887template <class Emitter>
3889 const Expr *E) {
3890 switch (T) {
3891 case PT_Bool:
3892 return this->emitZeroBool(E);
3893 case PT_Sint8:
3894 return this->emitZeroSint8(E);
3895 case PT_Uint8:
3896 return this->emitZeroUint8(E);
3897 case PT_Sint16:
3898 return this->emitZeroSint16(E);
3899 case PT_Uint16:
3900 return this->emitZeroUint16(E);
3901 case PT_Sint32:
3902 return this->emitZeroSint32(E);
3903 case PT_Uint32:
3904 return this->emitZeroUint32(E);
3905 case PT_Sint64:
3906 return this->emitZeroSint64(E);
3907 case PT_Uint64:
3908 return this->emitZeroUint64(E);
3909 case PT_IntAP:
3910 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
3911 case PT_IntAPS:
3912 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
3913 case PT_Ptr:
3914 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
3915 nullptr, E);
3916 case PT_FnPtr:
3917 return this->emitNullFnPtr(0, nullptr, E);
3918 case PT_MemberPtr:
3919 return this->emitNullMemberPtr(0, nullptr, E);
3920 case PT_Float:
3921 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E);
3922 case PT_FixedPoint: {
3923 auto Sem = Ctx.getASTContext().getFixedPointSemantics(E->getType());
3924 return this->emitConstFixedPoint(FixedPoint::zero(Sem), E);
3925 }
3926 llvm_unreachable("Implement");
3927 }
3928 llvm_unreachable("unknown primitive type");
3929}
3930
3931template <class Emitter>
3933 const Expr *E) {
3934 assert(E);
3935 assert(R);
3936 // Fields
3937 for (const Record::Field &Field : R->fields()) {
3938 if (Field.Decl->isUnnamedBitField())
3939 continue;
3940
3941 const Descriptor *D = Field.Desc;
3942 if (D->isPrimitive()) {
3943 QualType QT = D->getType();
3944 PrimType T = classifyPrim(D->getType());
3945 if (!this->visitZeroInitializer(T, QT, E))
3946 return false;
3947 if (!this->emitInitField(T, Field.Offset, E))
3948 return false;
3949 if (R->isUnion())
3950 break;
3951 continue;
3952 }
3953
3954 if (!this->emitGetPtrField(Field.Offset, E))
3955 return false;
3956
3957 if (D->isPrimitiveArray()) {
3958 QualType ET = D->getElemQualType();
3959 PrimType T = classifyPrim(ET);
3960 for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
3961 if (!this->visitZeroInitializer(T, ET, E))
3962 return false;
3963 if (!this->emitInitElem(T, I, E))
3964 return false;
3965 }
3966 } else if (D->isCompositeArray()) {
3967 // Can't be a vector or complex field.
3968 if (!this->visitZeroArrayInitializer(D->getType(), E))
3969 return false;
3970 } else if (D->isRecord()) {
3971 if (!this->visitZeroRecordInitializer(D->ElemRecord, E))
3972 return false;
3973 } else {
3974 assert(false);
3975 }
3976
3977 if (!this->emitFinishInitPop(E))
3978 return false;
3979
3980 // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the
3981 // object's first non-static named data member is zero-initialized
3982 if (R->isUnion())
3983 break;
3984 }
3985
3986 for (const Record::Base &B : R->bases()) {
3987 if (!this->emitGetPtrBase(B.Offset, E))
3988 return false;
3989 if (!this->visitZeroRecordInitializer(B.R, E))
3990 return false;
3991 if (!this->emitFinishInitPop(E))
3992 return false;
3993 }
3994
3995 // FIXME: Virtual bases.
3996
3997 return true;
3998}
3999
4000template <class Emitter>
4002 assert(T->isArrayType() || T->isAnyComplexType() || T->isVectorType());
4003 const ArrayType *AT = T->getAsArrayTypeUnsafe();
4004 QualType ElemType = AT->getElementType();
4005 size_t NumElems = cast<ConstantArrayType>(AT)->getZExtSize();
4006
4007 if (std::optional<PrimType> ElemT = classify(ElemType)) {
4008 for (size_t I = 0; I != NumElems; ++I) {
4009 if (!this->visitZeroInitializer(*ElemT, ElemType, E))
4010 return false;
4011 if (!this->emitInitElem(*ElemT, I, E))
4012 return false;
4013 }
4014 return true;
4015 } else if (ElemType->isRecordType()) {
4016 const Record *R = getRecord(ElemType);
4017
4018 for (size_t I = 0; I != NumElems; ++I) {
4019 if (!this->emitConstUint32(I, E))
4020 return false;
4021 if (!this->emitArrayElemPtr(PT_Uint32, E))
4022 return false;
4023 if (!this->visitZeroRecordInitializer(R, E))
4024 return false;
4025 if (!this->emitPopPtr(E))
4026 return false;
4027 }
4028 return true;
4029 } else if (ElemType->isArrayType()) {
4030 for (size_t I = 0; I != NumElems; ++I) {
4031 if (!this->emitConstUint32(I, E))
4032 return false;
4033 if (!this->emitArrayElemPtr(PT_Uint32, E))
4034 return false;
4035 if (!this->visitZeroArrayInitializer(ElemType, E))
4036 return false;
4037 if (!this->emitPopPtr(E))
4038 return false;
4039 }
4040 return true;
4041 }
4042
4043 return false;
4044}
4045
4046template <class Emitter>
4047template <typename T>
4049 switch (Ty) {
4050 case PT_Sint8:
4051 return this->emitConstSint8(Value, E);
4052 case PT_Uint8:
4053 return this->emitConstUint8(Value, E);
4054 case PT_Sint16:
4055 return this->emitConstSint16(Value, E);
4056 case PT_Uint16:
4057 return this->emitConstUint16(Value, E);
4058 case PT_Sint32:
4059 return this->emitConstSint32(Value, E);
4060 case PT_Uint32:
4061 return this->emitConstUint32(Value, E);
4062 case PT_Sint64:
4063 return this->emitConstSint64(Value, E);
4064 case PT_Uint64:
4065 return this->emitConstUint64(Value, E);
4066 case PT_Bool:
4067 return this->emitConstBool(Value, E);
4068 case PT_Ptr:
4069 case PT_FnPtr:
4070 case PT_MemberPtr:
4071 case PT_Float:
4072 case PT_IntAP:
4073 case PT_IntAPS:
4074 case PT_FixedPoint:
4075 llvm_unreachable("Invalid integral type");
4076 break;
4077 }
4078 llvm_unreachable("unknown primitive type");
4079}
4080
4081template <class Emitter>
4082template <typename T>
4084 return this->emitConst(Value, classifyPrim(E->getType()), E);
4085}
4086
4087template <class Emitter>
4089 const Expr *E) {
4090 if (Ty == PT_IntAPS)
4091 return this->emitConstIntAPS(Value, E);
4092 if (Ty == PT_IntAP)
4093 return this->emitConstIntAP(Value, E);
4094
4095 if (Value.isSigned())
4096 return this->emitConst(Value.getSExtValue(), Ty, E);
4097 return this->emitConst(Value.getZExtValue(), Ty, E);
4098}
4099
4100template <class Emitter>
4101bool Compiler<Emitter>::emitConst(const APSInt &Value, const Expr *E) {
4102 return this->emitConst(Value, classifyPrim(E->getType()), E);
4103}
4104
4105template <class Emitter>
4107 bool IsConst,
4108 bool IsExtended) {
4109 // Make sure we don't accidentally register the same decl twice.
4110 if (const auto *VD =
4111 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
4112 assert(!P.getGlobal(VD));
4113 assert(!Locals.contains(VD));
4114 (void)VD;
4115 }
4116
4117 // FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
4118 // (int){12} in C. Consider using Expr::isTemporaryObject() instead
4119 // or isa<MaterializeTemporaryExpr>().
4120 Descriptor *D = P.createDescriptor(Src, Ty, Descriptor::InlineDescMD, IsConst,
4121 isa<const Expr *>(Src));
4122 Scope::Local Local = this->createLocal(D);
4123 if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>()))
4124 Locals.insert({VD, Local});
4125 VarScope->add(Local, IsExtended);
4126 return Local.Offset;
4127}
4128
4129template <class Emitter>
4130std::optional<unsigned>
4132 const ValueDecl *ExtendingDecl) {
4133 // Make sure we don't accidentally register the same decl twice.
4134 if ([[maybe_unused]] const auto *VD =
4135 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
4136 assert(!P.getGlobal(VD));
4137 assert(!Locals.contains(VD));
4138 }
4139
4140 const ValueDecl *Key = nullptr;
4141 const Expr *Init = nullptr;
4142 bool IsTemporary = false;
4143 if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
4144 Key = VD;
4145 Ty = VD->getType();
4146
4147 if (const auto *VarD = dyn_cast<VarDecl>(VD))
4148 Init = VarD->getInit();
4149 }
4150 if (auto *E = Src.dyn_cast<const Expr *>()) {
4151 IsTemporary = true;
4152 if (Ty.isNull())
4153 Ty = E->getType();
4154 }
4155
4156 Descriptor *D = P.createDescriptor(
4158 IsTemporary, /*IsMutable=*/false, Init);
4159 if (!D)
4160 return std::nullopt;
4161
4162 Scope::Local Local = this->createLocal(D);
4163 if (Key)
4164 Locals.insert({Key, Local});
4165 if (ExtendingDecl)
4166 VarScope->addExtended(Local, ExtendingDecl);
4167 else
4168 VarScope->add(Local, false);
4169 return Local.Offset;
4170}
4171
4172template <class Emitter>
4174 QualType Ty = E->getType();
4175 assert(!Ty->isRecordType());
4176
4177 Descriptor *D = P.createDescriptor(
4179 /*IsTemporary=*/true, /*IsMutable=*/false, /*Init=*/nullptr);
4180 assert(D);
4181
4182 Scope::Local Local = this->createLocal(D);
4183 VariableScope<Emitter> *S = VarScope;
4184 assert(S);
4185 // Attach to topmost scope.
4186 while (S->getParent())
4187 S = S->getParent();
4188 assert(S && !S->getParent());
4189 S->addLocal(Local);
4190 return Local.Offset;
4191}
4192
4193template <class Emitter>
4195 if (const PointerType *PT = dyn_cast<PointerType>(Ty))
4196 return PT->getPointeeType()->getAs<RecordType>();
4197 return Ty->getAs<RecordType>();
4198}
4199
4200template <class Emitter> Record *Compiler<Emitter>::getRecord(QualType Ty) {
4201 if (const auto *RecordTy = getRecordTy(Ty))
4202 return getRecord(RecordTy->getDecl());
4203 return nullptr;
4204}
4205
4206template <class Emitter>
4208 return P.getOrCreateRecord(RD);
4209}
4210
4211template <class Emitter>
4213 return Ctx.getOrCreateFunction(FD);
4214}
4215
4216template <class Emitter>
4217bool Compiler<Emitter>::visitExpr(const Expr *E, bool DestroyToplevelScope) {
4218 LocalScope<Emitter> RootScope(this);
4219
4220 // If we won't destroy the toplevel scope, check for memory leaks first.
4221 if (!DestroyToplevelScope) {
4222 if (!this->emitCheckAllocations(E))
4223 return false;
4224 }
4225
4226 auto maybeDestroyLocals = [&]() -> bool {
4227 if (DestroyToplevelScope)
4228 return RootScope.destroyLocals() && this->emitCheckAllocations(E);
4229 return this->emitCheckAllocations(E);
4230 };
4231
4232 // Void expressions.
4233 if (E->getType()->isVoidType()) {
4234 if (!visit(E))
4235 return false;
4236 return this->emitRetVoid(E) && maybeDestroyLocals();
4237 }
4238
4239 // Expressions with a primitive return type.
4240 if (std::optional<PrimType> T = classify(E)) {
4241 if (!visit(E))
4242 return false;
4243
4244 return this->emitRet(*T, E) && maybeDestroyLocals();
4245 }
4246
4247 // Expressions with a composite return type.
4248 // For us, that means everything we don't
4249 // have a PrimType for.
4250 if (std::optional<unsigned> LocalOffset = this->allocateLocal(E)) {
4251 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalOffset));
4252 if (!this->emitGetPtrLocal(*LocalOffset, E))
4253 return false;
4254
4255 if (!visitInitializer(E))
4256 return false;
4257
4258 if (!this->emitFinishInit(E))
4259 return false;
4260 // We are destroying the locals AFTER the Ret op.
4261 // The Ret op needs to copy the (alive) values, but the
4262 // destructors may still turn the entire expression invalid.
4263 return this->emitRetValue(E) && maybeDestroyLocals();
4264 }
4265
4266 return maybeDestroyLocals() && this->emitCheckAllocations(E) && false;
4267}
4268
4269template <class Emitter>
4271
4272 auto R = this->visitVarDecl(VD, /*Toplevel=*/true);
4273
4274 if (R.notCreated())
4275 return R;
4276
4277 if (R)
4278 return true;
4279
4280 if (!R && Context::shouldBeGloballyIndexed(VD)) {
4281 if (auto GlobalIndex = P.getGlobal(VD)) {
4282 Block *GlobalBlock = P.getGlobal(*GlobalIndex);
4284 *reinterpret_cast<GlobalInlineDescriptor *>(GlobalBlock->rawData());
4285
4286 GD.InitState = GlobalInitState::InitializerFailed;
4287 GlobalBlock->invokeDtor();
4288 }
4289 }
4290
4291 return R;
4292}
4293
4294/// Toplevel visitDeclAndReturn().
4295/// We get here from evaluateAsInitializer().
4296/// We need to evaluate the initializer and return its value.
4297template <class Emitter>
4299 bool ConstantContext) {
4300 std::optional<PrimType> VarT = classify(VD->getType());
4301
4302 // We only create variables if we're evaluating in a constant context.
4303 // Otherwise, just evaluate the initializer and return it.
4304 if (!ConstantContext) {
4305 DeclScope<Emitter> LS(this, VD);
4306 if (!this->visit(VD->getAnyInitializer()))
4307 return false;
4308 return this->emitRet(VarT.value_or(PT_Ptr), VD) && LS.destroyLocals() &&
4309 this->emitCheckAllocations(VD);
4310 }
4311
4312 LocalScope<Emitter> VDScope(this, VD);
4313 if (!this->visitVarDecl(VD, /*Toplevel=*/true))
4314 return false;
4315
4317 auto GlobalIndex = P.getGlobal(VD);
4318 assert(GlobalIndex); // visitVarDecl() didn't return false.
4319 if (VarT) {
4320 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
4321 return false;
4322 } else {
4323 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
4324 return false;
4325 }
4326 } else {
4327 auto Local = Locals.find(VD);
4328 assert(Local != Locals.end()); // Same here.
4329 if (VarT) {
4330 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
4331 return false;
4332 } else {
4333 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
4334 return false;
4335 }
4336 }
4337
4338 // Return the value.
4339 if (!this->emitRet(VarT.value_or(PT_Ptr), VD)) {
4340 // If the Ret above failed and this is a global variable, mark it as
4341 // uninitialized, even everything else succeeded.
4343 auto GlobalIndex = P.getGlobal(VD);
4344 assert(GlobalIndex);
4345 Block *GlobalBlock = P.getGlobal(*GlobalIndex);
4347 *reinterpret_cast<GlobalInlineDescriptor *>(GlobalBlock->rawData());
4348
4349 GD.InitState = GlobalInitState::InitializerFailed;
4350 GlobalBlock->invokeDtor();
4351 }
4352 return false;
4353 }
4354
4355 return VDScope.destroyLocals() && this->emitCheckAllocations(VD);
4356}
4357
4358template <class Emitter>
4360 bool Toplevel) {
4361 // We don't know what to do with these, so just return false.
4362 if (VD->getType().isNull())
4363 return false;
4364
4365 // This case is EvalEmitter-only. If we won't create any instructions for the
4366 // initializer anyway, don't bother creating the variable in the first place.
4367 if (!this->isActive())
4369
4370 const Expr *Init = VD->getInit();
4371 std::optional<PrimType> VarT = classify(VD->getType());
4372
4373 if (Init && Init->isValueDependent())
4374 return false;
4375
4377 auto checkDecl = [&]() -> bool {
4378 bool NeedsOp = !Toplevel && VD->isLocalVarDecl() && VD->isStaticLocal();
4379 return !NeedsOp || this->emitCheckDecl(VD, VD);
4380 };
4381
4382 auto initGlobal = [&](unsigned GlobalIndex) -> bool {
4383 assert(Init);
4384
4385 if (VarT) {
4386 if (!this->visit(Init))
4387 return checkDecl() && false;
4388
4389 return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
4390 }
4391
4392 if (!checkDecl())
4393 return false;
4394
4395 if (!this->emitGetPtrGlobal(GlobalIndex, Init))
4396 return false;
4397
4398 if (!visitInitializer(Init))
4399 return false;
4400
4401 if (!this->emitFinishInit(Init))
4402 return false;
4403
4404 return this->emitPopPtr(Init);
4405 };
4406
4408
4409 // We've already seen and initialized this global.
4410 if (std::optional<unsigned> GlobalIndex = P.getGlobal(VD)) {
4411 if (P.getPtrGlobal(*GlobalIndex).isInitialized())
4412 return checkDecl();
4413
4414 // The previous attempt at initialization might've been unsuccessful,
4415 // so let's try this one.
4416 return Init && checkDecl() && initGlobal(*GlobalIndex);
4417 }
4418
4419 std::optional<unsigned> GlobalIndex = P.createGlobal(VD, Init);
4420
4421 if (!GlobalIndex)
4422 return false;
4423
4424 return !Init || (checkDecl() && initGlobal(*GlobalIndex));
4425 } else {
4427
4428 if (VarT) {
4429 unsigned Offset = this->allocateLocalPrimitive(
4430 VD, *VarT, VD->getType().isConstQualified());
4431 if (Init) {
4432 // If this is a toplevel declaration, create a scope for the
4433 // initializer.
4434 if (Toplevel) {
4436 if (!this->visit(Init))
4437 return false;
4438 return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals();
4439 } else {
4440 if (!this->visit(Init))
4441 return false;
4442 return this->emitSetLocal(*VarT, Offset, VD);
4443 }
4444 }
4445 } else {
4446 if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
4447 if (!Init)
4448 return true;
4449
4450 if (!this->emitGetPtrLocal(*Offset, Init))
4451 return false;
4452
4453 if (!visitInitializer(Init))
4454 return false;
4455
4456 if (!this->emitFinishInit(Init))
4457 return false;
4458
4459 return this->emitPopPtr(Init);
4460 }
4461 return false;
4462 }
4463 return true;
4464 }
4465
4466 return false;
4467}
4468
4469template <class Emitter>
4471 const Expr *E) {
4472 assert(!DiscardResult);
4473 if (Val.isInt())
4474 return this->emitConst(Val.getInt(), ValType, E);
4475 else if (Val.isFloat())
4476 return this->emitConstFloat(Val.getFloat(), E);
4477
4478 if (Val.isLValue()) {
4479 if (Val.isNullPointer())
4480 return this->emitNull(ValType, 0, nullptr, E);
4482 if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>())
4483 return this->visit(BaseExpr);
4484 else if (const auto *VD = Base.dyn_cast<const ValueDecl *>()) {
4485 return this->visitDeclRef(VD, E);
4486 }
4487 } else if (Val.isMemberPointer()) {
4488 if (const ValueDecl *MemberDecl = Val.getMemberPointerDecl())
4489 return this->emitGetMemberPtr(MemberDecl, E);
4490 return this->emitNullMemberPtr(0, nullptr, E);
4491 }
4492
4493 return false;
4494}
4495
4496template <class Emitter>
4498 const Expr *E) {
4499
4500 if (Val.isStruct()) {
4501 const Record *R = this->getRecord(E->getType());
4502 assert(R);
4503 for (unsigned I = 0, N = Val.getStructNumFields(); I != N; ++I) {
4504 const APValue &F = Val.getStructField(I);
4505 const Record::Field *RF = R->getField(I);
4506
4507 if (F.isInt() || F.isFloat() || F.isLValue() || F.isMemberPointer()) {
4508 PrimType T = classifyPrim(RF->Decl->getType());
4509 if (!this->visitAPValue(F, T, E))
4510 return false;
4511 if (!this->emitInitField(T, RF->Offset, E))
4512 return false;
4513 } else if (F.isArray()) {
4514 assert(RF->Desc->isPrimitiveArray());
4515 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
4516 PrimType ElemT = classifyPrim(ArrType->getElementType());
4517 assert(ArrType);
4518
4519 if (!this->emitGetPtrField(RF->Offset, E))
4520 return false;
4521
4522 for (unsigned A = 0, AN = F.getArraySize(); A != AN; ++A) {
4523 if (!this->visitAPValue(F.getArrayInitializedElt(A), ElemT, E))
4524 return false;
4525 if (!this->emitInitElem(ElemT, A, E))
4526 return false;
4527 }
4528
4529 if (!this->emitPopPtr(E))
4530 return false;
4531 } else if (F.isStruct() || F.isUnion()) {
4532 if (!this->emitGetPtrField(RF->Offset, E))
4533 return false;
4534 if (!this->visitAPValueInitializer(F, E))
4535 return false;
4536 if (!this->emitPopPtr(E))
4537 return false;
4538 } else {
4539 assert(false && "I don't think this should be possible");
4540 }
4541 }
4542 return true;
4543 } else if (Val.isUnion()) {
4544 const FieldDecl *UnionField = Val.getUnionField();
4545 const Record *R = this->getRecord(UnionField->getParent());
4546 assert(R);
4547 const APValue &F = Val.getUnionValue();
4548 const Record::Field *RF = R->getField(UnionField);
4549 PrimType T = classifyPrim(RF->Decl->getType());
4550 if (!this->visitAPValue(F, T, E))
4551 return false;
4552 return this->emitInitField(T, RF->Offset, E);
4553 }
4554 // TODO: Other types.
4555
4556 return false;
4557}
4558
4559template <class Emitter>
4561 unsigned BuiltinID) {
4562 const Function *Func = getFunction(E->getDirectCallee());
4563 if (!Func)
4564 return false;
4565
4566 // For these, we're expected to ultimately return an APValue pointing
4567 // to the CallExpr. This is needed to get the correct codegen.
4568 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
4569 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
4570 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
4571 BuiltinID == Builtin::BI__builtin_function_start) {
4572 if (DiscardResult)
4573 return true;
4574 return this->emitDummyPtr(E, E);
4575 }
4576
4577 QualType ReturnType = E->getType();
4578 std::optional<PrimType> ReturnT = classify(E);
4579
4580 // Non-primitive return type. Prepare storage.
4581 if (!Initializing && !ReturnT && !ReturnType->isVoidType()) {
4582 std::optional<unsigned> LocalIndex = allocateLocal(E);
4583 if (!LocalIndex)
4584 return false;
4585 if (!this->emitGetPtrLocal(*LocalIndex, E))
4586 return false;
4587 }
4588
4589 if (!Func->isUnevaluatedBuiltin()) {
4590 // Put arguments on the stack.
4591 for (const auto *Arg : E->arguments()) {
4592 if (!this->visit(Arg))
4593 return false;
4594 }
4595 }
4596
4597 if (!this->emitCallBI(Func, E, BuiltinID, E))
4598 return false;
4599
4600 if (DiscardResult && !ReturnType->isVoidType()) {
4601 assert(ReturnT);
4602 return this->emitPop(*ReturnT, E);
4603 }
4604
4605 return true;
4606}
4607
4608template <class Emitter>
4610 if (unsigned BuiltinID = E->getBuiltinCallee())
4611 return VisitBuiltinCallExpr(E, BuiltinID);
4612
4613 const FunctionDecl *FuncDecl = E->getDirectCallee();
4614 // Calls to replaceable operator new/operator delete.
4615 if (FuncDecl && FuncDecl->isReplaceableGlobalAllocationFunction()) {
4616 if (FuncDecl->getDeclName().getCXXOverloadedOperator() == OO_New ||
4617 FuncDecl->getDeclName().getCXXOverloadedOperator() == OO_Array_New) {
4618 return VisitBuiltinCallExpr(E, Builtin::BI__builtin_operator_new);
4619 } else {
4620 assert(FuncDecl->getDeclName().getCXXOverloadedOperator() == OO_Delete);
4621 return VisitBuiltinCallExpr(E, Builtin::BI__builtin_operator_delete);
4622 }
4623 }
4624 // Explicit calls to trivial destructors
4625 if (const auto *DD = dyn_cast_if_present<CXXDestructorDecl>(FuncDecl);
4626 DD && DD->isTrivial())
4627 return true;
4628
4629 QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
4630 std::optional<PrimType> T = classify(ReturnType);
4631 bool HasRVO = !ReturnType->isVoidType() && !T;
4632
4633 if (HasRVO) {
4634 if (DiscardResult) {
4635 // If we need to discard the return value but the function returns its
4636 // value via an RVO pointer, we need to create one such pointer just
4637 // for this call.
4638 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
4639 if (!this->emitGetPtrLocal(*LocalIndex, E))
4640 return false;
4641 }
4642 } else {
4643 // We need the result. Prepare a pointer to return or
4644 // dup the current one.
4645 if (!Initializing) {
4646 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
4647 if (!this->emitGetPtrLocal(*LocalIndex, E))
4648 return false;
4649 }
4650 }
4651 if (!this->emitDupPtr(E))
4652 return false;
4653 }
4654 }
4655
4657 llvm::ArrayRef(E->getArgs(), E->getNumArgs()));
4658
4659 bool IsAssignmentOperatorCall = false;
4660 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
4661 OCE && OCE->isAssignmentOp()) {
4662 // Just like with regular assignments, we need to special-case assignment
4663 // operators here and evaluate the RHS (the second arg) before the LHS (the
4664 // first arg. We fix this by using a Flip op later.
4665 assert(Args.size() == 2);
4666 IsAssignmentOperatorCall = true;
4667 std::reverse(Args.begin(), Args.end());
4668 }
4669 // Calling a static operator will still
4670 // pass the instance, but we don't need it.
4671 // Discard it here.
4672 if (isa<CXXOperatorCallExpr>(E)) {
4673 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
4674 MD && MD->isStatic()) {
4675 if (!this->discard(E->getArg(0)))
4676 return false;
4677 // Drop first arg.
4678 Args.erase(Args.begin());
4679 }
4680 }
4681
4682 std::optional<unsigned> CalleeOffset;
4683 // Add the (optional, implicit) This pointer.
4684 if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
4685 if (!FuncDecl && classifyPrim(E->getCallee()) == PT_MemberPtr) {
4686 // If we end up creating a CallPtr op for this, we need the base of the
4687 // member pointer as the instance pointer, and later extract the function
4688 // decl as the function pointer.
4689 const Expr *Callee = E->getCallee();
4690 CalleeOffset =
4691 this->allocateLocalPrimitive(Callee, PT_MemberPtr, true, false);
4692 if (!this->visit(Callee))
4693 return false;
4694 if (!this->emitSetLocal(PT_MemberPtr, *CalleeOffset, E))
4695 return false;
4696 if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
4697 return false;
4698 if (!this->emitGetMemberPtrBase(E))
4699 return false;
4700 } else if (!this->visit(MC->getImplicitObjectArgument())) {
4701 return false;
4702 }
4703 } else if (!FuncDecl) {
4704 const Expr *Callee = E->getCallee();
4705 CalleeOffset = this->allocateLocalPrimitive(Callee, PT_FnPtr, true, false);
4706 if (!this->visit(Callee))
4707 return false;
4708 if (!this->emitSetLocal(PT_FnPtr, *CalleeOffset, E))
4709 return false;
4710 }
4711
4712 llvm::BitVector NonNullArgs = collectNonNullArgs(FuncDecl, Args);
4713 // Put arguments on the stack.
4714 unsigned ArgIndex = 0;
4715 for (const auto *Arg : Args) {
4716 if (!this->visit(Arg))
4717 return false;
4718
4719 // If we know the callee already, check the known parametrs for nullability.
4720 if (FuncDecl && NonNullArgs[ArgIndex]) {
4721 PrimType ArgT = classify(Arg).value_or(PT_Ptr);
4722 if (ArgT == PT_Ptr || ArgT == PT_FnPtr) {
4723 if (!this->emitCheckNonNullArg(ArgT, Arg))
4724 return false;
4725 }
4726 }
4727 ++ArgIndex;
4728 }
4729
4730 // Undo the argument reversal we did earlier.
4731 if (IsAssignmentOperatorCall) {
4732 assert(Args.size() == 2);
4733 PrimType Arg1T = classify(Args[0]).value_or(PT_Ptr);
4734 PrimType Arg2T = classify(Args[1]).value_or(PT_Ptr);
4735 if (!this->emitFlip(Arg2T, Arg1T, E))
4736 return false;
4737 }
4738
4739 if (FuncDecl) {
4740 const Function *Func = getFunction(FuncDecl);
4741 if (!Func)
4742 return false;
4743 assert(HasRVO == Func->hasRVO());
4744
4745 bool HasQualifier = false;
4746 if (const auto *ME = dyn_cast<MemberExpr>(E->getCallee()))
4747 HasQualifier = ME->hasQualifier();
4748
4749 bool IsVirtual = false;
4750 if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
4751 IsVirtual = MD->isVirtual();
4752
4753 // In any case call the function. The return value will end up on the stack
4754 // and if the function has RVO, we already have the pointer on the stack to
4755 // write the result into.
4756 if (IsVirtual && !HasQualifier) {
4757 uint32_t VarArgSize = 0;
4758 unsigned NumParams =
4759 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(E);
4760 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
4761 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
4762
4763 if (!this->emitCallVirt(Func, VarArgSize, E))
4764 return false;
4765 } else if (Func->isVariadic()) {
4766 uint32_t VarArgSize = 0;
4767 unsigned NumParams =
4768 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(E);
4769 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
4770 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
4771 if (!this->emitCallVar(Func, VarArgSize, E))
4772 return false;
4773 } else {
4774 if (!this->emitCall(Func, 0, E))
4775 return false;
4776 }
4777 } else {
4778 // Indirect call. Visit the callee, which will leave a FunctionPointer on
4779 // the stack. Cleanup of the returned value if necessary will be done after
4780 // the function call completed.
4781
4782 // Sum the size of all args from the call expr.
4783 uint32_t ArgSize = 0;
4784 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
4785 ArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
4786
4787 // Get the callee, either from a member pointer or function pointer saved in
4788 // CalleeOffset.
4789 if (isa<CXXMemberCallExpr>(E) && CalleeOffset) {
4790 if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
4791 return false;
4792 if (!this->emitGetMemberPtrDecl(E))
4793 return false;
4794 } else {
4795 if (!this->emitGetLocal(PT_FnPtr, *CalleeOffset, E))
4796 return false;
4797 }
4798 if (!this->emitCallPtr(ArgSize, E, E))
4799 return false;
4800 }
4801
4802 // Cleanup for discarded return values.
4803 if (DiscardResult && !ReturnType->isVoidType() && T)
4804 return this->emitPop(*T, E);
4805
4806 return true;
4807}
4808
4809template <class Emitter>
4811 SourceLocScope<Emitter> SLS(this, E);
4812
4813 return this->delegate(E->getExpr());
4814}
4815
4816template <class Emitter>
4818 SourceLocScope<Emitter> SLS(this, E);
4819
4820 return this->delegate(E->getExpr());
4821}
4822
4823template <class Emitter>
4825 if (DiscardResult)
4826 return true;
4827
4828 return this->emitConstBool(E->getValue(), E);
4829}
4830
4831template <class Emitter>
4833 const CXXNullPtrLiteralExpr *E) {
4834 if (DiscardResult)
4835 return true;
4836
4837 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(E->getType());
4838 return this->emitNullPtr(Val, nullptr, E);
4839}
4840
4841template <class Emitter>
4843 if (DiscardResult)
4844 return true;
4845
4846 assert(E->getType()->isIntegerType());
4847
4848 PrimType T = classifyPrim(E->getType());
4849 return this->emitZero(T, E);
4850}
4851
4852template <class Emitter>
4854 if (DiscardResult)
4855 return true;
4856
4857 if (this->LambdaThisCapture.Offset > 0) {
4858 if (this->LambdaThisCapture.IsPtr)
4859 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
4860 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
4861 }
4862
4863 // In some circumstances, the 'this' pointer does not actually refer to the
4864 // instance pointer of the current function frame, but e.g. to the declaration
4865 // currently being initialized. Here we emit the necessary instruction(s) for
4866 // this scenario.
4867 if (!InitStackActive)
4868 return this->emitThis(E);
4869
4870 if (!InitStack.empty()) {
4871 // If our init stack is, for example:
4872 // 0 Stack: 3 (decl)
4873 // 1 Stack: 6 (init list)
4874 // 2 Stack: 1 (field)
4875 // 3 Stack: 6 (init list)
4876 // 4 Stack: 1 (field)
4877 //
4878 // We want to find the LAST element in it that's an init list,
4879 // which is marked with the K_InitList marker. The index right
4880 // before that points to an init list. We need to find the
4881 // elements before the K_InitList element that point to a base
4882 // (e.g. a decl or This), optionally followed by field, elem, etc.
4883 // In the example above, we want to emit elements [0..2].
4884 unsigned StartIndex = 0;
4885 unsigned EndIndex = 0;
4886 // Find the init list.
4887 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
4888 if (InitStack[StartIndex].Kind == InitLink::K_InitList ||
4889 InitStack[StartIndex].Kind == InitLink::K_This) {
4890 EndIndex = StartIndex;
4891 --StartIndex;
4892 break;
4893 }
4894 }
4895
4896 // Walk backwards to find the base.
4897 for (; StartIndex > 0; --StartIndex) {
4898 if (InitStack[StartIndex].Kind == InitLink::K_InitList)
4899 continue;
4900
4901 if (InitStack[StartIndex].Kind != InitLink::K_Field &&
4902 InitStack[StartIndex].Kind != InitLink::K_Elem)
4903 break;
4904 }
4905
4906 // Emit the instructions.
4907 for (unsigned I = StartIndex; I != EndIndex; ++I) {
4908 if (InitStack[I].Kind == InitLink::K_InitList)
4909 continue;
4910 if (!InitStack[I].template emit<Emitter>(this, E))
4911 return false;
4912 }
4913 return true;
4914 }
4915 return this->emitThis(E);
4916}
4917
4918template <class Emitter> bool Compiler<Emitter>::visitStmt(const Stmt *S) {
4919 switch (S->getStmtClass()) {
4920 case Stmt::CompoundStmtClass:
4921 return visitCompoundStmt(cast<CompoundStmt>(S));
4922 case Stmt::DeclStmtClass:
4923 return visitDeclStmt(cast<DeclStmt>(S));
4924 case Stmt::ReturnStmtClass:
4925 return visitReturnStmt(cast<ReturnStmt>(S));
4926 case Stmt::IfStmtClass:
4927 return visitIfStmt(cast<IfStmt>(S));
4928 case Stmt::WhileStmtClass:
4929 return visitWhileStmt(cast<WhileStmt>(S));
4930 case Stmt::DoStmtClass:
4931 return visitDoStmt(cast<DoStmt>(S));
4932 case Stmt::ForStmtClass:
4933 return visitForStmt(cast<ForStmt>(S));
4934 case Stmt::CXXForRangeStmtClass:
4935 return visitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
4936 case Stmt::BreakStmtClass:
4937 return visitBreakStmt(cast<BreakStmt>(S));
4938 case Stmt::ContinueStmtClass:
4939 return visitContinueStmt(cast<ContinueStmt>(S));
4940 case Stmt::SwitchStmtClass:
4941 return visitSwitchStmt(cast<SwitchStmt>(S));
4942 case Stmt::CaseStmtClass:
4943 return visitCaseStmt(cast<CaseStmt>(S));
4944 case Stmt::DefaultStmtClass:
4945 return visitDefaultStmt(cast<DefaultStmt>(S));
4946 case Stmt::AttributedStmtClass:
4947 return visitAttributedStmt(cast<AttributedStmt>(S));
4948 case Stmt::CXXTryStmtClass:
4949 return visitCXXTryStmt(cast<CXXTryStmt>(S));
4950 case Stmt::NullStmtClass:
4951 return true;
4952 // Always invalid statements.
4953 case Stmt::GCCAsmStmtClass:
4954 case Stmt::MSAsmStmtClass:
4955 case Stmt::GotoStmtClass:
4956 return this->emitInvalid(S);
4957 case Stmt::LabelStmtClass:
4958 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
4959 default: {
4960 if (const auto *E = dyn_cast<Expr>(S))
4961 return this->discard(E);
4962 return false;
4963 }
4964 }
4965}
4966
4967template <class Emitter>
4970 for (const auto *InnerStmt : S->body())
4971 if (!visitStmt(InnerStmt))
4972 return false;
4973 return Scope.destroyLocals();
4974}
4975
4976template <class Emitter>
4978 for (const auto *D : DS->decls()) {
4980 FunctionDecl>(D))
4981 continue;
4982
4983 const auto *VD = dyn_cast<VarDecl>(D);
4984 if (!VD)
4985 return false;
4986 if (!this->visitVarDecl(VD))
4987 return false;
4988
4989 // Register decomposition decl holding vars.
4990 if (const auto *DD = dyn_cast<DecompositionDecl>(VD)) {
4991 for (auto *BD : DD->bindings())
4992 if (auto *KD = BD->getHoldingVar()) {
4993 if (!this->visitVarDecl(KD))
4994 return false;
4995 }
4996 }
4997 }
4998
4999 return true;
5000}
5001
5002template <class Emitter>
5004 if (this->InStmtExpr)
5005 return this->emitUnsupported(RS);
5006
5007 if (const Expr *RE = RS->getRetValue()) {
5008 LocalScope<Emitter> RetScope(this);
5009 if (ReturnType) {
5010 // Primitive types are simply returned.
5011 if (!this->visit(RE))
5012 return false;
5013 this->emitCleanup();
5014 return this->emitRet(*ReturnType, RS);
5015 } else if (RE->getType()->isVoidType()) {
5016 if (!this->visit(RE))
5017 return false;
5018 } else {
5020 // RVO - construct the value in the return location.
5021 if (!this->emitRVOPtr(RE))
5022 return false;
5023 if (!this->visitInitializer(RE))
5024 return false;
5025 if (!this->emitPopPtr(RE))
5026 return false;
5027
5028 this->emitCleanup();
5029 return this->emitRetVoid(RS);
5030 }
5031 }
5032
5033 // Void return.
5034 this->emitCleanup();
5035 return this->emitRetVoid(RS);
5036}
5037
5038template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
5039 if (auto *CondInit = IS->getInit())
5040 if (!visitStmt(CondInit))
5041 return false;
5042
5043 if (const DeclStmt *CondDecl = IS->getConditionVariableDeclStmt())
5044 if (!visitDeclStmt(CondDecl))
5045 return false;
5046
5047 // Compile condition.
5048 if (IS->isNonNegatedConsteval()) {
5049 if (!this->emitIsConstantContext(IS))
5050 return false;
5051 } else if (IS->isNegatedConsteval()) {
5052 if (!this->emitIsConstantContext(IS))
5053 return false;
5054 if (!this->emitInv(IS))
5055 return false;
5056 } else {
5057 if (!this->visitBool(IS->getCond()))
5058 return false;
5059 }
5060
5061 if (const Stmt *Else = IS->getElse()) {
5062 LabelTy LabelElse = this->getLabel();
5063 LabelTy LabelEnd = this->getLabel();
5064 if (!this->jumpFalse(LabelElse))
5065 return false;
5066 {
5067 LocalScope<Emitter> ThenScope(this);
5068 if (!visitStmt(IS->getThen()))
5069 return false;
5070 if (!ThenScope.destroyLocals())
5071 return false;
5072 }
5073 if (!this->jump(LabelEnd))
5074 return false;
5075 this->emitLabel(LabelElse);
5076 {
5077 LocalScope<Emitter> ElseScope(this);
5078 if (!visitStmt(Else))
5079 return false;
5080 if (!ElseScope.destroyLocals())
5081 return false;
5082 }
5083 this->emitLabel(LabelEnd);
5084 } else {
5085 LabelTy LabelEnd = this->getLabel();
5086 if (!this->jumpFalse(LabelEnd))
5087 return false;
5088 {
5089 LocalScope<Emitter> ThenScope(this);
5090 if (!visitStmt(IS->getThen()))
5091 return false;
5092 if (!ThenScope.destroyLocals())
5093 return false;
5094 }
5095 this->emitLabel(LabelEnd);
5096 }
5097
5098 return true;
5099}
5100
5101template <class Emitter>
5103 const Expr *Cond = S->getCond();
5104 const Stmt *Body = S->getBody();
5105
5106 LabelTy CondLabel = this->getLabel(); // Label before the condition.
5107 LabelTy EndLabel = this->getLabel(); // Label after the loop.
5108 LoopScope<Emitter> LS(this, EndLabel, CondLabel);
5109
5110 this->fallthrough(CondLabel);
5111 this->emitLabel(CondLabel);
5112
5113 {
5114 LocalScope<Emitter> CondScope(this);
5115 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5116 if (!visitDeclStmt(CondDecl))
5117 return false;
5118
5119 if (!this->visitBool(Cond))
5120 return false;
5121 if (!this->jumpFalse(EndLabel))
5122 return false;
5123
5124 if (!this->visitStmt(Body))
5125 return false;
5126
5127 if (!CondScope.destroyLocals())
5128 return false;
5129 }
5130 if (!this->jump(CondLabel))
5131 return false;
5132 this->fallthrough(EndLabel);
5133 this->emitLabel(EndLabel);
5134
5135 return true;
5136}
5137
5138template <class Emitter> bool Compiler<Emitter>::visitDoStmt(const DoStmt *S) {
5139 const Expr *Cond = S->getCond();
5140 const Stmt *Body = S->getBody();
5141
5142 LabelTy StartLabel = this->getLabel();
5143 LabelTy EndLabel = this->getLabel();
5144 LabelTy CondLabel = this->getLabel();
5145 LoopScope<Emitter> LS(this, EndLabel, CondLabel);
5146
5147 this->fallthrough(StartLabel);
5148 this->emitLabel(StartLabel);
5149
5150 {
5151 LocalScope<Emitter> CondScope(this);
5152 if (!this->visitStmt(Body))
5153 return false;
5154 this->fallthrough(CondLabel);
5155 this->emitLabel(CondLabel);
5156 if (!this->visitBool(Cond))
5157 return false;
5158
5159 if (!CondScope.destroyLocals())
5160 return false;
5161 }
5162 if (!this->jumpTrue(StartLabel))
5163 return false;
5164
5165 this->fallthrough(EndLabel);
5166 this->emitLabel(EndLabel);
5167 return true;
5168}
5169
5170template <class Emitter>
5172 // for (Init; Cond; Inc) { Body }
5173 const Stmt *Init = S->getInit();
5174 const Expr *Cond = S->getCond();
5175 const Expr *Inc = S->getInc();
5176 const Stmt *Body = S->getBody();
5177
5178 LabelTy EndLabel = this->getLabel();
5179 LabelTy CondLabel = this->getLabel();
5180 LabelTy IncLabel = this->getLabel();
5181 LoopScope<Emitter> LS(this, EndLabel, IncLabel);
5182
5183 if (Init && !this->visitStmt(Init))
5184 return false;
5185
5186 this->fallthrough(CondLabel);
5187 this->emitLabel(CondLabel);
5188
5189 {
5190 LocalScope<Emitter> CondScope(this);
5191 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5192 if (!visitDeclStmt(CondDecl))
5193 return false;
5194
5195 if (Cond) {
5196 if (!this->visitBool(Cond))
5197 return false;
5198 if (!this->jumpFalse(EndLabel))
5199 return false;
5200 }
5201
5202 if (Body && !this->visitStmt(Body))
5203 return false;
5204
5205 this->fallthrough(IncLabel);
5206 this->emitLabel(IncLabel);
5207 if (Inc && !this->discard(Inc))
5208 return false;
5209
5210 if (!CondScope.destroyLocals())
5211 return false;
5212 }
5213 if (!this->jump(CondLabel))
5214 return false;
5215
5216 this->fallthrough(EndLabel);
5217 this->emitLabel(EndLabel);
5218 return true;
5219}
5220
5221template <class Emitter>
5223 const Stmt *Init = S->getInit();
5224 const Expr *Cond = S->getCond();
5225 const Expr *Inc = S->getInc();
5226 const Stmt *Body = S->getBody();
5227 const Stmt *BeginStmt = S->getBeginStmt();
5228 const Stmt *RangeStmt = S->getRangeStmt();
5229 const Stmt *EndStmt = S->getEndStmt();
5230 const VarDecl *LoopVar = S->getLoopVariable();
5231
5232 LabelTy EndLabel = this->getLabel();
5233 LabelTy CondLabel = this->getLabel();
5234 LabelTy IncLabel = this->getLabel();
5235 LoopScope<Emitter> LS(this, EndLabel, IncLabel);
5236
5237 // Emit declarations needed in the loop.
5238 if (Init && !this->visitStmt(Init))
5239 return false;
5240 if (!this->visitStmt(RangeStmt))
5241 return false;
5242 if (!this->visitStmt(BeginStmt))
5243 return false;
5244 if (!this->visitStmt(EndStmt))
5245 return false;
5246
5247 // Now the condition as well as the loop variable assignment.
5248 this->fallthrough(CondLabel);
5249 this->emitLabel(CondLabel);
5250 if (!this->visitBool(Cond))
5251 return false;
5252 if (!this->jumpFalse(EndLabel))
5253 return false;
5254
5255 if (!this->visitVarDecl(LoopVar))
5256 return false;
5257
5258 // Body.
5259 {
5260 if (!this->visitStmt(Body))
5261 return false;
5262
5263 this->fallthrough(IncLabel);
5264 this->emitLabel(IncLabel);
5265 if (!this->discard(Inc))
5266 return false;
5267 }
5268
5269 if (!this->jump(CondLabel))
5270 return false;
5271
5272 this->fallthrough(EndLabel);
5273 this->emitLabel(EndLabel);
5274 return true;
5275}
5276
5277template <class Emitter>
5279 if (!BreakLabel)
5280 return false;
5281
5282 for (VariableScope<Emitter> *C = VarScope; C != BreakVarScope;
5283 C = C->getParent())
5284 C->emitDestruction();
5285 return this->jump(*BreakLabel);
5286}
5287
5288template <class Emitter>
5290 if (!ContinueLabel)
5291 return false;
5292
5293 for (VariableScope<Emitter> *C = VarScope;
5294 C && C->getParent() != ContinueVarScope; C = C->getParent())
5295 C->emitDestruction();
5296 return this->jump(*ContinueLabel);
5297}
5298
5299template <class Emitter>
5301 const Expr *Cond = S->getCond();
5302 PrimType CondT = this->classifyPrim(Cond->getType());
5303 LocalScope<Emitter> LS(this);
5304
5305 LabelTy EndLabel = this->getLabel();
5306 OptLabelTy DefaultLabel = std::nullopt;
5307 unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT, true, false);
5308
5309 if (const auto *CondInit = S->getInit())
5310 if (!visitStmt(CondInit))
5311 return false;
5312
5313 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5314 if (!visitDeclStmt(CondDecl))
5315 return false;
5316
5317 // Initialize condition variable.
5318 if (!this->visit(Cond))
5319 return false;
5320 if (!this->emitSetLocal(CondT, CondVar, S))
5321 return false;
5322
5323 CaseMap CaseLabels;
5324 // Create labels and comparison ops for all case statements.
5325 for (const SwitchCase *SC = S->getSwitchCaseList(); SC;
5326 SC = SC->getNextSwitchCase()) {
5327 if (const auto *CS = dyn_cast<CaseStmt>(SC)) {
5328 // FIXME: Implement ranges.
5329 if (CS->caseStmtIsGNURange())
5330 return false;
5331 CaseLabels[SC] = this->getLabel();
5332
5333 const Expr *Value = CS->getLHS();
5334 PrimType ValueT = this->classifyPrim(Value->getType());
5335
5336 // Compare the case statement's value to the switch condition.
5337 if (!this->emitGetLocal(CondT, CondVar, CS))
5338 return false;
5339 if (!this->visit(Value))
5340 return false;
5341
5342 // Compare and jump to the case label.
5343 if (!this->emitEQ(ValueT, S))
5344 return false;
5345 if (!this->jumpTrue(CaseLabels[CS]))
5346 return false;
5347 } else {
5348 assert(!DefaultLabel);
5349 DefaultLabel = this->getLabel();
5350 }
5351 }
5352
5353 // If none of the conditions above were true, fall through to the default
5354 // statement or jump after the switch statement.
5355 if (DefaultLabel) {
5356 if (!this->jump(*DefaultLabel))
5357 return false;
5358 } else {
5359 if (!this->jump(EndLabel))
5360 return false;
5361 }
5362
5363 SwitchScope<Emitter> SS(this, std::move(CaseLabels), EndLabel, DefaultLabel);
5364 if (!this->visitStmt(S->getBody()))
5365 return false;
5366 this->emitLabel(EndLabel);
5367
5368 return LS.destroyLocals();
5369}
5370
5371template <class Emitter>
5373 this->emitLabel(CaseLabels[S]);
5374 return this->visitStmt(S->getSubStmt());
5375}
5376
5377template <class Emitter>
5379 this->emitLabel(*DefaultLabel);
5380 return this->visitStmt(S->getSubStmt());
5381}
5382
5383template <class Emitter>
5385 if (this->Ctx.getLangOpts().CXXAssumptions &&
5386 !this->Ctx.getLangOpts().MSVCCompat) {
5387 for (const Attr *A : S->getAttrs()) {
5388 auto *AA = dyn_cast<CXXAssumeAttr>(A);
5389 if (!AA)
5390 continue;
5391
5392 assert(isa<NullStmt>(S->getSubStmt()));
5393
5394 const Expr *Assumption = AA->getAssumption();
5395 if (Assumption->isValueDependent())
5396 return false;
5397
5398 if (Assumption->HasSideEffects(this->Ctx.getASTContext()))
5399 continue;
5400
5401 // Evaluate assumption.
5402 if (!this->visitBool(Assumption))
5403 return false;
5404
5405 if (!this->emitAssume(Assumption))
5406 return false;
5407 }
5408 }
5409
5410 // Ignore other attributes.
5411 return this->visitStmt(S->getSubStmt());
5412}
5413
5414template <class Emitter>
5416 // Ignore all handlers.
5417 return this->visitStmt(S->getTryBlock());
5418}
5419
5420template <class Emitter>
5422 assert(MD->isLambdaStaticInvoker());
5423 assert(MD->hasBody());
5424 assert(cast<CompoundStmt>(MD->getBody())->body_empty());
5425
5426 const CXXRecordDecl *ClosureClass = MD->getParent();
5427 const CXXMethodDecl *LambdaCallOp = ClosureClass->getLambdaCallOperator();
5428 assert(ClosureClass->captures_begin() == ClosureClass->captures_end());
5429 const Function *Func = this->getFunction(LambdaCallOp);
5430 if (!Func)
5431 return false;
5432 assert(Func->hasThisPointer());
5433 assert(Func->getNumParams() == (MD->getNumParams() + 1 + Func->hasRVO()));
5434
5435 if (Func->hasRVO()) {
5436 if (!this->emitRVOPtr(MD))
5437 return false;
5438 }
5439
5440 // The lambda call operator needs an instance pointer, but we don't have
5441 // one here, and we don't need one either because the lambda cannot have
5442 // any captures, as verified above. Emit a null pointer. This is then
5443 // special-cased when interpreting to not emit any misleading diagnostics.
5444 if (!this->emitNullPtr(0, nullptr, MD))
5445 return false;
5446
5447 // Forward all arguments from the static invoker to the lambda call operator.
5448 for (const ParmVarDecl *PVD : MD->parameters()) {
5449 auto It = this->Params.find(PVD);
5450 assert(It != this->Params.end());
5451
5452 // We do the lvalue-to-rvalue conversion manually here, so no need
5453 // to care about references.
5454 PrimType ParamType = this->classify(PVD->getType()).value_or(PT_Ptr);
5455 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
5456 return false;
5457 }
5458
5459 if (!this->emitCall(Func, 0, LambdaCallOp))
5460 return false;
5461
5462 this->emitCleanup();
5463 if (ReturnType)
5464 return this->emitRet(*ReturnType, MD);
5465
5466 // Nothing to do, since we emitted the RVO pointer above.
5467 return this->emitRetVoid(MD);
5468}
5469
5470template <class Emitter>
5472 if (Ctx.getLangOpts().CPlusPlus23)
5473 return true;
5474
5475 if (!E->isPRValue() || E->getType()->isLiteralType(Ctx.getASTContext()))
5476 return true;
5477
5478 return this->emitCheckLiteralType(E->getType().getTypePtr(), E);
5479}
5480
5481template <class Emitter>
5483 assert(!ReturnType);
5484
5485 auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
5486 const Expr *InitExpr) -> bool {
5487 // We don't know what to do with these, so just return false.
5488 if (InitExpr->getType().isNull())
5489 return false;
5490
5491 if (std::optional<PrimType> T = this->classify(InitExpr)) {
5492 if (!this->visit(InitExpr))
5493 return false;
5494
5495 if (F->isBitField())
5496 return this->emitInitThisBitField(*T, F, FieldOffset, InitExpr);
5497 return this->emitInitThisField(*T, FieldOffset, InitExpr);
5498 }
5499 // Non-primitive case. Get a pointer to the field-to-initialize
5500 // on the stack and call visitInitialzer() for it.
5501 InitLinkScope<Emitter> FieldScope(this, InitLink::Field(F->Offset));
5502 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
5503 return false;
5504
5505 if (!this->visitInitializer(InitExpr))
5506 return false;
5507
5508 return this->emitFinishInitPop(InitExpr);
5509 };
5510
5511 const RecordDecl *RD = Ctor->getParent();
5512 const Record *R = this->getRecord(RD);
5513 if (!R)
5514 return false;
5515
5516 if (R->isUnion() && Ctor->isCopyOrMoveConstructor()) {
5517 // union copy and move ctors are special.
5518 assert(cast<CompoundStmt>(Ctor->getBody())->body_empty());
5519 if (!this->emitThis(Ctor))
5520 return false;
5521
5522 auto PVD = Ctor->getParamDecl(0);
5523 ParamOffset PO = this->Params[PVD]; // Must exist.
5524
5525 if (!this->emitGetParam(PT_Ptr, PO.Offset, Ctor))
5526 return false;
5527
5528 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
5529 this->emitRetVoid(Ctor);
5530 }
5531
5533 for (const auto *Init : Ctor->inits()) {
5534 // Scope needed for the initializers.
5536
5537 const Expr *InitExpr = Init->getInit();
5538 if (const FieldDecl *Member = Init->getMember()) {
5539 const Record::Field *F = R->getField(Member);
5540
5541 if (!emitFieldInitializer(F, F->Offset, InitExpr))
5542 return false;
5543 } else if (const Type *Base = Init->getBaseClass()) {
5544 const auto *BaseDecl = Base->getAsCXXRecordDecl();
5545 assert(BaseDecl);
5546
5547 if (Init->isBaseVirtual()) {
5548 assert(R->getVirtualBase(BaseDecl));
5549 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
5550 return false;
5551
5552 } else {
5553 // Base class initializer.
5554 // Get This Base and call initializer on it.
5555 const Record::Base *B = R->getBase(BaseDecl);
5556 assert(B);
5557 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
5558 return false;
5559 }
5560
5561 if (!this->visitInitializer(InitExpr))
5562 return false;
5563 if (!this->emitFinishInitPop(InitExpr))
5564 return false;
5565 } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {
5566 assert(IFD->getChainingSize() >= 2);
5567
5568 unsigned NestedFieldOffset = 0;
5569 const Record::Field *NestedField = nullptr;
5570 for (const NamedDecl *ND : IFD->chain()) {
5571 const auto *FD = cast<FieldDecl>(ND);
5572 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
5573 assert(FieldRecord);
5574
5575 NestedField = FieldRecord->getField(FD);
5576 assert(NestedField);
5577
5578 NestedFieldOffset += NestedField->Offset;
5579 }
5580 assert(NestedField);
5581
5582 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
5583 return false;
5584 } else {
5585 assert(Init->isDelegatingInitializer());
5586 if (!this->emitThis(InitExpr))
5587 return false;
5588 if (!this->visitInitializer(Init->getInit()))
5589 return false;
5590 if (!this->emitPopPtr(InitExpr))
5591 return false;
5592 }
5593
5594 if (!Scope.destroyLocals())
5595 return false;
5596 }
5597
5598 if (const auto *Body = Ctor->getBody())
5599 if (!visitStmt(Body))
5600 return false;
5601
5602 return this->emitRetVoid(SourceInfo{});
5603}
5604
5605template <class Emitter>
5607 const RecordDecl *RD = Dtor->getParent();
5608 const Record *R = this->getRecord(RD);
5609 if (!R)
5610 return false;
5611
5612 if (!Dtor->isTrivial() && Dtor->getBody()) {
5613 if (!this->visitStmt(Dtor->getBody()))
5614 return false;
5615 }
5616
5617 if (!this->emitThis(Dtor))
5618 return false;
5619
5620 assert(R);
5621 if (!R->isUnion()) {
5622 // First, destroy all fields.
5623 for (const Record::Field &Field : llvm::reverse(R->fields())) {
5624 const Descriptor *D = Field.Desc;
5625 if (!D->isPrimitive() && !D->isPrimitiveArray()) {
5626 if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
5627 return false;
5628 if (!this->emitDestruction(D, SourceInfo{}))
5629 return false;
5630 if (!this->emitPopPtr(SourceInfo{}))
5631 return false;
5632 }
5633 }
5634 }
5635
5636 for (const Record::Base &Base : llvm::reverse(R->bases())) {
5637 if (Base.R->isAnonymousUnion())
5638 continue;
5639
5640 if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
5641 return false;
5642 if (!this->emitRecordDestruction(Base.R, {}))
5643 return false;
5644 if (!this->emitPopPtr(SourceInfo{}))
5645 return false;
5646 }
5647
5648 // FIXME: Virtual bases.
5649 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
5650}
5651
5652template <class Emitter>
5654 // Classify the return type.
5655 ReturnType = this->classify(F->getReturnType());
5656
5657 if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
5658 return this->compileConstructor(Ctor);
5659 if (const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
5660 return this->compileDestructor(Dtor);
5661
5662 // Emit custom code if this is a lambda static invoker.
5663 if (const auto *MD = dyn_cast<CXXMethodDecl>(F);
5664 MD && MD->isLambdaStaticInvoker())
5665 return this->emitLambdaStaticInvokerBody(MD);
5666
5667 // Regular functions.
5668 if (const auto *Body = F->getBody())
5669 if (!visitStmt(Body))
5670 return false;
5671
5672 // Emit a guard return to protect against a code path missing one.
5673 if (F->getReturnType()->isVoidType())
5674 return this->emitRetVoid(SourceInfo{});
5675 return this->emitNoRet(SourceInfo{});
5676}
5677
5678template <class Emitter>
5680 const Expr *SubExpr = E->getSubExpr();
5681 if (SubExpr->getType()->isAnyComplexType())
5682 return this->VisitComplexUnaryOperator(E);
5683 if (SubExpr->getType()->isVectorType())
5684 return this->VisitVectorUnaryOperator(E);
5685 if (SubExpr->getType()->isFixedPointType())
5686 return this->VisitFixedPointUnaryOperator(E);
5687 std::optional<PrimType> T = classify(SubExpr->getType());
5688
5689 switch (E->getOpcode()) {
5690 case UO_PostInc: { // x++
5691 if (!Ctx.getLangOpts().CPlusPlus14)
5692 return this->emitInvalid(E);
5693 if (!T)
5694 return this->emitError(E);
5695
5696 if (!this->visit(SubExpr))
5697 return false;
5698
5699 if (T == PT_Ptr || T == PT_FnPtr) {
5700 if (!this->emitIncPtr(E))
5701 return false;
5702
5703 return DiscardResult ? this->emitPopPtr(E) : true;
5704 }
5705
5706 if (T == PT_Float) {
5707 return DiscardResult ? this->emitIncfPop(getFPOptions(E), E)
5708 : this->emitIncf(getFPOptions(E), E);
5709 }
5710
5711 return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E);
5712 }
5713 case UO_PostDec: { // x--
5714 if (!Ctx.getLangOpts().CPlusPlus14)
5715 return this->emitInvalid(E);
5716 if (!T)
5717 return this->emitError(E);
5718
5719 if (!this->visit(SubExpr))
5720 return false;
5721
5722 if (T == PT_Ptr || T == PT_FnPtr) {
5723 if (!this->emitDecPtr(E))
5724 return false;
5725
5726 return DiscardResult ? this->emitPopPtr(E) : true;
5727 }
5728
5729 if (T == PT_Float) {
5730 return DiscardResult ? this->emitDecfPop(getFPOptions(E), E)
5731 : this->emitDecf(getFPOptions(E), E);
5732 }
5733
5734 return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E);
5735 }
5736 case UO_PreInc: { // ++x
5737 if (!Ctx.getLangOpts().CPlusPlus14)
5738 return this->emitInvalid(E);
5739 if (!T)
5740 return this->emitError(E);
5741
5742 if (!this->visit(SubExpr))
5743 return false;
5744
5745 if (T == PT_Ptr || T == PT_FnPtr) {
5746 if (!this->emitLoadPtr(E))
5747 return false;
5748 if (!this->emitConstUint8(1, E))
5749 return false;
5750 if (!this->emitAddOffsetUint8(E))
5751 return false;
5752 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
5753 }
5754
5755 // Post-inc and pre-inc are the same if the value is to be discarded.
5756 if (DiscardResult) {
5757 if (T == PT_Float)
5758 return this->emitIncfPop(getFPOptions(E), E);
5759 return this->emitIncPop(*T, E);
5760 }
5761
5762 if (T == PT_Float) {
5763 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
5764 if (!this->emitLoadFloat(E))
5765 return false;
5766 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
5767 return false;
5768 if (!this->emitAddf(getFPOptions(E), E))
5769 return false;
5770 if (!this->emitStoreFloat(E))
5771 return false;
5772 } else {
5773 assert(isIntegralType(*T));
5774 if (!this->emitLoad(*T, E))
5775 return false;
5776 if (!this->emitConst(1, E))
5777 return false;
5778 if (!this->emitAdd(*T, E))
5779 return false;
5780 if (!this->emitStore(*T, E))
5781 return false;
5782 }
5783 return E->isGLValue() || this->emitLoadPop(*T, E);
5784 }
5785 case UO_PreDec: { // --x
5786 if (!Ctx.getLangOpts().CPlusPlus14)
5787 return this->emitInvalid(E);
5788 if (!T)
5789 return this->emitError(E);
5790
5791 if (!this->visit(SubExpr))
5792 return false;
5793
5794 if (T == PT_Ptr || T == PT_FnPtr) {
5795 if (!this->emitLoadPtr(E))
5796 return false;
5797 if (!this->emitConstUint8(1, E))
5798 return false;
5799 if (!this->emitSubOffsetUint8(E))
5800 return false;
5801 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
5802 }
5803
5804 // Post-dec and pre-dec are the same if the value is to be discarded.
5805 if (DiscardResult) {
5806 if (T == PT_Float)
5807 return this->emitDecfPop(getFPOptions(E), E);
5808 return this->emitDecPop(*T, E);
5809 }
5810
5811 if (T == PT_Float) {
5812 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
5813 if (!this->emitLoadFloat(E))
5814 return false;
5815 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
5816 return false;
5817 if (!this->emitSubf(getFPOptions(E), E))
5818 return false;
5819 if (!this->emitStoreFloat(E))
5820 return false;
5821 } else {
5822 assert(isIntegralType(*T));
5823 if (!this->emitLoad(*T, E))
5824 return false;
5825 if (!this->emitConst(1, E))
5826 return false;
5827 if (!this->emitSub(*T, E))
5828 return false;
5829 if (!this->emitStore(*T, E))
5830 return false;
5831 }
5832 return E->isGLValue() || this->emitLoadPop(*T, E);
5833 }
5834 case UO_LNot: // !x
5835 if (!T)
5836 return this->emitError(E);
5837
5838 if (DiscardResult)
5839 return this->discard(SubExpr);
5840
5841 if (!this->visitBool(SubExpr))
5842 return false;
5843
5844 if (!this->emitInv(E))
5845 return false;
5846
5847 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
5848 return this->emitCast(PT_Bool, ET, E);
5849 return true;
5850 case UO_Minus: // -x
5851 if (!T)
5852 return this->emitError(E);
5853
5854 if (!this->visit(SubExpr))
5855 return false;
5856 return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
5857 case UO_Plus: // +x
5858 if (!T)
5859 return this->emitError(E);
5860
5861 if (!this->visit(SubExpr)) // noop
5862 return false;
5863 return DiscardResult ? this->emitPop(*T, E) : true;
5864 case UO_AddrOf: // &x
5865 if (E->getType()->isMemberPointerType()) {
5866 // C++11 [expr.unary.op]p3 has very strict rules on how the address of a
5867 // member can be formed.
5868 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(), E);
5869 }
5870 // We should already have a pointer when we get here.
5871 return this->delegate(SubExpr);
5872 case UO_Deref: // *x
5873 if (DiscardResult) {
5874 // assert(false);
5875 return this->discard(SubExpr);
5876 }
5877
5878 if (!this->visit(SubExpr))
5879 return false;
5880 if (classifyPrim(SubExpr) == PT_Ptr)
5881 return this->emitNarrowPtr(E);
5882 return true;
5883
5884 case UO_Not: // ~x
5885 if (!T)
5886 return this->emitError(E);
5887
5888 if (!this->visit(SubExpr))
5889 return false;
5890 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
5891 case UO_Real: // __real x
5892 assert(T);
5893 return this->delegate(SubExpr);
5894 case UO_Imag: { // __imag x
5895 assert(T);
5896 if (!this->discard(SubExpr))
5897 return false;
5898 return this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);
5899 }
5900 case UO_Extension:
5901 return this->delegate(SubExpr);
5902 case UO_Coawait:
5903 assert(false && "Unhandled opcode");
5904 }
5905
5906 return false;
5907}
5908
5909template <class Emitter>
5911 const Expr *SubExpr = E->getSubExpr();
5912 assert(SubExpr->getType()->isAnyComplexType());
5913
5914 if (DiscardResult)
5915 return this->discard(SubExpr);
5916
5917 std::optional<PrimType> ResT = classify(E);
5918 auto prepareResult = [=]() -> bool {
5919 if (!ResT && !Initializing) {
5920 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5921 if (!LocalIndex)
5922 return false;
5923 return this->emitGetPtrLocal(*LocalIndex, E);
5924 }
5925
5926 return true;
5927 };
5928
5929 // The offset of the temporary, if we created one.
5930 unsigned SubExprOffset = ~0u;
5931 auto createTemp = [=, &SubExprOffset]() -> bool {
5932 SubExprOffset = this->allocateLocalPrimitive(SubExpr, PT_Ptr, true, false);
5933 if (!this->visit(SubExpr))
5934 return false;
5935 return this->emitSetLocal(PT_Ptr, SubExprOffset, E);
5936 };
5937
5938 PrimType ElemT = classifyComplexElementType(SubExpr->getType());
5939 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
5940 if (!this->emitGetLocal(PT_Ptr, Offset, E))
5941 return false;
5942 return this->emitArrayElemPop(ElemT, Index, E);
5943 };
5944
5945 switch (E->getOpcode()) {
5946 case UO_Minus:
5947 if (!prepareResult())
5948 return false;
5949 if (!createTemp())
5950 return false;
5951 for (unsigned I = 0; I != 2; ++I) {
5952 if (!getElem(SubExprOffset, I))
5953 return false;
5954 if (!this->emitNeg(ElemT, E))
5955 return false;
5956 if (!this->emitInitElem(ElemT, I, E))
5957 return false;
5958 }
5959 break;
5960
5961 case UO_Plus: // +x
5962 case UO_AddrOf: // &x
5963 case UO_Deref: // *x
5964 return this->delegate(SubExpr);
5965
5966 case UO_LNot:
5967 if (!this->visit(SubExpr))
5968 return false;
5969 if (!this->emitComplexBoolCast(SubExpr))
5970 return false;
5971 if (!this->emitInv(E))
5972 return false;
5973 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
5974 return this->emitCast(PT_Bool, ET, E);
5975 return true;
5976
5977 case UO_Real:
5978 return this->emitComplexReal(SubExpr);
5979
5980 case UO_Imag:
5981 if (!this->visit(SubExpr))
5982 return false;
5983
5984 if (SubExpr->isLValue()) {
5985 if (!this->emitConstUint8(1, E))
5986 return false;
5987 return this->emitArrayElemPtrPopUint8(E);
5988 }
5989
5990 // Since our _Complex implementation does not map to a primitive type,
5991 // we sometimes have to do the lvalue-to-rvalue conversion here manually.
5992 return this->emitArrayElemPop(classifyPrim(E->getType()), 1, E);
5993
5994 case UO_Not: // ~x
5995 if (!this->visit(SubExpr))
5996 return false;
5997 // Negate the imaginary component.
5998 if (!this->emitArrayElem(ElemT, 1, E))
5999 return false;
6000 if (!this->emitNeg(ElemT, E))
6001 return false;
6002 if (!this->emitInitElem(ElemT, 1, E))
6003 return false;
6004 return DiscardResult ? this->emitPopPtr(E) : true;
6005
6006 case UO_Extension:
6007 return this->delegate(SubExpr);
6008
6009 default:
6010 return this->emitInvalid(E);
6011 }
6012
6013 return true;
6014}
6015
6016template <class Emitter>
6018 const Expr *SubExpr = E->getSubExpr();
6019 assert(SubExpr->getType()->isVectorType());
6020
6021 if (DiscardResult)
6022 return this->discard(SubExpr);
6023
6024 auto UnaryOp = E->getOpcode();
6025 if (UnaryOp == UO_Extension)
6026 return this->delegate(SubExpr);
6027
6028 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
6029 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
6030 return this->emitInvalid(E);
6031
6032 // Nothing to do here.
6033 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
6034 return this->delegate(SubExpr);
6035
6036 if (!Initializing) {
6037 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
6038 if (!LocalIndex)
6039 return false;
6040 if (!this->emitGetPtrLocal(*LocalIndex, E))
6041 return false;
6042 }
6043
6044 // The offset of the temporary, if we created one.
6045 unsigned SubExprOffset =
6046 this->allocateLocalPrimitive(SubExpr, PT_Ptr, true, false);
6047 if (!this->visit(SubExpr))
6048 return false;
6049 if (!this->emitSetLocal(PT_Ptr, SubExprOffset, E))
6050 return false;
6051
6052 const auto *VecTy = SubExpr->getType()->getAs<VectorType>();
6053 PrimType ElemT = classifyVectorElementType(SubExpr->getType());
6054 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
6055 if (!this->emitGetLocal(PT_Ptr, Offset, E))
6056 return false;
6057 return this->emitArrayElemPop(ElemT, Index, E);
6058 };
6059
6060 switch (UnaryOp) {
6061 case UO_Minus:
6062 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6063 if (!getElem(SubExprOffset, I))
6064 return false;
6065 if (!this->emitNeg(ElemT, E))
6066 return false;
6067 if (!this->emitInitElem(ElemT, I, E))
6068 return false;
6069 }
6070 break;
6071 case UO_LNot: { // !x
6072 // In C++, the logic operators !, &&, || are available for vectors. !v is
6073 // equivalent to v == 0.
6074 //
6075 // The result of the comparison is a vector of the same width and number of
6076 // elements as the comparison operands with a signed integral element type.
6077 //
6078 // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
6079 QualType ResultVecTy = E->getType();
6080 PrimType ResultVecElemT =
6081 classifyPrim(ResultVecTy->getAs<VectorType>()->getElementType());
6082 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6083 if (!getElem(SubExprOffset, I))
6084 return false;
6085 // operator ! on vectors returns -1 for 'truth', so negate it.
6086 if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E))
6087 return false;
6088 if (!this->emitInv(E))
6089 return false;
6090 if (!this->emitPrimCast(PT_Bool, ElemT, VecTy->getElementType(), E))
6091 return false;
6092 if (!this->emitNeg(ElemT, E))
6093 return false;
6094 if (ElemT != ResultVecElemT &&
6095 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy, E))
6096 return false;
6097 if (!this->emitInitElem(ResultVecElemT, I, E))
6098 return false;
6099 }
6100 break;
6101 }
6102 case UO_Not: // ~x
6103 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6104 if (!getElem(SubExprOffset, I))
6105 return false;
6106 if (ElemT == PT_Bool) {
6107 if (!this->emitInv(E))
6108 return false;
6109 } else {
6110 if (!this->emitComp(ElemT, E))
6111 return false;
6112 }
6113 if (!this->emitInitElem(ElemT, I, E))
6114 return false;
6115 }
6116 break;
6117 default:
6118 llvm_unreachable("Unsupported unary operators should be handled up front");
6119 }
6120 return true;
6121}
6122
6123template <class Emitter>
6125 if (DiscardResult)
6126 return true;
6127
6128 if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
6129 return this->emitConst(ECD->getInitVal(), E);
6130 } else if (const auto *BD = dyn_cast<BindingDecl>(D)) {
6131 return this->visit(BD->getBinding());
6132 } else if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
6133 const Function *F = getFunction(FuncDecl);
6134 return F && this->emitGetFnPtr(F, E);
6135 } else if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
6136 if (std::optional<unsigned> Index = P.getOrCreateGlobal(D)) {
6137 if (!this->emitGetPtrGlobal(*Index, E))
6138 return false;
6139 if (std::optional<PrimType> T = classify(E->getType())) {
6140 if (!this->visitAPValue(TPOD->getValue(), *T, E))
6141 return false;
6142 return this->emitInitGlobal(*T, *Index, E);
6143 }
6144 return this->visitAPValueInitializer(TPOD->getValue(), E);
6145 }
6146 return false;
6147 }
6148
6149 // References are implemented via pointers, so when we see a DeclRefExpr
6150 // pointing to a reference, we need to get its value directly (i.e. the
6151 // pointer to the actual value) instead of a pointer to the pointer to the
6152 // value.
6153 bool IsReference = D->getType()->isReferenceType();
6154
6155 // Check for local/global variables and parameters.
6156 if (auto It = Locals.find(D); It != Locals.end()) {
6157 const unsigned Offset = It->second.Offset;
6158 if (IsReference)
6159 return this->emitGetLocal(PT_Ptr, Offset, E);
6160 return this->emitGetPtrLocal(Offset, E);
6161 } else if (auto GlobalIndex = P.getGlobal(D)) {
6162 if (IsReference) {
6163 if (!Ctx.getLangOpts().CPlusPlus11)
6164 return this->emitGetGlobal(classifyPrim(E), *GlobalIndex, E);
6165 return this->emitGetGlobalUnchecked(classifyPrim(E), *GlobalIndex, E);
6166 }
6167
6168 return this->emitGetPtrGlobal(*GlobalIndex, E);
6169 } else if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
6170 if (auto It = this->Params.find(PVD); It != this->Params.end()) {
6171 if (IsReference || !It->second.IsPtr)
6172 return this->emitGetParam(classifyPrim(E), It->second.Offset, E);
6173
6174 return this->emitGetPtrParam(It->second.Offset, E);
6175 }
6176
6177 if (D->getType()->isReferenceType())
6178 return false; // FIXME: Do we need to emit InvalidDeclRef?
6179 }
6180
6181 // In case we need to re-visit a declaration.
6182 auto revisit = [&](const VarDecl *VD) -> bool {
6183 auto VarState = this->visitDecl(VD);
6184
6185 if (VarState.notCreated())
6186 return true;
6187 if (!VarState)
6188 return false;
6189 // Retry.
6190 return this->visitDeclRef(D, E);
6191 };
6192
6193 // Handle lambda captures.
6194 if (auto It = this->LambdaCaptures.find(D);
6195 It != this->LambdaCaptures.end()) {
6196 auto [Offset, IsPtr] = It->second;
6197
6198 if (IsPtr)
6199 return this->emitGetThisFieldPtr(Offset, E);
6200 return this->emitGetPtrThisField(Offset, E);
6201 } else if (const auto *DRE = dyn_cast<DeclRefExpr>(E);
6202 DRE && DRE->refersToEnclosingVariableOrCapture()) {
6203 if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture())
6204 return revisit(VD);
6205 }
6206
6207 // Avoid infinite recursion.
6208 if (D == InitializingDecl)
6209 return this->emitDummyPtr(D, E);
6210
6211 // Try to lazily visit (or emit dummy pointers for) declarations
6212 // we haven't seen yet.
6213 // For C.
6214 if (!Ctx.getLangOpts().CPlusPlus) {
6215 if (const auto *VD = dyn_cast<VarDecl>(D);
6216 VD && VD->getAnyInitializer() &&
6217 VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak())
6218 return revisit(VD);
6219 return this->emitDummyPtr(D, E);
6220 }
6221
6222 // ... and C++.
6223 const auto *VD = dyn_cast<VarDecl>(D);
6224 if (!VD)
6225 return this->emitDummyPtr(D, E);
6226
6227 const auto typeShouldBeVisited = [&](QualType T) -> bool {
6228 if (T.isConstant(Ctx.getASTContext()))
6229 return true;
6230 return T->isReferenceType();
6231 };
6232
6233 // DecompositionDecls are just proxies for us.
6234 if (isa<DecompositionDecl>(VD))
6235 return revisit(VD);
6236
6237 if ((VD->hasGlobalStorage() || VD->isStaticDataMember()) &&
6238 typeShouldBeVisited(VD->getType())) {
6239 if (const Expr *Init = VD->getAnyInitializer();
6240 Init && !Init->isValueDependent()) {
6241 // Whether or not the evaluation is successul doesn't really matter
6242 // here -- we will create a global variable in any case, and that
6243 // will have the state of initializer evaluation attached.
6244 APValue V;
6246 (void)Init->EvaluateAsInitializer(V, Ctx.getASTContext(), VD, Notes,
6247 true);
6248 return this->visitDeclRef(D, E);
6249 }
6250 return revisit(VD);
6251 }
6252
6253 // FIXME: The evaluateValue() check here is a little ridiculous, since
6254 // it will ultimately call into Context::evaluateAsInitializer(). In
6255 // other words, we're evaluating the initializer, just to know if we can
6256 // evaluate the initializer.
6257 if (VD->isLocalVarDecl() && typeShouldBeVisited(VD->getType()) &&
6258 VD->getInit() && !VD->getInit()->isValueDependent()) {
6259
6260 if (VD->evaluateValue())
6261 return revisit(VD);
6262
6263 if (!D->getType()->isReferenceType())
6264 return this->emitDummyPtr(D, E);
6265
6266 return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
6267 /*InitializerFailed=*/true, E);
6268 }
6269
6270 return this->emitDummyPtr(D, E);
6271}
6272
6273template <class Emitter>
6275 const auto *D = E->getDecl();
6276 return this->visitDeclRef(D, E);
6277}
6278
6279template <class Emitter> void Compiler<Emitter>::emitCleanup() {
6280 for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent())
6281 C->emitDestruction();
6282}
6283
6284template <class Emitter>
6285unsigned Compiler<Emitter>::collectBaseOffset(const QualType BaseType,
6286 const QualType DerivedType) {
6287 const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
6288 if (const auto *R = Ty->getPointeeCXXRecordDecl())
6289 return R;
6290 return Ty->getAsCXXRecordDecl();
6291 };
6292 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
6293 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
6294
6295 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
6296}
6297
6298/// Emit casts from a PrimType to another PrimType.
6299template <class Emitter>
6301 QualType ToQT, const Expr *E) {
6302
6303 if (FromT == PT_Float) {
6304 // Floating to floating.
6305 if (ToT == PT_Float) {
6306 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6307 return this->emitCastFP(ToSem, getRoundingMode(E), E);
6308 }
6309
6310 if (ToT == PT_IntAP)
6311 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
6312 getFPOptions(E), E);
6313 if (ToT == PT_IntAPS)
6314 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
6315 getFPOptions(E), E);
6316
6317 // Float to integral.
6318 if (isIntegralType(ToT) || ToT == PT_Bool)
6319 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
6320 }
6321
6322 if (isIntegralType(FromT) || FromT == PT_Bool) {
6323 if (ToT == PT_IntAP)
6324 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
6325 if (ToT == PT_IntAPS)
6326 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
6327
6328 // Integral to integral.
6329 if (isIntegralType(ToT) || ToT == PT_Bool)
6330 return FromT != ToT ? this->emitCast(FromT, ToT, E) : true;
6331
6332 if (ToT == PT_Float) {
6333 // Integral to floating.
6334 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6335 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E);
6336 }
6337 }
6338
6339 return false;
6340}
6341
6342/// Emits __real(SubExpr)
6343template <class Emitter>
6344bool Compiler<Emitter>::emitComplexReal(const Expr *SubExpr) {
6345 assert(SubExpr->getType()->isAnyComplexType());
6346
6347 if (DiscardResult)
6348 return this->discard(SubExpr);
6349
6350 if (!this->visit(SubExpr))
6351 return false;
6352 if (SubExpr->isLValue()) {
6353 if (!this->emitConstUint8(0, SubExpr))
6354 return false;
6355 return this->emitArrayElemPtrPopUint8(SubExpr);
6356 }
6357
6358 // Rvalue, load the actual element.
6359 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->getType()),
6360 0, SubExpr);
6361}
6362
6363template <class Emitter>
6365 assert(!DiscardResult);
6366 PrimType ElemT = classifyComplexElementType(E->getType());
6367 // We emit the expression (__real(E) != 0 || __imag(E) != 0)
6368 // for us, that means (bool)E[0] || (bool)E[1]
6369 if (!this->emitArrayElem(ElemT, 0, E))
6370 return false;
6371 if (ElemT == PT_Float) {
6372 if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
6373 return false;
6374 } else {
6375 if (!this->emitCast(ElemT, PT_Bool, E))
6376 return false;
6377 }
6378
6379 // We now have the bool value of E[0] on the stack.
6380 LabelTy LabelTrue = this->getLabel();
6381 if (!this->jumpTrue(LabelTrue))
6382 return false;
6383
6384 if (!this->emitArrayElemPop(ElemT, 1, E))
6385 return false;
6386 if (ElemT == PT_Float) {
6387 if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
6388 return false;
6389 } else {
6390 if (!this->emitCast(ElemT, PT_Bool, E))
6391 return false;
6392 }
6393 // Leave the boolean value of E[1] on the stack.
6394 LabelTy EndLabel = this->getLabel();
6395 this->jump(EndLabel);
6396
6397 this->emitLabel(LabelTrue);
6398 if (!this->emitPopPtr(E))
6399 return false;
6400 if (!this->emitConstBool(true, E))
6401 return false;
6402
6403 this->fallthrough(EndLabel);
6404 this->emitLabel(EndLabel);
6405
6406 return true;
6407}
6408
6409template <class Emitter>
6410bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS,
6411 const BinaryOperator *E) {
6412 assert(E->isComparisonOp());
6413 assert(!Initializing);
6414 assert(!DiscardResult);
6415
6416 PrimType ElemT;
6417 bool LHSIsComplex;
6418 unsigned LHSOffset;
6419 if (LHS->getType()->isAnyComplexType()) {
6420 LHSIsComplex = true;
6421 ElemT = classifyComplexElementType(LHS->getType());
6422 LHSOffset = allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true,
6423 /*IsExtended=*/false);
6424 if (!this->visit(LHS))
6425 return false;
6426 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
6427 return false;
6428 } else {
6429 LHSIsComplex = false;
6430 PrimType LHST = classifyPrim(LHS->getType());
6431 LHSOffset = this->allocateLocalPrimitive(LHS, LHST, true, false);
6432 if (!this->visit(LHS))
6433 return false;
6434 if (!this->emitSetLocal(LHST, LHSOffset, E))
6435 return false;
6436 }
6437
6438 bool RHSIsComplex;
6439 unsigned RHSOffset;
6440 if (RHS->getType()->isAnyComplexType()) {
6441 RHSIsComplex = true;
6442 ElemT = classifyComplexElementType(RHS->getType());
6443 RHSOffset = allocateLocalPrimitive(RHS, PT_Ptr, /*IsConst=*/true,
6444 /*IsExtended=*/false);
6445 if (!this->visit(RHS))
6446 return false;
6447 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
6448 return false;
6449 } else {
6450 RHSIsComplex = false;
6451 PrimType RHST = classifyPrim(RHS->getType());
6452 RHSOffset = this->allocateLocalPrimitive(RHS, RHST, true, false);
6453 if (!this->visit(RHS))
6454 return false;
6455 if (!this->emitSetLocal(RHST, RHSOffset, E))
6456 return false;
6457 }
6458
6459 auto getElem = [&](unsigned LocalOffset, unsigned Index,
6460 bool IsComplex) -> bool {
6461 if (IsComplex) {
6462 if (!this->emitGetLocal(PT_Ptr, LocalOffset, E))
6463 return false;
6464 return this->emitArrayElemPop(ElemT, Index, E);
6465 }
6466 return this->emitGetLocal(ElemT, LocalOffset, E);
6467 };
6468
6469 for (unsigned I = 0; I != 2; ++I) {
6470 // Get both values.
6471 if (!getElem(LHSOffset, I, LHSIsComplex))
6472 return false;
6473 if (!getElem(RHSOffset, I, RHSIsComplex))
6474 return false;
6475 // And compare them.
6476 if (!this->emitEQ(ElemT, E))
6477 return false;
6478
6479 if (!this->emitCastBoolUint8(E))
6480 return false;
6481 }
6482
6483 // We now have two bool values on the stack. Compare those.
6484 if (!this->emitAddUint8(E))
6485 return false;
6486 if (!this->emitConstUint8(2, E))
6487 return false;
6488
6489 if (E->getOpcode() == BO_EQ) {
6490 if (!this->emitEQUint8(E))
6491 return false;
6492 } else if (E->getOpcode() == BO_NE) {
6493 if (!this->emitNEUint8(E))
6494 return false;
6495 } else
6496 return false;
6497
6498 // In C, this returns an int.
6499 if (PrimType ResT = classifyPrim(E->getType()); ResT != PT_Bool)
6500 return this->emitCast(PT_Bool, ResT, E);
6501 return true;
6502}
6503
6504/// When calling this, we have a pointer of the local-to-destroy
6505/// on the stack.
6506/// Emit destruction of record types (or arrays of record types).
6507template <class Emitter>
6509 assert(R);
6510 assert(!R->isAnonymousUnion());
6511 const CXXDestructorDecl *Dtor = R->getDestructor();
6512 if (!Dtor || Dtor->isTrivial())
6513 return true;
6514
6515 assert(Dtor);
6516 const Function *DtorFunc = getFunction(Dtor);
6517 if (!DtorFunc)
6518 return false;
6519 assert(DtorFunc->hasThisPointer());
6520 assert(DtorFunc->getNumParams() == 1);
6521 if (!this->emitDupPtr(Loc))
6522 return false;
6523 return this->emitCall(DtorFunc, 0, Loc);
6524}
6525/// When calling this, we have a pointer of the local-to-destroy
6526/// on the stack.
6527/// Emit destruction of record types (or arrays of record types).
6528template <class Emitter>
6530 SourceInfo Loc) {
6531 assert(Desc);
6532 assert(!Desc->isPrimitive());
6533 assert(!Desc->isPrimitiveArray());
6534
6535 // Arrays.
6536 if (Desc->isArray()) {
6537 const Descriptor *ElemDesc = Desc->ElemDesc;
6538 assert(ElemDesc);
6539
6540 // Don't need to do anything for these.
6541 if (ElemDesc->isPrimitiveArray())
6542 return true;
6543
6544 // If this is an array of record types, check if we need
6545 // to call the element destructors at all. If not, try
6546 // to save the work.
6547 if (const Record *ElemRecord = ElemDesc->ElemRecord) {
6548 if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
6549 !Dtor || Dtor->isTrivial())
6550 return true;
6551 }
6552
6553 for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) {
6554 if (!this->emitConstUint64(I, Loc))
6555 return false;
6556 if (!this->emitArrayElemPtrUint64(Loc))
6557 return false;
6558 if (!this->emitDestruction(ElemDesc, Loc))
6559 return false;
6560 if (!this->emitPopPtr(Loc))
6561 return false;
6562 }
6563 return true;
6564 }
6565
6566 assert(Desc->ElemRecord);
6567 if (Desc->ElemRecord->isAnonymousUnion())
6568 return true;
6569
6570 return this->emitRecordDestruction(Desc->ElemRecord, Loc);
6571}
6572
6573/// Create a dummy pointer for the given decl (or expr) and
6574/// push a pointer to it on the stack.
6575template <class Emitter>
6576bool Compiler<Emitter>::emitDummyPtr(const DeclTy &D, const Expr *E) {
6577 assert(!DiscardResult && "Should've been checked before");
6578
6579 unsigned DummyID = P.getOrCreateDummy(D);
6580
6581 if (!this->emitGetPtrGlobal(DummyID, E))
6582 return false;
6583 if (E->getType()->isVoidType())
6584 return true;
6585
6586 // Convert the dummy pointer to another pointer type if we have to.
6587 if (PrimType PT = classifyPrim(E); PT != PT_Ptr) {
6588 if (isPtrType(PT))
6589 return this->emitDecayPtr(PT_Ptr, PT, E);
6590 return false;
6591 }
6592 return true;
6593}
6594
6595// This function is constexpr if and only if To, From, and the types of
6596// all subobjects of To and From are types T such that...
6597// (3.1) - is_union_v<T> is false;
6598// (3.2) - is_pointer_v<T> is false;
6599// (3.3) - is_member_pointer_v<T> is false;
6600// (3.4) - is_volatile_v<T> is false; and
6601// (3.5) - T has no non-static data members of reference type
6602template <class Emitter>
6604 const Expr *SubExpr = E->getSubExpr();
6605 QualType FromType = SubExpr->getType();
6606 QualType ToType = E->getType();
6607 std::optional<PrimType> ToT = classify(ToType);
6608
6609 assert(!ToType->isReferenceType());
6610
6611 // Prepare storage for the result in case we discard.
6612 if (DiscardResult && !Initializing && !ToT) {
6613 std::optional<unsigned> LocalIndex = allocateLocal(E);
6614 if (!LocalIndex)
6615 return false;
6616 if (!this->emitGetPtrLocal(*LocalIndex, E))
6617 return false;
6618 }
6619
6620 // Get a pointer to the value-to-cast on the stack.
6621 // For CK_LValueToRValueBitCast, this is always an lvalue and
6622 // we later assume it to be one (i.e. a PT_Ptr). However,
6623 // we call this function for other utility methods where
6624 // a bitcast might be useful, so convert it to a PT_Ptr in that case.
6625 if (SubExpr->isGLValue() || FromType->isVectorType()) {
6626 if (!this->visit(SubExpr))
6627 return false;
6628 } else if (std::optional<PrimType> FromT = classify(SubExpr)) {
6629 unsigned TempOffset = allocateLocalPrimitive(
6630 SubExpr, *FromT, /*IsConst=*/true, /*IsExtended=*/false);
6631 if (!this->visit(SubExpr))
6632 return false;
6633 if (!this->emitSetLocal(*FromT, TempOffset, E))
6634 return false;
6635 if (!this->emitGetPtrLocal(TempOffset, E))
6636 return false;
6637 } else {
6638 return false;
6639 }
6640
6641 if (!ToT) {
6642 if (!this->emitBitCast(E))
6643 return false;
6644 return DiscardResult ? this->emitPopPtr(E) : true;
6645 }
6646 assert(ToT);
6647
6648 const llvm::fltSemantics *TargetSemantics = nullptr;
6649 if (ToT == PT_Float)
6650 TargetSemantics = &Ctx.getFloatSemantics(ToType);
6651
6652 // Conversion to a primitive type. FromType can be another
6653 // primitive type, or a record/array.
6654 bool ToTypeIsUChar = (ToType->isSpecificBuiltinType(BuiltinType::UChar) ||
6655 ToType->isSpecificBuiltinType(BuiltinType::Char_U));
6656 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
6657
6658 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->isStdByteType(),
6659 ResultBitWidth, TargetSemantics, E))
6660 return false;
6661
6662 if (DiscardResult)
6663 return this->emitPop(*ToT, E);
6664
6665 return true;
6666}
6667
6668namespace clang {
6669namespace interp {
6670
6671template class Compiler<ByteCodeEmitter>;
6672template class Compiler<EvalEmitter>;
6673
6674} // namespace interp
6675} // namespace clang
#define V(N, I)
Definition: ASTContext.h:3460
ASTImporterLookupTable & LT
DynTypedNode Node
StringRef P
const Decl * D
Expr * E
#define EMIT_ARITH_OP(OP)
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
Definition: Compiler.cpp:2028
llvm::APSInt APSInt
Definition: Compiler.cpp:23
bool IsStatic
Definition: Format.cpp:3065
SourceLocation Loc
Definition: SemaObjC.cpp:759
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
const LValueBase getLValueBase() const
Definition: APValue.cpp:973
APValue & getArrayInitializedElt(unsigned I)
Definition: APValue.h:552
ArrayRef< LValuePathEntry > getLValuePath() const
Definition: APValue.cpp:993
APSInt & getInt()
Definition: APValue.h:465
APValue & getStructField(unsigned i)
Definition: APValue.h:593
const FieldDecl * getUnionField() const
Definition: APValue.h:605
unsigned getStructNumFields() const
Definition: APValue.h:584
bool isArray() const
Definition: APValue.h:450
bool isFloat() const
Definition: APValue.h:444
const ValueDecl * getMemberPointerDecl() const
Definition: APValue.cpp:1056
APValue & getUnionValue()
Definition: APValue.h:609
bool isLValue() const
Definition: APValue.h:448
bool isMemberPointer() const
Definition: APValue.h:453
bool isInt() const
Definition: APValue.h:443
unsigned getArraySize() const
Definition: APValue.h:575
bool isUnion() const
Definition: APValue.h:452
@ None
There is no such object (it's outside its lifetime).
Definition: APValue.h:129
bool isStruct() const
Definition: APValue.h:451
bool isNullPointer() const
Definition: APValue.cpp:1009
APFloat & getFloat()
Definition: APValue.h:479
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
const ConstantArrayType * getAsConstantArrayType(QualType T) const
Definition: ASTContext.h:2922
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
Definition: ASTContext.h:2580
const LangOptions & getLangOpts() const
Definition: ASTContext.h:834
ComparisonCategories CompCategories
Types and expressions required to build C++2a three-way comparisons using operator<=>,...
Definition: ASTContext.h:2420
CanQualType BoolTy
Definition: ASTContext.h:1161
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
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.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
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:4224
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition: Expr.h:4421
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition: Expr.h:5805
Represents a loop initializing the elements of an array.
Definition: Expr.h:5752
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2718
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition: ExprCXX.h:2853
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3577
QualType getElementType() const
Definition: Type.h:3589
Attr - This represents one attribute.
Definition: Attr.h:43
Represents an attribute applied to a statement.
Definition: Stmt.h:2107
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3909
static bool isLogicalOp(Opcode Opc)
Definition: Expr.h:4042
Expr * getLHS() const
Definition: Expr.h:3959
static bool isComparisonOp(Opcode Opc)
Definition: Expr.h:4009
static bool isCommaOp(Opcode Opc)
Definition: Expr.h:4012
static Opcode getOpForCompoundAssignment(Opcode Opc)
Definition: Expr.h:4056
Expr * getRHS() const
Definition: Expr.h:3961
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
Definition: Expr.h:3986
Opcode getOpcode() const
Definition: Expr.h:3954
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6414
BreakStmt - This represents a break.
Definition: Stmt.h:3007
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1491
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition: ExprCXX.h:720
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1546
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2553
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
Definition: DeclCXX.cpp:2904
A default argument (C++ [dcl.fct.default]).
Definition: ExprCXX.h:1268
A use of a default initializer in a constructor or in aggregate initialization.
Definition: ExprCXX.h:1375
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition: ExprCXX.h:2498
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2817
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Definition: StmtCXX.h:135
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition: ExprCXX.h:1737
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2078
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition: DeclCXX.h:2204
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
Definition: DeclCXX.cpp:2732
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition: ExprCXX.h:2241
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition: ExprCXX.h:4126
The null pointer literal (C++11 [lex.nullptr])
Definition: ExprCXX.h:765
Represents a list-initialization with parenthesis.
Definition: ExprCXX.h:4960
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
capture_const_iterator captures_end() const
Definition: DeclCXX.h:1119
capture_const_iterator captures_begin() const
Definition: DeclCXX.h:1113
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
Definition: DeclCXX.cpp:1700
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
An expression "T()" which creates an rvalue of a non-class type T.
Definition: ExprCXX.h:2182
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Definition: ExprCXX.h:797
Represents the this expression in C++.
Definition: ExprCXX.h:1152
A C++ throw-expression (C++ [except.throw]).
Definition: ExprCXX.h:1206
CXXTryStmt - A C++ try block, including all handlers.
Definition: StmtCXX.h:69
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition: ExprCXX.h:845
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Definition: ExprCXX.h:1066
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2874
CaseStmt - Represent a case statement.
Definition: Stmt.h:1828
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3547
CastKind getCastKind() const
Definition: Expr.h:3591
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
Definition: Expr.h:3634
Expr * getSubExpr()
Definition: Expr.h:3597
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
static CharUnits One()
One - Construct a CharUnits quantity of one.
Definition: CharUnits.h:58
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition: Expr.h:4641
const ComparisonCategoryInfo * lookupInfoForType(QualType Ty) const
Complex values, per C99 6.2.5p11.
Definition: Type.h:3145
QualType getElementType() const
Definition: Type.h:3155
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4171
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3477
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1628
body_range body()
Definition: Stmt.h:1691
Stmt * getStmtExprResult()
Definition: Stmt.h:1750
Represents the specialization of a concept - evaluates to a prvalue of type bool.
Definition: ExprConcepts.h:42
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3615
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
Definition: Type.h:3691
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition: Expr.h:1077
ContinueStmt - This represents a continue.
Definition: Stmt.h:2977
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition: Expr.h:4582
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2104
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1265
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1519
decl_range decls()
Definition: Stmt.h:1567
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
bool isInvalidDecl() const
Definition: DeclBase.h:591
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
DoStmt - This represents a 'do/while' stmt.
Definition: Stmt.h:2752
Represents a reference to #emded data.
Definition: Expr.h:4916
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
Definition: Decl.h:4075
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:6103
EnumDecl * getDecl() const
Definition: Type.h:6110
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3474
This represents one expression.
Definition: Expr.h:110
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
Definition: Expr.cpp:82
bool isGLValue() const
Definition: Expr.h:280
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition: Expr.h:175
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3093
bool isPRValue() const
Definition: Expr.h:278
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 HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
Definition: Expr.cpp:3594
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
Definition: Expr.cpp:3231
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:2924
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Definition: Expr.h:6354
Represents a member of a struct/union/class.
Definition: Decl.h:3033
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Definition: Decl.h:3264
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
Definition: Decl.h:3139
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition: Stmt.h:2808
Represents a function declaration or definition.
Definition: Decl.h:1935
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2672
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition: Decl.cpp:3243
QualType getReturnType() const
Definition: Decl.h:2720
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2649
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition: Decl.h:2305
bool isReplaceableGlobalAllocationFunction(std::optional< unsigned > *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
Definition: Decl.cpp:3372
bool isDefaulted() const
Whether this function is defaulted.
Definition: Decl.h:2313
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition: Decl.cpp:3702
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Definition: Decl.cpp:3163
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition: Expr.h:4716
Represents a C11 generic selection.
Definition: Expr.h:5966
IfStmt - This represents an if/then/else.
Definition: Stmt.h:2165
Stmt * getThen()
Definition: Stmt.h:2254
Stmt * getInit()
Definition: Stmt.h:2315
bool isNonNegatedConsteval() const
Definition: Stmt.h:2350
Expr * getCond()
Definition: Stmt.h:2242
bool isNegatedConsteval() const
Definition: Stmt.h:2354
Stmt * getElse()
Definition: Stmt.h:2263
DeclStmt * getConditionVariableDeclStmt()
If this IfStmt has a condition variable, return the faux DeclStmt associated with the creation of tha...
Definition: Stmt.h:2298
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition: Expr.h:1717
Represents an implicitly-generated value initialization of an object of a given type.
Definition: Expr.h:5841
Represents a field injected from an anonymous union/struct into the parent scope.
Definition: Decl.h:3335
Describes an C or C++ initializer list.
Definition: Expr.h:5088
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1954
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
Definition: DeclCXX.h:3252
A global _GUID constant.
Definition: DeclCXX.h:4312
APValue & getAsAPValue() const
Get the value of this MSGuidDecl as an APValue.
Definition: DeclCXX.cpp:3622
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition: ExprCXX.h:4734
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3236
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:3519
const Type * getClass() const
Definition: Type.h:3549
This represents a decl that may have a name.
Definition: Decl.h:253
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:319
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition: ExprObjC.h:87
ObjCBoxedExpr - used for generalized expression boxing.
Definition: ExprObjC.h:127
ObjCEncodeExpr, used for @encode in Objective-C.
Definition: ExprObjC.h:410
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition: ExprObjC.h:51
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition: Expr.h:2519
Helper class for OffsetOfExpr.
Definition: Expr.h:2413
@ Array
An index into an array.
Definition: Expr.h:2418
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1173
ParenExpr - This represents a parenthesized expression, e.g.
Definition: Expr.h:2170
Represents a parameter to a function.
Definition: Decl.h:1725
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3198
QualType getPointeeType() const
Definition: Type.h:3208
[C99 6.4.2.2] - A predefined identifier such as func.
Definition: Expr.h:1991
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:6546
A (possibly-)qualified type.
Definition: Type.h:929
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:996
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:7936
QualType getCanonicalType() const
Definition: Type.h:7988
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:8009
Represents a struct/union/class.
Definition: Decl.h:4162
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:6077
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Definition: Expr.h:7258
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3439
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Definition: ExprConcepts.h:502
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:3046
Expr * getRetValue()
Definition: Stmt.h:3077
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:41
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Definition: Expr.h:4514
Represents an expression that computes the length of a parameter pack.
Definition: ExprCXX.h:4258
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition: Expr.h:4810
Represents a C++11 static_assert declaration.
Definition: DeclCXX.h:4081
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition: Expr.h:4466
Stmt - This represents one statement.
Definition: Stmt.h:84
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1778
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:1194
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4490
SwitchStmt - This represents a 'switch' stmt.
Definition: Stmt.h:2415
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3578
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3681
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition: ExprCXX.h:2768
The base class of the type hierarchy.
Definition: Type.h:1828
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1916
bool isVoidType() const
Definition: Type.h:8515
bool isBooleanType() const
Definition: Type.h:8643
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
Definition: Type.cpp:2937
bool isIncompleteArrayType() const
Definition: Type.h:8271
bool isNothrowT() const
Definition: Type.cpp:3106
bool isVoidPointerType() const
Definition: Type.cpp:698
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
Definition: Type.cpp:2386
bool isArrayType() const
Definition: Type.h:8263
bool isPointerType() const
Definition: Type.h:8191
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:8555
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8805
bool isReferenceType() const
Definition: Type.h:8209
bool isEnumeralType() const
Definition: Type.h:8295
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:738
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:8630
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Definition: Type.h:8484
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2706
bool isAnyComplexType() const
Definition: Type.h:8299
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
Definition: Type.h:8568
bool isMemberPointerType() const
Definition: Type.h:8245
bool isAtomicType() const
Definition: Type.h:8346
bool isStdByteType() const
Definition: Type.cpp:3124
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition: Type.h:8791
bool isPointerOrReferenceType() const
Definition: Type.h:8195
bool isFunctionType() const
Definition: Type.h:8187
bool isVectorType() const
Definition: Type.h:8303
bool isFloatingType() const
Definition: Type.cpp:2283
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8736
bool isRecordType() const
Definition: Type.h:8291
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition: Type.cpp:1920
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3427
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2622
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2232
Represents a C++ using-enum-declaration.
Definition: DeclCXX.h:3736
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:671
QualType getType() const
Definition: Decl.h:682
QualType getType() const
Definition: Value.cpp:234
Represents a variable declaration or definition.
Definition: Decl.h:882
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition: Decl.h:1159
const Expr * getInit() const
Definition: Decl.h:1319
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
Definition: Decl.h:1204
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Definition: Decl.h:1309
Represents a GCC generic vector type.
Definition: Type.h:4034
unsigned getNumElements() const
Definition: Type.h:4049
QualType getElementType() const
Definition: Type.h:4048
WhileStmt - This represents a 'while' stmt.
Definition: Stmt.h:2611
Scope for storage declared in a compound statement.
Definition: Compiler.h:589
A memory block, either on the stack or in the heap.
Definition: InterpBlock.h:49
void invokeDtor()
Invokes the Destructor.
Definition: InterpBlock.h:123
std::byte * rawData()
Returns a pointer to the raw data, including metadata.
Definition: InterpBlock.h:104
Compilation context for expressions.
Definition: Compiler.h:108
OptLabelTy BreakLabel
Point to break to.
Definition: Compiler.h:427
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E)
Definition: Compiler.cpp:2215
bool VisitCXXDeleteExpr(const CXXDeleteExpr *E)
Definition: Compiler.cpp:3419
bool VisitOffsetOfExpr(const OffsetOfExpr *E)
Definition: Compiler.cpp:3138
bool visitContinueStmt(const ContinueStmt *S)
Definition: Compiler.cpp:5289
bool VisitCharacterLiteral(const CharacterLiteral *E)
Definition: Compiler.cpp:2432
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
Definition: Compiler.cpp:1995
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E)
Definition: Compiler.cpp:3529
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
Definition: Compiler.cpp:2765
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
Definition: Compiler.cpp:3854
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
Definition: Compiler.cpp:4810
bool visitDeclAndReturn(const VarDecl *VD, bool ConstantContext) override
Toplevel visitDeclAndReturn().
Definition: Compiler.cpp:4298
bool VisitTypeTraitExpr(const TypeTraitExpr *E)
Definition: Compiler.cpp:2830
bool VisitLambdaExpr(const LambdaExpr *E)
Definition: Compiler.cpp:2846
bool VisitMemberExpr(const MemberExpr *E)
Definition: Compiler.cpp:2159
bool VisitBinaryOperator(const BinaryOperator *E)
Definition: Compiler.cpp:796
bool visitAttributedStmt(const AttributedStmt *S)
Definition: Compiler.cpp:5384
bool VisitPackIndexingExpr(const PackIndexingExpr *E)
Definition: Compiler.cpp:3568
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
Definition: Compiler.cpp:1693
bool VisitCallExpr(const CallExpr *E)
Definition: Compiler.cpp:4609
bool VisitPseudoObjectExpr(const PseudoObjectExpr *E)
Definition: Compiler.cpp:3544
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E)
Definition: Compiler.cpp:2906
const Function * getFunction(const FunctionDecl *FD)
Returns a function for the given FunctionDecl.
Definition: Compiler.cpp:4212
void emitCleanup()
Emits scope cleanup instructions.
Definition: Compiler.cpp:6279
bool VisitFixedPointBinOp(const BinaryOperator *E)
Definition: Compiler.cpp:1525
bool VisitCastExpr(const CastExpr *E)
Definition: Compiler.cpp:195
bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E)
Definition: Compiler.cpp:2397
bool VisitFixedPointUnaryOperator(const UnaryOperator *E)
Definition: Compiler.cpp:1610
bool VisitComplexUnaryOperator(const UnaryOperator *E)
Definition: Compiler.cpp:5910
llvm::DenseMap< const SwitchCase *, LabelTy > CaseMap
Definition: Compiler.h:114
bool visitDeclStmt(const DeclStmt *DS)
Definition: Compiler.cpp:4977
bool VisitBlockExpr(const BlockExpr *E)
Definition: Compiler.cpp:3435
bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E)
Visit an APValue.
Definition: Compiler.cpp:4470
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
Definition: Compiler.cpp:3173
bool VisitLogicalBinOp(const BinaryOperator *E)
Definition: Compiler.cpp:1057
bool visitCompoundStmt(const CompoundStmt *S)
Definition: Compiler.cpp:4968
bool visitDeclRef(const ValueDecl *D, const Expr *E)
Visit the given decl as if we have a reference to it.
Definition: Compiler.cpp:6124
bool visitBreakStmt(const BreakStmt *S)
Definition: Compiler.cpp:5278
bool visitExpr(const Expr *E, bool DestroyToplevelScope) override
Definition: Compiler.cpp:4217
bool visitForStmt(const ForStmt *S)
Definition: Compiler.cpp:5171
bool VisitDeclRefExpr(const DeclRefExpr *E)
Definition: Compiler.cpp:6274
bool VisitOpaqueValueExpr(const OpaqueValueExpr *E)
Definition: Compiler.cpp:2254
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E)
Definition: Compiler.cpp:2224
OptLabelTy DefaultLabel
Default case label.
Definition: Compiler.h:433
bool VisitStmtExpr(const StmtExpr *E)
Definition: Compiler.cpp:3783
std::optional< unsigned > allocateLocal(DeclTy &&Decl, QualType Ty=QualType(), const ValueDecl *ExtendingDecl=nullptr)
Allocates a space storing a local given its type.
Definition: Compiler.cpp:4131
bool VisitFixedPointLiteral(const FixedPointLiteral *E)
Definition: Compiler.cpp:778
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
Definition: Compiler.cpp:4824
VariableScope< Emitter > * VarScope
Current scope.
Definition: Compiler.h:397
VariableScope< Emitter > * ContinueVarScope
Scope to cleanup until when we see a continue statement.
Definition: Compiler.h:429
bool VisitCXXNewExpr(const CXXNewExpr *E)
Definition: Compiler.cpp:3287
bool VisitCompoundAssignOperator(const CompoundAssignOperator *E)
Definition: Compiler.cpp:2549
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init)
Pointer to the array(not the element!) must be on the stack when calling this.
Definition: Compiler.cpp:1968
bool delegate(const Expr *E)
Just pass evaluation on to E.
Definition: Compiler.cpp:3811
bool discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
Definition: Compiler.cpp:3805
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
Definition: Compiler.cpp:4817
CaseMap CaseLabels
Switch case mapping.
Definition: Compiler.h:422
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
Definition: Compiler.cpp:4200
bool visit(const Expr *E)
Evaluates an expression and places the result on the stack.
Definition: Compiler.cpp:3818
const RecordType * getRecordTy(QualType Ty)
Returns a record type from a record or pointer type.
Definition: Compiler.cpp:4194
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E)
Definition: Compiler.cpp:3744
bool visitInitList(ArrayRef< const Expr * > Inits, const Expr *ArrayFiller, const Expr *E)
Definition: Compiler.cpp:1723
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E)
Definition: Compiler.cpp:3232
bool VisitPredefinedExpr(const PredefinedExpr *E)
Definition: Compiler.cpp:2885
bool VisitSourceLocExpr(const SourceLocExpr *E)
Definition: Compiler.cpp:3082
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E)
Definition: Compiler.cpp:3669
bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
Definition: Compiler.cpp:2390
bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E)
Definition: Compiler.cpp:2839
bool visitInitializer(const Expr *E)
Compiles an initializer.
Definition: Compiler.cpp:3846
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E)
Definition: Compiler.cpp:2759
bool VisitPointerArithBinOp(const BinaryOperator *E)
Perform addition/subtraction of a pointer and an integer or subtraction of two pointers.
Definition: Compiler.cpp:980
bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E)
Definition: Compiler.cpp:3248
bool visitDefaultStmt(const DefaultStmt *S)
Definition: Compiler.cpp:5378
typename Emitter::LabelTy LabelTy
Definition: Compiler.h:111
VarCreationState visitDecl(const VarDecl *VD)
Definition: Compiler.cpp:4270
bool visitStmt(const Stmt *S)
Definition: Compiler.cpp:4918
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
Definition: Compiler.cpp:3481
bool visitAPValueInitializer(const APValue &Val, const Expr *E)
Definition: Compiler.cpp:4497
bool VisitVectorUnaryOperator(const UnaryOperator *E)
Definition: Compiler.cpp:6017
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
Definition: Compiler.cpp:2962
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
Definition: Compiler.cpp:4832
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
Definition: Compiler.cpp:3731
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
Definition: Compiler.cpp:3256
bool VisitRecoveryExpr(const RecoveryExpr *E)
Definition: Compiler.cpp:3573
bool VisitRequiresExpr(const RequiresExpr *E)
Definition: Compiler.cpp:3521
bool visitReturnStmt(const ReturnStmt *RS)
Definition: Compiler.cpp:5003
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
Definition: Compiler.cpp:2898
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
Definition: Compiler.cpp:2001
bool VisitChooseExpr(const ChooseExpr *E)
Definition: Compiler.cpp:3243
bool visitFunc(const FunctionDecl *F) override
Definition: Compiler.cpp:5653
bool visitCXXForRangeStmt(const CXXForRangeStmt *S)
Definition: Compiler.cpp:5222
bool visitCaseStmt(const CaseStmt *S)
Definition: Compiler.cpp:5372
bool VisitComplexBinOp(const BinaryOperator *E)
Definition: Compiler.cpp:1118
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
Definition: Compiler.cpp:2290
bool VisitCXXTypeidExpr(const CXXTypeidExpr *E)
Definition: Compiler.cpp:3449
bool VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinID)
Definition: Compiler.cpp:4560
OptLabelTy ContinueLabel
Point to continue to.
Definition: Compiler.h:431
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
Definition: Compiler.cpp:1629
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
Definition: Compiler.cpp:3538
bool VisitUnaryOperator(const UnaryOperator *E)
Definition: Compiler.cpp:5679
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
Definition: Compiler.cpp:2439
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
Definition: Compiler.cpp:3237
bool visitDoStmt(const DoStmt *S)
Definition: Compiler.cpp:5138
bool VisitIntegerLiteral(const IntegerLiteral *E)
Definition: Compiler.cpp:740
bool VisitInitListExpr(const InitListExpr *E)
Definition: Compiler.cpp:1990
bool VisitVectorBinOp(const BinaryOperator *E)
Definition: Compiler.cpp:1341
bool VisitStringLiteral(const StringLiteral *E)
Definition: Compiler.cpp:2333
bool VisitParenExpr(const ParenExpr *E)
Definition: Compiler.cpp:791
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
Definition: Compiler.cpp:2953
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
Definition: Compiler.cpp:3626
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
Definition: Compiler.cpp:2512
VariableScope< Emitter > * BreakVarScope
Scope to cleanup until when we see a break statement.
Definition: Compiler.h:425
std::optional< LabelTy > OptLabelTy
Definition: Compiler.h:113
bool VisitEmbedExpr(const EmbedExpr *E)
Definition: Compiler.cpp:2023
bool VisitConvertVectorExpr(const ConvertVectorExpr *E)
Definition: Compiler.cpp:3588
bool VisitCXXThisExpr(const CXXThisExpr *E)
Definition: Compiler.cpp:4853
bool VisitConstantExpr(const ConstantExpr *E)
Definition: Compiler.cpp:2007
unsigned allocateTemporary(const Expr *E)
Definition: Compiler.cpp:4173
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
Definition: Compiler.cpp:2052
bool visitSwitchStmt(const SwitchStmt *S)
Definition: Compiler.cpp:5300
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E)
Definition: Compiler.cpp:3487
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsExtended=false)
Creates a local primitive value.
Definition: Compiler.cpp:4106
bool VisitExprWithCleanups(const ExprWithCleanups *E)
Definition: Compiler.cpp:2672
bool visitWhileStmt(const WhileStmt *S)
Definition: Compiler.cpp:5102
bool visitIfStmt(const IfStmt *IS)
Definition: Compiler.cpp:5038
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
Definition: Compiler.cpp:3578
bool VisitFloatingLiteral(const FloatingLiteral *E)
Definition: Compiler.cpp:748
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
Definition: Compiler.cpp:2680
bool VisitGNUNullExpr(const GNUNullExpr *E)
Definition: Compiler.cpp:4842
bool VisitImaginaryLiteral(const ImaginaryLiteral *E)
Definition: Compiler.cpp:756
bool VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E)
Definition: Compiler.cpp:2408
VarCreationState visitVarDecl(const VarDecl *VD, bool Toplevel=false)
Creates and initializes a variable from the given decl.
Definition: Compiler.cpp:4359
bool visitCXXTryStmt(const CXXTryStmt *S)
Definition: Compiler.cpp:5415
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Definition: Context.h:98
Scope used to handle temporaries in toplevel variable declarations.
Definition: Compiler.cpp:29
void addExtended(const Scope::Local &Local) override
Definition: Compiler.cpp:38
DeclScope(Compiler< Emitter > *Ctx, const ValueDecl *VD)
Definition: Compiler.cpp:31
Wrapper around fixed point types.
Definition: FixedPoint.h:23
static FixedPoint zero(llvm::FixedPointSemantics Sem)
Definition: FixedPoint.h:36
Bytecode function.
Definition: Function.h:81
unsigned getNumParams() const
Definition: Function.h:202
bool hasThisPointer() const
Definition: Function.h:186
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Definition: Function.h:116
Scope managing label targets.
Definition: Compiler.cpp:104
LabelScope(Compiler< Emitter > *Ctx)
Definition: Compiler.cpp:109
Compiler< Emitter > * Ctx
Compiler instance.
Definition: Compiler.cpp:111
Generic scope for local variables.
Definition: Compiler.h:501
bool destroyLocals(const Expr *E=nullptr) override
Explicit destruction of local variables.
Definition: Compiler.h:525
void addLocal(const Scope::Local &Local) override
Definition: Compiler.h:535
Sets the context for break/continue statements.
Definition: Compiler.cpp:115
typename Compiler< Emitter >::LabelTy LabelTy
Definition: Compiler.cpp:117
LoopScope(Compiler< Emitter > *Ctx, LabelTy BreakLabel, LabelTy ContinueLabel)
Definition: Compiler.cpp:120
typename Compiler< Emitter >::OptLabelTy OptLabelTy
Definition: Compiler.cpp:118
Scope used to handle initialization methods.
Definition: Compiler.cpp:53
OptionScope(Compiler< Emitter > *Ctx, bool NewDiscardResult, bool NewInitializing)
Root constructor, compiling or discarding primitives.
Definition: Compiler.cpp:56
Context to manage declaration lifetimes.
Definition: Program.h:133
Structure/Class descriptor.
Definition: Record.h:25
bool isUnion() const
Checks if the record is a union.
Definition: Record.h:57
const CXXDestructorDecl * getDestructor() const
Returns the destructor of the record, if any.
Definition: Record.h:73
const Field * getField(const FieldDecl *FD) const
Returns a field.
Definition: Record.cpp:40
llvm::iterator_range< const_base_iter > bases() const
Definition: Record.h:88
const Base * getVirtualBase(const RecordDecl *RD) const
Returns a virtual base descriptor.
Definition: Record.cpp:60
unsigned getNumFields() const
Definition: Record.h:84
bool isAnonymousUnion() const
Checks if the record is an anonymous union.
Definition: Record.h:59
llvm::iterator_range< const_field_iter > fields() const
Definition: Record.h:80
const Base * getBase(const RecordDecl *FD) const
Returns a base descriptor.
Definition: Record.cpp:46
Describes a scope block.
Definition: Function.h:36
Describes the statement/declaration an opcode was generated from.
Definition: Source.h:77
StmtExprScope(Compiler< Emitter > *Ctx)
Definition: Compiler.cpp:180
typename Compiler< Emitter >::LabelTy LabelTy
Definition: Compiler.cpp:148
typename Compiler< Emitter >::OptLabelTy OptLabelTy
Definition: Compiler.cpp:149
SwitchScope(Compiler< Emitter > *Ctx, CaseMap &&CaseLabels, LabelTy BreakLabel, OptLabelTy DefaultLabel)
Definition: Compiler.cpp:152
typename Compiler< Emitter >::CaseMap CaseMap
Definition: Compiler.cpp:150
Scope chain managing the variable lifetimes.
Definition: Compiler.h:440
Compiler< Emitter > * Ctx
Compiler instance.
Definition: Compiler.h:494
llvm::APInt APInt
Definition: FixedPoint.h:19
static llvm::RoundingMode getRoundingMode(FPOptions FPO)
Definition: Interp.h:409
bool Div(InterpState &S, CodePtr OpPC)
1) Pops the RHS from the stack.
Definition: Interp.h:674
constexpr bool isPtrType(PrimType T)
Definition: PrimType.h:53
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition: PrimType.h:131
bool InitScope(InterpState &S, CodePtr OpPC, uint32_t I)
Definition: Interp.h:2117
bool LE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:1171
PrimType
Enumeration of the primitive types of the VM.
Definition: PrimType.h:34
bool Mul(InterpState &S, CodePtr OpPC)
Definition: Interp.h:447
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:23
llvm::APSInt APSInt
Definition: FixedPoint.h:20
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
Definition: Descriptor.h:29
constexpr bool isIntegralType(PrimType T)
Definition: PrimType.h:74
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition: Address.h:328
BinaryOperatorKind
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
Definition: TypeTraits.h:51
@ SD_Static
Static storage duration.
Definition: Specifiers.h:331
const FunctionProtoType * T
@ Success
Template argument deduction was successful.
unsigned int uint32_t
#define true
Definition: stdbool.h:25
A quantity in bits.
Definition: BitcastBuffer.h:24
Describes a memory block created by an allocation site.
Definition: Descriptor.h:116
unsigned getNumElems() const
Returns the number of elements stored in the block.
Definition: Descriptor.h:243
bool isPrimitive() const
Checks if the descriptor is of a primitive.
Definition: Descriptor.h:257
const Descriptor *const ElemDesc
Descriptor of the array element.
Definition: Descriptor.h:148
static constexpr MetadataSize InlineDescMD
Definition: Descriptor.h:137
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
Definition: Descriptor.h:248
const Record *const ElemRecord
Pointer to the record, if block contains records.
Definition: Descriptor.h:146
bool isArray() const
Checks if the descriptor is of an array.
Definition: Descriptor.h:260
Descriptor used for global variables.
Definition: Descriptor.h:59
const FieldDecl * Decl
Definition: Record.h:29
Information about a local's storage.
Definition: Function.h:39
State encapsulating if a the variable creation has been successful, unsuccessful, or no variable has ...
Definition: Compiler.h:95
static VarCreationState NotCreated()
Definition: Compiler.h:99