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