clang 24.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 "../ExprConstShared.h"
11#include "ByteCodeEmitter.h"
12#include "Context.h"
13#include "FixedPoint.h"
14#include "Floating.h"
15#include "Function.h"
16#include "InterpShared.h"
17#include "PrimType.h"
18#include "Program.h"
19#include "clang/AST/Attr.h"
21#include "llvm/Support/SaveAndRestore.h"
22
23using namespace clang;
24using namespace clang::interp;
25
26using APSInt = llvm::APSInt;
27
28namespace clang {
29namespace interp {
30
31static std::optional<bool> getBoolValue(const Expr *E) {
32 if (const auto *CE = dyn_cast_if_present<ConstantExpr>(E);
33 CE && CE->hasAPValueResult() &&
34 CE->getResultAPValueKind() == APValue::ValueKind::Int) {
35 return CE->getResultAsAPSInt().getBoolValue();
36 }
37
38 return std::nullopt;
39}
40
41/// Check if \c E has side-effects. This is used to avoid some temporary
42/// variables and is supposed to be a quick check, not exhaustive. That's why
43/// we're not using Expr::HasSideEffects().
44static bool isSideEffectFree(const Expr *E) {
47 return true;
48 if (isa<DeclRefExpr>(E))
49 return true;
50
51 return false;
52}
53
54/// Scope chain managing the variable lifetimes.
55template <class Emitter> class VariableScope {
56public:
58 : Ctx(Ctx), Parent(Ctx->VarScope), Kind(Kind) {
59 if (Parent)
60 this->LocalsAlwaysEnabled = Parent->LocalsAlwaysEnabled;
61 Ctx->VarScope = this;
62 }
63
64 virtual ~VariableScope() { Ctx->VarScope = this->Parent; }
65
66 virtual void addLocal(Scope::Local Local) {
67 llvm_unreachable("Shouldn't be called");
68 }
69 /// Like addExtended, but adds to the nearest scope of the given kind.
71 VariableScope *P = this;
72 while (P) {
73 // We found the right scope kind.
74 if (P->Kind == Kind) {
75 P->addLocal(Local);
76 return;
77 }
78 // If we reached the root scope and we're looking for a Block scope,
79 // attach it to the root instead of the current scope.
80 if (!P->Parent && Kind == ScopeKind::Block) {
81 P->addLocal(Local);
82 return;
83 }
84 P = P->Parent;
85 if (!P)
86 break;
87 }
88
89 // Add to this scope.
90 this->addLocal(Local);
91 }
92
93 virtual bool emitDestructors(const Expr *E = nullptr) { return true; }
94 virtual bool destroyLocals(const Expr *E = nullptr) { return true; }
95 virtual void forceInit() {}
96 VariableScope *getParent() const { return Parent; }
97 ScopeKind getKind() const { return Kind; }
98
99 /// Whether locals added to this scope are enabled by default.
100 /// This is almost always true, except for the two branches
101 /// of a conditional operator.
103
104protected:
105 /// Compiler instance.
107 /// Link to the parent scope.
110};
111
112/// Generic scope for local variables.
113template <class Emitter> class LocalScope : public VariableScope<Emitter> {
114public:
117
118 /// Emit a Destroy op for this scope.
119 ~LocalScope() override {
120 if (!Idx || ExplicitlyDestroyed)
121 return;
122 this->Ctx->emitDestroy(*Idx, SourceInfo{});
124 }
125 /// Explicit destruction of local variables.
126 bool destroyLocals(const Expr *E = nullptr) override {
127 if (!Idx)
128 return true;
129
130 // NB: We are *not* resetting Idx here as to allow multiple
131 // calls to destroyLocals().
132 bool Success = this->emitDestructors(E);
133 this->Ctx->emitDestroy(*Idx, E);
134 ExplicitlyDestroyed = true;
135 return Success;
136 }
137
138 void addLocal(Scope::Local Local) override {
139 if (!Idx) {
140 Idx = static_cast<unsigned>(this->Ctx->Descriptors.size());
141 this->Ctx->Descriptors.emplace_back();
142 this->Ctx->emitInitScope(*Idx, {});
143 }
144
145 Local.EnabledByDefault = this->LocalsAlwaysEnabled;
146 this->Ctx->Descriptors[*Idx].emplace_back(Local);
147 }
148
149 /// Force-initialize this scope. Usually, scopes are lazily initialized when
150 /// the first local variable is created, but in scenarios with conditonal
151 /// operators, we need to ensure scope is initialized just in case one of the
152 /// arms will create a local and the other won't. In such a case, the
153 /// InitScope() op would be part of the arm that created the local.
154 void forceInit() override {
155 if (!Idx) {
156 Idx = static_cast<unsigned>(this->Ctx->Descriptors.size());
157 this->Ctx->Descriptors.emplace_back();
158 this->Ctx->emitInitScope(*Idx, {});
159 }
160 }
161
162 bool emitDestructors(const Expr *E = nullptr) override {
163 if (!Idx)
164 return true;
165
166 // Emit destructor calls for local variables of record
167 // type with a destructor.
168 for (Scope::Local &Local : llvm::reverse(this->Ctx->Descriptors[*Idx])) {
169 if (Local.Desc->hasTrivialDtor())
170 continue;
171
172 if (!Local.EnabledByDefault) {
173 typename Emitter::LabelTy EndLabel = this->Ctx->getLabel();
174 if (!this->Ctx->emitGetLocalEnabled(Local.Offset, E))
175 return false;
176 if (!this->Ctx->jumpFalse(EndLabel, E))
177 return false;
178
179 if (!this->Ctx->emitGetPtrLocal(Local.Offset, E))
180 return false;
181
182 if (!this->Ctx->emitDestructionPop(Local.Desc, Local.Desc->getLoc()))
183 return false;
184
185 this->Ctx->fallthrough(EndLabel);
186 this->Ctx->emitLabel(EndLabel);
187 } else {
188 if (!this->Ctx->emitGetPtrLocal(Local.Offset, E))
189 return false;
190 if (!this->Ctx->emitDestructionPop(Local.Desc, Local.Desc->getLoc()))
191 return false;
192 }
193
195 }
196 return true;
197 }
198
200 if (!Idx)
201 return;
202
203 for (const Scope::Local &Local : this->Ctx->Descriptors[*Idx]) {
205 }
206 }
207
209 if (const auto *OVE =
210 llvm::dyn_cast_if_present<OpaqueValueExpr>(Local.Desc->asExpr())) {
211 this->Ctx->OpaqueExprs.erase(OVE);
212 };
213 }
214
215 /// Index of the scope in the chain.
216 UnsignedOrNone Idx = std::nullopt;
218};
219
220template <class Emitter> class ArrayIndexScope final {
221public:
222 ArrayIndexScope(Compiler<Emitter> *Ctx, uint64_t Index) : Ctx(Ctx) {
223 OldArrayIndex = Ctx->ArrayIndex;
224 Ctx->ArrayIndex = Index;
225 }
226
227 ~ArrayIndexScope() { Ctx->ArrayIndex = OldArrayIndex; }
228
229private:
231 std::optional<uint64_t> OldArrayIndex;
232};
233
234template <class Emitter> class SourceLocScope final {
235public:
236 SourceLocScope(Compiler<Emitter> *Ctx, const Expr *DefaultExpr) : Ctx(Ctx) {
237 assert(DefaultExpr);
238 // We only switch if the current SourceLocDefaultExpr is null.
239 if (!Ctx->SourceLocDefaultExpr) {
240 Enabled = true;
241 Ctx->SourceLocDefaultExpr = DefaultExpr;
242 }
243 }
244
246 if (Enabled)
247 Ctx->SourceLocDefaultExpr = nullptr;
248 }
249
250private:
252 bool Enabled = false;
253};
254
255template <class Emitter> class InitLinkScope final {
256public:
258 Ctx->InitStack.push_back(std::move(Link));
259 }
260
261 ~InitLinkScope() { this->Ctx->InitStack.pop_back(); }
262
263public:
265};
266
267template <class Emitter> class InitStackScope final {
268public:
270 : Ctx(Ctx), OldValue(Ctx->InitStackActive), Active(Active) {
271 // An explicit initializer nested in a default member initializer still
272 // needs the surrounding default initializer's `this` reconstruction.
273 Ctx->InitStackActive = OldValue || Active;
274 if (Active)
275 Ctx->InitStack.push_back(InitLink::DIE());
276 }
277
279 this->Ctx->InitStackActive = OldValue;
280 if (Active)
281 Ctx->InitStack.pop_back();
282 }
283
284private:
286 bool OldValue;
287 bool Active;
288};
289
290/// Scope used to handle temporaries in toplevel variable declarations.
291template <class Emitter> class DeclScope final : public LocalScope<Emitter> {
292public:
294 : LocalScope<Emitter>(Ctx), Scope(Ctx->P),
295 OldInitializingDecl(Ctx->InitializingDecl) {
296 Ctx->InitializingDecl = VD;
297 Ctx->InitStack.push_back(InitLink::Decl(VD));
298 }
299
301 this->Ctx->InitializingDecl = OldInitializingDecl;
302 this->Ctx->InitStack.pop_back();
303 }
304
305private:
307 const VarDecl *OldInitializingDecl;
308};
309
310/// Scope used to handle initialization methods.
311template <class Emitter> class OptionScope final {
312public:
313 /// Root constructor, compiling or discarding primitives.
314 OptionScope(Compiler<Emitter> *Ctx, bool NewDiscardResult,
315 bool NewInitializing, bool NewToLValue)
316 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
317 OldInitializing(Ctx->Initializing), OldToLValue(Ctx->ToLValue) {
318 Ctx->DiscardResult = NewDiscardResult;
319 Ctx->Initializing = NewInitializing;
320 Ctx->ToLValue = NewToLValue;
321 }
322
324 Ctx->DiscardResult = OldDiscardResult;
325 Ctx->Initializing = OldInitializing;
326 Ctx->ToLValue = OldToLValue;
327 }
328
329private:
330 /// Parent context.
332 /// Old discard flag to restore.
333 bool OldDiscardResult;
334 bool OldInitializing;
335 bool OldToLValue;
336};
337
338template <class Emitter>
339bool InitLink::emit(Compiler<Emitter> *Ctx, const Expr *E) const {
340 switch (Kind) {
341 case K_This:
342 return Ctx->emitThis(E);
343 case K_Field:
344 // We're assuming there's a base pointer on the stack already.
345 return Ctx->emitGetPtrFieldPop(Offset, E);
346 case K_Base:
347 return Ctx->emitGetPtrBasePop(Offset, false, E);
348 case K_Temp:
349 return Ctx->emitGetPtrLocal(Offset, E);
350 case K_Decl:
351 return Ctx->visitDeclRef(D, E);
352 case K_Elem:
353 if (!Ctx->emitConstUint32(Offset, E))
354 return false;
355 return Ctx->emitArrayElemPtrPopUint32(E);
356 case K_RVO:
357 return Ctx->emitRVOPtr(E);
358 case K_InitList:
359 return true;
360 default:
361 llvm_unreachable("Unhandled InitLink kind");
362 }
363 return true;
364}
365
366/// Sets the context for break/continue statements.
367template <class Emitter> class LoopScope final {
368public:
372
373 LoopScope(Compiler<Emitter> *Ctx, const Stmt *Name, LabelTy BreakLabel,
374 LabelTy ContinueLabel)
375 : Ctx(Ctx) {
376#ifndef NDEBUG
377 for (const LabelInfo &LI : Ctx->LabelInfoStack)
378 assert(LI.Name != Name);
379#endif
380
381 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel, ContinueLabel,
382 /*DefaultLabel=*/std::nullopt,
383 Ctx->VarScope);
384 }
385
386 ~LoopScope() { this->Ctx->LabelInfoStack.pop_back(); }
387
388private:
390};
391
392// Sets the context for a switch scope, mapping labels.
393template <class Emitter> class SwitchScope final {
394public:
399
400 SwitchScope(Compiler<Emitter> *Ctx, const Stmt *Name, CaseMap &&CaseLabels,
401 LabelTy BreakLabel, OptLabelTy DefaultLabel)
402 : Ctx(Ctx), OldCaseLabels(std::move(this->Ctx->CaseLabels)) {
403#ifndef NDEBUG
404 for (const LabelInfo &LI : Ctx->LabelInfoStack)
405 assert(LI.Name != Name);
406#endif
407
408 this->Ctx->CaseLabels = std::move(CaseLabels);
409 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel,
410 /*ContinueLabel=*/std::nullopt,
411 DefaultLabel, Ctx->VarScope);
412 }
413
415 this->Ctx->CaseLabels = std::move(OldCaseLabels);
416 this->Ctx->LabelInfoStack.pop_back();
417 }
418
419private:
421 CaseMap OldCaseLabels;
422};
423
424/// When generating code for e.g. implicit field initializers in constructors,
425/// we don't have anything to point to in case the initializer causes an error.
426/// In that case, we need to disable location tracking for the initializer so
427/// we later point to the call range instead.
428template <class Emitter> class LocOverrideScope final {
429public:
431 bool Enabled = true)
432 : Ctx(Ctx), OldFlag(Ctx->LocOverride), Enabled(Enabled) {
433
434 if (Enabled)
435 Ctx->LocOverride = NewValue;
436 }
437
439 if (Enabled)
440 Ctx->LocOverride = OldFlag;
441 }
442
443private:
445 std::optional<SourceInfo> OldFlag;
446 bool Enabled;
447};
448
449} // namespace interp
450} // namespace clang
451
452template <class Emitter>
454 const Expr *SubExpr = E->getSubExpr();
455
456 if (DiscardResult)
457 return this->delegate(SubExpr);
458
459 switch (E->getCastKind()) {
460 case CK_LValueToRValue: {
461 if (ToLValue && E->getType()->isPointerType()) {
462 assert(!DiscardResult);
463 if (!this->visit(SubExpr))
464 return false;
465 return this->emitLoadPopL(E);
466 }
467
468 if (SubExpr->getType().isVolatileQualified())
469 return this->emitInvalidCast(CastKind::Volatile, /*Fatal=*/true, E);
470
471 OptPrimType SubExprT = classify(SubExpr->getType());
472 // Try to load the value directly. This is purely a performance
473 // optimization.
474 if (SubExprT) {
475 if (const auto *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
476 const ValueDecl *D = DRE->getDecl();
477 bool IsReference = D->getType()->isReferenceType();
478
479 if (!IsReference) {
481 if (auto GlobalIndex = P.getGlobal(D))
482 return this->emitGetGlobal(*SubExprT, *GlobalIndex, E);
483 } else if (auto It = Locals.find(D); It != Locals.end()) {
484 return this->emitGetLocal(*SubExprT, It->second.Offset, E);
485 } else if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
486 if (auto It = this->Params.find(PVD); It != this->Params.end()) {
487 return this->emitGetParam(*SubExprT, It->second.Index, E);
488 }
489 }
490 }
491 }
492 }
493
494 // Prepare storage for the result.
495 if (!Initializing && !SubExprT) {
496 UnsignedOrNone LocalIndex = allocateLocal(SubExpr);
497 if (!LocalIndex)
498 return false;
499 if (!this->emitGetPtrLocal(*LocalIndex, E))
500 return false;
501 }
502
503 if (!this->visit(SubExpr))
504 return false;
505
506 if (SubExprT)
507 return this->emitLoadPop(*SubExprT, E);
508
509 // If the subexpr type is not primitive, we need to perform a copy here.
510 // This happens for example in C when dereferencing a pointer of struct
511 // type.
512 return this->emitMemcpy(E);
513 }
514
515 case CK_DerivedToBaseMemberPointer: {
516 if (E->containsErrors())
517 return false;
518 assert(classifyPrim(E) == PT_MemberPtr);
519 assert(classifyPrim(SubExpr) == PT_MemberPtr);
520
521 if (!this->delegate(SubExpr))
522 return false;
523
524 const CXXRecordDecl *CurDecl = SubExpr->getType()
526 ->getMostRecentCXXRecordDecl();
527 for (const CXXBaseSpecifier *B : E->path()) {
528 const CXXRecordDecl *ToDecl = B->getType()->getAsCXXRecordDecl();
529 unsigned DerivedOffset = Ctx.collectBaseOffset(ToDecl, CurDecl);
530
531 if (!this->emitCastMemberPtrBasePop(DerivedOffset, ToDecl, E))
532 return false;
533 CurDecl = ToDecl;
534 }
535
536 return true;
537 }
538
539 case CK_BaseToDerivedMemberPointer: {
540 if (E->containsErrors())
541 return false;
542 assert(classifyPrim(E) == PT_MemberPtr);
543 assert(classifyPrim(SubExpr) == PT_MemberPtr);
544
545 if (!this->delegate(SubExpr))
546 return false;
547
548 const CXXRecordDecl *CurDecl = SubExpr->getType()
550 ->getMostRecentCXXRecordDecl();
551 // Base-to-derived member pointer casts store the path in derived-to-base
552 // order, so iterate backwards. The CXXBaseSpecifier also provides us with
553 // the wrong end of the derived->base arc, so stagger the path by one class.
554 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
555 for (ReverseIter PathI(E->path_end() - 1), PathE(E->path_begin());
556 PathI != PathE; ++PathI) {
557 const CXXRecordDecl *ToDecl = (*PathI)->getType()->getAsCXXRecordDecl();
558 unsigned DerivedOffset = Ctx.collectBaseOffset(CurDecl, ToDecl);
559
560 if (!this->emitCastMemberPtrDerivedPop(-DerivedOffset, ToDecl, E))
561 return false;
562 CurDecl = ToDecl;
563 }
564
565 const CXXRecordDecl *ToDecl =
566 E->getType()->castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
567 assert(ToDecl != CurDecl);
568 unsigned DerivedOffset = Ctx.collectBaseOffset(CurDecl, ToDecl);
569
570 if (!this->emitCastMemberPtrDerivedPop(-DerivedOffset, ToDecl, E))
571 return false;
572
573 return true;
574 }
575
576 case CK_UncheckedDerivedToBase:
577 case CK_DerivedToBase: {
578 if (!this->delegate(SubExpr))
579 return false;
580
581 const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
582 if (const auto *PT = dyn_cast<PointerType>(Ty))
583 return PT->getPointeeType()->getAsCXXRecordDecl();
584 return Ty->getAsCXXRecordDecl();
585 };
586
587 // FIXME: We can express a series of non-virtual casts as a single
588 // GetPtrBasePop op.
589 QualType CurType = SubExpr->getType();
590 for (const CXXBaseSpecifier *B : E->path()) {
591 if (B->isVirtual()) {
592 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), E))
593 return false;
594 CurType = B->getType();
595 } else {
596 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
597 if (!this->emitGetPtrBasePop(
598 DerivedOffset, /*NullOK=*/E->getType()->isPointerType(), E))
599 return false;
600 CurType = B->getType();
601 }
602 }
603
604 return true;
605 }
606
607 case CK_BaseToDerived: {
608 if (!this->delegate(SubExpr))
609 return false;
610 unsigned DerivedOffset =
611 collectBaseOffset(SubExpr->getType(), E->getType());
612
613 const Type *TargetType = E->getType().getTypePtr();
614 if (TargetType->isPointerOrReferenceType())
615 TargetType = TargetType->getPointeeType().getTypePtr();
616 return this->emitGetPtrDerivedPop(DerivedOffset,
617 /*NullOK=*/E->getType()->isPointerType(),
618 TargetType, E);
619 }
620
621 case CK_FloatingCast: {
622 // HLSL uses CK_FloatingCast to cast between vectors.
623 if (E->getType()->isVectorType())
624 return this->emitVectorConversion(E->getSubExpr(), E);
625 if (!SubExpr->getType()->isFloatingType() ||
626 !E->getType()->isFloatingType())
627 return false;
628 if (!this->visit(SubExpr))
629 return false;
630 const auto *TargetSemantics = &Ctx.getFloatSemantics(E->getType());
631 return this->emitCastFP(TargetSemantics, getRoundingMode(E), E);
632 }
633
634 case CK_IntegralToFloating: {
635 if (E->getType()->isVectorType())
636 return this->emitVectorConversion(E->getSubExpr(), E);
637 if (!E->getType()->isRealFloatingType())
638 return false;
639 if (!this->visit(SubExpr))
640 return false;
641 const auto *TargetSemantics = &Ctx.getFloatSemantics(E->getType());
642 return this->emitCastIntegralFloating(classifyPrim(SubExpr),
643 TargetSemantics, getFPOptions(E), E);
644 }
645
646 case CK_FloatingToBoolean: {
647 if (E->getType()->isVectorType())
648 return this->emitVectorConversion(E->getSubExpr(), E);
649 if (!SubExpr->getType()->isRealFloatingType() ||
651 return false;
652 if (const auto *FL = dyn_cast<FloatingLiteral>(SubExpr))
653 return this->emitConstBool(FL->getValue().isNonZero(), E);
654 if (!this->visit(SubExpr))
655 return false;
656 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
657 }
658
659 case CK_FloatingToIntegral: {
660 if (E->getType()->isVectorType())
661 return this->emitVectorConversion(E->getSubExpr(), E);
663 return false;
664 if (!this->visit(SubExpr))
665 return false;
666 PrimType ToT = classifyPrim(E);
667 if (ToT == PT_IntAP)
668 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(E->getType()),
669 getFPOptions(E), E);
670 if (ToT == PT_IntAPS)
671 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(E->getType()),
672 getFPOptions(E), E);
673
674 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
675 }
676
677 case CK_NullToPointer:
678 case CK_NullToMemberPointer: {
679 if (!this->discard(SubExpr))
680 return false;
681 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(E->getType());
682 return this->emitNull(classifyPrim(E->getType()), Val,
683 E->getType().getTypePtr(), E);
684 }
685
686 case CK_PointerToIntegral: {
687 if (!this->visit(SubExpr))
688 return false;
689
690 // If SubExpr doesn't result in a pointer, make it one.
691 if (PrimType FromT = classifyPrim(SubExpr->getType()); FromT != PT_Ptr) {
692 assert(isPtrType(FromT));
693 if (!this->emitDecayPtr(FromT, PT_Ptr, E))
694 return false;
695 }
696
698 if (T == PT_IntAP)
699 return this->emitCastPointerIntegralAP(Ctx.getBitWidth(E->getType()), E);
700 if (T == PT_IntAPS)
701 return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(E->getType()), E);
702 return this->emitCastPointerIntegral(T, E);
703 }
704
705 case CK_ArrayToPointerDecay: {
706 if (!this->visit(SubExpr))
707 return false;
708 return this->emitArrayDecay(E);
709 }
710
711 case CK_IntegralToPointer: {
712 QualType IntType = SubExpr->getType();
713 assert(IntType->isIntegralOrEnumerationType());
714 if (!this->visit(SubExpr))
715 return false;
716 // FIXME: I think the discard is wrong since the int->ptr cast might cause a
717 // diagnostic.
718 PrimType T = classifyPrim(IntType);
719 if (!this->emitGetIntPtr(T, E->getType().getTypePtr(), E))
720 return false;
721
722 QualType PtrType = E->getType();
723 PrimType DestPtrT = classifyPrim(PtrType);
724 if (DestPtrT == PT_Ptr)
725 return true;
726
727 // In case we're converting the integer to a non-Pointer.
728 return this->emitDecayPtr(PT_Ptr, DestPtrT, E);
729 }
730
731 case CK_AtomicToNonAtomic:
732 case CK_ConstructorConversion:
733 case CK_FunctionToPointerDecay:
734 case CK_NonAtomicToAtomic:
735 case CK_NoOp:
736 case CK_UserDefinedConversion:
737 case CK_AddressSpaceConversion:
738 case CK_CPointerToObjCPointerCast:
739 return this->delegate(SubExpr);
740
741 case CK_BitCast: {
742 if (E->containsErrors())
743 return false;
744 QualType ETy = E->getType();
745 // Reject bitcasts to atomic types.
746 if (ETy->isAtomicType()) {
747 if (!this->discard(SubExpr))
748 return false;
749 return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, E);
750 }
751 QualType SubExprTy = SubExpr->getType();
752 OptPrimType FromT = classify(SubExprTy);
753 // Casts from integer/vector to vector.
754 if (E->getType()->isVectorType())
755 return this->emitBuiltinBitCast(E);
756
757 OptPrimType ToT = classify(E->getType());
758 if (!FromT || !ToT)
759 return false;
760
761 assert(isPtrType(*FromT));
762 assert(isPtrType(*ToT));
763 bool SrcIsVoidPtr = SubExprTy->isVoidPointerType();
764 if (FromT == ToT) {
765 if (E->getType()->isVoidPointerType() &&
766 !SubExprTy->isFunctionPointerType()) {
767 return this->delegate(SubExpr);
768 }
769
770 if (!this->visit(SubExpr))
771 return false;
772 if (!this->emitCheckBitCast(ETy->getPointeeType().getTypePtr(),
773 SrcIsVoidPtr, E))
774 return false;
775
776 if (E->getType()->isFunctionPointerType() ||
777 SubExprTy->isFunctionPointerType()) {
778 return this->emitFnPtrCast(E);
779 }
780 if (FromT == PT_Ptr)
781 return this->emitPtrPtrCast(SubExprTy->isVoidPointerType(),
782 E->getType().getTypePtr(), E);
783 return true;
784 }
785
786 if (!this->visit(SubExpr))
787 return false;
788 return this->emitDecayPtr(*FromT, *ToT, E);
789 }
790 case CK_IntegralToBoolean:
791 case CK_FixedPointToBoolean: {
792 if (E->getType()->isVectorType())
793 return this->emitVectorConversion(E->getSubExpr(), E);
794 // HLSL uses this to cast to one-element vectors.
795 OptPrimType FromT = classify(SubExpr->getType());
796 if (!FromT)
797 return false;
798
799 if (const auto *IL = dyn_cast<IntegerLiteral>(SubExpr))
800 return this->emitConst(IL->getValue(), E);
801 if (!this->visit(SubExpr))
802 return false;
803 return this->emitCast(*FromT, classifyPrim(E), E);
804 }
805
806 case CK_IntegralCast:
807 if (E->getType()->isVectorType())
808 return this->emitVectorConversion(E->getSubExpr(), E);
809 [[fallthrough]];
810 case CK_BooleanToSignedIntegral: {
811 OptPrimType FromT = classify(SubExpr->getType());
812 OptPrimType ToT = classify(E->getType());
813 if (!FromT || !ToT)
814 return false;
815
816 // Try to emit a casted known constant value directly.
817 if (const auto *IL = dyn_cast<IntegerLiteral>(SubExpr)) {
818 if (ToT != PT_IntAP && ToT != PT_IntAPS && FromT != PT_IntAP &&
819 FromT != PT_IntAPS && !E->getType()->isEnumeralType())
820 return this->emitConst(APSInt(IL->getValue(), !isSignedType(*FromT)),
821 E);
822 if (!this->emitConst(IL->getValue(), SubExpr))
823 return false;
824 } else {
825 if (!this->visit(SubExpr))
826 return false;
827 }
828
829 // Possibly diagnose casts to enum types if the target type does not
830 // have a fixed size.
831 if (Ctx.getLangOpts().CPlusPlus && E->getType()->isEnumeralType()) {
832 const auto *ED = E->getType()->castAsEnumDecl();
833 if (!ED->isFixed()) {
834 if (!this->emitCheckEnumValue(*FromT, ED, E))
835 return false;
836 }
837 }
838
839 if (ToT == PT_IntAP) {
840 if (!this->emitCastAP(*FromT, Ctx.getBitWidth(E->getType()), E))
841 return false;
842 } else if (ToT == PT_IntAPS) {
843 if (!this->emitCastAPS(*FromT, Ctx.getBitWidth(E->getType()), E))
844 return false;
845 } else {
846 if (FromT == ToT)
847 return true;
848 if (!this->emitCast(*FromT, *ToT, E))
849 return false;
850 }
851 if (E->getCastKind() == CK_BooleanToSignedIntegral)
852 return this->emitNeg(*ToT, E);
853 return true;
854 }
855
856 case CK_PointerToBoolean:
857 if (!this->visit(SubExpr))
858 return false;
859 return this->emitIsNonNullPtr(E);
860
861 case CK_MemberPointerToBoolean:
862 if (!this->visit(SubExpr))
863 return false;
864 return this->emitIsNonNullMemberPtr(E);
865
866 case CK_IntegralComplexToBoolean:
867 case CK_FloatingComplexToBoolean: {
868 if (!this->visit(SubExpr))
869 return false;
870 return this->emitComplexBoolCast(SubExpr);
871 }
872
873 case CK_IntegralComplexToReal:
874 case CK_FloatingComplexToReal:
875 return this->emitComplexReal(SubExpr);
876
877 case CK_IntegralRealToComplex:
878 case CK_FloatingRealToComplex: {
879 // We're creating a complex value here, so we need to
880 // allocate storage for it.
881 if (!Initializing) {
882 UnsignedOrNone LocalIndex = allocateTemporary(E);
883 if (!LocalIndex)
884 return false;
885 if (!this->emitGetPtrLocal(*LocalIndex, E))
886 return false;
887 }
888
889 PrimType T = classifyPrim(SubExpr->getType());
890 // Init the complex value to {SubExpr, 0}.
891 if (!this->visitArrayElemInit(0, SubExpr, T))
892 return false;
893 // Zero-init the second element.
894 if (!this->visitZeroInitializer(T, SubExpr->getType(), SubExpr))
895 return false;
896 return this->emitInitElem(T, 1, SubExpr);
897 }
898
899 case CK_IntegralComplexCast:
900 case CK_FloatingComplexCast:
901 case CK_IntegralComplexToFloatingComplex:
902 case CK_FloatingComplexToIntegralComplex: {
903 assert(E->getType()->isAnyComplexType());
904 assert(SubExpr->getType()->isAnyComplexType());
905 if (!Initializing) {
906 UnsignedOrNone LocalIndex = allocateLocal(E);
907 if (!LocalIndex)
908 return false;
909 if (!this->emitGetPtrLocal(*LocalIndex, E))
910 return false;
911 }
912
913 // Location for the SubExpr.
914 // Since SubExpr is of complex type, visiting it results in a pointer
915 // anyway, so we just create a temporary pointer variable.
916 unsigned SubExprOffset =
917 allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
918 if (!this->visit(SubExpr))
919 return false;
920 if (!this->emitSetLocal(PT_Ptr, SubExprOffset, E))
921 return false;
922
923 PrimType SourceElemT = classifyComplexElementType(SubExpr->getType());
924 QualType DestElemType =
925 E->getType()->getAs<ComplexType>()->getElementType();
926 PrimType DestElemT = classifyPrim(DestElemType);
927 // Cast both elements individually.
928 for (unsigned I = 0; I != 2; ++I) {
929 if (!this->emitGetLocal(PT_Ptr, SubExprOffset, E))
930 return false;
931 if (!this->emitArrayElemPop(SourceElemT, I, E))
932 return false;
933
934 // Do the cast.
935 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, E))
936 return false;
937
938 // Save the value.
939 if (!this->emitInitElem(DestElemT, I, E))
940 return false;
941 }
942 return true;
943 }
944
945 case CK_VectorSplat: {
946 assert(!canClassify(E->getType()));
947 assert(E->getType()->isVectorType());
948
949 if (!canClassify(SubExpr->getType()))
950 return false;
951
952 if (!Initializing) {
953 UnsignedOrNone LocalIndex = allocateLocal(E);
954 if (!LocalIndex)
955 return false;
956 if (!this->emitGetPtrLocal(*LocalIndex, E))
957 return false;
958 }
959
960 const auto *VT = E->getType()->getAs<VectorType>();
961 PrimType ElemT = classifyPrim(SubExpr->getType());
962 unsigned ElemOffset =
963 allocateLocalPrimitive(SubExpr, ElemT, /*IsConst=*/true);
964
965 // Prepare a local variable for the scalar value.
966 if (!this->visit(SubExpr))
967 return false;
968 if (classifyPrim(SubExpr) == PT_Ptr && !this->emitLoadPop(ElemT, E))
969 return false;
970
971 if (!this->emitSetLocal(ElemT, ElemOffset, E))
972 return false;
973
974 for (unsigned I = 0; I != VT->getNumElements(); ++I) {
975 if (!this->emitGetLocal(ElemT, ElemOffset, E))
976 return false;
977 if (!this->emitInitElem(ElemT, I, E))
978 return false;
979 }
980
981 return true;
982 }
983
984 case CK_HLSLVectorTruncation: {
985 assert(SubExpr->getType()->isVectorType());
986 if (OptPrimType ResultT = classify(E)) {
987 assert(!DiscardResult);
988 // Result must be either a float or integer. Take the first element.
989 if (!this->visit(SubExpr))
990 return false;
991 return this->emitArrayElemPop(*ResultT, 0, E);
992 }
993 // Otherwise, this truncates from one vector type to another.
994 assert(E->getType()->isVectorType());
995
996 if (!Initializing) {
997 UnsignedOrNone LocalIndex = allocateTemporary(E);
998 if (!LocalIndex)
999 return false;
1000 if (!this->emitGetPtrLocal(*LocalIndex, E))
1001 return false;
1002 }
1003 unsigned ToSize = E->getType()->getAs<VectorType>()->getNumElements();
1004 assert(SubExpr->getType()->getAs<VectorType>()->getNumElements() > ToSize);
1005 if (!this->visit(SubExpr))
1006 return false;
1007 return this->emitCopyArray(classifyVectorElementType(E->getType()), 0, 0,
1008 ToSize, E);
1009 };
1010
1011 case CK_IntegralToFixedPoint: {
1012 if (!this->visit(SubExpr))
1013 return false;
1014
1015 auto Sem =
1016 Ctx.getASTContext().getFixedPointSemantics(E->getType()).toOpaqueInt();
1017 if (!this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->getType()), Sem,
1018 E))
1019 return false;
1020 if (DiscardResult)
1021 return this->emitPopFixedPoint(E);
1022 return true;
1023 }
1024 case CK_FloatingToFixedPoint: {
1025 if (!this->visit(SubExpr))
1026 return false;
1027
1028 auto Sem =
1029 Ctx.getASTContext().getFixedPointSemantics(E->getType()).toOpaqueInt();
1030 if (!this->emitCastFloatingFixedPoint(Sem, E))
1031 return false;
1032 if (DiscardResult)
1033 return this->emitPopFixedPoint(E);
1034 return true;
1035 }
1036 case CK_FixedPointToFloating: {
1037 if (!this->visit(SubExpr))
1038 return false;
1039 const auto *TargetSemantics = &Ctx.getFloatSemantics(E->getType());
1040 if (!this->emitCastFixedPointFloating(TargetSemantics, E))
1041 return false;
1042 if (DiscardResult)
1043 return this->emitPopFloat(E);
1044 return true;
1045 }
1046 case CK_FixedPointToIntegral: {
1047 if (!this->visit(SubExpr))
1048 return false;
1049 PrimType IntegralT = classifyPrim(E->getType());
1050 if (!this->emitCastFixedPointIntegral(IntegralT, E))
1051 return false;
1052 if (DiscardResult)
1053 return this->emitPop(IntegralT, E);
1054 return true;
1055 }
1056 case CK_FixedPointCast: {
1057 if (!this->visit(SubExpr))
1058 return false;
1059 auto Sem =
1060 Ctx.getASTContext().getFixedPointSemantics(E->getType()).toOpaqueInt();
1061 if (!this->emitCastFixedPoint(Sem, E))
1062 return false;
1063 if (DiscardResult)
1064 return this->emitPopFixedPoint(E);
1065 return true;
1066 }
1067
1068 case CK_ToVoid:
1069 return discard(SubExpr);
1070
1071 case CK_Dynamic:
1072 llvm_unreachable("CXXDynamicCastExpr has its own function");
1073
1074 case CK_LValueBitCast:
1075 if (!this->emitInvalidCast(CastKind::ReinterpretLike, /*Fatal=*/false, E))
1076 return false;
1077 return this->delegate(SubExpr);
1078
1079 case CK_HLSLArrayRValue: {
1080 // Non-decaying array rvalue cast - creates an rvalue copy of an lvalue
1081 // array, similar to LValueToRValue for composite types.
1082 if (!Initializing) {
1083 UnsignedOrNone LocalIndex = allocateLocal(E);
1084 if (!LocalIndex)
1085 return false;
1086 if (!this->emitGetPtrLocal(*LocalIndex, E))
1087 return false;
1088 }
1089 if (!this->visit(SubExpr))
1090 return false;
1091 return this->emitMemcpy(E);
1092 }
1093
1094 case CK_HLSLMatrixTruncation: {
1095 assert(SubExpr->getType()->isConstantMatrixType());
1096 if (OptPrimType ResultT = classify(E)) {
1097 assert(!DiscardResult);
1098 // Result must be either a float or integer. Take the first element.
1099 if (!this->visit(SubExpr))
1100 return false;
1101 return this->emitArrayElemPop(*ResultT, 0, E);
1102 }
1103 // Otherwise, this truncates to a a constant matrix type.
1104 assert(E->getType()->isConstantMatrixType());
1105
1106 if (!Initializing) {
1107 UnsignedOrNone LocalIndex = allocateTemporary(E);
1108 if (!LocalIndex)
1109 return false;
1110 if (!this->emitGetPtrLocal(*LocalIndex, E))
1111 return false;
1112 }
1113 unsigned ToSize =
1114 E->getType()->getAs<ConstantMatrixType>()->getNumElementsFlattened();
1115 if (!this->visit(SubExpr))
1116 return false;
1117 return this->emitCopyArray(classifyMatrixElementType(SubExpr->getType()), 0,
1118 0, ToSize, E);
1119 }
1120
1121 case CK_HLSLAggregateSplatCast: {
1122 // Aggregate splat cast: convert a scalar value to one of an aggregate type
1123 // by replicating and casting the scalar to every element of the destination
1124 // aggregate (vector, matrix, array, or struct).
1125 assert(canClassify(SubExpr->getType()));
1126
1127 if (!Initializing) {
1128 UnsignedOrNone LocalIndex = allocateLocal(E);
1129 if (!LocalIndex)
1130 return false;
1131 if (!this->emitGetPtrLocal(*LocalIndex, E))
1132 return false;
1133 }
1134
1135 // The scalar to be splatted is stored in a local to be repeatedly loaded
1136 // once for every scalar element of the destination.
1137 PrimType SrcElemT = classifyPrim(SubExpr->getType());
1138 unsigned SrcOffset =
1139 allocateLocalPrimitive(SubExpr, SrcElemT, /*IsConst=*/true);
1140
1141 if (!this->visit(SubExpr))
1142 return false;
1143 if (!this->emitSetLocal(SrcElemT, SrcOffset, E))
1144 return false;
1145
1146 // Recursively splat the scalar into every element of the destination.
1147 return emitHLSLAggregateSplat(SrcElemT, SrcOffset, E->getType(), E);
1148 }
1149
1150 case CK_HLSLElementwiseCast: {
1151 // Elementwise cast: flatten the elements of one aggregate source type and
1152 // store to a destination scalar or aggregate type of the same or fewer
1153 // number of elements. Casts are inserted element-wise to convert each
1154 // source scalar element to its corresponding destination scalar element.
1155 QualType SrcType = SubExpr->getType();
1156 QualType DestType = E->getType();
1157
1158 if (OptPrimType DestT = classify(DestType)) {
1159 // When the destination is a scalar, we only need the first scalar
1160 // element of the source.
1161 unsigned SrcPtrOffset =
1162 allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
1163 if (!this->visit(SubExpr))
1164 return false;
1165 if (!this->emitSetLocal(PT_Ptr, SrcPtrOffset, E))
1166 return false;
1167
1169 if (!emitHLSLFlattenAggregate(SrcType, SrcPtrOffset, Elements, 1, E))
1170 return false;
1171 if (Elements.empty())
1172 return false;
1173
1174 const HLSLFlatElement &Src = Elements[0];
1175 if (!this->emitGetLocal(Src.Type, Src.LocalOffset, E))
1176 return false;
1177 return this->emitPrimCast(Src.Type, *DestT, DestType, E);
1178 }
1179
1180 if (!Initializing) {
1181 UnsignedOrNone LocalIndex = allocateLocal(E);
1182 if (!LocalIndex)
1183 return false;
1184 if (!this->emitGetPtrLocal(*LocalIndex, E))
1185 return false;
1186 }
1187
1188 unsigned SrcOffset =
1189 allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
1190 if (!this->visit(SubExpr))
1191 return false;
1192 if (!this->emitSetLocal(PT_Ptr, SrcOffset, E))
1193 return false;
1194
1195 // Only flatten as many source elements as the destination requires.
1196 unsigned ElemCount = countHLSLFlatElements(DestType);
1197
1199 Elements.reserve(ElemCount);
1200 if (!emitHLSLFlattenAggregate(SrcType, SrcOffset, Elements, ElemCount, E))
1201 return false;
1202
1203 // Sema is expected to reject an elementwise cast whose source has fewer
1204 // scalar elements than the destination.
1205 assert(Elements.size() == ElemCount &&
1206 "Source type has fewer scalar elements than the destination type");
1207
1208 return emitHLSLConstructAggregate(DestType, Elements, E);
1209 }
1210
1211 case CK_ToUnion: {
1212 const FieldDecl *UnionField = E->getTargetUnionField();
1213 const Record *R = this->getRecord(E->getType());
1214 assert(R);
1215 const Record::Field *RF = R->getField(UnionField);
1216
1217 if (OptPrimType PT = RF->T) {
1218 if (!this->visit(SubExpr))
1219 return false;
1220 if (RF->isBitField())
1221 return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(),
1222 E);
1223 return this->emitInitFieldActivate(*PT, RF->Offset, E);
1224 }
1225
1226 if (!this->emitGetPtrField(RF->Offset, E))
1227 return false;
1228 if (!this->emitActivate(E))
1229 return false;
1230 return this->visitInitializerPop(SubExpr);
1231 }
1232
1233 default:
1234 return this->emitInvalid(E);
1235 }
1236 llvm_unreachable("Unhandled clang::CastKind enum");
1237}
1238
1239template <class Emitter>
1241 return this->emitBuiltinBitCast(E);
1242}
1243
1244template <class Emitter>
1246 if (DiscardResult)
1247 return true;
1248
1249 return this->emitConst(LE->getValue(), LE);
1250}
1251
1252template <class Emitter>
1254 if (DiscardResult)
1255 return true;
1256
1257 APFloat F = E->getValue();
1258 return this->emitFloat(F, E);
1259}
1260
1261template <class Emitter>
1263 assert(E->getType()->isAnyComplexType());
1264 if (DiscardResult)
1265 return true;
1266
1267 if (!Initializing) {
1268 UnsignedOrNone LocalIndex = allocateTemporary(E);
1269 if (!LocalIndex)
1270 return false;
1271 if (!this->emitGetPtrLocal(*LocalIndex, E))
1272 return false;
1273 }
1274
1275 const Expr *SubExpr = E->getSubExpr();
1276 PrimType SubExprT = classifyPrim(SubExpr->getType());
1277
1278 if (!this->visitZeroInitializer(SubExprT, SubExpr->getType(), SubExpr))
1279 return false;
1280 if (!this->emitInitElem(SubExprT, 0, SubExpr))
1281 return false;
1282 return this->visitArrayElemInit(1, SubExpr, SubExprT);
1283}
1284
1285template <class Emitter>
1287 assert(E->getType()->isFixedPointType());
1288 assert(classifyPrim(E) == PT_FixedPoint);
1289
1290 if (DiscardResult)
1291 return true;
1292
1293 auto Sem = Ctx.getASTContext().getFixedPointSemantics(E->getType());
1294 APInt Value = E->getValue();
1295 return this->emitConstFixedPoint(FixedPoint(Value, Sem), E);
1296}
1297
1298template <class Emitter>
1300 return this->delegate(E->getSubExpr());
1301}
1302
1303template <class Emitter>
1305 // Need short-circuiting for these.
1306 if (E->isLogicalOp() && !E->getType()->isVectorType())
1307 return this->VisitLogicalBinOp(E);
1308
1309 const Expr *LHS = E->getLHS();
1310 const Expr *RHS = E->getRHS();
1311
1312 // Handle comma operators. Just discard the LHS
1313 // and delegate to RHS.
1314 if (E->isCommaOp()) {
1315 if (!this->discard(LHS))
1316 return false;
1317 if (RHS->getType()->isVoidType())
1318 return this->discard(RHS);
1319
1320 return this->delegate(RHS);
1321 }
1322
1323 if (E->getType()->isAnyComplexType())
1324 return this->VisitComplexBinOp(E);
1325 if (E->getType()->isVectorType())
1326 return this->VisitVectorBinOp(E);
1327 if ((LHS->getType()->isAnyComplexType() ||
1328 RHS->getType()->isAnyComplexType()) &&
1329 E->isComparisonOp())
1330 return this->emitComplexComparison(LHS, RHS, E);
1331 if (LHS->getType()->isFixedPointType() || RHS->getType()->isFixedPointType())
1332 return this->VisitFixedPointBinOp(E);
1333
1334 if (E->isPtrMemOp()) {
1335 if (E->containsErrors())
1336 return false;
1337
1338 if (!this->visit(LHS))
1339 return false;
1340
1341 if (!this->visit(RHS))
1342 return false;
1343
1344 if (!this->emitToMemberPtr(E))
1345 return false;
1346
1347 if (classifyPrim(E) == PT_MemberPtr)
1348 return true;
1349
1350 if (!this->emitCastMemberPtrPtr(E))
1351 return false;
1352 return DiscardResult ? this->emitPopPtr(E) : true;
1353 }
1354
1355 // Typecheck the args.
1356 OptPrimType LT = classify(LHS);
1357 OptPrimType RT = classify(RHS);
1358 OptPrimType T = classify(E->getType());
1359
1360 // Special case for C++'s three-way/spaceship operator <=>, which
1361 // returns a std::{strong,weak,partial}_ordering (which is a class, so doesn't
1362 // have a PrimType).
1363 if (!T && E->getOpcode() == BO_Cmp) {
1364 if (DiscardResult)
1365 return true;
1366 const ComparisonCategoryInfo *CmpInfo =
1367 Ctx.getASTContext().CompCategories.lookupInfoForType(E->getType());
1368 assert(CmpInfo);
1369
1370 // We need a temporary variable holding our return value.
1371 if (!Initializing) {
1372 UnsignedOrNone ResultIndex = this->allocateLocal(E);
1373 if (!this->emitGetPtrLocal(*ResultIndex, E))
1374 return false;
1375 }
1376
1377 if (!visit(LHS) || !visit(RHS))
1378 return false;
1379
1380 return this->emitCMP3(*LT, CmpInfo, E);
1381 }
1382
1383 if (!LT || !RT || !T)
1384 return false;
1385
1386 // Pointer arithmetic special case.
1387 if (E->getOpcode() == BO_Add || E->getOpcode() == BO_Sub) {
1388 if (isPtrType(*T) || (isPtrType(*LT) && isPtrType(*RT)))
1389 return this->VisitPointerArithBinOp(E);
1390 }
1391
1392 if (E->getOpcode() == BO_Assign)
1393 return this->visitAssignment(LHS, RHS, E);
1394
1395 if (!visit(LHS) || !visit(RHS))
1396 return false;
1397
1398 // For languages such as C, cast the result of one
1399 // of our comparision opcodes to T (which is usually int).
1400 auto MaybeCastToBool = [this, T, E](bool Result) {
1401 if (!Result)
1402 return false;
1403 if (DiscardResult)
1404 return this->emitPopBool(E);
1405 if (T != PT_Bool)
1406 return this->emitCast(PT_Bool, *T, E);
1407 return true;
1408 };
1409
1410 auto Discard = [this, T, E](bool Result) {
1411 if (!Result)
1412 return false;
1413 return DiscardResult ? this->emitPop(*T, E) : true;
1414 };
1415
1416 switch (E->getOpcode()) {
1417 case BO_EQ:
1418 return MaybeCastToBool(this->emitEQ(*LT, E));
1419 case BO_NE:
1420 return MaybeCastToBool(this->emitNE(*LT, E));
1421 case BO_LT:
1422 return MaybeCastToBool(this->emitLT(*LT, E));
1423 case BO_LE:
1424 return MaybeCastToBool(this->emitLE(*LT, E));
1425 case BO_GT:
1426 return MaybeCastToBool(this->emitGT(*LT, E));
1427 case BO_GE:
1428 return MaybeCastToBool(this->emitGE(*LT, E));
1429 case BO_Sub:
1430 if (E->getType()->isFloatingType())
1431 return Discard(this->emitSubf(getFPOptions(E), E));
1432 return Discard(this->emitSub(*T, E));
1433 case BO_Add:
1434 if (E->getType()->isFloatingType())
1435 return Discard(this->emitAddf(getFPOptions(E), E));
1436 return Discard(this->emitAdd(*T, E));
1437 case BO_Mul:
1438 if (E->getType()->isFloatingType())
1439 return Discard(this->emitMulf(getFPOptions(E), E));
1440 return Discard(this->emitMul(*T, E));
1441 case BO_Rem:
1442 return Discard(this->emitRem(*T, E));
1443 case BO_Div:
1444 if (E->getType()->isFloatingType())
1445 return Discard(this->emitDivf(getFPOptions(E), E));
1446 return Discard(this->emitDiv(*T, E));
1447 case BO_And:
1448 return Discard(this->emitBitAnd(*T, E));
1449 case BO_Or:
1450 return Discard(this->emitBitOr(*T, E));
1451 case BO_Shl:
1452 return Discard(this->emitShl(*LT, *RT, E));
1453 case BO_Shr:
1454 return Discard(this->emitShr(*LT, *RT, E));
1455 case BO_Xor:
1456 return Discard(this->emitBitXor(*T, E));
1457 case BO_LOr:
1458 case BO_LAnd:
1459 llvm_unreachable("Already handled earlier");
1460 default:
1461 return false;
1462 }
1463
1464 llvm_unreachable("Unhandled binary op");
1465}
1466
1467/// Perform addition/subtraction of a pointer and an integer or
1468/// subtraction of two pointers.
1469template <class Emitter>
1471 BinaryOperatorKind Op = E->getOpcode();
1472 const Expr *LHS = E->getLHS();
1473 const Expr *RHS = E->getRHS();
1474
1475 if ((Op != BO_Add && Op != BO_Sub) ||
1476 (!LHS->getType()->isPointerType() && !RHS->getType()->isPointerType()))
1477 return false;
1478
1479 OptPrimType LT = classify(LHS);
1480 OptPrimType RT = classify(RHS);
1481
1482 if (!LT || !RT)
1483 return false;
1484
1485 // Visit the given pointer expression and optionally convert to a PT_Ptr.
1486 auto visitAsPointer = [&](const Expr *E, PrimType T) -> bool {
1487 if (!this->visit(E))
1488 return false;
1489 if (T != PT_Ptr)
1490 return this->emitDecayPtr(T, PT_Ptr, E);
1491 return true;
1492 };
1493
1494 if (LHS->getType()->isPointerType() && RHS->getType()->isPointerType()) {
1495 if (Op != BO_Sub)
1496 return false;
1497
1498 assert(E->getType()->isIntegerType());
1499 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *LT))
1500 return false;
1501
1502 QualType ElemType = LHS->getType()->getPointeeType();
1503 CharUnits ElemTypeSize;
1504 if (ElemType->isVoidType() || ElemType->isFunctionType())
1505 ElemTypeSize = CharUnits::One();
1506 else
1507 ElemTypeSize = Ctx.getASTContext().getTypeSizeInChars(ElemType);
1508
1509 PrimType IntT = classifyPrim(E->getType());
1510 if (!this->emitSubPtr(IntT, ElemTypeSize.getQuantity(), E))
1511 return false;
1512 return DiscardResult ? this->emitPop(IntT, E) : true;
1513 }
1514
1515 PrimType OffsetType;
1516 if (LHS->getType()->isIntegerType()) {
1517 if (!visitAsPointer(RHS, *RT))
1518 return false;
1519 if (!this->visit(LHS))
1520 return false;
1521 OffsetType = *LT;
1522 } else if (RHS->getType()->isIntegerType()) {
1523 if (!visitAsPointer(LHS, *LT))
1524 return false;
1525 if (!this->visit(RHS))
1526 return false;
1527 OffsetType = *RT;
1528 } else {
1529 return false;
1530 }
1531
1532 // Do the operation and optionally transform to
1533 // result pointer type.
1534 switch (Op) {
1535 case BO_Add:
1536 if (!this->emitAddOffset(OffsetType, E))
1537 return false;
1538 break;
1539 case BO_Sub:
1540 if (!this->emitSubOffset(OffsetType, E))
1541 return false;
1542 break;
1543 default:
1544 return false;
1545 }
1546
1547 PrimType ExprT = classifyPrim(E);
1548 if (ExprT != PT_Ptr) {
1549 if (!this->emitDecayPtr(PT_Ptr, ExprT, E))
1550 return false;
1551 }
1552
1553 if (DiscardResult)
1554 return this->emitPop(ExprT, E);
1555 return true;
1556}
1557
1558template <class Emitter>
1560 assert(E->isLogicalOp());
1561 BinaryOperatorKind Op = E->getOpcode();
1562 const Expr *LHS = E->getLHS();
1563 const Expr *RHS = E->getRHS();
1564
1565 if (Op == BO_LOr) {
1566 // Logical OR. Visit LHS and only evaluate RHS if LHS was FALSE.
1567 LabelTy LabelTrue = this->getLabel();
1568 LabelTy LabelEnd = this->getLabel();
1569
1570 if (!this->visitBool(LHS))
1571 return false;
1572 if (!this->jumpTrue(LabelTrue, E))
1573 return false;
1574
1575 if (!this->visitBool(RHS))
1576 return false;
1577 if (!this->jump(LabelEnd, E))
1578 return false;
1579
1580 this->emitLabel(LabelTrue);
1581 this->emitConstBool(true, E);
1582 this->fallthrough(LabelEnd);
1583 this->emitLabel(LabelEnd);
1584
1585 } else {
1586 assert(Op == BO_LAnd);
1587 // Logical AND.
1588 // Visit LHS. Only visit RHS if LHS was TRUE.
1589 LabelTy LabelFalse = this->getLabel();
1590 LabelTy LabelEnd = this->getLabel();
1591
1592 if (!this->visitBool(LHS))
1593 return false;
1594 if (!this->jumpFalse(LabelFalse, E))
1595 return false;
1596
1597 if (!this->visitBool(RHS))
1598 return false;
1599 if (!this->jump(LabelEnd, E))
1600 return false;
1601
1602 this->emitLabel(LabelFalse);
1603 this->emitConstBool(false, E);
1604 this->fallthrough(LabelEnd);
1605 this->emitLabel(LabelEnd);
1606 }
1607
1608 if (DiscardResult)
1609 return this->emitPopBool(E);
1610
1611 // For C, cast back to integer type.
1612 if (!E->getType()->isBooleanType()) {
1614 return this->emitCast(PT_Bool, T, E);
1615 }
1616 return true;
1617}
1618
1619template <class Emitter>
1621 // Prepare storage for result.
1622 if (!Initializing) {
1623 UnsignedOrNone LocalIndex = allocateTemporary(E);
1624 if (!LocalIndex)
1625 return false;
1626 if (!this->emitGetPtrLocal(*LocalIndex, E))
1627 return false;
1628 }
1629
1630 // Both LHS and RHS might _not_ be of complex type, but one of them
1631 // needs to be.
1632 const Expr *LHS = E->getLHS();
1633 const Expr *RHS = E->getRHS();
1634
1635 PrimType ResultElemT = this->classifyComplexElementType(E->getType());
1636 unsigned ResultOffset = ~0u;
1637 if (!DiscardResult)
1638 ResultOffset = this->allocateLocalPrimitive(E, PT_Ptr, /*IsConst=*/true);
1639
1640 // Save result pointer in ResultOffset
1641 if (!this->DiscardResult) {
1642 if (!this->emitDupPtr(E))
1643 return false;
1644 if (!this->emitSetLocal(PT_Ptr, ResultOffset, E))
1645 return false;
1646 }
1647 QualType LHSType = LHS->getType();
1648 if (const auto *AT = LHSType->getAs<AtomicType>())
1649 LHSType = AT->getValueType();
1650 QualType RHSType = RHS->getType();
1651 if (const auto *AT = RHSType->getAs<AtomicType>())
1652 RHSType = AT->getValueType();
1653
1654 bool LHSIsComplex = LHSType->isAnyComplexType();
1655 unsigned LHSOffset;
1656 bool RHSIsComplex = RHSType->isAnyComplexType();
1657
1658 // For ComplexComplex Mul, we have special ops to make their implementation
1659 // easier.
1660 BinaryOperatorKind Op = E->getOpcode();
1661 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1662 assert(classifyPrim(LHSType->getAs<ComplexType>()->getElementType()) ==
1664 PrimType ElemT =
1666 if (!this->visit(LHS))
1667 return false;
1668 if (!this->visit(RHS))
1669 return false;
1670 if (!this->emitMulc(ElemT, E))
1671 return false;
1672 if (DiscardResult)
1673 return this->emitPopPtr(E);
1674 return true;
1675 }
1676
1677 if (Op == BO_Div && RHSIsComplex) {
1678 QualType ElemQT = RHSType->getAs<ComplexType>()->getElementType();
1679 PrimType ElemT = classifyPrim(ElemQT);
1680 // If the LHS is not complex, we still need to do the full complex
1681 // division, so just stub create a complex value and stub it out with
1682 // the LHS and a zero.
1683
1684 if (!LHSIsComplex) {
1685 // This is using the RHS type for the fake-complex LHS.
1686 UnsignedOrNone LocalIndex = allocateTemporary(RHS);
1687 if (!LocalIndex)
1688 return false;
1689 LHSOffset = *LocalIndex;
1690
1691 if (!this->emitGetPtrLocal(LHSOffset, E))
1692 return false;
1693
1694 if (!this->visit(LHS))
1695 return false;
1696 // real is LHS
1697 if (!this->emitInitElem(ElemT, 0, E))
1698 return false;
1699 // imag is zero
1700 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1701 return false;
1702 if (!this->emitInitElem(ElemT, 1, E))
1703 return false;
1704 } else {
1705 if (!this->visit(LHS))
1706 return false;
1707 }
1708
1709 if (!this->visit(RHS))
1710 return false;
1711 if (!this->emitDivc(ElemT, E))
1712 return false;
1713 if (DiscardResult)
1714 return this->emitPopPtr(E);
1715 return true;
1716 }
1717
1718 // Evaluate LHS and save value to LHSOffset.
1719 if (LHSType->isAnyComplexType()) {
1720 LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true);
1721 if (!this->visit(LHS))
1722 return false;
1723 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
1724 return false;
1725 } else {
1726 PrimType LHST = classifyPrim(LHSType);
1727 LHSOffset = this->allocateLocalPrimitive(LHS, LHST, /*IsConst=*/true);
1728 if (!this->visit(LHS))
1729 return false;
1730 if (!this->emitSetLocal(LHST, LHSOffset, E))
1731 return false;
1732 }
1733
1734 // Same with RHS.
1735 unsigned RHSOffset;
1736 if (RHSType->isAnyComplexType()) {
1737 RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, /*IsConst=*/true);
1738 if (!this->visit(RHS))
1739 return false;
1740 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
1741 return false;
1742 } else {
1743 PrimType RHST = classifyPrim(RHSType);
1744 RHSOffset = this->allocateLocalPrimitive(RHS, RHST, /*IsConst=*/true);
1745 if (!this->visit(RHS))
1746 return false;
1747 if (!this->emitSetLocal(RHST, RHSOffset, E))
1748 return false;
1749 }
1750
1751 // For both LHS and RHS, either load the value from the complex pointer, or
1752 // directly from the local variable. For index 1 (i.e. the imaginary part),
1753 // just load 0 and do the operation anyway.
1754 auto loadComplexValue = [this](bool IsComplex, bool LoadZero,
1755 unsigned ElemIndex, unsigned Offset,
1756 const Expr *E) -> bool {
1757 if (IsComplex) {
1758 if (!this->emitGetLocal(PT_Ptr, Offset, E))
1759 return false;
1760 return this->emitArrayElemPop(classifyComplexElementType(E->getType()),
1761 ElemIndex, E);
1762 }
1763 if (ElemIndex == 0 || !LoadZero)
1764 return this->emitGetLocal(classifyPrim(E->getType()), Offset, E);
1765 return this->visitZeroInitializer(classifyPrim(E->getType()), E->getType(),
1766 E);
1767 };
1768
1769 // Now we can get pointers to the LHS and RHS from the offsets above.
1770 for (unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1771 // Result pointer for the store later.
1772 if (!this->DiscardResult) {
1773 if (!this->emitGetLocal(PT_Ptr, ResultOffset, E))
1774 return false;
1775 }
1776
1777 // The actual operation.
1778 switch (Op) {
1779 case BO_Add:
1780 if (!loadComplexValue(LHSIsComplex, true, ElemIndex, LHSOffset, LHS))
1781 return false;
1782
1783 if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))
1784 return false;
1785 if (ResultElemT == PT_Float) {
1786 if (!this->emitAddf(getFPOptions(E), E))
1787 return false;
1788 } else {
1789 if (!this->emitAdd(ResultElemT, E))
1790 return false;
1791 }
1792 break;
1793 case BO_Sub:
1794 if (!loadComplexValue(LHSIsComplex, true, ElemIndex, LHSOffset, LHS))
1795 return false;
1796
1797 if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))
1798 return false;
1799 if (ResultElemT == PT_Float) {
1800 if (!this->emitSubf(getFPOptions(E), E))
1801 return false;
1802 } else {
1803 if (!this->emitSub(ResultElemT, E))
1804 return false;
1805 }
1806 break;
1807 case BO_Mul:
1808 if (!loadComplexValue(LHSIsComplex, false, ElemIndex, LHSOffset, LHS))
1809 return false;
1810
1811 if (!loadComplexValue(RHSIsComplex, false, ElemIndex, RHSOffset, RHS))
1812 return false;
1813
1814 if (ResultElemT == PT_Float) {
1815 if (!this->emitMulf(getFPOptions(E), E))
1816 return false;
1817 } else {
1818 if (!this->emitMul(ResultElemT, E))
1819 return false;
1820 }
1821 break;
1822 case BO_Div:
1823 assert(!RHSIsComplex);
1824 if (!loadComplexValue(LHSIsComplex, false, ElemIndex, LHSOffset, LHS))
1825 return false;
1826
1827 if (!loadComplexValue(RHSIsComplex, false, ElemIndex, RHSOffset, RHS))
1828 return false;
1829
1830 if (ResultElemT == PT_Float) {
1831 if (!this->emitDivf(getFPOptions(E), E))
1832 return false;
1833 } else {
1834 if (!this->emitDiv(ResultElemT, E))
1835 return false;
1836 }
1837 break;
1838
1839 default:
1840 return false;
1841 }
1842
1843 if (!this->DiscardResult) {
1844 // Initialize array element with the value we just computed.
1845 if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))
1846 return false;
1847 } else {
1848 if (!this->emitPop(ResultElemT, E))
1849 return false;
1850 // Remove the Complex temporary pointer we created ourselves at the
1851 // beginning of this function.
1852 if (!Initializing)
1853 return this->emitPopPtr(E);
1854 }
1855 }
1856 return true;
1857}
1858
1859template <class Emitter>
1861 const Expr *LHS = E->getLHS();
1862 const Expr *RHS = E->getRHS();
1863 assert(!E->isCommaOp() &&
1864 "Comma op should be handled in VisitBinaryOperator");
1865 assert(E->getType()->isVectorType());
1866 assert(LHS->getType()->isVectorType());
1867 assert(RHS->getType()->isVectorType());
1868
1869 // We can only handle vectors with primitive element types.
1871 return false;
1872
1873 // Prepare storage for result.
1874 if (!Initializing && !E->isCompoundAssignmentOp() && !E->isAssignmentOp()) {
1875 UnsignedOrNone LocalIndex = allocateTemporary(E);
1876 if (!LocalIndex)
1877 return false;
1878 if (!this->emitGetPtrLocal(*LocalIndex, E))
1879 return false;
1880 }
1881
1882 const auto *VecTy = E->getType()->getAs<VectorType>();
1883 auto Op = E->isCompoundAssignmentOp()
1885 : E->getOpcode();
1886
1887 PrimType ElemT = this->classifyVectorElementType(LHS->getType());
1888 PrimType RHSElemT = this->classifyVectorElementType(RHS->getType());
1889 PrimType ResultElemT = this->classifyVectorElementType(E->getType());
1890
1891 if (E->getOpcode() == BO_Assign) {
1892 assert(Ctx.getASTContext().hasSameUnqualifiedType(
1894 RHS->getType()->castAs<VectorType>()->getElementType()));
1895 if (!this->visit(LHS))
1896 return false;
1897 if (!this->visit(RHS))
1898 return false;
1899 if (!this->emitCopyArray(ElemT, 0, 0, VecTy->getNumElements(), E))
1900 return false;
1901 if (DiscardResult)
1902 return this->emitPopPtr(E);
1903 return true;
1904 }
1905
1906 // Evaluate LHS and save value to LHSOffset.
1907 unsigned LHSOffset =
1908 this->allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true);
1909 if (!this->visit(LHS))
1910 return false;
1911 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
1912 return false;
1913
1914 // Evaluate RHS and save value to RHSOffset.
1915 unsigned RHSOffset =
1916 this->allocateLocalPrimitive(RHS, PT_Ptr, /*IsConst=*/true);
1917 if (!this->visit(RHS))
1918 return false;
1919 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
1920 return false;
1921
1922 if (E->isCompoundAssignmentOp() && !this->emitGetLocal(PT_Ptr, LHSOffset, E))
1923 return false;
1924
1925 // BitAdd/BitOr/BitXor/Shl/Shr doesn't support bool type, we need perform the
1926 // integer promotion.
1927 bool NeedIntPromot = ElemT == PT_Bool && (E->isBitwiseOp() || E->isShiftOp());
1928 QualType PromotTy;
1929 PrimType PromotT = PT_Bool;
1930 PrimType OpT = ElemT;
1931 if (NeedIntPromot) {
1932 PromotTy =
1933 Ctx.getASTContext().getPromotedIntegerType(Ctx.getASTContext().BoolTy);
1934 PromotT = classifyPrim(PromotTy);
1935 OpT = PromotT;
1936 }
1937
1938 auto getElem = [=](unsigned Offset, PrimType ElemT, unsigned Index) {
1939 if (!this->emitGetLocal(PT_Ptr, Offset, E))
1940 return false;
1941 if (!this->emitArrayElemPop(ElemT, Index, E))
1942 return false;
1943 if (E->isLogicalOp()) {
1944 if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E))
1945 return false;
1946 if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E))
1947 return false;
1948 } else if (NeedIntPromot) {
1949 if (!this->emitPrimCast(ElemT, PromotT, PromotTy, E))
1950 return false;
1951 }
1952 return true;
1953 };
1954
1955#define EMIT_ARITH_OP(OP) \
1956 { \
1957 if (ElemT == PT_Float) { \
1958 if (!this->emit##OP##f(getFPOptions(E), E)) \
1959 return false; \
1960 } else { \
1961 if (!this->emit##OP(ElemT, E)) \
1962 return false; \
1963 } \
1964 break; \
1965 }
1966
1967 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
1968 if (!getElem(LHSOffset, ElemT, I))
1969 return false;
1970 if (!getElem(RHSOffset, RHSElemT, I))
1971 return false;
1972 switch (Op) {
1973 case BO_Add:
1975 case BO_Sub:
1977 case BO_Mul:
1979 case BO_Div:
1981 case BO_Rem:
1982 if (!this->emitRem(ElemT, E))
1983 return false;
1984 break;
1985 case BO_And:
1986 if (!this->emitBitAnd(OpT, E))
1987 return false;
1988 break;
1989 case BO_Or:
1990 if (!this->emitBitOr(OpT, E))
1991 return false;
1992 break;
1993 case BO_Xor:
1994 if (!this->emitBitXor(OpT, E))
1995 return false;
1996 break;
1997 case BO_Shl:
1998 if (!this->emitShl(OpT, RHSElemT, E))
1999 return false;
2000 break;
2001 case BO_Shr:
2002 if (!this->emitShr(OpT, RHSElemT, E))
2003 return false;
2004 break;
2005 case BO_EQ:
2006 if (!this->emitEQ(ElemT, E))
2007 return false;
2008 break;
2009 case BO_NE:
2010 if (!this->emitNE(ElemT, E))
2011 return false;
2012 break;
2013 case BO_LE:
2014 if (!this->emitLE(ElemT, E))
2015 return false;
2016 break;
2017 case BO_LT:
2018 if (!this->emitLT(ElemT, E))
2019 return false;
2020 break;
2021 case BO_GE:
2022 if (!this->emitGE(ElemT, E))
2023 return false;
2024 break;
2025 case BO_GT:
2026 if (!this->emitGT(ElemT, E))
2027 return false;
2028 break;
2029 case BO_LAnd:
2030 // a && b is equivalent to a!=0 & b!=0
2031 if (!this->emitBitAnd(ResultElemT, E))
2032 return false;
2033 break;
2034 case BO_LOr:
2035 // a || b is equivalent to a!=0 | b!=0
2036 if (!this->emitBitOr(ResultElemT, E))
2037 return false;
2038 break;
2039 default:
2040 return this->emitInvalid(E);
2041 }
2042
2043 // The result of the comparison is a vector of the same width and number
2044 // of elements as the comparison operands with a signed integral element
2045 // type.
2046 //
2047 // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
2048 if (E->isComparisonOp()) {
2049 if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E))
2050 return false;
2051 if (!this->emitNeg(ResultElemT, E))
2052 return false;
2053 }
2054
2055 // If we performed an integer promotion, we need to cast the compute result
2056 // into result vector element type.
2057 if (NeedIntPromot &&
2058 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(), E))
2059 return false;
2060
2061 // Initialize array element with the value we just computed.
2062 if (!this->emitInitElem(ResultElemT, I, E))
2063 return false;
2064 }
2065
2066 if (DiscardResult && E->isCompoundAssignmentOp() && !this->emitPopPtr(E))
2067 return false;
2068 return true;
2069}
2070
2071template <class Emitter>
2073 const Expr *LHS = E->getLHS();
2074 const Expr *RHS = E->getRHS();
2075 const ASTContext &ASTCtx = Ctx.getASTContext();
2076
2077 assert(LHS->getType()->isFixedPointType() ||
2078 RHS->getType()->isFixedPointType());
2079
2080 auto LHSSema = ASTCtx.getFixedPointSemantics(LHS->getType());
2081 auto LHSSemaInt = LHSSema.toOpaqueInt();
2082 auto RHSSema = ASTCtx.getFixedPointSemantics(RHS->getType());
2083 auto RHSSemaInt = RHSSema.toOpaqueInt();
2084
2085 if (!this->visit(LHS))
2086 return false;
2087 if (!LHS->getType()->isFixedPointType()) {
2088 if (!this->emitCastIntegralFixedPoint(classifyPrim(LHS->getType()),
2089 LHSSemaInt, E))
2090 return false;
2091 }
2092
2093 if (!this->visit(RHS))
2094 return false;
2095 if (!RHS->getType()->isFixedPointType()) {
2096 if (!this->emitCastIntegralFixedPoint(classifyPrim(RHS->getType()),
2097 RHSSemaInt, E))
2098 return false;
2099 }
2100
2101 // Convert the result to the target semantics.
2102 auto ConvertResult = [&](bool R) -> bool {
2103 if (!R)
2104 return false;
2105 auto ResultSema = ASTCtx.getFixedPointSemantics(E->getType()).toOpaqueInt();
2106 auto CommonSema = LHSSema.getCommonSemantics(RHSSema).toOpaqueInt();
2107 if (ResultSema != CommonSema)
2108 return this->emitCastFixedPoint(ResultSema, E);
2109 return true;
2110 };
2111
2112 auto MaybeCastToBool = [&](bool Result) {
2113 if (!Result)
2114 return false;
2115 PrimType T = classifyPrim(E);
2116 if (DiscardResult)
2117 return this->emitPop(T, E);
2118 if (T != PT_Bool)
2119 return this->emitCast(PT_Bool, T, E);
2120 return true;
2121 };
2122
2123 switch (E->getOpcode()) {
2124 case BO_EQ:
2125 return MaybeCastToBool(this->emitEQFixedPoint(E));
2126 case BO_NE:
2127 return MaybeCastToBool(this->emitNEFixedPoint(E));
2128 case BO_LT:
2129 return MaybeCastToBool(this->emitLTFixedPoint(E));
2130 case BO_LE:
2131 return MaybeCastToBool(this->emitLEFixedPoint(E));
2132 case BO_GT:
2133 return MaybeCastToBool(this->emitGTFixedPoint(E));
2134 case BO_GE:
2135 return MaybeCastToBool(this->emitGEFixedPoint(E));
2136 case BO_Add:
2137 return ConvertResult(this->emitAddFixedPoint(E));
2138 case BO_Sub:
2139 return ConvertResult(this->emitSubFixedPoint(E));
2140 case BO_Mul:
2141 return ConvertResult(this->emitMulFixedPoint(E));
2142 case BO_Div:
2143 return ConvertResult(this->emitDivFixedPoint(E));
2144 case BO_Shl:
2145 return ConvertResult(this->emitShiftFixedPoint(/*Left=*/true, E));
2146 case BO_Shr:
2147 return ConvertResult(this->emitShiftFixedPoint(/*Left=*/false, E));
2148
2149 default:
2150 return this->emitInvalid(E);
2151 }
2152
2153 llvm_unreachable("unhandled binop opcode");
2154}
2155
2156template <class Emitter>
2158 const Expr *SubExpr = E->getSubExpr();
2159 assert(SubExpr->getType()->isFixedPointType());
2160
2161 switch (E->getOpcode()) {
2162 case UO_Plus:
2163 return this->delegate(SubExpr);
2164 case UO_Minus:
2165 if (!this->visit(SubExpr))
2166 return false;
2167 if (!this->emitNegFixedPoint(E))
2168 return false;
2169 if (DiscardResult)
2170 return this->emitPopFixedPoint(E);
2171 return true;
2172 default:
2173 return false;
2174 }
2175
2176 llvm_unreachable("Unhandled unary opcode");
2177}
2178
2179template <class Emitter>
2181 const ImplicitValueInitExpr *E) {
2182 if (DiscardResult)
2183 return true;
2184
2185 QualType QT = E->getType();
2186
2187 if (OptPrimType T = classify(QT))
2188 return this->visitZeroInitializer(*T, QT, E);
2189
2190 if (QT->isRecordType()) {
2191 const RecordDecl *RD = QT->getAsRecordDecl();
2192 assert(RD);
2193 if (RD->isInvalidDecl())
2194 return false;
2195
2196 const Record *R = getRecord(QT);
2197 if (!R)
2198 return false;
2199
2200 assert(Initializing);
2201 return this->visitZeroRecordInitializer(R, E);
2202 }
2203
2204 if (QT->isIncompleteArrayType())
2205 return true;
2206
2207 if (QT->isArrayType())
2208 return this->visitZeroArrayInitializer(QT, E);
2209
2210 if (const auto *ComplexTy = E->getType()->getAs<ComplexType>()) {
2211 assert(Initializing);
2212 QualType ElemQT = ComplexTy->getElementType();
2213 PrimType ElemT = classifyPrim(ElemQT);
2214 for (unsigned I = 0; I < 2; ++I) {
2215 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2216 return false;
2217 if (!this->emitInitElem(ElemT, I, E))
2218 return false;
2219 }
2220 return true;
2221 }
2222
2223 if (const auto *VecT = E->getType()->getAs<VectorType>()) {
2224 unsigned NumVecElements = VecT->getNumElements();
2225 QualType ElemQT = VecT->getElementType();
2226 PrimType ElemT = classifyPrim(ElemQT);
2227
2228 for (unsigned I = 0; I < NumVecElements; ++I) {
2229 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2230 return false;
2231 if (!this->emitInitElem(ElemT, I, E))
2232 return false;
2233 }
2234 return true;
2235 }
2236
2237 if (const auto *MT = E->getType()->getAs<ConstantMatrixType>()) {
2238 unsigned NumElems = MT->getNumElementsFlattened();
2239 QualType ElemQT = MT->getElementType();
2240 PrimType ElemT = classifyPrim(ElemQT);
2241
2242 for (unsigned I = 0; I != NumElems; ++I) {
2243 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2244 return false;
2245 if (!this->emitInitElem(ElemT, I, E))
2246 return false;
2247 }
2248 return true;
2249 }
2250
2251 return false;
2252}
2253
2254template <class Emitter>
2256 if (E->getType()->isVoidType() || E->containsErrors())
2257 return false;
2258
2259 const Expr *LHS = E->getLHS();
2260 const Expr *RHS = E->getRHS();
2261 const Expr *Index = E->getIdx();
2262 const Expr *Base = E->getBase();
2263
2264 // C++17's rules require us to evaluate the LHS first, regardless of which
2265 // side is the base.
2266 bool Success = true;
2267 for (const Expr *SubExpr : {LHS, RHS}) {
2268 if (!this->visit(SubExpr)) {
2269 Success = false;
2270 continue;
2271 }
2272
2273 // Expand the base if this is a subscript on a
2274 // pointer expression.
2275 if (SubExpr == Base && Base->getType()->isPointerType()) {
2276 if (!this->emitExpandPtr(E))
2277 Success = false;
2278 }
2279 }
2280
2281 if (!Success)
2282 return false;
2283
2284 OptPrimType IndexT = classify(Index->getType());
2285 // In error-recovery cases, the index expression has a dependent type.
2286 if (!IndexT)
2287 return this->emitError(E);
2288 // If the index is first, we need to change that.
2289 if (LHS == Index) {
2290 if (!this->emitFlip(PT_Ptr, *IndexT, E))
2291 return false;
2292 }
2293
2294 if (!this->emitArrayElemPtrPop(*IndexT, E))
2295 return false;
2296 if (DiscardResult)
2297 return this->emitPopPtr(E);
2298
2299 if (E->isGLValue())
2300 return true;
2301
2303 return this->emitLoadPop(*T, E);
2304}
2305
2306template <class Emitter>
2308 const Expr *ArrayFiller, const Expr *E) {
2310
2311 QualType QT = E->getType();
2312 if (const auto *AT = QT->getAs<AtomicType>())
2313 QT = AT->getValueType();
2314
2315 if (QT->isVoidType()) {
2316 if (Inits.size() == 0)
2317 return true;
2318 return this->emitInvalid(E);
2319 }
2320
2321 // Primitive values. A discarded one can simply discard each initializer;
2322 // there is no object to establish.
2323 if (OptPrimType T = classify(QT)) {
2324 if (DiscardResult) {
2325 for (const Expr *Init : Inits) {
2326 if (!this->discard(Init))
2327 return false;
2328 }
2329 return true;
2330 }
2331 if (Inits.size() == 0)
2332 return this->visitZeroInitializer(*T, QT, E);
2333 assert(Inits.size() == 1);
2334 return this->delegate(Inits[0]);
2335 }
2336
2337 assert(!canClassify(E->getType()));
2338
2339 // A composite prvalue needs somewhere to live even when it is discarded: a
2340 // default member initializer may read subobjects initialized earlier in this
2341 // same list, so those have to actually be written and `this` has to denote
2342 // the object. Materialize one and initialize into it.
2343 if (DiscardResult && !Initializing) {
2344 UnsignedOrNone LocalIndex = allocateLocal(E);
2345 if (!LocalIndex)
2346 return false;
2347 if (!this->emitGetPtrLocal(*LocalIndex, E))
2348 return false;
2349 InitLinkScope<Emitter> ILS2(this, InitLink::Temp(*LocalIndex));
2350 return this->visitInitializerPop(E);
2351 }
2352
2353 if (QT->isRecordType()) {
2354 const Record *R = getRecord(QT);
2355
2356 if (Inits.size() == 1 && E->getType() == Inits[0]->getType())
2357 return this->delegate(Inits[0]);
2358
2359 if (!R)
2360 return false;
2361
2362 auto initPrimitiveField = [=](const Record::Field *FieldToInit,
2363 const Expr *Init, PrimType T,
2364 bool Activate = false) -> bool {
2366 if (!this->visit(Init))
2367 return false;
2368
2369 bool BitField = FieldToInit->isBitField();
2370 if (BitField && Activate)
2371 return this->emitInitBitFieldActivate(T, FieldToInit->Offset,
2372 FieldToInit->bitWidth(), E);
2373 if (BitField)
2374 return this->emitInitBitField(T, FieldToInit->Offset,
2375 FieldToInit->bitWidth(), E);
2376 if (Activate)
2377 return this->emitInitFieldActivate(T, FieldToInit->Offset, E);
2378 return this->emitInitField(T, FieldToInit->Offset, E);
2379 };
2380
2381 auto initCompositeField = [=](const Record::Field *FieldToInit,
2382 const Expr *Init,
2383 bool Activate = false) -> bool {
2385 InitLinkScope<Emitter> ILS(this, InitLink::Field(FieldToInit->Offset));
2386
2387 // Non-primitive case. Get a pointer to the field-to-initialize
2388 // on the stack and recurse into visitInitializer().
2389 if (!this->emitGetPtrField(FieldToInit->Offset, Init))
2390 return false;
2391
2392 if (Activate && !this->emitActivate(E))
2393 return false;
2394
2395 return this->visitInitializerPop(Init);
2396 };
2397
2398 if (R->isUnion()) {
2399 if (Inits.size() == 0) {
2400 if (!this->visitZeroRecordInitializer(R, E))
2401 return false;
2402 } else {
2403 const Expr *Init = Inits[0];
2404 const FieldDecl *FToInit = nullptr;
2405 if (const auto *ILE = dyn_cast<InitListExpr>(E))
2406 FToInit = ILE->getInitializedFieldInUnion();
2407 else
2408 FToInit = cast<CXXParenListInitExpr>(E)->getInitializedFieldInUnion();
2409
2410 const Record::Field *FieldToInit = R->getField(FToInit);
2411 if (OptPrimType T = classify(Init)) {
2412 if (!initPrimitiveField(FieldToInit, Init, *T, /*Activate=*/true))
2413 return false;
2414 } else {
2415 if (!initCompositeField(FieldToInit, Init, /*Activate=*/true))
2416 return false;
2417 }
2418 }
2419 return this->emitFinishInit(E);
2420 }
2421
2422 assert(!R->isUnion());
2423 for (unsigned BI = 0; BI != R->getNumBases(); ++BI) {
2424 const Expr *Init = Inits[BI];
2425 const Record::Base *B = R->getBase(BI);
2427 InitLinkScope<Emitter> ILS(this, InitLink::Base(B->Offset));
2428 if (!this->emitGetPtrBase(B->Offset, Init))
2429 return false;
2430 if (!this->visitInitializerPop(Init))
2431 return false;
2432 }
2433
2434 unsigned FieldIndex = 0;
2435 for (unsigned FI = R->getNumBases(); FI != Inits.size();) {
2436 const Record::Field *FieldToInit = R->getField(FieldIndex);
2437 if (FieldToInit->isUnnamedBitField()) {
2438 ++FieldIndex;
2439 continue;
2440 }
2441
2442 const Expr *Init = Inits[FI];
2443 // If this is a child of a DesignatedInitUpdateExpr, skip elements which
2444 // aren't supposed to be modified.
2445 if (isa<NoInitExpr>(Init)) {
2446 ++FieldIndex;
2447 ++FI;
2448 continue;
2449 }
2450
2451 if (OptPrimType T = classify(Init)) {
2452 if (!initPrimitiveField(FieldToInit, Init, *T))
2453 return false;
2454 } else if (!initCompositeField(FieldToInit, Init)) {
2455 return false;
2456 }
2457
2458 ++FI;
2459 ++FieldIndex;
2460 }
2461
2462 assert(R->getNumVirtualBases() == 0);
2463
2464 return this->emitFinishInit(E);
2465 }
2466
2467 if (QT->isArrayType()) {
2468 const ConstantArrayType *CAT =
2469 Ctx.getASTContext().getAsConstantArrayType(QT);
2470 uint64_t NumElems = CAT->getZExtSize();
2471
2472 if (Initializing &&
2473 (!InitializingDecl || InitializingDecl->hasLocalStorage()) &&
2474 !this->emitCheckArrayDestSize(NumElems, E))
2475 return false;
2476
2477 if (Inits.size() == 1 && QT == Inits[0]->getType())
2478 return this->delegate(Inits[0]);
2479
2480 OptPrimType InitT = classify(CAT->getElementType());
2481 unsigned ElementIndex = 0;
2482 for (const Expr *Init : Inits) {
2483 if (const auto *EmbedS =
2484 dyn_cast<EmbedExpr>(Init->IgnoreParenImpCasts())) {
2485 PrimType TargetT = classifyPrim(Init->getType());
2486
2487 auto Eval = [&](const IntegerLiteral *IL, unsigned ElemIndex) {
2488 if (TargetT == PT_Float) {
2489 if (!this->emitConst(IL->getValue(), classifyPrim(IL), Init))
2490 return false;
2491 const auto *Sem = &Ctx.getFloatSemantics(CAT->getElementType());
2492 if (!this->emitCastIntegralFloating(classifyPrim(IL), Sem,
2493 getFPOptions(E), E))
2494 return false;
2495 } else {
2496 if (!this->emitConst(IL->getValue(), TargetT, Init))
2497 return false;
2498 }
2499 return this->emitInitElem(TargetT, ElemIndex, IL);
2500 };
2501 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
2502 return false;
2503 } else if (isa<NoInitExpr>(Init)) {
2504 // If this is a child of a DesignatedInitUpdateExpr, skip elements which
2505 // aren't supposed to be modified.
2506 ++ElementIndex;
2507 } else {
2508 if (!this->visitArrayElemInit(ElementIndex, Init, InitT))
2509 return false;
2510 ++ElementIndex;
2511 }
2512 }
2513
2514 // Expand the filler expression.
2515 // FIXME: This should go away.
2516 if (ArrayFiller && !isa<NoInitExpr>(ArrayFiller)) {
2517 for (; ElementIndex != NumElems; ++ElementIndex) {
2518 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller, InitT))
2519 return false;
2520 }
2521 }
2522
2523 return this->emitFinishInit(E);
2524 }
2525
2526 if (const auto *ComplexTy = QT->getAs<ComplexType>()) {
2527 unsigned NumInits = Inits.size();
2528
2529 if (NumInits == 1)
2530 return this->delegate(Inits[0]);
2531
2532 QualType ElemQT = ComplexTy->getElementType();
2533 PrimType ElemT = classifyPrim(ElemQT);
2534 if (NumInits == 0) {
2535 // Zero-initialize both elements.
2536 for (unsigned I = 0; I < 2; ++I) {
2537 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2538 return false;
2539 if (!this->emitInitElem(ElemT, I, E))
2540 return false;
2541 }
2542 } else if (NumInits == 2) {
2543 unsigned InitIndex = 0;
2544 for (const Expr *Init : Inits) {
2545 if (!this->visit(Init))
2546 return false;
2547
2548 if (!this->emitInitElem(ElemT, InitIndex, E))
2549 return false;
2550 ++InitIndex;
2551 }
2552 }
2553 return true;
2554 }
2555
2556 if (const auto *VecT = QT->getAs<VectorType>()) {
2557 unsigned NumVecElements = VecT->getNumElements();
2558 assert(NumVecElements >= Inits.size());
2559
2560 QualType ElemQT = VecT->getElementType();
2561 PrimType ElemT = classifyPrim(ElemQT);
2562
2563 // All initializer elements.
2564 unsigned InitIndex = 0;
2565 for (const Expr *Init : Inits) {
2566 if (!this->visit(Init))
2567 return false;
2568
2569 // If the initializer is of vector type itself, we have to deconstruct
2570 // that and initialize all the target fields from the initializer fields.
2571 if (const auto *InitVecT = Init->getType()->getAs<VectorType>()) {
2572 if (!this->emitCopyArray(ElemT, 0, InitIndex,
2573 InitVecT->getNumElements(), E))
2574 return false;
2575 InitIndex += InitVecT->getNumElements();
2576 } else {
2577 if (!this->emitInitElem(ElemT, InitIndex, E))
2578 return false;
2579 ++InitIndex;
2580 }
2581 }
2582
2583 assert(InitIndex <= NumVecElements);
2584
2585 // Fill the rest with zeroes.
2586 for (; InitIndex != NumVecElements; ++InitIndex) {
2587 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2588 return false;
2589 if (!this->emitInitElem(ElemT, InitIndex, E))
2590 return false;
2591 }
2592 return true;
2593 }
2594
2595 if (const auto *MT = QT->getAs<ConstantMatrixType>()) {
2596 unsigned NumElems = MT->getNumElementsFlattened();
2597 assert(Inits.size() == NumElems);
2598
2599 QualType ElemQT = MT->getElementType();
2600 PrimType ElemT = classifyPrim(ElemQT);
2601
2602 // Matrix initializer list elements are in row-major order, which matches
2603 // the matrix APValue convention and therefore no index remapping is
2604 // required.
2605 for (unsigned I = 0; I != NumElems; ++I) {
2606 if (!this->visit(Inits[I]))
2607 return false;
2608 if (!this->emitInitElem(ElemT, I, E))
2609 return false;
2610 }
2611 return true;
2612 }
2613
2614 return false;
2615}
2616
2617/// Pointer to the array(not the element!) must be on the stack when calling
2618/// this.
2619template <class Emitter>
2620bool Compiler<Emitter>::visitArrayElemInit(unsigned ElemIndex, const Expr *Init,
2621 OptPrimType InitT) {
2622 if (InitT) {
2623 // Visit the primitive element like normal.
2624 if (!this->visit(Init))
2625 return false;
2626 return this->emitInitElem(*InitT, ElemIndex, Init);
2627 }
2628
2629 InitLinkScope<Emitter> ILS(this, InitLink::Elem(ElemIndex));
2630 // Advance the pointer currently on the stack to the given
2631 // dimension.
2632 if (!this->emitConstUint32(ElemIndex, Init))
2633 return false;
2634 if (!this->emitArrayElemPtrUint32(Init))
2635 return false;
2636 return this->visitInitializerPop(Init);
2637}
2638
2639template <class Emitter>
2641 const FunctionDecl *FuncDecl,
2642 bool Activate, bool IsOperatorCall) {
2643 assert(VarScope->getKind() == ScopeKind::Call);
2644 llvm::BitVector NonNullArgs;
2645 if (FuncDecl && FuncDecl->hasAttr<NonNullAttr>())
2646 NonNullArgs = collectNonNullArgs(FuncDecl, Args);
2647
2648 bool ExplicitMemberFn = false;
2649 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl))
2650 ExplicitMemberFn = MD->isExplicitObjectMemberFunction();
2651
2652 unsigned ArgIndex = 0;
2653 for (const Expr *Arg : Args) {
2654 if (canClassify(Arg)) {
2655 if (!this->visit(Arg))
2656 return false;
2657 } else {
2658
2659 DeclOrExpr Source = Arg;
2660 if (FuncDecl) {
2661 // Try to use the parameter declaration instead of the argument
2662 // expression as a source.
2663 unsigned DeclIndex = ArgIndex - IsOperatorCall + ExplicitMemberFn;
2664 if (DeclIndex < FuncDecl->getNumParams())
2665 Source = FuncDecl->getParamDecl(ArgIndex - IsOperatorCall +
2666 ExplicitMemberFn);
2667 }
2668
2669 UnsignedOrNone LocalIndex =
2670 allocateLocal(std::move(Source), Arg->getType(), ScopeKind::Call);
2671 if (!LocalIndex)
2672 return false;
2673
2674 if (!this->emitGetPtrLocal(*LocalIndex, Arg))
2675 return false;
2676 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
2677 if (!this->visitInitializer(Arg))
2678 return false;
2679 }
2680
2681 if (ArgIndex == 1 && Activate) {
2682 if (!this->emitActivate(Arg))
2683 return false;
2684 }
2685
2686 if (!NonNullArgs.empty() && NonNullArgs[ArgIndex]) {
2687 PrimType ArgT = classify(Arg).value_or(PT_Ptr);
2688 if (ArgT == PT_Ptr) {
2689 if (!this->emitCheckNonNullArg(ArgT, Arg))
2690 return false;
2691 }
2692 }
2693
2694 ++ArgIndex;
2695 }
2696
2697 return true;
2698}
2699
2700template <class Emitter>
2702 return this->visitInitList(E->inits(), E->getArrayFiller(), E);
2703}
2704
2705template <class Emitter>
2710
2711template <class Emitter>
2716
2717template <class Emitter>
2719 if (!E->hasAPValueResult())
2720 return this->delegate(E->getSubExpr());
2721
2722 if (OptPrimType T = classify(E)) {
2723 // Try to emit the APValue directly, without visiting the subexpr.
2724 // This will only fail if we can't emit the APValue, so won't emit any
2725 // diagnostics or any double values.
2726 if (DiscardResult)
2727 return true;
2728 return this->visitAPValue(E->getAPValueResult(), *T, E);
2729 }
2730
2731 // Fall back to the subexpr for non-primitive APValues.
2732 return this->delegate(E->getSubExpr());
2733}
2734
2735template <class Emitter>
2737 auto It = E->begin();
2738 return this->visit(*It);
2739}
2740
2742 UnaryExprOrTypeTrait Kind) {
2743 bool AlignOfReturnsPreferred =
2744 ASTCtx.getLangOpts().isCompatibleWith(LangOptions::ClangABI::Ver7);
2745
2746 // C++ [expr.alignof]p3:
2747 // When alignof is applied to a reference type, the result is the
2748 // alignment of the referenced type.
2749 if (const auto *Ref = T->getAs<ReferenceType>())
2750 T = Ref->getPointeeType();
2751
2752 if (T.getQualifiers().hasUnaligned())
2753 return CharUnits::One();
2754
2755 // __alignof is defined to return the preferred alignment.
2756 // Before 8, clang returned the preferred alignment for alignof and
2757 // _Alignof as well.
2758 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2759 return ASTCtx.toCharUnitsFromBits(ASTCtx.getPreferredTypeAlign(T));
2760
2761 return ASTCtx.getTypeAlignInChars(T);
2762}
2763
2764template <class Emitter>
2766 const UnaryExprOrTypeTraitExpr *E) {
2767
2768 UnaryExprOrTypeTrait Kind = E->getKind();
2769 const ASTContext &ASTCtx = Ctx.getASTContext();
2770
2771 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2773
2774 // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
2775 // the result is the size of the referenced type."
2776 if (const auto *Ref = ArgType->getAs<ReferenceType>())
2777 ArgType = Ref->getPointeeType();
2778
2779 CharUnits Size;
2780 if (ArgType->isVoidType() || ArgType->isFunctionType())
2781 Size = CharUnits::One();
2782 else {
2783 if (ArgType->isDependentType() || !ArgType->isConstantSizeType())
2784 return this->emitInvalid(E);
2785
2786 if (Kind == UETT_SizeOf)
2787 Size = ASTCtx.getTypeSizeInChars(ArgType);
2788 else
2790 }
2791
2792 if (DiscardResult)
2793 return true;
2794
2795 return this->emitConst(Size.getQuantity(), E);
2796 }
2797
2798 if (Kind == UETT_CountOf) {
2799 QualType Ty = E->getTypeOfArgument();
2800 assert(Ty->isArrayType());
2801
2802 // We don't need to worry about array element qualifiers, so getting the
2803 // unsafe array type is fine.
2804 if (const auto *CAT =
2805 dyn_cast<ConstantArrayType>(Ty->getAsArrayTypeUnsafe())) {
2806 if (DiscardResult)
2807 return true;
2808 return this->emitConst(CAT->getSize(), E);
2809 }
2810
2811 assert(!Ty->isConstantSizeType());
2812
2813 // If it's a variable-length array type, we need to check whether it is a
2814 // multidimensional array. If so, we need to check the size expression of
2815 // the VLA to see if it's a constant size. If so, we can return that value.
2816 const auto *VAT = ASTCtx.getAsVariableArrayType(Ty);
2817 assert(VAT);
2818 if (VAT->getElementType()->isArrayType()) {
2819 std::optional<APSInt> Res =
2820 VAT->getSizeExpr()
2821 ? VAT->getSizeExpr()->getIntegerConstantExpr(ASTCtx)
2822 : std::nullopt;
2823 if (Res) {
2824 if (DiscardResult)
2825 return true;
2826 return this->emitConst(*Res, E);
2827 }
2828 }
2829 }
2830
2831 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2832 CharUnits Size;
2833
2834 if (E->isArgumentType()) {
2836
2837 Size = AlignOfType(ArgType, ASTCtx, Kind);
2838 } else {
2839 // Argument is an expression, not a type.
2840 const Expr *Arg = E->getArgumentExpr()->IgnoreParens();
2841
2842 if (Arg->getType()->isDependentType())
2843 return false;
2844
2845 // The kinds of expressions that we have special-case logic here for
2846 // should be kept up to date with the special checks for those
2847 // expressions in Sema.
2848
2849 // alignof decl is always accepted, even if it doesn't make sense: we
2850 // default to 1 in those cases.
2851 if (const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2852 Size = ASTCtx.getDeclAlign(DRE->getDecl(),
2853 /*RefAsPointee*/ true);
2854 else if (const auto *ME = dyn_cast<MemberExpr>(Arg))
2855 Size = ASTCtx.getDeclAlign(ME->getMemberDecl(),
2856 /*RefAsPointee*/ true);
2857 else
2858 Size = AlignOfType(Arg->getType(), ASTCtx, Kind);
2859 }
2860
2861 if (DiscardResult)
2862 return true;
2863
2864 return this->emitConst(Size.getQuantity(), E);
2865 }
2866
2867 if (Kind == UETT_VectorElements) {
2868 if (E->containsErrors())
2869 return false;
2870
2871 if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>())
2872 return this->emitConst(VT->getNumElements(), E);
2874 return this->emitSizelessVectorElementSize(E);
2875 }
2876
2877 if (Kind == UETT_VecStep) {
2878 if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>()) {
2879 unsigned N = VT->getNumElements();
2880
2881 // The vec_step built-in functions that take a 3-component
2882 // vector return 4. (OpenCL 1.1 spec 6.11.12)
2883 if (N == 3)
2884 N = 4;
2885
2886 return this->emitConst(N, E);
2887 }
2888 return this->emitConst(1, E);
2889 }
2890
2891 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2892 if (E->containsErrors())
2893 return false;
2894 assert(E->isArgumentType());
2895 unsigned Bits = ASTCtx.getOpenMPDefaultSimdAlign(E->getArgumentType());
2896
2897 return this->emitConst(ASTCtx.toCharUnitsFromBits(Bits).getQuantity(), E);
2898 }
2899
2900 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2901 if (E->getArgumentType()->isDependentType())
2902 return this->emitInvalid(E);
2903
2904 return this->emitConst(
2905 const_cast<ASTContext &>(ASTCtx).getPointerAuthTypeDiscriminator(
2906 E->getArgumentType()),
2907 E);
2908 }
2909
2910 return false;
2911}
2912
2913template <class Emitter>
2915 // 'Base.Member'
2916 const Expr *Base = E->getBase();
2917 const ValueDecl *Member = E->getMemberDecl();
2918
2919 if (DiscardResult)
2920 return this->discard(Base);
2921
2922 if (const auto *VD = dyn_cast<VarDecl>(Member)) {
2923 // If the member is a VarDecl, this is a static variable.
2924 // We need to try to lazily evaluate its initializer here since the
2925 // variable might've been deserialized and not registered
2926 // as a global variable yet.
2927 if (VD->getInit() && !VD->getInit()->isValueDependent())
2928 VD->evaluateValue();
2929 if (auto GlobalIndex = P.getGlobal(VD)) {
2930 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2931 return false;
2932 if (Member->getType()->isReferenceType())
2933 return this->emitLoadPopPtr(E);
2934 return true;
2935 }
2936 return false;
2937 }
2938
2939 if (!isa<FieldDecl>(Member)) {
2940 // A non-static member function access only makes sense as part of the
2941 // enclosing call here. Don't try to evaluate it in isolation.
2942 if (const auto *MD = dyn_cast<CXXMethodDecl>(Member);
2943 MD && !MD->isStatic()) {
2944 return false;
2945 }
2946
2947 if (!this->discard(Base) && !this->emitSideEffect(E))
2948 return false;
2949
2950 return this->visitDeclRef(Member, E);
2951 }
2952
2953 if (!this->visit(Base))
2954 return false;
2955
2956 // Base above gives us a pointer on the stack.
2957 const auto *FD = cast<FieldDecl>(Member);
2958 const RecordDecl *RD = FD->getParent();
2959 const Record *R = getRecord(RD);
2960 if (!R)
2961 return false;
2962 const Record::Field *F = R->getField(FD);
2963
2964 // MemberExprs are almost always lvalues, in which case we don't need to
2965 // do the load. But sometimes they aren't.
2966 const auto maybeLoadValue = [&]() -> bool {
2967 if (E->isGLValue())
2968 return true;
2969 if (OptPrimType T = classify(E))
2970 return this->emitLoadPop(*T, E);
2971 return false;
2972 };
2973
2974 // Leave a pointer to the field on the stack.
2975 if (F->Decl->getType()->isReferenceType())
2976 return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue();
2977 return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue();
2978}
2979
2980template <class Emitter>
2982 assert(!DiscardResult);
2983 // ArrayIndex might not be set if a ArrayInitIndexExpr is being evaluated
2984 // stand-alone, e.g. via EvaluateAsInt().
2985 if (!ArrayIndex)
2986 return false;
2987 return this->emitConst(*ArrayIndex, E);
2988}
2989
2990template <class Emitter>
2992 assert(Initializing);
2993 assert(!DiscardResult);
2994
2995 const Expr *Common = E->getCommonExpr();
2996 const Expr *SubExpr = E->getSubExpr();
2997 OptPrimType SubExprT = classify(SubExpr);
2998 size_t Size = E->getArraySize().getZExtValue();
2999
3000 if (SubExprT) {
3001 // Unwrap the OpaqueValueExpr so we don't cache something we won't reuse.
3002 Common = cast<OpaqueValueExpr>(Common)->getSourceExpr();
3003
3004 if (!this->visit(Common))
3005 return false;
3006 return this->emitCopyArray(*SubExprT, 0, 0, Size, E);
3007 }
3008
3009 // We visit the common opaque expression here once so we have its value
3010 // cached.
3011 if (!this->discard(Common))
3012 return false;
3013
3014 // TODO: This compiles to quite a lot of bytecode if the array is larger.
3015 // Investigate compiling this to a loop.
3016
3017 // So, every iteration, we execute an assignment here
3018 // where the LHS is on the stack (the target array)
3019 // and the RHS is our SubExpr.
3020 for (size_t I = 0; I != Size; ++I) {
3021 ArrayIndexScope<Emitter> IndexScope(this, I);
3023
3024 if (!this->visitArrayElemInit(I, SubExpr, SubExprT))
3025 return false;
3026 if (!BS.destroyLocals())
3027 return false;
3028 }
3029 return true;
3030}
3031
3032template <class Emitter>
3034 const Expr *SourceExpr = E->getSourceExpr();
3035 if (!SourceExpr)
3036 return false;
3037
3038 if (Initializing) {
3039 assert(!DiscardResult);
3040 return this->visitInitializer(SourceExpr);
3041 }
3042
3043 PrimType SubExprT = classify(SourceExpr).value_or(PT_Ptr);
3044 if (auto It = OpaqueExprs.find(E); It != OpaqueExprs.end()) {
3045 if (DiscardResult)
3046 return true;
3047 return this->emitGetLocal(SubExprT, It->second, E);
3048 }
3049
3050 if (!this->visit(SourceExpr))
3051 return false;
3052
3053 // At this point we either have the evaluated source expression or a pointer
3054 // to an object on the stack. We want to create a local variable that stores
3055 // this value.
3056 unsigned LocalIndex = allocateLocalPrimitive(E, SubExprT, /*IsConst=*/true);
3057 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
3058 return false;
3059
3060 // This is cleaned up when the local variable is destroyed.
3061 OpaqueExprs.insert({E, LocalIndex});
3062
3063 // Here the local variable is created but the value is removed from the stack,
3064 // so we put it back if the caller needs it.
3065 if (!DiscardResult)
3066 return this->emitGetLocal(SubExprT, LocalIndex, E);
3067 return true;
3068}
3069
3070template <class Emitter>
3072 const AbstractConditionalOperator *E) {
3073 const Expr *Condition = E->getCond();
3074 const Expr *TrueExpr = E->getTrueExpr();
3075 const Expr *FalseExpr = E->getFalseExpr();
3076
3077 if (std::optional<bool> BoolValue = getBoolValue(Condition)) {
3078 if (*BoolValue)
3079 return this->delegate(TrueExpr);
3080 return this->delegate(FalseExpr);
3081 }
3082
3083 bool IsBcpCall = false;
3084 if (const auto *CE = dyn_cast<CallExpr>(Condition->IgnoreParenCasts());
3085 CE && CE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) {
3086 IsBcpCall = true;
3087 }
3088
3089 LabelTy LabelEnd = this->getLabel(); // Label after the operator.
3090 LabelTy LabelFalse = this->getLabel(); // Label for the false expr.
3091
3092 if (IsBcpCall) {
3093 if (!this->emitPushIgnoreDiags(E))
3094 return false;
3095 }
3096
3097 if (!this->visitBool(Condition)) {
3098 // If the condition failed and we're checking for undefined behavior
3099 // (which only happens with EvalEmitter) check the TrueExpr and FalseExpr
3100 // as well.
3101 if (this->checkingForUndefinedBehavior()) {
3102 if (!this->discard(TrueExpr))
3103 return false;
3104 if (!this->discard(FalseExpr))
3105 return false;
3106 }
3107 return false;
3108 }
3109
3110 // Force-init the scope, which creates a InitScope op. This is necessary so
3111 // the scope is not only initialized in one arm of the conditional operator.
3112 this->VarScope->forceInit();
3113 // The TrueExpr and FalseExpr of a conditional operator do _not_ create a
3114 // scope, which means the local variables created within them unconditionally
3115 // always exist. However, we need to later differentiate which branch was
3116 // taken and only destroy the varibles of the active branch. This is what the
3117 // "enabled" flags on local variables are used for.
3118 llvm::SaveAndRestore LAAA(this->VarScope->LocalsAlwaysEnabled,
3119 /*NewValue=*/false);
3120
3121 if (!this->jumpFalse(LabelFalse, E))
3122 return false;
3123 if (!this->delegate(TrueExpr))
3124 return false;
3125
3126 if (!this->jump(LabelEnd, E))
3127 return false;
3128 this->emitLabel(LabelFalse);
3129 if (!this->delegate(FalseExpr))
3130 return false;
3131
3132 this->fallthrough(LabelEnd);
3133 this->emitLabel(LabelEnd);
3134
3135 if (IsBcpCall)
3136 return this->emitPopIgnoreDiags(E);
3137 return true;
3138}
3139
3140template <class Emitter>
3142 if (DiscardResult)
3143 return true;
3144
3145 if (!Initializing)
3146 return this->emitGetStringPtr(E, E);
3147
3148 // We are initializing an array on the stack.
3149 const ConstantArrayType *CAT =
3150 Ctx.getASTContext().getAsConstantArrayType(E->getType());
3151 assert(CAT && "a string literal that's not a constant array?");
3152
3153 // If the initializer string is too long, a diagnostic has already been
3154 // emitted. Read only the array length from the string literal.
3155 unsigned ArraySize = CAT->getZExtSize();
3156 unsigned N = std::min(ArraySize, E->getLength());
3157 unsigned CharWidth = E->getCharByteWidth();
3158
3159 for (unsigned I = 0; I != N; ++I) {
3160 uint32_t CodeUnit = E->getCodeUnit(I);
3161
3162 if (CharWidth == 1) {
3163 this->emitConstSint8(CodeUnit, E);
3164 this->emitInitElemSint8(I, E);
3165 } else if (CharWidth == 2) {
3166 this->emitConstUint16(CodeUnit, E);
3167 this->emitInitElemUint16(I, E);
3168 } else if (CharWidth == 4) {
3169 this->emitConstUint32(CodeUnit, E);
3170 this->emitInitElemUint32(I, E);
3171 } else {
3172 llvm_unreachable("unsupported character width");
3173 }
3174 }
3175
3176 // Fill up the rest of the char array with NUL bytes.
3177 for (unsigned I = N; I != ArraySize; ++I) {
3178 if (CharWidth == 1) {
3179 this->emitConstSint8(0, E);
3180 this->emitInitElemSint8(I, E);
3181 } else if (CharWidth == 2) {
3182 this->emitConstUint16(0, E);
3183 this->emitInitElemUint16(I, E);
3184 } else if (CharWidth == 4) {
3185 this->emitConstUint32(0, E);
3186 this->emitInitElemUint32(I, E);
3187 } else {
3188 llvm_unreachable("unsupported character width");
3189 }
3190 }
3191
3192 return true;
3193}
3194
3195template <class Emitter>
3197 if (DiscardResult)
3198 return true;
3199 return this->emitDummyPtr(E, E);
3200}
3201
3202template <class Emitter>
3204 auto &A = Ctx.getASTContext();
3205 std::string Str;
3206 A.getObjCEncodingForType(E->getEncodedType(), Str);
3207 StringLiteral *SL =
3209 /*Pascal=*/false, E->getType(), E->getAtLoc());
3210 return this->delegate(SL);
3211}
3212
3213template <class Emitter>
3215 const SYCLUniqueStableNameExpr *E) {
3216 if (DiscardResult)
3217 return true;
3218
3219 assert(!Initializing);
3220
3221 auto &A = Ctx.getASTContext();
3222 std::string ResultStr = E->ComputeName(A);
3223
3224 QualType CharTy = A.CharTy.withConst();
3225 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
3226 QualType ArrayTy = A.getConstantArrayType(CharTy, Size, nullptr,
3228
3229 StringLiteral *SL =
3231 /*Pascal=*/false, ArrayTy, E->getLocation());
3232 return this->emitGetStringPtr(SL, E);
3233}
3234
3235template <class Emitter>
3237 if (DiscardResult)
3238 return true;
3239 return this->emitConst(E->getValue(), E);
3240}
3241
3242template <class Emitter>
3244 const CompoundAssignOperator *E) {
3245
3246 const Expr *LHS = E->getLHS();
3247 const Expr *RHS = E->getRHS();
3248 QualType LHSType = LHS->getType();
3249 QualType LHSComputationType = E->getComputationLHSType();
3250 QualType ResultType = E->getComputationResultType();
3251 OptPrimType LT = classify(LHSComputationType);
3252 OptPrimType RT = classify(ResultType);
3253
3254 assert(ResultType->isFloatingType());
3255
3256 if (!LT || !RT)
3257 return false;
3258
3259 PrimType LHST = classifyPrim(LHSType);
3260
3261 if (isSideEffectFree(RHS)) {
3262 if (!visit(LHS))
3263 return false;
3264 if (!this->emitLoad(LHST, E))
3265 return false;
3266 // If necessary, convert LHS to its computation type.
3267 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
3268 LHSComputationType, E))
3269 return false;
3270 if (!visit(RHS))
3271 return false;
3272
3273 } else {
3274 // C++17 onwards require that we evaluate the RHS first.
3275 // Compute RHS and save it in a temporary variable so we can
3276 // load it again later.
3277 if (!visit(RHS))
3278 return false;
3279
3280 unsigned TempOffset =
3281 this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
3282 if (!this->emitSetLocal(*RT, TempOffset, E))
3283 return false;
3284
3285 // First, visit LHS.
3286 if (!visit(LHS))
3287 return false;
3288 if (!this->emitLoad(LHST, E))
3289 return false;
3290
3291 // If necessary, convert LHS to its computation type.
3292 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
3293 LHSComputationType, E))
3294 return false;
3295
3296 // Now load RHS.
3297 if (!this->emitGetLocal(*RT, TempOffset, E))
3298 return false;
3299 }
3300
3301 switch (E->getOpcode()) {
3302 case BO_AddAssign:
3303 if (!this->emitAddf(getFPOptions(E), E))
3304 return false;
3305 break;
3306 case BO_SubAssign:
3307 if (!this->emitSubf(getFPOptions(E), E))
3308 return false;
3309 break;
3310 case BO_MulAssign:
3311 if (!this->emitMulf(getFPOptions(E), E))
3312 return false;
3313 break;
3314 case BO_DivAssign:
3315 if (!this->emitDivf(getFPOptions(E), E))
3316 return false;
3317 break;
3318 default:
3319 return false;
3320 }
3321
3322 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->getType(), E))
3323 return false;
3324
3325 if (DiscardResult)
3326 return this->emitStorePop(LHST, E);
3327 return this->emitStore(LHST, E);
3328}
3329
3330template <class Emitter>
3332 const CompoundAssignOperator *E) {
3333 BinaryOperatorKind Op = E->getOpcode();
3334 const Expr *LHS = E->getLHS();
3335 const Expr *RHS = E->getRHS();
3336 OptPrimType LT = classify(LHS->getType());
3337 OptPrimType RT = classify(RHS->getType());
3338
3339 if (Op != BO_AddAssign && Op != BO_SubAssign)
3340 return false;
3341
3342 if (!LT || !RT)
3343 return false;
3344
3345 if (!visit(LHS))
3346 return false;
3347
3348 if (!this->emitLoad(*LT, LHS))
3349 return false;
3350
3351 if (!visit(RHS))
3352 return false;
3353
3354 if (Op == BO_AddAssign) {
3355 if (!this->emitAddOffset(*RT, E))
3356 return false;
3357 } else {
3358 if (!this->emitSubOffset(*RT, E))
3359 return false;
3360 }
3361
3362 if (DiscardResult)
3363 return this->emitStorePopPtr(E);
3364 return this->emitStorePtr(E);
3365}
3366
3367template <class Emitter>
3369 const CompoundAssignOperator *E) {
3370 if (E->getType()->isVectorType())
3371 return VisitVectorBinOp(E);
3372
3373 const Expr *LHS = E->getLHS();
3374 const Expr *RHS = E->getRHS();
3375 OptPrimType LHSComputationT = classify(E->getComputationLHSType());
3376 OptPrimType LT = classify(LHS->getType());
3377 OptPrimType RT = classify(RHS->getType());
3378 OptPrimType ResultT = classify(E->getType());
3379
3380 if (!Ctx.getLangOpts().CPlusPlus14)
3381 return this->visit(RHS) && this->visit(LHS) && this->emitError(E);
3382
3383 if (!LT || !RT || !ResultT || !LHSComputationT)
3384 return false;
3385
3386 // Handle floating point operations separately here, since they
3387 // require special care.
3388 if (ResultT == PT_Float || RT == PT_Float)
3390
3391 if (E->getType()->isPointerType())
3393
3394 assert(!E->getType()->isPointerType() && "Handled above");
3395 assert(!E->getType()->isFloatingType() && "Handled above");
3396
3397 if (isSideEffectFree(RHS)) {
3398 if (!visit(LHS))
3399 return false;
3400 if (!this->emitLoad(*LT, E))
3401 return false;
3402 if (LT != LHSComputationT &&
3403 !this->emitIntegralCast(*LT, *LHSComputationT,
3404 E->getComputationLHSType(), E))
3405 return false;
3406 if (!visit(RHS))
3407 return false;
3408 } else {
3409 // C++17 onwards require that we evaluate the RHS first.
3410 // Compute RHS and save it in a temporary variable so we can
3411 // load it again later.
3412 // FIXME: Compound assignments are unsequenced in C, so we might
3413 // have to figure out how to reject them.
3414 if (!visit(RHS))
3415 return false;
3416
3417 unsigned TempOffset =
3418 this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
3419
3420 if (!this->emitSetLocal(*RT, TempOffset, E))
3421 return false;
3422
3423 // Get LHS pointer, load its value and cast it to the
3424 // computation type if necessary.
3425 if (!visit(LHS))
3426 return false;
3427 if (!this->emitLoad(*LT, E))
3428 return false;
3429 if (LT != LHSComputationT &&
3430 !this->emitIntegralCast(*LT, *LHSComputationT,
3431 E->getComputationLHSType(), E))
3432 return false;
3433
3434 // Get the RHS value on the stack.
3435 if (!this->emitGetLocal(*RT, TempOffset, E))
3436 return false;
3437 }
3438
3439 // Perform operation.
3440 switch (E->getOpcode()) {
3441 case BO_AddAssign:
3442 if (!this->emitAdd(*LHSComputationT, E))
3443 return false;
3444 break;
3445 case BO_SubAssign:
3446 if (!this->emitSub(*LHSComputationT, E))
3447 return false;
3448 break;
3449 case BO_MulAssign:
3450 if (!this->emitMul(*LHSComputationT, E))
3451 return false;
3452 break;
3453 case BO_DivAssign:
3454 if (!this->emitDiv(*LHSComputationT, E))
3455 return false;
3456 break;
3457 case BO_RemAssign:
3458 if (!this->emitRem(*LHSComputationT, E))
3459 return false;
3460 break;
3461 case BO_ShlAssign:
3462 if (!this->emitShl(*LHSComputationT, *RT, E))
3463 return false;
3464 break;
3465 case BO_ShrAssign:
3466 if (!this->emitShr(*LHSComputationT, *RT, E))
3467 return false;
3468 break;
3469 case BO_AndAssign:
3470 if (!this->emitBitAnd(*LHSComputationT, E))
3471 return false;
3472 break;
3473 case BO_XorAssign:
3474 if (!this->emitBitXor(*LHSComputationT, E))
3475 return false;
3476 break;
3477 case BO_OrAssign:
3478 if (!this->emitBitOr(*LHSComputationT, E))
3479 return false;
3480 break;
3481 default:
3482 llvm_unreachable("Unimplemented compound assign operator");
3483 }
3484
3485 // And now cast from LHSComputationT to ResultT.
3486 if (ResultT != LHSComputationT &&
3487 !this->emitIntegralCast(*LHSComputationT, *ResultT, E->getType(), E))
3488 return false;
3489
3490 // And store the result in LHS.
3491 if (DiscardResult) {
3492 if (LHS->refersToBitField())
3493 return this->emitStoreBitFieldPop(*ResultT, E);
3494 return this->emitStorePop(*ResultT, E);
3495 }
3496 if (LHS->refersToBitField())
3497 return this->emitStoreBitField(*ResultT, E);
3498 return this->emitStore(*ResultT, E);
3499}
3500
3501template <class Emitter>
3504 const Expr *SubExpr = E->getSubExpr();
3505
3506 return this->delegate(SubExpr) && ES.destroyLocals(E);
3507}
3508
3509template <class Emitter>
3511 const MaterializeTemporaryExpr *E) {
3512 if (Initializing) {
3513 // We already have a value, just initialize that.
3514 return this->delegate(E->getSubExpr());
3515 }
3516 // If we don't end up using the materialized temporary anyway, don't
3517 // bother creating it.
3518 if (DiscardResult)
3519 return this->discard(E->getSubExpr());
3520
3523 const Expr *Inner;
3524 if (!Ctx.getLangOpts().CPlusPlus11)
3525 Inner =
3526 E->getSubExpr()->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
3527 else
3528 Inner = E->getSubExpr();
3529
3530 // If we passed any comma operators, evaluate their LHSs.
3531 for (const Expr *LHS : CommaLHSs) {
3532 if (!this->discard(LHS))
3533 return false;
3534 }
3535
3536 // FIXME: Find a test case where Adjustments matters.
3537
3538 // When we're extending a global variable *or* the storage duration of
3539 // the temporary is explicitly static, create a global variable.
3540 OptPrimType InnerT = classify(Inner);
3541 const ValueDecl *ExtendingDecl = E->getExtendingDecl();
3542 bool IsStatic = E->getStorageDuration() == SD_Static;
3543 if (IsStatic ||
3544 (ExtendingDecl && Context::shouldBeGloballyIndexed(ExtendingDecl))) {
3545 UnsignedOrNone GlobalIndex = P.createGlobal(E, Inner->getType());
3546 if (!GlobalIndex)
3547 return false;
3548
3549 const LifetimeExtendedTemporaryDecl *TempDecl =
3551
3552 if (InnerT) {
3553 if (!this->visit(Inner))
3554 return false;
3555
3556 if (IsStatic) {
3557 assert(TempDecl);
3558 if (!this->emitInitGlobalTemp(*InnerT, *GlobalIndex, TempDecl, E))
3559 return false;
3560 } else {
3561 if (!this->emitInitGlobal(*InnerT, *GlobalIndex, E))
3562 return false;
3563 }
3564 return this->emitGetPtrGlobal(*GlobalIndex, E);
3565 }
3566
3567 if (!this->checkLiteralType(Inner))
3568 return false;
3569 // Non-primitive values.
3570 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3571 return false;
3572 if (!this->visitInitializer(Inner))
3573 return false;
3574 if (IsStatic) {
3575 assert(TempDecl);
3576 return this->emitInitGlobalTempComp(TempDecl, E);
3577 }
3578 return true;
3579 }
3580
3584
3585 // For everyhing else, use local variables.
3586 if (InnerT) {
3587 bool IsConst = Inner->getType().isConstQualified();
3588 bool IsVolatile = Inner->getType().isVolatileQualified();
3589 unsigned LocalIndex =
3590 allocateLocalPrimitive(E, *InnerT, IsConst, IsVolatile, VarScope);
3591 if (!this->VarScope->LocalsAlwaysEnabled &&
3592 !this->emitEnableLocal(LocalIndex, E))
3593 return false;
3594
3595 if (!this->visit(Inner))
3596 return false;
3597 if (!this->emitSetLocal(*InnerT, LocalIndex, E))
3598 return false;
3599
3600 return this->emitGetPtrLocal(LocalIndex, E);
3601 }
3602
3603 if (!this->checkLiteralType(Inner))
3604 return false;
3605
3606 if (UnsignedOrNone LocalIndex =
3607 allocateLocal(E, Inner->getType(), VarScope)) {
3608 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
3609
3610 if (!this->VarScope->LocalsAlwaysEnabled &&
3611 !this->emitEnableLocal(*LocalIndex, E))
3612 return false;
3613
3614 if (!this->emitGetPtrLocal(*LocalIndex, E))
3615 return false;
3616 return this->visitInitializer(Inner);
3617 }
3618 return false;
3619}
3620
3621template <class Emitter>
3623 const CXXBindTemporaryExpr *E) {
3624 const Expr *SubExpr = E->getSubExpr();
3625
3626 if (Initializing)
3627 return this->delegate(SubExpr);
3628
3629 // Make sure we create a temporary even if we're discarding, since that will
3630 // make sure we will also call the destructor.
3631
3632 if (!this->visit(SubExpr))
3633 return false;
3634
3635 if (DiscardResult)
3636 return this->emitPopPtr(E);
3637 return true;
3638}
3639
3640template <class Emitter>
3642 const Expr *Init = E->getInitializer();
3643 if (DiscardResult)
3644 return this->discard(Init);
3645
3646 if (Initializing) {
3647 // We already have a value, just initialize that.
3648 return this->visitInitializer(Init);
3649 }
3650
3651 OptPrimType T = classify(E->getType());
3652 if (E->isFileScope()) {
3653 // Avoid creating a variable if this is a primitive RValue anyway.
3654 if (T && !E->isLValue())
3655 return this->delegate(Init);
3656
3657 UnsignedOrNone GlobalIndex = P.createGlobal(E, E->getType());
3658 if (!GlobalIndex)
3659 return false;
3660
3661 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3662 return false;
3663
3664 // Since this is a global variable, we might've already seen,
3665 // don't do it again.
3666 if (P.isGlobalInitialized(*GlobalIndex))
3667 return true;
3668
3669 if (T) {
3670 if (!this->visit(Init))
3671 return false;
3672 return this->emitInitGlobal(*T, *GlobalIndex, E);
3673 }
3674
3675 return this->visitInitializer(Init);
3676 }
3677
3678 // Otherwise, use a local variable.
3679 if (T && !E->isLValue()) {
3680 // For primitive types, we just visit the initializer.
3681 return this->delegate(Init);
3682 }
3683
3684 unsigned LocalIndex;
3685 if (T)
3686 LocalIndex = this->allocateLocalPrimitive(Init, *T, /*IsConst=*/false);
3687 else if (UnsignedOrNone MaybeIndex = this->allocateLocal(Init))
3688 LocalIndex = *MaybeIndex;
3689 else
3690 return false;
3691
3692 if (!this->emitGetPtrLocal(LocalIndex, E))
3693 return false;
3694
3695 if (T)
3696 return this->visit(Init) && this->emitInit(*T, E);
3697 return this->visitInitializer(Init);
3698}
3699
3700template <class Emitter>
3702 if (DiscardResult)
3703 return true;
3704 if (E->isStoredAsBoolean()) {
3705 if (E->getType()->isBooleanType())
3706 return this->emitConstBool(E->getBoolValue(), E);
3707 return this->emitConst(E->getBoolValue(), E);
3708 }
3709 if (E->isStoredAsComparisonResult()) {
3710 const ComparisonCategoryInfo &CmpInfo =
3711 Ctx.getASTContext().CompCategories.getInfoForType(E->getType());
3712 const auto Result =
3713 ComparisonCategoryResult(E->getAPValue().getInt().getZExtValue());
3714 const Record *R = getRecord(E->getType());
3715 if (!R || R->getNumFields() == 0)
3716 return false;
3717 const Record::Field *Field = R->getField(0U);
3718 assert(Field->T);
3719 if (!this->emitConst(CmpInfo.getValueInfo(Result)->getIntValue(), *Field->T,
3720 E))
3721 return false;
3722 return this->emitInitField(*Field->T, Field->Offset, E);
3723 }
3724
3726 return this->visitAPValue(E->getAPValue(), T, E);
3727}
3728
3729template <class Emitter>
3731 if (DiscardResult)
3732 return true;
3733 return this->emitConst(E->getValue(), E);
3734}
3735
3736template <class Emitter>
3738 if (DiscardResult)
3739 return true;
3740
3741 assert(Initializing);
3742 const Record *R = P.getOrCreateRecord(E->getLambdaClass());
3743 if (!R)
3744 return false;
3745
3746 auto *CaptureInitIt = E->capture_init_begin();
3747 // Initialize all fields (which represent lambda captures) of the
3748 // record with their initializers.
3749 for (const Record::Field &F : R->fields()) {
3750 const Expr *Init = *CaptureInitIt;
3751 if (!Init || Init->containsErrors())
3752 continue;
3753 ++CaptureInitIt;
3754
3755 if (OptPrimType T = classify(Init)) {
3756 if (!this->visit(Init))
3757 return false;
3758
3759 if (!this->emitInitField(*T, F.Offset, E))
3760 return false;
3761 } else {
3762 if (!this->emitGetPtrField(F.Offset, E))
3763 return false;
3764
3765 if (!this->visitInitializerPop(Init))
3766 return false;
3767 }
3768 }
3769
3770 return true;
3771}
3772
3773template <class Emitter>
3775 if (DiscardResult)
3776 return true;
3777
3778 if (!Initializing)
3779 return this->emitGetStringPtr(E, E);
3780 return this->delegate(E->getFunctionName());
3781}
3782
3783template <class Emitter>
3785 if (E->getSubExpr() && !this->discard(E->getSubExpr()))
3786 return false;
3787
3788 return this->emitInvalid(E);
3789}
3790
3791template <class Emitter>
3793 const CXXReinterpretCastExpr *E) {
3794 const Expr *SubExpr = E->getSubExpr();
3795
3796 OptPrimType FromT = classify(SubExpr);
3797 OptPrimType ToT = classify(E);
3798
3799 if (!FromT || !ToT)
3800 return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, E);
3801
3802 if (FromT == PT_Ptr || ToT == PT_Ptr) {
3805 if (!this->emitInvalidCast(CastKind, /*Fatal=*/false, E))
3806 return false;
3807 if (E->getCastKind() == CK_LValueBitCast)
3808 return this->delegate(SubExpr);
3809 return this->VisitCastExpr(E);
3810 }
3811
3812 // Try to actually do the cast.
3813 bool Fatal = (ToT != FromT);
3814 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal, E))
3815 return false;
3816
3817 return this->VisitCastExpr(E);
3818}
3819
3820template <class Emitter>
3822 if (!Ctx.getLangOpts().CPlusPlus20) {
3823 if (!this->emitInvalidCast(CastKind::Dynamic, /*Fatal=*/false, E))
3824 return false;
3825 }
3826
3827 if (E->getCastKind() != CK_Dynamic)
3828 return this->VisitCastExpr(E);
3829
3830 QualType DestType = E->getType();
3831 // "target type must be a reference or pointer type to a defined class"
3832 if (DestType->isRecordType()) {
3833 assert(E->isGLValue());
3834 } else {
3835 assert(DestType->isPointerOrReferenceType());
3836 assert(DestType->isVoidPointerType() ||
3837 DestType->getPointeeType()->isRecordType());
3838 DestType = DestType->getPointeeType();
3839 }
3840
3841 if (!this->visit(E->getSubExpr()))
3842 return false;
3843 if (!this->emitDynamicCast(DestType.getTypePtr(),
3844 /*IsReferenceCast=*/E->isGLValue(), E))
3845 return false;
3846
3847 if (DiscardResult)
3848 return this->emitPopPtr(E);
3849 return true;
3850}
3851
3852template <class Emitter>
3854 assert(E->getType()->isBooleanType());
3855
3856 if (DiscardResult)
3857 return true;
3858 return this->emitConstBool(E->getValue(), E);
3859}
3860
3861template <class Emitter>
3863 QualType T = E->getType();
3864 assert(!canClassify(T));
3865
3866 if (T->isRecordType()) {
3867 const CXXConstructorDecl *Ctor = E->getConstructor();
3868
3869 // If we're discarding a construct expression, we still need
3870 // to allocate a variable and call the constructor and destructor.
3871 if (DiscardResult) {
3872 if (Ctor->isTrivial())
3873 return true;
3874 assert(!Initializing);
3875 UnsignedOrNone LocalIndex = allocateLocal(E);
3876
3877 if (!LocalIndex)
3878 return false;
3879
3880 if (!this->emitGetPtrLocal(*LocalIndex, E))
3881 return false;
3882 }
3883
3884 // Trivial copy/move constructor. Avoid copy.
3885 if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&
3886 Ctor->isTrivial() &&
3887 E->getArg(0)->isTemporaryObject(Ctx.getASTContext(),
3888 T->getAsCXXRecordDecl()))
3889 return this->visitInitializer(E->getArg(0));
3890
3891 // Zero initialization.
3892 bool ZeroInit = E->requiresZeroInitialization();
3893 if (ZeroInit) {
3894 const Record *R = getRecord(E->getType());
3895 if (!R)
3896 return false;
3897
3898 if (!this->visitZeroRecordInitializer(R, E))
3899 return false;
3900
3901 // If the constructor is trivial anyway, we're done.
3902 if (Ctor->isTrivial())
3903 return true;
3904 }
3905
3906 // Trivial default constructors might never be implicitly defined by the
3907 // AST, so we need to special-case them here.
3908 if (Ctor->isTrivial() && Ctor->isDefaultConstructor()) {
3909 if (!this->emitDefaultInit(Ctor, E))
3910 return false;
3911 if (DiscardResult)
3912 return this->emitPopPtr(E);
3913 return true;
3914 }
3915
3916 // Avoid materializing a temporary for an elidable copy/move constructor.
3917 if (!ZeroInit && E->isElidable()) {
3918 const Expr *SrcObj = E->getArg(0);
3919 assert(SrcObj->isTemporaryObject(Ctx.getASTContext(), Ctor->getParent()));
3920 assert(Ctx.getASTContext().hasSameUnqualifiedType(E->getType(),
3921 SrcObj->getType()));
3922 if (const auto *ME = dyn_cast<MaterializeTemporaryExpr>(SrcObj)) {
3923 if (!this->emitCheckFunctionDecl(Ctor, E))
3924 return false;
3925 return this->visitInitializer(ME->getSubExpr());
3926 }
3927 }
3928
3929 const Function *Func = getFunction(Ctor);
3930
3931 if (!Func)
3932 return false;
3933
3934 assert(Func->hasThisPointer());
3935 assert(!Func->hasRVO());
3936
3937 // The This pointer is already on the stack because this is an initializer,
3938 // but we need to dup() so the call() below has its own copy.
3939 if (!this->emitDupPtr(E))
3940 return false;
3941
3942 // Constructor arguments.
3943 for (const auto *Arg : E->arguments()) {
3944 if (!this->visit(Arg))
3945 return false;
3946 }
3947
3948 if (Func->isVariadic()) {
3949 uint32_t VarArgSize = 0;
3950 unsigned NumParams = Func->getNumWrittenParams();
3951 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I) {
3952 VarArgSize +=
3953 align(primSize(classify(E->getArg(I)->getType()).value_or(PT_Ptr)));
3954 }
3955 if (!this->emitCallVar(Func, VarArgSize, E))
3956 return false;
3957 } else {
3958 if (!this->emitCall(Func, 0, E)) {
3959 // When discarding, we don't need the result anyway, so clean up
3960 // the instance dup we did earlier in case surrounding code wants
3961 // to keep evaluating.
3962 if (DiscardResult)
3963 (void)this->emitPopPtr(E);
3964 return false;
3965 }
3966 }
3967
3968 if (DiscardResult)
3969 return this->emitPopPtr(E);
3970 return true;
3971 }
3972
3973 if (T->isArrayType()) {
3974 const Function *Func = getFunction(E->getConstructor());
3975 if (!Func)
3976 return false;
3977
3978 if (!this->emitDupPtr(E))
3979 return false;
3980
3981 std::function<bool(QualType)> initArrayDimension;
3982 initArrayDimension = [&](QualType T) -> bool {
3983 if (!T->isArrayType()) {
3984 // Constructor arguments.
3985 for (const auto *Arg : E->arguments()) {
3986 if (!this->visit(Arg))
3987 return false;
3988 }
3989
3990 return this->emitCall(Func, 0, E);
3991 }
3992
3993 const ConstantArrayType *CAT =
3994 Ctx.getASTContext().getAsConstantArrayType(T);
3995 if (!CAT)
3996 return false;
3997 QualType ElemTy = CAT->getElementType();
3998 unsigned NumElems = CAT->getZExtSize();
3999 for (size_t I = 0; I != NumElems; ++I) {
4000 if (!this->emitConstUint64(I, E))
4001 return false;
4002 if (!this->emitArrayElemPtrUint64(E))
4003 return false;
4004 if (!initArrayDimension(ElemTy))
4005 return false;
4006 }
4007 return this->emitPopPtr(E);
4008 };
4009
4010 return initArrayDimension(E->getType());
4011 }
4012
4013 return false;
4014}
4015
4016template <class Emitter>
4018 if (DiscardResult)
4019 return true;
4020
4021 const APValue Val =
4022 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
4023
4024 // Things like __builtin_LINE().
4025 if (E->getType()->isIntegerType()) {
4026 assert(Val.isInt());
4027 const APSInt &I = Val.getInt();
4028 return this->emitConst(I, E);
4029 }
4030 // Otherwise, the APValue is an LValue, with only one element.
4031 // Theoretically, we don't need the APValue at all of course.
4032 assert(E->getType()->isPointerType());
4033 assert(Val.isLValue());
4034 const APValue::LValueBase &Base = Val.getLValueBase();
4035 if (const Expr *LValueExpr = Base.dyn_cast<const Expr *>())
4036 return this->visit(LValueExpr);
4037
4038 // Otherwise, we have a decl (which is the case for
4039 // __builtin_source_location).
4040 assert(Base.is<const ValueDecl *>());
4041 assert(Val.getLValuePath().size() == 0);
4042 const auto *BaseDecl = Base.dyn_cast<const ValueDecl *>();
4043 assert(BaseDecl);
4044
4045 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
4046
4047 UnsignedOrNone GlobalIndex = P.getOrCreateGlobal(UGCD);
4048 if (!GlobalIndex)
4049 return false;
4050
4051 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4052 return false;
4053
4054 const Record *R = getRecord(E->getType());
4055 const APValue &V = UGCD->getValue();
4056 for (unsigned I = 0, N = R->getNumFields(); I != N; ++I) {
4057 const Record::Field *F = R->getField(I);
4058 const APValue &FieldValue = V.getStructField(I);
4059
4060 if (!this->visitAPValue(FieldValue, *F->T, E))
4061 return false;
4062 if (!this->emitInitField(*F->T, F->Offset, E))
4063 return false;
4064 }
4065
4066 // Leave the pointer to the global on the stack.
4067 return true;
4068}
4069
4070template <class Emitter>
4072 unsigned N = E->getNumComponents();
4073 if (N == 0)
4074 return false;
4075
4076 for (unsigned I = 0; I != N; ++I) {
4077 const OffsetOfNode &Node = E->getComponent(I);
4078 if (Node.getKind() == OffsetOfNode::Array) {
4079 const Expr *ArrayIndexExpr = E->getIndexExpr(Node.getArrayExprIndex());
4080 PrimType IndexT = classifyPrim(ArrayIndexExpr->getType());
4081
4082 if (DiscardResult) {
4083 if (!this->discard(ArrayIndexExpr))
4084 return false;
4085 continue;
4086 }
4087
4088 if (IndexT == PT_IntAP || IndexT == PT_IntAPS) {
4089 if (!this->visit(ArrayIndexExpr))
4090 return false;
4091 if (!this->emitCastAPToOffsetIndex(IndexT, E))
4092 return false;
4093 continue;
4094 }
4095 if (!this->visit(ArrayIndexExpr))
4096 return false;
4097 // Cast to Sint64.
4098 if (IndexT != PT_Sint64) {
4099 if (!this->emitCast(IndexT, PT_Sint64, E))
4100 return false;
4101 }
4102 }
4103 }
4104
4105 if (DiscardResult)
4106 return true;
4107
4109 return this->emitOffsetOf(T, E, E);
4110}
4111
4112template <class Emitter>
4114 const CXXScalarValueInitExpr *E) {
4115 QualType Ty = E->getType();
4116
4117 if (DiscardResult || Ty->isVoidType())
4118 return true;
4119
4120 if (OptPrimType T = classify(Ty))
4121 return this->visitZeroInitializer(*T, Ty, E);
4122
4123 if (Ty->isAnyComplexType() || Ty->isVectorType()) {
4124 if (!Initializing) {
4125 UnsignedOrNone LocalIndex = allocateLocal(E);
4126 if (!LocalIndex)
4127 return false;
4128 if (!this->emitGetPtrLocal(*LocalIndex, E))
4129 return false;
4130 }
4131
4132 QualType ElemQT;
4133 unsigned NumElems;
4134 if (const auto *CT = Ty->getAs<ComplexType>()) {
4135 NumElems = 2;
4136 ElemQT = CT->getElementType();
4137 } else {
4138 const auto *VT = Ty->castAs<VectorType>();
4139 NumElems = VT->getNumElements();
4140 ElemQT = VT->getElementType();
4141 }
4142
4143 PrimType ElemT = classifyPrim(ElemQT);
4144
4145 // Initialize all fields to 0.
4146 for (unsigned I = 0; I != NumElems; ++I) {
4147 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
4148 return false;
4149 if (!this->emitInitElem(ElemT, I, E))
4150 return false;
4151 }
4152 return true;
4153 }
4154
4155 return false;
4156}
4157
4158template <class Emitter>
4160 return this->emitConst(E->getPackLength(), E);
4161}
4162
4163template <class Emitter>
4168
4169template <class Emitter>
4171 return this->delegate(E->getChosenSubExpr());
4172}
4173
4174template <class Emitter>
4176 if (DiscardResult)
4177 return true;
4178
4179 return this->emitConst(E->getValue(), E);
4180}
4181
4182template <class Emitter>
4184 const CXXInheritedCtorInitExpr *E) {
4185 const CXXConstructorDecl *Ctor = E->getConstructor();
4186 assert(!Ctor->isTrivial() &&
4187 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
4188 const Function *F = this->getFunction(Ctor);
4189 if (!F)
4190 return false;
4191 assert(!F->hasRVO());
4192 assert(F->hasThisPointer());
4193
4194 if (!this->emitDupPtr(SourceInfo{}))
4195 return false;
4196
4197 // Forward all arguments of the current function (which should be a
4198 // constructor itself) to the inherited ctor.
4199 // This is necessary because the calling code has pushed the pointer
4200 // of the correct base for us already, but the arguments need
4201 // to come after.
4202 unsigned ParamIndex = 0;
4203 for (const ParmVarDecl *PD : Ctor->parameters()) {
4204 PrimType PT = this->classify(PD->getType()).value_or(PT_Ptr);
4205
4206 if (!this->emitGetParam(PT, ParamIndex, E))
4207 return false;
4208 ++ParamIndex;
4209 }
4210
4211 return this->emitCall(F, 0, E);
4212}
4213
4214// FIXME: This function has become rather unwieldy, especially
4215// the part where we initialize an array allocation of dynamic size.
4216template <class Emitter>
4218 assert(classifyPrim(E->getType()) == PT_Ptr);
4219 const Expr *Init = E->getInitializer();
4220 QualType ElementType = E->getAllocatedType();
4221 OptPrimType ElemT = classify(ElementType);
4222 unsigned PlacementArgs = E->getNumPlacementArgs();
4223 const FunctionDecl *OperatorNew = E->getOperatorNew();
4224 const Expr *PlacementDest = nullptr;
4225 bool IsNoThrow = false;
4226
4227 if (E->containsErrors())
4228 return false;
4229
4230 if (PlacementArgs != 0) {
4231 // FIXME: There is no restriction on this, but it's not clear that any
4232 // other form makes any sense. We get here for cases such as:
4233 //
4234 // new (std::align_val_t{N}) X(int)
4235 //
4236 // (which should presumably be valid only if N is a multiple of
4237 // alignof(int), and in any case can't be deallocated unless N is
4238 // alignof(X) and X has new-extended alignment).
4239 if (PlacementArgs == 1) {
4240 const Expr *Arg1 = E->getPlacementArg(0);
4241 if (Arg1->getType()->isNothrowT()) {
4242 if (!this->discard(Arg1))
4243 return false;
4244 IsNoThrow = true;
4245 } else {
4246 // Invalid unless we have C++26 or are in a std:: function.
4247 if (!this->emitInvalidNewDeleteExpr(E, E))
4248 return false;
4249
4250 // If we have a placement-new destination, we'll later use that instead
4251 // of allocating.
4252 if (OperatorNew->isReservedGlobalPlacementOperator())
4253 PlacementDest = Arg1;
4254 }
4255 } else {
4256 // Always invalid.
4257 return this->emitInvalid(E);
4258 }
4259 } else if (!OperatorNew
4260 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4261 return this->emitInvalidNewDeleteExpr(E, E);
4262
4263 const Descriptor *Desc;
4264 if (!PlacementDest) {
4265 if (ElemT) {
4266 if (E->isArray())
4267 Desc = nullptr; // We're not going to use it in this case.
4268 else
4269 Desc = P.createDescriptor(E, *ElemT);
4270 } else {
4271 Desc = P.createDescriptor(E, ElementType.getTypePtr(), /*IsConst=*/false,
4272 /*IsTemporary=*/false, /*IsMutable=*/false,
4273 /*IsVolatile=*/false, Init);
4274 }
4275 }
4276
4277 if (E->isArray()) {
4278 std::optional<const Expr *> ArraySizeExpr = E->getArraySize();
4279 if (!ArraySizeExpr)
4280 return false;
4281
4282 const Expr *Stripped = *ArraySizeExpr;
4283 for (; auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
4284 Stripped = ICE->getSubExpr())
4285 if (ICE->getCastKind() != CK_NoOp &&
4286 ICE->getCastKind() != CK_IntegralCast)
4287 break;
4288
4289 PrimType SizeT = classifyPrim(Stripped->getType());
4290
4291 // Save evaluated array size to a variable.
4292 unsigned ArrayLen =
4293 allocateLocalPrimitive(Stripped, SizeT, /*IsConst=*/false);
4294 if (!this->visit(Stripped))
4295 return false;
4296 if (!this->emitSetLocal(SizeT, ArrayLen, E))
4297 return false;
4298
4299 if (PlacementDest) {
4300 if (!this->visit(PlacementDest))
4301 return false;
4302 if (!this->emitGetLocal(SizeT, ArrayLen, E))
4303 return false;
4304 if (!this->emitCheckNewTypeMismatchArray(SizeT, E, E))
4305 return false;
4306 } else {
4307 if (!this->emitGetLocal(SizeT, ArrayLen, E))
4308 return false;
4309
4310 if (ElemT) {
4311 // N primitive elements.
4312 if (!this->emitAllocN(SizeT, *ElemT, E, IsNoThrow, E))
4313 return false;
4314 } else {
4315 // N Composite elements.
4316 if (!this->emitAllocCN(SizeT, Desc, IsNoThrow, E))
4317 return false;
4318 }
4319 }
4320
4321 if (Init) {
4322 QualType InitType = Init->getType();
4323 size_t StaticInitElems = 0;
4324 const Expr *DynamicInit = nullptr;
4325 OptPrimType ElemT;
4326
4327 if (const ConstantArrayType *CAT =
4328 Ctx.getASTContext().getAsConstantArrayType(InitType)) {
4329 StaticInitElems = CAT->getZExtSize();
4330 // Initialize the first S element from the initializer.
4331 if (!this->visitInitializer(Init))
4332 return false;
4333
4334 if (const auto *ILE = dyn_cast<InitListExpr>(Init)) {
4335 if (ILE->hasArrayFiller())
4336 DynamicInit = ILE->getArrayFiller();
4337 else if (StaticInitElems > 0 && isa<StringLiteral>(ILE->getInit(0)))
4338 ElemT = classifyPrim(CAT->getElementType());
4339 }
4340 }
4341
4342 // The initializer initializes a certain number of elements, S.
4343 // However, the complete number of elements, N, might be larger than that.
4344 // In this case, we need to get an initializer for the remaining elements.
4345 // There are three cases:
4346 // 1) For the form 'new Struct[n];', the initializer is a
4347 // CXXConstructExpr and its type is an IncompleteArrayType.
4348 // 2) For the form 'new Struct[n]{1,2,3}', the initializer is an
4349 // InitListExpr and the initializer for the remaining elements
4350 // is the array filler.
4351 // 3) StringLiterals don't have an array filler, so we need to zero
4352 // the remaining elements.
4353
4354 if (DynamicInit || ElemT || InitType->isIncompleteArrayType()) {
4355 const Function *CtorFunc = nullptr;
4356 if (const auto *CE = dyn_cast<CXXConstructExpr>(Init)) {
4357 CtorFunc = getFunction(CE->getConstructor());
4358 if (!CtorFunc)
4359 return false;
4360 } else if (!DynamicInit && !ElemT)
4361 DynamicInit = Init;
4362
4363 LabelTy EndLabel = this->getLabel();
4364 LabelTy StartLabel = this->getLabel();
4365
4366 // In the nothrow case, the alloc above might have returned nullptr.
4367 // Don't call any constructors that case.
4368 if (IsNoThrow) {
4369 if (!this->emitDupPtr(E))
4370 return false;
4371 if (!this->emitIsNonNullPtr(E))
4372 return false;
4373 if (!this->jumpFalse(EndLabel, E))
4374 return false;
4375 }
4376
4377 // Create loop variables.
4378 unsigned Iter =
4379 allocateLocalPrimitive(Stripped, SizeT, /*IsConst=*/false);
4380 if (!this->emitConst(StaticInitElems, SizeT, E))
4381 return false;
4382 if (!this->emitSetLocal(SizeT, Iter, E))
4383 return false;
4384
4385 this->fallthrough(StartLabel);
4386 this->emitLabel(StartLabel);
4387 // Condition. Iter < ArrayLen?
4388 if (!this->emitGetLocal(SizeT, Iter, E))
4389 return false;
4390 if (!this->emitGetLocal(SizeT, ArrayLen, E))
4391 return false;
4392 if (!this->emitLT(SizeT, E))
4393 return false;
4394 if (!this->jumpFalse(EndLabel, E))
4395 return false;
4396
4397 // Pointer to the allocated array is already on the stack.
4398 if (!this->emitGetLocal(SizeT, Iter, E))
4399 return false;
4400 if (!this->emitArrayElemPtr(SizeT, E))
4401 return false;
4402
4403 if (isa_and_nonnull<ImplicitValueInitExpr>(DynamicInit) &&
4404 DynamicInit->getType()->isArrayType()) {
4405 QualType ElemType =
4406 DynamicInit->getType()->getAsArrayTypeUnsafe()->getElementType();
4407 if (OptPrimType InitT = classify(ElemType)) {
4408 if (!this->visitZeroInitializer(*InitT, ElemType, E))
4409 return false;
4410 if (!this->emitStorePop(*InitT, E))
4411 return false;
4412 } else {
4413 assert(ElemType->isArrayType());
4414 if (!this->visitZeroArrayInitializer(ElemType, E))
4415 return false;
4416 }
4417 } else if (DynamicInit) {
4418 if (OptPrimType InitT = classify(DynamicInit)) {
4419 if (!this->visit(DynamicInit))
4420 return false;
4421 if (!this->emitStorePop(*InitT, E))
4422 return false;
4423 } else {
4424 if (!this->visitInitializerPop(DynamicInit))
4425 return false;
4426 }
4427 } else if (ElemT) {
4428 if (!this->visitZeroInitializer(
4429 *ElemT, InitType->getAsArrayTypeUnsafe()->getElementType(),
4430 Init))
4431 return false;
4432 if (!this->emitStorePop(*ElemT, E))
4433 return false;
4434 } else {
4435 assert(CtorFunc);
4436 if (!this->emitCall(CtorFunc, 0, E))
4437 return false;
4438 }
4439
4440 // ++Iter;
4441 if (!this->emitGetPtrLocal(Iter, E))
4442 return false;
4443 if (!this->emitIncPop(SizeT, false, E))
4444 return false;
4445
4446 if (!this->jump(StartLabel, E))
4447 return false;
4448
4449 this->fallthrough(EndLabel);
4450 this->emitLabel(EndLabel);
4451 }
4452 }
4453 } else { // Non-array.
4454 if (PlacementDest) {
4455 if (!this->visit(PlacementDest))
4456 return false;
4457 if (!this->emitCheckNewTypeMismatch(E, E))
4458 return false;
4459
4460 } else {
4461 // Allocate just one element.
4462 if (!this->emitAlloc(Desc, E))
4463 return false;
4464 }
4465
4466 if (Init) {
4467 if (ElemT) {
4468 if (!this->visit(Init))
4469 return false;
4470
4471 if (!this->emitInit(*ElemT, E))
4472 return false;
4473 } else {
4474 // Composite.
4475 if (!this->visitInitializer(Init))
4476 return false;
4477 }
4478 }
4479 }
4480
4481 if (DiscardResult)
4482 return this->emitPopPtr(E);
4483
4484 return true;
4485}
4486
4487template <class Emitter>
4489 if (E->containsErrors())
4490 return false;
4491 const FunctionDecl *OperatorDelete = E->getOperatorDelete();
4492
4493 if (!OperatorDelete->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4494 return this->emitInvalidNewDeleteExpr(E, E);
4495
4496 // Arg must be an lvalue.
4497 if (!this->visit(E->getArgument()))
4498 return false;
4499
4500 return this->emitFree(E->isArrayForm(), E->isGlobalDelete(), E);
4501}
4502
4503template <class Emitter>
4505 if (DiscardResult)
4506 return true;
4507
4508 const Function *Func = nullptr;
4509 if (const Function *F = Ctx.getOrCreateObjCBlock(E))
4510 Func = F;
4511
4512 if (!Func)
4513 return false;
4514 return this->emitGetFnPtr(Func, E);
4515}
4516
4517template <class Emitter>
4519 const Type *TypeInfoType = E->getType().getTypePtr();
4520
4521 auto canonType = [](const Type *T) {
4522 return T->getCanonicalTypeUnqualified().getTypePtr();
4523 };
4524
4525 if (!E->isPotentiallyEvaluated()) {
4526 if (DiscardResult)
4527 return true;
4528
4529 if (E->isTypeOperand())
4530 return this->emitGetTypeid(
4531 canonType(E->getTypeOperand(Ctx.getASTContext()).getTypePtr()),
4532 TypeInfoType, E);
4533
4534 return this->emitGetTypeid(
4535 canonType(E->getExprOperand()->getType().getTypePtr()), TypeInfoType,
4536 E);
4537 }
4538
4539 // Otherwise, we need to evaluate the expression operand.
4540 assert(E->getExprOperand());
4541 assert(E->getExprOperand()->isLValue());
4542
4543 if (!Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(E))
4544 return false;
4545
4546 if (!this->visit(E->getExprOperand()))
4547 return false;
4548
4549 if (!this->emitGetTypeidPtr(TypeInfoType, E))
4550 return false;
4551 if (DiscardResult)
4552 return this->emitPopPtr(E);
4553 return true;
4554}
4555
4556template <class Emitter>
4558 const ObjCDictionaryLiteral *E) {
4560 return this->emitDummyPtr(E, E);
4561 return this->emitError(E);
4562}
4563
4564template <class Emitter>
4567 return this->emitDummyPtr(E, E);
4568 return this->emitError(E);
4569}
4570
4571template <class Emitter>
4573 assert(Ctx.getLangOpts().CPlusPlus);
4574 return this->emitConstBool(E->getValue(), E);
4575}
4576
4577template <class Emitter>
4579 if (DiscardResult)
4580 return true;
4581 assert(!Initializing);
4582
4583 const MSGuidDecl *GuidDecl = E->getGuidDecl();
4584 const RecordDecl *RD = GuidDecl->getType()->getAsRecordDecl();
4585 assert(RD);
4586 // If the definiton of the result type is incomplete, just return a dummy.
4587 // If (and when) that is read from, we will fail, but not now.
4588 if (!RD->isCompleteDefinition())
4589 return this->emitDummyPtr(GuidDecl, E);
4590
4591 UnsignedOrNone GlobalIndex = P.getOrCreateGlobal(GuidDecl);
4592 if (!GlobalIndex)
4593 return false;
4594 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4595 return false;
4596
4597 assert(this->getRecord(E->getType()));
4598
4599 const APValue &V = GuidDecl->getAsAPValue();
4600 if (V.getKind() == APValue::None)
4601 return true;
4602
4603 assert(V.isStruct());
4604 assert(V.getStructNumBases() == 0);
4605 if (!this->visitAPValueInitializer(V, E, E->getType()))
4606 return false;
4607
4608 return this->emitFinishInit(E);
4609}
4610
4611template <class Emitter>
4613 assert(classifyPrim(E->getType()) == PT_Bool);
4614 if (E->isValueDependent())
4615 return false;
4616 if (DiscardResult)
4617 return true;
4618 return this->emitConstBool(E->isSatisfied(), E);
4619}
4620
4621template <class Emitter>
4623 const ConceptSpecializationExpr *E) {
4624 assert(classifyPrim(E->getType()) == PT_Bool);
4625 if (DiscardResult)
4626 return true;
4627 return this->emitConstBool(E->isSatisfied(), E);
4628}
4629
4630template <class Emitter>
4635
4636template <class Emitter>
4638
4639 for (const Expr *SemE : E->semantics()) {
4640 if (auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
4641 if (SemE == E->getResultExpr())
4642 return false;
4643
4644 if (OVE->isUnique())
4645 continue;
4646
4647 if (!this->discard(OVE))
4648 return false;
4649 } else if (SemE == E->getResultExpr()) {
4650 if (!this->delegate(SemE))
4651 return false;
4652 } else {
4653 if (!this->discard(SemE))
4654 return false;
4655 }
4656 }
4657 return true;
4658}
4659
4660template <class Emitter>
4664
4665template <class Emitter>
4667 return this->emitError(E);
4668}
4669
4670template <class Emitter>
4672 assert(E->getType()->isVoidPointerType());
4673 if (DiscardResult)
4674 return true;
4675
4676 return this->emitDummyPtr(E, E);
4677}
4678
4679template <class Emitter>
4680bool Compiler<Emitter>::emitVectorConversion(const Expr *Src, const Expr *E) {
4681 if (Src->containsErrors())
4682 return false;
4683
4684 const auto *VT = E->getType()->castAs<VectorType>();
4685 QualType ElemType = VT->getElementType();
4686 PrimType ElemT = classifyPrim(ElemType);
4687 QualType SrcType = Src->getType();
4688 PrimType SrcElemT = classifyVectorElementType(SrcType);
4689
4690 if (!Initializing) {
4691 UnsignedOrNone LocalIndex = allocateLocal(E);
4692 if (!LocalIndex)
4693 return false;
4694 if (!this->emitGetPtrLocal(*LocalIndex, E))
4695 return false;
4696 }
4697
4698 unsigned SrcOffset =
4699 this->allocateLocalPrimitive(Src, PT_Ptr, /*IsConst=*/true);
4700 if (!this->visit(Src))
4701 return false;
4702 if (!this->emitSetLocal(PT_Ptr, SrcOffset, E))
4703 return false;
4704
4705 for (unsigned I = 0; I != VT->getNumElements(); ++I) {
4706 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
4707 return false;
4708 if (!this->emitArrayElemPop(SrcElemT, I, E))
4709 return false;
4710
4711 // Cast to the desired result element type.
4712 if (SrcElemT != ElemT) {
4713 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
4714 return false;
4715 } else if (ElemType->isFloatingType() && SrcType != ElemType) {
4716 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
4717 if (!this->emitCastFP(TargetSemantics, getRoundingMode(E), E))
4718 return false;
4719 }
4720 if (!this->emitInitElem(ElemT, I, E))
4721 return false;
4722 }
4723 return true;
4724}
4725
4726template <class Emitter>
4728 return emitVectorConversion(E->getSrcExpr(), E);
4729}
4730
4731template <class Emitter>
4733 // FIXME: Unary shuffle with mask not currently supported.
4734 if (E->getNumSubExprs() == 2)
4735 return this->emitInvalid(E);
4736
4737 assert(E->getNumSubExprs() > 2);
4738
4739 const Expr *Vecs[] = {E->getExpr(0), E->getExpr(1)};
4740 const VectorType *VT = Vecs[0]->getType()->castAs<VectorType>();
4741 PrimType ElemT = classifyPrim(VT->getElementType());
4742 unsigned NumInputElems = VT->getNumElements();
4743 unsigned NumOutputElems = E->getNumSubExprs() - 2;
4744 assert(NumOutputElems > 0);
4745
4746 if (!Initializing) {
4747 UnsignedOrNone LocalIndex = allocateLocal(E);
4748 if (!LocalIndex)
4749 return false;
4750 if (!this->emitGetPtrLocal(*LocalIndex, E))
4751 return false;
4752 }
4753
4754 // Save both input vectors to a local variable.
4755 unsigned VectorOffsets[2];
4756 for (unsigned I = 0; I != 2; ++I) {
4757 VectorOffsets[I] =
4758 this->allocateLocalPrimitive(Vecs[I], PT_Ptr, /*IsConst=*/true);
4759 if (!this->visit(Vecs[I]))
4760 return false;
4761 if (!this->emitSetLocal(PT_Ptr, VectorOffsets[I], E))
4762 return false;
4763 }
4764 for (unsigned I = 0; I != NumOutputElems; ++I) {
4765 APSInt ShuffleIndex = E->getShuffleMaskIdx(I);
4766 assert(ShuffleIndex >= -1);
4767 if (ShuffleIndex == -1)
4768 return this->emitInvalidShuffleVectorIndex(I, E);
4769
4770 assert(ShuffleIndex < (NumInputElems * 2));
4771 if (!this->emitGetLocal(PT_Ptr,
4772 VectorOffsets[ShuffleIndex >= NumInputElems], E))
4773 return false;
4774 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
4775 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
4776 return false;
4777
4778 if (!this->emitInitElem(ElemT, I, E))
4779 return false;
4780 }
4781
4782 if (DiscardResult)
4783 return this->emitPopPtr(E);
4784
4785 return true;
4786}
4787
4788template <class Emitter>
4790 const ExtVectorElementExpr *E) {
4791 const Expr *Base = E->getBase();
4792 assert(
4793 Base->getType()->isVectorType() ||
4794 Base->getType()->getAs<PointerType>()->getPointeeType()->isVectorType());
4795
4797 E->getEncodedElementAccess(Indices);
4798
4799 if (Indices.size() == 1) {
4800 if (!this->visit(Base))
4801 return false;
4802
4803 if (E->isGLValue()) {
4804 if (!this->emitConstUint32(Indices[0], E))
4805 return false;
4806 return this->emitArrayElemPtrPop(PT_Uint32, E);
4807 }
4808 // Else, also load the value.
4809 return this->emitArrayElemPop(classifyPrim(E->getType()), Indices[0], E);
4810 }
4811
4812 // Create a local variable for the base.
4813 unsigned BaseOffset = allocateLocalPrimitive(Base, PT_Ptr, /*IsConst=*/true);
4814 if (!this->visit(Base))
4815 return false;
4816 if (!this->emitSetLocal(PT_Ptr, BaseOffset, E))
4817 return false;
4818
4819 // Now the vector variable for the return value.
4820 if (!Initializing) {
4821 UnsignedOrNone ResultIndex = allocateLocal(E);
4822 if (!ResultIndex)
4823 return false;
4824 if (!this->emitGetPtrLocal(*ResultIndex, E))
4825 return false;
4826 }
4827
4828 assert(Indices.size() == E->getType()->getAs<VectorType>()->getNumElements());
4829
4830 PrimType ElemT =
4832 uint32_t DstIndex = 0;
4833 for (uint32_t I : Indices) {
4834 if (!this->emitGetLocal(PT_Ptr, BaseOffset, E))
4835 return false;
4836 if (!this->emitArrayElemPop(ElemT, I, E))
4837 return false;
4838 if (!this->emitInitElem(ElemT, DstIndex, E))
4839 return false;
4840 ++DstIndex;
4841 }
4842
4843 // Leave the result pointer on the stack.
4844 assert(!DiscardResult);
4845 return true;
4846}
4847
4848template <class Emitter>
4850 const Expr *SubExpr = E->getSubExpr();
4852 return this->discard(SubExpr) && this->emitInvalid(E);
4853
4854 if (DiscardResult)
4855 return true;
4856
4857 assert(classifyPrim(E) == PT_Ptr);
4858 return this->emitDummyPtr(E, E);
4859}
4860
4861template <class Emitter>
4863 const CXXStdInitializerListExpr *E) {
4864 const Expr *SubExpr = E->getSubExpr();
4866 Ctx.getASTContext().getAsConstantArrayType(SubExpr->getType());
4867 const Record *R = getRecord(E->getType());
4868 assert(Initializing);
4869 assert(SubExpr->isGLValue());
4870
4871 if (!this->visit(SubExpr))
4872 return false;
4873 if (!this->emitConstUint8(0, E))
4874 return false;
4875 if (!this->emitArrayElemPtrPopUint8(E))
4876 return false;
4877 if (!this->emitInitFieldPtr(R->getField(0u)->Offset, E))
4878 return false;
4879
4880 PrimType SecondFieldT = *R->getField(1u)->T;
4881 if (isIntegerOrBoolType(SecondFieldT)) {
4882 if (!this->emitConst(ArrayType->getSize(), SecondFieldT, E))
4883 return false;
4884 return this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E);
4885 }
4886 assert(SecondFieldT == PT_Ptr);
4887
4888 if (!this->emitGetFieldPtr(R->getField(0u)->Offset, E))
4889 return false;
4890 if (!this->emitExpandPtr(E))
4891 return false;
4892 if (!this->emitConst(ArrayType->getSize(), PT_Uint64, E))
4893 return false;
4894 if (!this->emitArrayElemPtrPop(PT_Uint64, E))
4895 return false;
4896 return this->emitInitFieldPtr(R->getField(1u)->Offset, E);
4897}
4898
4899template <class Emitter>
4901 LocalScope<Emitter> BS(this);
4902 llvm::SaveAndRestore StmtExprSAR(this->InStmtExpr, true);
4903
4904 const CompoundStmt *CS = E->getSubStmt();
4905 const Stmt *Result = CS->body_back();
4906 for (const Stmt *S : CS->body()) {
4907 if (S != Result) {
4908 if (!this->visitStmt(S))
4909 return false;
4910 continue;
4911 }
4912
4913 assert(S == Result);
4914 if (const Expr *ResultExpr = dyn_cast<Expr>(S))
4915 return this->delegate(ResultExpr);
4916 if (!this->visitStmt(S))
4917 return false;
4918 return this->emitUnsupported(E);
4919 }
4920
4921 return BS.destroyLocals();
4922}
4923
4924template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {
4925 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
4926 /*NewInitializing=*/false, /*ToLValue=*/false);
4927 return this->Visit(E);
4928}
4929
4930template <class Emitter> bool Compiler<Emitter>::delegate(const Expr *E) {
4931 // We're basically doing:
4932 // OptionScope<Emitter> Scope(this, DicardResult, Initializing, ToLValue);
4933 // but that's unnecessary of course.
4934 return this->Visit(E);
4935}
4936
4938 if (const auto *PE = dyn_cast<ParenExpr>(E))
4939 return stripCheckedDerivedToBaseCasts(PE->getSubExpr());
4940
4941 if (const auto *CE = dyn_cast<CastExpr>(E);
4942 CE &&
4943 (CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp))
4944 return stripCheckedDerivedToBaseCasts(CE->getSubExpr());
4945
4946 return E;
4947}
4948
4949static const Expr *stripDerivedToBaseCasts(const Expr *E) {
4950 if (const auto *PE = dyn_cast<ParenExpr>(E))
4951 return stripDerivedToBaseCasts(PE->getSubExpr());
4952
4953 if (const auto *CE = dyn_cast<CastExpr>(E);
4954 CE && (CE->getCastKind() == CK_DerivedToBase ||
4955 CE->getCastKind() == CK_UncheckedDerivedToBase ||
4956 CE->getCastKind() == CK_NoOp))
4957 return stripDerivedToBaseCasts(CE->getSubExpr());
4958
4959 return E;
4960}
4961
4962template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) {
4963 if (E->getType().isNull())
4964 return false;
4965
4966 if (E->getType()->isVoidType())
4967 return this->discard(E);
4968
4969 // Create local variable to hold the return value.
4970 if (!E->isGLValue() && !canClassify(E->getType())) {
4971 UnsignedOrNone LocalIndex = allocateLocal(
4973 if (!LocalIndex)
4974 return false;
4975
4976 if (!this->emitGetPtrLocal(*LocalIndex, E))
4977 return false;
4978 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
4979 return this->visitInitializer(E);
4980 }
4981
4982 // Otherwise,we have a primitive return value, produce the value directly
4983 // and push it on the stack.
4984 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
4985 /*NewInitializing=*/false, /*ToLValue=*/ToLValue);
4986 return this->Visit(E);
4987}
4988
4989template <class Emitter>
4991 assert(!canClassify(E->getType()));
4992
4993 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
4994 /*NewInitializing=*/true, /*ToLValue=*/false);
4995 return this->Visit(E) && this->emitFinishInit(E);
4996}
4997
4998template <class Emitter>
5000 assert(!canClassify(E->getType()));
5001
5002 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
5003 /*NewInitializing=*/true, /*ToLValue=*/false);
5004 return this->Visit(E) && this->emitFinishInitPop(E);
5005}
5006
5007template <class Emitter> bool Compiler<Emitter>::visitAsLValue(const Expr *E) {
5008 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
5009 /*NewInitializing=*/false, /*ToLValue=*/true);
5010 return this->Visit(E);
5011}
5012
5013template <class Emitter> bool Compiler<Emitter>::visitBool(const Expr *E) {
5014 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
5015 /*NewInitializing=*/false, /*ToLValue=*/ToLValue);
5016
5017 OptPrimType T = classify(E->getType());
5018 if (!T) {
5019 // Convert complex values to bool.
5020 if (E->getType()->isAnyComplexType()) {
5021 if (!this->visit(E))
5022 return false;
5023 return this->emitComplexBoolCast(E);
5024 }
5025 return false;
5026 }
5027
5028 if (!this->visit(E))
5029 return false;
5030
5031 if (T == PT_Bool)
5032 return true;
5033
5034 // Convert pointers to bool.
5035 if (T == PT_Ptr)
5036 return this->emitIsNonNullPtr(E);
5037
5038 // Or Floats.
5039 if (T == PT_Float)
5040 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
5041
5042 // Or anything else we can.
5043 return this->emitCast(*T, PT_Bool, E);
5044}
5045
5046template <class Emitter>
5047bool Compiler<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
5048 const Expr *E) {
5049 if (const auto *AT = QT->getAs<AtomicType>())
5050 QT = AT->getValueType();
5051
5052 switch (T) {
5053 case PT_Bool:
5054 return this->emitZeroBool(E);
5055 case PT_Sint8:
5056 return this->emitZeroSint8(E);
5057 case PT_Uint8:
5058 return this->emitZeroUint8(E);
5059 case PT_Sint16:
5060 return this->emitZeroSint16(E);
5061 case PT_Uint16:
5062 return this->emitZeroUint16(E);
5063 case PT_Sint32:
5064 return this->emitZeroSint32(E);
5065 case PT_Uint32:
5066 return this->emitZeroUint32(E);
5067 case PT_Sint64:
5068 return this->emitZeroSint64(E);
5069 case PT_Uint64:
5070 return this->emitZeroUint64(E);
5071 case PT_IntAP:
5072 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
5073 case PT_IntAPS:
5074 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
5075 case PT_Ptr:
5076 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
5077 nullptr, E);
5078 case PT_MemberPtr:
5079 return this->emitNullMemberPtr(0, nullptr, E);
5080 case PT_Float: {
5081 APFloat F = APFloat::getZero(Ctx.getFloatSemantics(QT));
5082 return this->emitFloat(F, E);
5083 }
5084 case PT_FixedPoint: {
5085 auto Sem = Ctx.getASTContext().getFixedPointSemantics(QT);
5086 return this->emitConstFixedPoint(FixedPoint::zero(Sem), E);
5087 }
5088 }
5089 llvm_unreachable("unknown primitive type");
5090}
5091
5092template <class Emitter>
5093bool Compiler<Emitter>::visitZeroRecordInitializer(const Record *R,
5094 const Expr *E,
5095 bool IsCompleteClass) {
5096 assert(E);
5097 assert(R);
5098 // Fields
5099 for (const Record::Field &Field : R->fields()) {
5100 if (Field.isUnnamedBitField())
5101 continue;
5102
5103 const Descriptor *D = Field.Desc;
5104 if (D->isPrimitive()) {
5105 QualType QT = D->getType();
5106 PrimType T = D->getPrimType();
5107 if (!this->visitZeroInitializer(T, QT, E))
5108 return false;
5109 if (R->isUnion()) {
5110 if (!this->emitInitFieldActivate(T, Field.Offset, E))
5111 return false;
5112 break;
5113 }
5114 if (!this->emitInitField(T, Field.Offset, E))
5115 return false;
5116 continue;
5117 }
5118
5119 if (!this->emitGetPtrField(Field.Offset, E))
5120 return false;
5121
5122 if (D->isPrimitiveArray()) {
5123 QualType ET = D->getElemQualType();
5124 PrimType T = D->getPrimType();
5125 for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
5126 if (!this->visitZeroInitializer(T, ET, E))
5127 return false;
5128 if (!this->emitInitElem(T, I, E))
5129 return false;
5130 }
5131 } else if (D->isCompositeArray()) {
5132 // Can't be a vector or complex field.
5133 if (!this->visitZeroArrayInitializer(D->getType(), E))
5134 return false;
5135 } else if (D->isRecord()) {
5136 if (!this->visitZeroRecordInitializer(D->ElemRecord, E))
5137 return false;
5138 } else
5139 return false;
5140
5141 // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the
5142 // object's first non-static named data member is zero-initialized
5143 if (R->isUnion()) {
5144 if (!this->emitFinishInitActivatePop(E))
5145 return false;
5146 break;
5147 }
5148 if (!this->emitFinishInitPop(E))
5149 return false;
5150 }
5151
5152 for (const Record::Base &B : R->bases()) {
5153 if (!this->emitGetPtrBase(B.Offset, E))
5154 return false;
5155 if (!this->visitZeroRecordInitializer(B.R, E, /*IsCompleteClass=*/false))
5156 return false;
5157 if (!this->emitFinishInitPop(E))
5158 return false;
5159 }
5160
5161 if (IsCompleteClass) {
5162 for (const Record::Base &B : R->virtual_bases()) {
5163 if (!this->emitGetPtrVirtBase(cast<CXXRecordDecl>(B.R->getDecl()), E))
5164 return false;
5165 if (!this->visitZeroRecordInitializer(B.R, E, /*IsCompleteClass=*/false))
5166 return false;
5167 if (!this->emitFinishInitPop(E))
5168 return false;
5169 }
5170 }
5171
5172 return true;
5173}
5174
5175template <class Emitter>
5176bool Compiler<Emitter>::visitZeroArrayInitializer(QualType T, const Expr *E) {
5177 assert(T->isArrayType() || T->isAnyComplexType() || T->isVectorType());
5178 const ArrayType *AT = T->getAsArrayTypeUnsafe();
5179 QualType ElemType = AT->getElementType();
5180 size_t NumElems = cast<ConstantArrayType>(AT)->getZExtSize();
5181
5182 if (OptPrimType ElemT = classify(ElemType)) {
5183 for (size_t I = 0; I != NumElems; ++I) {
5184 if (!this->visitZeroInitializer(*ElemT, ElemType, E))
5185 return false;
5186 if (!this->emitInitElem(*ElemT, I, E))
5187 return false;
5188 }
5189 return true;
5190 }
5191 if (ElemType->isRecordType()) {
5192 const Record *R = getRecord(ElemType);
5193 if (!R)
5194 return false;
5195
5196 for (size_t I = 0; I != NumElems; ++I) {
5197 if (!this->emitConstUint32(I, E))
5198 return false;
5199 if (!this->emitArrayElemPtr(PT_Uint32, E))
5200 return false;
5201 if (!this->visitZeroRecordInitializer(R, E))
5202 return false;
5203 if (!this->emitPopPtr(E))
5204 return false;
5205 }
5206 return true;
5207 }
5208 if (ElemType->isArrayType()) {
5209 for (size_t I = 0; I != NumElems; ++I) {
5210 if (!this->emitConstUint32(I, E))
5211 return false;
5212 if (!this->emitArrayElemPtr(PT_Uint32, E))
5213 return false;
5214 if (!this->visitZeroArrayInitializer(ElemType, E))
5215 return false;
5216 if (!this->emitPopPtr(E))
5217 return false;
5218 }
5219 return true;
5220 }
5221
5222 return false;
5223}
5224
5225template <class Emitter>
5226bool Compiler<Emitter>::visitAssignment(const Expr *LHS, const Expr *RHS,
5227 const Expr *E) {
5228 if (!canClassify(E->getType()))
5229 return false;
5230
5231 bool NeedsFlip = !isSideEffectFree(RHS);
5232 if (!NeedsFlip) {
5233 if (!this->visit(LHS))
5234 return false;
5235 if (!this->visit(RHS))
5236 return false;
5237 } else {
5238 if (!this->visit(RHS))
5239 return false;
5240 if (!this->visit(LHS))
5241 return false;
5242 }
5243
5244 if (LHS->getType().isVolatileQualified())
5245 return this->emitInvalidStore(LHS->getType().getTypePtr(), E);
5246
5247 // We don't support assignments in C.
5248 if (!Ctx.getLangOpts().CPlusPlus && !this->emitInvalid(E))
5249 return false;
5250
5251 PrimType RHT = classifyPrim(RHS);
5252 bool Activates = refersToUnion(LHS);
5253 bool BitField = LHS->refersToBitField();
5254
5255 if (NeedsFlip && !this->emitFlip(PT_Ptr, RHT, E))
5256 return false;
5257
5258 if (DiscardResult) {
5259 if (BitField && Activates)
5260 return this->emitStoreBitFieldActivatePop(RHT, E);
5261 if (BitField)
5262 return this->emitStoreBitFieldPop(RHT, E);
5263 if (Activates)
5264 return this->emitStoreActivatePop(RHT, E);
5265 // Otherwise, regular non-activating store.
5266 return this->emitStorePop(RHT, E);
5267 }
5268
5269 auto maybeLoad = [&](bool Result) -> bool {
5270 if (!Result)
5271 return false;
5272 // Assignments aren't necessarily lvalues in C.
5273 // Load from them in that case.
5274 if (!E->isLValue())
5275 return this->emitLoadPop(RHT, E);
5276 return true;
5277 };
5278
5279 if (BitField && Activates)
5280 return maybeLoad(this->emitStoreBitFieldActivate(RHT, E));
5281 if (BitField)
5282 return maybeLoad(this->emitStoreBitField(RHT, E));
5283 if (Activates)
5284 return maybeLoad(this->emitStoreActivate(RHT, E));
5285 // Otherwise, regular non-activating store.
5286 return maybeLoad(this->emitStore(RHT, E));
5287}
5288
5289template <class Emitter>
5290template <typename T>
5291bool Compiler<Emitter>::emitConst(T Value, PrimType Ty, SourceInfo Info) {
5292 switch (Ty) {
5293 case PT_Sint8:
5294 return this->emitConstSint8(Value, Info);
5295 case PT_Uint8:
5296 return this->emitConstUint8(Value, Info);
5297 case PT_Sint16:
5298 return this->emitConstSint16(Value, Info);
5299 case PT_Uint16:
5300 return this->emitConstUint16(Value, Info);
5301 case PT_Sint32:
5302 return this->emitConstSint32(Value, Info);
5303 case PT_Uint32:
5304 return this->emitConstUint32(Value, Info);
5305 case PT_Sint64:
5306 return this->emitConstSint64(Value, Info);
5307 case PT_Uint64:
5308 return this->emitConstUint64(Value, Info);
5309 case PT_Bool:
5310 return this->emitConstBool(Value, Info);
5311 case PT_Ptr:
5312 case PT_MemberPtr:
5313 case PT_Float:
5314 case PT_IntAP:
5315 case PT_IntAPS:
5316 case PT_FixedPoint:
5317 llvm_unreachable("Invalid integral type");
5318 break;
5319 }
5320 llvm_unreachable("unknown primitive type");
5321}
5322
5323template <class Emitter>
5324template <typename T>
5325bool Compiler<Emitter>::emitConst(T Value, const Expr *E) {
5326 return this->emitConst(Value, classifyPrim(E->getType()), E);
5327}
5328
5329template <class Emitter>
5330bool Compiler<Emitter>::emitConst(const APSInt &Value, PrimType Ty,
5331 SourceInfo Info) {
5332 if (Ty == PT_IntAPS)
5333 return this->emitConstIntAPS(Value, Info);
5334 if (Ty == PT_IntAP)
5335 return this->emitConstIntAP(Value, Info);
5336
5337 if (Value.isSigned())
5338 return this->emitConst(Value.getSExtValue(), Ty, Info);
5339 return this->emitConst(Value.getZExtValue(), Ty, Info);
5340}
5341
5342template <class Emitter>
5343bool Compiler<Emitter>::emitConst(const APInt &Value, PrimType Ty,
5344 SourceInfo Info) {
5345 if (Ty == PT_IntAPS)
5346 return this->emitConstIntAPS(Value, Info);
5347 if (Ty == PT_IntAP)
5348 return this->emitConstIntAP(Value, Info);
5349
5350 if (isSignedType(Ty))
5351 return this->emitConst(Value.getSExtValue(), Ty, Info);
5352 return this->emitConst(Value.getZExtValue(), Ty, Info);
5353}
5354
5355template <class Emitter>
5356bool Compiler<Emitter>::emitConst(const APSInt &Value, const Expr *E) {
5357 return this->emitConst(Value, classifyPrim(E->getType()), E);
5358}
5359
5360template <class Emitter>
5362 bool IsConst,
5363 bool IsVolatile,
5364 ScopeKind SC) {
5365 // FIXME: There are cases where Src.isExpr() is wrong, e.g.
5366 // (int){12} in C. Consider using Expr::isTemporaryObject() instead
5367 // or isa<MaterializeTemporaryExpr>().
5368 Descriptor *D = P.createDescriptor(Src, Ty, nullptr, IsConst, Src.isExpr(),
5369 /*IsMutable=*/false, IsVolatile);
5371 Scope::Local Local = this->createLocal(D);
5372 if (auto *VD = Src.asValueDecl())
5373 Locals.insert({VD, Local});
5374 VarScope->addForScopeKind(Local, SC);
5375 return Local.Offset;
5376}
5377
5378template <class Emitter>
5380 ScopeKind SC) {
5381 const ValueDecl *Key = nullptr;
5382 const Expr *Init = nullptr;
5383 bool IsTemporary = false;
5384 if (auto *VD = Src.asValueDecl()) {
5385 Key = VD;
5386
5387 if (const auto *VarD = dyn_cast<VarDecl>(VD))
5388 Init = VarD->getInit();
5389 }
5390 if (const auto *E = Src.asExpr()) {
5391 IsTemporary = true;
5392 if (Ty.isNull())
5393 Ty = E->getType();
5394 }
5395
5396 Descriptor *D = P.createDescriptor(
5397 Src, Ty.getTypePtr(), Ty.isConstQualified(), IsTemporary,
5398 /*IsMutable=*/false, /*IsVolatile=*/Ty.isVolatileQualified(), Init);
5399 if (!D)
5400 return std::nullopt;
5402
5403 Scope::Local Local = this->createLocal(D);
5404 if (Key)
5405 Locals.insert({Key, Local});
5406 VarScope->addForScopeKind(Local, SC);
5407 return Local.Offset;
5408}
5409
5410template <class Emitter>
5412 QualType Ty = E->getType();
5413 assert(!Ty->isRecordType());
5414
5415 Descriptor *D = P.createDescriptor(E, Ty.getTypePtr(), Ty.isConstQualified(),
5416 /*IsTemporary=*/true);
5417
5418 if (!D)
5419 return std::nullopt;
5420
5421 Scope::Local Local = this->createLocal(D);
5423 assert(S);
5424 // Attach to topmost scope.
5425 while (S->getParent())
5426 S = S->getParent();
5427 assert(S && !S->getParent());
5428 S->addLocal(Local);
5429 return Local.Offset;
5430}
5431
5432template <class Emitter>
5434 if (const PointerType *PT = dyn_cast<PointerType>(Ty))
5435 return PT->getPointeeType()->getAsCanonical<RecordType>();
5436 return Ty->getAsCanonical<RecordType>();
5437}
5438
5439template <class Emitter> Record *Compiler<Emitter>::getRecord(QualType Ty) {
5440 if (const auto *RecordTy = getRecordTy(Ty))
5441 return getRecord(RecordTy->getDecl()->getDefinitionOrSelf());
5442 return nullptr;
5443}
5444
5445template <class Emitter>
5447 return P.getOrCreateRecord(RD);
5448}
5449
5450template <class Emitter>
5452 return Ctx.getOrCreateFunction(FD);
5453}
5454
5455template <class Emitter>
5456bool Compiler<Emitter>::visitExpr(const Expr *E, bool DestroyToplevelScope) {
5458
5459 auto maybeDestroyLocals = [&]() -> bool {
5460 if (DestroyToplevelScope)
5461 return RootScope.destroyLocals() && this->emitCheckAllocations(E);
5462 return this->emitCheckAllocations(E);
5463 };
5464
5465 // Void expressions.
5466 if (E->getType()->isVoidType()) {
5467 if (!visit(E))
5468 return false;
5469 return this->emitRetVoid(E) && maybeDestroyLocals();
5470 }
5471
5472 // Expressions with a primitive return type.
5473 if (OptPrimType T = classify(E)) {
5474 if (!visit(E))
5475 return false;
5476
5477 return this->emitRet(*T, E) && maybeDestroyLocals();
5478 }
5479
5480 // Expressions with a composite return type.
5481 // For us, that means everything we don't
5482 // have a PrimType for.
5483 if (UnsignedOrNone LocalOffset = this->allocateLocal(E)) {
5484 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalOffset));
5485 if (!this->emitGetPtrLocal(*LocalOffset, E))
5486 return false;
5487
5488 if (!visitInitializer(E))
5489 return false;
5490 // We are destroying the locals AFTER the Ret op.
5491 // The Ret op needs to copy the (alive) values, but the
5492 // destructors may still turn the entire expression invalid.
5493 return this->emitRetValue(E) && maybeDestroyLocals();
5494 }
5495
5496 return maybeDestroyLocals() && false;
5497}
5498
5499template <class Emitter>
5501 bool DestroyToplevelScope) {
5502 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
5503 /*NewInitializing=*/false, /*ToLValue=*/true);
5504
5505 return this->visitExpr(E, DestroyToplevelScope);
5506}
5507
5508template <class Emitter>
5510
5511 auto R = this->visitVarDecl(VD, VD->getInit(), /*Toplevel=*/true);
5512
5513 if (R.notCreated())
5514 return R;
5515
5516 if (R)
5517 return true;
5518
5519 if (!R && Context::shouldBeGloballyIndexed(VD)) {
5520 if (auto GlobalIndex = P.getGlobal(VD)) {
5521 Block *GlobalBlock = P.getGlobal(*GlobalIndex);
5522 auto &GD = GlobalBlock->getBlockDesc<GlobalInlineDescriptor>();
5523
5525 GlobalBlock->invokeDtor();
5526 }
5527 }
5528
5529 return R;
5530}
5531
5532/// Toplevel visitDeclAndReturn().
5533/// We get here from evaluateAsInitializer().
5534/// We need to evaluate the initializer and return its value.
5535template <class Emitter>
5537 bool ConstantContext) {
5538 // We only create variables if we're evaluating in a constant context.
5539 // Otherwise, just evaluate the initializer and return it.
5540 if (!ConstantContext) {
5541 DeclScope<Emitter> LS(this, VD);
5542 if (!this->visit(Init))
5543 return false;
5544 return this->emitRet(classify(Init).value_or(PT_Ptr), VD) &&
5545 LS.destroyLocals() && this->emitCheckAllocations(VD);
5546 }
5547
5548 LocalScope<Emitter> VDScope(this);
5549 if (!this->visitVarDecl(VD, Init, /*Toplevel=*/true))
5550 return false;
5551
5552 OptPrimType VarT = classify(VD->getType());
5553 bool IsReference = VD->getType()->isReferenceType();
5555 auto GlobalIndex = P.getGlobal(VD);
5556 assert(GlobalIndex); // visitVarDecl() didn't return false.
5557 if (VarT) {
5558 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
5559 return false;
5560 } else {
5561 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
5562 return false;
5563 }
5564 } else {
5565 auto Local = Locals.find(VD);
5566 assert(Local != Locals.end()); // Same here.
5567 if (VarT) {
5568 if (IsReference) {
5569 if (!this->emitGetRefLocal(Local->second.Offset, VD))
5570 return false;
5571 } else if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
5572 return false;
5573 } else {
5574 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
5575 return false;
5576 }
5577 }
5578
5579 // Return the value.
5580 if (!this->emitRet(VarT.value_or(PT_Ptr), VD)) {
5581 // If the Ret above failed and this is a global variable, mark it as
5582 // uninitialized, even everything else succeeded.
5584 auto GlobalIndex = P.getGlobal(VD);
5585 assert(GlobalIndex);
5586 Block *GlobalBlock = P.getGlobal(*GlobalIndex);
5587 auto &GD = GlobalBlock->getBlockDesc<GlobalInlineDescriptor>();
5588
5590 GlobalBlock->invokeDtor();
5591 }
5592 return false;
5593 }
5594
5595 return VDScope.destroyLocals() && this->emitCheckAllocations(VD);
5596}
5597
5598template <class Emitter>
5600 const Expr *Init,
5601 bool Toplevel) {
5602 QualType VarTy = VD->getType();
5603 // We don't know what to do with these, so just return false.
5604 if (VarTy.isNull())
5605 return false;
5606
5607 // This case is EvalEmitter-only. If we won't create any instructions for the
5608 // initializer anyway, don't bother creating the variable in the first place.
5609 if (!this->isActive())
5611
5612 OptPrimType VarT = classify(VD->getType());
5613
5614 if (Init && Init->isValueDependent())
5615 return false;
5616
5618 auto checkDecl = [&]() -> bool {
5619 bool NeedsOp = !Toplevel && VD->isLocalVarDecl() && VD->isStaticLocal();
5620 return !NeedsOp || this->emitCheckDecl(VD, VD);
5621 };
5622
5624 UnsignedOrNone GlobalIndex = P.getGlobal(VD);
5625 if (GlobalIndex) {
5626 // The global was previously created but the initializer failed.
5627 if (!P.getGlobal(*GlobalIndex)->isInitialized())
5628 return false;
5629 // We've already seen and initialized this global.
5630 if (P.isGlobalInitialized(*GlobalIndex))
5631 return checkDecl();
5632 // The previous attempt at initialization might've been unsuccessful,
5633 // so let's try this one.
5634 } else if ((GlobalIndex =
5635 P.createGlobal(VD, Init, VariablesAreConstexprUnknown))) {
5636 } else {
5637 return false;
5638 }
5639 if (!Init)
5640 return true;
5641
5642 if (!checkDecl())
5643 return false;
5644
5645 if (VarT) {
5646 if (!this->visit(Init))
5647 return false;
5648
5649 return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
5650 }
5651
5652 if (!this->emitGetPtrGlobal(*GlobalIndex, Init))
5653 return false;
5654
5655 if (!this->emitStartInit(Init))
5656 return false;
5657
5658 if (!visitInitializer(Init))
5659 return false;
5660
5661 if (!this->emitEndInit(Init))
5662 return false;
5663
5664 return this->emitFinishInitGlobal(Init);
5665 }
5666 // Local variables.
5668
5669 if (VarT) {
5670 unsigned Offset = this->allocateLocalPrimitive(
5671 VD, *VarT, VarTy.isConstQualified(), VarTy.isVolatileQualified(),
5673
5674 if (!Init || Init->getType()->isVoidType())
5675 return true;
5676
5677 // If this is a toplevel declaration, create a scope for the
5678 // initializer.
5679 if (Toplevel) {
5681 if (!this->visit(Init))
5682 return false;
5683 return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals();
5684 }
5685 if (!this->visit(Init))
5686 return false;
5687
5688 if (VarTy->isReferenceType()) {
5689 // [C++26][decl.ref]
5690 // The object designated by such a glvalue can be outside its lifetime
5691 // Because a null pointer value or a pointer past the end of an object
5692 // does not point to an object, a reference in a well-defined program
5693 // cannot refer to such things;
5694 assert(classifyPrim(VarTy) == PT_Ptr);
5695 if (!this->emitCheckRefInit(Init))
5696 return false;
5697 }
5698
5699 return this->emitSetLocal(*VarT, Offset, VD);
5700 }
5701 // Local composite variables.
5702 if (UnsignedOrNone Offset =
5703 this->allocateLocal(VD, VarTy, ScopeKind::Block)) {
5704 if (!Init)
5705 return true;
5706
5707 if (!this->emitGetPtrLocal(*Offset, Init))
5708 return false;
5709
5710 return visitInitializerPop(Init);
5711 }
5712 return false;
5713}
5714
5715template <class Emitter>
5717 assert(!canClassify(VD->getType()));
5718
5720 // Create a local variable to use as the instance.
5721 QualType Ty = VD->getType();
5722 Descriptor *D =
5723 P.createDescriptor(VD, Ty.getTypePtr(), /*IsConst=*/Ty.isConstQualified(),
5724 /*IsTemporary=*/false, /*IsMutable=*/false,
5725 /*IsVolatile=*/Ty.isVolatileQualified(), nullptr);
5726 if (!D)
5727 return false;
5728
5729 // FIXME: Would be nice if we didn't allocate the descriptor at all in this
5730 // case.
5731 if (D->hasTrivialDtor())
5732 return true;
5733
5734 Scope::Local Local = this->createLocal(D);
5735 Locals.insert({VD, Local});
5736 VarScope->addForScopeKind(Local, ScopeKind::Block);
5737
5738 if (!this->emitGetPtrLocal(Local.Offset, VD))
5739 return false;
5740
5741 if (!this->visitAPValueInitializer(Value, VD, Ty))
5742 return false;
5743
5744 return this->emitDestructionPop(D, VD);
5745}
5746
5748public:
5750 explicit ParamFinder() {}
5751
5752 bool VisitDeclRefExpr(const DeclRefExpr *E) override {
5753 if (const auto *P = dyn_cast<ParmVarDecl>(E->getDecl()))
5754 FoundParams.insert(P);
5755 return true;
5756 }
5757};
5758
5759/// Evaluate the \p Condition as if it was in the body of \p Callee.
5760/// Specifically, all the parameters of the callee are available to use
5761/// for the condition, and their values are given by \p Args (and \p This).
5762///
5763// Since this is a somewhat niche feature, we're abusing a few other mechanisms
5764// to implement this.
5765//
5766// We don't create an actual function frame but instead register the parameters
5767// as local variables.
5768//
5769// So we evaluate something like:
5770//
5771// bool thisfunc() {
5772// auto Arg0 = Args[0];
5773// ...
5774// return Condition;
5775// }
5776//
5777template <class Emitter>
5780 const Expr *This,
5781 const Expr *Condition) {
5782 // Instead of evaluating all parameters and trying to ignore failure,
5783 // we collect all the parameters used in the condition and only evaluate
5784 // those. Note that we still ignore failure in the loop below because the
5785 // failure might be inconsequential in the end,
5786 // e.g. in the case of `true || x`.
5787 ParamFinder PF;
5789
5790 LocalScope<Emitter> ArgScope(this);
5791 for (const ParmVarDecl *PVD : PF.FoundParams) {
5792 unsigned ParamIndex = 0;
5793 for (const ParmVarDecl *P : Callee->parameters()) {
5794 if (P == PVD)
5795 break;
5796 ++ParamIndex;
5797 }
5798
5799 const Expr *Arg = Args[ParamIndex];
5800 const ParmVarDecl *Param = Callee->getParamDecl(ParamIndex);
5801 if (OptPrimType ParamT = classify(Param->getType())) {
5802 unsigned ArgOffset =
5803 allocateLocalPrimitive(Param, *ParamT, /*IsConst=*/true);
5804 if (!this->visit(Arg))
5805 continue;
5806 if (!this->emitSetLocal(*ParamT, ArgOffset, Arg))
5807 return false;
5808 } else {
5809 UnsignedOrNone ArgOffset = this->allocateLocal(Param, Param->getType());
5810 if (!ArgOffset)
5811 return false;
5812 if (!this->emitGetPtrLocal(*ArgOffset, Arg))
5813 return false;
5814 if (!this->visitInitializerPop(Arg))
5815 continue;
5816 }
5817 }
5818
5819 if (This) {
5820 // We abuse the init stack for this and tell it to use
5821 // either a local variable or another decl for the This pointer.
5822 this->InitStackActive = true;
5823
5824 if (This->getType()->isPointerType()) {
5825 // Nothing to do here, the evaluation will fail if the instance
5826 // pointer is used.
5827 } else if (const auto *DRE = dyn_cast<DeclRefExpr>(This)) {
5828 InitStack.push_back(InitLink::Decl(DRE->getDecl()));
5829 } else {
5830 assert(!canClassify(This->getType()));
5831 UnsignedOrNone ArgOffset = this->allocateLocal(This, This->getType());
5832 if (!ArgOffset)
5833 return false;
5834 if (!this->emitGetPtrLocal(*ArgOffset, This))
5835 return false;
5836 if (!this->visitInitializerPop(This))
5837 return false;
5838 this->InitStack.push_back(InitLink::Temp(*ArgOffset));
5839 }
5840 }
5841
5842 // Destruction of the argument values is part of the callee frame,
5843 // so we simply ignore them here.
5844 this->VarScope = nullptr;
5845
5846 LocalScope<Emitter> RetScope(this);
5847 if (!this->visit(Condition))
5848 return false;
5849 if (!RetScope.destroyLocals())
5850 return false;
5851
5852 // Result of the condition should be on the stack.
5853 return this->emitRet(PT_Bool, Condition);
5854}
5855
5856template <class Emitter>
5858 SourceInfo Info) {
5859 assert(!Val.isIndeterminate() && "Needs to be checked before");
5860 assert(!DiscardResult);
5861 if (Val.isInt())
5862 return this->emitConst(Val.getInt(), ValType, Info);
5863 if (Val.isFloat())
5864 return this->emitFloat(Val.getFloat(), Info);
5865
5866 if (Val.isMemberPointer()) {
5867 if (const ValueDecl *MemberDecl = Val.getMemberPointerDecl()) {
5868 if (!this->emitGetMemberPtr(MemberDecl, Info))
5869 return false;
5870
5871 bool IsDerived = Val.isMemberPointerToDerivedMember();
5872 // Apply the member pointer path.
5873 for (const CXXRecordDecl *PathEntry : Val.getMemberPointerPath()) {
5874 if (!this->emitCopyMemberPtrPath(PathEntry, IsDerived, Info))
5875 return false;
5876 }
5877
5878 return true;
5879 }
5880 return this->emitNullMemberPtr(0, nullptr, Info);
5881 }
5882
5883 if (Val.isLValue()) {
5884 if (Val.isNullPointer())
5885 return this->emitNull(ValType, 0, nullptr, Info);
5886
5889
5890 if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>())
5891 return this->visit(BaseExpr);
5892 if (const auto *VD = Base.dyn_cast<const ValueDecl *>()) {
5893 if (!this->visitDeclRef(VD, Info.asExpr()))
5894 return false;
5895
5896 QualType EntryType = VD->getType();
5897 for (auto &Entry : Path) {
5898 if (EntryType->isArrayType()) {
5899 uint64_t Index = Entry.getAsArrayIndex();
5900 QualType ElemType =
5901 EntryType->getAsArrayTypeUnsafe()->getElementType();
5902 if (!this->emitConst(Index, PT_Uint64, Info))
5903 return false;
5904 if (!this->emitArrayElemPtrPop(PT_Uint64, Info))
5905 return false;
5906 EntryType = ElemType;
5907 } else {
5908 assert(EntryType->isRecordType());
5909 const Record *EntryRecord = getRecord(EntryType);
5910 if (!EntryRecord)
5911 return false;
5912
5913 const Decl *BaseOrMember = Entry.getAsBaseOrMember().getPointer();
5914 if (const auto *FD = dyn_cast<FieldDecl>(BaseOrMember)) {
5915 unsigned EntryOffset = EntryRecord->getField(FD)->Offset;
5916 if (!this->emitGetPtrFieldPop(EntryOffset, Info))
5917 return false;
5918 EntryType = FD->getType();
5919 } else {
5920 const auto *Base = cast<CXXRecordDecl>(BaseOrMember);
5921 if (const Record::Base *B = EntryRecord->getBaseOrNull(Base)) {
5922 if (!this->emitGetPtrBasePop(B->Offset, /*NullOK=*/false, Info))
5923 return false;
5924 } else {
5925 // Must be a virtual base.
5926 assert(EntryRecord->findVirtualBase(Base));
5927 if (!this->emitGetPtrVirtBasePop(Base, Info))
5928 return false;
5929 }
5930 EntryType = Ctx.getASTContext().getCanonicalTagType(Base);
5931 }
5932 }
5933 }
5934
5935 return true;
5936 }
5937 }
5938
5939 return false;
5940}
5941
5942template <class Emitter>
5944 SourceInfo Info, QualType T,
5945 bool IsCompleteClass) {
5946 if (Val.isStruct()) {
5947 const Record *R = this->getRecord(T);
5948 assert(R);
5949
5950 assert(R->getNumBases() == Val.getStructNumBases());
5951 if (IsCompleteClass)
5952 assert(R->getNumVirtualBases() == Val.getStructNumVirtualBases());
5953
5954 for (unsigned I = 0, N = Val.getStructNumBases(); I != N; ++I) {
5955 const APValue &B = Val.getStructBase(I);
5956 if (B.isIndeterminate())
5957 continue;
5958 const Record::Base *RB = R->getBase(I);
5959 QualType BaseType = Ctx.getASTContext().getCanonicalTagType(RB->Decl);
5960
5961 if (!this->emitGetPtrBase(RB->Offset, Info))
5962 return false;
5963 if (!this->visitAPValueInitializer(B, Info, BaseType,
5964 /*IsCompleteClass=*/false))
5965 return false;
5966 if (!this->emitFinishInitPop(Info))
5967 return false;
5968 }
5969
5970 for (unsigned I = 0, N = Val.getStructNumFields(); I != N; ++I) {
5971 const APValue &F = Val.getStructField(I);
5972 if (F.isIndeterminate())
5973 continue;
5974 const Record::Field *RF = R->getField(I);
5975 QualType FieldType = RF->Decl->getType();
5976 // Fields.
5977 if (OptPrimType PT = RF->T) {
5978 if (!this->visitAPValue(F, *PT, Info))
5979 return false;
5980 if (!this->emitInitField(*PT, RF->Offset, Info))
5981 return false;
5982 } else {
5983 if (!this->emitGetPtrField(RF->Offset, Info))
5984 return false;
5985 if (!this->visitAPValueInitializer(F, Info, FieldType))
5986 return false;
5987 if (!this->emitFinishInitPop(Info))
5988 return false;
5989 }
5990 }
5991
5992 // Virtual Bases.
5993 if (IsCompleteClass) {
5994 for (unsigned I = 0, N = Val.getStructNumVirtualBases(); I != N; ++I) {
5995 const APValue &B = Val.getStructVirtualBase(I);
5996 if (B.isIndeterminate())
5997 continue;
5998 const Record::Base *RB = R->getVirtualBase(I);
5999 QualType BaseType = Ctx.getASTContext().getCanonicalTagType(RB->Decl);
6000
6001 if (!this->emitGetPtrVirtBase(cast<CXXRecordDecl>(RB->R->getDecl()),
6002 Info))
6003 return false;
6004 if (!this->visitAPValueInitializer(B, Info, BaseType,
6005 /*IsCompleteClass=*/false))
6006 return false;
6007 if (!this->emitFinishInitPop(Info))
6008 return false;
6009 }
6010 }
6011
6012 return true;
6013 }
6014 if (Val.isUnion()) {
6015 const FieldDecl *UnionField = Val.getUnionField();
6016 if (!UnionField)
6017 return true;
6018 const Record *R = this->getRecord(T);
6019 assert(R);
6020 const APValue &F = Val.getUnionValue();
6021 if (F.isIndeterminate())
6022 return true;
6023 const Record::Field *RF = R->getField(UnionField);
6024 QualType FieldType = RF->Decl->getType();
6025
6026 if (OptPrimType PT = RF->T) {
6027 if (!this->visitAPValue(F, *PT, Info))
6028 return false;
6029 if (RF->isBitField())
6030 return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(),
6031 Info);
6032 return this->emitInitFieldActivate(*PT, RF->Offset, Info);
6033 }
6034
6035 if (!this->emitGetPtrField(RF->Offset, Info))
6036 return false;
6037 if (!this->emitActivate(Info))
6038 return false;
6039 if (!this->visitAPValueInitializer(F, Info, FieldType))
6040 return false;
6041 return this->emitPopPtr(Info);
6042 }
6043 if (Val.isArray()) {
6044 unsigned InitializedElems = Val.getArrayInitializedElts();
6045 const auto *ArrType = T->getAsArrayTypeUnsafe();
6046 QualType ElemType = ArrType->getElementType();
6047 OptPrimType ElemT = classify(ElemType);
6048
6049 for (unsigned A = 0, AN = Val.getArraySize(); A != AN; ++A) {
6050 const APValue &Elem = A >= InitializedElems
6051 ? Val.getArrayFiller()
6052 : Val.getArrayInitializedElt(A);
6053 if (Elem.isIndeterminate())
6054 continue;
6055
6056 if (ElemT) {
6057 if (!this->visitAPValue(Elem, *ElemT, Info))
6058 return false;
6059 if (!this->emitInitElem(*ElemT, A, Info))
6060 return false;
6061 } else {
6062 if (!this->emitConstUint32(A, Info))
6063 return false;
6064 if (!this->emitArrayElemPtrUint32(Info))
6065 return false;
6066 if (!this->visitAPValueInitializer(Elem, Info, ElemType))
6067 return false;
6068 if (!this->emitPopPtr(Info))
6069 return false;
6070 }
6071 }
6072 return true;
6073 }
6074 // TODO: Other types.
6075
6076 return false;
6077}
6078
6079template <class Emitter>
6081 if (P.getGlobal(VD))
6082 return true;
6083
6084 UnsignedOrNone GlobalIndex = P.createGlobal(VD, /*Init=*/nullptr);
6085 if (!GlobalIndex) {
6086 llvm_unreachable("Why didn't that work?");
6087 }
6088
6089 assert(canClassify(VD->getType()) &&
6090 "registerRedecl should only be called with primitive values");
6091
6092 PrimType T = classifyPrim(VD->getType());
6093 if (!visitAPValue(Val, T, VD))
6094 return false;
6095 return this->emitInitGlobal(T, *GlobalIndex, {});
6096}
6097
6098template <class Emitter>
6100 unsigned BuiltinID) {
6101 if (BuiltinID == Builtin::BI__builtin_constant_p) {
6102 // Void argument is always invalid and harder to handle later.
6103 if (E->getArg(0)->getType()->isVoidType()) {
6104 if (DiscardResult)
6105 return true;
6106 return this->emitConst(0, E);
6107 }
6108
6109 if (!this->emitStartSpeculation(E))
6110 return false;
6111 LabelTy EndLabel = this->getLabel();
6112 if (!this->speculate(E, EndLabel))
6113 return false;
6114 if (!this->emitEndSpeculation(E))
6115 return false;
6116 this->fallthrough(EndLabel);
6117 if (DiscardResult)
6118 return this->emitPop(classifyPrim(E), E);
6119 return true;
6120 }
6121
6122 // For these, we're expected to ultimately return an APValue pointing
6123 // to the CallExpr. This is needed to get the correct codegen.
6124 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6125 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
6126 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
6127 BuiltinID == Builtin::BI__builtin_function_start) {
6128 if (DiscardResult)
6129 return true;
6130 return this->emitDummyPtr(E, E);
6131 }
6132
6134 OptPrimType ReturnT = classify(E);
6135
6136 // Non-primitive return type. Prepare storage.
6137 if (!Initializing && !ReturnT && !ReturnType->isVoidType()) {
6138 UnsignedOrNone LocalIndex = allocateLocal(E);
6139 if (!LocalIndex)
6140 return false;
6141 if (!this->emitGetPtrLocal(*LocalIndex, E))
6142 return false;
6143 }
6144
6145 // Prepare function arguments including special cases.
6146 switch (BuiltinID) {
6147 case Builtin::BI__builtin_object_size:
6148 case Builtin::BI__builtin_dynamic_object_size: {
6149 assert(E->getNumArgs() == 2);
6150 const Expr *Arg0 = E->getArg(0);
6151 if (Arg0->isGLValue()) {
6152 if (!this->visit(Arg0))
6153 return false;
6154
6155 } else {
6157 return false;
6158 }
6159 if (!this->visit(E->getArg(1)))
6160 return false;
6161
6162 } break;
6163 case Builtin::BI__assume:
6164 case Builtin::BI__builtin_assume:
6165 // Argument is not evaluated.
6166 break;
6167 case Builtin::BI__atomic_is_lock_free:
6168 case Builtin::BI__atomic_always_lock_free: {
6169 assert(E->getNumArgs() == 2);
6170 if (!this->visit(E->getArg(0)))
6171 return false;
6172 if (!this->visitAsLValue(E->getArg(1)))
6173 return false;
6174 } break;
6175
6176 default:
6177 if (!Context::isUnevaluatedBuiltin(BuiltinID)) {
6178 // Put arguments on the stack.
6179 for (const auto *Arg : E->arguments()) {
6180 if (!this->visit(Arg))
6181 return false;
6182 }
6183 }
6184 }
6185
6186 if (!this->emitCallBI(E, BuiltinID, E))
6187 return false;
6188
6189 if (DiscardResult && !ReturnType->isVoidType())
6190 return this->emitPop(ReturnT.value_or(PT_Ptr), E);
6191
6192 return true;
6193}
6194
6196 if (!MD || !MD->isDefaulted())
6197 return false;
6199 return false;
6200 return MD->getParent()->isUnion() ||
6202}
6203
6204template <class Emitter>
6206 if (E->containsErrors())
6207 return false;
6208 const FunctionDecl *FuncDecl = E->getDirectCallee();
6209
6210 if (FuncDecl) {
6211 if (unsigned BuiltinID = FuncDecl->getBuiltinID())
6212 return VisitBuiltinCallExpr(E, BuiltinID);
6213
6214 // Calls to replaceable operator new/operator delete.
6216 if (FuncDecl->getDeclName().isAnyOperatorNew())
6217 return VisitBuiltinCallExpr(E, Builtin::BI__builtin_operator_new);
6218 assert(FuncDecl->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
6219 FuncDecl->getDeclName().getCXXOverloadedOperator() ==
6220 OO_Array_Delete);
6221 return VisitBuiltinCallExpr(E, Builtin::BI__builtin_operator_delete);
6222 }
6223
6224 // Explicit calls to trivial destructors
6225 if (const auto *DD = dyn_cast<CXXDestructorDecl>(FuncDecl);
6226 DD && DD->isTrivial()) {
6227 const auto *MemberCall = cast<CXXMemberCallExpr>(E);
6228 if (!this->visit(MemberCall->getImplicitObjectArgument()))
6229 return false;
6230 return this->emitCheckDestruction(E) && this->emitEndLifetime(E) &&
6231 this->emitPopPtr(E);
6232 }
6233 }
6234
6235 LocalScope<Emitter> CallScope(this, ScopeKind::Call);
6236 ArrayRef<const Expr *> Args(E->getArgs(), E->getNumArgs());
6237 bool ActivateLHS = false;
6238
6239 // Emit a special op for trivial copy/move operators.
6240 if (isTrivialMemoryOperation(dyn_cast_if_present<CXXMethodDecl>(FuncDecl))) {
6241 const Function *Func = getFunction(FuncDecl);
6242 if (!Func)
6243 return false;
6244
6245 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
6246 OCE && OCE->isAssignmentOp()) {
6247 const CXXRecordDecl *LHSRecord = Args[0]->getType()->getAsCXXRecordDecl();
6248 ActivateLHS = LHSRecord && LHSRecord->hasTrivialDefaultConstructor();
6249 }
6250 if (const auto *MCE = dyn_cast<CXXMemberCallExpr>(E))
6251 if (!this->visit(MCE->getImplicitObjectArgument()))
6252 return false;
6253
6254 if (!this->visitCallArgs(Args, FuncDecl, /*ActivateLHS=*/ActivateLHS,
6256 return false;
6257
6258 if (!this->emitTrivialCopy(ActivateLHS, Func, E))
6259 return false;
6260
6261 if (!DiscardResult)
6262 return CallScope.destroyLocals();
6263 return this->emitPopPtr(E) && CallScope.destroyLocals();
6264 }
6265
6266 QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
6268 bool HasRVO = !ReturnType->isVoidType() && !T;
6269
6270 if (HasRVO) {
6271 if (DiscardResult) {
6272 // If we need to discard the return value but the function returns its
6273 // value via an RVO pointer, we need to create one such pointer just
6274 // for this call.
6275 if (UnsignedOrNone LocalIndex = allocateLocal(E)) {
6276 if (!this->emitGetPtrLocal(*LocalIndex, E))
6277 return false;
6278 }
6279 } else {
6280 // We need the result. Prepare a pointer to return or
6281 // dup the current one.
6282 if (!Initializing) {
6283 if (UnsignedOrNone LocalIndex = allocateLocal(E)) {
6284 if (!this->emitGetPtrLocal(*LocalIndex, E))
6285 return false;
6286 }
6287 }
6288 if (!this->emitDupPtr(E))
6289 return false;
6290 }
6291 }
6292
6293 const Expr *ReversedArgs[2];
6294 bool IsAssignmentOperatorCall = false;
6295 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
6296 OCE && OCE->isAssignmentOp()) {
6297 // Just like with regular assignments, we need to special-case assignment
6298 // operators here and evaluate the RHS (the second arg) before the LHS (the
6299 // first arg). We fix this by using a Flip op later.
6300 assert(Args.size() == 2);
6301 const CXXRecordDecl *LHSRecord = Args[0]->getType()->getAsCXXRecordDecl();
6302 ActivateLHS = LHSRecord && LHSRecord->hasTrivialDefaultConstructor();
6303 IsAssignmentOperatorCall = true;
6304 ReversedArgs[0] = Args[1];
6305 ReversedArgs[1] = Args[0];
6306 Args = ReversedArgs;
6307 }
6308
6309 // Calling a static operator will still
6310 // pass the instance, but we don't need it.
6311 // Discard it here.
6312 if (isa<CXXOperatorCallExpr>(E)) {
6313 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
6314 MD && MD->isStatic()) {
6315 if (!this->discard(E->getArg(0)))
6316 return false;
6317 // Drop first arg.
6318 Args = Args.drop_front();
6319 }
6320 }
6321
6322 bool Devirtualized = false;
6323 UnsignedOrNone CalleeOffset = std::nullopt;
6324 // Add the (optional, implicit) This pointer.
6325 if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
6326 if (!FuncDecl && classifyPrim(E->getCallee()) == PT_MemberPtr) {
6327 // If we end up creating a CallPtr op for this, we need the base of the
6328 // member pointer as the instance pointer, and later extract the function
6329 // decl as the function pointer.
6330 const Expr *Callee = E->getCallee();
6331 CalleeOffset =
6332 this->allocateLocalPrimitive(Callee, PT_MemberPtr, /*IsConst=*/true);
6333 if (!this->visit(Callee))
6334 return false;
6335 if (!this->emitSetLocal(PT_MemberPtr, *CalleeOffset, E))
6336 return false;
6337 if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
6338 return false;
6339 if (!this->emitGetMemberPtrBase(E))
6340 return false;
6341 } else {
6342 const auto *InstancePtr = MC->getImplicitObjectArgument();
6343 if (isa_and_nonnull<CXXDestructorDecl>(CompilingFunction) ||
6344 isa_and_nonnull<CXXConstructorDecl>(CompilingFunction)) {
6345 const auto *Stripped = stripCheckedDerivedToBaseCasts(InstancePtr);
6346 if (isa<CXXThisExpr>(Stripped)) {
6347 FuncDecl =
6348 cast<CXXMethodDecl>(FuncDecl)->getCorrespondingMethodInClass(
6349 Stripped->getType()->getPointeeType()->getAsCXXRecordDecl());
6350 Devirtualized = true;
6351 if (!this->visit(Stripped))
6352 return false;
6353 } else {
6354 if (!this->visit(InstancePtr))
6355 return false;
6356 }
6357 } else {
6358 if (!this->visit(InstancePtr))
6359 return false;
6360 }
6361 }
6362 } else if (const auto *PD =
6363 dyn_cast<CXXPseudoDestructorExpr>(E->getCallee())) {
6364 if (!this->emitCheckPseudoDtor(E))
6365 return false;
6366 const Expr *Base = PD->getBase();
6367 // E.g. `using T = int; 0.~T();`.
6368 if (OptPrimType BaseT = classify(Base); !BaseT || BaseT != PT_Ptr)
6369 return this->discard(Base);
6370 if (!this->visit(Base))
6371 return false;
6372 return this->emitPseudoDtor(E);
6373 } else if (!FuncDecl) {
6374 const Expr *Callee = E->getCallee();
6375 CalleeOffset =
6376 this->allocateLocalPrimitive(Callee, PT_Ptr, /*IsConst=*/true);
6377 if (!this->visit(Callee))
6378 return false;
6379 if (!this->emitSetLocal(PT_Ptr, *CalleeOffset, E))
6380 return false;
6381 }
6382
6383 if (!this->visitCallArgs(Args, FuncDecl, ActivateLHS,
6385 return false;
6386
6387 // Undo the argument reversal we did earlier.
6388 if (IsAssignmentOperatorCall) {
6389 assert(Args.size() == 2);
6390 PrimType Arg1T = classify(Args[0]).value_or(PT_Ptr);
6391 PrimType Arg2T = classify(Args[1]).value_or(PT_Ptr);
6392 if (!this->emitFlip(Arg2T, Arg1T, E))
6393 return false;
6394 }
6395
6396 if (FuncDecl) {
6397 const Function *Func = getFunction(FuncDecl);
6398 if (!Func)
6399 return false;
6400
6401 // In error cases, the function may be called with fewer arguments than
6402 // parameters.
6403 if (E->getNumArgs() < Func->getNumWrittenParams())
6404 return false;
6405
6406 assert(HasRVO == Func->hasRVO());
6407
6408 bool HasQualifier = false;
6409 if (const auto *ME = dyn_cast<MemberExpr>(E->getCallee()))
6410 HasQualifier = ME->hasQualifier();
6411
6412 bool IsVirtual = false;
6413 if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
6414 IsVirtual = !Devirtualized && MD->isVirtual();
6415
6416 // In any case call the function. The return value will end up on the stack
6417 // and if the function has RVO, we already have the pointer on the stack to
6418 // write the result into.
6419 if (IsVirtual && !HasQualifier) {
6420 uint32_t VarArgSize = 0;
6421 unsigned NumParams =
6422 Func->getNumWrittenParams() +
6423 (isa<CXXOperatorCallExpr>(E) && Func->hasImplicitThisPointer());
6424 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
6425 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
6426
6427 if (!this->emitCallVirt(Func, VarArgSize, E))
6428 return false;
6429 } else if (Func->isVariadic()) {
6430 uint32_t VarArgSize = 0;
6431 unsigned NumParams =
6432 Func->getNumWrittenParams() +
6433 (isa<CXXOperatorCallExpr>(E) && Func->hasImplicitThisPointer());
6434 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
6435 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
6436 if (!this->emitCallVar(Func, VarArgSize, E))
6437 return false;
6438 } else {
6439 if (!this->emitCall(Func, 0, E))
6440 return false;
6441 }
6442 } else {
6443 // Indirect call. Visit the callee, which will leave a FunctionPointer on
6444 // the stack. Cleanup of the returned value if necessary will be done after
6445 // the function call completed.
6446
6447 // Sum the size of all args from the call expr.
6448 uint32_t ArgSize = 0;
6449 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
6450 ArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
6451
6452 // Get the callee, either from a member pointer or function pointer saved in
6453 // CalleeOffset.
6454 if (isa<CXXMemberCallExpr>(E) && CalleeOffset) {
6455 if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
6456 return false;
6457 if (!this->emitGetMemberPtrDecl(E))
6458 return false;
6459 } else {
6460 if (!this->emitGetLocal(PT_Ptr, *CalleeOffset, E))
6461 return false;
6462 }
6463 if (!this->emitCallPtr(ArgSize, E, E))
6464 return false;
6465 }
6466
6467 // Cleanup for discarded return values.
6468 if (DiscardResult && !ReturnType->isVoidType() && T)
6469 return this->emitPop(*T, E) && CallScope.destroyLocals();
6470
6471 return CallScope.destroyLocals();
6472}
6473
6474template <class Emitter>
6476 SourceLocScope<Emitter> SLS(this, E);
6477
6478 return this->delegate(E->getExpr());
6479}
6480
6481template <class Emitter>
6483 SourceLocScope<Emitter> SLS(this, E);
6484
6485 return this->delegate(E->getExpr());
6486}
6487
6488template <class Emitter>
6490 if (DiscardResult)
6491 return true;
6492
6493 return this->emitConstBool(E->getValue(), E);
6494}
6495
6496template <class Emitter>
6498 const CXXNullPtrLiteralExpr *E) {
6499 if (DiscardResult)
6500 return true;
6501
6502 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(E->getType());
6503 return this->emitNullPtr(Val, nullptr, E);
6504}
6505
6506template <class Emitter>
6508 if (DiscardResult)
6509 return true;
6510
6511 assert(E->getType()->isIntegerType());
6512
6514 return this->emitZero(T, E);
6515}
6516
6517template <class Emitter>
6519 if (DiscardResult)
6520 return true;
6521
6522 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
6523 if (this->LambdaThisCapture.Offset > 0) {
6524 if (this->LambdaThisCapture.IsPtr)
6525 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
6526 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
6527 }
6528 }
6529
6530 // In some circumstances, the 'this' pointer does not actually refer to the
6531 // instance pointer of the current function frame, but e.g. to the declaration
6532 // currently being initialized. Here we emit the necessary instruction(s) for
6533 // this scenario.
6534 if (!InitStackActive || InitStack.empty())
6535 return this->emitThis(E);
6536
6537 // If our init stack is, for example:
6538 // 0 Stack: 3 (decl)
6539 // 1 Stack: 6 (init list)
6540 // 2 Stack: 1 (field)
6541 // 3 Stack: 6 (init list)
6542 // 4 Stack: 1 (field)
6543 //
6544 // We want to find the LAST element in it that's an init list,
6545 // which is marked with the K_InitList marker. The index right
6546 // before that points to an init list. We need to find the
6547 // elements before the K_InitList element that point to a base
6548 // (e.g. a decl or This), optionally followed by field, elem, etc.
6549 // In the example above, we want to emit elements [0..2].
6550 unsigned StartIndex = 0;
6551 unsigned EndIndex = 0;
6552 // Find the init list.
6553 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
6554 if (InitStack[StartIndex].Kind == InitLink::K_DIE) {
6555 EndIndex = StartIndex;
6556 --StartIndex;
6557 break;
6558 }
6559 }
6560
6561 // Walk backwards to find the base.
6562 for (; StartIndex > 0; --StartIndex) {
6563 if (InitStack[StartIndex].Kind == InitLink::K_InitList)
6564 continue;
6565
6566 if (InitStack[StartIndex].Kind != InitLink::K_Field &&
6567 InitStack[StartIndex].Kind != InitLink::K_Elem &&
6568 InitStack[StartIndex].Kind != InitLink::K_Base &&
6569 InitStack[StartIndex].Kind != InitLink::K_DIE)
6570 break;
6571 }
6572
6573 if (StartIndex == 0 && EndIndex == 0)
6574 EndIndex = InitStack.size() - 1;
6575
6576 assert(InitStack[StartIndex].Kind == InitLink::K_Decl ||
6577 InitStack[StartIndex].Kind == InitLink::K_This ||
6578 InitStack[StartIndex].Kind == InitLink::K_Temp ||
6579 InitStack[StartIndex].Kind == InitLink::K_RVO);
6580
6581 // NOTE: This could be StartIndex < EndIndex, but we're also abusing the
6582 // InitStack mechanism in visitWithSubstitutions to have the This pointer
6583 // _just_ be a local variable.
6584 assert(StartIndex <= EndIndex);
6585
6586 // Emit the instructions.
6587 for (unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
6588 if (InitStack[I].Kind == InitLink::K_InitList ||
6589 InitStack[I].Kind == InitLink::K_DIE)
6590 continue;
6591 if (!InitStack[I].template emit<Emitter>(this, E))
6592 return false;
6593 }
6594 return true;
6595}
6596
6597template <class Emitter> bool Compiler<Emitter>::visitStmt(const Stmt *S) {
6598 switch (S->getStmtClass()) {
6599 case Stmt::CompoundStmtClass:
6601 case Stmt::DeclStmtClass:
6602 return visitDeclStmt(cast<DeclStmt>(S), /*EvaluateConditionDecl=*/true);
6603 case Stmt::ReturnStmtClass:
6605 case Stmt::IfStmtClass:
6606 return visitIfStmt(cast<IfStmt>(S));
6607 case Stmt::WhileStmtClass:
6609 case Stmt::DoStmtClass:
6610 return visitDoStmt(cast<DoStmt>(S));
6611 case Stmt::ForStmtClass:
6612 return visitForStmt(cast<ForStmt>(S));
6613 case Stmt::CXXForRangeStmtClass:
6615 case Stmt::BreakStmtClass:
6617 case Stmt::ContinueStmtClass:
6619 case Stmt::SwitchStmtClass:
6621 case Stmt::CaseStmtClass:
6622 return visitCaseStmt(cast<CaseStmt>(S));
6623 case Stmt::DefaultStmtClass:
6625 case Stmt::AttributedStmtClass:
6627 case Stmt::CXXTryStmtClass:
6629 case Stmt::NullStmtClass:
6630 return true;
6631 // Always invalid statements.
6632 case Stmt::GCCAsmStmtClass:
6633 case Stmt::MSAsmStmtClass:
6634 case Stmt::GotoStmtClass:
6635 return this->emitInvalid(S);
6636 case Stmt::LabelStmtClass:
6637 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
6638 case Stmt::CXXExpansionStmtInstantiationClass:
6641 default: {
6642 if (const auto *E = dyn_cast<Expr>(S))
6643 return this->discard(E);
6644 return false;
6645 }
6646 }
6647}
6648
6649template <class Emitter>
6652 for (const auto *InnerStmt : S->body())
6653 if (!visitStmt(InnerStmt))
6654 return false;
6655 return Scope.destroyLocals();
6656}
6657
6658template <class Emitter>
6659bool Compiler<Emitter>::maybeEmitDeferredVarInit(const VarDecl *VD) {
6660 if (auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
6661 for (auto *BD : DD->flat_bindings())
6662 if (auto *KD = BD->getHoldingVar();
6663 KD && !this->visitVarDecl(KD, KD->getInit()))
6664 return false;
6665 }
6666 return true;
6667}
6668
6670 assert(FD);
6671 assert(FD->getParent()->isUnion());
6672 const CXXRecordDecl *CXXRD =
6674 return !CXXRD || CXXRD->hasTrivialDefaultConstructor();
6675}
6676
6677template <class Emitter> bool Compiler<Emitter>::refersToUnion(const Expr *E) {
6678 for (;;) {
6679 if (const auto *ME = dyn_cast<MemberExpr>(E)) {
6680 if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6681 FD && FD->getParent()->isUnion() && hasTrivialDefaultCtorParent(FD))
6682 return true;
6683 E = ME->getBase();
6684 continue;
6685 }
6686
6687 if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6688 E = ASE->getBase()->IgnoreImplicit();
6689 continue;
6690 }
6691
6692 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E);
6693 ICE && (ICE->getCastKind() == CK_NoOp ||
6694 ICE->getCastKind() == CK_DerivedToBase ||
6695 ICE->getCastKind() == CK_UncheckedDerivedToBase)) {
6696 E = ICE->getSubExpr();
6697 continue;
6698 }
6699
6700 if (const auto *This = dyn_cast<CXXThisExpr>(E)) {
6701 const auto *ThisRecord =
6702 This->getType()->getPointeeType()->getAsRecordDecl();
6703 if (!ThisRecord->isUnion())
6704 return false;
6705 // Otherwise, always activate if we're in the ctor.
6706 if (const auto *Ctor =
6707 dyn_cast_if_present<CXXConstructorDecl>(CompilingFunction))
6708 return Ctor->getParent() == ThisRecord;
6709 return false;
6710 }
6711
6712 break;
6713 }
6714 return false;
6715}
6716
6717template <class Emitter>
6719 bool EvaluateConditionDecl) {
6720 for (const auto *D : DS->decls()) {
6723 continue;
6724
6725 if (const auto *ESD = dyn_cast<CXXExpansionStmtDecl>(D)) {
6726 assert(ESD->getInstantiations() && "not expanded?");
6727 if (!this->visitStmt(ESD->getInstantiations()))
6728 return false;
6729 continue;
6730 }
6731
6732 const auto *VD = dyn_cast<VarDecl>(D);
6733 if (!VD)
6734 return false;
6735 if (!this->visitVarDecl(VD, VD->getInit()))
6736 return false;
6737
6738 // Register decomposition decl holding vars.
6739 if (EvaluateConditionDecl && !this->maybeEmitDeferredVarInit(VD))
6740 return false;
6741 }
6742
6743 return true;
6744}
6745
6746template <class Emitter>
6748 if (this->InStmtExpr)
6749 return this->emitUnsupported(RS);
6750
6751 if (const Expr *RE = RS->getRetValue()) {
6752 LocalScope<Emitter> RetScope(this);
6753 if (ReturnType) {
6754 // Primitive types are simply returned.
6755 if (!this->visit(RE))
6756 return false;
6757 this->emitCleanup();
6758 return this->emitRet(*ReturnType, RS);
6759 }
6760
6761 if (RE->getType()->isVoidType()) {
6762 if (!this->visit(RE))
6763 return false;
6764 } else {
6765 if (RE->containsErrors())
6766 return false;
6767
6769 // RVO - construct the value in the return location.
6770 if (!this->emitRVOPtr(RE))
6771 return false;
6772 if (!this->visitInitializerPop(RE))
6773 return false;
6774
6775 this->emitCleanup();
6776 return this->emitRetVoid(RS);
6777 }
6778 }
6779
6780 // Void return.
6781 this->emitCleanup();
6782 return this->emitRetVoid(RS);
6783}
6784
6785template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
6786 LocalScope<Emitter> IfScope(this);
6787
6788 auto visitChildStmt = [&](const Stmt *S) -> bool {
6789 LocalScope<Emitter> SScope(this);
6790 if (!visitStmt(S))
6791 return false;
6792 return SScope.destroyLocals();
6793 };
6794
6795 if (auto *CondInit = IS->getInit()) {
6796 if (!visitStmt(CondInit))
6797 return false;
6798 }
6799
6800 if (const DeclStmt *CondDecl = IS->getConditionVariableDeclStmt()) {
6801 if (!visitDeclStmt(CondDecl))
6802 return false;
6803 }
6804
6805 // Save ourselves compiling some code and the jumps, etc. if the condition is
6806 // stataically known to be either true or false. We could look at more cases
6807 // here, but I think all the ones that actually happen are using a
6808 // ConstantExpr.
6809 if (std::optional<bool> BoolValue = getBoolValue(IS->getCond())) {
6810 if (*BoolValue)
6811 return visitChildStmt(IS->getThen());
6812 if (const Stmt *Else = IS->getElse())
6813 return visitChildStmt(Else);
6814 return true;
6815 }
6816
6817 // Otherwise, compile the condition.
6818 if (IS->isNonNegatedConsteval()) {
6819 if (!this->emitIsConstantContext(IS))
6820 return false;
6821 } else if (IS->isNegatedConsteval()) {
6822 if (!this->emitIsConstantContext(IS))
6823 return false;
6824 if (!this->emitInv(IS))
6825 return false;
6826 } else {
6828 if (!this->visitBool(IS->getCond()))
6829 return false;
6830 if (!CondScope.destroyLocals())
6831 return false;
6832 }
6833
6834 if (!this->maybeEmitDeferredVarInit(IS->getConditionVariable()))
6835 return false;
6836
6837 if (const Stmt *Else = IS->getElse()) {
6838 LabelTy LabelElse = this->getLabel();
6839 LabelTy LabelEnd = this->getLabel();
6840 if (!this->jumpFalse(LabelElse, IS))
6841 return false;
6842 if (!visitChildStmt(IS->getThen()))
6843 return false;
6844 if (!this->jump(LabelEnd, IS))
6845 return false;
6846 this->emitLabel(LabelElse);
6847 if (!visitChildStmt(Else))
6848 return false;
6849 this->emitLabel(LabelEnd);
6850 } else {
6851 LabelTy LabelEnd = this->getLabel();
6852 if (!this->jumpFalse(LabelEnd, IS))
6853 return false;
6854 if (!visitChildStmt(IS->getThen()))
6855 return false;
6856 this->emitLabel(LabelEnd);
6857 }
6858
6859 if (!IfScope.destroyLocals())
6860 return false;
6861
6862 return true;
6863}
6864
6865template <class Emitter>
6867 const Expr *Cond = S->getCond();
6868 const Stmt *Body = S->getBody();
6869
6870 LabelTy CondLabel = this->getLabel(); // Label before the condition.
6871 LabelTy EndLabel = this->getLabel(); // Label after the loop.
6872 LocalScope<Emitter> WholeLoopScope(this);
6873 LoopScope<Emitter> LS(this, S, EndLabel, CondLabel);
6874
6875 this->fallthrough(CondLabel);
6876 this->emitLabel(CondLabel);
6877
6878 // Start of the loop body {
6879 LocalScope<Emitter> CondScope(this);
6880
6881 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt()) {
6882 if (!visitDeclStmt(CondDecl))
6883 return false;
6884 }
6885
6886 if (!this->visitBool(Cond))
6887 return false;
6888
6889 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
6890 return false;
6891
6892 if (!this->jumpFalse(EndLabel, S))
6893 return false;
6894
6895 if (!this->visitStmt(Body))
6896 return false;
6897
6898 if (!CondScope.destroyLocals())
6899 return false;
6900 // } End of loop body.
6901
6902 if (!this->jump(CondLabel, S))
6903 return false;
6904 this->fallthrough(EndLabel);
6905 this->emitLabel(EndLabel);
6906
6907 return CondScope.destroyLocals() && WholeLoopScope.destroyLocals();
6908}
6909
6910template <class Emitter> bool Compiler<Emitter>::visitDoStmt(const DoStmt *S) {
6911 const Expr *Cond = S->getCond();
6912 const Stmt *Body = S->getBody();
6913
6914 LabelTy StartLabel = this->getLabel();
6915 LabelTy EndLabel = this->getLabel();
6916 LabelTy CondLabel = this->getLabel();
6917 LocalScope<Emitter> WholeLoopScope(this);
6918 LoopScope<Emitter> LS(this, S, EndLabel, CondLabel);
6919
6920 this->fallthrough(StartLabel);
6921 this->emitLabel(StartLabel);
6922
6923 {
6924 LocalScope<Emitter> CondScope(this);
6925 if (!this->visitStmt(Body))
6926 return false;
6927 this->fallthrough(CondLabel);
6928 this->emitLabel(CondLabel);
6929 if (!this->visitBool(Cond))
6930 return false;
6931
6932 if (!CondScope.destroyLocals())
6933 return false;
6934 }
6935 if (!this->jumpTrue(StartLabel, S))
6936 return false;
6937
6938 this->fallthrough(EndLabel);
6939 this->emitLabel(EndLabel);
6940 return WholeLoopScope.destroyLocals();
6941}
6942
6943template <class Emitter>
6945 // for (Init; Cond; Inc) { Body }
6946 const Stmt *Init = S->getInit();
6947 const Expr *Cond = S->getCond();
6948 const Expr *Inc = S->getInc();
6949 const Stmt *Body = S->getBody();
6950
6951 LabelTy EndLabel = this->getLabel();
6952 LabelTy CondLabel = this->getLabel();
6953 LabelTy IncLabel = this->getLabel();
6954
6955 LocalScope<Emitter> WholeLoopScope(this);
6956 if (Init && !this->visitStmt(Init))
6957 return false;
6958
6959 // Start of the loop body {
6960 this->fallthrough(CondLabel);
6961 this->emitLabel(CondLabel);
6962
6963 LocalScope<Emitter> CondScope(this);
6964 LoopScope<Emitter> LS(this, S, EndLabel, IncLabel);
6965 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt()) {
6966 if (!visitDeclStmt(CondDecl))
6967 return false;
6968 }
6969
6970 if (Cond) {
6971 if (!this->visitBool(Cond))
6972 return false;
6973 if (!this->jumpFalse(EndLabel, S))
6974 return false;
6975 }
6976 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
6977 return false;
6978
6979 if (Body && !this->visitStmt(Body))
6980 return false;
6981
6982 this->fallthrough(IncLabel);
6983 this->emitLabel(IncLabel);
6984 if (Inc && !this->discard(Inc))
6985 return false;
6986
6987 if (!CondScope.destroyLocals())
6988 return false;
6989 if (!this->jump(CondLabel, S))
6990 return false;
6991 // } End of loop body.
6992
6993 this->emitLabel(EndLabel);
6994 // If we jumped out of the loop above, we still need to clean up the condition
6995 // scope.
6996 return CondScope.destroyLocals() && WholeLoopScope.destroyLocals();
6997}
6998
6999template <class Emitter>
7001 const Stmt *Init = S->getInit();
7002 const Expr *Cond = S->getCond();
7003 const Expr *Inc = S->getInc();
7004 const Stmt *Body = S->getBody();
7005 const Stmt *BeginStmt = S->getBeginStmt();
7006 const Stmt *RangeStmt = S->getRangeStmt();
7007 const Stmt *EndStmt = S->getEndStmt();
7008
7009 LabelTy EndLabel = this->getLabel();
7010 LabelTy CondLabel = this->getLabel();
7011 LabelTy IncLabel = this->getLabel();
7012 LocalScope<Emitter> WholeLoopScope(this);
7013 LoopScope<Emitter> LS(this, S, EndLabel, IncLabel);
7014
7015 // Emit declarations needed in the loop.
7016 if (Init && !this->visitStmt(Init))
7017 return false;
7018 if (!this->visitStmt(RangeStmt))
7019 return false;
7020 if (!this->visitStmt(BeginStmt))
7021 return false;
7022 if (!this->visitStmt(EndStmt))
7023 return false;
7024
7025 LocalScope<Emitter> CondScope(this);
7026 // Now the condition as well as the loop variable assignment.
7027 this->fallthrough(CondLabel);
7028 this->emitLabel(CondLabel);
7029 if (!this->visitBool(Cond))
7030 return false;
7031 if (!this->jumpFalse(EndLabel, S))
7032 return false;
7033
7034 if (!this->visitDeclStmt(S->getLoopVarStmt(), /*EvaluateConditionDecl=*/true))
7035 return false;
7036
7037 // Body.
7038 {
7039 if (!this->visitStmt(Body))
7040 return false;
7041
7042 this->fallthrough(IncLabel);
7043 this->emitLabel(IncLabel);
7044 if (!this->discard(Inc))
7045 return false;
7046 }
7047
7048 if (!CondScope.destroyLocals())
7049 return false;
7050 if (!this->jump(CondLabel, S))
7051 return false;
7052
7053 this->fallthrough(EndLabel);
7054 this->emitLabel(EndLabel);
7055 return WholeLoopScope.destroyLocals();
7056}
7057
7058template <class Emitter>
7060 if (LabelInfoStack.empty())
7061 return false;
7062
7063 OptLabelTy TargetLabel = std::nullopt;
7064 const Stmt *TargetLoop = S->getNamedLoopOrSwitch();
7065 const VariableScope<Emitter> *BreakScope = nullptr;
7066
7067 if (!TargetLoop) {
7068 for (const auto &LI : llvm::reverse(LabelInfoStack)) {
7069 if (LI.BreakLabel) {
7070 TargetLabel = *LI.BreakLabel;
7071 BreakScope = LI.BreakOrContinueScope;
7072 break;
7073 }
7074 }
7075 } else {
7076 for (const auto &LI : LabelInfoStack) {
7077 if (LI.Name == TargetLoop) {
7078 TargetLabel = *LI.BreakLabel;
7079 BreakScope = LI.BreakOrContinueScope;
7080 break;
7081 }
7082 }
7083 }
7084
7085 // Faulty break statement (e.g. label redefined or named loops disabled).
7086 if (!TargetLabel)
7087 return false;
7088
7089 for (VariableScope<Emitter> *C = this->VarScope; C != BreakScope;
7090 C = C->getParent()) {
7091 if (!C->destroyLocals())
7092 return false;
7093 }
7094
7095 return this->jump(*TargetLabel, S);
7096}
7097
7098template <class Emitter>
7100 if (LabelInfoStack.empty())
7101 return false;
7102
7103 OptLabelTy TargetLabel = std::nullopt;
7104 const Stmt *TargetLoop = S->getNamedLoopOrSwitch();
7105 const VariableScope<Emitter> *ContinueScope = nullptr;
7106
7107 if (!TargetLoop) {
7108 for (const auto &LI : llvm::reverse(LabelInfoStack)) {
7109 if (LI.ContinueLabel) {
7110 TargetLabel = *LI.ContinueLabel;
7111 ContinueScope = LI.BreakOrContinueScope;
7112 break;
7113 }
7114 }
7115 } else {
7116 for (auto LI : LabelInfoStack) {
7117 if (LI.Name == TargetLoop) {
7118 TargetLabel = *LI.ContinueLabel;
7119 ContinueScope = LI.BreakOrContinueScope;
7120 break;
7121 }
7122 }
7123 }
7124
7125 if (!TargetLabel)
7126 return false;
7127
7128 for (VariableScope<Emitter> *C = VarScope; C != ContinueScope;
7129 C = C->getParent()) {
7130 if (!C->destroyLocals())
7131 return false;
7132 }
7133
7134 return this->jump(*TargetLabel, S);
7135}
7136
7137template <class Emitter>
7139 const Expr *Cond = S->getCond();
7140 if (Cond->containsErrors())
7141 return false;
7142
7143 PrimType CondT = this->classifyPrim(Cond->getType());
7144 LocalScope<Emitter> LS(this);
7145 llvm::SaveAndRestore StmtExprSAR(this->SwitchInStmtExpr, this->InStmtExpr);
7146
7147 LabelTy EndLabel = this->getLabel();
7148 UnsignedOrNone DefaultLabel = std::nullopt;
7149 unsigned CondVar =
7150 this->allocateLocalPrimitive(Cond, CondT, /*IsConst=*/true);
7151
7152 if (const auto *CondInit = S->getInit())
7153 if (!visitStmt(CondInit))
7154 return false;
7155
7156 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
7157 if (!visitDeclStmt(CondDecl))
7158 return false;
7159
7160 // Initialize condition variable.
7161 if (!this->visit(Cond))
7162 return false;
7163 if (!this->emitSetLocal(CondT, CondVar, S))
7164 return false;
7165
7166 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
7167 return false;
7168
7170 // Create labels and comparison ops for all case statements.
7171 for (const SwitchCase *SC = S->getSwitchCaseList(); SC;
7172 SC = SC->getNextSwitchCase()) {
7173 if (const auto *CS = dyn_cast<CaseStmt>(SC)) {
7174 CaseLabels[SC] = this->getLabel();
7175
7176 if (CS->caseStmtIsGNURange()) {
7177 LabelTy EndOfRangeCheck = this->getLabel();
7178 const Expr *Low = CS->getLHS();
7179 const Expr *High = CS->getRHS();
7180 if (Low->isValueDependent() || High->isValueDependent())
7181 return false;
7182
7183 if (!this->emitGetLocal(CondT, CondVar, CS))
7184 return false;
7185 if (!this->visit(Low))
7186 return false;
7187 PrimType LT = this->classifyPrim(Low->getType());
7188 if (!this->emitGE(LT, S))
7189 return false;
7190 if (!this->jumpFalse(EndOfRangeCheck, S))
7191 return false;
7192
7193 if (!this->emitGetLocal(CondT, CondVar, CS))
7194 return false;
7195 if (!this->visit(High))
7196 return false;
7197 PrimType HT = this->classifyPrim(High->getType());
7198 if (!this->emitLE(HT, S))
7199 return false;
7200 if (!this->jumpTrue(CaseLabels[CS], S))
7201 return false;
7202 this->emitLabel(EndOfRangeCheck);
7203 continue;
7204 }
7205
7206 const Expr *Value = CS->getLHS();
7207 if (Value->isValueDependent())
7208 return false;
7209 PrimType ValueT = this->classifyPrim(Value->getType());
7210
7211 // Compare the case statement's value to the switch condition.
7212 if (!this->emitGetLocal(CondT, CondVar, CS))
7213 return false;
7214 if (!this->visit(Value))
7215 return false;
7216
7217 // Compare and jump to the case label.
7218 if (!this->emitEQ(ValueT, S))
7219 return false;
7220 if (!this->jumpTrue(CaseLabels[CS], S))
7221 return false;
7222 } else {
7223 assert(!DefaultLabel);
7224 DefaultLabel = this->getLabel();
7225 }
7226 }
7227
7228 // If none of the conditions above were true, fall through to the default
7229 // statement or jump after the switch statement.
7230 if (DefaultLabel) {
7231 if (!this->jump(*DefaultLabel, S))
7232 return false;
7233 } else {
7234 if (!this->jump(EndLabel, S))
7235 return false;
7236 }
7237
7238 SwitchScope<Emitter> SS(this, S, std::move(CaseLabels), EndLabel,
7239 DefaultLabel);
7240 if (!this->visitStmt(S->getBody()))
7241 return false;
7242 this->fallthrough(EndLabel);
7243 this->emitLabel(EndLabel);
7244
7245 return LS.destroyLocals();
7246}
7247
7248template <class Emitter>
7250 this->fallthrough(CaseLabels[S]);
7251 this->emitLabel(CaseLabels[S]);
7252
7253 // We can't jump from an outer switch statement to a case label
7254 // that's inside a StmtExpr.
7255 if (this->InStmtExpr && !this->SwitchInStmtExpr)
7256 return this->emitUnsupported(S);
7257
7258 return this->visitStmt(S->getSubStmt());
7259}
7260
7261template <class Emitter>
7263 if (LabelInfoStack.empty())
7264 return false;
7265
7266 LabelTy DefaultLabel;
7267 for (const LabelInfo &LI : llvm::reverse(LabelInfoStack)) {
7268 if (LI.DefaultLabel) {
7269 DefaultLabel = *LI.DefaultLabel;
7270 break;
7271 }
7272 }
7273
7274 this->emitLabel(DefaultLabel);
7275 return this->visitStmt(S->getSubStmt());
7276}
7277
7278template <class Emitter>
7280 const Stmt *SubStmt = S->getSubStmt();
7281
7282 bool IsMSVCConstexprAttr = isa<ReturnStmt>(SubStmt) &&
7284
7285 if (IsMSVCConstexprAttr && !this->emitPushMSVCCE(S))
7286 return false;
7287
7288 if (this->Ctx.getLangOpts().CXXAssumptions &&
7289 !this->Ctx.getLangOpts().MSVCCompat) {
7290 for (const Attr *A : S->getAttrs()) {
7291 auto *AA = dyn_cast<CXXAssumeAttr>(A);
7292 if (!AA)
7293 continue;
7294
7295 assert(isa<NullStmt>(SubStmt));
7296
7297 const Expr *Assumption = AA->getAssumption();
7298 if (Assumption->isValueDependent())
7299 return false;
7300
7301 if (Assumption->HasSideEffects(this->Ctx.getASTContext()))
7302 continue;
7303
7304 // Evaluate assumption.
7305 if (!this->visitBool(Assumption))
7306 return false;
7307
7308 if (!this->emitAssume(Assumption))
7309 return false;
7310 }
7311 }
7312
7313 // Ignore other attributes.
7314 if (!this->visitStmt(SubStmt))
7315 return false;
7316
7317 if (IsMSVCConstexprAttr)
7318 return this->emitPopMSVCCE(S);
7319 return true;
7320}
7321
7322template <class Emitter>
7324 // Ignore all handlers.
7325 return this->visitStmt(S->getTryBlock());
7326}
7327
7328/// template for (auto x : {1, 2}) {}
7329///
7330/// This is not a loop from an AST perspective at all since it has already
7331/// been instantiated to a list of compound statements.
7332///
7333/// Since we can have control flow in those compound statements, we need to
7334/// handle it mostly like a loop though.
7335template <class Emitter>
7338 LocalScope<Emitter> WholeLoopScope(this, ScopeKind::Block);
7339
7340 for (const Stmt *PreambleStmt : S->getPreambleStmts()) {
7341 if (!this->visitDeclStmt(cast<DeclStmt>(PreambleStmt), true))
7342 return false;
7343 }
7344
7345 LabelTy EndLabel = this->getLabel();
7346 for (const Stmt *Instantiation : S->getInstantiations()) {
7347 LabelTy ContinueLabel = this->getLabel();
7348 LoopScope<Emitter> LS(this, S, EndLabel, ContinueLabel);
7349
7350 if (!this->visitStmt(Instantiation))
7351 return false;
7352 this->emitLabel(ContinueLabel);
7353 }
7354
7355 this->emitLabel(EndLabel);
7356
7357 return WholeLoopScope.destroyLocals();
7358}
7359
7360template <class Emitter>
7361bool Compiler<Emitter>::emitLambdaStaticInvokerBody(const CXXMethodDecl *MD) {
7362 assert(MD->isLambdaStaticInvoker());
7363 assert(MD->hasBody());
7364 assert(cast<CompoundStmt>(MD->getBody())->body_empty());
7365
7366 const CXXRecordDecl *ClosureClass = MD->getParent();
7367 const FunctionDecl *LambdaCallOp;
7368 assert(ClosureClass->captures().empty());
7369 if (ClosureClass->isGenericLambda()) {
7370 LambdaCallOp = ClosureClass->getLambdaCallOperator();
7371 assert(MD->isFunctionTemplateSpecialization() &&
7372 "A generic lambda's static-invoker function must be a "
7373 "template specialization");
7375 FunctionTemplateDecl *CallOpTemplate =
7376 LambdaCallOp->getDescribedFunctionTemplate();
7377 llvm::FoldingSetInsertToken InsertToken;
7378 const FunctionDecl *CorrespondingCallOpSpecialization =
7379 CallOpTemplate->findSpecialization(TAL->asArray(), InsertToken);
7380 assert(CorrespondingCallOpSpecialization);
7381 LambdaCallOp = CorrespondingCallOpSpecialization;
7382 } else {
7383 LambdaCallOp = ClosureClass->getLambdaCallOperator();
7384 }
7385 assert(ClosureClass->captures().empty());
7386 const Function *Func = this->getFunction(LambdaCallOp);
7387 if (!Func)
7388 return false;
7389 assert(Func->hasThisPointer());
7390 assert(Func->getNumParams() == (MD->getNumParams() + 1 + Func->hasRVO()));
7391
7392 if (Func->hasRVO()) {
7393 if (!this->emitRVOPtr(MD))
7394 return false;
7395 }
7396
7397 // The lambda call operator needs an instance pointer, but we don't have
7398 // one here, and we don't need one either because the lambda cannot have
7399 // any captures, as verified above. Emit a null pointer. This is then
7400 // special-cased when interpreting to not emit any misleading diagnostics.
7401 if (!this->emitNullPtr(0, nullptr, MD))
7402 return false;
7403
7404 // Forward all arguments from the static invoker to the lambda call operator.
7405 for (const ParmVarDecl *PVD : MD->parameters()) {
7406 auto It = this->Params.find(PVD);
7407 assert(It != this->Params.end());
7408
7409 // We do the lvalue-to-rvalue conversion manually here, so no need
7410 // to care about references.
7411 PrimType ParamType = this->classify(PVD->getType()).value_or(PT_Ptr);
7412 if (!this->emitGetParam(ParamType, It->second.Index, MD))
7413 return false;
7414 }
7415
7416 if (!this->emitCall(Func, 0, LambdaCallOp))
7417 return false;
7418
7419 this->emitCleanup();
7420 if (ReturnType)
7421 return this->emitRet(*ReturnType, MD);
7422
7423 // Nothing to do, since we emitted the RVO pointer above.
7424 return this->emitRetVoid(MD);
7425}
7426
7427template <class Emitter>
7428bool Compiler<Emitter>::checkLiteralType(const Expr *E) {
7429 if (Ctx.getLangOpts().CPlusPlus23)
7430 return true;
7431
7432 if (!E->isPRValue() || E->getType()->isLiteralType(Ctx.getASTContext()))
7433 return true;
7434
7435 return this->emitCheckLiteralType(E->getType().getTypePtr(), E);
7436}
7437
7439 const Expr *InitExpr = Init->getInit();
7440
7441 if (!Init->isWritten() && !Init->isInClassMemberInitializer() &&
7442 !isa<CXXConstructExpr>(InitExpr))
7443 return true;
7444
7445 if (const auto *CE = dyn_cast<CXXConstructExpr>(InitExpr)) {
7446 const CXXConstructorDecl *Ctor = CE->getConstructor();
7447 if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&
7448 Ctor->isTrivial())
7449 return true;
7450 }
7451
7452 return false;
7453}
7454
7455template <class Emitter>
7456bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
7457 assert(!ReturnType);
7458
7459 // Only start the lifetime of the instance pointer.
7460 if (!this->emitStartThisLifetime1(Ctor))
7461 return false;
7462
7463 auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
7464 const Expr *InitExpr,
7465 bool Activate = false) -> bool {
7466 // We don't know what to do with these, so just return false.
7467 if (InitExpr->getType().isNull())
7468 return false;
7469
7470 if (OptPrimType T = this->classify(InitExpr)) {
7471 if (Activate && !this->emitActivateThisField(FieldOffset, InitExpr))
7472 return false;
7473
7474 if (!this->visit(InitExpr))
7475 return false;
7476
7477 if (F->isBitField())
7478 return this->emitInitThisBitField(*T, FieldOffset, F->bitWidth(),
7479 InitExpr);
7480 return this->emitInitThisField(*T, FieldOffset, InitExpr);
7481 }
7482 // Non-primitive case. Get a pointer to the field-to-initialize
7483 // on the stack and call visitInitialzer() for it.
7484 InitLinkScope<Emitter> FieldScope(this, InitLink::Field(F->Offset));
7485 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
7486 return false;
7487
7488 if (Activate && !this->emitActivate(InitExpr))
7489 return false;
7490
7491 return this->visitInitializerPop(InitExpr);
7492 };
7493
7494 const RecordDecl *RD = Ctor->getParent();
7495 const Record *R = this->getRecord(RD);
7496 if (!R)
7497 return false;
7498 bool IsUnion = R->isUnion();
7499
7500 // Default union copy and move ctors are special.
7501 if (IsUnion && Ctor->isCopyOrMoveConstructor() && Ctor->isDefaulted()) {
7503
7504 // No special case for NumFields == 0 here, so the Memcpy op
7505 // below also does its checks in those cases.
7506
7507 assert(cast<CompoundStmt>(Ctor->getBody())->body_empty());
7508 if (!this->emitThis(Ctor))
7509 return false;
7510
7511 if (!this->emitGetParam(PT_Ptr, /*ParamIndex=*/0, Ctor))
7512 return false;
7513
7514 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
7515 this->emitRetVoid(Ctor);
7516 }
7517
7518 unsigned FieldInits = 0;
7520 // First, initialize virtual bases if the records has them.
7521 if (R->getNumVirtualBases() > 0) {
7522 if (!this->emitThis(Ctor))
7523 return false;
7524 LabelTy AfterVirtBasesLabel = this->getLabel();
7525
7526 // If the instance pointer is a base class, skip the virtual bases.
7527 if (!this->emitIsBaseClass({}))
7528 return false;
7529 if (!this->jumpTrue(AfterVirtBasesLabel, {}))
7530 return false;
7531
7532 for (const auto *Init : Ctor->inits()) {
7533 if (const Type *Base = Init->getBaseClass();
7534 Base && Init->isBaseVirtual()) {
7535 const auto *BaseDecl = Base->getAsCXXRecordDecl();
7536 assert(BaseDecl);
7537 assert(R->findVirtualBase(BaseDecl));
7538 if (!this->emitGetPtrThisVirtBase(BaseDecl, Ctor))
7539 return false;
7540 if (!this->visitInitializerPop(Init->getInit()))
7541 return false;
7542 }
7543 }
7544
7545 this->fallthrough(AfterVirtBasesLabel);
7546 this->emitLabel(AfterVirtBasesLabel);
7547
7548 if (!this->emitPopPtr(Ctor))
7549 return false;
7550 }
7551
7552 for (const auto *Init : Ctor->inits()) {
7553 // Scope needed for the initializers.
7554 LocalScope<Emitter> Scope(this, ScopeKind::FullExpression);
7555
7556 const Expr *InitExpr = Init->getInit();
7557 if (const FieldDecl *Member = Init->getMember()) {
7558 const Record::Field *F = R->getField(Member);
7559
7562 if (!emitFieldInitializer(F, F->Offset, InitExpr, IsUnion))
7563 return false;
7564 ++FieldInits;
7565 } else if (const Type *Base = Init->getBaseClass()) {
7566 const auto *BaseDecl = Base->getAsCXXRecordDecl();
7567 assert(BaseDecl);
7568
7569 if (Init->isBaseVirtual()) {
7570 // See above.
7571 continue;
7572 } else {
7573 // Base class initializer.
7574 // Get This Base and call initializer on it.
7575 const Record::Base *B = R->getBase(BaseDecl);
7576 assert(B);
7577 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
7578 return false;
7579 }
7580
7581 if (!this->visitInitializerPop(InitExpr))
7582 return false;
7583 } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {
7586 unsigned ChainSize = IFD->getChainingSize();
7587 assert(ChainSize >= 2);
7588
7589 unsigned NestedFieldOffset = 0;
7590 const Record::Field *NestedField = nullptr;
7591 for (unsigned I = 0; I != ChainSize; ++I) {
7592 const auto *FD = cast<FieldDecl>(IFD->chain()[I]);
7593 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
7594 assert(FieldRecord);
7595
7596 NestedField = FieldRecord->getField(FD);
7597 assert(NestedField);
7598 IsUnion = IsUnion || FieldRecord->isUnion();
7599
7600 NestedFieldOffset += NestedField->Offset;
7601
7602 // Add a new InitChainLink for the record, but not for the final field.
7603 if (I != ChainSize - 1)
7604 InitStack.push_back(InitLink::Field(NestedField->Offset));
7605 }
7606 assert(NestedField);
7607
7609 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
7610 IsUnion))
7611 return false;
7612
7613 // Mark all chain links as initialized.
7614 unsigned InitFieldOffset = 0;
7615 for (const NamedDecl *ND : IFD->chain().drop_back()) {
7616 const auto *FD = cast<FieldDecl>(ND);
7617 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
7618 assert(FieldRecord);
7619 NestedField = FieldRecord->getField(FD);
7620 InitFieldOffset += NestedField->Offset;
7621 assert(NestedField);
7622 if (!this->emitGetPtrThisField(InitFieldOffset, InitExpr))
7623 return false;
7624 if (!this->emitFinishInitPop(InitExpr))
7625 return false;
7626 }
7627
7628 InitStack.pop_back_n(ChainSize - 1);
7629
7630 } else {
7631 assert(Init->isDelegatingInitializer());
7632 if (!this->emitThis(InitExpr))
7633 return false;
7634 if (!this->visitInitializerPop(Init->getInit()))
7635 return false;
7636 }
7637
7638 if (!Scope.destroyLocals())
7639 return false;
7640 }
7641
7642 if (FieldInits != R->getNumFields()) {
7643 assert(FieldInits < R->getNumFields());
7644 // Start the lifetime of all members.
7645 if (!this->emitStartThisLifetime(Ctor))
7646 return false;
7647 }
7648
7649 if (const Stmt *Body = Ctor->getBody()) {
7650 // Only emit the CtorCheck op for non-empty CompoundStmt bodies.
7651 // For non-CompoundStmts, always assume they are non-empty and emit it.
7652 if (const auto *CS = dyn_cast<CompoundStmt>(Body)) {
7653 if (!CS->body_empty() && !this->emitCtorCheck(SourceInfo{}))
7654 return false;
7655 } else {
7656 if (!this->emitCtorCheck(SourceInfo{}))
7657 return false;
7658 }
7659
7660 if (!visitStmt(Body))
7661 return false;
7662 }
7663
7664 return this->emitRetVoid(SourceInfo{});
7665}
7666
7667template <class Emitter>
7668bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) {
7669 const RecordDecl *RD = Dtor->getParent();
7670 const Record *R = this->getRecord(RD);
7671 if (!R)
7672 return false;
7673
7674 if (!Dtor->isTrivial() && Dtor->getBody()) {
7675 if (!this->visitStmt(Dtor->getBody()))
7676 return false;
7677 }
7678
7679 if (!this->emitThis(Dtor))
7680 return false;
7681
7682 if (!this->emitCheckDestruction(Dtor))
7683 return false;
7684
7685 assert(R);
7686 if (!R->isUnion()) {
7687
7689 // First, destroy all fields.
7690 for (const Record::Field &Field : llvm::reverse(R->fields())) {
7691 const Descriptor *D = Field.Desc;
7692 if (D->hasTrivialDtor())
7693 continue;
7694 if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
7695 return false;
7696 if (!this->emitDestructionPop(D, SourceInfo{}))
7697 return false;
7698 }
7699 }
7700
7701 for (const Record::Base &Base : llvm::reverse(R->bases())) {
7702 if (Base.R->hasTrivialDtor())
7703 continue;
7704 if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
7705 return false;
7706 if (!this->emitRecordDestructionPop(Base.R, {}))
7707 return false;
7708 }
7709
7710 if (R->getNumVirtualBases() > 0) {
7711 LabelTy EndLabel = this->getLabel();
7712 // If this is a base class, skip the virtual bases.
7713 if (!this->emitIsBaseClass({}))
7714 return false;
7715 if (!this->jumpTrue(EndLabel, {}))
7716 return false;
7717
7718 for (const Record::Base &Base : llvm::reverse(R->virtual_bases())) {
7719 if (Base.R->hasTrivialDtor())
7720 continue;
7721 if (!this->emitGetPtrVirtBase(cast<CXXRecordDecl>(Base.R->getDecl()),
7722 SourceInfo{}))
7723 return false;
7724 if (!this->emitRecordDestructionPop(Base.R, {}))
7725 return false;
7726 }
7727
7728 this->fallthrough(EndLabel);
7729 this->emitLabel(EndLabel);
7730 }
7731
7732 if (!this->emitMarkDestroyed(Dtor))
7733 return false;
7734
7735 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
7736}
7737
7738template <class Emitter>
7739bool Compiler<Emitter>::compileUnionAssignmentOperator(
7740 const CXXMethodDecl *MD) {
7741 if (!this->emitThis(MD))
7742 return false;
7743
7744 if (!this->emitGetParam(PT_Ptr, /*ParamIndex=*/0, MD))
7745 return false;
7746
7747 return this->emitMemcpy(MD) && this->emitRet(PT_Ptr, MD);
7748}
7749
7750template <class Emitter>
7752 if (F->getReturnType()->isDependentType())
7753 return false;
7754
7755 // Classify the return type.
7756 ReturnType = this->classify(F->getReturnType());
7757
7758 this->CompilingFunction = F;
7759
7760 if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
7761 return this->compileConstructor(Ctor);
7762 if (const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
7763 return this->compileDestructor(Dtor);
7764
7765 // Emit custom code if this is a lambda static invoker.
7766 if (const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
7767 const RecordDecl *RD = MD->getParent();
7768
7769 if (RD->isUnion() &&
7771 return this->compileUnionAssignmentOperator(MD);
7772
7773 if (MD->isLambdaStaticInvoker())
7774 return this->emitLambdaStaticInvokerBody(MD);
7775 }
7776
7777 // Regular functions.
7778 if (const auto *Body = F->getBody())
7779 if (!visitStmt(Body))
7780 return false;
7781
7782 // Emit a guard return to protect against a code path missing one.
7783 if (F->getReturnType()->isVoidType())
7784 return this->emitRetVoid(SourceInfo{});
7785 return this->emitNoRet(SourceInfo{});
7786}
7787
7788static uint32_t getBitWidth(const Expr *E) {
7789 assert(E->refersToBitField());
7790 const auto *ME = cast<MemberExpr>(E);
7791 const auto *FD = cast<FieldDecl>(ME->getMemberDecl());
7792 return FD->getBitWidthValue();
7793}
7794
7795template <class Emitter>
7797 if (E->containsErrors())
7798 return false;
7799
7800 const Expr *SubExpr = E->getSubExpr();
7801 if (SubExpr->getType()->isAnyComplexType())
7802 return this->VisitComplexUnaryOperator(E);
7803 if (SubExpr->getType()->isVectorType())
7804 return this->VisitVectorUnaryOperator(E);
7805 if (SubExpr->getType()->isFixedPointType())
7806 return this->VisitFixedPointUnaryOperator(E);
7807 OptPrimType T = classify(SubExpr->getType());
7808
7809 switch (E->getOpcode()) {
7810 case UO_PostInc: { // x++
7811 if (!Ctx.getLangOpts().CPlusPlus14)
7812 return this->emitInvalid(E);
7813 if (!T)
7814 return this->emitError(E);
7815
7816 if (!this->visit(SubExpr))
7817 return false;
7818
7819 if (T == PT_Ptr) {
7820 if (!this->emitIncPtr(E))
7821 return false;
7822
7823 return DiscardResult ? this->emitPopPtr(E) : true;
7824 }
7825
7826 if (T == PT_Float)
7827 return DiscardResult ? this->emitIncfPop(getFPOptions(E), E)
7828 : this->emitIncf(getFPOptions(E), E);
7829
7830 if (SubExpr->refersToBitField())
7831 return DiscardResult ? this->emitIncPopBitfield(*T, E->canOverflow(),
7832 getBitWidth(SubExpr), E)
7833 : this->emitIncBitfield(*T, E->canOverflow(),
7834 getBitWidth(SubExpr), E);
7835
7836 return DiscardResult ? this->emitIncPop(*T, E->canOverflow(), E)
7837 : this->emitInc(*T, E->canOverflow(), E);
7838 }
7839 case UO_PostDec: { // x--
7840 if (!Ctx.getLangOpts().CPlusPlus14)
7841 return this->emitInvalid(E);
7842 if (!T)
7843 return this->emitError(E);
7844
7845 if (!this->visit(SubExpr))
7846 return false;
7847
7848 if (T == PT_Ptr) {
7849 if (!this->emitDecPtr(E))
7850 return false;
7851
7852 return DiscardResult ? this->emitPopPtr(E) : true;
7853 }
7854
7855 if (T == PT_Float)
7856 return DiscardResult ? this->emitDecfPop(getFPOptions(E), E)
7857 : this->emitDecf(getFPOptions(E), E);
7858
7859 if (SubExpr->refersToBitField()) {
7860 return DiscardResult ? this->emitDecPopBitfield(*T, E->canOverflow(),
7861 getBitWidth(SubExpr), E)
7862 : this->emitDecBitfield(*T, E->canOverflow(),
7863 getBitWidth(SubExpr), E);
7864 }
7865
7866 return DiscardResult ? this->emitDecPop(*T, E->canOverflow(), E)
7867 : this->emitDec(*T, E->canOverflow(), E);
7868 }
7869 case UO_PreInc: { // ++x
7870 if (!Ctx.getLangOpts().CPlusPlus14)
7871 return this->emitInvalid(E);
7872 if (!T)
7873 return this->emitError(E);
7874
7875 if (!this->visit(SubExpr))
7876 return false;
7877
7878 if (T == PT_Ptr) {
7879 if (!this->emitLoadPtr(E))
7880 return false;
7881 if (!this->emitConstUint8(1, E))
7882 return false;
7883 if (!this->emitAddOffsetUint8(E))
7884 return false;
7885 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7886 }
7887
7888 // Post-inc and pre-inc are the same if the value is to be discarded.
7889 if (DiscardResult) {
7890 if (T == PT_Float)
7891 return this->emitIncfPop(getFPOptions(E), E);
7892 if (SubExpr->refersToBitField())
7893 return DiscardResult ? this->emitIncPopBitfield(*T, E->canOverflow(),
7894 getBitWidth(SubExpr), E)
7895 : this->emitIncBitfield(*T, E->canOverflow(),
7896 getBitWidth(SubExpr), E);
7897 return this->emitIncPop(*T, E->canOverflow(), E);
7898 }
7899
7900 if (T == PT_Float) {
7901 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
7902 if (!this->emitLoadFloat(E))
7903 return false;
7904 APFloat F(TargetSemantics, 1);
7905 if (!this->emitFloat(F, E))
7906 return false;
7907
7908 if (!this->emitAddf(getFPOptions(E), E))
7909 return false;
7910 if (!this->emitStoreFloat(E))
7911 return false;
7912 } else if (SubExpr->refersToBitField()) {
7913 assert(isIntegerOrBoolType(*T));
7914 if (!this->emitPreIncBitfield(*T, E->canOverflow(), getBitWidth(SubExpr),
7915 E))
7916 return false;
7917 } else {
7918 assert(isIntegerOrBoolType(*T));
7919 if (!this->emitPreInc(*T, E->canOverflow(), E))
7920 return false;
7921 }
7922 return E->isGLValue() || this->emitLoadPop(*T, E);
7923 }
7924 case UO_PreDec: { // --x
7925 if (!Ctx.getLangOpts().CPlusPlus14)
7926 return this->emitInvalid(E);
7927 if (!T)
7928 return this->emitError(E);
7929
7930 if (!this->visit(SubExpr))
7931 return false;
7932
7933 if (T == PT_Ptr) {
7934 if (!this->emitLoadPtr(E))
7935 return false;
7936 if (!this->emitConstUint8(1, E))
7937 return false;
7938 if (!this->emitSubOffsetUint8(E))
7939 return false;
7940 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7941 }
7942
7943 // Post-dec and pre-dec are the same if the value is to be discarded.
7944 if (DiscardResult) {
7945 if (T == PT_Float)
7946 return this->emitDecfPop(getFPOptions(E), E);
7947 if (SubExpr->refersToBitField())
7948 return DiscardResult ? this->emitDecPopBitfield(*T, E->canOverflow(),
7949 getBitWidth(SubExpr), E)
7950 : this->emitDecBitfield(*T, E->canOverflow(),
7951 getBitWidth(SubExpr), E);
7952 return this->emitDecPop(*T, E->canOverflow(), E);
7953 }
7954
7955 if (T == PT_Float) {
7956 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
7957 if (!this->emitLoadFloat(E))
7958 return false;
7959 APFloat F(TargetSemantics, 1);
7960 if (!this->emitFloat(F, E))
7961 return false;
7962
7963 if (!this->emitSubf(getFPOptions(E), E))
7964 return false;
7965 if (!this->emitStoreFloat(E))
7966 return false;
7967 } else if (SubExpr->refersToBitField()) {
7968 assert(isIntegerOrBoolType(*T));
7969 if (!this->emitPreDecBitfield(*T, E->canOverflow(), getBitWidth(SubExpr),
7970 E))
7971 return false;
7972 } else {
7973 assert(isIntegerOrBoolType(*T));
7974 if (!this->emitPreDec(*T, E->canOverflow(), E))
7975 return false;
7976 }
7977 return E->isGLValue() || this->emitLoadPop(*T, E);
7978 }
7979 case UO_LNot: // !x
7980 if (!T)
7981 return this->emitError(E);
7982
7983 if (DiscardResult)
7984 return this->discard(SubExpr);
7985
7986 if (!this->visitBool(SubExpr))
7987 return false;
7988
7989 if (!this->emitInv(E))
7990 return false;
7991
7992 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
7993 return this->emitCast(PT_Bool, ET, E);
7994 return true;
7995 case UO_Minus: // -x
7996 if (!T)
7997 return this->emitError(E);
7998
7999 if (!this->visit(SubExpr))
8000 return false;
8001 return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
8002 case UO_Plus: // +x
8003 if (!T)
8004 return this->emitError(E);
8005
8006 if (!this->visit(SubExpr)) // noop
8007 return false;
8008 return DiscardResult ? this->emitPop(*T, E) : true;
8009 case UO_AddrOf: // &x
8010 if (E->getType()->isMemberPointerType()) {
8011 // C++11 [expr.unary.op]p3 has very strict rules on how the address of a
8012 // member can be formed.
8013 if (DiscardResult)
8014 return true;
8015 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(), E);
8016 }
8017 // [C11 6.5.3.2p3]: if the operand of '&' is the result of a unary '*'
8018 // operator, neither operator is evaluated and the result is as if both
8019 // were omitted. So '&*q' is just 'q' with no dereference; delegate to the
8020 // pointer operand directly instead of to the '*' (which would emit a null
8021 // check), so that e.g. '&*(int *)0' is not rejected.
8022 if (!Ctx.getLangOpts().CPlusPlus) {
8023 const Expr *Sub = SubExpr->IgnoreParens();
8024
8025 if (const auto *Deref = dyn_cast<UnaryOperator>(Sub);
8026 Deref && Deref->getOpcode() == UO_Deref) {
8027 if (DiscardResult)
8028 return this->discard(Deref->getSubExpr());
8029 return this->visit(Deref->getSubExpr()) && this->emitAddrOf(E);
8030 }
8031 }
8032 // We should already have a pointer when we get here.
8033 if (DiscardResult)
8034 return this->discard(SubExpr);
8035 return this->delegate(SubExpr) && this->emitAddrOf(E);
8036 case UO_Deref: // *x
8037 if (DiscardResult)
8038 return this->discard(SubExpr);
8039
8040 if (!this->visit(SubExpr))
8041 return false;
8042
8043 if (!SubExpr->getType()->isFunctionPointerType() && !this->emitCheckNull(E))
8044 return false;
8045
8046 if (classifyPrim(SubExpr) == PT_Ptr)
8047 return this->emitNarrowPtr(E);
8048 return true;
8049
8050 case UO_Not: // ~x
8051 if (!T)
8052 return this->emitError(E);
8053
8054 if (!this->visit(SubExpr))
8055 return false;
8056 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
8057 case UO_Real: // __real x
8058 if (!T)
8059 return false;
8060 return this->delegate(SubExpr);
8061 case UO_Imag: { // __imag x
8062 if (!T)
8063 return false;
8064 if (!this->discard(SubExpr))
8065 return false;
8066 return DiscardResult
8067 ? true
8068 : this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);
8069 }
8070 case UO_Extension:
8071 return this->delegate(SubExpr);
8072 case UO_Coawait:
8073 assert(false && "Unhandled opcode");
8074 }
8075
8076 return false;
8077}
8078
8079template <class Emitter>
8081 const Expr *SubExpr = E->getSubExpr();
8082 assert(SubExpr->getType()->isAnyComplexType());
8083
8084 if (DiscardResult)
8085 return this->discard(SubExpr);
8086
8087 OptPrimType ResT = classify(E);
8088 auto prepareResult = [=]() -> bool {
8089 if (!ResT && !Initializing) {
8090 UnsignedOrNone LocalIndex = allocateLocal(SubExpr);
8091 if (!LocalIndex)
8092 return false;
8093 return this->emitGetPtrLocal(*LocalIndex, E);
8094 }
8095
8096 return true;
8097 };
8098
8099 // The offset of the temporary, if we created one.
8100 unsigned SubExprOffset = ~0u;
8101 auto createTemp = [=, &SubExprOffset]() -> bool {
8102 SubExprOffset =
8103 this->allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
8104 if (!this->visit(SubExpr))
8105 return false;
8106 return this->emitSetLocal(PT_Ptr, SubExprOffset, E);
8107 };
8108
8109 PrimType ElemT = classifyComplexElementType(SubExpr->getType());
8110 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
8111 if (!this->emitGetLocal(PT_Ptr, Offset, E))
8112 return false;
8113 return this->emitArrayElemPop(ElemT, Index, E);
8114 };
8115
8116 switch (E->getOpcode()) {
8117 case UO_Minus: // -x
8118 if (!prepareResult())
8119 return false;
8120 if (!createTemp())
8121 return false;
8122 for (unsigned I = 0; I != 2; ++I) {
8123 if (!getElem(SubExprOffset, I))
8124 return false;
8125 if (!this->emitNeg(ElemT, E))
8126 return false;
8127 if (!this->emitInitElem(ElemT, I, E))
8128 return false;
8129 }
8130 break;
8131
8132 case UO_Plus: // +x
8133 case UO_AddrOf: // &x
8134 case UO_Deref: // *x
8135 return this->delegate(SubExpr);
8136
8137 case UO_LNot:
8138 if (!this->visit(SubExpr))
8139 return false;
8140 if (!this->emitComplexBoolCast(SubExpr))
8141 return false;
8142 if (!this->emitInv(E))
8143 return false;
8144 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
8145 return this->emitCast(PT_Bool, ET, E);
8146 return true;
8147
8148 case UO_Real:
8149 return this->emitComplexReal(SubExpr);
8150
8151 case UO_Imag:
8152 if (!this->visit(SubExpr))
8153 return false;
8154
8155 if (SubExpr->isLValue()) {
8156 if (!this->emitConstUint8(1, E))
8157 return false;
8158 return this->emitArrayElemPtrPopUint8(E);
8159 }
8160
8161 // Since our _Complex implementation does not map to a primitive type,
8162 // we sometimes have to do the lvalue-to-rvalue conversion here manually.
8163 return this->emitArrayElemPop(classifyPrim(E->getType()), 1, E);
8164
8165 case UO_Not: // ~x
8166 if (!this->delegate(SubExpr))
8167 return false;
8168 // Negate the imaginary component.
8169 if (!this->emitArrayElem(ElemT, 1, E))
8170 return false;
8171 if (!this->emitNeg(ElemT, E))
8172 return false;
8173 if (!this->emitInitElem(ElemT, 1, E))
8174 return false;
8175 return DiscardResult ? this->emitPopPtr(E) : true;
8176
8177 case UO_Extension:
8178 return this->delegate(SubExpr);
8179
8180 default:
8181 return this->emitInvalid(E);
8182 }
8183
8184 return true;
8185}
8186
8187template <class Emitter>
8189 const Expr *SubExpr = E->getSubExpr();
8190 assert(SubExpr->getType()->isVectorType());
8191
8192 if (DiscardResult)
8193 return this->discard(SubExpr);
8194
8195 auto UnaryOp = E->getOpcode();
8196 if (UnaryOp == UO_Extension)
8197 return this->delegate(SubExpr);
8198
8199 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
8200 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
8201 return this->emitInvalid(E);
8202
8203 // Nothing to do here.
8204 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
8205 return this->delegate(SubExpr);
8206
8207 if (!Initializing) {
8208 UnsignedOrNone LocalIndex = allocateLocal(SubExpr);
8209 if (!LocalIndex)
8210 return false;
8211 if (!this->emitGetPtrLocal(*LocalIndex, E))
8212 return false;
8213 }
8214
8215 // The offset of the temporary, if we created one.
8216 unsigned SubExprOffset =
8217 this->allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
8218 if (!this->visit(SubExpr))
8219 return false;
8220 if (!this->emitSetLocal(PT_Ptr, SubExprOffset, E))
8221 return false;
8222
8223 const auto *VecTy = SubExpr->getType()->getAs<VectorType>();
8224 PrimType ElemT = classifyVectorElementType(SubExpr->getType());
8225 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
8226 if (!this->emitGetLocal(PT_Ptr, Offset, E))
8227 return false;
8228 return this->emitArrayElemPop(ElemT, Index, E);
8229 };
8230
8231 switch (UnaryOp) {
8232 case UO_Minus:
8233 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8234 if (!getElem(SubExprOffset, I))
8235 return false;
8236 if (!this->emitNeg(ElemT, E))
8237 return false;
8238 if (!this->emitInitElem(ElemT, I, E))
8239 return false;
8240 }
8241 break;
8242 case UO_LNot: { // !x
8243 // In C++, the logic operators !, &&, || are available for vectors. !v is
8244 // equivalent to v == 0.
8245 //
8246 // The result of the comparison is a vector of the same width and number of
8247 // elements as the comparison operands with a signed integral element type.
8248 //
8249 // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
8250 QualType ResultVecTy = E->getType();
8251 PrimType ResultVecElemT =
8252 classifyPrim(ResultVecTy->getAs<VectorType>()->getElementType());
8253 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8254 if (!getElem(SubExprOffset, I))
8255 return false;
8256 // operator ! on vectors returns -1 for 'truth', so negate it.
8257 if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E))
8258 return false;
8259 if (!this->emitInv(E))
8260 return false;
8261 if (!this->emitPrimCast(PT_Bool, ElemT, VecTy->getElementType(), E))
8262 return false;
8263 if (!this->emitNeg(ElemT, E))
8264 return false;
8265 if (ElemT != ResultVecElemT &&
8266 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy, E))
8267 return false;
8268 if (!this->emitInitElem(ResultVecElemT, I, E))
8269 return false;
8270 }
8271 break;
8272 }
8273 case UO_Not: // ~x
8274 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8275 if (!getElem(SubExprOffset, I))
8276 return false;
8277 if (ElemT == PT_Bool) {
8278 if (!this->emitInv(E))
8279 return false;
8280 } else {
8281 if (!this->emitComp(ElemT, E))
8282 return false;
8283 }
8284 if (!this->emitInitElem(ElemT, I, E))
8285 return false;
8286 }
8287 break;
8288 default:
8289 llvm_unreachable("Unsupported unary operators should be handled up front");
8290 }
8291 return true;
8292}
8293
8294template <class Emitter>
8296 if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
8297 if (DiscardResult)
8298 return true;
8299 return this->emitConst(ECD->getInitVal(), E);
8300 }
8301 if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
8302 if (DiscardResult)
8303 return true;
8304 const Function *F = getFunction(FuncDecl);
8305 return F && this->emitGetFnPtr(F, E);
8306 }
8307 if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
8308 TPOD = TPOD->getFirstDecl();
8309 if (DiscardResult)
8310 return true;
8311 if (UnsignedOrNone GlobalIndex = P.getGlobal(TPOD))
8312 return this->emitGetPtrGlobal(*GlobalIndex, E);
8313
8314 if (UnsignedOrNone Index = P.getOrCreateGlobal(TPOD)) {
8315 if (OptPrimType T = classify(TPOD->getType())) {
8316 if (!this->visitAPValue(TPOD->getValue(), *T, E))
8317 return false;
8318 return this->emitInitGlobal(*T, *Index, E);
8319 }
8320
8321 if (!this->emitGetPtrGlobal(*Index, E))
8322 return false;
8323 if (!this->visitAPValueInitializer(TPOD->getValue(), E, TPOD->getType()))
8324 return false;
8325 return this->emitFinishInit(E);
8326 }
8327 return false;
8328 }
8329
8330 // References are implemented via pointers, so when we see a DeclRefExpr
8331 // pointing to a reference, we need to get its value directly (i.e. the
8332 // pointer to the actual value) instead of a pointer to the pointer to the
8333 // value.
8334 QualType DeclType = D->getType();
8335 bool IsReference = DeclType->isReferenceType();
8336
8337 auto maybePopPtr = [&]() -> bool {
8338 if (DiscardResult)
8339 return this->emitPopPtr(E);
8340 return true;
8341 };
8342
8343 // Function parameters.
8344 // Note that it's important to check them first since we might have a local
8345 // variable created for a ParmVarDecl as well.
8346 if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
8347 if (DiscardResult)
8348 return true;
8349
8350 if (Ctx.getLangOpts().CPlusPlus && !Ctx.getLangOpts().CPlusPlus11 &&
8351 !DeclType->isIntegralOrEnumerationType()) {
8352 return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
8353 /*InitializerFailed=*/false, E);
8354 }
8355 if (auto It = this->Params.find(PVD); It != this->Params.end()) {
8356 if (IsReference || !It->second.IsPtr)
8357 return this->emitGetParam(classifyPrim(E), It->second.Index, E);
8358
8359 return this->emitGetPtrParam(It->second.Index, E);
8360 }
8361
8362 if (!Ctx.getLangOpts().CPlusPlus23 && IsReference && !Locals.contains(D))
8363 return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
8364 /*InitializerFailed=*/false, E);
8365 }
8366
8367 // Local variables.
8368 if (auto It = Locals.find(D); It != Locals.end()) {
8369 const unsigned Offset = It->second.Offset;
8370 if (IsReference) {
8371 assert(classifyPrim(E) == PT_Ptr);
8372 return this->emitGetRefLocal(Offset, E) && maybePopPtr();
8373 }
8374 return this->emitGetPtrLocal(Offset, E) && maybePopPtr();
8375 }
8376 // Global variables.
8377 if (auto GlobalIndex = P.getGlobal(D)) {
8378 if (IsReference) {
8379 if (!Ctx.getLangOpts().CPlusPlus11)
8380 return this->emitGetGlobal(classifyPrim(E), *GlobalIndex, E);
8381 if (!Ctx.getLangOpts().CPlusPlus23)
8382 return this->emitGetGlobalUnchecked(classifyPrim(E), *GlobalIndex, E);
8383
8384 return this->emitGetRefGlobal(*GlobalIndex, E) && maybePopPtr();
8385 }
8386
8387 return this->emitGetPtrGlobal(*GlobalIndex, E) && maybePopPtr();
8388 }
8389
8390 // In case we need to re-visit a declaration.
8391 auto revisit = [&](const VarDecl *VD,
8392 bool IsConstexprUnknown = true) -> bool {
8394 IsConstexprUnknown);
8395 if constexpr (std::is_same_v<Emitter, EvalEmitter>) {
8396 if (!this->emitPushCC(VD->hasConstantInitialization(), E))
8397 return false;
8398 }
8399 auto VarState = this->visitDecl(VD);
8400
8401 if constexpr (std::is_same_v<Emitter, EvalEmitter>) {
8402 if (!this->emitPopCC(E))
8403 return false;
8404 }
8405
8406 if (VarState.notCreated())
8407 return true;
8408 if (!VarState)
8409 return false;
8410 // Retry.
8411 return this->visitDeclRef(D, E);
8412 };
8413
8414 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
8415 // Lambda captures.
8416 if (auto It = this->LambdaCaptures.find(D);
8417 It != this->LambdaCaptures.end()) {
8418 auto [Offset, IsPtr] = It->second;
8419
8420 if (IsPtr)
8421 return this->emitGetThisFieldPtr(Offset, E) && maybePopPtr();
8422 return this->emitGetPtrThisField(Offset, E) && maybePopPtr();
8423 }
8424 }
8425
8426 if (const auto *DRE = dyn_cast<DeclRefExpr>(E);
8427 DRE && DRE->refersToEnclosingVariableOrCapture()) {
8428 if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture())
8429 return revisit(VD);
8430 }
8431
8432 if (const auto *BD = dyn_cast<BindingDecl>(D))
8433 return this->delegate(BD->getBinding());
8434
8435 // Avoid infinite recursion.
8436 if (D == InitializingDecl) {
8437 if (DiscardResult)
8438 return true;
8439 return this->emitDummyPtr(D, E);
8440 }
8441
8442 // Try to lazily visit (or emit dummy pointers for) declarations
8443 // we haven't seen yet.
8444 const auto *VD = dyn_cast<VarDecl>(D);
8445 if (!VD)
8446 return this->emitError(E);
8447
8448 // For C.
8449 if (!Ctx.getLangOpts().CPlusPlus) {
8450 if (VD->getInit() && !VD->getInit()->isValueDependent() &&
8451 DeclType.isConstant(Ctx.getASTContext()) && !VD->isWeak() &&
8452 VD->evaluateValue())
8453 return revisit(VD, /*IsConstexprUnknown=*/false);
8454
8455 if (DiscardResult)
8456 return true;
8457 return this->emitDummyPtr(D, E);
8458 }
8459
8460 // ... and C++.
8461 const auto typeShouldBeVisited = [&](QualType T) -> bool {
8462 if (T.isConstant(Ctx.getASTContext()))
8463 return true;
8464 return T->isReferenceType();
8465 };
8466
8467 if ((VD->hasGlobalStorage() || VD->isStaticDataMember()) &&
8468 typeShouldBeVisited(DeclType)) {
8469 if (const Expr *Init = VD->getAnyInitializer();
8470 Init && !Init->isValueDependent()) {
8471 // Whether or not the evaluation is successul doesn't really matter
8472 // here -- we will create a global variable in any case, and that
8473 // will have the state of initializer evaluation attached.
8475 (void)Init->EvaluateAsInitializer(Ctx.getASTContext(), VD, Result, true);
8476 return this->visitDeclRef(D, E);
8477 }
8478 return revisit(VD, !VD->isConstexpr() && DeclType->isReferenceType());
8479 }
8480
8481 // FIXME: The evaluateValue() check here is a little ridiculous, since
8482 // it will ultimately call into Context::evaluateAsInitializer(). In
8483 // other words, we're evaluating the initializer, just to know if we can
8484 // evaluate the initializer.
8485 if (VD->isLocalVarDecl() && typeShouldBeVisited(DeclType) && VD->getInit() &&
8486 !VD->getInit()->isValueDependent()) {
8487 if (VD->evaluateValue()) {
8488 bool IsConstexprUnknown = !DeclType.isConstant(Ctx.getASTContext()) &&
8489 !DeclType->isReferenceType();
8490 // Revisit the variable declaration, but make sure it's associated with a
8491 // different evaluation, so e.g. mutable reads don't work on it.
8492 EvalIDScope _(Ctx);
8493 return revisit(VD, IsConstexprUnknown);
8494 } else if (Ctx.getLangOpts().CPlusPlus23 && IsReference)
8495 return revisit(VD, /*IsConstexprUnknown=*/true);
8496
8497 if (IsReference)
8498 return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
8499 /*InitializerFailed=*/true, E);
8500 }
8501
8502 if (DiscardResult)
8503 return true;
8504 return this->emitDummyPtr(
8505 D, E, Ctx.getLangOpts().CPlusPlus23 && DeclType->isReferenceType());
8506}
8507
8508template <class Emitter>
8510 const auto *D = E->getDecl();
8511 return this->visitDeclRef(D, E);
8512}
8513
8514template <class Emitter>
8516 const DesignatedInitUpdateExpr *E) {
8517 if (!this->visitInitializer(E->getBase()))
8518 return false;
8519 return this->visitInitializer(E->getUpdater());
8520}
8521
8522template <class Emitter> bool Compiler<Emitter>::emitCleanup() {
8523 for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent()) {
8524 if (!C->destroyLocals())
8525 return false;
8526 }
8527 return true;
8528}
8529
8530template <class Emitter>
8531unsigned Compiler<Emitter>::collectBaseOffset(const QualType BaseType,
8532 const QualType DerivedType) {
8533 const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
8534 if (const auto *R = Ty->getPointeeCXXRecordDecl())
8535 return R;
8536 return Ty->getAsCXXRecordDecl();
8537 };
8538 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
8539 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
8540
8541 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
8542}
8543
8544/// Emit casts from a PrimType to another PrimType.
8545template <class Emitter>
8546bool Compiler<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT,
8547 QualType ToQT, const Expr *E) {
8548
8549 if (FromT == PT_Float) {
8550 // Floating to floating.
8551 if (ToT == PT_Float) {
8552 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
8553 return this->emitCastFP(ToSem, getRoundingMode(E), E);
8554 }
8555
8556 if (ToT == PT_IntAP)
8557 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
8558 getFPOptions(E), E);
8559 if (ToT == PT_IntAPS)
8560 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
8561 getFPOptions(E), E);
8562
8563 // Float to integral.
8564 if (isIntegerOrBoolType(ToT) || ToT == PT_Bool)
8565 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
8566 }
8567
8568 if (isIntegerOrBoolType(FromT) || FromT == PT_Bool) {
8569 if (ToT == PT_IntAP)
8570 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
8571 if (ToT == PT_IntAPS)
8572 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
8573
8574 // Integral to integral.
8575 if (isIntegerOrBoolType(ToT) || ToT == PT_Bool)
8576 return FromT != ToT ? this->emitCast(FromT, ToT, E) : true;
8577
8578 if (ToT == PT_Float) {
8579 // Integral to floating.
8580 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
8581 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E);
8582 }
8583 }
8584
8585 return false;
8586}
8587
8588template <class Emitter>
8589bool Compiler<Emitter>::emitIntegralCast(PrimType FromT, PrimType ToT,
8590 QualType ToQT, const Expr *E) {
8591 assert(FromT != ToT);
8592
8593 if (ToT == PT_IntAP)
8594 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
8595 if (ToT == PT_IntAPS)
8596 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
8597
8598 return this->emitCast(FromT, ToT, E);
8599}
8600
8601/// Emits __real(SubExpr)
8602template <class Emitter>
8603bool Compiler<Emitter>::emitComplexReal(const Expr *SubExpr) {
8604 assert(SubExpr->getType()->isAnyComplexType());
8605
8606 if (DiscardResult)
8607 return this->discard(SubExpr);
8608
8609 if (!this->visit(SubExpr))
8610 return false;
8611 if (SubExpr->isLValue()) {
8612 if (!this->emitConstUint8(0, SubExpr))
8613 return false;
8614 return this->emitArrayElemPtrPopUint8(SubExpr);
8615 }
8616
8617 // Rvalue, load the actual element.
8618 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->getType()),
8619 0, SubExpr);
8620}
8621
8622template <class Emitter>
8623bool Compiler<Emitter>::emitComplexBoolCast(const Expr *E) {
8624 assert(!DiscardResult);
8625 PrimType ElemT = classifyComplexElementType(E->getType());
8626 // We emit the expression (__real(E) != 0 || __imag(E) != 0)
8627 // for us, that means (bool)E[0] || (bool)E[1]
8628 if (!this->emitArrayElem(ElemT, 0, E))
8629 return false;
8630 if (ElemT == PT_Float) {
8631 if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
8632 return false;
8633 } else {
8634 if (!this->emitCast(ElemT, PT_Bool, E))
8635 return false;
8636 }
8637
8638 // We now have the bool value of E[0] on the stack.
8639 LabelTy LabelTrue = this->getLabel();
8640 if (!this->jumpTrue(LabelTrue, E))
8641 return false;
8642
8643 if (!this->emitArrayElemPop(ElemT, 1, E))
8644 return false;
8645 if (ElemT == PT_Float) {
8646 if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
8647 return false;
8648 } else {
8649 if (!this->emitCast(ElemT, PT_Bool, E))
8650 return false;
8651 }
8652 // Leave the boolean value of E[1] on the stack.
8653 LabelTy EndLabel = this->getLabel();
8654 this->jump(EndLabel, E);
8655
8656 this->emitLabel(LabelTrue);
8657 if (!this->emitPopPtr(E))
8658 return false;
8659 if (!this->emitConstBool(true, E))
8660 return false;
8661
8662 this->fallthrough(EndLabel);
8663 this->emitLabel(EndLabel);
8664
8665 return true;
8666}
8667
8668template <class Emitter>
8669bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS,
8670 const BinaryOperator *E) {
8671 assert(E->isComparisonOp());
8672 assert(!Initializing);
8673 if (DiscardResult)
8674 return this->discard(LHS) && this->discard(RHS);
8675
8676 PrimType ElemT;
8677 bool LHSIsComplex;
8678 unsigned LHSOffset;
8679 if (LHS->getType()->isAnyComplexType()) {
8680 LHSIsComplex = true;
8681 ElemT = classifyComplexElementType(LHS->getType());
8682 LHSOffset = allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true);
8683 if (!this->visit(LHS))
8684 return false;
8685 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
8686 return false;
8687 } else {
8688 LHSIsComplex = false;
8689 PrimType LHST = classifyPrim(LHS->getType());
8690 LHSOffset = this->allocateLocalPrimitive(LHS, LHST, /*IsConst=*/true);
8691 if (!this->visit(LHS))
8692 return false;
8693 if (!this->emitSetLocal(LHST, LHSOffset, E))
8694 return false;
8695 }
8696
8697 bool RHSIsComplex;
8698 unsigned RHSOffset;
8699 if (RHS->getType()->isAnyComplexType()) {
8700 RHSIsComplex = true;
8701 ElemT = classifyComplexElementType(RHS->getType());
8702 RHSOffset = allocateLocalPrimitive(RHS, PT_Ptr, /*IsConst=*/true);
8703 if (!this->visit(RHS))
8704 return false;
8705 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
8706 return false;
8707 } else {
8708 RHSIsComplex = false;
8709 PrimType RHST = classifyPrim(RHS->getType());
8710 RHSOffset = this->allocateLocalPrimitive(RHS, RHST, /*IsConst=*/true);
8711 if (!this->visit(RHS))
8712 return false;
8713 if (!this->emitSetLocal(RHST, RHSOffset, E))
8714 return false;
8715 }
8716
8717 auto getElem = [&](unsigned LocalOffset, unsigned Index,
8718 bool IsComplex) -> bool {
8719 if (IsComplex) {
8720 if (!this->emitGetLocal(PT_Ptr, LocalOffset, E))
8721 return false;
8722 return this->emitArrayElemPop(ElemT, Index, E);
8723 }
8724 return this->emitGetLocal(ElemT, LocalOffset, E);
8725 };
8726
8727 for (unsigned I = 0; I != 2; ++I) {
8728 // Get both values.
8729 if (!getElem(LHSOffset, I, LHSIsComplex))
8730 return false;
8731 if (!getElem(RHSOffset, I, RHSIsComplex))
8732 return false;
8733 // And compare them.
8734 if (!this->emitEQ(ElemT, E))
8735 return false;
8736
8737 if (!this->emitCastBoolUint8(E))
8738 return false;
8739 }
8740
8741 // We now have two bool values on the stack. Compare those.
8742 if (!this->emitAddUint8(E))
8743 return false;
8744 if (!this->emitConstUint8(2, E))
8745 return false;
8746
8747 if (E->getOpcode() == BO_EQ) {
8748 if (!this->emitEQUint8(E))
8749 return false;
8750 } else if (E->getOpcode() == BO_NE) {
8751 if (!this->emitNEUint8(E))
8752 return false;
8753 } else
8754 return false;
8755
8756 // In C, this returns an int.
8757 if (PrimType ResT = classifyPrim(E->getType()); ResT != PT_Bool)
8758 return this->emitCast(PT_Bool, ResT, E);
8759 return true;
8760}
8761
8762/// When calling this, we have a pointer of the local-to-destroy
8763/// on the stack.
8764/// Emit destruction of record types (or arrays of record types).
8765template <class Emitter>
8766bool Compiler<Emitter>::emitRecordDestructionPop(const Record *R,
8767 SourceInfo Loc) {
8768 assert(R);
8769 assert(!R->hasTrivialDtor());
8770 const CXXDestructorDecl *Dtor = R->getDestructor();
8771 assert(Dtor);
8772 const Function *DtorFunc = getFunction(Dtor);
8773 if (!DtorFunc)
8774 return false;
8775 assert(DtorFunc->hasThisPointer());
8776 assert(DtorFunc->getNumParams() == 1);
8777 return this->emitCall(DtorFunc, 0, Loc);
8778}
8779/// When calling this, we have a pointer of the local-to-destroy
8780/// on the stack.
8781/// Emit destruction of record types (or arrays of record types).
8782template <class Emitter>
8783bool Compiler<Emitter>::emitDestructionPop(const Descriptor *Desc,
8784 SourceInfo Loc) {
8785 assert(Desc);
8786 assert(!Desc->hasTrivialDtor());
8787
8788 // Arrays.
8789 if (Desc->isArray()) {
8790 const Descriptor *ElemDesc = Desc->ElemDesc;
8791 assert(ElemDesc);
8792
8793 unsigned N = Desc->getNumElems();
8794 if (N == 0)
8795 return this->emitPopPtr(Loc);
8796
8797 for (ssize_t I = N - 1; I >= 1; --I) {
8798 if (!this->emitConstUint64(I, Loc))
8799 return false;
8800 if (!this->emitArrayElemPtrUint64(Loc))
8801 return false;
8802 if (!this->emitDestructionPop(ElemDesc, Loc))
8803 return false;
8804 }
8805 // Last iteration, removes the instance pointer from the stack.
8806 if (!this->emitConstUint64(0, Loc))
8807 return false;
8808 if (!this->emitArrayElemPtrPopUint64(Loc))
8809 return false;
8810 return this->emitDestructionPop(ElemDesc, Loc);
8811 }
8812
8813 assert(Desc->ElemRecord);
8814 assert(!Desc->ElemRecord->hasTrivialDtor());
8815 return this->emitRecordDestructionPop(Desc->ElemRecord, Loc);
8816}
8817
8818/// Create a dummy pointer for the given decl (or expr) and
8819/// push a pointer to it on the stack.
8820template <class Emitter>
8821bool Compiler<Emitter>::emitDummyPtr(DeclOrExpr D, const Expr *E, bool CU) {
8822 assert(!DiscardResult && "Should've been checked before");
8823 return this->emitGetOpaquePtr(D, CU, E);
8824}
8825
8826template <class Emitter>
8827bool Compiler<Emitter>::emitFloat(const APFloat &F, SourceInfo Info) {
8828 if (Floating::singleWord(F.getSemantics()))
8829 return this->emitConstFloat(Floating(F), Info);
8830
8831 APInt I = F.bitcastToAPInt();
8832 return this->emitConstFloat(
8833 Floating(const_cast<uint64_t *>(I.getRawData()),
8834 llvm::APFloatBase::SemanticsToEnum(F.getSemantics())),
8835 Info);
8836}
8837
8838// This function is constexpr if and only if To, From, and the types of
8839// all subobjects of To and From are types T such that...
8840// (3.1) - is_union_v<T> is false;
8841// (3.2) - is_pointer_v<T> is false;
8842// (3.3) - is_member_pointer_v<T> is false;
8843// (3.4) - is_volatile_v<T> is false; and
8844// (3.5) - T has no non-static data members of reference type
8845template <class Emitter>
8846bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) {
8847 const Expr *SubExpr = E->getSubExpr();
8848 QualType FromType = SubExpr->getType();
8849 QualType ToType = E->getType();
8850 OptPrimType ToT = classify(ToType);
8851
8852 assert(!ToType->isReferenceType());
8853
8854 // Prepare storage for the result in case we discard.
8855 if (DiscardResult && !Initializing && !ToT) {
8856 UnsignedOrNone LocalIndex = allocateLocal(E);
8857 if (!LocalIndex)
8858 return false;
8859 if (!this->emitGetPtrLocal(*LocalIndex, E))
8860 return false;
8861 }
8862
8863 // Get a pointer to the value-to-cast on the stack.
8864 // For CK_LValueToRValueBitCast, this is always an lvalue and
8865 // we later assume it to be one (i.e. a PT_Ptr). However,
8866 // we call this function for other utility methods where
8867 // a bitcast might be useful, so convert it to a PT_Ptr in that case.
8868 if (SubExpr->isGLValue() || FromType->isVectorType()) {
8869 if (!this->visit(SubExpr))
8870 return false;
8871 } else if (OptPrimType FromT = classify(SubExpr)) {
8872 unsigned TempOffset =
8873 allocateLocalPrimitive(SubExpr, *FromT, /*IsConst=*/true);
8874 if (!this->visit(SubExpr))
8875 return false;
8876 if (!this->emitSetLocal(*FromT, TempOffset, E))
8877 return false;
8878 if (!this->emitGetPtrLocal(TempOffset, E))
8879 return false;
8880 } else {
8881 return false;
8882 }
8883
8884 if (!ToT) {
8885 if (!this->emitBitCast(E))
8886 return false;
8887 return DiscardResult ? this->emitPopPtr(E) : true;
8888 }
8889 assert(ToT);
8890
8891 const llvm::fltSemantics *TargetSemantics = nullptr;
8892 if (ToT == PT_Float)
8893 TargetSemantics = &Ctx.getFloatSemantics(ToType);
8894
8895 // Conversion to a primitive type. FromType can be another
8896 // primitive type, or a record/array.
8897 bool ToTypeIsUChar = (ToType->isSpecificBuiltinType(BuiltinType::UChar) ||
8898 ToType->isSpecificBuiltinType(BuiltinType::Char_U));
8899 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
8900
8901 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->isStdByteType(),
8902 ResultBitWidth, TargetSemantics,
8903 ToType.getTypePtr(), E))
8904 return false;
8905
8906 if (DiscardResult)
8907 return this->emitPop(*ToT, E);
8908
8909 return true;
8910}
8911
8912/// Replicate a scalar value into every scalar element of an aggregate.
8913/// The scalar is stored in a local at \p SrcOffset and a pointer to the
8914/// destination must be on top of the interpreter stack. Each element receives
8915/// the scalar, cast to its own type.
8916template <class Emitter>
8917bool Compiler<Emitter>::emitHLSLAggregateSplat(PrimType SrcT,
8918 unsigned SrcOffset,
8919 QualType DestType,
8920 const Expr *E) {
8921 // Vectors and matrices are treated as flat sequences of elements.
8922 unsigned NumElems = 0;
8923 QualType ElemType;
8924 if (const auto *VT = DestType->getAs<VectorType>()) {
8925 NumElems = VT->getNumElements();
8926 ElemType = VT->getElementType();
8927 } else if (const auto *MT = DestType->getAs<ConstantMatrixType>()) {
8928 NumElems = MT->getNumElementsFlattened();
8929 ElemType = MT->getElementType();
8930 }
8931 if (NumElems > 0) {
8932 PrimType ElemT = classifyPrim(ElemType);
8933 for (unsigned I = 0; I != NumElems; ++I) {
8934 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8935 return false;
8936 if (!this->emitPrimCast(SrcT, ElemT, ElemType, E))
8937 return false;
8938 if (!this->emitInitElem(ElemT, I, E))
8939 return false;
8940 }
8941 return true;
8942 }
8943
8944 // Arrays: primitive elements are filled directly; composite elements
8945 // require recursion into each sub-aggregate.
8946 if (const auto *AT = DestType->getAsArrayTypeUnsafe()) {
8947 const auto *CAT = cast<ConstantArrayType>(AT);
8948 QualType ArrElemType = CAT->getElementType();
8949 unsigned ArrSize = CAT->getZExtSize();
8950
8951 if (OptPrimType ElemT = classify(ArrElemType)) {
8952 for (unsigned I = 0; I != ArrSize; ++I) {
8953 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8954 return false;
8955 if (!this->emitPrimCast(SrcT, *ElemT, ArrElemType, E))
8956 return false;
8957 if (!this->emitInitElem(*ElemT, I, E))
8958 return false;
8959 }
8960 } else {
8961 for (unsigned I = 0; I != ArrSize; ++I) {
8962 if (!this->emitConstUint32(I, E))
8963 return false;
8964 if (!this->emitArrayElemPtrUint32(E))
8965 return false;
8966 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, ArrElemType, E))
8967 return false;
8968 if (!this->emitFinishInitPop(E))
8969 return false;
8970 }
8971 }
8972 return true;
8973 }
8974
8975 // Records: fill base classes first, then named fields in declaration
8976 // order.
8977 if (DestType->isRecordType()) {
8978 const Record *R = getRecord(DestType);
8979 if (!R)
8980 return false;
8981
8982 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
8983 for (const CXXBaseSpecifier &BS : CXXRD->bases()) {
8984 const Record::Base *B = R->getBase(BS.getType());
8985 assert(B);
8986 if (!this->emitGetPtrBase(B->Offset, E))
8987 return false;
8988 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, BS.getType(), E))
8989 return false;
8990 if (!this->emitFinishInitPop(E))
8991 return false;
8992 }
8993 }
8994
8995 for (const Record::Field &F : R->fields()) {
8996 if (F.isUnnamedBitField())
8997 continue;
8998
8999 QualType FieldType = F.Decl->getType();
9000 if (OptPrimType FieldT = F.T) {
9001 if (!this->emitGetLocal(SrcT, SrcOffset, E))
9002 return false;
9003 if (!this->emitPrimCast(SrcT, *FieldT, FieldType, E))
9004 return false;
9005 if (F.isBitField()) {
9006 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
9007 return false;
9008 } else {
9009 if (!this->emitInitField(*FieldT, F.Offset, E))
9010 return false;
9011 }
9012 } else {
9013 if (!this->emitGetPtrField(F.Offset, E))
9014 return false;
9015 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, FieldType, E))
9016 return false;
9017 if (!this->emitPopPtr(E))
9018 return false;
9019 }
9020 }
9021 return true;
9022 }
9023
9024 return false;
9025}
9026
9027/// Return the total number of scalar elements in a type. This is used
9028/// to cap how many source elements are extracted during an elementwise cast,
9029/// so we never flatten more than the destination can hold.
9030template <class Emitter>
9031unsigned Compiler<Emitter>::countHLSLFlatElements(QualType Ty) {
9032 // Vector and matrix types are treated as flat sequences of elements.
9033 if (const auto *VT = Ty->getAs<VectorType>())
9034 return VT->getNumElements();
9035 if (const auto *MT = Ty->getAs<ConstantMatrixType>())
9036 return MT->getNumElementsFlattened();
9037 // Arrays: total count is array size * scalar elements per element.
9038 if (const auto *AT = Ty->getAsArrayTypeUnsafe()) {
9039 const auto *CAT = cast<ConstantArrayType>(AT);
9040 return CAT->getZExtSize() * countHLSLFlatElements(CAT->getElementType());
9041 }
9042 // Records: sum scalar element counts of base classes and named fields.
9043 if (Ty->isRecordType()) {
9044 const Record *R = getRecord(Ty);
9045 if (!R)
9046 return 0;
9047 unsigned Count = 0;
9048 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
9049 for (const CXXBaseSpecifier &BS : CXXRD->bases())
9050 Count += countHLSLFlatElements(BS.getType());
9051 }
9052 for (const Record::Field &F : R->fields()) {
9053 if (F.isUnnamedBitField())
9054 continue;
9055 Count += countHLSLFlatElements(F.Decl->getType());
9056 }
9057 return Count;
9058 }
9059 // Scalar primitive types contribute one element.
9060 if (canClassify(Ty))
9061 return 1;
9062 return 0;
9063}
9064
9065/// Walk a source aggregate and extract every scalar element into its own local
9066/// variable. The results are appended to \p Elements in declaration order,
9067/// stopping once \p MaxElements have been collected. A pointer to the
9068/// source aggregate must be stored in the local at \p SrcOffset.
9069template <class Emitter>
9070bool Compiler<Emitter>::emitHLSLFlattenAggregate(
9071 QualType SrcType, unsigned SrcOffset,
9072 SmallVectorImpl<HLSLFlatElement> &Elements, unsigned MaxElements,
9073 const Expr *E) {
9074
9075 // Save a scalar value from the stack into a new local and record it.
9076 auto saveToLocal = [&](PrimType T) -> bool {
9077 unsigned Offset = allocateLocalPrimitive(E, T, /*IsConst=*/true);
9078 if (!this->emitSetLocal(T, Offset, E))
9079 return false;
9080 Elements.push_back({Offset, T});
9081 return true;
9082 };
9083
9084 // Save a pointer from the stack into a new local for later use.
9085 auto savePtrToLocal = [&]() -> UnsignedOrNone {
9086 unsigned Offset = allocateLocalPrimitive(E, PT_Ptr, /*IsConst=*/true);
9087 if (!this->emitSetLocal(PT_Ptr, Offset, E))
9088 return std::nullopt;
9089 return Offset;
9090 };
9091
9092 // Vectors and matrices are flat sequences of elements.
9093 unsigned NumElems = 0;
9094 QualType ElemType;
9095 if (const auto *VT = SrcType->getAs<VectorType>()) {
9096 NumElems = VT->getNumElements();
9097 ElemType = VT->getElementType();
9098 } else if (const auto *MT = SrcType->getAs<ConstantMatrixType>()) {
9099 NumElems = MT->getNumElementsFlattened();
9100 ElemType = MT->getElementType();
9101 }
9102 if (NumElems > 0) {
9103 PrimType ElemT = classifyPrim(ElemType);
9104 for (unsigned I = 0; I != NumElems && Elements.size() < MaxElements; ++I) {
9105 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9106 return false;
9107 if (!this->emitArrayElemPop(ElemT, I, E))
9108 return false;
9109 if (!saveToLocal(ElemT))
9110 return false;
9111 }
9112 return true;
9113 }
9114
9115 // Arrays: primitive elements are extracted directly; composite elements
9116 // require recursion into each sub-aggregate.
9117 if (const auto *AT = SrcType->getAsArrayTypeUnsafe()) {
9118 const auto *CAT = cast<ConstantArrayType>(AT);
9119 QualType ArrElemType = CAT->getElementType();
9120 unsigned ArrSize = CAT->getZExtSize();
9121
9122 if (OptPrimType ElemT = classify(ArrElemType)) {
9123 for (unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
9124 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9125 return false;
9126 if (!this->emitArrayElemPop(*ElemT, I, E))
9127 return false;
9128 if (!saveToLocal(*ElemT))
9129 return false;
9130 }
9131 } else {
9132 for (unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
9133 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9134 return false;
9135 if (!this->emitConstUint32(I, E))
9136 return false;
9137 if (!this->emitArrayElemPtrPopUint32(E))
9138 return false;
9139 UnsignedOrNone ElemPtrOffset = savePtrToLocal();
9140 if (!ElemPtrOffset)
9141 return false;
9142 if (!emitHLSLFlattenAggregate(ArrElemType, *ElemPtrOffset, Elements,
9143 MaxElements, E))
9144 return false;
9145 }
9146 }
9147 return true;
9148 }
9149
9150 // Records: base classes come first, then named fields in declaration
9151 // order.
9152 if (SrcType->isRecordType()) {
9153 const Record *R = getRecord(SrcType);
9154 if (!R)
9155 return false;
9156
9157 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
9158 for (const CXXBaseSpecifier &BS : CXXRD->bases()) {
9159 if (Elements.size() >= MaxElements)
9160 break;
9161 const Record::Base *B = R->getBase(BS.getType());
9162 assert(B);
9163 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9164 return false;
9165 if (!this->emitGetPtrBasePop(B->Offset, /*NullOK=*/false, E))
9166 return false;
9167 UnsignedOrNone BasePtrOffset = savePtrToLocal();
9168 if (!BasePtrOffset)
9169 return false;
9170 if (!emitHLSLFlattenAggregate(BS.getType(), *BasePtrOffset, Elements,
9171 MaxElements, E))
9172 return false;
9173 }
9174 }
9175
9176 for (const Record::Field &F : R->fields()) {
9177 if (Elements.size() >= MaxElements)
9178 break;
9179 if (F.isUnnamedBitField())
9180 continue;
9181
9182 QualType FieldType = F.Decl->getType();
9183 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9184 return false;
9185 if (!this->emitGetPtrFieldPop(F.Offset, E))
9186 return false;
9187
9188 if (OptPrimType FieldT = F.T) {
9189 if (!this->emitLoadPop(*FieldT, E))
9190 return false;
9191 if (!saveToLocal(*FieldT))
9192 return false;
9193 } else {
9194 UnsignedOrNone FieldPtrOffset = savePtrToLocal();
9195 if (!FieldPtrOffset)
9196 return false;
9197 if (!emitHLSLFlattenAggregate(FieldType, *FieldPtrOffset, Elements,
9198 MaxElements, E))
9199 return false;
9200 }
9201 }
9202 return true;
9203 }
9204
9205 return false;
9206}
9207
9208/// Populate an HLSL aggregate from a flat list of previously extracted source
9209/// elements, casting each to the corresponding destination element type.
9210/// \p ElemIdx tracks the current position in \p Elements and is advanced as
9211/// elements are consumed. A pointer to the destination must be on top of the
9212/// interpreter stack.
9213template <class Emitter>
9214bool Compiler<Emitter>::emitHLSLConstructAggregate(
9215 QualType DestType, ArrayRef<HLSLFlatElement> Elements, unsigned &ElemIdx,
9216 const Expr *E) {
9217
9218 // Consume the next source element, cast it, and leave it on the stack.
9219 auto loadAndCast = [&](PrimType DestT, QualType DestQT) -> bool {
9220 const auto &Src = Elements[ElemIdx++];
9221 if (!this->emitGetLocal(Src.Type, Src.LocalOffset, E))
9222 return false;
9223 return this->emitPrimCast(Src.Type, DestT, DestQT, E);
9224 };
9225
9226 // Vectors and matrices are flat sequences of elements.
9227 unsigned NumElems = 0;
9228 QualType ElemType;
9229 if (const auto *VT = DestType->getAs<VectorType>()) {
9230 NumElems = VT->getNumElements();
9231 ElemType = VT->getElementType();
9232 } else if (const auto *MT = DestType->getAs<ConstantMatrixType>()) {
9233 NumElems = MT->getNumElementsFlattened();
9234 ElemType = MT->getElementType();
9235 }
9236 if (NumElems > 0) {
9237 PrimType DestElemT = classifyPrim(ElemType);
9238 for (unsigned I = 0; I != NumElems; ++I) {
9239 if (!loadAndCast(DestElemT, ElemType))
9240 return false;
9241 if (!this->emitInitElem(DestElemT, I, E))
9242 return false;
9243 }
9244 return true;
9245 }
9246
9247 // Arrays: primitive elements are filled directly; composite elements
9248 // require recursion into each sub-aggregate.
9249 if (const auto *AT = DestType->getAsArrayTypeUnsafe()) {
9250 const auto *CAT = cast<ConstantArrayType>(AT);
9251 QualType ArrElemType = CAT->getElementType();
9252 unsigned ArrSize = CAT->getZExtSize();
9253
9254 if (OptPrimType ElemT = classify(ArrElemType)) {
9255 for (unsigned I = 0; I != ArrSize; ++I) {
9256 if (!loadAndCast(*ElemT, ArrElemType))
9257 return false;
9258 if (!this->emitInitElem(*ElemT, I, E))
9259 return false;
9260 }
9261 } else {
9262 for (unsigned I = 0; I != ArrSize; ++I) {
9263 if (!this->emitConstUint32(I, E))
9264 return false;
9265 if (!this->emitArrayElemPtrUint32(E))
9266 return false;
9267 if (!emitHLSLConstructAggregate(ArrElemType, Elements, ElemIdx, E))
9268 return false;
9269 if (!this->emitFinishInitPop(E))
9270 return false;
9271 }
9272 }
9273 return true;
9274 }
9275
9276 // Records: base classes come first, then named fields in declaration
9277 // order.
9278 if (DestType->isRecordType()) {
9279 const Record *R = getRecord(DestType);
9280 if (!R)
9281 return false;
9282
9283 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
9284 for (const CXXBaseSpecifier &BS : CXXRD->bases()) {
9285 const Record::Base *B = R->getBase(BS.getType());
9286 assert(B);
9287 if (!this->emitGetPtrBase(B->Offset, E))
9288 return false;
9289 if (!emitHLSLConstructAggregate(BS.getType(), Elements, ElemIdx, E))
9290 return false;
9291 if (!this->emitFinishInitPop(E))
9292 return false;
9293 }
9294 }
9295
9296 for (const Record::Field &F : R->fields()) {
9297 if (F.isUnnamedBitField())
9298 continue;
9299
9300 QualType FieldType = F.Decl->getType();
9301 if (OptPrimType FieldT = F.T) {
9302 if (!loadAndCast(*FieldT, FieldType))
9303 return false;
9304 if (F.isBitField()) {
9305 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
9306 return false;
9307 } else {
9308 if (!this->emitInitField(*FieldT, F.Offset, E))
9309 return false;
9310 }
9311 } else {
9312 if (!this->emitGetPtrField(F.Offset, E))
9313 return false;
9314 if (!emitHLSLConstructAggregate(FieldType, Elements, ElemIdx, E))
9315 return false;
9316 if (!this->emitPopPtr(E))
9317 return false;
9318 }
9319 }
9320 return true;
9321 }
9322
9323 return false;
9324}
9325
9326namespace clang {
9327namespace interp {
9328
9329template class Compiler<ByteCodeEmitter>;
9330template class Compiler<EvalEmitter>;
9331
9332} // namespace interp
9333} // namespace clang
#define V(N, I)
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static void emitCleanup(CIRGenFunction &cgf, cir::CleanupScopeOp cleanupScope, EHScopeStack::Cleanup *cleanup, EHScopeStack::Cleanup::Flags flags, Address activeFlag)
static uint32_t getBitWidth(const Expr *E)
#define EMIT_ARITH_OP(OP)
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
static const Expr * stripDerivedToBaseCasts(const Expr *E)
static bool isTrivialMemoryOperation(const CXXMethodDecl *MD)
static const Expr * stripCheckedDerivedToBaseCasts(const Expr *E)
static bool hasTrivialDefaultCtorParent(const FieldDecl *FD)
static bool initNeedsOverridenLoc(const CXXCtorInitializer *Init)
llvm::APSInt APSInt
Definition Compiler.cpp:26
const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. This ignores some c...
bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
Result
Implement __builtin_bit_cast and related operations.
llvm::SmallPtrSet< const ParmVarDecl *, 1 > FoundParams
bool VisitDeclRefExpr(const DeclRefExpr *E) override
a trap message and trap category.
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
const LValueBase getLValueBase() const
Definition APValue.cpp:1018
APValue & getArrayInitializedElt(unsigned I)
Definition APValue.h:629
ArrayRef< LValuePathEntry > getLValuePath() const
Definition APValue.cpp:1038
APSInt & getInt()
Definition APValue.h:511
APValue & getStructField(unsigned i)
Definition APValue.h:674
const FieldDecl * getUnionField() const
Definition APValue.h:695
unsigned getStructNumFields() const
Definition APValue.h:661
APValue & getStructVirtualBase(unsigned i)
Definition APValue.h:679
bool isArray() const
Definition APValue.h:496
bool isMemberPointerToDerivedMember() const
Definition APValue.cpp:1108
unsigned getArrayInitializedElts() const
Definition APValue.h:648
bool isFloat() const
Definition APValue.h:489
unsigned getStructNumBases() const
Definition APValue.h:657
unsigned getStructNumVirtualBases() const
Definition APValue.h:665
const ValueDecl * getMemberPointerDecl() const
Definition APValue.cpp:1101
APValue & getUnionValue()
Definition APValue.h:699
APValue & getArrayFiller()
Definition APValue.h:640
bool isLValue() const
Definition APValue.h:493
bool isIndeterminate() const
Definition APValue.h:485
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
Definition APValue.cpp:1115
bool isMemberPointer() const
Definition APValue.h:499
bool isInt() const
Definition APValue.h:488
unsigned getArraySize() const
Definition APValue.h:652
bool isUnion() const
Definition APValue.h:498
@ None
There is no such object (it's outside its lifetime).
Definition APValue.h:129
bool isStruct() const
Definition APValue.h:497
bool isNullPointer() const
Definition APValue.cpp:1054
APFloat & getFloat()
Definition APValue.h:525
APValue & getStructBase(unsigned i)
Definition APValue.h:669
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:239
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
const LangOptions & getLangOpts() const
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.
const VariableArrayType * getAsVariableArrayType(QualType T) const
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:4397
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Definition Expr.h:4575
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Definition Expr.h:4581
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Definition Expr.h:4587
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition Expr.h:4594
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition Expr.h:6071
Represents a loop initializing the elements of an array.
Definition Expr.h:6018
llvm::APInt getArraySize() const
Definition Expr.h:6040
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Definition Expr.h:6033
Expr * getSubExpr() const
Get the initializer to use for each array element.
Definition Expr.h:6038
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition Expr.h:2765
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Definition Expr.h:2794
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition ExprCXX.h:3010
uint64_t getValue() const
Definition ExprCXX.h:3058
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3813
QualType getElementType() const
Definition TypeBase.h:3825
Attr - This represents one attribute.
Definition Attr.h:46
Represents an attribute applied to a statement.
Definition Stmt.h:2215
Stmt * getSubStmt()
Definition Stmt.h:2251
ArrayRef< const Attr * > getAttrs() const
Definition Stmt.h:2247
Represents a C++ declaration that introduces decls from somewhere else.
Definition DeclCXX.h:3525
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4082
static bool isLogicalOp(Opcode Opc)
Definition Expr.h:4215
Expr * getLHS() const
Definition Expr.h:4132
static bool isComparisonOp(Opcode Opc)
Definition Expr.h:4182
static bool isShiftOp(Opcode Opc)
Definition Expr.h:4170
static bool isCommaOp(Opcode Opc)
Definition Expr.h:4185
static Opcode getOpForCompoundAssignment(Opcode Opc)
Definition Expr.h:4229
Expr * getRHS() const
Definition Expr.h:4134
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
Definition Expr.h:4159
static bool isAssignmentOp(Opcode Opc)
Definition Expr.h:4218
static bool isCompoundAssignmentOp(Opcode Opc)
Definition Expr.h:4223
Opcode getOpcode() const
Definition Expr.h:4127
static bool isBitwiseOp(Opcode Opc)
Definition Expr.h:4173
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6722
BreakStmt - This represents a break.
Definition Stmt.h:3147
Represents a C++2a __builtin_bit_cast(T, v) expression.
Definition ExprCXX.h:5529
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents binding an expression to a temporary.
Definition ExprCXX.h:1497
const Expr * getSubExpr() const
Definition ExprCXX.h:1519
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition ExprCXX.h:727
bool getValue() const
Definition ExprCXX.h:744
Represents a call to a C++ constructor.
Definition ExprCXX.h:1552
bool isElidable() const
Whether this construction is elidable.
Definition ExprCXX.h:1621
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition ExprCXX.h:1695
arg_range arguments()
Definition ExprCXX.h:1676
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
Definition ExprCXX.h:1654
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition ExprCXX.h:1615
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Definition ExprCXX.h:1692
Represents a C++ constructor within a class.
Definition DeclCXX.h:2641
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Definition DeclCXX.cpp:3049
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
Definition DeclCXX.cpp:3069
Represents a C++ base or member initializer.
Definition DeclCXX.h:2406
A default argument (C++ [dcl.fct.default]).
Definition ExprCXX.h:1274
A use of a default initializer in a constructor or in aggregate initialization.
Definition ExprCXX.h:1381
Expr * getExpr()
Get the initialization expression that will be used.
Definition ExprCXX.cpp:1138
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition ExprCXX.h:2630
FunctionDecl * getOperatorDelete() const
Definition ExprCXX.h:2669
bool isArrayForm() const
Definition ExprCXX.h:2656
bool isGlobalDelete() const
Definition ExprCXX.h:2655
Represents a C++ destructor within a class.
Definition DeclCXX.h:2906
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Definition ExprCXX.h:485
Represents the code generated for an expanded expansion statement.
Definition StmtCXX.h:1028
ArrayRef< Stmt * > getInstantiations() const
Definition StmtCXX.h:1069
ArrayRef< Stmt * > getPreambleStmts() const
Definition StmtCXX.h:1073
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Definition StmtCXX.h:136
DeclStmt * getBeginStmt()
Definition StmtCXX.h:164
DeclStmt * getLoopVarStmt()
Definition StmtCXX.h:170
DeclStmt * getEndStmt()
Definition StmtCXX.h:167
DeclStmt * getRangeStmt()
Definition StmtCXX.h:163
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition ExprCXX.h:1755
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Definition ExprCXX.h:1792
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2149
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition DeclCXX.h:2292
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
Definition DeclCXX.cpp:2751
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Definition DeclCXX.cpp:2730
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
Definition DeclCXX.cpp:2895
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2359
bool isArray() const
Definition ExprCXX.h:2468
QualType getAllocatedType() const
Definition ExprCXX.h:2438
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Definition ExprCXX.h:2473
Expr * getPlacementArg(unsigned I)
Definition ExprCXX.h:2507
unsigned getNumPlacementArgs() const
Definition ExprCXX.h:2498
FunctionDecl * getOperatorNew() const
Definition ExprCXX.h:2463
Expr * getInitializer()
The initializer of this new-expression.
Definition ExprCXX.h:2537
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition ExprCXX.h:4362
bool getValue() const
Definition ExprCXX.h:4385
The null pointer literal (C++11 [lex.nullptr])
Definition ExprCXX.h:772
Represents a list-initialization with parenthesis.
Definition ExprCXX.h:5194
MutableArrayRef< Expr * > getInitExprs()
Definition ExprCXX.h:5234
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
Definition DeclCXX.h:1255
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
Definition DeclCXX.cpp:1681
capture_const_range captures() const
Definition DeclCXX.h:1106
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
Definition DeclCXX.cpp:1744
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
Definition ExprCXX.h:530
A rewritten comparison expression that was originally written using operator syntax.
Definition ExprCXX.h:290
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
Definition ExprCXX.h:308
An expression "T()" which creates an rvalue of a non-class type T.
Definition ExprCXX.h:2200
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Definition ExprCXX.h:804
Represents the this expression in C++.
Definition ExprCXX.h:1158
A C++ throw-expression (C++ [except.throw]).
Definition ExprCXX.h:1212
const Expr * getSubExpr() const
Definition ExprCXX.h:1232
CXXTryStmt - A C++ try block, including all handlers.
Definition StmtCXX.h:70
CompoundStmt * getTryBlock()
Definition StmtCXX.h:101
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition ExprCXX.h:852
bool isTypeOperand() const
Definition ExprCXX.h:888
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Definition ExprCXX.cpp:167
Expr * getExprOperand() const
Definition ExprCXX.h:899
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
Definition ExprCXX.cpp:135
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Definition ExprCXX.h:1072
MSGuidDecl * getGuidDecl() const
Definition ExprCXX.h:1118
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2987
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3191
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3170
Expr * getCallee()
Definition Expr.h:3134
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition Expr.h:3178
Expr ** getArgs()
Retrieve the call arguments.
Definition Expr.h:3181
arg_range arguments()
Definition Expr.h:3239
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition Expr.cpp:1631
CaseStmt - Represent a case statement.
Definition Stmt.h:1932
Stmt * getSubStmt()
Definition Stmt.h:2045
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition Expr.h:3720
path_iterator path_begin()
Definition Expr.h:3790
CastKind getCastKind() const
Definition Expr.h:3764
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
Definition Expr.h:3807
const FieldDecl * getTargetUnionField() const
Definition Expr.h:3814
path_iterator path_end()
Definition Expr.h:3791
Expr * getSubExpr()
Definition Expr.h:3770
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
unsigned getValue() const
Definition Expr.h:1649
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition Expr.h:4892
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Definition Expr.h:4928
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
Complex values, per C99 6.2.5p11.
Definition TypeBase.h:3355
QualType getElementType() const
Definition TypeBase.h:3365
CompoundAssignOperator - For compound assignments (e.g.
Definition Expr.h:4344
QualType getComputationLHSType() const
Definition Expr.h:4378
QualType getComputationResultType() const
Definition Expr.h:4381
CompoundLiteralExpr - [C99 6.5.2.5].
Definition Expr.h:3649
bool isFileScope() const
Definition Expr.h:3681
const Expr * getInitializer() const
Definition Expr.h:3677
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition Stmt.h:1752
body_range body()
Definition Stmt.h:1815
Stmt * body_back()
Definition Stmt.h:1820
Represents the specialization of a concept - evaluates to a prvalue of type bool.
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3851
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
Definition TypeBase.h:3927
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition Expr.h:1102
APValue getAPValueResult() const
Definition Expr.cpp:419
bool hasAPValueResult() const
Definition Expr.h:1177
Represents a concrete matrix type with constant number of rows and columns.
Definition TypeBase.h:4478
ContinueStmt - This represents a continue.
Definition Stmt.h:3131
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition Expr.h:4763
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Definition Expr.h:4853
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2126
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1290
ValueDecl * getDecl()
Definition Expr.h:1358
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition Stmt.h:1643
decl_range decls()
Definition Stmt.h:1691
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool isInvalidDecl() const
Definition DeclBase.h:596
bool hasAttr() const
Definition DeclBase.h:585
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
Stmt * getSubStmt()
Definition Stmt.h:2093
InitListExpr * getUpdater() const
Definition Expr.h:5986
DoStmt - This represents a 'do/while' stmt.
Definition Stmt.h:2844
Stmt * getBody()
Definition Stmt.h:2869
Expr * getCond()
Definition Stmt.h:2862
virtual bool TraverseStmt(MaybeConst< Stmt > *S)
Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...
const Expr * getBase() const
Definition Expr.h:6631
Represents a reference to emded data.
Definition Expr.h:5179
ChildElementIter< false > begin()
Definition Expr.h:5285
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition ExprCXX.h:3714
This represents one expression.
Definition Expr.h:113
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:85
bool isGLValue() const
Definition Expr.h:288
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition Expr.h:178
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3111
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
Definition Expr.h:247
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3119
bool isPRValue() const
Definition Expr.h:286
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
Definition Expr.h:285
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:3722
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:3286
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
Definition Expr.h:480
QualType getType() const
Definition Expr.h:145
An expression trait intrinsic.
Definition ExprCXX.h:3083
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Definition Expr.h:6660
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
Definition Expr.cpp:4585
Represents a member of a struct/union/class.
Definition Decl.h:3295
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Definition Decl.h:3531
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
Definition Expr.h:1595
llvm::APFloat getValue() const
Definition Expr.h:1686
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition Stmt.h:2900
Stmt * getInit()
Definition Stmt.h:2915
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
Definition Stmt.cpp:1120
Stmt * getBody()
Definition Stmt.h:2944
Expr * getInc()
Definition Stmt.h:2943
Expr * getCond()
Definition Stmt.h:2942
DeclStmt * getConditionVariableDeclStmt()
If this ForStmt has a condition variable, return the faux DeclStmt associated with the creation of th...
Definition Stmt.h:2930
const Expr * getSubExpr() const
Definition Expr.h:1082
Represents a function declaration or definition.
Definition Decl.h:2059
const ParmVarDecl * getParamDecl(unsigned i) const
Definition Decl.h:2928
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition Decl.cpp:3266
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition Decl.cpp:4244
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition Decl.cpp:4232
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3804
QualType getReturnType() const
Definition Decl.h:2976
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:2905
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2504
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition Decl.cpp:4368
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
Definition Decl.cpp:3468
bool isDefaulted() const
Whether this function is defaulted.
Definition Decl.h:2512
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition Decl.cpp:3868
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Definition Decl.cpp:3186
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition Expr.h:4967
Represents a C11 generic selection.
Definition Expr.h:6232
Expr * getResultExpr()
Return the result expression of this controlling expression.
Definition Expr.h:6518
IfStmt - This represents an if/then/else.
Definition Stmt.h:2271
Stmt * getThen()
Definition Stmt.h:2360
Stmt * getInit()
Definition Stmt.h:2421
bool isNonNegatedConsteval() const
Definition Stmt.h:2456
Expr * getCond()
Definition Stmt.h:2348
bool isNegatedConsteval() const
Definition Stmt.h:2460
Stmt * getElse()
Definition Stmt.h:2369
DeclStmt * getConditionVariableDeclStmt()
If this IfStmt has a condition variable, return the faux DeclStmt associated with the creation of tha...
Definition Stmt.h:2404
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
Definition Stmt.cpp:1068
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition Expr.h:1751
const Expr * getSubExpr() const
Definition Expr.h:1763
Represents an implicitly-generated value initialization of an object of a given type.
Definition Expr.h:6107
Represents a field injected from an anonymous union/struct into the parent scope.
Definition Decl.h:3602
Describes an C or C++ initializer list.
Definition Expr.h:5352
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
Definition Expr.h:5455
ArrayRef< Expr * > inits() const
Definition Expr.h:5405
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition ExprCXX.h:1972
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
Definition ExprCXX.h:2098
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Definition ExprCXX.cpp:1433
bool isCompatibleWith(ClangABI Version) const
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
Definition DeclCXX.h:3337
const Stmt * getNamedLoopOrSwitch() const
If this is a named break/continue, get the loop or switch statement that this targets.
Definition Stmt.cpp:1535
A global _GUID constant.
Definition DeclCXX.h:4432
APValue & getAsAPValue() const
Get the value of this MSGuidDecl as an APValue.
Definition DeclCXX.cpp:3872
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition ExprCXX.h:4973
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Definition ExprCXX.h:4998
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition ExprCXX.h:4990
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
Definition ExprCXX.h:5023
LifetimeExtendedTemporaryDecl * getLifetimeExtendedTemporaryDecl()
Definition ExprCXX.h:5013
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition Expr.h:3408
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition Expr.h:3491
Expr * getBase() const
Definition Expr.h:3485
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3744
This represents a decl that may have a name.
Definition Decl.h:275
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:341
Represents a C++ namespace alias.
Definition DeclCXX.h:3230
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Definition ExprObjC.h:219
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition ExprObjC.h:118
ObjCBoxedExpr - used for generalized expression boxing.
Definition ExprObjC.h:158
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition ExprObjC.h:341
ObjCEncodeExpr, used for @encode in Objective-C.
Definition ExprObjC.h:440
QualType getEncodedType() const
Definition ExprObjC.h:459
SourceLocation getAtLoc() const
Definition ExprObjC.h:454
bool isExpressibleAsConstantInitializer() const
Definition ExprObjC.h:67
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition ExprObjC.h:83
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition Expr.h:2571
Expr * getIndexExpr(unsigned Idx)
Definition Expr.h:2630
const OffsetOfNode & getComponent(unsigned Idx) const
Definition Expr.h:2618
unsigned getNumComponents() const
Definition Expr.h:2626
Helper class for OffsetOfExpr.
Definition Expr.h:2465
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
Definition Expr.h:2523
@ Array
An index into an array.
Definition Expr.h:2470
Kind getKind() const
Determine what kind of offsetof node this is.
Definition Expr.h:2519
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1198
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition Expr.h:1248
Expr * getSelectedExpr() const
Definition ExprCXX.h:4692
ParenExpr - This represents a parenthesized expression, e.g.
Definition Expr.h:2226
const Expr * getSubExpr() const
Definition Expr.h:2243
Represents a parameter to a function.
Definition Decl.h:1820
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3396
QualType getPointeeType() const
Definition TypeBase.h:3406
[C99 6.4.2.2] - A predefined identifier such as func.
Definition Expr.h:2049
StringLiteral * getFunctionName()
Definition Expr.h:2093
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition Expr.h:6854
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
Definition Expr.h:6902
ArrayRef< Expr * > semantics()
Definition Expr.h:6926
A (possibly-)qualified type.
Definition TypeBase.h:938
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
Definition TypeBase.h:8512
QualType withConst() const
Definition TypeBase.h:1175
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1005
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8428
bool isConstant(const ASTContext &Ctx) const
Definition TypeBase.h:1098
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition TypeBase.h:8501
Represents a struct/union/class.
Definition Decl.h:4460
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Definition Expr.h:7553
Base for LValueReferenceType and RValueReferenceType.
Definition TypeBase.h:3671
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
bool isSatisfied() const
Whether or not the requires clause is satisfied.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition Stmt.h:3172
Expr * getRetValue()
Definition Stmt.h:3199
SourceLocation getLocation() const
Definition Expr.h:2199
std::string ComputeName(ASTContext &Context) const
Definition Expr.cpp:593
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:4687
llvm::APSInt getShuffleMaskIdx(unsigned N) const
Definition Expr.h:4739
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Definition Expr.h:4720
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Definition Expr.h:4726
Represents an expression that computes the length of a parameter pack.
Definition ExprCXX.h:4494
unsigned getPackLength() const
Retrieve the length of the parameter pack.
Definition ExprCXX.h:4568
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition Expr.h:5070
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Definition Expr.cpp:2313
Represents a C++11 static_assert declaration.
Definition DeclCXX.h:4165
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition Expr.h:4639
CompoundStmt * getSubStmt()
Definition Expr.h:4656
Stmt - This represents one statement.
Definition Stmt.h:85
StmtClass getStmtClass() const
Definition Stmt.h:1505
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1819
unsigned getLength() const
Definition Expr.h:1944
uint32_t getCodeUnit(size_t I) const
Return the code unit at the given position.
Definition Expr.h:1906
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, ArrayRef< SourceLocation > Locs)
This is the "fully general" constructor that allows representation of strings formed from one or more...
Definition Expr.cpp:1194
unsigned getCharByteWidth() const
Definition Expr.h:1946
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition ExprCXX.h:4717
const SwitchCase * getNextSwitchCase() const
Definition Stmt.h:1905
SwitchStmt - This represents a 'switch' stmt.
Definition Stmt.h:2521
Expr * getCond()
Definition Stmt.h:2584
Stmt * getBody()
Definition Stmt.h:2596
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
Definition Stmt.cpp:1186
Stmt * getInit()
Definition Stmt.h:2601
SwitchCase * getSwitchCaseList()
Definition Stmt.h:2652
DeclStmt * getConditionVariableDeclStmt()
If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...
Definition Stmt.h:2635
Represents the declaration of a struct/union/class/enum.
Definition Decl.h:3852
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition Decl.h:3953
bool isUnion() const
Definition Decl.h:4063
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition ExprCXX.h:2900
bool getBoolValue() const
Definition ExprCXX.h:2961
bool isStoredAsComparisonResult() const
Definition ExprCXX.h:2957
const APValue & getAPValue() const
Definition ExprCXX.h:2966
bool isStoredAsBoolean() const
Definition ExprCXX.h:2953
The base class of the type hierarchy.
Definition TypeBase.h:1879
bool isVoidType() const
Definition TypeBase.h:9037
bool isBooleanType() const
Definition TypeBase.h:9174
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
Definition Type.cpp:3237
bool isIncompleteArrayType() const
Definition TypeBase.h:8772
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
bool isNothrowT() const
Definition Type.cpp:3421
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
bool isVoidPointerType() const
Definition Type.cpp:841
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
Definition Type.cpp:2641
bool isArrayType() const
Definition TypeBase.h:8764
bool isFunctionPointerType() const
Definition TypeBase.h:8732
bool isConstantMatrixType() const
Definition TypeBase.h:8832
bool isPointerType() const
Definition TypeBase.h:8665
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition TypeBase.h:9081
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9331
bool isReferenceType() const
Definition TypeBase.h:8689
bool isEnumeralType() const
Definition TypeBase.h:8796
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:881
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition TypeBase.h:9159
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Definition TypeBase.h:9006
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2859
bool isAnyComplexType() const
Definition TypeBase.h:8800
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
Definition TypeBase.h:9097
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
Definition TypeBase.h:9217
bool isMemberPointerType() const
Definition TypeBase.h:8746
bool isAtomicType() const
Definition TypeBase.h:8857
EnumDecl * castAsEnumDecl() const
Definition Type.h:59
bool isStdByteType() const
Definition Type.cpp:3440
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition TypeBase.h:9317
bool isPointerOrReferenceType() const
Definition TypeBase.h:8669
bool isFunctionType() const
Definition TypeBase.h:8661
bool isVectorType() const
Definition TypeBase.h:8804
bool isRealFloatingType() const
Floating point categories.
Definition Type.cpp:2529
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2998
bool isFloatingType() const
Definition Type.cpp:2513
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9264
bool isRecordType() const
Definition TypeBase.h:8792
bool isSizelessVectorType() const
Returns true for all scalable vector types.
Definition Type.cpp:2787
bool hasBooleanRepresentation() const
Determine whether this type has a boolean representation – i.e., it is a boolean type,...
Definition Type.cpp:2568
Base class for declarations which introduce a typedef-name.
Definition Decl.h:3697
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition Expr.h:2669
QualType getArgumentType() const
Definition Expr.h:2712
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
Definition Expr.h:2738
UnaryExprOrTypeTrait getKind() const
Definition Expr.h:2701
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2288
Expr * getSubExpr() const
Definition Expr.h:2329
Opcode getOpcode() const
Definition Expr.h:2324
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Definition Expr.h:2342
Represents C++ using-directive.
Definition DeclCXX.h:3125
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:713
QualType getType() const
Definition Decl.h:724
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Definition Decl.cpp:5646
QualType getType() const
Definition Value.cpp:238
Represents a variable declaration or definition.
Definition Decl.h:933
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition Decl.h:1594
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
Definition Decl.h:1603
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition Decl.h:1307
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition Decl.h:1248
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
Definition Decl.cpp:2639
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition Decl.h:1215
const Expr * getInit() const
Definition Decl.h:1392
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
Definition Decl.cpp:2555
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
Definition Decl.h:1275
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Definition Decl.h:1382
Represents a GCC generic vector type.
Definition TypeBase.h:4266
unsigned getNumElements() const
Definition TypeBase.h:4281
QualType getElementType() const
Definition TypeBase.h:4280
WhileStmt - This represents a 'while' stmt.
Definition Stmt.h:2709
Expr * getCond()
Definition Stmt.h:2761
DeclStmt * getConditionVariableDeclStmt()
If this WhileStmt has a condition variable, return the faux DeclStmt associated with the creation of ...
Definition Stmt.h:2797
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
Definition Stmt.cpp:1247
Stmt * getBody()
Definition Stmt.h:2773
ArrayIndexScope(Compiler< Emitter > *Ctx, uint64_t Index)
Definition Compiler.cpp:222
A memory block, either on the stack or in the heap.
Definition InterpBlock.h:43
void invokeDtor()
Invokes the Destructor.
Compilation context for expressions.
Definition Compiler.h:119
llvm::SmallVector< InitLink > InitStack
Definition Compiler.h:508
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E)
bool VisitCXXDeleteExpr(const CXXDeleteExpr *E)
bool VisitOffsetOfExpr(const OffsetOfExpr *E)
bool visitContinueStmt(const ContinueStmt *S)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init, OptPrimType InitT)
Pointer to the array(not the element!) must be on the stack when calling this.
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E)
bool visitInitializerPop(const Expr *E)
Similar, but will also pop the pointer.
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
PrimType classifyPrim(QualType Ty) const
Classifies a known primitive type.
Definition Compiler.h:299
bool VisitTypeTraitExpr(const TypeTraitExpr *E)
bool VisitLambdaExpr(const LambdaExpr *E)
bool VisitMemberExpr(const MemberExpr *E)
llvm::DenseMap< const OpaqueValueExpr *, unsigned > OpaqueExprs
OpaqueValueExpr to location mapping.
Definition Compiler.h:483
bool VisitBinaryOperator(const BinaryOperator *E)
bool visitCXXExpansionStmtInstantiation(const CXXExpansionStmtInstantiation *S)
template for (auto x : {1, 2}) {}
bool visitAttributedStmt(const AttributedStmt *S)
bool VisitPackIndexingExpr(const PackIndexingExpr *E)
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
bool VisitCallExpr(const CallExpr *E)
std::optional< uint64_t > ArrayIndex
Current argument index. Needed to emit ArrayInitIndexExpr.
Definition Compiler.h:489
bool VisitPseudoObjectExpr(const PseudoObjectExpr *E)
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E)
bool visitAPValueInitializer(const APValue &Val, SourceInfo Info, QualType T, bool IsCompleteClass=true)
const Function * getFunction(const FunctionDecl *FD)
Returns a function for the given FunctionDecl.
bool VisitFixedPointBinOp(const BinaryOperator *E)
bool VisitCastExpr(const CastExpr *E)
Definition Compiler.cpp:453
bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E)
bool VisitFixedPointUnaryOperator(const UnaryOperator *E)
bool VisitComplexUnaryOperator(const UnaryOperator *E)
llvm::DenseMap< const SwitchCase *, LabelTy > CaseMap
Definition Compiler.h:125
bool VisitBlockExpr(const BlockExpr *E)
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
bool VisitLogicalBinOp(const BinaryOperator *E)
bool visitCompoundStmt(const CompoundStmt *S)
Context & Ctx
Current compilation context.
Definition Compiler.h:142
const VarDecl * InitializingDecl
Definition Compiler.h:506
bool visitDeclRef(const ValueDecl *D, const Expr *E)
Visit the given decl as if we have a reference to it.
bool visitBreakStmt(const BreakStmt *S)
bool visitExpr(const Expr *E, bool DestroyToplevelScope) override
bool visitForStmt(const ForStmt *S)
bool VisitDeclRefExpr(const DeclRefExpr *E)
bool VisitOpaqueValueExpr(const OpaqueValueExpr *E)
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E)
bool visitAPValue(const APValue &Val, PrimType ValType, SourceInfo Info)
Visit an APValue.
bool VisitStmtExpr(const StmtExpr *E)
bool VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *E)
bool VisitFixedPointLiteral(const FixedPointLiteral *E)
const FunctionDecl * CompilingFunction
Definition Compiler.h:519
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
VarCreationState visitVarDecl(const VarDecl *VD, const Expr *Init, bool Toplevel=false)
Creates and initializes a variable from the given decl.
VariableScope< Emitter > * VarScope
Current scope.
Definition Compiler.h:486
bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init, bool ConstantContext) override
Toplevel visitDeclAndReturn().
bool VisitCXXNewExpr(const CXXNewExpr *E)
bool VisitCompoundAssignOperator(const CompoundAssignOperator *E)
bool visit(const Expr *E) override
Evaluates an expression and places the result on the stack.
bool delegate(const Expr *E)
Just pass evaluation on to E.
bool visitLValueExpr(const Expr *E, bool DestroyToplevelScope) override
bool discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
CaseMap CaseLabels
Switch case mapping.
Definition Compiler.h:515
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
const RecordType * getRecordTy(QualType Ty)
Returns a record type from a record or pointer type.
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E)
bool visitInitList(ArrayRef< const Expr * > Inits, const Expr *ArrayFiller, const Expr *E)
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E)
bool VisitPredefinedExpr(const PredefinedExpr *E)
bool VisitSourceLocExpr(const SourceLocExpr *E)
bool visitDeclStmt(const DeclStmt *DS, bool EvaluateConditionDecl=false)
bool registerRedecl(const VarDecl *VD, const APValue &V)
bool emitCleanup()
Emits scope cleanup instructions.
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E)
bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E)
bool visitInitializer(const Expr *E)
Compiles an initializer.
bool visitDtorCall(const VarDecl *VD, const APValue &Value) override
const Expr * SourceLocDefaultExpr
DefaultInit- or DefaultArgExpr, needed for SourceLocExpr.
Definition Compiler.h:492
bool VisitObjCArrayLiteral(const ObjCArrayLiteral *E)
UnsignedOrNone OptLabelTy
Definition Compiler.h:124
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E)
bool VisitPointerArithBinOp(const BinaryOperator *E)
Perform addition/subtraction of a pointer and an integer or subtraction of two pointers.
bool visitCallArgs(ArrayRef< const Expr * > Args, const FunctionDecl *FuncDecl, bool Activate, bool IsOperatorCall)
bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E)
bool visitDefaultStmt(const DefaultStmt *S)
bool VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
bool visitWithSubstitutions(const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This, const Expr *Condition) override
Evaluate the Condition as if it was in the body of Callee.
typename Emitter::LabelTy LabelTy
Definition Compiler.h:122
VarCreationState visitDecl(const VarDecl *VD)
bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E)
bool visitStmt(const Stmt *S)
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
bool VisitVectorUnaryOperator(const UnaryOperator *E)
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
bool VisitDesignatedInitUpdateExpr(const DesignatedInitUpdateExpr *E)
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
bool VisitRecoveryExpr(const RecoveryExpr *E)
bool VisitRequiresExpr(const RequiresExpr *E)
bool Initializing
Flag inidicating if we're initializing an already created variable.
Definition Compiler.h:505
bool visitReturnStmt(const ReturnStmt *RS)
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitChooseExpr(const ChooseExpr *E)
bool visitFunc(const FunctionDecl *F) override
bool visitCXXForRangeStmt(const CXXForRangeStmt *S)
bool visitCaseStmt(const CaseStmt *S)
bool VisitComplexBinOp(const BinaryOperator *E)
llvm::DenseMap< const ValueDecl *, Scope::Local > Locals
Variable to storage mapping.
Definition Compiler.h:480
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
bool VisitCXXTypeidExpr(const CXXTypeidExpr *E)
UnsignedOrNone allocateTemporary(const Expr *E)
bool VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinID)
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
OptPrimType ReturnType
Type of the expression returned by the function.
Definition Compiler.h:512
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
OptPrimType classify(const Expr *E) const
Definition Compiler.h:293
llvm::SmallVector< LabelInfo > LabelInfoStack
Stack of label information for loops and switch statements.
Definition Compiler.h:517
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
bool visitDoStmt(const DoStmt *S)
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitInitListExpr(const InitListExpr *E)
bool VisitVectorBinOp(const BinaryOperator *E)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
bool DiscardResult
Flag indicating if return value is to be discarded.
Definition Compiler.h:495
bool VisitEmbedExpr(const EmbedExpr *E)
UnsignedOrNone allocateLocal(DeclOrExpr Decl, QualType Ty=QualType(), ScopeKind=ScopeKind::Block)
Allocates a space storing a local given its type.
bool VisitConvertVectorExpr(const ConvertVectorExpr *E)
bool VisitCXXThisExpr(const CXXThisExpr *E)
bool VisitConstantExpr(const ConstantExpr *E)
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool visitSwitchStmt(const SwitchStmt *S)
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E)
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool visitAsLValue(const Expr *E)
unsigned allocateLocalPrimitive(DeclOrExpr Decl, PrimType Ty, bool IsConst, bool IsVolatile=false, ScopeKind SC=ScopeKind::Block)
Creates a local primitive value.
bool visitWhileStmt(const WhileStmt *S)
bool visitIfStmt(const IfStmt *IS)
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
bool canClassify(const Expr *E) const
Definition Compiler.h:295
bool VisitFloatingLiteral(const FloatingLiteral *E)
Program & P
Program to link to.
Definition Compiler.h:144
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
bool VisitGNUNullExpr(const GNUNullExpr *E)
bool VisitImaginaryLiteral(const ImaginaryLiteral *E)
bool VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E)
bool visitCXXTryStmt(const CXXTryStmt *S)
static bool isUnevaluatedBuiltin(unsigned ID)
Unevaluated builtins don't get their arguments put on the stack automatically.
Definition Context.cpp:828
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Definition Context.h:168
Scope used to handle temporaries in toplevel variable declarations.
Definition Compiler.cpp:291
DeclScope(Compiler< Emitter > *Ctx, const VarDecl *VD)
Definition Compiler.cpp:293
Wrapper around fixed point types.
Definition FixedPoint.h:23
static FixedPoint zero(llvm::FixedPointSemantics Sem)
Definition FixedPoint.h:36
If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY.
Definition Floating.h:35
bool singleWord() const
Definition Floating.h:107
Bytecode function.
Definition Function.h:98
bool hasThisPointer() const
Definition Function.h:225
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Definition Function.h:155
InitLinkScope(Compiler< Emitter > *Ctx, InitLink &&Link)
Definition Compiler.cpp:257
Compiler< Emitter > * Ctx
Definition Compiler.cpp:264
InitStackScope(Compiler< Emitter > *Ctx, bool Active)
Definition Compiler.cpp:269
When generating code for e.g.
Definition Compiler.cpp:428
LocOverrideScope(Compiler< Emitter > *Ctx, SourceInfo NewValue, bool Enabled=true)
Definition Compiler.cpp:430
Generic scope for local variables.
Definition Compiler.cpp:113
UnsignedOrNone Idx
Index of the scope in the chain.
Definition Compiler.cpp:216
~LocalScope() override
Emit a Destroy op for this scope.
Definition Compiler.cpp:119
bool destroyLocals(const Expr *E=nullptr) override
Explicit destruction of local variables.
Definition Compiler.cpp:126
bool emitDestructors(const Expr *E=nullptr) override
Definition Compiler.cpp:162
void removeIfStoredOpaqueValue(const Scope::Local &Local)
Definition Compiler.cpp:208
void addLocal(Scope::Local Local) override
Definition Compiler.cpp:138
void forceInit() override
Force-initialize this scope.
Definition Compiler.cpp:154
LocalScope(Compiler< Emitter > *Ctx, ScopeKind Kind=ScopeKind::Block)
Definition Compiler.cpp:115
Sets the context for break/continue statements.
Definition Compiler.cpp:367
typename Compiler< Emitter >::LabelTy LabelTy
Definition Compiler.cpp:369
typename Compiler< Emitter >::OptLabelTy OptLabelTy
Definition Compiler.cpp:370
typename Compiler< Emitter >::LabelInfo LabelInfo
Definition Compiler.cpp:371
LoopScope(Compiler< Emitter > *Ctx, const Stmt *Name, LabelTy BreakLabel, LabelTy ContinueLabel)
Definition Compiler.cpp:373
PrimType value_or(PrimType PT) const
Definition PrimType.h:88
Scope used to handle initialization methods.
Definition Compiler.cpp:311
OptionScope(Compiler< Emitter > *Ctx, bool NewDiscardResult, bool NewInitializing, bool NewToLValue)
Root constructor, compiling or discarding primitives.
Definition Compiler.cpp:314
Context to manage declaration lifetimes.
Definition Program.h:138
Structure/Class descriptor.
Definition Record.h:27
bool isUnion() const
Checks if the record is a union.
Definition Record.h:71
const Field * getField(unsigned I) const
Definition Record.h:97
const Base * getBaseOrNull(const RecordDecl *RD) const
Definition Record.cpp:56
bool hasTrivialDtor() const
Returns true for anonymous unions and records with no destructor or for those with a trivial destruct...
Definition Record.cpp:34
const Base * findVirtualBase(const RecordDecl *RD) const
Returns a virtual base descriptor.
Definition Record.cpp:75
Describes a scope block.
Definition Function.h:35
Describes the statement/declaration an opcode was generated from.
Definition Source.h:77
const Expr * asExpr() const
Definition Source.h:92
SourceLocScope(Compiler< Emitter > *Ctx, const Expr *DefaultExpr)
Definition Compiler.cpp:236
typename Compiler< Emitter >::LabelTy LabelTy
Definition Compiler.cpp:395
typename Compiler< Emitter >::OptLabelTy OptLabelTy
Definition Compiler.cpp:396
typename Compiler< Emitter >::LabelInfo LabelInfo
Definition Compiler.cpp:398
typename Compiler< Emitter >::CaseMap CaseMap
Definition Compiler.cpp:397
SwitchScope(Compiler< Emitter > *Ctx, const Stmt *Name, CaseMap &&CaseLabels, LabelTy BreakLabel, OptLabelTy DefaultLabel)
Definition Compiler.cpp:400
Scope chain managing the variable lifetimes.
Definition Compiler.cpp:55
void addForScopeKind(const Scope::Local &Local, ScopeKind Kind)
Like addExtended, but adds to the nearest scope of the given kind.
Definition Compiler.cpp:70
bool LocalsAlwaysEnabled
Whether locals added to this scope are enabled by default.
Definition Compiler.cpp:102
Compiler< Emitter > * Ctx
Compiler instance.
Definition Compiler.cpp:106
virtual bool emitDestructors(const Expr *E=nullptr)
Definition Compiler.cpp:93
VariableScope(Compiler< Emitter > *Ctx, ScopeKind Kind=ScopeKind::Block)
Definition Compiler.cpp:57
virtual bool destroyLocals(const Expr *E=nullptr)
Definition Compiler.cpp:94
virtual void addLocal(Scope::Local Local)
Definition Compiler.cpp:66
VariableScope * Parent
Link to the parent scope.
Definition Compiler.cpp:108
ScopeKind getKind() const
Definition Compiler.cpp:97
VariableScope * getParent() const
Definition Compiler.cpp:96
bool Sub(InterpState &S, CodePtr OpPC)
Definition Interp.h:436
bool LT(InterpState &S, CodePtr OpPC)
Definition Interp.h:1528
static llvm::RoundingMode getRoundingMode(FPOptions FPO)
constexpr bool isSignedType(PrimType T)
Definition PrimType.h:59
bool Div(InterpState &S, CodePtr OpPC)
1) Pops the RHS from the stack.
Definition Interp.h:781
constexpr bool isPtrType(PrimType T)
Definition PrimType.h:55
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition PrimType.h:213
bool This(InterpState &S, CodePtr OpPC)
Definition Interp.h:3222
constexpr bool isIntegerOrBoolType(PrimType T)
Definition PrimType.h:52
llvm::APFloat APFloat
Definition Floating.h:27
bool InitScope(InterpState &S, uint32_t I)
Definition Interp.h:2869
static void discard(InterpStack &Stk, PrimType T)
static bool isSideEffectFree(const Expr *E)
Check if E has side-effects.
Definition Compiler.cpp:44
llvm::APInt APInt
Definition FixedPoint.h:19
bool LE(InterpState &S, CodePtr OpPC)
Definition Interp.h:1535
PrimType
Enumeration of the primitive types of the VM.
Definition PrimType.h:34
static std::optional< bool > getBoolValue(const Expr *E)
Definition Compiler.cpp:31
static bool Activate(InterpState &S)
Definition Interp.h:2315
bool Init(InterpState &S, CodePtr OpPC)
Definition Interp.h:2432
bool Mul(InterpState &S, CodePtr OpPC)
Definition Interp.h:490
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
Definition PrimType.cpp:24
bool Inc(InterpState &S, CodePtr OpPC, bool CanOverflow)
1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...
Definition Interp.h:975
bool Add(InterpState &S, CodePtr OpPC)
Definition Interp.h:407
llvm::BitVector collectNonNullArgs(const FunctionDecl *F, ArrayRef< const Expr * > Args)
constexpr bool isIntegerType(PrimType T)
Definition PrimType.h:53
llvm::APSInt APSInt
Definition FixedPoint.h:20
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
Definition Address.h:330
bool hasSpecificAttr(const Container &container)
@ Success
Annotation was successful.
Definition Parser.h:65
@ Link
'link' clause, allowed on 'declare' construct.
DynamicRecursiveASTVisitorBase< true > ConstDynamicRecursiveASTVisitor
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
@ SD_Static
Static storage duration.
Definition Specifiers.h:342
@ SD_FullExpression
Full-expression storage duration (for temporaries).
Definition Specifiers.h:339
@ Result
The result type of a method or function.
Definition TypeBase.h:906
OptionalUnsigned< unsigned > UnsignedOrNone
const FunctionProtoType * T
U cast(CodeGen::Address addr)
Definition Address.h:327
int const char * function
Definition c++config.h:31
__builtin_elementwise_add_sat __builtin_elementwise_sub_sat uint32_t __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
#define true
Definition stdbool.h:25
llvm::APSInt getIntValue() const
Get the constant integer value used by this variable to represent the comparison category result type...
EvalResult is a struct with detailed info about an evaluated expression.
Definition Expr.h:666
A quantity in bits.
const ValueDecl * asValueDecl() const
Definition DeclOrExpr.h:35
const Expr * asExpr() const
Definition DeclOrExpr.h:33
Describes a memory block created by an allocation site.
Definition Descriptor.h:122
unsigned getNumElems() const
Returns the number of elements stored in the block.
Definition Descriptor.h:246
bool isPrimitive() const
Checks if the descriptor is of a primitive.
Definition Descriptor.h:260
QualType getElemQualType() const
bool hasTrivialDtor() const
Whether variables of this descriptor need their destructor called or not.
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
Definition Descriptor.h:253
QualType getType() const
const Descriptor *const ElemDesc
Descriptor of the array element.
Definition Descriptor.h:148
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
Definition Descriptor.h:251
PrimType getPrimType() const
Definition Descriptor.h:231
bool isRecord() const
Checks if the descriptor is of a record.
Definition Descriptor.h:265
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:263
Descriptor used for global variables.
Definition Descriptor.h:49
Information about a local's storage.
Definition Function.h:38
State encapsulating if a the variable creation has been successful, unsuccessful, or no variable has ...
Definition Compiler.h:104
static VarCreationState NotCreated()
Definition Compiler.h:108