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 // I am almost confident in saying that a var decl must be static
2924 // and therefore registered as a global variable.
2925 if (auto GlobalIndex = P.getGlobal(VD)) {
2926 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2927 return false;
2928 if (Member->getType()->isReferenceType())
2929 return this->emitLoadPopPtr(E);
2930 return true;
2931 }
2932 return false;
2933 }
2934
2935 if (!isa<FieldDecl>(Member)) {
2936 // A non-static member function access only makes sense as part of the
2937 // enclosing call here. Don't try to evaluate it in isolation.
2938 if (const auto *MD = dyn_cast<CXXMethodDecl>(Member);
2939 MD && !MD->isStatic()) {
2940 return false;
2941 }
2942
2943 if (!this->discard(Base) && !this->emitSideEffect(E))
2944 return false;
2945
2946 return this->visitDeclRef(Member, E);
2947 }
2948
2949 if (!this->visit(Base))
2950 return false;
2951
2952 // Base above gives us a pointer on the stack.
2953 const auto *FD = cast<FieldDecl>(Member);
2954 const RecordDecl *RD = FD->getParent();
2955 const Record *R = getRecord(RD);
2956 if (!R)
2957 return false;
2958 const Record::Field *F = R->getField(FD);
2959
2960 // MemberExprs are almost always lvalues, in which case we don't need to
2961 // do the load. But sometimes they aren't.
2962 const auto maybeLoadValue = [&]() -> bool {
2963 if (E->isGLValue())
2964 return true;
2965 if (OptPrimType T = classify(E))
2966 return this->emitLoadPop(*T, E);
2967 return false;
2968 };
2969
2970 // Leave a pointer to the field on the stack.
2971 if (F->Decl->getType()->isReferenceType())
2972 return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue();
2973 return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue();
2974}
2975
2976template <class Emitter>
2978 assert(!DiscardResult);
2979 // ArrayIndex might not be set if a ArrayInitIndexExpr is being evaluated
2980 // stand-alone, e.g. via EvaluateAsInt().
2981 if (!ArrayIndex)
2982 return false;
2983 return this->emitConst(*ArrayIndex, E);
2984}
2985
2986template <class Emitter>
2988 assert(Initializing);
2989 assert(!DiscardResult);
2990
2991 const Expr *Common = E->getCommonExpr();
2992 const Expr *SubExpr = E->getSubExpr();
2993 OptPrimType SubExprT = classify(SubExpr);
2994 size_t Size = E->getArraySize().getZExtValue();
2995
2996 if (SubExprT) {
2997 // Unwrap the OpaqueValueExpr so we don't cache something we won't reuse.
2998 Common = cast<OpaqueValueExpr>(Common)->getSourceExpr();
2999
3000 if (!this->visit(Common))
3001 return false;
3002 return this->emitCopyArray(*SubExprT, 0, 0, Size, E);
3003 }
3004
3005 // We visit the common opaque expression here once so we have its value
3006 // cached.
3007 if (!this->discard(Common))
3008 return false;
3009
3010 // TODO: This compiles to quite a lot of bytecode if the array is larger.
3011 // Investigate compiling this to a loop.
3012
3013 // So, every iteration, we execute an assignment here
3014 // where the LHS is on the stack (the target array)
3015 // and the RHS is our SubExpr.
3016 for (size_t I = 0; I != Size; ++I) {
3017 ArrayIndexScope<Emitter> IndexScope(this, I);
3019
3020 if (!this->visitArrayElemInit(I, SubExpr, SubExprT))
3021 return false;
3022 if (!BS.destroyLocals())
3023 return false;
3024 }
3025 return true;
3026}
3027
3028template <class Emitter>
3030 const Expr *SourceExpr = E->getSourceExpr();
3031 if (!SourceExpr)
3032 return false;
3033
3034 if (Initializing) {
3035 assert(!DiscardResult);
3036 return this->visitInitializer(SourceExpr);
3037 }
3038
3039 PrimType SubExprT = classify(SourceExpr).value_or(PT_Ptr);
3040 if (auto It = OpaqueExprs.find(E); It != OpaqueExprs.end()) {
3041 if (DiscardResult)
3042 return true;
3043 return this->emitGetLocal(SubExprT, It->second, E);
3044 }
3045
3046 if (!this->visit(SourceExpr))
3047 return false;
3048
3049 // At this point we either have the evaluated source expression or a pointer
3050 // to an object on the stack. We want to create a local variable that stores
3051 // this value.
3052 unsigned LocalIndex = allocateLocalPrimitive(E, SubExprT, /*IsConst=*/true);
3053 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
3054 return false;
3055
3056 // This is cleaned up when the local variable is destroyed.
3057 OpaqueExprs.insert({E, LocalIndex});
3058
3059 // Here the local variable is created but the value is removed from the stack,
3060 // so we put it back if the caller needs it.
3061 if (!DiscardResult)
3062 return this->emitGetLocal(SubExprT, LocalIndex, E);
3063 return true;
3064}
3065
3066template <class Emitter>
3068 const AbstractConditionalOperator *E) {
3069 const Expr *Condition = E->getCond();
3070 const Expr *TrueExpr = E->getTrueExpr();
3071 const Expr *FalseExpr = E->getFalseExpr();
3072
3073 if (std::optional<bool> BoolValue = getBoolValue(Condition)) {
3074 if (*BoolValue)
3075 return this->delegate(TrueExpr);
3076 return this->delegate(FalseExpr);
3077 }
3078
3079 bool IsBcpCall = false;
3080 if (const auto *CE = dyn_cast<CallExpr>(Condition->IgnoreParenCasts());
3081 CE && CE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) {
3082 IsBcpCall = true;
3083 }
3084
3085 LabelTy LabelEnd = this->getLabel(); // Label after the operator.
3086 LabelTy LabelFalse = this->getLabel(); // Label for the false expr.
3087
3088 if (IsBcpCall) {
3089 if (!this->emitPushIgnoreDiags(E))
3090 return false;
3091 }
3092
3093 if (!this->visitBool(Condition)) {
3094 // If the condition failed and we're checking for undefined behavior
3095 // (which only happens with EvalEmitter) check the TrueExpr and FalseExpr
3096 // as well.
3097 if (this->checkingForUndefinedBehavior()) {
3098 if (!this->discard(TrueExpr))
3099 return false;
3100 if (!this->discard(FalseExpr))
3101 return false;
3102 }
3103 return false;
3104 }
3105
3106 // Force-init the scope, which creates a InitScope op. This is necessary so
3107 // the scope is not only initialized in one arm of the conditional operator.
3108 this->VarScope->forceInit();
3109 // The TrueExpr and FalseExpr of a conditional operator do _not_ create a
3110 // scope, which means the local variables created within them unconditionally
3111 // always exist. However, we need to later differentiate which branch was
3112 // taken and only destroy the varibles of the active branch. This is what the
3113 // "enabled" flags on local variables are used for.
3114 llvm::SaveAndRestore LAAA(this->VarScope->LocalsAlwaysEnabled,
3115 /*NewValue=*/false);
3116
3117 if (!this->jumpFalse(LabelFalse, E))
3118 return false;
3119 if (!this->delegate(TrueExpr))
3120 return false;
3121
3122 if (!this->jump(LabelEnd, E))
3123 return false;
3124 this->emitLabel(LabelFalse);
3125 if (!this->delegate(FalseExpr))
3126 return false;
3127
3128 this->fallthrough(LabelEnd);
3129 this->emitLabel(LabelEnd);
3130
3131 if (IsBcpCall)
3132 return this->emitPopIgnoreDiags(E);
3133 return true;
3134}
3135
3136template <class Emitter>
3138 if (DiscardResult)
3139 return true;
3140
3141 if (!Initializing)
3142 return this->emitGetStringPtr(E, E);
3143
3144 // We are initializing an array on the stack.
3145 const ConstantArrayType *CAT =
3146 Ctx.getASTContext().getAsConstantArrayType(E->getType());
3147 assert(CAT && "a string literal that's not a constant array?");
3148
3149 // If the initializer string is too long, a diagnostic has already been
3150 // emitted. Read only the array length from the string literal.
3151 unsigned ArraySize = CAT->getZExtSize();
3152 unsigned N = std::min(ArraySize, E->getLength());
3153 unsigned CharWidth = E->getCharByteWidth();
3154
3155 for (unsigned I = 0; I != N; ++I) {
3156 uint32_t CodeUnit = E->getCodeUnit(I);
3157
3158 if (CharWidth == 1) {
3159 this->emitConstSint8(CodeUnit, E);
3160 this->emitInitElemSint8(I, E);
3161 } else if (CharWidth == 2) {
3162 this->emitConstUint16(CodeUnit, E);
3163 this->emitInitElemUint16(I, E);
3164 } else if (CharWidth == 4) {
3165 this->emitConstUint32(CodeUnit, E);
3166 this->emitInitElemUint32(I, E);
3167 } else {
3168 llvm_unreachable("unsupported character width");
3169 }
3170 }
3171
3172 // Fill up the rest of the char array with NUL bytes.
3173 for (unsigned I = N; I != ArraySize; ++I) {
3174 if (CharWidth == 1) {
3175 this->emitConstSint8(0, E);
3176 this->emitInitElemSint8(I, E);
3177 } else if (CharWidth == 2) {
3178 this->emitConstUint16(0, E);
3179 this->emitInitElemUint16(I, E);
3180 } else if (CharWidth == 4) {
3181 this->emitConstUint32(0, E);
3182 this->emitInitElemUint32(I, E);
3183 } else {
3184 llvm_unreachable("unsupported character width");
3185 }
3186 }
3187
3188 return true;
3189}
3190
3191template <class Emitter>
3193 if (DiscardResult)
3194 return true;
3195 return this->emitDummyPtr(E, E);
3196}
3197
3198template <class Emitter>
3200 auto &A = Ctx.getASTContext();
3201 std::string Str;
3202 A.getObjCEncodingForType(E->getEncodedType(), Str);
3203 StringLiteral *SL =
3205 /*Pascal=*/false, E->getType(), E->getAtLoc());
3206 return this->delegate(SL);
3207}
3208
3209template <class Emitter>
3211 const SYCLUniqueStableNameExpr *E) {
3212 if (DiscardResult)
3213 return true;
3214
3215 assert(!Initializing);
3216
3217 auto &A = Ctx.getASTContext();
3218 std::string ResultStr = E->ComputeName(A);
3219
3220 QualType CharTy = A.CharTy.withConst();
3221 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
3222 QualType ArrayTy = A.getConstantArrayType(CharTy, Size, nullptr,
3224
3225 StringLiteral *SL =
3227 /*Pascal=*/false, ArrayTy, E->getLocation());
3228 return this->emitGetStringPtr(SL, E);
3229}
3230
3231template <class Emitter>
3233 if (DiscardResult)
3234 return true;
3235 return this->emitConst(E->getValue(), E);
3236}
3237
3238template <class Emitter>
3240 const CompoundAssignOperator *E) {
3241
3242 const Expr *LHS = E->getLHS();
3243 const Expr *RHS = E->getRHS();
3244 QualType LHSType = LHS->getType();
3245 QualType LHSComputationType = E->getComputationLHSType();
3246 QualType ResultType = E->getComputationResultType();
3247 OptPrimType LT = classify(LHSComputationType);
3248 OptPrimType RT = classify(ResultType);
3249
3250 assert(ResultType->isFloatingType());
3251
3252 if (!LT || !RT)
3253 return false;
3254
3255 PrimType LHST = classifyPrim(LHSType);
3256
3257 if (isSideEffectFree(RHS)) {
3258 if (!visit(LHS))
3259 return false;
3260 if (!this->emitLoad(LHST, E))
3261 return false;
3262 // If necessary, convert LHS to its computation type.
3263 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
3264 LHSComputationType, E))
3265 return false;
3266 if (!visit(RHS))
3267 return false;
3268
3269 } else {
3270 // C++17 onwards require that we evaluate the RHS first.
3271 // Compute RHS and save it in a temporary variable so we can
3272 // load it again later.
3273 if (!visit(RHS))
3274 return false;
3275
3276 unsigned TempOffset =
3277 this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
3278 if (!this->emitSetLocal(*RT, TempOffset, E))
3279 return false;
3280
3281 // First, visit LHS.
3282 if (!visit(LHS))
3283 return false;
3284 if (!this->emitLoad(LHST, E))
3285 return false;
3286
3287 // If necessary, convert LHS to its computation type.
3288 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
3289 LHSComputationType, E))
3290 return false;
3291
3292 // Now load RHS.
3293 if (!this->emitGetLocal(*RT, TempOffset, E))
3294 return false;
3295 }
3296
3297 switch (E->getOpcode()) {
3298 case BO_AddAssign:
3299 if (!this->emitAddf(getFPOptions(E), E))
3300 return false;
3301 break;
3302 case BO_SubAssign:
3303 if (!this->emitSubf(getFPOptions(E), E))
3304 return false;
3305 break;
3306 case BO_MulAssign:
3307 if (!this->emitMulf(getFPOptions(E), E))
3308 return false;
3309 break;
3310 case BO_DivAssign:
3311 if (!this->emitDivf(getFPOptions(E), E))
3312 return false;
3313 break;
3314 default:
3315 return false;
3316 }
3317
3318 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->getType(), E))
3319 return false;
3320
3321 if (DiscardResult)
3322 return this->emitStorePop(LHST, E);
3323 return this->emitStore(LHST, E);
3324}
3325
3326template <class Emitter>
3328 const CompoundAssignOperator *E) {
3329 BinaryOperatorKind Op = E->getOpcode();
3330 const Expr *LHS = E->getLHS();
3331 const Expr *RHS = E->getRHS();
3332 OptPrimType LT = classify(LHS->getType());
3333 OptPrimType RT = classify(RHS->getType());
3334
3335 if (Op != BO_AddAssign && Op != BO_SubAssign)
3336 return false;
3337
3338 if (!LT || !RT)
3339 return false;
3340
3341 if (!visit(LHS))
3342 return false;
3343
3344 if (!this->emitLoad(*LT, LHS))
3345 return false;
3346
3347 if (!visit(RHS))
3348 return false;
3349
3350 if (Op == BO_AddAssign) {
3351 if (!this->emitAddOffset(*RT, E))
3352 return false;
3353 } else {
3354 if (!this->emitSubOffset(*RT, E))
3355 return false;
3356 }
3357
3358 if (DiscardResult)
3359 return this->emitStorePopPtr(E);
3360 return this->emitStorePtr(E);
3361}
3362
3363template <class Emitter>
3365 const CompoundAssignOperator *E) {
3366 if (E->getType()->isVectorType())
3367 return VisitVectorBinOp(E);
3368
3369 const Expr *LHS = E->getLHS();
3370 const Expr *RHS = E->getRHS();
3371 OptPrimType LHSComputationT = classify(E->getComputationLHSType());
3372 OptPrimType LT = classify(LHS->getType());
3373 OptPrimType RT = classify(RHS->getType());
3374 OptPrimType ResultT = classify(E->getType());
3375
3376 if (!Ctx.getLangOpts().CPlusPlus14)
3377 return this->visit(RHS) && this->visit(LHS) && this->emitError(E);
3378
3379 if (!LT || !RT || !ResultT || !LHSComputationT)
3380 return false;
3381
3382 // Handle floating point operations separately here, since they
3383 // require special care.
3384 if (ResultT == PT_Float || RT == PT_Float)
3386
3387 if (E->getType()->isPointerType())
3389
3390 assert(!E->getType()->isPointerType() && "Handled above");
3391 assert(!E->getType()->isFloatingType() && "Handled above");
3392
3393 if (isSideEffectFree(RHS)) {
3394 if (!visit(LHS))
3395 return false;
3396 if (!this->emitLoad(*LT, E))
3397 return false;
3398 if (LT != LHSComputationT &&
3399 !this->emitIntegralCast(*LT, *LHSComputationT,
3400 E->getComputationLHSType(), E))
3401 return false;
3402 if (!visit(RHS))
3403 return false;
3404 } else {
3405 // C++17 onwards require that we evaluate the RHS first.
3406 // Compute RHS and save it in a temporary variable so we can
3407 // load it again later.
3408 // FIXME: Compound assignments are unsequenced in C, so we might
3409 // have to figure out how to reject them.
3410 if (!visit(RHS))
3411 return false;
3412
3413 unsigned TempOffset =
3414 this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
3415
3416 if (!this->emitSetLocal(*RT, TempOffset, E))
3417 return false;
3418
3419 // Get LHS pointer, load its value and cast it to the
3420 // computation type if necessary.
3421 if (!visit(LHS))
3422 return false;
3423 if (!this->emitLoad(*LT, E))
3424 return false;
3425 if (LT != LHSComputationT &&
3426 !this->emitIntegralCast(*LT, *LHSComputationT,
3427 E->getComputationLHSType(), E))
3428 return false;
3429
3430 // Get the RHS value on the stack.
3431 if (!this->emitGetLocal(*RT, TempOffset, E))
3432 return false;
3433 }
3434
3435 // Perform operation.
3436 switch (E->getOpcode()) {
3437 case BO_AddAssign:
3438 if (!this->emitAdd(*LHSComputationT, E))
3439 return false;
3440 break;
3441 case BO_SubAssign:
3442 if (!this->emitSub(*LHSComputationT, E))
3443 return false;
3444 break;
3445 case BO_MulAssign:
3446 if (!this->emitMul(*LHSComputationT, E))
3447 return false;
3448 break;
3449 case BO_DivAssign:
3450 if (!this->emitDiv(*LHSComputationT, E))
3451 return false;
3452 break;
3453 case BO_RemAssign:
3454 if (!this->emitRem(*LHSComputationT, E))
3455 return false;
3456 break;
3457 case BO_ShlAssign:
3458 if (!this->emitShl(*LHSComputationT, *RT, E))
3459 return false;
3460 break;
3461 case BO_ShrAssign:
3462 if (!this->emitShr(*LHSComputationT, *RT, E))
3463 return false;
3464 break;
3465 case BO_AndAssign:
3466 if (!this->emitBitAnd(*LHSComputationT, E))
3467 return false;
3468 break;
3469 case BO_XorAssign:
3470 if (!this->emitBitXor(*LHSComputationT, E))
3471 return false;
3472 break;
3473 case BO_OrAssign:
3474 if (!this->emitBitOr(*LHSComputationT, E))
3475 return false;
3476 break;
3477 default:
3478 llvm_unreachable("Unimplemented compound assign operator");
3479 }
3480
3481 // And now cast from LHSComputationT to ResultT.
3482 if (ResultT != LHSComputationT &&
3483 !this->emitIntegralCast(*LHSComputationT, *ResultT, E->getType(), E))
3484 return false;
3485
3486 // And store the result in LHS.
3487 if (DiscardResult) {
3488 if (LHS->refersToBitField())
3489 return this->emitStoreBitFieldPop(*ResultT, E);
3490 return this->emitStorePop(*ResultT, E);
3491 }
3492 if (LHS->refersToBitField())
3493 return this->emitStoreBitField(*ResultT, E);
3494 return this->emitStore(*ResultT, E);
3495}
3496
3497template <class Emitter>
3500 const Expr *SubExpr = E->getSubExpr();
3501
3502 return this->delegate(SubExpr) && ES.destroyLocals(E);
3503}
3504
3505template <class Emitter>
3507 const MaterializeTemporaryExpr *E) {
3508 if (Initializing) {
3509 // We already have a value, just initialize that.
3510 return this->delegate(E->getSubExpr());
3511 }
3512 // If we don't end up using the materialized temporary anyway, don't
3513 // bother creating it.
3514 if (DiscardResult)
3515 return this->discard(E->getSubExpr());
3516
3519 const Expr *Inner;
3520 if (!Ctx.getLangOpts().CPlusPlus11)
3521 Inner =
3522 E->getSubExpr()->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
3523 else
3524 Inner = E->getSubExpr();
3525
3526 // If we passed any comma operators, evaluate their LHSs.
3527 for (const Expr *LHS : CommaLHSs) {
3528 if (!this->discard(LHS))
3529 return false;
3530 }
3531
3532 // FIXME: Find a test case where Adjustments matters.
3533
3534 // When we're extending a global variable *or* the storage duration of
3535 // the temporary is explicitly static, create a global variable.
3536 OptPrimType InnerT = classify(Inner);
3537 const ValueDecl *ExtendingDecl = E->getExtendingDecl();
3538 bool IsStatic = E->getStorageDuration() == SD_Static;
3539 if (IsStatic ||
3540 (ExtendingDecl && Context::shouldBeGloballyIndexed(ExtendingDecl))) {
3541 UnsignedOrNone GlobalIndex = P.createGlobal(E, Inner->getType());
3542 if (!GlobalIndex)
3543 return false;
3544
3545 const LifetimeExtendedTemporaryDecl *TempDecl =
3547
3548 if (InnerT) {
3549 if (!this->visit(Inner))
3550 return false;
3551
3552 if (IsStatic) {
3553 assert(TempDecl);
3554 if (!this->emitInitGlobalTemp(*InnerT, *GlobalIndex, TempDecl, E))
3555 return false;
3556 } else {
3557 if (!this->emitInitGlobal(*InnerT, *GlobalIndex, E))
3558 return false;
3559 }
3560 return this->emitGetPtrGlobal(*GlobalIndex, E);
3561 }
3562
3563 if (!this->checkLiteralType(Inner))
3564 return false;
3565 // Non-primitive values.
3566 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3567 return false;
3568 if (!this->visitInitializer(Inner))
3569 return false;
3570 if (IsStatic) {
3571 assert(TempDecl);
3572 return this->emitInitGlobalTempComp(TempDecl, E);
3573 }
3574 return true;
3575 }
3576
3580
3581 // For everyhing else, use local variables.
3582 if (InnerT) {
3583 bool IsConst = Inner->getType().isConstQualified();
3584 bool IsVolatile = Inner->getType().isVolatileQualified();
3585 unsigned LocalIndex =
3586 allocateLocalPrimitive(E, *InnerT, IsConst, IsVolatile, VarScope);
3587 if (!this->VarScope->LocalsAlwaysEnabled &&
3588 !this->emitEnableLocal(LocalIndex, E))
3589 return false;
3590
3591 if (!this->visit(Inner))
3592 return false;
3593 if (!this->emitSetLocal(*InnerT, LocalIndex, E))
3594 return false;
3595
3596 return this->emitGetPtrLocal(LocalIndex, E);
3597 }
3598
3599 if (!this->checkLiteralType(Inner))
3600 return false;
3601
3602 if (UnsignedOrNone LocalIndex =
3603 allocateLocal(E, Inner->getType(), VarScope)) {
3604 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
3605
3606 if (!this->VarScope->LocalsAlwaysEnabled &&
3607 !this->emitEnableLocal(*LocalIndex, E))
3608 return false;
3609
3610 if (!this->emitGetPtrLocal(*LocalIndex, E))
3611 return false;
3612 return this->visitInitializer(Inner);
3613 }
3614 return false;
3615}
3616
3617template <class Emitter>
3619 const CXXBindTemporaryExpr *E) {
3620 const Expr *SubExpr = E->getSubExpr();
3621
3622 if (Initializing)
3623 return this->delegate(SubExpr);
3624
3625 // Make sure we create a temporary even if we're discarding, since that will
3626 // make sure we will also call the destructor.
3627
3628 if (!this->visit(SubExpr))
3629 return false;
3630
3631 if (DiscardResult)
3632 return this->emitPopPtr(E);
3633 return true;
3634}
3635
3636template <class Emitter>
3638 const Expr *Init = E->getInitializer();
3639 if (DiscardResult)
3640 return this->discard(Init);
3641
3642 if (Initializing) {
3643 // We already have a value, just initialize that.
3644 return this->visitInitializer(Init);
3645 }
3646
3647 OptPrimType T = classify(E->getType());
3648 if (E->isFileScope()) {
3649 // Avoid creating a variable if this is a primitive RValue anyway.
3650 if (T && !E->isLValue())
3651 return this->delegate(Init);
3652
3653 UnsignedOrNone GlobalIndex = P.createGlobal(E, E->getType());
3654 if (!GlobalIndex)
3655 return false;
3656
3657 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3658 return false;
3659
3660 // Since this is a global variable, we might've already seen,
3661 // don't do it again.
3662 if (P.isGlobalInitialized(*GlobalIndex))
3663 return true;
3664
3665 if (T) {
3666 if (!this->visit(Init))
3667 return false;
3668 return this->emitInitGlobal(*T, *GlobalIndex, E);
3669 }
3670
3671 return this->visitInitializer(Init);
3672 }
3673
3674 // Otherwise, use a local variable.
3675 if (T && !E->isLValue()) {
3676 // For primitive types, we just visit the initializer.
3677 return this->delegate(Init);
3678 }
3679
3680 unsigned LocalIndex;
3681 if (T)
3682 LocalIndex = this->allocateLocalPrimitive(Init, *T, /*IsConst=*/false);
3683 else if (UnsignedOrNone MaybeIndex = this->allocateLocal(Init))
3684 LocalIndex = *MaybeIndex;
3685 else
3686 return false;
3687
3688 if (!this->emitGetPtrLocal(LocalIndex, E))
3689 return false;
3690
3691 if (T)
3692 return this->visit(Init) && this->emitInit(*T, E);
3693 return this->visitInitializer(Init);
3694}
3695
3696template <class Emitter>
3698 if (DiscardResult)
3699 return true;
3700 if (E->isStoredAsBoolean()) {
3701 if (E->getType()->isBooleanType())
3702 return this->emitConstBool(E->getBoolValue(), E);
3703 return this->emitConst(E->getBoolValue(), E);
3704 }
3705 if (E->isStoredAsComparisonResult()) {
3706 const ComparisonCategoryInfo &CmpInfo =
3707 Ctx.getASTContext().CompCategories.getInfoForType(E->getType());
3708 const auto Result =
3709 ComparisonCategoryResult(E->getAPValue().getInt().getZExtValue());
3710 const Record *R = getRecord(E->getType());
3711 if (!R || R->getNumFields() == 0)
3712 return false;
3713 const Record::Field *Field = R->getField(0U);
3714 assert(Field->T);
3715 if (!this->emitConst(CmpInfo.getValueInfo(Result)->getIntValue(), *Field->T,
3716 E))
3717 return false;
3718 return this->emitInitField(*Field->T, Field->Offset, E);
3719 }
3720
3722 return this->visitAPValue(E->getAPValue(), T, E);
3723}
3724
3725template <class Emitter>
3727 if (DiscardResult)
3728 return true;
3729 return this->emitConst(E->getValue(), E);
3730}
3731
3732template <class Emitter>
3734 if (DiscardResult)
3735 return true;
3736
3737 assert(Initializing);
3738 const Record *R = P.getOrCreateRecord(E->getLambdaClass());
3739 if (!R)
3740 return false;
3741
3742 auto *CaptureInitIt = E->capture_init_begin();
3743 // Initialize all fields (which represent lambda captures) of the
3744 // record with their initializers.
3745 for (const Record::Field &F : R->fields()) {
3746 const Expr *Init = *CaptureInitIt;
3747 if (!Init || Init->containsErrors())
3748 continue;
3749 ++CaptureInitIt;
3750
3751 if (OptPrimType T = classify(Init)) {
3752 if (!this->visit(Init))
3753 return false;
3754
3755 if (!this->emitInitField(*T, F.Offset, E))
3756 return false;
3757 } else {
3758 if (!this->emitGetPtrField(F.Offset, E))
3759 return false;
3760
3761 if (!this->visitInitializerPop(Init))
3762 return false;
3763 }
3764 }
3765
3766 return true;
3767}
3768
3769template <class Emitter>
3771 if (DiscardResult)
3772 return true;
3773
3774 if (!Initializing)
3775 return this->emitGetStringPtr(E, E);
3776 return this->delegate(E->getFunctionName());
3777}
3778
3779template <class Emitter>
3781 if (E->getSubExpr() && !this->discard(E->getSubExpr()))
3782 return false;
3783
3784 return this->emitInvalid(E);
3785}
3786
3787template <class Emitter>
3789 const CXXReinterpretCastExpr *E) {
3790 const Expr *SubExpr = E->getSubExpr();
3791
3792 OptPrimType FromT = classify(SubExpr);
3793 OptPrimType ToT = classify(E);
3794
3795 if (!FromT || !ToT)
3796 return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, E);
3797
3798 if (FromT == PT_Ptr || ToT == PT_Ptr) {
3801 if (!this->emitInvalidCast(CastKind, /*Fatal=*/false, E))
3802 return false;
3803 if (E->getCastKind() == CK_LValueBitCast)
3804 return this->delegate(SubExpr);
3805 return this->VisitCastExpr(E);
3806 }
3807
3808 // Try to actually do the cast.
3809 bool Fatal = (ToT != FromT);
3810 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal, E))
3811 return false;
3812
3813 return this->VisitCastExpr(E);
3814}
3815
3816template <class Emitter>
3818 if (!Ctx.getLangOpts().CPlusPlus20) {
3819 if (!this->emitInvalidCast(CastKind::Dynamic, /*Fatal=*/false, E))
3820 return false;
3821 }
3822
3823 if (E->getCastKind() != CK_Dynamic)
3824 return this->VisitCastExpr(E);
3825
3826 QualType DestType = E->getType();
3827 // "target type must be a reference or pointer type to a defined class"
3828 if (DestType->isRecordType()) {
3829 assert(E->isGLValue());
3830 } else {
3831 assert(DestType->isPointerOrReferenceType());
3832 assert(DestType->isVoidPointerType() ||
3833 DestType->getPointeeType()->isRecordType());
3834 DestType = DestType->getPointeeType();
3835 }
3836
3837 if (!this->visit(E->getSubExpr()))
3838 return false;
3839 if (!this->emitDynamicCast(DestType.getTypePtr(),
3840 /*IsReferenceCast=*/E->isGLValue(), E))
3841 return false;
3842
3843 if (DiscardResult)
3844 return this->emitPopPtr(E);
3845 return true;
3846}
3847
3848template <class Emitter>
3850 assert(E->getType()->isBooleanType());
3851
3852 if (DiscardResult)
3853 return true;
3854 return this->emitConstBool(E->getValue(), E);
3855}
3856
3857template <class Emitter>
3859 QualType T = E->getType();
3860 assert(!canClassify(T));
3861
3862 if (T->isRecordType()) {
3863 const CXXConstructorDecl *Ctor = E->getConstructor();
3864
3865 // If we're discarding a construct expression, we still need
3866 // to allocate a variable and call the constructor and destructor.
3867 if (DiscardResult) {
3868 if (Ctor->isTrivial())
3869 return true;
3870 assert(!Initializing);
3871 UnsignedOrNone LocalIndex = allocateLocal(E);
3872
3873 if (!LocalIndex)
3874 return false;
3875
3876 if (!this->emitGetPtrLocal(*LocalIndex, E))
3877 return false;
3878 }
3879
3880 // Trivial copy/move constructor. Avoid copy.
3881 if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&
3882 Ctor->isTrivial() &&
3883 E->getArg(0)->isTemporaryObject(Ctx.getASTContext(),
3884 T->getAsCXXRecordDecl()))
3885 return this->visitInitializer(E->getArg(0));
3886
3887 // Zero initialization.
3888 bool ZeroInit = E->requiresZeroInitialization();
3889 if (ZeroInit) {
3890 const Record *R = getRecord(E->getType());
3891 if (!R)
3892 return false;
3893
3894 if (!this->visitZeroRecordInitializer(R, E))
3895 return false;
3896
3897 // If the constructor is trivial anyway, we're done.
3898 if (Ctor->isTrivial())
3899 return true;
3900 }
3901
3902 // Avoid materializing a temporary for an elidable copy/move constructor.
3903 if (!ZeroInit && E->isElidable()) {
3904 const Expr *SrcObj = E->getArg(0);
3905 assert(SrcObj->isTemporaryObject(Ctx.getASTContext(), Ctor->getParent()));
3906 assert(Ctx.getASTContext().hasSameUnqualifiedType(E->getType(),
3907 SrcObj->getType()));
3908 if (const auto *ME = dyn_cast<MaterializeTemporaryExpr>(SrcObj)) {
3909 if (!this->emitCheckFunctionDecl(Ctor, E))
3910 return false;
3911 return this->visitInitializer(ME->getSubExpr());
3912 }
3913 }
3914
3915 const Function *Func = getFunction(Ctor);
3916
3917 if (!Func)
3918 return false;
3919
3920 assert(Func->hasThisPointer());
3921 assert(!Func->hasRVO());
3922
3923 // The This pointer is already on the stack because this is an initializer,
3924 // but we need to dup() so the call() below has its own copy.
3925 if (!this->emitDupPtr(E))
3926 return false;
3927
3928 // Constructor arguments.
3929 for (const auto *Arg : E->arguments()) {
3930 if (!this->visit(Arg))
3931 return false;
3932 }
3933
3934 if (Func->isVariadic()) {
3935 uint32_t VarArgSize = 0;
3936 unsigned NumParams = Func->getNumWrittenParams();
3937 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I) {
3938 VarArgSize +=
3939 align(primSize(classify(E->getArg(I)->getType()).value_or(PT_Ptr)));
3940 }
3941 if (!this->emitCallVar(Func, VarArgSize, E))
3942 return false;
3943 } else {
3944 if (!this->emitCall(Func, 0, E)) {
3945 // When discarding, we don't need the result anyway, so clean up
3946 // the instance dup we did earlier in case surrounding code wants
3947 // to keep evaluating.
3948 if (DiscardResult)
3949 (void)this->emitPopPtr(E);
3950 return false;
3951 }
3952 }
3953
3954 if (DiscardResult)
3955 return this->emitPopPtr(E);
3956 return true;
3957 }
3958
3959 if (T->isArrayType()) {
3960 const Function *Func = getFunction(E->getConstructor());
3961 if (!Func)
3962 return false;
3963
3964 if (!this->emitDupPtr(E))
3965 return false;
3966
3967 std::function<bool(QualType)> initArrayDimension;
3968 initArrayDimension = [&](QualType T) -> bool {
3969 if (!T->isArrayType()) {
3970 // Constructor arguments.
3971 for (const auto *Arg : E->arguments()) {
3972 if (!this->visit(Arg))
3973 return false;
3974 }
3975
3976 return this->emitCall(Func, 0, E);
3977 }
3978
3979 const ConstantArrayType *CAT =
3980 Ctx.getASTContext().getAsConstantArrayType(T);
3981 if (!CAT)
3982 return false;
3983 QualType ElemTy = CAT->getElementType();
3984 unsigned NumElems = CAT->getZExtSize();
3985 for (size_t I = 0; I != NumElems; ++I) {
3986 if (!this->emitConstUint64(I, E))
3987 return false;
3988 if (!this->emitArrayElemPtrUint64(E))
3989 return false;
3990 if (!initArrayDimension(ElemTy))
3991 return false;
3992 }
3993 return this->emitPopPtr(E);
3994 };
3995
3996 return initArrayDimension(E->getType());
3997 }
3998
3999 return false;
4000}
4001
4002template <class Emitter>
4004 if (DiscardResult)
4005 return true;
4006
4007 const APValue Val =
4008 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
4009
4010 // Things like __builtin_LINE().
4011 if (E->getType()->isIntegerType()) {
4012 assert(Val.isInt());
4013 const APSInt &I = Val.getInt();
4014 return this->emitConst(I, E);
4015 }
4016 // Otherwise, the APValue is an LValue, with only one element.
4017 // Theoretically, we don't need the APValue at all of course.
4018 assert(E->getType()->isPointerType());
4019 assert(Val.isLValue());
4020 const APValue::LValueBase &Base = Val.getLValueBase();
4021 if (const Expr *LValueExpr = Base.dyn_cast<const Expr *>())
4022 return this->visit(LValueExpr);
4023
4024 // Otherwise, we have a decl (which is the case for
4025 // __builtin_source_location).
4026 assert(Base.is<const ValueDecl *>());
4027 assert(Val.getLValuePath().size() == 0);
4028 const auto *BaseDecl = Base.dyn_cast<const ValueDecl *>();
4029 assert(BaseDecl);
4030
4031 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
4032
4033 UnsignedOrNone GlobalIndex = P.getOrCreateGlobal(UGCD);
4034 if (!GlobalIndex)
4035 return false;
4036
4037 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4038 return false;
4039
4040 const Record *R = getRecord(E->getType());
4041 const APValue &V = UGCD->getValue();
4042 for (unsigned I = 0, N = R->getNumFields(); I != N; ++I) {
4043 const Record::Field *F = R->getField(I);
4044 const APValue &FieldValue = V.getStructField(I);
4045
4046 if (!this->visitAPValue(FieldValue, *F->T, E))
4047 return false;
4048 if (!this->emitInitField(*F->T, F->Offset, E))
4049 return false;
4050 }
4051
4052 // Leave the pointer to the global on the stack.
4053 return true;
4054}
4055
4056template <class Emitter>
4058 unsigned N = E->getNumComponents();
4059 if (N == 0)
4060 return false;
4061
4062 for (unsigned I = 0; I != N; ++I) {
4063 const OffsetOfNode &Node = E->getComponent(I);
4064 if (Node.getKind() == OffsetOfNode::Array) {
4065 const Expr *ArrayIndexExpr = E->getIndexExpr(Node.getArrayExprIndex());
4066 PrimType IndexT = classifyPrim(ArrayIndexExpr->getType());
4067
4068 if (DiscardResult) {
4069 if (!this->discard(ArrayIndexExpr))
4070 return false;
4071 continue;
4072 }
4073
4074 if (IndexT == PT_IntAP || IndexT == PT_IntAPS) {
4075 if (!this->visit(ArrayIndexExpr))
4076 return false;
4077 if (!this->emitCastAPToOffsetIndex(IndexT, E))
4078 return false;
4079 continue;
4080 }
4081 if (!this->visit(ArrayIndexExpr))
4082 return false;
4083 // Cast to Sint64.
4084 if (IndexT != PT_Sint64) {
4085 if (!this->emitCast(IndexT, PT_Sint64, E))
4086 return false;
4087 }
4088 }
4089 }
4090
4091 if (DiscardResult)
4092 return true;
4093
4095 return this->emitOffsetOf(T, E, E);
4096}
4097
4098template <class Emitter>
4100 const CXXScalarValueInitExpr *E) {
4101 QualType Ty = E->getType();
4102
4103 if (DiscardResult || Ty->isVoidType())
4104 return true;
4105
4106 if (OptPrimType T = classify(Ty))
4107 return this->visitZeroInitializer(*T, Ty, E);
4108
4109 if (Ty->isAnyComplexType() || Ty->isVectorType()) {
4110 if (!Initializing) {
4111 UnsignedOrNone LocalIndex = allocateLocal(E);
4112 if (!LocalIndex)
4113 return false;
4114 if (!this->emitGetPtrLocal(*LocalIndex, E))
4115 return false;
4116 }
4117
4118 QualType ElemQT;
4119 unsigned NumElems;
4120 if (const auto *CT = Ty->getAs<ComplexType>()) {
4121 NumElems = 2;
4122 ElemQT = CT->getElementType();
4123 } else {
4124 const auto *VT = Ty->castAs<VectorType>();
4125 NumElems = VT->getNumElements();
4126 ElemQT = VT->getElementType();
4127 }
4128
4129 PrimType ElemT = classifyPrim(ElemQT);
4130
4131 // Initialize all fields to 0.
4132 for (unsigned I = 0; I != NumElems; ++I) {
4133 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
4134 return false;
4135 if (!this->emitInitElem(ElemT, I, E))
4136 return false;
4137 }
4138 return true;
4139 }
4140
4141 return false;
4142}
4143
4144template <class Emitter>
4146 return this->emitConst(E->getPackLength(), E);
4147}
4148
4149template <class Emitter>
4154
4155template <class Emitter>
4157 return this->delegate(E->getChosenSubExpr());
4158}
4159
4160template <class Emitter>
4162 if (DiscardResult)
4163 return true;
4164
4165 return this->emitConst(E->getValue(), E);
4166}
4167
4168template <class Emitter>
4170 const CXXInheritedCtorInitExpr *E) {
4171 const CXXConstructorDecl *Ctor = E->getConstructor();
4172 assert(!Ctor->isTrivial() &&
4173 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
4174 const Function *F = this->getFunction(Ctor);
4175 if (!F)
4176 return false;
4177 assert(!F->hasRVO());
4178 assert(F->hasThisPointer());
4179
4180 if (!this->emitDupPtr(SourceInfo{}))
4181 return false;
4182
4183 // Forward all arguments of the current function (which should be a
4184 // constructor itself) to the inherited ctor.
4185 // This is necessary because the calling code has pushed the pointer
4186 // of the correct base for us already, but the arguments need
4187 // to come after.
4188 unsigned ParamIndex = 0;
4189 for (const ParmVarDecl *PD : Ctor->parameters()) {
4190 PrimType PT = this->classify(PD->getType()).value_or(PT_Ptr);
4191
4192 if (!this->emitGetParam(PT, ParamIndex, E))
4193 return false;
4194 ++ParamIndex;
4195 }
4196
4197 return this->emitCall(F, 0, E);
4198}
4199
4200// FIXME: This function has become rather unwieldy, especially
4201// the part where we initialize an array allocation of dynamic size.
4202template <class Emitter>
4204 assert(classifyPrim(E->getType()) == PT_Ptr);
4205 const Expr *Init = E->getInitializer();
4206 QualType ElementType = E->getAllocatedType();
4207 OptPrimType ElemT = classify(ElementType);
4208 unsigned PlacementArgs = E->getNumPlacementArgs();
4209 const FunctionDecl *OperatorNew = E->getOperatorNew();
4210 const Expr *PlacementDest = nullptr;
4211 bool IsNoThrow = false;
4212
4213 if (E->containsErrors())
4214 return false;
4215
4216 if (PlacementArgs != 0) {
4217 // FIXME: There is no restriction on this, but it's not clear that any
4218 // other form makes any sense. We get here for cases such as:
4219 //
4220 // new (std::align_val_t{N}) X(int)
4221 //
4222 // (which should presumably be valid only if N is a multiple of
4223 // alignof(int), and in any case can't be deallocated unless N is
4224 // alignof(X) and X has new-extended alignment).
4225 if (PlacementArgs == 1) {
4226 const Expr *Arg1 = E->getPlacementArg(0);
4227 if (Arg1->getType()->isNothrowT()) {
4228 if (!this->discard(Arg1))
4229 return false;
4230 IsNoThrow = true;
4231 } else {
4232 // Invalid unless we have C++26 or are in a std:: function.
4233 if (!this->emitInvalidNewDeleteExpr(E, E))
4234 return false;
4235
4236 // If we have a placement-new destination, we'll later use that instead
4237 // of allocating.
4238 if (OperatorNew->isReservedGlobalPlacementOperator())
4239 PlacementDest = Arg1;
4240 }
4241 } else {
4242 // Always invalid.
4243 return this->emitInvalid(E);
4244 }
4245 } else if (!OperatorNew
4246 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4247 return this->emitInvalidNewDeleteExpr(E, E);
4248
4249 const Descriptor *Desc;
4250 if (!PlacementDest) {
4251 if (ElemT) {
4252 if (E->isArray())
4253 Desc = nullptr; // We're not going to use it in this case.
4254 else
4255 Desc = P.createDescriptor(E, *ElemT);
4256 } else {
4257 Desc = P.createDescriptor(E, ElementType.getTypePtr(), /*IsConst=*/false,
4258 /*IsTemporary=*/false, /*IsMutable=*/false,
4259 /*IsVolatile=*/false, Init);
4260 }
4261 }
4262
4263 if (E->isArray()) {
4264 std::optional<const Expr *> ArraySizeExpr = E->getArraySize();
4265 if (!ArraySizeExpr)
4266 return false;
4267
4268 const Expr *Stripped = *ArraySizeExpr;
4269 for (; auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
4270 Stripped = ICE->getSubExpr())
4271 if (ICE->getCastKind() != CK_NoOp &&
4272 ICE->getCastKind() != CK_IntegralCast)
4273 break;
4274
4275 PrimType SizeT = classifyPrim(Stripped->getType());
4276
4277 // Save evaluated array size to a variable.
4278 unsigned ArrayLen =
4279 allocateLocalPrimitive(Stripped, SizeT, /*IsConst=*/false);
4280 if (!this->visit(Stripped))
4281 return false;
4282 if (!this->emitSetLocal(SizeT, ArrayLen, E))
4283 return false;
4284
4285 if (PlacementDest) {
4286 if (!this->visit(PlacementDest))
4287 return false;
4288 if (!this->emitGetLocal(SizeT, ArrayLen, E))
4289 return false;
4290 if (!this->emitCheckNewTypeMismatchArray(SizeT, E, E))
4291 return false;
4292 } else {
4293 if (!this->emitGetLocal(SizeT, ArrayLen, E))
4294 return false;
4295
4296 if (ElemT) {
4297 // N primitive elements.
4298 if (!this->emitAllocN(SizeT, *ElemT, E, IsNoThrow, E))
4299 return false;
4300 } else {
4301 // N Composite elements.
4302 if (!this->emitAllocCN(SizeT, Desc, IsNoThrow, E))
4303 return false;
4304 }
4305 }
4306
4307 if (Init) {
4308 QualType InitType = Init->getType();
4309 size_t StaticInitElems = 0;
4310 const Expr *DynamicInit = nullptr;
4311 OptPrimType ElemT;
4312
4313 if (const ConstantArrayType *CAT =
4314 Ctx.getASTContext().getAsConstantArrayType(InitType)) {
4315 StaticInitElems = CAT->getZExtSize();
4316 // Initialize the first S element from the initializer.
4317 if (!this->visitInitializer(Init))
4318 return false;
4319
4320 if (const auto *ILE = dyn_cast<InitListExpr>(Init)) {
4321 if (ILE->hasArrayFiller())
4322 DynamicInit = ILE->getArrayFiller();
4323 else if (StaticInitElems > 0 && isa<StringLiteral>(ILE->getInit(0)))
4324 ElemT = classifyPrim(CAT->getElementType());
4325 }
4326 }
4327
4328 // The initializer initializes a certain number of elements, S.
4329 // However, the complete number of elements, N, might be larger than that.
4330 // In this case, we need to get an initializer for the remaining elements.
4331 // There are three cases:
4332 // 1) For the form 'new Struct[n];', the initializer is a
4333 // CXXConstructExpr and its type is an IncompleteArrayType.
4334 // 2) For the form 'new Struct[n]{1,2,3}', the initializer is an
4335 // InitListExpr and the initializer for the remaining elements
4336 // is the array filler.
4337 // 3) StringLiterals don't have an array filler, so we need to zero
4338 // the remaining elements.
4339
4340 if (DynamicInit || ElemT || InitType->isIncompleteArrayType()) {
4341 const Function *CtorFunc = nullptr;
4342 if (const auto *CE = dyn_cast<CXXConstructExpr>(Init)) {
4343 CtorFunc = getFunction(CE->getConstructor());
4344 if (!CtorFunc)
4345 return false;
4346 } else if (!DynamicInit && !ElemT)
4347 DynamicInit = Init;
4348
4349 LabelTy EndLabel = this->getLabel();
4350 LabelTy StartLabel = this->getLabel();
4351
4352 // In the nothrow case, the alloc above might have returned nullptr.
4353 // Don't call any constructors that case.
4354 if (IsNoThrow) {
4355 if (!this->emitDupPtr(E))
4356 return false;
4357 if (!this->emitIsNonNullPtr(E))
4358 return false;
4359 if (!this->jumpFalse(EndLabel, E))
4360 return false;
4361 }
4362
4363 // Create loop variables.
4364 unsigned Iter =
4365 allocateLocalPrimitive(Stripped, SizeT, /*IsConst=*/false);
4366 if (!this->emitConst(StaticInitElems, SizeT, E))
4367 return false;
4368 if (!this->emitSetLocal(SizeT, Iter, E))
4369 return false;
4370
4371 this->fallthrough(StartLabel);
4372 this->emitLabel(StartLabel);
4373 // Condition. Iter < ArrayLen?
4374 if (!this->emitGetLocal(SizeT, Iter, E))
4375 return false;
4376 if (!this->emitGetLocal(SizeT, ArrayLen, E))
4377 return false;
4378 if (!this->emitLT(SizeT, E))
4379 return false;
4380 if (!this->jumpFalse(EndLabel, E))
4381 return false;
4382
4383 // Pointer to the allocated array is already on the stack.
4384 if (!this->emitGetLocal(SizeT, Iter, E))
4385 return false;
4386 if (!this->emitArrayElemPtr(SizeT, E))
4387 return false;
4388
4389 if (isa_and_nonnull<ImplicitValueInitExpr>(DynamicInit) &&
4390 DynamicInit->getType()->isArrayType()) {
4391 QualType ElemType =
4392 DynamicInit->getType()->getAsArrayTypeUnsafe()->getElementType();
4393 if (OptPrimType InitT = classify(ElemType)) {
4394 if (!this->visitZeroInitializer(*InitT, ElemType, E))
4395 return false;
4396 if (!this->emitStorePop(*InitT, E))
4397 return false;
4398 } else {
4399 assert(ElemType->isArrayType());
4400 if (!this->visitZeroArrayInitializer(ElemType, E))
4401 return false;
4402 }
4403 } else if (DynamicInit) {
4404 if (OptPrimType InitT = classify(DynamicInit)) {
4405 if (!this->visit(DynamicInit))
4406 return false;
4407 if (!this->emitStorePop(*InitT, E))
4408 return false;
4409 } else {
4410 if (!this->visitInitializerPop(DynamicInit))
4411 return false;
4412 }
4413 } else if (ElemT) {
4414 if (!this->visitZeroInitializer(
4415 *ElemT, InitType->getAsArrayTypeUnsafe()->getElementType(),
4416 Init))
4417 return false;
4418 if (!this->emitStorePop(*ElemT, E))
4419 return false;
4420 } else {
4421 assert(CtorFunc);
4422 if (!this->emitCall(CtorFunc, 0, E))
4423 return false;
4424 }
4425
4426 // ++Iter;
4427 if (!this->emitGetPtrLocal(Iter, E))
4428 return false;
4429 if (!this->emitIncPop(SizeT, false, E))
4430 return false;
4431
4432 if (!this->jump(StartLabel, E))
4433 return false;
4434
4435 this->fallthrough(EndLabel);
4436 this->emitLabel(EndLabel);
4437 }
4438 }
4439 } else { // Non-array.
4440 if (PlacementDest) {
4441 if (!this->visit(PlacementDest))
4442 return false;
4443 if (!this->emitCheckNewTypeMismatch(E, E))
4444 return false;
4445
4446 } else {
4447 // Allocate just one element.
4448 if (!this->emitAlloc(Desc, E))
4449 return false;
4450 }
4451
4452 if (Init) {
4453 if (ElemT) {
4454 if (!this->visit(Init))
4455 return false;
4456
4457 if (!this->emitInit(*ElemT, E))
4458 return false;
4459 } else {
4460 // Composite.
4461 if (!this->visitInitializer(Init))
4462 return false;
4463 }
4464 }
4465 }
4466
4467 if (DiscardResult)
4468 return this->emitPopPtr(E);
4469
4470 return true;
4471}
4472
4473template <class Emitter>
4475 if (E->containsErrors())
4476 return false;
4477 const FunctionDecl *OperatorDelete = E->getOperatorDelete();
4478
4479 if (!OperatorDelete->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4480 return this->emitInvalidNewDeleteExpr(E, E);
4481
4482 // Arg must be an lvalue.
4483 if (!this->visit(E->getArgument()))
4484 return false;
4485
4486 return this->emitFree(E->isArrayForm(), E->isGlobalDelete(), E);
4487}
4488
4489template <class Emitter>
4491 if (DiscardResult)
4492 return true;
4493
4494 const Function *Func = nullptr;
4495 if (const Function *F = Ctx.getOrCreateObjCBlock(E))
4496 Func = F;
4497
4498 if (!Func)
4499 return false;
4500 return this->emitGetFnPtr(Func, E);
4501}
4502
4503template <class Emitter>
4505 const Type *TypeInfoType = E->getType().getTypePtr();
4506
4507 auto canonType = [](const Type *T) {
4508 return T->getCanonicalTypeUnqualified().getTypePtr();
4509 };
4510
4511 if (!E->isPotentiallyEvaluated()) {
4512 if (DiscardResult)
4513 return true;
4514
4515 if (E->isTypeOperand())
4516 return this->emitGetTypeid(
4517 canonType(E->getTypeOperand(Ctx.getASTContext()).getTypePtr()),
4518 TypeInfoType, E);
4519
4520 return this->emitGetTypeid(
4521 canonType(E->getExprOperand()->getType().getTypePtr()), TypeInfoType,
4522 E);
4523 }
4524
4525 // Otherwise, we need to evaluate the expression operand.
4526 assert(E->getExprOperand());
4527 assert(E->getExprOperand()->isLValue());
4528
4529 if (!Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(E))
4530 return false;
4531
4532 if (!this->visit(E->getExprOperand()))
4533 return false;
4534
4535 if (!this->emitGetTypeidPtr(TypeInfoType, E))
4536 return false;
4537 if (DiscardResult)
4538 return this->emitPopPtr(E);
4539 return true;
4540}
4541
4542template <class Emitter>
4544 const ObjCDictionaryLiteral *E) {
4546 return this->emitDummyPtr(E, E);
4547 return this->emitError(E);
4548}
4549
4550template <class Emitter>
4553 return this->emitDummyPtr(E, E);
4554 return this->emitError(E);
4555}
4556
4557template <class Emitter>
4559 assert(Ctx.getLangOpts().CPlusPlus);
4560 return this->emitConstBool(E->getValue(), E);
4561}
4562
4563template <class Emitter>
4565 if (DiscardResult)
4566 return true;
4567 assert(!Initializing);
4568
4569 const MSGuidDecl *GuidDecl = E->getGuidDecl();
4570 const RecordDecl *RD = GuidDecl->getType()->getAsRecordDecl();
4571 assert(RD);
4572 // If the definiton of the result type is incomplete, just return a dummy.
4573 // If (and when) that is read from, we will fail, but not now.
4574 if (!RD->isCompleteDefinition())
4575 return this->emitDummyPtr(GuidDecl, E);
4576
4577 UnsignedOrNone GlobalIndex = P.getOrCreateGlobal(GuidDecl);
4578 if (!GlobalIndex)
4579 return false;
4580 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4581 return false;
4582
4583 assert(this->getRecord(E->getType()));
4584
4585 const APValue &V = GuidDecl->getAsAPValue();
4586 if (V.getKind() == APValue::None)
4587 return true;
4588
4589 assert(V.isStruct());
4590 assert(V.getStructNumBases() == 0);
4591 if (!this->visitAPValueInitializer(V, E, E->getType()))
4592 return false;
4593
4594 return this->emitFinishInit(E);
4595}
4596
4597template <class Emitter>
4599 assert(classifyPrim(E->getType()) == PT_Bool);
4600 if (E->isValueDependent())
4601 return false;
4602 if (DiscardResult)
4603 return true;
4604 return this->emitConstBool(E->isSatisfied(), E);
4605}
4606
4607template <class Emitter>
4609 const ConceptSpecializationExpr *E) {
4610 assert(classifyPrim(E->getType()) == PT_Bool);
4611 if (DiscardResult)
4612 return true;
4613 return this->emitConstBool(E->isSatisfied(), E);
4614}
4615
4616template <class Emitter>
4621
4622template <class Emitter>
4624
4625 for (const Expr *SemE : E->semantics()) {
4626 if (auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
4627 if (SemE == E->getResultExpr())
4628 return false;
4629
4630 if (OVE->isUnique())
4631 continue;
4632
4633 if (!this->discard(OVE))
4634 return false;
4635 } else if (SemE == E->getResultExpr()) {
4636 if (!this->delegate(SemE))
4637 return false;
4638 } else {
4639 if (!this->discard(SemE))
4640 return false;
4641 }
4642 }
4643 return true;
4644}
4645
4646template <class Emitter>
4650
4651template <class Emitter>
4653 return this->emitError(E);
4654}
4655
4656template <class Emitter>
4658 assert(E->getType()->isVoidPointerType());
4659 if (DiscardResult)
4660 return true;
4661
4662 return this->emitDummyPtr(E, E);
4663}
4664
4665template <class Emitter>
4666bool Compiler<Emitter>::emitVectorConversion(const Expr *Src, const Expr *E) {
4667 if (Src->containsErrors())
4668 return false;
4669
4670 const auto *VT = E->getType()->castAs<VectorType>();
4671 QualType ElemType = VT->getElementType();
4672 PrimType ElemT = classifyPrim(ElemType);
4673 QualType SrcType = Src->getType();
4674 PrimType SrcElemT = classifyVectorElementType(SrcType);
4675
4676 if (!Initializing) {
4677 UnsignedOrNone LocalIndex = allocateLocal(E);
4678 if (!LocalIndex)
4679 return false;
4680 if (!this->emitGetPtrLocal(*LocalIndex, E))
4681 return false;
4682 }
4683
4684 unsigned SrcOffset =
4685 this->allocateLocalPrimitive(Src, PT_Ptr, /*IsConst=*/true);
4686 if (!this->visit(Src))
4687 return false;
4688 if (!this->emitSetLocal(PT_Ptr, SrcOffset, E))
4689 return false;
4690
4691 for (unsigned I = 0; I != VT->getNumElements(); ++I) {
4692 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
4693 return false;
4694 if (!this->emitArrayElemPop(SrcElemT, I, E))
4695 return false;
4696
4697 // Cast to the desired result element type.
4698 if (SrcElemT != ElemT) {
4699 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
4700 return false;
4701 } else if (ElemType->isFloatingType() && SrcType != ElemType) {
4702 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
4703 if (!this->emitCastFP(TargetSemantics, getRoundingMode(E), E))
4704 return false;
4705 }
4706 if (!this->emitInitElem(ElemT, I, E))
4707 return false;
4708 }
4709 return true;
4710}
4711
4712template <class Emitter>
4714 return emitVectorConversion(E->getSrcExpr(), E);
4715}
4716
4717template <class Emitter>
4719 // FIXME: Unary shuffle with mask not currently supported.
4720 if (E->getNumSubExprs() == 2)
4721 return this->emitInvalid(E);
4722
4723 assert(E->getNumSubExprs() > 2);
4724
4725 const Expr *Vecs[] = {E->getExpr(0), E->getExpr(1)};
4726 const VectorType *VT = Vecs[0]->getType()->castAs<VectorType>();
4727 PrimType ElemT = classifyPrim(VT->getElementType());
4728 unsigned NumInputElems = VT->getNumElements();
4729 unsigned NumOutputElems = E->getNumSubExprs() - 2;
4730 assert(NumOutputElems > 0);
4731
4732 if (!Initializing) {
4733 UnsignedOrNone LocalIndex = allocateLocal(E);
4734 if (!LocalIndex)
4735 return false;
4736 if (!this->emitGetPtrLocal(*LocalIndex, E))
4737 return false;
4738 }
4739
4740 // Save both input vectors to a local variable.
4741 unsigned VectorOffsets[2];
4742 for (unsigned I = 0; I != 2; ++I) {
4743 VectorOffsets[I] =
4744 this->allocateLocalPrimitive(Vecs[I], PT_Ptr, /*IsConst=*/true);
4745 if (!this->visit(Vecs[I]))
4746 return false;
4747 if (!this->emitSetLocal(PT_Ptr, VectorOffsets[I], E))
4748 return false;
4749 }
4750 for (unsigned I = 0; I != NumOutputElems; ++I) {
4751 APSInt ShuffleIndex = E->getShuffleMaskIdx(I);
4752 assert(ShuffleIndex >= -1);
4753 if (ShuffleIndex == -1)
4754 return this->emitInvalidShuffleVectorIndex(I, E);
4755
4756 assert(ShuffleIndex < (NumInputElems * 2));
4757 if (!this->emitGetLocal(PT_Ptr,
4758 VectorOffsets[ShuffleIndex >= NumInputElems], E))
4759 return false;
4760 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
4761 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
4762 return false;
4763
4764 if (!this->emitInitElem(ElemT, I, E))
4765 return false;
4766 }
4767
4768 if (DiscardResult)
4769 return this->emitPopPtr(E);
4770
4771 return true;
4772}
4773
4774template <class Emitter>
4776 const ExtVectorElementExpr *E) {
4777 const Expr *Base = E->getBase();
4778 assert(
4779 Base->getType()->isVectorType() ||
4780 Base->getType()->getAs<PointerType>()->getPointeeType()->isVectorType());
4781
4783 E->getEncodedElementAccess(Indices);
4784
4785 if (Indices.size() == 1) {
4786 if (!this->visit(Base))
4787 return false;
4788
4789 if (E->isGLValue()) {
4790 if (!this->emitConstUint32(Indices[0], E))
4791 return false;
4792 return this->emitArrayElemPtrPop(PT_Uint32, E);
4793 }
4794 // Else, also load the value.
4795 return this->emitArrayElemPop(classifyPrim(E->getType()), Indices[0], E);
4796 }
4797
4798 // Create a local variable for the base.
4799 unsigned BaseOffset = allocateLocalPrimitive(Base, PT_Ptr, /*IsConst=*/true);
4800 if (!this->visit(Base))
4801 return false;
4802 if (!this->emitSetLocal(PT_Ptr, BaseOffset, E))
4803 return false;
4804
4805 // Now the vector variable for the return value.
4806 if (!Initializing) {
4807 UnsignedOrNone ResultIndex = allocateLocal(E);
4808 if (!ResultIndex)
4809 return false;
4810 if (!this->emitGetPtrLocal(*ResultIndex, E))
4811 return false;
4812 }
4813
4814 assert(Indices.size() == E->getType()->getAs<VectorType>()->getNumElements());
4815
4816 PrimType ElemT =
4818 uint32_t DstIndex = 0;
4819 for (uint32_t I : Indices) {
4820 if (!this->emitGetLocal(PT_Ptr, BaseOffset, E))
4821 return false;
4822 if (!this->emitArrayElemPop(ElemT, I, E))
4823 return false;
4824 if (!this->emitInitElem(ElemT, DstIndex, E))
4825 return false;
4826 ++DstIndex;
4827 }
4828
4829 // Leave the result pointer on the stack.
4830 assert(!DiscardResult);
4831 return true;
4832}
4833
4834template <class Emitter>
4836 const Expr *SubExpr = E->getSubExpr();
4838 return this->discard(SubExpr) && this->emitInvalid(E);
4839
4840 if (DiscardResult)
4841 return true;
4842
4843 assert(classifyPrim(E) == PT_Ptr);
4844 return this->emitDummyPtr(E, E);
4845}
4846
4847template <class Emitter>
4849 const CXXStdInitializerListExpr *E) {
4850 const Expr *SubExpr = E->getSubExpr();
4852 Ctx.getASTContext().getAsConstantArrayType(SubExpr->getType());
4853 const Record *R = getRecord(E->getType());
4854 assert(Initializing);
4855 assert(SubExpr->isGLValue());
4856
4857 if (!this->visit(SubExpr))
4858 return false;
4859 if (!this->emitConstUint8(0, E))
4860 return false;
4861 if (!this->emitArrayElemPtrPopUint8(E))
4862 return false;
4863 if (!this->emitInitFieldPtr(R->getField(0u)->Offset, E))
4864 return false;
4865
4866 PrimType SecondFieldT = *R->getField(1u)->T;
4867 if (isIntegerOrBoolType(SecondFieldT)) {
4868 if (!this->emitConst(ArrayType->getSize(), SecondFieldT, E))
4869 return false;
4870 return this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E);
4871 }
4872 assert(SecondFieldT == PT_Ptr);
4873
4874 if (!this->emitGetFieldPtr(R->getField(0u)->Offset, E))
4875 return false;
4876 if (!this->emitExpandPtr(E))
4877 return false;
4878 if (!this->emitConst(ArrayType->getSize(), PT_Uint64, E))
4879 return false;
4880 if (!this->emitArrayElemPtrPop(PT_Uint64, E))
4881 return false;
4882 return this->emitInitFieldPtr(R->getField(1u)->Offset, E);
4883}
4884
4885template <class Emitter>
4887 LocalScope<Emitter> BS(this);
4888 llvm::SaveAndRestore StmtExprSAR(this->InStmtExpr, true);
4889
4890 const CompoundStmt *CS = E->getSubStmt();
4891 const Stmt *Result = CS->body_back();
4892 for (const Stmt *S : CS->body()) {
4893 if (S != Result) {
4894 if (!this->visitStmt(S))
4895 return false;
4896 continue;
4897 }
4898
4899 assert(S == Result);
4900 if (const Expr *ResultExpr = dyn_cast<Expr>(S))
4901 return this->delegate(ResultExpr);
4902 if (!this->visitStmt(S))
4903 return false;
4904 return this->emitUnsupported(E);
4905 }
4906
4907 return BS.destroyLocals();
4908}
4909
4910template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {
4911 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
4912 /*NewInitializing=*/false, /*ToLValue=*/false);
4913 return this->Visit(E);
4914}
4915
4916template <class Emitter> bool Compiler<Emitter>::delegate(const Expr *E) {
4917 // We're basically doing:
4918 // OptionScope<Emitter> Scope(this, DicardResult, Initializing, ToLValue);
4919 // but that's unnecessary of course.
4920 return this->Visit(E);
4921}
4922
4924 if (const auto *PE = dyn_cast<ParenExpr>(E))
4925 return stripCheckedDerivedToBaseCasts(PE->getSubExpr());
4926
4927 if (const auto *CE = dyn_cast<CastExpr>(E);
4928 CE &&
4929 (CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp))
4930 return stripCheckedDerivedToBaseCasts(CE->getSubExpr());
4931
4932 return E;
4933}
4934
4935static const Expr *stripDerivedToBaseCasts(const Expr *E) {
4936 if (const auto *PE = dyn_cast<ParenExpr>(E))
4937 return stripDerivedToBaseCasts(PE->getSubExpr());
4938
4939 if (const auto *CE = dyn_cast<CastExpr>(E);
4940 CE && (CE->getCastKind() == CK_DerivedToBase ||
4941 CE->getCastKind() == CK_UncheckedDerivedToBase ||
4942 CE->getCastKind() == CK_NoOp))
4943 return stripDerivedToBaseCasts(CE->getSubExpr());
4944
4945 return E;
4946}
4947
4948template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) {
4949 if (E->getType().isNull())
4950 return false;
4951
4952 if (E->getType()->isVoidType())
4953 return this->discard(E);
4954
4955 // Create local variable to hold the return value.
4956 if (!E->isGLValue() && !canClassify(E->getType())) {
4957 UnsignedOrNone LocalIndex = allocateLocal(
4959 if (!LocalIndex)
4960 return false;
4961
4962 if (!this->emitGetPtrLocal(*LocalIndex, E))
4963 return false;
4964 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
4965 return this->visitInitializer(E);
4966 }
4967
4968 // Otherwise,we have a primitive return value, produce the value directly
4969 // and push it on the stack.
4970 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
4971 /*NewInitializing=*/false, /*ToLValue=*/ToLValue);
4972 return this->Visit(E);
4973}
4974
4975template <class Emitter>
4977 assert(!canClassify(E->getType()));
4978
4979 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
4980 /*NewInitializing=*/true, /*ToLValue=*/false);
4981 return this->Visit(E) && this->emitFinishInit(E);
4982}
4983
4984template <class Emitter>
4986 assert(!canClassify(E->getType()));
4987
4988 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
4989 /*NewInitializing=*/true, /*ToLValue=*/false);
4990 return this->Visit(E) && this->emitFinishInitPop(E);
4991}
4992
4993template <class Emitter> bool Compiler<Emitter>::visitAsLValue(const Expr *E) {
4994 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
4995 /*NewInitializing=*/false, /*ToLValue=*/true);
4996 return this->Visit(E);
4997}
4998
4999template <class Emitter> bool Compiler<Emitter>::visitBool(const Expr *E) {
5000 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
5001 /*NewInitializing=*/false, /*ToLValue=*/ToLValue);
5002
5003 OptPrimType T = classify(E->getType());
5004 if (!T) {
5005 // Convert complex values to bool.
5006 if (E->getType()->isAnyComplexType()) {
5007 if (!this->visit(E))
5008 return false;
5009 return this->emitComplexBoolCast(E);
5010 }
5011 return false;
5012 }
5013
5014 if (!this->visit(E))
5015 return false;
5016
5017 if (T == PT_Bool)
5018 return true;
5019
5020 // Convert pointers to bool.
5021 if (T == PT_Ptr)
5022 return this->emitIsNonNullPtr(E);
5023
5024 // Or Floats.
5025 if (T == PT_Float)
5026 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
5027
5028 // Or anything else we can.
5029 return this->emitCast(*T, PT_Bool, E);
5030}
5031
5032template <class Emitter>
5033bool Compiler<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
5034 const Expr *E) {
5035 if (const auto *AT = QT->getAs<AtomicType>())
5036 QT = AT->getValueType();
5037
5038 switch (T) {
5039 case PT_Bool:
5040 return this->emitZeroBool(E);
5041 case PT_Sint8:
5042 return this->emitZeroSint8(E);
5043 case PT_Uint8:
5044 return this->emitZeroUint8(E);
5045 case PT_Sint16:
5046 return this->emitZeroSint16(E);
5047 case PT_Uint16:
5048 return this->emitZeroUint16(E);
5049 case PT_Sint32:
5050 return this->emitZeroSint32(E);
5051 case PT_Uint32:
5052 return this->emitZeroUint32(E);
5053 case PT_Sint64:
5054 return this->emitZeroSint64(E);
5055 case PT_Uint64:
5056 return this->emitZeroUint64(E);
5057 case PT_IntAP:
5058 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
5059 case PT_IntAPS:
5060 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
5061 case PT_Ptr:
5062 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
5063 nullptr, E);
5064 case PT_MemberPtr:
5065 return this->emitNullMemberPtr(0, nullptr, E);
5066 case PT_Float: {
5067 APFloat F = APFloat::getZero(Ctx.getFloatSemantics(QT));
5068 return this->emitFloat(F, E);
5069 }
5070 case PT_FixedPoint: {
5071 auto Sem = Ctx.getASTContext().getFixedPointSemantics(QT);
5072 return this->emitConstFixedPoint(FixedPoint::zero(Sem), E);
5073 }
5074 }
5075 llvm_unreachable("unknown primitive type");
5076}
5077
5078template <class Emitter>
5079bool Compiler<Emitter>::visitZeroRecordInitializer(const Record *R,
5080 const Expr *E,
5081 bool IsCompleteClass) {
5082 assert(E);
5083 assert(R);
5084 // Fields
5085 for (const Record::Field &Field : R->fields()) {
5086 if (Field.isUnnamedBitField())
5087 continue;
5088
5089 const Descriptor *D = Field.Desc;
5090 if (D->isPrimitive()) {
5091 QualType QT = D->getType();
5092 PrimType T = D->getPrimType();
5093 if (!this->visitZeroInitializer(T, QT, E))
5094 return false;
5095 if (R->isUnion()) {
5096 if (!this->emitInitFieldActivate(T, Field.Offset, E))
5097 return false;
5098 break;
5099 }
5100 if (!this->emitInitField(T, Field.Offset, E))
5101 return false;
5102 continue;
5103 }
5104
5105 if (!this->emitGetPtrField(Field.Offset, E))
5106 return false;
5107
5108 if (D->isPrimitiveArray()) {
5109 QualType ET = D->getElemQualType();
5110 PrimType T = D->getPrimType();
5111 for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
5112 if (!this->visitZeroInitializer(T, ET, E))
5113 return false;
5114 if (!this->emitInitElem(T, I, E))
5115 return false;
5116 }
5117 } else if (D->isCompositeArray()) {
5118 // Can't be a vector or complex field.
5119 if (!this->visitZeroArrayInitializer(D->getType(), E))
5120 return false;
5121 } else if (D->isRecord()) {
5122 if (!this->visitZeroRecordInitializer(D->ElemRecord, E))
5123 return false;
5124 } else
5125 return false;
5126
5127 // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the
5128 // object's first non-static named data member is zero-initialized
5129 if (R->isUnion()) {
5130 if (!this->emitFinishInitActivatePop(E))
5131 return false;
5132 break;
5133 }
5134 if (!this->emitFinishInitPop(E))
5135 return false;
5136 }
5137
5138 for (const Record::Base &B : R->bases()) {
5139 if (!this->emitGetPtrBase(B.Offset, E))
5140 return false;
5141 if (!this->visitZeroRecordInitializer(B.R, E, /*IsCompleteClass=*/false))
5142 return false;
5143 if (!this->emitFinishInitPop(E))
5144 return false;
5145 }
5146
5147 if (IsCompleteClass) {
5148 for (const Record::Base &B : R->virtual_bases()) {
5149 if (!this->emitGetPtrVirtBase(cast<CXXRecordDecl>(B.R->getDecl()), E))
5150 return false;
5151 if (!this->visitZeroRecordInitializer(B.R, E, /*IsCompleteClass=*/false))
5152 return false;
5153 if (!this->emitFinishInitPop(E))
5154 return false;
5155 }
5156 }
5157
5158 return true;
5159}
5160
5161template <class Emitter>
5162bool Compiler<Emitter>::visitZeroArrayInitializer(QualType T, const Expr *E) {
5163 assert(T->isArrayType() || T->isAnyComplexType() || T->isVectorType());
5164 const ArrayType *AT = T->getAsArrayTypeUnsafe();
5165 QualType ElemType = AT->getElementType();
5166 size_t NumElems = cast<ConstantArrayType>(AT)->getZExtSize();
5167
5168 if (OptPrimType ElemT = classify(ElemType)) {
5169 for (size_t I = 0; I != NumElems; ++I) {
5170 if (!this->visitZeroInitializer(*ElemT, ElemType, E))
5171 return false;
5172 if (!this->emitInitElem(*ElemT, I, E))
5173 return false;
5174 }
5175 return true;
5176 }
5177 if (ElemType->isRecordType()) {
5178 const Record *R = getRecord(ElemType);
5179 if (!R)
5180 return false;
5181
5182 for (size_t I = 0; I != NumElems; ++I) {
5183 if (!this->emitConstUint32(I, E))
5184 return false;
5185 if (!this->emitArrayElemPtr(PT_Uint32, E))
5186 return false;
5187 if (!this->visitZeroRecordInitializer(R, E))
5188 return false;
5189 if (!this->emitPopPtr(E))
5190 return false;
5191 }
5192 return true;
5193 }
5194 if (ElemType->isArrayType()) {
5195 for (size_t I = 0; I != NumElems; ++I) {
5196 if (!this->emitConstUint32(I, E))
5197 return false;
5198 if (!this->emitArrayElemPtr(PT_Uint32, E))
5199 return false;
5200 if (!this->visitZeroArrayInitializer(ElemType, E))
5201 return false;
5202 if (!this->emitPopPtr(E))
5203 return false;
5204 }
5205 return true;
5206 }
5207
5208 return false;
5209}
5210
5211template <class Emitter>
5212bool Compiler<Emitter>::visitAssignment(const Expr *LHS, const Expr *RHS,
5213 const Expr *E) {
5214 if (!canClassify(E->getType()))
5215 return false;
5216
5217 bool NeedsFlip = !isSideEffectFree(RHS);
5218 if (!NeedsFlip) {
5219 if (!this->visit(LHS))
5220 return false;
5221 if (!this->visit(RHS))
5222 return false;
5223 } else {
5224 if (!this->visit(RHS))
5225 return false;
5226 if (!this->visit(LHS))
5227 return false;
5228 }
5229
5230 if (LHS->getType().isVolatileQualified())
5231 return this->emitInvalidStore(LHS->getType().getTypePtr(), E);
5232
5233 // We don't support assignments in C.
5234 if (!Ctx.getLangOpts().CPlusPlus && !this->emitInvalid(E))
5235 return false;
5236
5237 PrimType RHT = classifyPrim(RHS);
5238 bool Activates = refersToUnion(LHS);
5239 bool BitField = LHS->refersToBitField();
5240
5241 if (NeedsFlip && !this->emitFlip(PT_Ptr, RHT, E))
5242 return false;
5243
5244 if (DiscardResult) {
5245 if (BitField && Activates)
5246 return this->emitStoreBitFieldActivatePop(RHT, E);
5247 if (BitField)
5248 return this->emitStoreBitFieldPop(RHT, E);
5249 if (Activates)
5250 return this->emitStoreActivatePop(RHT, E);
5251 // Otherwise, regular non-activating store.
5252 return this->emitStorePop(RHT, E);
5253 }
5254
5255 auto maybeLoad = [&](bool Result) -> bool {
5256 if (!Result)
5257 return false;
5258 // Assignments aren't necessarily lvalues in C.
5259 // Load from them in that case.
5260 if (!E->isLValue())
5261 return this->emitLoadPop(RHT, E);
5262 return true;
5263 };
5264
5265 if (BitField && Activates)
5266 return maybeLoad(this->emitStoreBitFieldActivate(RHT, E));
5267 if (BitField)
5268 return maybeLoad(this->emitStoreBitField(RHT, E));
5269 if (Activates)
5270 return maybeLoad(this->emitStoreActivate(RHT, E));
5271 // Otherwise, regular non-activating store.
5272 return maybeLoad(this->emitStore(RHT, E));
5273}
5274
5275template <class Emitter>
5276template <typename T>
5277bool Compiler<Emitter>::emitConst(T Value, PrimType Ty, SourceInfo Info) {
5278 switch (Ty) {
5279 case PT_Sint8:
5280 return this->emitConstSint8(Value, Info);
5281 case PT_Uint8:
5282 return this->emitConstUint8(Value, Info);
5283 case PT_Sint16:
5284 return this->emitConstSint16(Value, Info);
5285 case PT_Uint16:
5286 return this->emitConstUint16(Value, Info);
5287 case PT_Sint32:
5288 return this->emitConstSint32(Value, Info);
5289 case PT_Uint32:
5290 return this->emitConstUint32(Value, Info);
5291 case PT_Sint64:
5292 return this->emitConstSint64(Value, Info);
5293 case PT_Uint64:
5294 return this->emitConstUint64(Value, Info);
5295 case PT_Bool:
5296 return this->emitConstBool(Value, Info);
5297 case PT_Ptr:
5298 case PT_MemberPtr:
5299 case PT_Float:
5300 case PT_IntAP:
5301 case PT_IntAPS:
5302 case PT_FixedPoint:
5303 llvm_unreachable("Invalid integral type");
5304 break;
5305 }
5306 llvm_unreachable("unknown primitive type");
5307}
5308
5309template <class Emitter>
5310template <typename T>
5311bool Compiler<Emitter>::emitConst(T Value, const Expr *E) {
5312 return this->emitConst(Value, classifyPrim(E->getType()), E);
5313}
5314
5315template <class Emitter>
5316bool Compiler<Emitter>::emitConst(const APSInt &Value, PrimType Ty,
5317 SourceInfo Info) {
5318 if (Ty == PT_IntAPS)
5319 return this->emitConstIntAPS(Value, Info);
5320 if (Ty == PT_IntAP)
5321 return this->emitConstIntAP(Value, Info);
5322
5323 if (Value.isSigned())
5324 return this->emitConst(Value.getSExtValue(), Ty, Info);
5325 return this->emitConst(Value.getZExtValue(), Ty, Info);
5326}
5327
5328template <class Emitter>
5329bool Compiler<Emitter>::emitConst(const APInt &Value, PrimType Ty,
5330 SourceInfo Info) {
5331 if (Ty == PT_IntAPS)
5332 return this->emitConstIntAPS(Value, Info);
5333 if (Ty == PT_IntAP)
5334 return this->emitConstIntAP(Value, Info);
5335
5336 if (isSignedType(Ty))
5337 return this->emitConst(Value.getSExtValue(), Ty, Info);
5338 return this->emitConst(Value.getZExtValue(), Ty, Info);
5339}
5340
5341template <class Emitter>
5342bool Compiler<Emitter>::emitConst(const APSInt &Value, const Expr *E) {
5343 return this->emitConst(Value, classifyPrim(E->getType()), E);
5344}
5345
5346template <class Emitter>
5348 bool IsConst,
5349 bool IsVolatile,
5350 ScopeKind SC) {
5351 // FIXME: There are cases where Src.isExpr() is wrong, e.g.
5352 // (int){12} in C. Consider using Expr::isTemporaryObject() instead
5353 // or isa<MaterializeTemporaryExpr>().
5354 Descriptor *D = P.createDescriptor(Src, Ty, nullptr, IsConst, Src.isExpr(),
5355 /*IsMutable=*/false, IsVolatile);
5357 Scope::Local Local = this->createLocal(D);
5358 if (auto *VD = Src.asValueDecl())
5359 Locals.insert({VD, Local});
5360 VarScope->addForScopeKind(Local, SC);
5361 return Local.Offset;
5362}
5363
5364template <class Emitter>
5366 ScopeKind SC) {
5367 const ValueDecl *Key = nullptr;
5368 const Expr *Init = nullptr;
5369 bool IsTemporary = false;
5370 if (auto *VD = Src.asValueDecl()) {
5371 Key = VD;
5372
5373 if (const auto *VarD = dyn_cast<VarDecl>(VD))
5374 Init = VarD->getInit();
5375 }
5376 if (const auto *E = Src.asExpr()) {
5377 IsTemporary = true;
5378 if (Ty.isNull())
5379 Ty = E->getType();
5380 }
5381
5382 Descriptor *D = P.createDescriptor(
5383 Src, Ty.getTypePtr(), Ty.isConstQualified(), IsTemporary,
5384 /*IsMutable=*/false, /*IsVolatile=*/Ty.isVolatileQualified(), Init);
5385 if (!D)
5386 return std::nullopt;
5388
5389 Scope::Local Local = this->createLocal(D);
5390 if (Key)
5391 Locals.insert({Key, Local});
5392 VarScope->addForScopeKind(Local, SC);
5393 return Local.Offset;
5394}
5395
5396template <class Emitter>
5398 QualType Ty = E->getType();
5399 assert(!Ty->isRecordType());
5400
5401 Descriptor *D = P.createDescriptor(E, Ty.getTypePtr(), Ty.isConstQualified(),
5402 /*IsTemporary=*/true);
5403
5404 if (!D)
5405 return std::nullopt;
5406
5407 Scope::Local Local = this->createLocal(D);
5409 assert(S);
5410 // Attach to topmost scope.
5411 while (S->getParent())
5412 S = S->getParent();
5413 assert(S && !S->getParent());
5414 S->addLocal(Local);
5415 return Local.Offset;
5416}
5417
5418template <class Emitter>
5420 if (const PointerType *PT = dyn_cast<PointerType>(Ty))
5421 return PT->getPointeeType()->getAsCanonical<RecordType>();
5422 return Ty->getAsCanonical<RecordType>();
5423}
5424
5425template <class Emitter> Record *Compiler<Emitter>::getRecord(QualType Ty) {
5426 if (const auto *RecordTy = getRecordTy(Ty))
5427 return getRecord(RecordTy->getDecl()->getDefinitionOrSelf());
5428 return nullptr;
5429}
5430
5431template <class Emitter>
5433 return P.getOrCreateRecord(RD);
5434}
5435
5436template <class Emitter>
5438 return Ctx.getOrCreateFunction(FD);
5439}
5440
5441template <class Emitter>
5442bool Compiler<Emitter>::visitExpr(const Expr *E, bool DestroyToplevelScope) {
5444
5445 auto maybeDestroyLocals = [&]() -> bool {
5446 if (DestroyToplevelScope)
5447 return RootScope.destroyLocals() && this->emitCheckAllocations(E);
5448 return this->emitCheckAllocations(E);
5449 };
5450
5451 // Void expressions.
5452 if (E->getType()->isVoidType()) {
5453 if (!visit(E))
5454 return false;
5455 return this->emitRetVoid(E) && maybeDestroyLocals();
5456 }
5457
5458 // Expressions with a primitive return type.
5459 if (OptPrimType T = classify(E)) {
5460 if (!visit(E))
5461 return false;
5462
5463 return this->emitRet(*T, E) && maybeDestroyLocals();
5464 }
5465
5466 // Expressions with a composite return type.
5467 // For us, that means everything we don't
5468 // have a PrimType for.
5469 if (UnsignedOrNone LocalOffset = this->allocateLocal(E)) {
5470 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalOffset));
5471 if (!this->emitGetPtrLocal(*LocalOffset, E))
5472 return false;
5473
5474 if (!visitInitializer(E))
5475 return false;
5476 // We are destroying the locals AFTER the Ret op.
5477 // The Ret op needs to copy the (alive) values, but the
5478 // destructors may still turn the entire expression invalid.
5479 return this->emitRetValue(E) && maybeDestroyLocals();
5480 }
5481
5482 return maybeDestroyLocals() && false;
5483}
5484
5485template <class Emitter>
5487 bool DestroyToplevelScope) {
5488 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
5489 /*NewInitializing=*/false, /*ToLValue=*/true);
5490
5491 return this->visitExpr(E, DestroyToplevelScope);
5492}
5493
5494template <class Emitter>
5496
5497 auto R = this->visitVarDecl(VD, VD->getInit(), /*Toplevel=*/true);
5498
5499 if (R.notCreated())
5500 return R;
5501
5502 if (R)
5503 return true;
5504
5505 if (!R && Context::shouldBeGloballyIndexed(VD)) {
5506 if (auto GlobalIndex = P.getGlobal(VD)) {
5507 Block *GlobalBlock = P.getGlobal(*GlobalIndex);
5508 auto &GD = GlobalBlock->getBlockDesc<GlobalInlineDescriptor>();
5509
5511 GlobalBlock->invokeDtor();
5512 }
5513 }
5514
5515 return R;
5516}
5517
5518/// Toplevel visitDeclAndReturn().
5519/// We get here from evaluateAsInitializer().
5520/// We need to evaluate the initializer and return its value.
5521template <class Emitter>
5523 bool ConstantContext) {
5524 // We only create variables if we're evaluating in a constant context.
5525 // Otherwise, just evaluate the initializer and return it.
5526 if (!ConstantContext) {
5527 DeclScope<Emitter> LS(this, VD);
5528 if (!this->visit(Init))
5529 return false;
5530 return this->emitRet(classify(Init).value_or(PT_Ptr), VD) &&
5531 LS.destroyLocals() && this->emitCheckAllocations(VD);
5532 }
5533
5534 LocalScope<Emitter> VDScope(this);
5535 if (!this->visitVarDecl(VD, Init, /*Toplevel=*/true))
5536 return false;
5537
5538 OptPrimType VarT = classify(VD->getType());
5539 bool IsReference = VD->getType()->isReferenceType();
5541 auto GlobalIndex = P.getGlobal(VD);
5542 assert(GlobalIndex); // visitVarDecl() didn't return false.
5543 if (VarT) {
5544 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
5545 return false;
5546 } else {
5547 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
5548 return false;
5549 }
5550 } else {
5551 auto Local = Locals.find(VD);
5552 assert(Local != Locals.end()); // Same here.
5553 if (VarT) {
5554 if (IsReference) {
5555 if (!this->emitGetRefLocal(Local->second.Offset, VD))
5556 return false;
5557 } else if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
5558 return false;
5559 } else {
5560 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
5561 return false;
5562 }
5563 }
5564
5565 // Return the value.
5566 if (!this->emitRet(VarT.value_or(PT_Ptr), VD)) {
5567 // If the Ret above failed and this is a global variable, mark it as
5568 // uninitialized, even everything else succeeded.
5570 auto GlobalIndex = P.getGlobal(VD);
5571 assert(GlobalIndex);
5572 Block *GlobalBlock = P.getGlobal(*GlobalIndex);
5573 auto &GD = GlobalBlock->getBlockDesc<GlobalInlineDescriptor>();
5574
5576 GlobalBlock->invokeDtor();
5577 }
5578 return false;
5579 }
5580
5581 return VDScope.destroyLocals() && this->emitCheckAllocations(VD);
5582}
5583
5584template <class Emitter>
5586 const Expr *Init,
5587 bool Toplevel) {
5588 QualType VarTy = VD->getType();
5589 // We don't know what to do with these, so just return false.
5590 if (VarTy.isNull())
5591 return false;
5592
5593 // This case is EvalEmitter-only. If we won't create any instructions for the
5594 // initializer anyway, don't bother creating the variable in the first place.
5595 if (!this->isActive())
5597
5598 OptPrimType VarT = classify(VD->getType());
5599
5600 if (Init && Init->isValueDependent())
5601 return false;
5602
5604 auto checkDecl = [&]() -> bool {
5605 bool NeedsOp = !Toplevel && VD->isLocalVarDecl() && VD->isStaticLocal();
5606 return !NeedsOp || this->emitCheckDecl(VD, VD);
5607 };
5608
5610 UnsignedOrNone GlobalIndex = P.getGlobal(VD);
5611 if (GlobalIndex) {
5612 // The global was previously created but the initializer failed.
5613 if (!P.getGlobal(*GlobalIndex)->isInitialized())
5614 return false;
5615 // We've already seen and initialized this global.
5616 if (P.isGlobalInitialized(*GlobalIndex))
5617 return checkDecl();
5618 // The previous attempt at initialization might've been unsuccessful,
5619 // so let's try this one.
5620 } else if ((GlobalIndex =
5621 P.createGlobal(VD, Init, VariablesAreConstexprUnknown))) {
5622 } else {
5623 return false;
5624 }
5625 if (!Init)
5626 return true;
5627
5628 if (!checkDecl())
5629 return false;
5630
5631 if (VarT) {
5632 if (!this->visit(Init))
5633 return false;
5634
5635 return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
5636 }
5637
5638 if (!this->emitGetPtrGlobal(*GlobalIndex, Init))
5639 return false;
5640
5641 if (!this->emitStartInit(Init))
5642 return false;
5643
5644 if (!visitInitializer(Init))
5645 return false;
5646
5647 if (!this->emitEndInit(Init))
5648 return false;
5649
5650 return this->emitFinishInitGlobal(Init);
5651 }
5652 // Local variables.
5654
5655 if (VarT) {
5656 unsigned Offset = this->allocateLocalPrimitive(
5657 VD, *VarT, VarTy.isConstQualified(), VarTy.isVolatileQualified(),
5659
5660 if (!Init || Init->getType()->isVoidType())
5661 return true;
5662
5663 // If this is a toplevel declaration, create a scope for the
5664 // initializer.
5665 if (Toplevel) {
5667 if (!this->visit(Init))
5668 return false;
5669 return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals();
5670 }
5671 if (!this->visit(Init))
5672 return false;
5673
5674 if (VarTy->isReferenceType()) {
5675 // [C++26][decl.ref]
5676 // The object designated by such a glvalue can be outside its lifetime
5677 // Because a null pointer value or a pointer past the end of an object
5678 // does not point to an object, a reference in a well-defined program
5679 // cannot refer to such things;
5680 assert(classifyPrim(VarTy) == PT_Ptr);
5681 if (!this->emitCheckRefInit(Init))
5682 return false;
5683 }
5684
5685 return this->emitSetLocal(*VarT, Offset, VD);
5686 }
5687 // Local composite variables.
5688 if (UnsignedOrNone Offset =
5689 this->allocateLocal(VD, VarTy, ScopeKind::Block)) {
5690 if (!Init)
5691 return true;
5692
5693 if (!this->emitGetPtrLocal(*Offset, Init))
5694 return false;
5695
5696 return visitInitializerPop(Init);
5697 }
5698 return false;
5699}
5700
5701template <class Emitter>
5703 assert(!canClassify(VD->getType()));
5704
5706 // Create a local variable to use as the instance.
5707 QualType Ty = VD->getType();
5708 Descriptor *D =
5709 P.createDescriptor(VD, Ty.getTypePtr(), /*IsConst=*/Ty.isConstQualified(),
5710 /*IsTemporary=*/false, /*IsMutable=*/false,
5711 /*IsVolatile=*/Ty.isVolatileQualified(), nullptr);
5712 if (!D)
5713 return false;
5714
5715 // FIXME: Would be nice if we didn't allocate the descriptor at all in this
5716 // case.
5717 if (D->hasTrivialDtor())
5718 return true;
5719
5720 Scope::Local Local = this->createLocal(D);
5721 Locals.insert({VD, Local});
5722 VarScope->addForScopeKind(Local, ScopeKind::Block);
5723
5724 if (!this->emitGetPtrLocal(Local.Offset, VD))
5725 return false;
5726
5727 if (!this->visitAPValueInitializer(Value, VD, Ty))
5728 return false;
5729
5730 return this->emitDestructionPop(D, VD);
5731}
5732
5734public:
5736 explicit ParamFinder() {}
5737
5738 bool VisitDeclRefExpr(const DeclRefExpr *E) override {
5739 if (const auto *P = dyn_cast<ParmVarDecl>(E->getDecl()))
5740 FoundParams.insert(P);
5741 return true;
5742 }
5743};
5744
5745/// Evaluate the \p Condition as if it was in the body of \p Callee.
5746/// Specifically, all the parameters of the callee are available to use
5747/// for the condition, and their values are given by \p Args (and \p This).
5748///
5749// Since this is a somewhat niche feature, we're abusing a few other mechanisms
5750// to implement this.
5751//
5752// We don't create an actual function frame but instead register the parameters
5753// as local variables.
5754//
5755// So we evaluate something like:
5756//
5757// bool thisfunc() {
5758// auto Arg0 = Args[0];
5759// ...
5760// return Condition;
5761// }
5762//
5763template <class Emitter>
5766 const Expr *This,
5767 const Expr *Condition) {
5768 // Instead of evaluating all parameters and trying to ignore failure,
5769 // we collect all the parameters used in the condition and only evaluate
5770 // those. Note that we still ignore failure in the loop below because the
5771 // failure might be inconsequential in the end,
5772 // e.g. in the case of `true || x`.
5773 ParamFinder PF;
5775
5776 LocalScope<Emitter> ArgScope(this);
5777 for (const ParmVarDecl *PVD : PF.FoundParams) {
5778 unsigned ParamIndex = 0;
5779 for (const ParmVarDecl *P : Callee->parameters()) {
5780 if (P == PVD)
5781 break;
5782 ++ParamIndex;
5783 }
5784
5785 const Expr *Arg = Args[ParamIndex];
5786 const ParmVarDecl *Param = Callee->getParamDecl(ParamIndex);
5787 if (OptPrimType ParamT = classify(Param->getType())) {
5788 unsigned ArgOffset =
5789 allocateLocalPrimitive(Param, *ParamT, /*IsConst=*/true);
5790 if (!this->visit(Arg))
5791 continue;
5792 if (!this->emitSetLocal(*ParamT, ArgOffset, Arg))
5793 return false;
5794 } else {
5795 UnsignedOrNone ArgOffset = this->allocateLocal(Param, Param->getType());
5796 if (!ArgOffset)
5797 return false;
5798 if (!this->emitGetPtrLocal(*ArgOffset, Arg))
5799 return false;
5800 if (!this->visitInitializerPop(Arg))
5801 continue;
5802 }
5803 }
5804
5805 if (This) {
5806 // We abuse the init stack for this and tell it to use
5807 // either a local variable or another decl for the This pointer.
5808 this->InitStackActive = true;
5809
5810 if (This->getType()->isPointerType()) {
5811 // Nothing to do here, the evaluation will fail if the instance
5812 // pointer is used.
5813 } else if (const auto *DRE = dyn_cast<DeclRefExpr>(This)) {
5814 InitStack.push_back(InitLink::Decl(DRE->getDecl()));
5815 } else {
5816 assert(!canClassify(This->getType()));
5817 UnsignedOrNone ArgOffset = this->allocateLocal(This, This->getType());
5818 if (!ArgOffset)
5819 return false;
5820 if (!this->emitGetPtrLocal(*ArgOffset, This))
5821 return false;
5822 if (!this->visitInitializerPop(This))
5823 return false;
5824 this->InitStack.push_back(InitLink::Temp(*ArgOffset));
5825 }
5826 }
5827
5828 // Destruction of the argument values is part of the callee frame,
5829 // so we simply ignore them here.
5830 this->VarScope = nullptr;
5831
5832 LocalScope<Emitter> RetScope(this);
5833 if (!this->visit(Condition))
5834 return false;
5835 if (!RetScope.destroyLocals())
5836 return false;
5837
5838 // Result of the condition should be on the stack.
5839 return this->emitRet(PT_Bool, Condition);
5840}
5841
5842template <class Emitter>
5844 SourceInfo Info) {
5845 assert(!Val.isIndeterminate() && "Needs to be checked before");
5846 assert(!DiscardResult);
5847 if (Val.isInt())
5848 return this->emitConst(Val.getInt(), ValType, Info);
5849 if (Val.isFloat())
5850 return this->emitFloat(Val.getFloat(), Info);
5851
5852 if (Val.isMemberPointer()) {
5853 if (const ValueDecl *MemberDecl = Val.getMemberPointerDecl()) {
5854 if (!this->emitGetMemberPtr(MemberDecl, Info))
5855 return false;
5856
5857 bool IsDerived = Val.isMemberPointerToDerivedMember();
5858 // Apply the member pointer path.
5859 for (const CXXRecordDecl *PathEntry : Val.getMemberPointerPath()) {
5860 if (!this->emitCopyMemberPtrPath(PathEntry, IsDerived, Info))
5861 return false;
5862 }
5863
5864 return true;
5865 }
5866 return this->emitNullMemberPtr(0, nullptr, Info);
5867 }
5868
5869 if (Val.isLValue()) {
5870 if (Val.isNullPointer())
5871 return this->emitNull(ValType, 0, nullptr, Info);
5872
5875
5876 if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>())
5877 return this->visit(BaseExpr);
5878 if (const auto *VD = Base.dyn_cast<const ValueDecl *>()) {
5879 if (!this->visitDeclRef(VD, Info.asExpr()))
5880 return false;
5881
5882 QualType EntryType = VD->getType();
5883 for (auto &Entry : Path) {
5884 if (EntryType->isArrayType()) {
5885 uint64_t Index = Entry.getAsArrayIndex();
5886 QualType ElemType =
5887 EntryType->getAsArrayTypeUnsafe()->getElementType();
5888 if (!this->emitConst(Index, PT_Uint64, Info))
5889 return false;
5890 if (!this->emitArrayElemPtrPop(PT_Uint64, Info))
5891 return false;
5892 EntryType = ElemType;
5893 } else {
5894 assert(EntryType->isRecordType());
5895 const Record *EntryRecord = getRecord(EntryType);
5896 if (!EntryRecord)
5897 return false;
5898
5899 const Decl *BaseOrMember = Entry.getAsBaseOrMember().getPointer();
5900 if (const auto *FD = dyn_cast<FieldDecl>(BaseOrMember)) {
5901 unsigned EntryOffset = EntryRecord->getField(FD)->Offset;
5902 if (!this->emitGetPtrFieldPop(EntryOffset, Info))
5903 return false;
5904 EntryType = FD->getType();
5905 } else {
5906 const auto *Base = cast<CXXRecordDecl>(BaseOrMember);
5907 if (const Record::Base *B = EntryRecord->getBaseOrNull(Base)) {
5908 if (!this->emitGetPtrBasePop(B->Offset, /*NullOK=*/false, Info))
5909 return false;
5910 } else {
5911 // Must be a virtual base.
5912 assert(EntryRecord->findVirtualBase(Base));
5913 if (!this->emitGetPtrVirtBasePop(Base, Info))
5914 return false;
5915 }
5916 EntryType = Ctx.getASTContext().getCanonicalTagType(Base);
5917 }
5918 }
5919 }
5920
5921 return true;
5922 }
5923 }
5924
5925 return false;
5926}
5927
5928template <class Emitter>
5930 SourceInfo Info, QualType T,
5931 bool IsCompleteClass) {
5932 if (Val.isStruct()) {
5933 const Record *R = this->getRecord(T);
5934 assert(R);
5935
5936 assert(R->getNumBases() == Val.getStructNumBases());
5937 if (IsCompleteClass)
5938 assert(R->getNumVirtualBases() == Val.getStructNumVirtualBases());
5939
5940 for (unsigned I = 0, N = Val.getStructNumBases(); I != N; ++I) {
5941 const APValue &B = Val.getStructBase(I);
5942 if (B.isIndeterminate())
5943 continue;
5944 const Record::Base *RB = R->getBase(I);
5945 QualType BaseType = Ctx.getASTContext().getCanonicalTagType(RB->Decl);
5946
5947 if (!this->emitGetPtrBase(RB->Offset, Info))
5948 return false;
5949 if (!this->visitAPValueInitializer(B, Info, BaseType,
5950 /*IsCompleteClass=*/false))
5951 return false;
5952 if (!this->emitFinishInitPop(Info))
5953 return false;
5954 }
5955
5956 for (unsigned I = 0, N = Val.getStructNumFields(); I != N; ++I) {
5957 const APValue &F = Val.getStructField(I);
5958 if (F.isIndeterminate())
5959 continue;
5960 const Record::Field *RF = R->getField(I);
5961 QualType FieldType = RF->Decl->getType();
5962 // Fields.
5963 if (OptPrimType PT = RF->T) {
5964 if (!this->visitAPValue(F, *PT, Info))
5965 return false;
5966 if (!this->emitInitField(*PT, RF->Offset, Info))
5967 return false;
5968 } else {
5969 if (!this->emitGetPtrField(RF->Offset, Info))
5970 return false;
5971 if (!this->visitAPValueInitializer(F, Info, FieldType))
5972 return false;
5973 if (!this->emitFinishInitPop(Info))
5974 return false;
5975 }
5976 }
5977
5978 // Virtual Bases.
5979 if (IsCompleteClass) {
5980 for (unsigned I = 0, N = Val.getStructNumVirtualBases(); I != N; ++I) {
5981 const APValue &B = Val.getStructVirtualBase(I);
5982 if (B.isIndeterminate())
5983 continue;
5984 const Record::Base *RB = R->getVirtualBase(I);
5985 QualType BaseType = Ctx.getASTContext().getCanonicalTagType(RB->Decl);
5986
5987 if (!this->emitGetPtrVirtBase(cast<CXXRecordDecl>(RB->R->getDecl()),
5988 Info))
5989 return false;
5990 if (!this->visitAPValueInitializer(B, Info, BaseType,
5991 /*IsCompleteClass=*/false))
5992 return false;
5993 if (!this->emitFinishInitPop(Info))
5994 return false;
5995 }
5996 }
5997
5998 return true;
5999 }
6000 if (Val.isUnion()) {
6001 const FieldDecl *UnionField = Val.getUnionField();
6002 if (!UnionField)
6003 return true;
6004 const Record *R = this->getRecord(T);
6005 assert(R);
6006 const APValue &F = Val.getUnionValue();
6007 if (F.isIndeterminate())
6008 return true;
6009 const Record::Field *RF = R->getField(UnionField);
6010 QualType FieldType = RF->Decl->getType();
6011
6012 if (OptPrimType PT = RF->T) {
6013 if (!this->visitAPValue(F, *PT, Info))
6014 return false;
6015 if (RF->isBitField())
6016 return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(),
6017 Info);
6018 return this->emitInitFieldActivate(*PT, RF->Offset, Info);
6019 }
6020
6021 if (!this->emitGetPtrField(RF->Offset, Info))
6022 return false;
6023 if (!this->emitActivate(Info))
6024 return false;
6025 if (!this->visitAPValueInitializer(F, Info, FieldType))
6026 return false;
6027 return this->emitPopPtr(Info);
6028 }
6029 if (Val.isArray()) {
6030 unsigned InitializedElems = Val.getArrayInitializedElts();
6031 const auto *ArrType = T->getAsArrayTypeUnsafe();
6032 QualType ElemType = ArrType->getElementType();
6033 OptPrimType ElemT = classify(ElemType);
6034
6035 for (unsigned A = 0, AN = Val.getArraySize(); A != AN; ++A) {
6036 const APValue &Elem = A >= InitializedElems
6037 ? Val.getArrayFiller()
6038 : Val.getArrayInitializedElt(A);
6039 if (Elem.isIndeterminate())
6040 continue;
6041
6042 if (ElemT) {
6043 if (!this->visitAPValue(Elem, *ElemT, Info))
6044 return false;
6045 if (!this->emitInitElem(*ElemT, A, Info))
6046 return false;
6047 } else {
6048 if (!this->emitConstUint32(A, Info))
6049 return false;
6050 if (!this->emitArrayElemPtrUint32(Info))
6051 return false;
6052 if (!this->visitAPValueInitializer(Elem, Info, ElemType))
6053 return false;
6054 if (!this->emitPopPtr(Info))
6055 return false;
6056 }
6057 }
6058 return true;
6059 }
6060 // TODO: Other types.
6061
6062 return false;
6063}
6064
6065template <class Emitter>
6067 unsigned BuiltinID) {
6068 if (BuiltinID == Builtin::BI__builtin_constant_p) {
6069 // Void argument is always invalid and harder to handle later.
6070 if (E->getArg(0)->getType()->isVoidType()) {
6071 if (DiscardResult)
6072 return true;
6073 return this->emitConst(0, E);
6074 }
6075
6076 if (!this->emitStartSpeculation(E))
6077 return false;
6078 LabelTy EndLabel = this->getLabel();
6079 if (!this->speculate(E, EndLabel))
6080 return false;
6081 if (!this->emitEndSpeculation(E))
6082 return false;
6083 this->fallthrough(EndLabel);
6084 if (DiscardResult)
6085 return this->emitPop(classifyPrim(E), E);
6086 return true;
6087 }
6088
6089 // For these, we're expected to ultimately return an APValue pointing
6090 // to the CallExpr. This is needed to get the correct codegen.
6091 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6092 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
6093 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
6094 BuiltinID == Builtin::BI__builtin_function_start) {
6095 if (DiscardResult)
6096 return true;
6097 return this->emitDummyPtr(E, E);
6098 }
6099
6101 OptPrimType ReturnT = classify(E);
6102
6103 // Non-primitive return type. Prepare storage.
6104 if (!Initializing && !ReturnT && !ReturnType->isVoidType()) {
6105 UnsignedOrNone LocalIndex = allocateLocal(E);
6106 if (!LocalIndex)
6107 return false;
6108 if (!this->emitGetPtrLocal(*LocalIndex, E))
6109 return false;
6110 }
6111
6112 // Prepare function arguments including special cases.
6113 switch (BuiltinID) {
6114 case Builtin::BI__builtin_object_size:
6115 case Builtin::BI__builtin_dynamic_object_size: {
6116 assert(E->getNumArgs() == 2);
6117 const Expr *Arg0 = E->getArg(0);
6118 if (Arg0->isGLValue()) {
6119 if (!this->visit(Arg0))
6120 return false;
6121
6122 } else {
6124 return false;
6125 }
6126 if (!this->visit(E->getArg(1)))
6127 return false;
6128
6129 } break;
6130 case Builtin::BI__assume:
6131 case Builtin::BI__builtin_assume:
6132 // Argument is not evaluated.
6133 break;
6134 case Builtin::BI__atomic_is_lock_free:
6135 case Builtin::BI__atomic_always_lock_free: {
6136 assert(E->getNumArgs() == 2);
6137 if (!this->visit(E->getArg(0)))
6138 return false;
6139 if (!this->visitAsLValue(E->getArg(1)))
6140 return false;
6141 } break;
6142
6143 default:
6144 if (!Context::isUnevaluatedBuiltin(BuiltinID)) {
6145 // Put arguments on the stack.
6146 for (const auto *Arg : E->arguments()) {
6147 if (!this->visit(Arg))
6148 return false;
6149 }
6150 }
6151 }
6152
6153 if (!this->emitCallBI(E, BuiltinID, E))
6154 return false;
6155
6156 if (DiscardResult && !ReturnType->isVoidType())
6157 return this->emitPop(ReturnT.value_or(PT_Ptr), E);
6158
6159 return true;
6160}
6161
6163 if (!MD || !MD->isDefaulted())
6164 return false;
6166 return false;
6167 return MD->getParent()->isUnion() ||
6169}
6170
6171template <class Emitter>
6173 if (E->containsErrors())
6174 return false;
6175 const FunctionDecl *FuncDecl = E->getDirectCallee();
6176
6177 if (FuncDecl) {
6178 if (unsigned BuiltinID = FuncDecl->getBuiltinID())
6179 return VisitBuiltinCallExpr(E, BuiltinID);
6180
6181 // Calls to replaceable operator new/operator delete.
6183 if (FuncDecl->getDeclName().isAnyOperatorNew())
6184 return VisitBuiltinCallExpr(E, Builtin::BI__builtin_operator_new);
6185 assert(FuncDecl->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
6186 FuncDecl->getDeclName().getCXXOverloadedOperator() ==
6187 OO_Array_Delete);
6188 return VisitBuiltinCallExpr(E, Builtin::BI__builtin_operator_delete);
6189 }
6190
6191 // Explicit calls to trivial destructors
6192 if (const auto *DD = dyn_cast<CXXDestructorDecl>(FuncDecl);
6193 DD && DD->isTrivial()) {
6194 const auto *MemberCall = cast<CXXMemberCallExpr>(E);
6195 if (!this->visit(MemberCall->getImplicitObjectArgument()))
6196 return false;
6197 return this->emitCheckDestruction(E) && this->emitEndLifetime(E) &&
6198 this->emitPopPtr(E);
6199 }
6200 }
6201
6202 LocalScope<Emitter> CallScope(this, ScopeKind::Call);
6203 ArrayRef<const Expr *> Args(E->getArgs(), E->getNumArgs());
6204 bool ActivateLHS = false;
6205
6206 // Emit a special op for trivial copy/move operators.
6207 if (isTrivialMemoryOperation(dyn_cast_if_present<CXXMethodDecl>(FuncDecl))) {
6208 const Function *Func = getFunction(FuncDecl);
6209 if (!Func)
6210 return false;
6211
6212 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
6213 OCE && OCE->isAssignmentOp()) {
6214 const CXXRecordDecl *LHSRecord = Args[0]->getType()->getAsCXXRecordDecl();
6215 ActivateLHS = LHSRecord && LHSRecord->hasTrivialDefaultConstructor();
6216 }
6217 if (const auto *MCE = dyn_cast<CXXMemberCallExpr>(E))
6218 if (!this->visit(MCE->getImplicitObjectArgument()))
6219 return false;
6220
6221 if (!this->visitCallArgs(Args, FuncDecl, /*ActivateLHS=*/ActivateLHS,
6223 return false;
6224
6225 if (!this->emitTrivialCopy(ActivateLHS, Func, E))
6226 return false;
6227
6228 if (!DiscardResult)
6229 return CallScope.destroyLocals();
6230 return this->emitPopPtr(E) && CallScope.destroyLocals();
6231 }
6232
6233 QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
6235 bool HasRVO = !ReturnType->isVoidType() && !T;
6236
6237 if (HasRVO) {
6238 if (DiscardResult) {
6239 // If we need to discard the return value but the function returns its
6240 // value via an RVO pointer, we need to create one such pointer just
6241 // for this call.
6242 if (UnsignedOrNone LocalIndex = allocateLocal(E)) {
6243 if (!this->emitGetPtrLocal(*LocalIndex, E))
6244 return false;
6245 }
6246 } else {
6247 // We need the result. Prepare a pointer to return or
6248 // dup the current one.
6249 if (!Initializing) {
6250 if (UnsignedOrNone LocalIndex = allocateLocal(E)) {
6251 if (!this->emitGetPtrLocal(*LocalIndex, E))
6252 return false;
6253 }
6254 }
6255 if (!this->emitDupPtr(E))
6256 return false;
6257 }
6258 }
6259
6260 const Expr *ReversedArgs[2];
6261 bool IsAssignmentOperatorCall = false;
6262 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
6263 OCE && OCE->isAssignmentOp()) {
6264 // Just like with regular assignments, we need to special-case assignment
6265 // operators here and evaluate the RHS (the second arg) before the LHS (the
6266 // first arg). We fix this by using a Flip op later.
6267 assert(Args.size() == 2);
6268 const CXXRecordDecl *LHSRecord = Args[0]->getType()->getAsCXXRecordDecl();
6269 ActivateLHS = LHSRecord && LHSRecord->hasTrivialDefaultConstructor();
6270 IsAssignmentOperatorCall = true;
6271 ReversedArgs[0] = Args[1];
6272 ReversedArgs[1] = Args[0];
6273 Args = ReversedArgs;
6274 }
6275
6276 // Calling a static operator will still
6277 // pass the instance, but we don't need it.
6278 // Discard it here.
6279 if (isa<CXXOperatorCallExpr>(E)) {
6280 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
6281 MD && MD->isStatic()) {
6282 if (!this->discard(E->getArg(0)))
6283 return false;
6284 // Drop first arg.
6285 Args = Args.drop_front();
6286 }
6287 }
6288
6289 bool Devirtualized = false;
6290 UnsignedOrNone CalleeOffset = std::nullopt;
6291 // Add the (optional, implicit) This pointer.
6292 if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
6293 if (!FuncDecl && classifyPrim(E->getCallee()) == PT_MemberPtr) {
6294 // If we end up creating a CallPtr op for this, we need the base of the
6295 // member pointer as the instance pointer, and later extract the function
6296 // decl as the function pointer.
6297 const Expr *Callee = E->getCallee();
6298 CalleeOffset =
6299 this->allocateLocalPrimitive(Callee, PT_MemberPtr, /*IsConst=*/true);
6300 if (!this->visit(Callee))
6301 return false;
6302 if (!this->emitSetLocal(PT_MemberPtr, *CalleeOffset, E))
6303 return false;
6304 if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
6305 return false;
6306 if (!this->emitGetMemberPtrBase(E))
6307 return false;
6308 } else {
6309 const auto *InstancePtr = MC->getImplicitObjectArgument();
6310 if (isa_and_nonnull<CXXDestructorDecl>(CompilingFunction) ||
6311 isa_and_nonnull<CXXConstructorDecl>(CompilingFunction)) {
6312 const auto *Stripped = stripCheckedDerivedToBaseCasts(InstancePtr);
6313 if (isa<CXXThisExpr>(Stripped)) {
6314 FuncDecl =
6315 cast<CXXMethodDecl>(FuncDecl)->getCorrespondingMethodInClass(
6316 Stripped->getType()->getPointeeType()->getAsCXXRecordDecl());
6317 Devirtualized = true;
6318 if (!this->visit(Stripped))
6319 return false;
6320 } else {
6321 if (!this->visit(InstancePtr))
6322 return false;
6323 }
6324 } else {
6325 if (!this->visit(InstancePtr))
6326 return false;
6327 }
6328 }
6329 } else if (const auto *PD =
6330 dyn_cast<CXXPseudoDestructorExpr>(E->getCallee())) {
6331 if (!this->emitCheckPseudoDtor(E))
6332 return false;
6333 const Expr *Base = PD->getBase();
6334 // E.g. `using T = int; 0.~T();`.
6335 if (OptPrimType BaseT = classify(Base); !BaseT || BaseT != PT_Ptr)
6336 return this->discard(Base);
6337 if (!this->visit(Base))
6338 return false;
6339 return this->emitPseudoDtor(E);
6340 } else if (!FuncDecl) {
6341 const Expr *Callee = E->getCallee();
6342 CalleeOffset =
6343 this->allocateLocalPrimitive(Callee, PT_Ptr, /*IsConst=*/true);
6344 if (!this->visit(Callee))
6345 return false;
6346 if (!this->emitSetLocal(PT_Ptr, *CalleeOffset, E))
6347 return false;
6348 }
6349
6350 if (!this->visitCallArgs(Args, FuncDecl, ActivateLHS,
6352 return false;
6353
6354 // Undo the argument reversal we did earlier.
6355 if (IsAssignmentOperatorCall) {
6356 assert(Args.size() == 2);
6357 PrimType Arg1T = classify(Args[0]).value_or(PT_Ptr);
6358 PrimType Arg2T = classify(Args[1]).value_or(PT_Ptr);
6359 if (!this->emitFlip(Arg2T, Arg1T, E))
6360 return false;
6361 }
6362
6363 if (FuncDecl) {
6364 const Function *Func = getFunction(FuncDecl);
6365 if (!Func)
6366 return false;
6367
6368 // In error cases, the function may be called with fewer arguments than
6369 // parameters.
6370 if (E->getNumArgs() < Func->getNumWrittenParams())
6371 return false;
6372
6373 assert(HasRVO == Func->hasRVO());
6374
6375 bool HasQualifier = false;
6376 if (const auto *ME = dyn_cast<MemberExpr>(E->getCallee()))
6377 HasQualifier = ME->hasQualifier();
6378
6379 bool IsVirtual = false;
6380 if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
6381 IsVirtual = !Devirtualized && MD->isVirtual();
6382
6383 // In any case call the function. The return value will end up on the stack
6384 // and if the function has RVO, we already have the pointer on the stack to
6385 // write the result into.
6386 if (IsVirtual && !HasQualifier) {
6387 uint32_t VarArgSize = 0;
6388 unsigned NumParams =
6389 Func->getNumWrittenParams() +
6390 (isa<CXXOperatorCallExpr>(E) && Func->hasImplicitThisPointer());
6391 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
6392 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
6393
6394 if (!this->emitCallVirt(Func, VarArgSize, E))
6395 return false;
6396 } else if (Func->isVariadic()) {
6397 uint32_t VarArgSize = 0;
6398 unsigned NumParams =
6399 Func->getNumWrittenParams() +
6400 (isa<CXXOperatorCallExpr>(E) && Func->hasImplicitThisPointer());
6401 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
6402 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
6403 if (!this->emitCallVar(Func, VarArgSize, E))
6404 return false;
6405 } else {
6406 if (!this->emitCall(Func, 0, E))
6407 return false;
6408 }
6409 } else {
6410 // Indirect call. Visit the callee, which will leave a FunctionPointer on
6411 // the stack. Cleanup of the returned value if necessary will be done after
6412 // the function call completed.
6413
6414 // Sum the size of all args from the call expr.
6415 uint32_t ArgSize = 0;
6416 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
6417 ArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
6418
6419 // Get the callee, either from a member pointer or function pointer saved in
6420 // CalleeOffset.
6421 if (isa<CXXMemberCallExpr>(E) && CalleeOffset) {
6422 if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
6423 return false;
6424 if (!this->emitGetMemberPtrDecl(E))
6425 return false;
6426 } else {
6427 if (!this->emitGetLocal(PT_Ptr, *CalleeOffset, E))
6428 return false;
6429 }
6430 if (!this->emitCallPtr(ArgSize, E, E))
6431 return false;
6432 }
6433
6434 // Cleanup for discarded return values.
6435 if (DiscardResult && !ReturnType->isVoidType() && T)
6436 return this->emitPop(*T, E) && CallScope.destroyLocals();
6437
6438 return CallScope.destroyLocals();
6439}
6440
6441template <class Emitter>
6443 SourceLocScope<Emitter> SLS(this, E);
6444
6445 return this->delegate(E->getExpr());
6446}
6447
6448template <class Emitter>
6450 SourceLocScope<Emitter> SLS(this, E);
6451
6452 return this->delegate(E->getExpr());
6453}
6454
6455template <class Emitter>
6457 if (DiscardResult)
6458 return true;
6459
6460 return this->emitConstBool(E->getValue(), E);
6461}
6462
6463template <class Emitter>
6465 const CXXNullPtrLiteralExpr *E) {
6466 if (DiscardResult)
6467 return true;
6468
6469 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(E->getType());
6470 return this->emitNullPtr(Val, nullptr, E);
6471}
6472
6473template <class Emitter>
6475 if (DiscardResult)
6476 return true;
6477
6478 assert(E->getType()->isIntegerType());
6479
6481 return this->emitZero(T, E);
6482}
6483
6484template <class Emitter>
6486 if (DiscardResult)
6487 return true;
6488
6489 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
6490 if (this->LambdaThisCapture.Offset > 0) {
6491 if (this->LambdaThisCapture.IsPtr)
6492 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
6493 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
6494 }
6495 }
6496
6497 // In some circumstances, the 'this' pointer does not actually refer to the
6498 // instance pointer of the current function frame, but e.g. to the declaration
6499 // currently being initialized. Here we emit the necessary instruction(s) for
6500 // this scenario.
6501 if (!InitStackActive || InitStack.empty())
6502 return this->emitThis(E);
6503
6504 // If our init stack is, for example:
6505 // 0 Stack: 3 (decl)
6506 // 1 Stack: 6 (init list)
6507 // 2 Stack: 1 (field)
6508 // 3 Stack: 6 (init list)
6509 // 4 Stack: 1 (field)
6510 //
6511 // We want to find the LAST element in it that's an init list,
6512 // which is marked with the K_InitList marker. The index right
6513 // before that points to an init list. We need to find the
6514 // elements before the K_InitList element that point to a base
6515 // (e.g. a decl or This), optionally followed by field, elem, etc.
6516 // In the example above, we want to emit elements [0..2].
6517 unsigned StartIndex = 0;
6518 unsigned EndIndex = 0;
6519 // Find the init list.
6520 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
6521 if (InitStack[StartIndex].Kind == InitLink::K_DIE) {
6522 EndIndex = StartIndex;
6523 --StartIndex;
6524 break;
6525 }
6526 }
6527
6528 // Walk backwards to find the base.
6529 for (; StartIndex > 0; --StartIndex) {
6530 if (InitStack[StartIndex].Kind == InitLink::K_InitList)
6531 continue;
6532
6533 if (InitStack[StartIndex].Kind != InitLink::K_Field &&
6534 InitStack[StartIndex].Kind != InitLink::K_Elem &&
6535 InitStack[StartIndex].Kind != InitLink::K_Base &&
6536 InitStack[StartIndex].Kind != InitLink::K_DIE)
6537 break;
6538 }
6539
6540 if (StartIndex == 0 && EndIndex == 0)
6541 EndIndex = InitStack.size() - 1;
6542
6543 assert(InitStack[StartIndex].Kind == InitLink::K_Decl ||
6544 InitStack[StartIndex].Kind == InitLink::K_This ||
6545 InitStack[StartIndex].Kind == InitLink::K_Temp ||
6546 InitStack[StartIndex].Kind == InitLink::K_RVO);
6547
6548 // NOTE: This could be StartIndex < EndIndex, but we're also abusing the
6549 // InitStack mechanism in visitWithSubstitutions to have the This pointer
6550 // _just_ be a local variable.
6551 assert(StartIndex <= EndIndex);
6552
6553 // Emit the instructions.
6554 for (unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
6555 if (InitStack[I].Kind == InitLink::K_InitList ||
6556 InitStack[I].Kind == InitLink::K_DIE)
6557 continue;
6558 if (!InitStack[I].template emit<Emitter>(this, E))
6559 return false;
6560 }
6561 return true;
6562}
6563
6564template <class Emitter> bool Compiler<Emitter>::visitStmt(const Stmt *S) {
6565 switch (S->getStmtClass()) {
6566 case Stmt::CompoundStmtClass:
6568 case Stmt::DeclStmtClass:
6569 return visitDeclStmt(cast<DeclStmt>(S), /*EvaluateConditionDecl=*/true);
6570 case Stmt::ReturnStmtClass:
6572 case Stmt::IfStmtClass:
6573 return visitIfStmt(cast<IfStmt>(S));
6574 case Stmt::WhileStmtClass:
6576 case Stmt::DoStmtClass:
6577 return visitDoStmt(cast<DoStmt>(S));
6578 case Stmt::ForStmtClass:
6579 return visitForStmt(cast<ForStmt>(S));
6580 case Stmt::CXXForRangeStmtClass:
6582 case Stmt::BreakStmtClass:
6584 case Stmt::ContinueStmtClass:
6586 case Stmt::SwitchStmtClass:
6588 case Stmt::CaseStmtClass:
6589 return visitCaseStmt(cast<CaseStmt>(S));
6590 case Stmt::DefaultStmtClass:
6592 case Stmt::AttributedStmtClass:
6594 case Stmt::CXXTryStmtClass:
6596 case Stmt::NullStmtClass:
6597 return true;
6598 // Always invalid statements.
6599 case Stmt::GCCAsmStmtClass:
6600 case Stmt::MSAsmStmtClass:
6601 case Stmt::GotoStmtClass:
6602 return this->emitInvalid(S);
6603 case Stmt::LabelStmtClass:
6604 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
6605 case Stmt::CXXExpansionStmtInstantiationClass:
6608 default: {
6609 if (const auto *E = dyn_cast<Expr>(S))
6610 return this->discard(E);
6611 return false;
6612 }
6613 }
6614}
6615
6616template <class Emitter>
6619 for (const auto *InnerStmt : S->body())
6620 if (!visitStmt(InnerStmt))
6621 return false;
6622 return Scope.destroyLocals();
6623}
6624
6625template <class Emitter>
6626bool Compiler<Emitter>::maybeEmitDeferredVarInit(const VarDecl *VD) {
6627 if (auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
6628 for (auto *BD : DD->flat_bindings())
6629 if (auto *KD = BD->getHoldingVar();
6630 KD && !this->visitVarDecl(KD, KD->getInit()))
6631 return false;
6632 }
6633 return true;
6634}
6635
6637 assert(FD);
6638 assert(FD->getParent()->isUnion());
6639 const CXXRecordDecl *CXXRD =
6641 return !CXXRD || CXXRD->hasTrivialDefaultConstructor();
6642}
6643
6644template <class Emitter> bool Compiler<Emitter>::refersToUnion(const Expr *E) {
6645 for (;;) {
6646 if (const auto *ME = dyn_cast<MemberExpr>(E)) {
6647 if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6648 FD && FD->getParent()->isUnion() && hasTrivialDefaultCtorParent(FD))
6649 return true;
6650 E = ME->getBase();
6651 continue;
6652 }
6653
6654 if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6655 E = ASE->getBase()->IgnoreImplicit();
6656 continue;
6657 }
6658
6659 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E);
6660 ICE && (ICE->getCastKind() == CK_NoOp ||
6661 ICE->getCastKind() == CK_DerivedToBase ||
6662 ICE->getCastKind() == CK_UncheckedDerivedToBase)) {
6663 E = ICE->getSubExpr();
6664 continue;
6665 }
6666
6667 if (const auto *This = dyn_cast<CXXThisExpr>(E)) {
6668 const auto *ThisRecord =
6669 This->getType()->getPointeeType()->getAsRecordDecl();
6670 if (!ThisRecord->isUnion())
6671 return false;
6672 // Otherwise, always activate if we're in the ctor.
6673 if (const auto *Ctor =
6674 dyn_cast_if_present<CXXConstructorDecl>(CompilingFunction))
6675 return Ctor->getParent() == ThisRecord;
6676 return false;
6677 }
6678
6679 break;
6680 }
6681 return false;
6682}
6683
6684template <class Emitter>
6686 bool EvaluateConditionDecl) {
6687 for (const auto *D : DS->decls()) {
6690 continue;
6691
6692 if (const auto *ESD = dyn_cast<CXXExpansionStmtDecl>(D)) {
6693 assert(ESD->getInstantiations() && "not expanded?");
6694 if (!this->visitStmt(ESD->getInstantiations()))
6695 return false;
6696 continue;
6697 }
6698
6699 const auto *VD = dyn_cast<VarDecl>(D);
6700 if (!VD)
6701 return false;
6702 if (!this->visitVarDecl(VD, VD->getInit()))
6703 return false;
6704
6705 // Register decomposition decl holding vars.
6706 if (EvaluateConditionDecl && !this->maybeEmitDeferredVarInit(VD))
6707 return false;
6708 }
6709
6710 return true;
6711}
6712
6713template <class Emitter>
6715 if (this->InStmtExpr)
6716 return this->emitUnsupported(RS);
6717
6718 if (const Expr *RE = RS->getRetValue()) {
6719 LocalScope<Emitter> RetScope(this);
6720 if (ReturnType) {
6721 // Primitive types are simply returned.
6722 if (!this->visit(RE))
6723 return false;
6724 this->emitCleanup();
6725 return this->emitRet(*ReturnType, RS);
6726 }
6727
6728 if (RE->getType()->isVoidType()) {
6729 if (!this->visit(RE))
6730 return false;
6731 } else {
6732 if (RE->containsErrors())
6733 return false;
6734
6736 // RVO - construct the value in the return location.
6737 if (!this->emitRVOPtr(RE))
6738 return false;
6739 if (!this->visitInitializerPop(RE))
6740 return false;
6741
6742 this->emitCleanup();
6743 return this->emitRetVoid(RS);
6744 }
6745 }
6746
6747 // Void return.
6748 this->emitCleanup();
6749 return this->emitRetVoid(RS);
6750}
6751
6752template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
6753 LocalScope<Emitter> IfScope(this);
6754
6755 auto visitChildStmt = [&](const Stmt *S) -> bool {
6756 LocalScope<Emitter> SScope(this);
6757 if (!visitStmt(S))
6758 return false;
6759 return SScope.destroyLocals();
6760 };
6761
6762 if (auto *CondInit = IS->getInit()) {
6763 if (!visitStmt(CondInit))
6764 return false;
6765 }
6766
6767 if (const DeclStmt *CondDecl = IS->getConditionVariableDeclStmt()) {
6768 if (!visitDeclStmt(CondDecl))
6769 return false;
6770 }
6771
6772 // Save ourselves compiling some code and the jumps, etc. if the condition is
6773 // stataically known to be either true or false. We could look at more cases
6774 // here, but I think all the ones that actually happen are using a
6775 // ConstantExpr.
6776 if (std::optional<bool> BoolValue = getBoolValue(IS->getCond())) {
6777 if (*BoolValue)
6778 return visitChildStmt(IS->getThen());
6779 if (const Stmt *Else = IS->getElse())
6780 return visitChildStmt(Else);
6781 return true;
6782 }
6783
6784 // Otherwise, compile the condition.
6785 if (IS->isNonNegatedConsteval()) {
6786 if (!this->emitIsConstantContext(IS))
6787 return false;
6788 } else if (IS->isNegatedConsteval()) {
6789 if (!this->emitIsConstantContext(IS))
6790 return false;
6791 if (!this->emitInv(IS))
6792 return false;
6793 } else {
6795 if (!this->visitBool(IS->getCond()))
6796 return false;
6797 if (!CondScope.destroyLocals())
6798 return false;
6799 }
6800
6801 if (!this->maybeEmitDeferredVarInit(IS->getConditionVariable()))
6802 return false;
6803
6804 if (const Stmt *Else = IS->getElse()) {
6805 LabelTy LabelElse = this->getLabel();
6806 LabelTy LabelEnd = this->getLabel();
6807 if (!this->jumpFalse(LabelElse, IS))
6808 return false;
6809 if (!visitChildStmt(IS->getThen()))
6810 return false;
6811 if (!this->jump(LabelEnd, IS))
6812 return false;
6813 this->emitLabel(LabelElse);
6814 if (!visitChildStmt(Else))
6815 return false;
6816 this->emitLabel(LabelEnd);
6817 } else {
6818 LabelTy LabelEnd = this->getLabel();
6819 if (!this->jumpFalse(LabelEnd, IS))
6820 return false;
6821 if (!visitChildStmt(IS->getThen()))
6822 return false;
6823 this->emitLabel(LabelEnd);
6824 }
6825
6826 if (!IfScope.destroyLocals())
6827 return false;
6828
6829 return true;
6830}
6831
6832template <class Emitter>
6834 const Expr *Cond = S->getCond();
6835 const Stmt *Body = S->getBody();
6836
6837 LabelTy CondLabel = this->getLabel(); // Label before the condition.
6838 LabelTy EndLabel = this->getLabel(); // Label after the loop.
6839 LocalScope<Emitter> WholeLoopScope(this);
6840 LoopScope<Emitter> LS(this, S, EndLabel, CondLabel);
6841
6842 this->fallthrough(CondLabel);
6843 this->emitLabel(CondLabel);
6844
6845 // Start of the loop body {
6846 LocalScope<Emitter> CondScope(this);
6847
6848 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt()) {
6849 if (!visitDeclStmt(CondDecl))
6850 return false;
6851 }
6852
6853 if (!this->visitBool(Cond))
6854 return false;
6855
6856 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
6857 return false;
6858
6859 if (!this->jumpFalse(EndLabel, S))
6860 return false;
6861
6862 if (!this->visitStmt(Body))
6863 return false;
6864
6865 if (!CondScope.destroyLocals())
6866 return false;
6867 // } End of loop body.
6868
6869 if (!this->jump(CondLabel, S))
6870 return false;
6871 this->fallthrough(EndLabel);
6872 this->emitLabel(EndLabel);
6873
6874 return CondScope.destroyLocals() && WholeLoopScope.destroyLocals();
6875}
6876
6877template <class Emitter> bool Compiler<Emitter>::visitDoStmt(const DoStmt *S) {
6878 const Expr *Cond = S->getCond();
6879 const Stmt *Body = S->getBody();
6880
6881 LabelTy StartLabel = this->getLabel();
6882 LabelTy EndLabel = this->getLabel();
6883 LabelTy CondLabel = this->getLabel();
6884 LocalScope<Emitter> WholeLoopScope(this);
6885 LoopScope<Emitter> LS(this, S, EndLabel, CondLabel);
6886
6887 this->fallthrough(StartLabel);
6888 this->emitLabel(StartLabel);
6889
6890 {
6891 LocalScope<Emitter> CondScope(this);
6892 if (!this->visitStmt(Body))
6893 return false;
6894 this->fallthrough(CondLabel);
6895 this->emitLabel(CondLabel);
6896 if (!this->visitBool(Cond))
6897 return false;
6898
6899 if (!CondScope.destroyLocals())
6900 return false;
6901 }
6902 if (!this->jumpTrue(StartLabel, S))
6903 return false;
6904
6905 this->fallthrough(EndLabel);
6906 this->emitLabel(EndLabel);
6907 return WholeLoopScope.destroyLocals();
6908}
6909
6910template <class Emitter>
6912 // for (Init; Cond; Inc) { Body }
6913 const Stmt *Init = S->getInit();
6914 const Expr *Cond = S->getCond();
6915 const Expr *Inc = S->getInc();
6916 const Stmt *Body = S->getBody();
6917
6918 LabelTy EndLabel = this->getLabel();
6919 LabelTy CondLabel = this->getLabel();
6920 LabelTy IncLabel = this->getLabel();
6921
6922 LocalScope<Emitter> WholeLoopScope(this);
6923 if (Init && !this->visitStmt(Init))
6924 return false;
6925
6926 // Start of the loop body {
6927 this->fallthrough(CondLabel);
6928 this->emitLabel(CondLabel);
6929
6930 LocalScope<Emitter> CondScope(this);
6931 LoopScope<Emitter> LS(this, S, EndLabel, IncLabel);
6932 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt()) {
6933 if (!visitDeclStmt(CondDecl))
6934 return false;
6935 }
6936
6937 if (Cond) {
6938 if (!this->visitBool(Cond))
6939 return false;
6940 if (!this->jumpFalse(EndLabel, S))
6941 return false;
6942 }
6943 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
6944 return false;
6945
6946 if (Body && !this->visitStmt(Body))
6947 return false;
6948
6949 this->fallthrough(IncLabel);
6950 this->emitLabel(IncLabel);
6951 if (Inc && !this->discard(Inc))
6952 return false;
6953
6954 if (!CondScope.destroyLocals())
6955 return false;
6956 if (!this->jump(CondLabel, S))
6957 return false;
6958 // } End of loop body.
6959
6960 this->emitLabel(EndLabel);
6961 // If we jumped out of the loop above, we still need to clean up the condition
6962 // scope.
6963 return CondScope.destroyLocals() && WholeLoopScope.destroyLocals();
6964}
6965
6966template <class Emitter>
6968 const Stmt *Init = S->getInit();
6969 const Expr *Cond = S->getCond();
6970 const Expr *Inc = S->getInc();
6971 const Stmt *Body = S->getBody();
6972 const Stmt *BeginStmt = S->getBeginStmt();
6973 const Stmt *RangeStmt = S->getRangeStmt();
6974 const Stmt *EndStmt = S->getEndStmt();
6975
6976 LabelTy EndLabel = this->getLabel();
6977 LabelTy CondLabel = this->getLabel();
6978 LabelTy IncLabel = this->getLabel();
6979 LocalScope<Emitter> WholeLoopScope(this);
6980 LoopScope<Emitter> LS(this, S, EndLabel, IncLabel);
6981
6982 // Emit declarations needed in the loop.
6983 if (Init && !this->visitStmt(Init))
6984 return false;
6985 if (!this->visitStmt(RangeStmt))
6986 return false;
6987 if (!this->visitStmt(BeginStmt))
6988 return false;
6989 if (!this->visitStmt(EndStmt))
6990 return false;
6991
6992 LocalScope<Emitter> CondScope(this);
6993 // Now the condition as well as the loop variable assignment.
6994 this->fallthrough(CondLabel);
6995 this->emitLabel(CondLabel);
6996 if (!this->visitBool(Cond))
6997 return false;
6998 if (!this->jumpFalse(EndLabel, S))
6999 return false;
7000
7001 if (!this->visitDeclStmt(S->getLoopVarStmt(), /*EvaluateConditionDecl=*/true))
7002 return false;
7003
7004 // Body.
7005 {
7006 if (!this->visitStmt(Body))
7007 return false;
7008
7009 this->fallthrough(IncLabel);
7010 this->emitLabel(IncLabel);
7011 if (!this->discard(Inc))
7012 return false;
7013 }
7014
7015 if (!CondScope.destroyLocals())
7016 return false;
7017 if (!this->jump(CondLabel, S))
7018 return false;
7019
7020 this->fallthrough(EndLabel);
7021 this->emitLabel(EndLabel);
7022 return WholeLoopScope.destroyLocals();
7023}
7024
7025template <class Emitter>
7027 if (LabelInfoStack.empty())
7028 return false;
7029
7030 OptLabelTy TargetLabel = std::nullopt;
7031 const Stmt *TargetLoop = S->getNamedLoopOrSwitch();
7032 const VariableScope<Emitter> *BreakScope = nullptr;
7033
7034 if (!TargetLoop) {
7035 for (const auto &LI : llvm::reverse(LabelInfoStack)) {
7036 if (LI.BreakLabel) {
7037 TargetLabel = *LI.BreakLabel;
7038 BreakScope = LI.BreakOrContinueScope;
7039 break;
7040 }
7041 }
7042 } else {
7043 for (const auto &LI : LabelInfoStack) {
7044 if (LI.Name == TargetLoop) {
7045 TargetLabel = *LI.BreakLabel;
7046 BreakScope = LI.BreakOrContinueScope;
7047 break;
7048 }
7049 }
7050 }
7051
7052 // Faulty break statement (e.g. label redefined or named loops disabled).
7053 if (!TargetLabel)
7054 return false;
7055
7056 for (VariableScope<Emitter> *C = this->VarScope; C != BreakScope;
7057 C = C->getParent()) {
7058 if (!C->destroyLocals())
7059 return false;
7060 }
7061
7062 return this->jump(*TargetLabel, S);
7063}
7064
7065template <class Emitter>
7067 if (LabelInfoStack.empty())
7068 return false;
7069
7070 OptLabelTy TargetLabel = std::nullopt;
7071 const Stmt *TargetLoop = S->getNamedLoopOrSwitch();
7072 const VariableScope<Emitter> *ContinueScope = nullptr;
7073
7074 if (!TargetLoop) {
7075 for (const auto &LI : llvm::reverse(LabelInfoStack)) {
7076 if (LI.ContinueLabel) {
7077 TargetLabel = *LI.ContinueLabel;
7078 ContinueScope = LI.BreakOrContinueScope;
7079 break;
7080 }
7081 }
7082 } else {
7083 for (auto LI : LabelInfoStack) {
7084 if (LI.Name == TargetLoop) {
7085 TargetLabel = *LI.ContinueLabel;
7086 ContinueScope = LI.BreakOrContinueScope;
7087 break;
7088 }
7089 }
7090 }
7091
7092 if (!TargetLabel)
7093 return false;
7094
7095 for (VariableScope<Emitter> *C = VarScope; C != ContinueScope;
7096 C = C->getParent()) {
7097 if (!C->destroyLocals())
7098 return false;
7099 }
7100
7101 return this->jump(*TargetLabel, S);
7102}
7103
7104template <class Emitter>
7106 const Expr *Cond = S->getCond();
7107 if (Cond->containsErrors())
7108 return false;
7109
7110 PrimType CondT = this->classifyPrim(Cond->getType());
7111 LocalScope<Emitter> LS(this);
7112 llvm::SaveAndRestore StmtExprSAR(this->SwitchInStmtExpr, this->InStmtExpr);
7113
7114 LabelTy EndLabel = this->getLabel();
7115 UnsignedOrNone DefaultLabel = std::nullopt;
7116 unsigned CondVar =
7117 this->allocateLocalPrimitive(Cond, CondT, /*IsConst=*/true);
7118
7119 if (const auto *CondInit = S->getInit())
7120 if (!visitStmt(CondInit))
7121 return false;
7122
7123 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
7124 if (!visitDeclStmt(CondDecl))
7125 return false;
7126
7127 // Initialize condition variable.
7128 if (!this->visit(Cond))
7129 return false;
7130 if (!this->emitSetLocal(CondT, CondVar, S))
7131 return false;
7132
7133 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
7134 return false;
7135
7137 // Create labels and comparison ops for all case statements.
7138 for (const SwitchCase *SC = S->getSwitchCaseList(); SC;
7139 SC = SC->getNextSwitchCase()) {
7140 if (const auto *CS = dyn_cast<CaseStmt>(SC)) {
7141 CaseLabels[SC] = this->getLabel();
7142
7143 if (CS->caseStmtIsGNURange()) {
7144 LabelTy EndOfRangeCheck = this->getLabel();
7145 const Expr *Low = CS->getLHS();
7146 const Expr *High = CS->getRHS();
7147 if (Low->isValueDependent() || High->isValueDependent())
7148 return false;
7149
7150 if (!this->emitGetLocal(CondT, CondVar, CS))
7151 return false;
7152 if (!this->visit(Low))
7153 return false;
7154 PrimType LT = this->classifyPrim(Low->getType());
7155 if (!this->emitGE(LT, S))
7156 return false;
7157 if (!this->jumpFalse(EndOfRangeCheck, S))
7158 return false;
7159
7160 if (!this->emitGetLocal(CondT, CondVar, CS))
7161 return false;
7162 if (!this->visit(High))
7163 return false;
7164 PrimType HT = this->classifyPrim(High->getType());
7165 if (!this->emitLE(HT, S))
7166 return false;
7167 if (!this->jumpTrue(CaseLabels[CS], S))
7168 return false;
7169 this->emitLabel(EndOfRangeCheck);
7170 continue;
7171 }
7172
7173 const Expr *Value = CS->getLHS();
7174 if (Value->isValueDependent())
7175 return false;
7176 PrimType ValueT = this->classifyPrim(Value->getType());
7177
7178 // Compare the case statement's value to the switch condition.
7179 if (!this->emitGetLocal(CondT, CondVar, CS))
7180 return false;
7181 if (!this->visit(Value))
7182 return false;
7183
7184 // Compare and jump to the case label.
7185 if (!this->emitEQ(ValueT, S))
7186 return false;
7187 if (!this->jumpTrue(CaseLabels[CS], S))
7188 return false;
7189 } else {
7190 assert(!DefaultLabel);
7191 DefaultLabel = this->getLabel();
7192 }
7193 }
7194
7195 // If none of the conditions above were true, fall through to the default
7196 // statement or jump after the switch statement.
7197 if (DefaultLabel) {
7198 if (!this->jump(*DefaultLabel, S))
7199 return false;
7200 } else {
7201 if (!this->jump(EndLabel, S))
7202 return false;
7203 }
7204
7205 SwitchScope<Emitter> SS(this, S, std::move(CaseLabels), EndLabel,
7206 DefaultLabel);
7207 if (!this->visitStmt(S->getBody()))
7208 return false;
7209 this->fallthrough(EndLabel);
7210 this->emitLabel(EndLabel);
7211
7212 return LS.destroyLocals();
7213}
7214
7215template <class Emitter>
7217 this->fallthrough(CaseLabels[S]);
7218 this->emitLabel(CaseLabels[S]);
7219
7220 // We can't jump from an outer switch statement to a case label
7221 // that's inside a StmtExpr.
7222 if (this->InStmtExpr && !this->SwitchInStmtExpr)
7223 return this->emitUnsupported(S);
7224
7225 return this->visitStmt(S->getSubStmt());
7226}
7227
7228template <class Emitter>
7230 if (LabelInfoStack.empty())
7231 return false;
7232
7233 LabelTy DefaultLabel;
7234 for (const LabelInfo &LI : llvm::reverse(LabelInfoStack)) {
7235 if (LI.DefaultLabel) {
7236 DefaultLabel = *LI.DefaultLabel;
7237 break;
7238 }
7239 }
7240
7241 this->emitLabel(DefaultLabel);
7242 return this->visitStmt(S->getSubStmt());
7243}
7244
7245template <class Emitter>
7247 const Stmt *SubStmt = S->getSubStmt();
7248
7249 bool IsMSVCConstexprAttr = isa<ReturnStmt>(SubStmt) &&
7251
7252 if (IsMSVCConstexprAttr && !this->emitPushMSVCCE(S))
7253 return false;
7254
7255 if (this->Ctx.getLangOpts().CXXAssumptions &&
7256 !this->Ctx.getLangOpts().MSVCCompat) {
7257 for (const Attr *A : S->getAttrs()) {
7258 auto *AA = dyn_cast<CXXAssumeAttr>(A);
7259 if (!AA)
7260 continue;
7261
7262 assert(isa<NullStmt>(SubStmt));
7263
7264 const Expr *Assumption = AA->getAssumption();
7265 if (Assumption->isValueDependent())
7266 return false;
7267
7268 if (Assumption->HasSideEffects(this->Ctx.getASTContext()))
7269 continue;
7270
7271 // Evaluate assumption.
7272 if (!this->visitBool(Assumption))
7273 return false;
7274
7275 if (!this->emitAssume(Assumption))
7276 return false;
7277 }
7278 }
7279
7280 // Ignore other attributes.
7281 if (!this->visitStmt(SubStmt))
7282 return false;
7283
7284 if (IsMSVCConstexprAttr)
7285 return this->emitPopMSVCCE(S);
7286 return true;
7287}
7288
7289template <class Emitter>
7291 // Ignore all handlers.
7292 return this->visitStmt(S->getTryBlock());
7293}
7294
7295/// template for (auto x : {1, 2}) {}
7296///
7297/// This is not a loop from an AST perspective at all since it has already
7298/// been instantiated to a list of compound statements.
7299///
7300/// Since we can have control flow in those compound statements, we need to
7301/// handle it mostly like a loop though.
7302template <class Emitter>
7305 LocalScope<Emitter> WholeLoopScope(this, ScopeKind::Block);
7306
7307 for (const Stmt *PreambleStmt : S->getPreambleStmts()) {
7308 if (!this->visitDeclStmt(cast<DeclStmt>(PreambleStmt), true))
7309 return false;
7310 }
7311
7312 LabelTy EndLabel = this->getLabel();
7313 for (const Stmt *Instantiation : S->getInstantiations()) {
7314 LabelTy ContinueLabel = this->getLabel();
7315 LoopScope<Emitter> LS(this, S, EndLabel, ContinueLabel);
7316
7317 if (!this->visitStmt(Instantiation))
7318 return false;
7319 this->emitLabel(ContinueLabel);
7320 }
7321
7322 this->emitLabel(EndLabel);
7323
7324 return WholeLoopScope.destroyLocals();
7325}
7326
7327template <class Emitter>
7328bool Compiler<Emitter>::emitLambdaStaticInvokerBody(const CXXMethodDecl *MD) {
7329 assert(MD->isLambdaStaticInvoker());
7330 assert(MD->hasBody());
7331 assert(cast<CompoundStmt>(MD->getBody())->body_empty());
7332
7333 const CXXRecordDecl *ClosureClass = MD->getParent();
7334 const FunctionDecl *LambdaCallOp;
7335 assert(ClosureClass->captures().empty());
7336 if (ClosureClass->isGenericLambda()) {
7337 LambdaCallOp = ClosureClass->getLambdaCallOperator();
7338 assert(MD->isFunctionTemplateSpecialization() &&
7339 "A generic lambda's static-invoker function must be a "
7340 "template specialization");
7342 FunctionTemplateDecl *CallOpTemplate =
7343 LambdaCallOp->getDescribedFunctionTemplate();
7344 llvm::FoldingSetInsertToken InsertToken;
7345 const FunctionDecl *CorrespondingCallOpSpecialization =
7346 CallOpTemplate->findSpecialization(TAL->asArray(), InsertToken);
7347 assert(CorrespondingCallOpSpecialization);
7348 LambdaCallOp = CorrespondingCallOpSpecialization;
7349 } else {
7350 LambdaCallOp = ClosureClass->getLambdaCallOperator();
7351 }
7352 assert(ClosureClass->captures().empty());
7353 const Function *Func = this->getFunction(LambdaCallOp);
7354 if (!Func)
7355 return false;
7356 assert(Func->hasThisPointer());
7357 assert(Func->getNumParams() == (MD->getNumParams() + 1 + Func->hasRVO()));
7358
7359 if (Func->hasRVO()) {
7360 if (!this->emitRVOPtr(MD))
7361 return false;
7362 }
7363
7364 // The lambda call operator needs an instance pointer, but we don't have
7365 // one here, and we don't need one either because the lambda cannot have
7366 // any captures, as verified above. Emit a null pointer. This is then
7367 // special-cased when interpreting to not emit any misleading diagnostics.
7368 if (!this->emitNullPtr(0, nullptr, MD))
7369 return false;
7370
7371 // Forward all arguments from the static invoker to the lambda call operator.
7372 for (const ParmVarDecl *PVD : MD->parameters()) {
7373 auto It = this->Params.find(PVD);
7374 assert(It != this->Params.end());
7375
7376 // We do the lvalue-to-rvalue conversion manually here, so no need
7377 // to care about references.
7378 PrimType ParamType = this->classify(PVD->getType()).value_or(PT_Ptr);
7379 if (!this->emitGetParam(ParamType, It->second.Index, MD))
7380 return false;
7381 }
7382
7383 if (!this->emitCall(Func, 0, LambdaCallOp))
7384 return false;
7385
7386 this->emitCleanup();
7387 if (ReturnType)
7388 return this->emitRet(*ReturnType, MD);
7389
7390 // Nothing to do, since we emitted the RVO pointer above.
7391 return this->emitRetVoid(MD);
7392}
7393
7394template <class Emitter>
7395bool Compiler<Emitter>::checkLiteralType(const Expr *E) {
7396 if (Ctx.getLangOpts().CPlusPlus23)
7397 return true;
7398
7399 if (!E->isPRValue() || E->getType()->isLiteralType(Ctx.getASTContext()))
7400 return true;
7401
7402 return this->emitCheckLiteralType(E->getType().getTypePtr(), E);
7403}
7404
7406 const Expr *InitExpr = Init->getInit();
7407
7408 if (!Init->isWritten() && !Init->isInClassMemberInitializer() &&
7409 !isa<CXXConstructExpr>(InitExpr))
7410 return true;
7411
7412 if (const auto *CE = dyn_cast<CXXConstructExpr>(InitExpr)) {
7413 const CXXConstructorDecl *Ctor = CE->getConstructor();
7414 if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&
7415 Ctor->isTrivial())
7416 return true;
7417 }
7418
7419 return false;
7420}
7421
7422template <class Emitter>
7423bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
7424 assert(!ReturnType);
7425
7426 // Only start the lifetime of the instance pointer.
7427 if (!this->emitStartThisLifetime1(Ctor))
7428 return false;
7429
7430 auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
7431 const Expr *InitExpr,
7432 bool Activate = false) -> bool {
7433 // We don't know what to do with these, so just return false.
7434 if (InitExpr->getType().isNull())
7435 return false;
7436
7437 if (OptPrimType T = this->classify(InitExpr)) {
7438 if (Activate && !this->emitActivateThisField(FieldOffset, InitExpr))
7439 return false;
7440
7441 if (!this->visit(InitExpr))
7442 return false;
7443
7444 if (F->isBitField())
7445 return this->emitInitThisBitField(*T, FieldOffset, F->bitWidth(),
7446 InitExpr);
7447 return this->emitInitThisField(*T, FieldOffset, InitExpr);
7448 }
7449 // Non-primitive case. Get a pointer to the field-to-initialize
7450 // on the stack and call visitInitialzer() for it.
7451 InitLinkScope<Emitter> FieldScope(this, InitLink::Field(F->Offset));
7452 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
7453 return false;
7454
7455 if (Activate && !this->emitActivate(InitExpr))
7456 return false;
7457
7458 return this->visitInitializerPop(InitExpr);
7459 };
7460
7461 const RecordDecl *RD = Ctor->getParent();
7462 const Record *R = this->getRecord(RD);
7463 if (!R)
7464 return false;
7465 bool IsUnion = R->isUnion();
7466
7467 // Default union copy and move ctors are special.
7468 if (IsUnion && Ctor->isCopyOrMoveConstructor() && Ctor->isDefaulted()) {
7470
7471 // No special case for NumFields == 0 here, so the Memcpy op
7472 // below also does its checks in those cases.
7473
7474 assert(cast<CompoundStmt>(Ctor->getBody())->body_empty());
7475 if (!this->emitThis(Ctor))
7476 return false;
7477
7478 if (!this->emitGetParam(PT_Ptr, /*ParamIndex=*/0, Ctor))
7479 return false;
7480
7481 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
7482 this->emitRetVoid(Ctor);
7483 }
7484
7485 unsigned FieldInits = 0;
7487 // First, initialize virtual bases if the records has them.
7488 if (R->getNumVirtualBases() > 0) {
7489 if (!this->emitThis(Ctor))
7490 return false;
7491 LabelTy AfterVirtBasesLabel = this->getLabel();
7492
7493 // If the instance pointer is a base class, skip the virtual bases.
7494 if (!this->emitIsBaseClass({}))
7495 return false;
7496 if (!this->jumpTrue(AfterVirtBasesLabel, {}))
7497 return false;
7498
7499 for (const auto *Init : Ctor->inits()) {
7500 if (const Type *Base = Init->getBaseClass();
7501 Base && Init->isBaseVirtual()) {
7502 const auto *BaseDecl = Base->getAsCXXRecordDecl();
7503 assert(BaseDecl);
7504 assert(R->findVirtualBase(BaseDecl));
7505 if (!this->emitGetPtrThisVirtBase(BaseDecl, Ctor))
7506 return false;
7507 if (!this->visitInitializerPop(Init->getInit()))
7508 return false;
7509 }
7510 }
7511
7512 this->fallthrough(AfterVirtBasesLabel);
7513 this->emitLabel(AfterVirtBasesLabel);
7514
7515 if (!this->emitPopPtr(Ctor))
7516 return false;
7517 }
7518
7519 for (const auto *Init : Ctor->inits()) {
7520 // Scope needed for the initializers.
7521 LocalScope<Emitter> Scope(this, ScopeKind::FullExpression);
7522
7523 const Expr *InitExpr = Init->getInit();
7524 if (const FieldDecl *Member = Init->getMember()) {
7525 const Record::Field *F = R->getField(Member);
7526
7529 if (!emitFieldInitializer(F, F->Offset, InitExpr, IsUnion))
7530 return false;
7531 ++FieldInits;
7532 } else if (const Type *Base = Init->getBaseClass()) {
7533 const auto *BaseDecl = Base->getAsCXXRecordDecl();
7534 assert(BaseDecl);
7535
7536 if (Init->isBaseVirtual()) {
7537 // See above.
7538 continue;
7539 } else {
7540 // Base class initializer.
7541 // Get This Base and call initializer on it.
7542 const Record::Base *B = R->getBase(BaseDecl);
7543 assert(B);
7544 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
7545 return false;
7546 }
7547
7548 if (!this->visitInitializerPop(InitExpr))
7549 return false;
7550 } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {
7553 unsigned ChainSize = IFD->getChainingSize();
7554 assert(ChainSize >= 2);
7555
7556 unsigned NestedFieldOffset = 0;
7557 const Record::Field *NestedField = nullptr;
7558 for (unsigned I = 0; I != ChainSize; ++I) {
7559 const auto *FD = cast<FieldDecl>(IFD->chain()[I]);
7560 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
7561 assert(FieldRecord);
7562
7563 NestedField = FieldRecord->getField(FD);
7564 assert(NestedField);
7565 IsUnion = IsUnion || FieldRecord->isUnion();
7566
7567 NestedFieldOffset += NestedField->Offset;
7568
7569 // Add a new InitChainLink for the record, but not for the final field.
7570 if (I != ChainSize - 1)
7571 InitStack.push_back(InitLink::Field(NestedField->Offset));
7572 }
7573 assert(NestedField);
7574
7576 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
7577 IsUnion))
7578 return false;
7579
7580 // Mark all chain links as initialized.
7581 unsigned InitFieldOffset = 0;
7582 for (const NamedDecl *ND : IFD->chain().drop_back()) {
7583 const auto *FD = cast<FieldDecl>(ND);
7584 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
7585 assert(FieldRecord);
7586 NestedField = FieldRecord->getField(FD);
7587 InitFieldOffset += NestedField->Offset;
7588 assert(NestedField);
7589 if (!this->emitGetPtrThisField(InitFieldOffset, InitExpr))
7590 return false;
7591 if (!this->emitFinishInitPop(InitExpr))
7592 return false;
7593 }
7594
7595 InitStack.pop_back_n(ChainSize - 1);
7596
7597 } else {
7598 assert(Init->isDelegatingInitializer());
7599 if (!this->emitThis(InitExpr))
7600 return false;
7601 if (!this->visitInitializerPop(Init->getInit()))
7602 return false;
7603 }
7604
7605 if (!Scope.destroyLocals())
7606 return false;
7607 }
7608
7609 if (FieldInits != R->getNumFields()) {
7610 assert(FieldInits < R->getNumFields());
7611 // Start the lifetime of all members.
7612 if (!this->emitStartThisLifetime(Ctor))
7613 return false;
7614 }
7615
7616 if (const Stmt *Body = Ctor->getBody()) {
7617 // Only emit the CtorCheck op for non-empty CompoundStmt bodies.
7618 // For non-CompoundStmts, always assume they are non-empty and emit it.
7619 if (const auto *CS = dyn_cast<CompoundStmt>(Body)) {
7620 if (!CS->body_empty() && !this->emitCtorCheck(SourceInfo{}))
7621 return false;
7622 } else {
7623 if (!this->emitCtorCheck(SourceInfo{}))
7624 return false;
7625 }
7626
7627 if (!visitStmt(Body))
7628 return false;
7629 }
7630
7631 return this->emitRetVoid(SourceInfo{});
7632}
7633
7634template <class Emitter>
7635bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) {
7636 const RecordDecl *RD = Dtor->getParent();
7637 const Record *R = this->getRecord(RD);
7638 if (!R)
7639 return false;
7640
7641 if (!Dtor->isTrivial() && Dtor->getBody()) {
7642 if (!this->visitStmt(Dtor->getBody()))
7643 return false;
7644 }
7645
7646 if (!this->emitThis(Dtor))
7647 return false;
7648
7649 if (!this->emitCheckDestruction(Dtor))
7650 return false;
7651
7652 assert(R);
7653 if (!R->isUnion()) {
7654
7656 // First, destroy all fields.
7657 for (const Record::Field &Field : llvm::reverse(R->fields())) {
7658 const Descriptor *D = Field.Desc;
7659 if (D->hasTrivialDtor())
7660 continue;
7661 if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
7662 return false;
7663 if (!this->emitDestructionPop(D, SourceInfo{}))
7664 return false;
7665 }
7666 }
7667
7668 for (const Record::Base &Base : llvm::reverse(R->bases())) {
7669 if (Base.R->hasTrivialDtor())
7670 continue;
7671 if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
7672 return false;
7673 if (!this->emitRecordDestructionPop(Base.R, {}))
7674 return false;
7675 }
7676
7677 if (R->getNumVirtualBases() > 0) {
7678 LabelTy EndLabel = this->getLabel();
7679 // If this is a base class, skip the virtual bases.
7680 if (!this->emitIsBaseClass({}))
7681 return false;
7682 if (!this->jumpTrue(EndLabel, {}))
7683 return false;
7684
7685 for (const Record::Base &Base : llvm::reverse(R->virtual_bases())) {
7686 if (Base.R->hasTrivialDtor())
7687 continue;
7688 if (!this->emitGetPtrVirtBase(cast<CXXRecordDecl>(Base.R->getDecl()),
7689 SourceInfo{}))
7690 return false;
7691 if (!this->emitRecordDestructionPop(Base.R, {}))
7692 return false;
7693 }
7694
7695 this->fallthrough(EndLabel);
7696 this->emitLabel(EndLabel);
7697 }
7698
7699 if (!this->emitMarkDestroyed(Dtor))
7700 return false;
7701
7702 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
7703}
7704
7705template <class Emitter>
7706bool Compiler<Emitter>::compileUnionAssignmentOperator(
7707 const CXXMethodDecl *MD) {
7708 if (!this->emitThis(MD))
7709 return false;
7710
7711 if (!this->emitGetParam(PT_Ptr, /*ParamIndex=*/0, MD))
7712 return false;
7713
7714 return this->emitMemcpy(MD) && this->emitRet(PT_Ptr, MD);
7715}
7716
7717template <class Emitter>
7719 if (F->getReturnType()->isDependentType())
7720 return false;
7721
7722 // Classify the return type.
7723 ReturnType = this->classify(F->getReturnType());
7724
7725 this->CompilingFunction = F;
7726
7727 if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
7728 return this->compileConstructor(Ctor);
7729 if (const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
7730 return this->compileDestructor(Dtor);
7731
7732 // Emit custom code if this is a lambda static invoker.
7733 if (const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
7734 const RecordDecl *RD = MD->getParent();
7735
7736 if (RD->isUnion() &&
7738 return this->compileUnionAssignmentOperator(MD);
7739
7740 if (MD->isLambdaStaticInvoker())
7741 return this->emitLambdaStaticInvokerBody(MD);
7742 }
7743
7744 // Regular functions.
7745 if (const auto *Body = F->getBody())
7746 if (!visitStmt(Body))
7747 return false;
7748
7749 // Emit a guard return to protect against a code path missing one.
7750 if (F->getReturnType()->isVoidType())
7751 return this->emitRetVoid(SourceInfo{});
7752 return this->emitNoRet(SourceInfo{});
7753}
7754
7755static uint32_t getBitWidth(const Expr *E) {
7756 assert(E->refersToBitField());
7757 const auto *ME = cast<MemberExpr>(E);
7758 const auto *FD = cast<FieldDecl>(ME->getMemberDecl());
7759 return FD->getBitWidthValue();
7760}
7761
7762template <class Emitter>
7764 if (E->containsErrors())
7765 return false;
7766
7767 const Expr *SubExpr = E->getSubExpr();
7768 if (SubExpr->getType()->isAnyComplexType())
7769 return this->VisitComplexUnaryOperator(E);
7770 if (SubExpr->getType()->isVectorType())
7771 return this->VisitVectorUnaryOperator(E);
7772 if (SubExpr->getType()->isFixedPointType())
7773 return this->VisitFixedPointUnaryOperator(E);
7774 OptPrimType T = classify(SubExpr->getType());
7775
7776 switch (E->getOpcode()) {
7777 case UO_PostInc: { // x++
7778 if (!Ctx.getLangOpts().CPlusPlus14)
7779 return this->emitInvalid(E);
7780 if (!T)
7781 return this->emitError(E);
7782
7783 if (!this->visit(SubExpr))
7784 return false;
7785
7786 if (T == PT_Ptr) {
7787 if (!this->emitIncPtr(E))
7788 return false;
7789
7790 return DiscardResult ? this->emitPopPtr(E) : true;
7791 }
7792
7793 if (T == PT_Float)
7794 return DiscardResult ? this->emitIncfPop(getFPOptions(E), E)
7795 : this->emitIncf(getFPOptions(E), E);
7796
7797 if (SubExpr->refersToBitField())
7798 return DiscardResult ? this->emitIncPopBitfield(*T, E->canOverflow(),
7799 getBitWidth(SubExpr), E)
7800 : this->emitIncBitfield(*T, E->canOverflow(),
7801 getBitWidth(SubExpr), E);
7802
7803 return DiscardResult ? this->emitIncPop(*T, E->canOverflow(), E)
7804 : this->emitInc(*T, E->canOverflow(), E);
7805 }
7806 case UO_PostDec: { // x--
7807 if (!Ctx.getLangOpts().CPlusPlus14)
7808 return this->emitInvalid(E);
7809 if (!T)
7810 return this->emitError(E);
7811
7812 if (!this->visit(SubExpr))
7813 return false;
7814
7815 if (T == PT_Ptr) {
7816 if (!this->emitDecPtr(E))
7817 return false;
7818
7819 return DiscardResult ? this->emitPopPtr(E) : true;
7820 }
7821
7822 if (T == PT_Float)
7823 return DiscardResult ? this->emitDecfPop(getFPOptions(E), E)
7824 : this->emitDecf(getFPOptions(E), E);
7825
7826 if (SubExpr->refersToBitField()) {
7827 return DiscardResult ? this->emitDecPopBitfield(*T, E->canOverflow(),
7828 getBitWidth(SubExpr), E)
7829 : this->emitDecBitfield(*T, E->canOverflow(),
7830 getBitWidth(SubExpr), E);
7831 }
7832
7833 return DiscardResult ? this->emitDecPop(*T, E->canOverflow(), E)
7834 : this->emitDec(*T, E->canOverflow(), E);
7835 }
7836 case UO_PreInc: { // ++x
7837 if (!Ctx.getLangOpts().CPlusPlus14)
7838 return this->emitInvalid(E);
7839 if (!T)
7840 return this->emitError(E);
7841
7842 if (!this->visit(SubExpr))
7843 return false;
7844
7845 if (T == PT_Ptr) {
7846 if (!this->emitLoadPtr(E))
7847 return false;
7848 if (!this->emitConstUint8(1, E))
7849 return false;
7850 if (!this->emitAddOffsetUint8(E))
7851 return false;
7852 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7853 }
7854
7855 // Post-inc and pre-inc are the same if the value is to be discarded.
7856 if (DiscardResult) {
7857 if (T == PT_Float)
7858 return this->emitIncfPop(getFPOptions(E), E);
7859 if (SubExpr->refersToBitField())
7860 return DiscardResult ? this->emitIncPopBitfield(*T, E->canOverflow(),
7861 getBitWidth(SubExpr), E)
7862 : this->emitIncBitfield(*T, E->canOverflow(),
7863 getBitWidth(SubExpr), E);
7864 return this->emitIncPop(*T, E->canOverflow(), E);
7865 }
7866
7867 if (T == PT_Float) {
7868 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
7869 if (!this->emitLoadFloat(E))
7870 return false;
7871 APFloat F(TargetSemantics, 1);
7872 if (!this->emitFloat(F, E))
7873 return false;
7874
7875 if (!this->emitAddf(getFPOptions(E), E))
7876 return false;
7877 if (!this->emitStoreFloat(E))
7878 return false;
7879 } else if (SubExpr->refersToBitField()) {
7880 assert(isIntegerOrBoolType(*T));
7881 if (!this->emitPreIncBitfield(*T, E->canOverflow(), getBitWidth(SubExpr),
7882 E))
7883 return false;
7884 } else {
7885 assert(isIntegerOrBoolType(*T));
7886 if (!this->emitPreInc(*T, E->canOverflow(), E))
7887 return false;
7888 }
7889 return E->isGLValue() || this->emitLoadPop(*T, E);
7890 }
7891 case UO_PreDec: { // --x
7892 if (!Ctx.getLangOpts().CPlusPlus14)
7893 return this->emitInvalid(E);
7894 if (!T)
7895 return this->emitError(E);
7896
7897 if (!this->visit(SubExpr))
7898 return false;
7899
7900 if (T == PT_Ptr) {
7901 if (!this->emitLoadPtr(E))
7902 return false;
7903 if (!this->emitConstUint8(1, E))
7904 return false;
7905 if (!this->emitSubOffsetUint8(E))
7906 return false;
7907 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7908 }
7909
7910 // Post-dec and pre-dec are the same if the value is to be discarded.
7911 if (DiscardResult) {
7912 if (T == PT_Float)
7913 return this->emitDecfPop(getFPOptions(E), E);
7914 if (SubExpr->refersToBitField())
7915 return DiscardResult ? this->emitDecPopBitfield(*T, E->canOverflow(),
7916 getBitWidth(SubExpr), E)
7917 : this->emitDecBitfield(*T, E->canOverflow(),
7918 getBitWidth(SubExpr), E);
7919 return this->emitDecPop(*T, E->canOverflow(), E);
7920 }
7921
7922 if (T == PT_Float) {
7923 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
7924 if (!this->emitLoadFloat(E))
7925 return false;
7926 APFloat F(TargetSemantics, 1);
7927 if (!this->emitFloat(F, E))
7928 return false;
7929
7930 if (!this->emitSubf(getFPOptions(E), E))
7931 return false;
7932 if (!this->emitStoreFloat(E))
7933 return false;
7934 } else if (SubExpr->refersToBitField()) {
7935 assert(isIntegerOrBoolType(*T));
7936 if (!this->emitPreDecBitfield(*T, E->canOverflow(), getBitWidth(SubExpr),
7937 E))
7938 return false;
7939 } else {
7940 assert(isIntegerOrBoolType(*T));
7941 if (!this->emitPreDec(*T, E->canOverflow(), E))
7942 return false;
7943 }
7944 return E->isGLValue() || this->emitLoadPop(*T, E);
7945 }
7946 case UO_LNot: // !x
7947 if (!T)
7948 return this->emitError(E);
7949
7950 if (DiscardResult)
7951 return this->discard(SubExpr);
7952
7953 if (!this->visitBool(SubExpr))
7954 return false;
7955
7956 if (!this->emitInv(E))
7957 return false;
7958
7959 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
7960 return this->emitCast(PT_Bool, ET, E);
7961 return true;
7962 case UO_Minus: // -x
7963 if (!T)
7964 return this->emitError(E);
7965
7966 if (!this->visit(SubExpr))
7967 return false;
7968 return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
7969 case UO_Plus: // +x
7970 if (!T)
7971 return this->emitError(E);
7972
7973 if (!this->visit(SubExpr)) // noop
7974 return false;
7975 return DiscardResult ? this->emitPop(*T, E) : true;
7976 case UO_AddrOf: // &x
7977 if (E->getType()->isMemberPointerType()) {
7978 // C++11 [expr.unary.op]p3 has very strict rules on how the address of a
7979 // member can be formed.
7980 if (DiscardResult)
7981 return true;
7982 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(), E);
7983 }
7984 // [C11 6.5.3.2p3]: if the operand of '&' is the result of a unary '*'
7985 // operator, neither operator is evaluated and the result is as if both
7986 // were omitted. So '&*q' is just 'q' with no dereference; delegate to the
7987 // pointer operand directly instead of to the '*' (which would emit a null
7988 // check), so that e.g. '&*(int *)0' is not rejected.
7989 if (!Ctx.getLangOpts().CPlusPlus) {
7990 const Expr *Sub = SubExpr->IgnoreParens();
7991
7992 if (const auto *Deref = dyn_cast<UnaryOperator>(Sub);
7993 Deref && Deref->getOpcode() == UO_Deref) {
7994 if (DiscardResult)
7995 return this->discard(Deref->getSubExpr());
7996 return this->visit(Deref->getSubExpr()) && this->emitAddrOf(E);
7997 }
7998 }
7999 // We should already have a pointer when we get here.
8000 if (DiscardResult)
8001 return this->discard(SubExpr);
8002 return this->delegate(SubExpr) && this->emitAddrOf(E);
8003 case UO_Deref: // *x
8004 if (DiscardResult)
8005 return this->discard(SubExpr);
8006
8007 if (!this->visit(SubExpr))
8008 return false;
8009
8010 if (!SubExpr->getType()->isFunctionPointerType() && !this->emitCheckNull(E))
8011 return false;
8012
8013 if (classifyPrim(SubExpr) == PT_Ptr)
8014 return this->emitNarrowPtr(E);
8015 return true;
8016
8017 case UO_Not: // ~x
8018 if (!T)
8019 return this->emitError(E);
8020
8021 if (!this->visit(SubExpr))
8022 return false;
8023 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
8024 case UO_Real: // __real x
8025 if (!T)
8026 return false;
8027 return this->delegate(SubExpr);
8028 case UO_Imag: { // __imag x
8029 if (!T)
8030 return false;
8031 if (!this->discard(SubExpr))
8032 return false;
8033 return DiscardResult
8034 ? true
8035 : this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);
8036 }
8037 case UO_Extension:
8038 return this->delegate(SubExpr);
8039 case UO_Coawait:
8040 assert(false && "Unhandled opcode");
8041 }
8042
8043 return false;
8044}
8045
8046template <class Emitter>
8048 const Expr *SubExpr = E->getSubExpr();
8049 assert(SubExpr->getType()->isAnyComplexType());
8050
8051 if (DiscardResult)
8052 return this->discard(SubExpr);
8053
8054 OptPrimType ResT = classify(E);
8055 auto prepareResult = [=]() -> bool {
8056 if (!ResT && !Initializing) {
8057 UnsignedOrNone LocalIndex = allocateLocal(SubExpr);
8058 if (!LocalIndex)
8059 return false;
8060 return this->emitGetPtrLocal(*LocalIndex, E);
8061 }
8062
8063 return true;
8064 };
8065
8066 // The offset of the temporary, if we created one.
8067 unsigned SubExprOffset = ~0u;
8068 auto createTemp = [=, &SubExprOffset]() -> bool {
8069 SubExprOffset =
8070 this->allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
8071 if (!this->visit(SubExpr))
8072 return false;
8073 return this->emitSetLocal(PT_Ptr, SubExprOffset, E);
8074 };
8075
8076 PrimType ElemT = classifyComplexElementType(SubExpr->getType());
8077 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
8078 if (!this->emitGetLocal(PT_Ptr, Offset, E))
8079 return false;
8080 return this->emitArrayElemPop(ElemT, Index, E);
8081 };
8082
8083 switch (E->getOpcode()) {
8084 case UO_Minus: // -x
8085 if (!prepareResult())
8086 return false;
8087 if (!createTemp())
8088 return false;
8089 for (unsigned I = 0; I != 2; ++I) {
8090 if (!getElem(SubExprOffset, I))
8091 return false;
8092 if (!this->emitNeg(ElemT, E))
8093 return false;
8094 if (!this->emitInitElem(ElemT, I, E))
8095 return false;
8096 }
8097 break;
8098
8099 case UO_Plus: // +x
8100 case UO_AddrOf: // &x
8101 case UO_Deref: // *x
8102 return this->delegate(SubExpr);
8103
8104 case UO_LNot:
8105 if (!this->visit(SubExpr))
8106 return false;
8107 if (!this->emitComplexBoolCast(SubExpr))
8108 return false;
8109 if (!this->emitInv(E))
8110 return false;
8111 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
8112 return this->emitCast(PT_Bool, ET, E);
8113 return true;
8114
8115 case UO_Real:
8116 return this->emitComplexReal(SubExpr);
8117
8118 case UO_Imag:
8119 if (!this->visit(SubExpr))
8120 return false;
8121
8122 if (SubExpr->isLValue()) {
8123 if (!this->emitConstUint8(1, E))
8124 return false;
8125 return this->emitArrayElemPtrPopUint8(E);
8126 }
8127
8128 // Since our _Complex implementation does not map to a primitive type,
8129 // we sometimes have to do the lvalue-to-rvalue conversion here manually.
8130 return this->emitArrayElemPop(classifyPrim(E->getType()), 1, E);
8131
8132 case UO_Not: // ~x
8133 if (!this->delegate(SubExpr))
8134 return false;
8135 // Negate the imaginary component.
8136 if (!this->emitArrayElem(ElemT, 1, E))
8137 return false;
8138 if (!this->emitNeg(ElemT, E))
8139 return false;
8140 if (!this->emitInitElem(ElemT, 1, E))
8141 return false;
8142 return DiscardResult ? this->emitPopPtr(E) : true;
8143
8144 case UO_Extension:
8145 return this->delegate(SubExpr);
8146
8147 default:
8148 return this->emitInvalid(E);
8149 }
8150
8151 return true;
8152}
8153
8154template <class Emitter>
8156 const Expr *SubExpr = E->getSubExpr();
8157 assert(SubExpr->getType()->isVectorType());
8158
8159 if (DiscardResult)
8160 return this->discard(SubExpr);
8161
8162 auto UnaryOp = E->getOpcode();
8163 if (UnaryOp == UO_Extension)
8164 return this->delegate(SubExpr);
8165
8166 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
8167 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
8168 return this->emitInvalid(E);
8169
8170 // Nothing to do here.
8171 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
8172 return this->delegate(SubExpr);
8173
8174 if (!Initializing) {
8175 UnsignedOrNone LocalIndex = allocateLocal(SubExpr);
8176 if (!LocalIndex)
8177 return false;
8178 if (!this->emitGetPtrLocal(*LocalIndex, E))
8179 return false;
8180 }
8181
8182 // The offset of the temporary, if we created one.
8183 unsigned SubExprOffset =
8184 this->allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
8185 if (!this->visit(SubExpr))
8186 return false;
8187 if (!this->emitSetLocal(PT_Ptr, SubExprOffset, E))
8188 return false;
8189
8190 const auto *VecTy = SubExpr->getType()->getAs<VectorType>();
8191 PrimType ElemT = classifyVectorElementType(SubExpr->getType());
8192 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
8193 if (!this->emitGetLocal(PT_Ptr, Offset, E))
8194 return false;
8195 return this->emitArrayElemPop(ElemT, Index, E);
8196 };
8197
8198 switch (UnaryOp) {
8199 case UO_Minus:
8200 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8201 if (!getElem(SubExprOffset, I))
8202 return false;
8203 if (!this->emitNeg(ElemT, E))
8204 return false;
8205 if (!this->emitInitElem(ElemT, I, E))
8206 return false;
8207 }
8208 break;
8209 case UO_LNot: { // !x
8210 // In C++, the logic operators !, &&, || are available for vectors. !v is
8211 // equivalent to v == 0.
8212 //
8213 // The result of the comparison is a vector of the same width and number of
8214 // elements as the comparison operands with a signed integral element type.
8215 //
8216 // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
8217 QualType ResultVecTy = E->getType();
8218 PrimType ResultVecElemT =
8219 classifyPrim(ResultVecTy->getAs<VectorType>()->getElementType());
8220 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8221 if (!getElem(SubExprOffset, I))
8222 return false;
8223 // operator ! on vectors returns -1 for 'truth', so negate it.
8224 if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E))
8225 return false;
8226 if (!this->emitInv(E))
8227 return false;
8228 if (!this->emitPrimCast(PT_Bool, ElemT, VecTy->getElementType(), E))
8229 return false;
8230 if (!this->emitNeg(ElemT, E))
8231 return false;
8232 if (ElemT != ResultVecElemT &&
8233 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy, E))
8234 return false;
8235 if (!this->emitInitElem(ResultVecElemT, I, E))
8236 return false;
8237 }
8238 break;
8239 }
8240 case UO_Not: // ~x
8241 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8242 if (!getElem(SubExprOffset, I))
8243 return false;
8244 if (ElemT == PT_Bool) {
8245 if (!this->emitInv(E))
8246 return false;
8247 } else {
8248 if (!this->emitComp(ElemT, E))
8249 return false;
8250 }
8251 if (!this->emitInitElem(ElemT, I, E))
8252 return false;
8253 }
8254 break;
8255 default:
8256 llvm_unreachable("Unsupported unary operators should be handled up front");
8257 }
8258 return true;
8259}
8260
8261template <class Emitter>
8263 if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
8264 if (DiscardResult)
8265 return true;
8266 return this->emitConst(ECD->getInitVal(), E);
8267 }
8268 if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
8269 if (DiscardResult)
8270 return true;
8271 const Function *F = getFunction(FuncDecl);
8272 return F && this->emitGetFnPtr(F, E);
8273 }
8274 if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
8275 TPOD = TPOD->getFirstDecl();
8276 if (DiscardResult)
8277 return true;
8278 if (UnsignedOrNone GlobalIndex = P.getGlobal(TPOD))
8279 return this->emitGetPtrGlobal(*GlobalIndex, E);
8280
8281 if (UnsignedOrNone Index = P.getOrCreateGlobal(TPOD)) {
8282 if (OptPrimType T = classify(TPOD->getType())) {
8283 if (!this->visitAPValue(TPOD->getValue(), *T, E))
8284 return false;
8285 return this->emitInitGlobal(*T, *Index, E);
8286 }
8287
8288 if (!this->emitGetPtrGlobal(*Index, E))
8289 return false;
8290 if (!this->visitAPValueInitializer(TPOD->getValue(), E, TPOD->getType()))
8291 return false;
8292 return this->emitFinishInit(E);
8293 }
8294 return false;
8295 }
8296
8297 // References are implemented via pointers, so when we see a DeclRefExpr
8298 // pointing to a reference, we need to get its value directly (i.e. the
8299 // pointer to the actual value) instead of a pointer to the pointer to the
8300 // value.
8301 QualType DeclType = D->getType();
8302 bool IsReference = DeclType->isReferenceType();
8303
8304 auto maybePopPtr = [&]() -> bool {
8305 if (DiscardResult)
8306 return this->emitPopPtr(E);
8307 return true;
8308 };
8309
8310 // Function parameters.
8311 // Note that it's important to check them first since we might have a local
8312 // variable created for a ParmVarDecl as well.
8313 if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
8314 if (DiscardResult)
8315 return true;
8316
8317 if (Ctx.getLangOpts().CPlusPlus && !Ctx.getLangOpts().CPlusPlus11 &&
8318 !DeclType->isIntegralOrEnumerationType()) {
8319 return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
8320 /*InitializerFailed=*/false, E);
8321 }
8322 if (auto It = this->Params.find(PVD); It != this->Params.end()) {
8323 if (IsReference || !It->second.IsPtr)
8324 return this->emitGetParam(classifyPrim(E), It->second.Index, E);
8325
8326 return this->emitGetPtrParam(It->second.Index, E);
8327 }
8328
8329 if (!Ctx.getLangOpts().CPlusPlus23 && IsReference && !Locals.contains(D))
8330 return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
8331 /*InitializerFailed=*/false, E);
8332 }
8333
8334 // Local variables.
8335 if (auto It = Locals.find(D); It != Locals.end()) {
8336 const unsigned Offset = It->second.Offset;
8337 if (IsReference) {
8338 assert(classifyPrim(E) == PT_Ptr);
8339 return this->emitGetRefLocal(Offset, E) && maybePopPtr();
8340 }
8341 return this->emitGetPtrLocal(Offset, E) && maybePopPtr();
8342 }
8343 // Global variables.
8344 if (auto GlobalIndex = P.getGlobal(D)) {
8345 if (IsReference) {
8346 if (!Ctx.getLangOpts().CPlusPlus11)
8347 return this->emitGetGlobal(classifyPrim(E), *GlobalIndex, E);
8348 if (!Ctx.getLangOpts().CPlusPlus23)
8349 return this->emitGetGlobalUnchecked(classifyPrim(E), *GlobalIndex, E);
8350
8351 return this->emitGetRefGlobal(*GlobalIndex, E) && maybePopPtr();
8352 }
8353
8354 return this->emitGetPtrGlobal(*GlobalIndex, E) && maybePopPtr();
8355 }
8356
8357 // In case we need to re-visit a declaration.
8358 auto revisit = [&](const VarDecl *VD,
8359 bool IsConstexprUnknown = true) -> bool {
8361 IsConstexprUnknown);
8362 if constexpr (std::is_same_v<Emitter, EvalEmitter>) {
8363 if (!this->emitPushCC(VD->hasConstantInitialization(), E))
8364 return false;
8365 }
8366 auto VarState = this->visitDecl(VD);
8367
8368 if constexpr (std::is_same_v<Emitter, EvalEmitter>) {
8369 if (!this->emitPopCC(E))
8370 return false;
8371 }
8372
8373 if (VarState.notCreated())
8374 return true;
8375 if (!VarState)
8376 return false;
8377 // Retry.
8378 return this->visitDeclRef(D, E);
8379 };
8380
8381 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
8382 // Lambda captures.
8383 if (auto It = this->LambdaCaptures.find(D);
8384 It != this->LambdaCaptures.end()) {
8385 auto [Offset, IsPtr] = It->second;
8386
8387 if (IsPtr)
8388 return this->emitGetThisFieldPtr(Offset, E) && maybePopPtr();
8389 return this->emitGetPtrThisField(Offset, E) && maybePopPtr();
8390 }
8391 }
8392
8393 if (const auto *DRE = dyn_cast<DeclRefExpr>(E);
8394 DRE && DRE->refersToEnclosingVariableOrCapture()) {
8395 if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture())
8396 return revisit(VD);
8397 }
8398
8399 if (const auto *BD = dyn_cast<BindingDecl>(D))
8400 return this->delegate(BD->getBinding());
8401
8402 // Avoid infinite recursion.
8403 if (D == InitializingDecl) {
8404 if (DiscardResult)
8405 return true;
8406 return this->emitDummyPtr(D, E);
8407 }
8408
8409 // Try to lazily visit (or emit dummy pointers for) declarations
8410 // we haven't seen yet.
8411 const auto *VD = dyn_cast<VarDecl>(D);
8412 if (!VD)
8413 return this->emitError(E);
8414
8415 // For C.
8416 if (!Ctx.getLangOpts().CPlusPlus) {
8417 if (VD->getInit() && !VD->getInit()->isValueDependent() &&
8418 DeclType.isConstant(Ctx.getASTContext()) && !VD->isWeak() &&
8419 VD->evaluateValue())
8420 return revisit(VD, /*IsConstexprUnknown=*/false);
8421
8422 if (DiscardResult)
8423 return true;
8424 return this->emitDummyPtr(D, E);
8425 }
8426
8427 // ... and C++.
8428 const auto typeShouldBeVisited = [&](QualType T) -> bool {
8429 if (T.isConstant(Ctx.getASTContext()))
8430 return true;
8431 return T->isReferenceType();
8432 };
8433
8434 if ((VD->hasGlobalStorage() || VD->isStaticDataMember()) &&
8435 typeShouldBeVisited(DeclType)) {
8436 if (const Expr *Init = VD->getAnyInitializer();
8437 Init && !Init->isValueDependent()) {
8438 // Whether or not the evaluation is successul doesn't really matter
8439 // here -- we will create a global variable in any case, and that
8440 // will have the state of initializer evaluation attached.
8442 (void)Init->EvaluateAsInitializer(Ctx.getASTContext(), VD, Result, true);
8443 return this->visitDeclRef(D, E);
8444 }
8445 return revisit(VD, !VD->isConstexpr() && DeclType->isReferenceType());
8446 }
8447
8448 // FIXME: The evaluateValue() check here is a little ridiculous, since
8449 // it will ultimately call into Context::evaluateAsInitializer(). In
8450 // other words, we're evaluating the initializer, just to know if we can
8451 // evaluate the initializer.
8452 if (VD->isLocalVarDecl() && typeShouldBeVisited(DeclType) && VD->getInit() &&
8453 !VD->getInit()->isValueDependent()) {
8454 if (VD->evaluateValue()) {
8455 bool IsConstexprUnknown = !DeclType.isConstant(Ctx.getASTContext()) &&
8456 !DeclType->isReferenceType();
8457 // Revisit the variable declaration, but make sure it's associated with a
8458 // different evaluation, so e.g. mutable reads don't work on it.
8459 EvalIDScope _(Ctx);
8460 return revisit(VD, IsConstexprUnknown);
8461 } else if (Ctx.getLangOpts().CPlusPlus23 && IsReference)
8462 return revisit(VD, /*IsConstexprUnknown=*/true);
8463
8464 if (IsReference)
8465 return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
8466 /*InitializerFailed=*/true, E);
8467 }
8468
8469 if (DiscardResult)
8470 return true;
8471 return this->emitDummyPtr(
8472 D, E, Ctx.getLangOpts().CPlusPlus23 && DeclType->isReferenceType());
8473}
8474
8475template <class Emitter>
8477 const auto *D = E->getDecl();
8478 return this->visitDeclRef(D, E);
8479}
8480
8481template <class Emitter>
8483 const DesignatedInitUpdateExpr *E) {
8484 if (!this->visitInitializer(E->getBase()))
8485 return false;
8486 return this->visitInitializer(E->getUpdater());
8487}
8488
8489template <class Emitter> bool Compiler<Emitter>::emitCleanup() {
8490 for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent()) {
8491 if (!C->destroyLocals())
8492 return false;
8493 }
8494 return true;
8495}
8496
8497template <class Emitter>
8498unsigned Compiler<Emitter>::collectBaseOffset(const QualType BaseType,
8499 const QualType DerivedType) {
8500 const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
8501 if (const auto *R = Ty->getPointeeCXXRecordDecl())
8502 return R;
8503 return Ty->getAsCXXRecordDecl();
8504 };
8505 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
8506 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
8507
8508 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
8509}
8510
8511/// Emit casts from a PrimType to another PrimType.
8512template <class Emitter>
8513bool Compiler<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT,
8514 QualType ToQT, const Expr *E) {
8515
8516 if (FromT == PT_Float) {
8517 // Floating to floating.
8518 if (ToT == PT_Float) {
8519 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
8520 return this->emitCastFP(ToSem, getRoundingMode(E), E);
8521 }
8522
8523 if (ToT == PT_IntAP)
8524 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
8525 getFPOptions(E), E);
8526 if (ToT == PT_IntAPS)
8527 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
8528 getFPOptions(E), E);
8529
8530 // Float to integral.
8531 if (isIntegerOrBoolType(ToT) || ToT == PT_Bool)
8532 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
8533 }
8534
8535 if (isIntegerOrBoolType(FromT) || FromT == PT_Bool) {
8536 if (ToT == PT_IntAP)
8537 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
8538 if (ToT == PT_IntAPS)
8539 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
8540
8541 // Integral to integral.
8542 if (isIntegerOrBoolType(ToT) || ToT == PT_Bool)
8543 return FromT != ToT ? this->emitCast(FromT, ToT, E) : true;
8544
8545 if (ToT == PT_Float) {
8546 // Integral to floating.
8547 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
8548 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E);
8549 }
8550 }
8551
8552 return false;
8553}
8554
8555template <class Emitter>
8556bool Compiler<Emitter>::emitIntegralCast(PrimType FromT, PrimType ToT,
8557 QualType ToQT, const Expr *E) {
8558 assert(FromT != ToT);
8559
8560 if (ToT == PT_IntAP)
8561 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
8562 if (ToT == PT_IntAPS)
8563 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
8564
8565 return this->emitCast(FromT, ToT, E);
8566}
8567
8568/// Emits __real(SubExpr)
8569template <class Emitter>
8570bool Compiler<Emitter>::emitComplexReal(const Expr *SubExpr) {
8571 assert(SubExpr->getType()->isAnyComplexType());
8572
8573 if (DiscardResult)
8574 return this->discard(SubExpr);
8575
8576 if (!this->visit(SubExpr))
8577 return false;
8578 if (SubExpr->isLValue()) {
8579 if (!this->emitConstUint8(0, SubExpr))
8580 return false;
8581 return this->emitArrayElemPtrPopUint8(SubExpr);
8582 }
8583
8584 // Rvalue, load the actual element.
8585 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->getType()),
8586 0, SubExpr);
8587}
8588
8589template <class Emitter>
8590bool Compiler<Emitter>::emitComplexBoolCast(const Expr *E) {
8591 assert(!DiscardResult);
8592 PrimType ElemT = classifyComplexElementType(E->getType());
8593 // We emit the expression (__real(E) != 0 || __imag(E) != 0)
8594 // for us, that means (bool)E[0] || (bool)E[1]
8595 if (!this->emitArrayElem(ElemT, 0, E))
8596 return false;
8597 if (ElemT == PT_Float) {
8598 if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
8599 return false;
8600 } else {
8601 if (!this->emitCast(ElemT, PT_Bool, E))
8602 return false;
8603 }
8604
8605 // We now have the bool value of E[0] on the stack.
8606 LabelTy LabelTrue = this->getLabel();
8607 if (!this->jumpTrue(LabelTrue, E))
8608 return false;
8609
8610 if (!this->emitArrayElemPop(ElemT, 1, E))
8611 return false;
8612 if (ElemT == PT_Float) {
8613 if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
8614 return false;
8615 } else {
8616 if (!this->emitCast(ElemT, PT_Bool, E))
8617 return false;
8618 }
8619 // Leave the boolean value of E[1] on the stack.
8620 LabelTy EndLabel = this->getLabel();
8621 this->jump(EndLabel, E);
8622
8623 this->emitLabel(LabelTrue);
8624 if (!this->emitPopPtr(E))
8625 return false;
8626 if (!this->emitConstBool(true, E))
8627 return false;
8628
8629 this->fallthrough(EndLabel);
8630 this->emitLabel(EndLabel);
8631
8632 return true;
8633}
8634
8635template <class Emitter>
8636bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS,
8637 const BinaryOperator *E) {
8638 assert(E->isComparisonOp());
8639 assert(!Initializing);
8640 if (DiscardResult)
8641 return this->discard(LHS) && this->discard(RHS);
8642
8643 PrimType ElemT;
8644 bool LHSIsComplex;
8645 unsigned LHSOffset;
8646 if (LHS->getType()->isAnyComplexType()) {
8647 LHSIsComplex = true;
8648 ElemT = classifyComplexElementType(LHS->getType());
8649 LHSOffset = allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true);
8650 if (!this->visit(LHS))
8651 return false;
8652 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
8653 return false;
8654 } else {
8655 LHSIsComplex = false;
8656 PrimType LHST = classifyPrim(LHS->getType());
8657 LHSOffset = this->allocateLocalPrimitive(LHS, LHST, /*IsConst=*/true);
8658 if (!this->visit(LHS))
8659 return false;
8660 if (!this->emitSetLocal(LHST, LHSOffset, E))
8661 return false;
8662 }
8663
8664 bool RHSIsComplex;
8665 unsigned RHSOffset;
8666 if (RHS->getType()->isAnyComplexType()) {
8667 RHSIsComplex = true;
8668 ElemT = classifyComplexElementType(RHS->getType());
8669 RHSOffset = allocateLocalPrimitive(RHS, PT_Ptr, /*IsConst=*/true);
8670 if (!this->visit(RHS))
8671 return false;
8672 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
8673 return false;
8674 } else {
8675 RHSIsComplex = false;
8676 PrimType RHST = classifyPrim(RHS->getType());
8677 RHSOffset = this->allocateLocalPrimitive(RHS, RHST, /*IsConst=*/true);
8678 if (!this->visit(RHS))
8679 return false;
8680 if (!this->emitSetLocal(RHST, RHSOffset, E))
8681 return false;
8682 }
8683
8684 auto getElem = [&](unsigned LocalOffset, unsigned Index,
8685 bool IsComplex) -> bool {
8686 if (IsComplex) {
8687 if (!this->emitGetLocal(PT_Ptr, LocalOffset, E))
8688 return false;
8689 return this->emitArrayElemPop(ElemT, Index, E);
8690 }
8691 return this->emitGetLocal(ElemT, LocalOffset, E);
8692 };
8693
8694 for (unsigned I = 0; I != 2; ++I) {
8695 // Get both values.
8696 if (!getElem(LHSOffset, I, LHSIsComplex))
8697 return false;
8698 if (!getElem(RHSOffset, I, RHSIsComplex))
8699 return false;
8700 // And compare them.
8701 if (!this->emitEQ(ElemT, E))
8702 return false;
8703
8704 if (!this->emitCastBoolUint8(E))
8705 return false;
8706 }
8707
8708 // We now have two bool values on the stack. Compare those.
8709 if (!this->emitAddUint8(E))
8710 return false;
8711 if (!this->emitConstUint8(2, E))
8712 return false;
8713
8714 if (E->getOpcode() == BO_EQ) {
8715 if (!this->emitEQUint8(E))
8716 return false;
8717 } else if (E->getOpcode() == BO_NE) {
8718 if (!this->emitNEUint8(E))
8719 return false;
8720 } else
8721 return false;
8722
8723 // In C, this returns an int.
8724 if (PrimType ResT = classifyPrim(E->getType()); ResT != PT_Bool)
8725 return this->emitCast(PT_Bool, ResT, E);
8726 return true;
8727}
8728
8729/// When calling this, we have a pointer of the local-to-destroy
8730/// on the stack.
8731/// Emit destruction of record types (or arrays of record types).
8732template <class Emitter>
8733bool Compiler<Emitter>::emitRecordDestructionPop(const Record *R,
8734 SourceInfo Loc) {
8735 assert(R);
8736 assert(!R->hasTrivialDtor());
8737 const CXXDestructorDecl *Dtor = R->getDestructor();
8738 assert(Dtor);
8739 const Function *DtorFunc = getFunction(Dtor);
8740 if (!DtorFunc)
8741 return false;
8742 assert(DtorFunc->hasThisPointer());
8743 assert(DtorFunc->getNumParams() == 1);
8744 return this->emitCall(DtorFunc, 0, Loc);
8745}
8746/// When calling this, we have a pointer of the local-to-destroy
8747/// on the stack.
8748/// Emit destruction of record types (or arrays of record types).
8749template <class Emitter>
8750bool Compiler<Emitter>::emitDestructionPop(const Descriptor *Desc,
8751 SourceInfo Loc) {
8752 assert(Desc);
8753 assert(!Desc->hasTrivialDtor());
8754
8755 // Arrays.
8756 if (Desc->isArray()) {
8757 const Descriptor *ElemDesc = Desc->ElemDesc;
8758 assert(ElemDesc);
8759
8760 unsigned N = Desc->getNumElems();
8761 if (N == 0)
8762 return this->emitPopPtr(Loc);
8763
8764 for (ssize_t I = N - 1; I >= 1; --I) {
8765 if (!this->emitConstUint64(I, Loc))
8766 return false;
8767 if (!this->emitArrayElemPtrUint64(Loc))
8768 return false;
8769 if (!this->emitDestructionPop(ElemDesc, Loc))
8770 return false;
8771 }
8772 // Last iteration, removes the instance pointer from the stack.
8773 if (!this->emitConstUint64(0, Loc))
8774 return false;
8775 if (!this->emitArrayElemPtrPopUint64(Loc))
8776 return false;
8777 return this->emitDestructionPop(ElemDesc, Loc);
8778 }
8779
8780 assert(Desc->ElemRecord);
8781 assert(!Desc->ElemRecord->hasTrivialDtor());
8782 return this->emitRecordDestructionPop(Desc->ElemRecord, Loc);
8783}
8784
8785/// Create a dummy pointer for the given decl (or expr) and
8786/// push a pointer to it on the stack.
8787template <class Emitter>
8788bool Compiler<Emitter>::emitDummyPtr(DeclOrExpr D, const Expr *E, bool CU) {
8789 assert(!DiscardResult && "Should've been checked before");
8790 return this->emitGetOpaquePtr(D, CU, E);
8791}
8792
8793template <class Emitter>
8794bool Compiler<Emitter>::emitFloat(const APFloat &F, SourceInfo Info) {
8795 if (Floating::singleWord(F.getSemantics()))
8796 return this->emitConstFloat(Floating(F), Info);
8797
8798 APInt I = F.bitcastToAPInt();
8799 return this->emitConstFloat(
8800 Floating(const_cast<uint64_t *>(I.getRawData()),
8801 llvm::APFloatBase::SemanticsToEnum(F.getSemantics())),
8802 Info);
8803}
8804
8805// This function is constexpr if and only if To, From, and the types of
8806// all subobjects of To and From are types T such that...
8807// (3.1) - is_union_v<T> is false;
8808// (3.2) - is_pointer_v<T> is false;
8809// (3.3) - is_member_pointer_v<T> is false;
8810// (3.4) - is_volatile_v<T> is false; and
8811// (3.5) - T has no non-static data members of reference type
8812template <class Emitter>
8813bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) {
8814 const Expr *SubExpr = E->getSubExpr();
8815 QualType FromType = SubExpr->getType();
8816 QualType ToType = E->getType();
8817 OptPrimType ToT = classify(ToType);
8818
8819 assert(!ToType->isReferenceType());
8820
8821 // Prepare storage for the result in case we discard.
8822 if (DiscardResult && !Initializing && !ToT) {
8823 UnsignedOrNone LocalIndex = allocateLocal(E);
8824 if (!LocalIndex)
8825 return false;
8826 if (!this->emitGetPtrLocal(*LocalIndex, E))
8827 return false;
8828 }
8829
8830 // Get a pointer to the value-to-cast on the stack.
8831 // For CK_LValueToRValueBitCast, this is always an lvalue and
8832 // we later assume it to be one (i.e. a PT_Ptr). However,
8833 // we call this function for other utility methods where
8834 // a bitcast might be useful, so convert it to a PT_Ptr in that case.
8835 if (SubExpr->isGLValue() || FromType->isVectorType()) {
8836 if (!this->visit(SubExpr))
8837 return false;
8838 } else if (OptPrimType FromT = classify(SubExpr)) {
8839 unsigned TempOffset =
8840 allocateLocalPrimitive(SubExpr, *FromT, /*IsConst=*/true);
8841 if (!this->visit(SubExpr))
8842 return false;
8843 if (!this->emitSetLocal(*FromT, TempOffset, E))
8844 return false;
8845 if (!this->emitGetPtrLocal(TempOffset, E))
8846 return false;
8847 } else {
8848 return false;
8849 }
8850
8851 if (!ToT) {
8852 if (!this->emitBitCast(E))
8853 return false;
8854 return DiscardResult ? this->emitPopPtr(E) : true;
8855 }
8856 assert(ToT);
8857
8858 const llvm::fltSemantics *TargetSemantics = nullptr;
8859 if (ToT == PT_Float)
8860 TargetSemantics = &Ctx.getFloatSemantics(ToType);
8861
8862 // Conversion to a primitive type. FromType can be another
8863 // primitive type, or a record/array.
8864 bool ToTypeIsUChar = (ToType->isSpecificBuiltinType(BuiltinType::UChar) ||
8865 ToType->isSpecificBuiltinType(BuiltinType::Char_U));
8866 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
8867
8868 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->isStdByteType(),
8869 ResultBitWidth, TargetSemantics,
8870 ToType.getTypePtr(), E))
8871 return false;
8872
8873 if (DiscardResult)
8874 return this->emitPop(*ToT, E);
8875
8876 return true;
8877}
8878
8879/// Replicate a scalar value into every scalar element of an aggregate.
8880/// The scalar is stored in a local at \p SrcOffset and a pointer to the
8881/// destination must be on top of the interpreter stack. Each element receives
8882/// the scalar, cast to its own type.
8883template <class Emitter>
8884bool Compiler<Emitter>::emitHLSLAggregateSplat(PrimType SrcT,
8885 unsigned SrcOffset,
8886 QualType DestType,
8887 const Expr *E) {
8888 // Vectors and matrices are treated as flat sequences of elements.
8889 unsigned NumElems = 0;
8890 QualType ElemType;
8891 if (const auto *VT = DestType->getAs<VectorType>()) {
8892 NumElems = VT->getNumElements();
8893 ElemType = VT->getElementType();
8894 } else if (const auto *MT = DestType->getAs<ConstantMatrixType>()) {
8895 NumElems = MT->getNumElementsFlattened();
8896 ElemType = MT->getElementType();
8897 }
8898 if (NumElems > 0) {
8899 PrimType ElemT = classifyPrim(ElemType);
8900 for (unsigned I = 0; I != NumElems; ++I) {
8901 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8902 return false;
8903 if (!this->emitPrimCast(SrcT, ElemT, ElemType, E))
8904 return false;
8905 if (!this->emitInitElem(ElemT, I, E))
8906 return false;
8907 }
8908 return true;
8909 }
8910
8911 // Arrays: primitive elements are filled directly; composite elements
8912 // require recursion into each sub-aggregate.
8913 if (const auto *AT = DestType->getAsArrayTypeUnsafe()) {
8914 const auto *CAT = cast<ConstantArrayType>(AT);
8915 QualType ArrElemType = CAT->getElementType();
8916 unsigned ArrSize = CAT->getZExtSize();
8917
8918 if (OptPrimType ElemT = classify(ArrElemType)) {
8919 for (unsigned I = 0; I != ArrSize; ++I) {
8920 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8921 return false;
8922 if (!this->emitPrimCast(SrcT, *ElemT, ArrElemType, E))
8923 return false;
8924 if (!this->emitInitElem(*ElemT, I, E))
8925 return false;
8926 }
8927 } else {
8928 for (unsigned I = 0; I != ArrSize; ++I) {
8929 if (!this->emitConstUint32(I, E))
8930 return false;
8931 if (!this->emitArrayElemPtrUint32(E))
8932 return false;
8933 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, ArrElemType, E))
8934 return false;
8935 if (!this->emitFinishInitPop(E))
8936 return false;
8937 }
8938 }
8939 return true;
8940 }
8941
8942 // Records: fill base classes first, then named fields in declaration
8943 // order.
8944 if (DestType->isRecordType()) {
8945 const Record *R = getRecord(DestType);
8946 if (!R)
8947 return false;
8948
8949 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
8950 for (const CXXBaseSpecifier &BS : CXXRD->bases()) {
8951 const Record::Base *B = R->getBase(BS.getType());
8952 assert(B);
8953 if (!this->emitGetPtrBase(B->Offset, E))
8954 return false;
8955 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, BS.getType(), E))
8956 return false;
8957 if (!this->emitFinishInitPop(E))
8958 return false;
8959 }
8960 }
8961
8962 for (const Record::Field &F : R->fields()) {
8963 if (F.isUnnamedBitField())
8964 continue;
8965
8966 QualType FieldType = F.Decl->getType();
8967 if (OptPrimType FieldT = F.T) {
8968 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8969 return false;
8970 if (!this->emitPrimCast(SrcT, *FieldT, FieldType, E))
8971 return false;
8972 if (F.isBitField()) {
8973 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
8974 return false;
8975 } else {
8976 if (!this->emitInitField(*FieldT, F.Offset, E))
8977 return false;
8978 }
8979 } else {
8980 if (!this->emitGetPtrField(F.Offset, E))
8981 return false;
8982 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, FieldType, E))
8983 return false;
8984 if (!this->emitPopPtr(E))
8985 return false;
8986 }
8987 }
8988 return true;
8989 }
8990
8991 return false;
8992}
8993
8994/// Return the total number of scalar elements in a type. This is used
8995/// to cap how many source elements are extracted during an elementwise cast,
8996/// so we never flatten more than the destination can hold.
8997template <class Emitter>
8998unsigned Compiler<Emitter>::countHLSLFlatElements(QualType Ty) {
8999 // Vector and matrix types are treated as flat sequences of elements.
9000 if (const auto *VT = Ty->getAs<VectorType>())
9001 return VT->getNumElements();
9002 if (const auto *MT = Ty->getAs<ConstantMatrixType>())
9003 return MT->getNumElementsFlattened();
9004 // Arrays: total count is array size * scalar elements per element.
9005 if (const auto *AT = Ty->getAsArrayTypeUnsafe()) {
9006 const auto *CAT = cast<ConstantArrayType>(AT);
9007 return CAT->getZExtSize() * countHLSLFlatElements(CAT->getElementType());
9008 }
9009 // Records: sum scalar element counts of base classes and named fields.
9010 if (Ty->isRecordType()) {
9011 const Record *R = getRecord(Ty);
9012 if (!R)
9013 return 0;
9014 unsigned Count = 0;
9015 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
9016 for (const CXXBaseSpecifier &BS : CXXRD->bases())
9017 Count += countHLSLFlatElements(BS.getType());
9018 }
9019 for (const Record::Field &F : R->fields()) {
9020 if (F.isUnnamedBitField())
9021 continue;
9022 Count += countHLSLFlatElements(F.Decl->getType());
9023 }
9024 return Count;
9025 }
9026 // Scalar primitive types contribute one element.
9027 if (canClassify(Ty))
9028 return 1;
9029 return 0;
9030}
9031
9032/// Walk a source aggregate and extract every scalar element into its own local
9033/// variable. The results are appended to \p Elements in declaration order,
9034/// stopping once \p MaxElements have been collected. A pointer to the
9035/// source aggregate must be stored in the local at \p SrcOffset.
9036template <class Emitter>
9037bool Compiler<Emitter>::emitHLSLFlattenAggregate(
9038 QualType SrcType, unsigned SrcOffset,
9039 SmallVectorImpl<HLSLFlatElement> &Elements, unsigned MaxElements,
9040 const Expr *E) {
9041
9042 // Save a scalar value from the stack into a new local and record it.
9043 auto saveToLocal = [&](PrimType T) -> bool {
9044 unsigned Offset = allocateLocalPrimitive(E, T, /*IsConst=*/true);
9045 if (!this->emitSetLocal(T, Offset, E))
9046 return false;
9047 Elements.push_back({Offset, T});
9048 return true;
9049 };
9050
9051 // Save a pointer from the stack into a new local for later use.
9052 auto savePtrToLocal = [&]() -> UnsignedOrNone {
9053 unsigned Offset = allocateLocalPrimitive(E, PT_Ptr, /*IsConst=*/true);
9054 if (!this->emitSetLocal(PT_Ptr, Offset, E))
9055 return std::nullopt;
9056 return Offset;
9057 };
9058
9059 // Vectors and matrices are flat sequences of elements.
9060 unsigned NumElems = 0;
9061 QualType ElemType;
9062 if (const auto *VT = SrcType->getAs<VectorType>()) {
9063 NumElems = VT->getNumElements();
9064 ElemType = VT->getElementType();
9065 } else if (const auto *MT = SrcType->getAs<ConstantMatrixType>()) {
9066 NumElems = MT->getNumElementsFlattened();
9067 ElemType = MT->getElementType();
9068 }
9069 if (NumElems > 0) {
9070 PrimType ElemT = classifyPrim(ElemType);
9071 for (unsigned I = 0; I != NumElems && Elements.size() < MaxElements; ++I) {
9072 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9073 return false;
9074 if (!this->emitArrayElemPop(ElemT, I, E))
9075 return false;
9076 if (!saveToLocal(ElemT))
9077 return false;
9078 }
9079 return true;
9080 }
9081
9082 // Arrays: primitive elements are extracted directly; composite elements
9083 // require recursion into each sub-aggregate.
9084 if (const auto *AT = SrcType->getAsArrayTypeUnsafe()) {
9085 const auto *CAT = cast<ConstantArrayType>(AT);
9086 QualType ArrElemType = CAT->getElementType();
9087 unsigned ArrSize = CAT->getZExtSize();
9088
9089 if (OptPrimType ElemT = classify(ArrElemType)) {
9090 for (unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
9091 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9092 return false;
9093 if (!this->emitArrayElemPop(*ElemT, I, E))
9094 return false;
9095 if (!saveToLocal(*ElemT))
9096 return false;
9097 }
9098 } else {
9099 for (unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
9100 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9101 return false;
9102 if (!this->emitConstUint32(I, E))
9103 return false;
9104 if (!this->emitArrayElemPtrPopUint32(E))
9105 return false;
9106 UnsignedOrNone ElemPtrOffset = savePtrToLocal();
9107 if (!ElemPtrOffset)
9108 return false;
9109 if (!emitHLSLFlattenAggregate(ArrElemType, *ElemPtrOffset, Elements,
9110 MaxElements, E))
9111 return false;
9112 }
9113 }
9114 return true;
9115 }
9116
9117 // Records: base classes come first, then named fields in declaration
9118 // order.
9119 if (SrcType->isRecordType()) {
9120 const Record *R = getRecord(SrcType);
9121 if (!R)
9122 return false;
9123
9124 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
9125 for (const CXXBaseSpecifier &BS : CXXRD->bases()) {
9126 if (Elements.size() >= MaxElements)
9127 break;
9128 const Record::Base *B = R->getBase(BS.getType());
9129 assert(B);
9130 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9131 return false;
9132 if (!this->emitGetPtrBasePop(B->Offset, /*NullOK=*/false, E))
9133 return false;
9134 UnsignedOrNone BasePtrOffset = savePtrToLocal();
9135 if (!BasePtrOffset)
9136 return false;
9137 if (!emitHLSLFlattenAggregate(BS.getType(), *BasePtrOffset, Elements,
9138 MaxElements, E))
9139 return false;
9140 }
9141 }
9142
9143 for (const Record::Field &F : R->fields()) {
9144 if (Elements.size() >= MaxElements)
9145 break;
9146 if (F.isUnnamedBitField())
9147 continue;
9148
9149 QualType FieldType = F.Decl->getType();
9150 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9151 return false;
9152 if (!this->emitGetPtrFieldPop(F.Offset, E))
9153 return false;
9154
9155 if (OptPrimType FieldT = F.T) {
9156 if (!this->emitLoadPop(*FieldT, E))
9157 return false;
9158 if (!saveToLocal(*FieldT))
9159 return false;
9160 } else {
9161 UnsignedOrNone FieldPtrOffset = savePtrToLocal();
9162 if (!FieldPtrOffset)
9163 return false;
9164 if (!emitHLSLFlattenAggregate(FieldType, *FieldPtrOffset, Elements,
9165 MaxElements, E))
9166 return false;
9167 }
9168 }
9169 return true;
9170 }
9171
9172 return false;
9173}
9174
9175/// Populate an HLSL aggregate from a flat list of previously extracted source
9176/// elements, casting each to the corresponding destination element type.
9177/// \p ElemIdx tracks the current position in \p Elements and is advanced as
9178/// elements are consumed. A pointer to the destination must be on top of the
9179/// interpreter stack.
9180template <class Emitter>
9181bool Compiler<Emitter>::emitHLSLConstructAggregate(
9182 QualType DestType, ArrayRef<HLSLFlatElement> Elements, unsigned &ElemIdx,
9183 const Expr *E) {
9184
9185 // Consume the next source element, cast it, and leave it on the stack.
9186 auto loadAndCast = [&](PrimType DestT, QualType DestQT) -> bool {
9187 const auto &Src = Elements[ElemIdx++];
9188 if (!this->emitGetLocal(Src.Type, Src.LocalOffset, E))
9189 return false;
9190 return this->emitPrimCast(Src.Type, DestT, DestQT, E);
9191 };
9192
9193 // Vectors and matrices are flat sequences of elements.
9194 unsigned NumElems = 0;
9195 QualType ElemType;
9196 if (const auto *VT = DestType->getAs<VectorType>()) {
9197 NumElems = VT->getNumElements();
9198 ElemType = VT->getElementType();
9199 } else if (const auto *MT = DestType->getAs<ConstantMatrixType>()) {
9200 NumElems = MT->getNumElementsFlattened();
9201 ElemType = MT->getElementType();
9202 }
9203 if (NumElems > 0) {
9204 PrimType DestElemT = classifyPrim(ElemType);
9205 for (unsigned I = 0; I != NumElems; ++I) {
9206 if (!loadAndCast(DestElemT, ElemType))
9207 return false;
9208 if (!this->emitInitElem(DestElemT, I, E))
9209 return false;
9210 }
9211 return true;
9212 }
9213
9214 // Arrays: primitive elements are filled directly; composite elements
9215 // require recursion into each sub-aggregate.
9216 if (const auto *AT = DestType->getAsArrayTypeUnsafe()) {
9217 const auto *CAT = cast<ConstantArrayType>(AT);
9218 QualType ArrElemType = CAT->getElementType();
9219 unsigned ArrSize = CAT->getZExtSize();
9220
9221 if (OptPrimType ElemT = classify(ArrElemType)) {
9222 for (unsigned I = 0; I != ArrSize; ++I) {
9223 if (!loadAndCast(*ElemT, ArrElemType))
9224 return false;
9225 if (!this->emitInitElem(*ElemT, I, E))
9226 return false;
9227 }
9228 } else {
9229 for (unsigned I = 0; I != ArrSize; ++I) {
9230 if (!this->emitConstUint32(I, E))
9231 return false;
9232 if (!this->emitArrayElemPtrUint32(E))
9233 return false;
9234 if (!emitHLSLConstructAggregate(ArrElemType, Elements, ElemIdx, E))
9235 return false;
9236 if (!this->emitFinishInitPop(E))
9237 return false;
9238 }
9239 }
9240 return true;
9241 }
9242
9243 // Records: base classes come first, then named fields in declaration
9244 // order.
9245 if (DestType->isRecordType()) {
9246 const Record *R = getRecord(DestType);
9247 if (!R)
9248 return false;
9249
9250 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
9251 for (const CXXBaseSpecifier &BS : CXXRD->bases()) {
9252 const Record::Base *B = R->getBase(BS.getType());
9253 assert(B);
9254 if (!this->emitGetPtrBase(B->Offset, E))
9255 return false;
9256 if (!emitHLSLConstructAggregate(BS.getType(), Elements, ElemIdx, E))
9257 return false;
9258 if (!this->emitFinishInitPop(E))
9259 return false;
9260 }
9261 }
9262
9263 for (const Record::Field &F : R->fields()) {
9264 if (F.isUnnamedBitField())
9265 continue;
9266
9267 QualType FieldType = F.Decl->getType();
9268 if (OptPrimType FieldT = F.T) {
9269 if (!loadAndCast(*FieldT, FieldType))
9270 return false;
9271 if (F.isBitField()) {
9272 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
9273 return false;
9274 } else {
9275 if (!this->emitInitField(*FieldT, F.Offset, E))
9276 return false;
9277 }
9278 } else {
9279 if (!this->emitGetPtrField(F.Offset, E))
9280 return false;
9281 if (!emitHLSLConstructAggregate(FieldType, Elements, ElemIdx, E))
9282 return false;
9283 if (!this->emitPopPtr(E))
9284 return false;
9285 }
9286 }
9287 return true;
9288 }
9289
9290 return false;
9291}
9292
9293namespace clang {
9294namespace interp {
9295
9296template class Compiler<ByteCodeEmitter>;
9297template class Compiler<EvalEmitter>;
9298
9299} // namespace interp
9300} // 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 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:3268
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition Decl.cpp:4246
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition Decl.cpp:4234
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3806
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:4370
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:3470
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:3870
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Definition Decl.cpp:3188
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:3154
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:3338
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
bool isVoidPointerType() const
Definition Type.cpp:758
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
Definition Type.cpp:2558
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:798
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:3357
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:2446
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:2430
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:2704
bool hasBooleanRepresentation() const
Determine whether this type has a boolean representation – i.e., it is a boolean type,...
Definition Type.cpp:2485
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:5648
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:2641
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:2557
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:506
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:297
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:481
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:487
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:504
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:517
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:484
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:513
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 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:490
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:503
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:478
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:510
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
OptPrimType classify(const Expr *E) const
Definition Compiler.h:291
llvm::SmallVector< LabelInfo > LabelInfoStack
Stack of label information for loops and switch statements.
Definition Compiler.h:515
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:493
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:293
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:821
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Definition Context.h:167
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:3221
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:2868
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:2314
bool Init(InterpState &S, CodePtr OpPC)
Definition Interp.h:2431
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
__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