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 {
2367
2368 if (DefaultInit && !this->emitStartFieldInit(FieldToInit->Offset, Init))
2369 return false;
2370
2371 if (!this->visit(Init))
2372 return false;
2373
2374 if (DefaultInit && !this->emitEndInit(Init))
2375 return false;
2376
2377 bool BitField = FieldToInit->isBitField();
2378 if (BitField && Activate)
2379 return this->emitInitBitFieldActivate(T, FieldToInit->Offset,
2380 FieldToInit->bitWidth(), E);
2381 if (BitField)
2382 return this->emitInitBitField(T, FieldToInit->Offset,
2383 FieldToInit->bitWidth(), E);
2384 if (Activate)
2385 return this->emitInitFieldActivate(T, FieldToInit->Offset, E);
2386 return this->emitInitField(T, FieldToInit->Offset, E);
2387 };
2388
2389 auto initCompositeField = [=](const Record::Field *FieldToInit,
2390 const Expr *Init,
2391 bool Activate = false) -> bool {
2393 InitLinkScope<Emitter> ILS(this, InitLink::Field(FieldToInit->Offset));
2394
2395 // Non-primitive case. Get a pointer to the field-to-initialize
2396 // on the stack and recurse into visitInitializer().
2397 if (!this->emitGetPtrField(FieldToInit->Offset, Init))
2398 return false;
2399
2400 if (Activate && !this->emitActivate(E))
2401 return false;
2402
2403 if (!this->emitStartInit(Init))
2404 return false;
2405
2406 return this->visitInitializerPop(Init) && this->emitEndInit(Init);
2407 };
2408
2409 if (R->isUnion()) {
2410 if (Inits.size() == 0) {
2411 if (!this->visitZeroRecordInitializer(R, E))
2412 return false;
2413 } else {
2414 const Expr *Init = Inits[0];
2415 const FieldDecl *FToInit = nullptr;
2416 if (const auto *ILE = dyn_cast<InitListExpr>(E))
2417 FToInit = ILE->getInitializedFieldInUnion();
2418 else
2419 FToInit = cast<CXXParenListInitExpr>(E)->getInitializedFieldInUnion();
2420
2421 const Record::Field *FieldToInit = R->getField(FToInit);
2422 if (OptPrimType T = classify(Init)) {
2423 if (!initPrimitiveField(FieldToInit, Init, *T, /*Activate=*/true))
2424 return false;
2425 } else {
2426 if (!initCompositeField(FieldToInit, Init, /*Activate=*/true))
2427 return false;
2428 }
2429 }
2430 return this->emitFinishInit(E);
2431 }
2432
2433 assert(!R->isUnion());
2434 for (unsigned BI = 0; BI != R->getNumBases(); ++BI) {
2435 const Expr *Init = Inits[BI];
2436 const Record::Base *B = R->getBase(BI);
2438 InitLinkScope<Emitter> ILS(this, InitLink::Base(B->Offset));
2439 if (!this->emitGetPtrBase(B->Offset, Init))
2440 return false;
2441 if (!this->visitInitializerPop(Init))
2442 return false;
2443 }
2444
2445 unsigned FieldIndex = 0;
2446 for (unsigned FI = R->getNumBases(); FI != Inits.size();) {
2447 const Record::Field *FieldToInit = R->getField(FieldIndex);
2448 if (FieldToInit->isUnnamedBitField()) {
2449 ++FieldIndex;
2450 continue;
2451 }
2452
2453 const Expr *Init = Inits[FI];
2454 // If this is a child of a DesignatedInitUpdateExpr, skip elements which
2455 // aren't supposed to be modified.
2456 if (isa<NoInitExpr>(Init)) {
2457 ++FieldIndex;
2458 ++FI;
2459 continue;
2460 }
2461
2462 if (OptPrimType T = classify(Init)) {
2463 if (!initPrimitiveField(FieldToInit, Init, *T))
2464 return false;
2465 } else if (!initCompositeField(FieldToInit, Init)) {
2466 return false;
2467 }
2468
2469 ++FI;
2470 ++FieldIndex;
2471 }
2472
2473 assert(R->getNumVirtualBases() == 0);
2474
2475 return this->emitFinishInit(E);
2476 }
2477
2478 if (QT->isArrayType()) {
2479 const ConstantArrayType *CAT =
2480 Ctx.getASTContext().getAsConstantArrayType(QT);
2481 uint64_t NumElems = CAT->getZExtSize();
2482
2483 if (Initializing &&
2484 (!InitializingDecl || InitializingDecl->hasLocalStorage()) &&
2485 !this->emitCheckArrayDestSize(NumElems, E))
2486 return false;
2487
2488 if (Inits.size() == 1 && QT == Inits[0]->getType())
2489 return this->delegate(Inits[0]);
2490
2491 OptPrimType InitT = classify(CAT->getElementType());
2492 unsigned ElementIndex = 0;
2493 for (const Expr *Init : Inits) {
2494 if (const auto *EmbedS =
2495 dyn_cast<EmbedExpr>(Init->IgnoreParenImpCasts())) {
2496 PrimType TargetT = classifyPrim(Init->getType());
2497
2498 auto Eval = [&](const IntegerLiteral *IL, unsigned ElemIndex) {
2499 if (TargetT == PT_Float) {
2500 if (!this->emitConst(IL->getValue(), classifyPrim(IL), Init))
2501 return false;
2502 const auto *Sem = &Ctx.getFloatSemantics(CAT->getElementType());
2503 if (!this->emitCastIntegralFloating(classifyPrim(IL), Sem,
2504 getFPOptions(E), E))
2505 return false;
2506 } else {
2507 if (!this->emitConst(IL->getValue(), TargetT, Init))
2508 return false;
2509 }
2510 return this->emitInitElem(TargetT, ElemIndex, IL);
2511 };
2512 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
2513 return false;
2514 } else if (isa<NoInitExpr>(Init)) {
2515 // If this is a child of a DesignatedInitUpdateExpr, skip elements which
2516 // aren't supposed to be modified.
2517 ++ElementIndex;
2518 } else {
2519 if (!this->visitArrayElemInit(ElementIndex, Init, InitT))
2520 return false;
2521 ++ElementIndex;
2522 }
2523 }
2524
2525 // Expand the filler expression.
2526 // FIXME: This should go away.
2527 if (ArrayFiller && !isa<NoInitExpr>(ArrayFiller)) {
2528 for (; ElementIndex != NumElems; ++ElementIndex) {
2529 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller, InitT))
2530 return false;
2531 }
2532 }
2533
2534 return this->emitFinishInit(E);
2535 }
2536
2537 if (const auto *ComplexTy = QT->getAs<ComplexType>()) {
2538 unsigned NumInits = Inits.size();
2539
2540 if (NumInits == 1)
2541 return this->delegate(Inits[0]);
2542
2543 QualType ElemQT = ComplexTy->getElementType();
2544 PrimType ElemT = classifyPrim(ElemQT);
2545 if (NumInits == 0) {
2546 // Zero-initialize both elements.
2547 for (unsigned I = 0; I < 2; ++I) {
2548 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2549 return false;
2550 if (!this->emitInitElem(ElemT, I, E))
2551 return false;
2552 }
2553 } else if (NumInits == 2) {
2554 unsigned InitIndex = 0;
2555 for (const Expr *Init : Inits) {
2556 if (!this->visit(Init))
2557 return false;
2558
2559 if (!this->emitInitElem(ElemT, InitIndex, E))
2560 return false;
2561 ++InitIndex;
2562 }
2563 }
2564 return true;
2565 }
2566
2567 if (const auto *VecT = QT->getAs<VectorType>()) {
2568 unsigned NumVecElements = VecT->getNumElements();
2569 assert(NumVecElements >= Inits.size());
2570
2571 QualType ElemQT = VecT->getElementType();
2572 PrimType ElemT = classifyPrim(ElemQT);
2573
2574 // All initializer elements.
2575 unsigned InitIndex = 0;
2576 for (const Expr *Init : Inits) {
2577 if (!this->visit(Init))
2578 return false;
2579
2580 // If the initializer is of vector type itself, we have to deconstruct
2581 // that and initialize all the target fields from the initializer fields.
2582 if (const auto *InitVecT = Init->getType()->getAs<VectorType>()) {
2583 if (!this->emitCopyArray(ElemT, 0, InitIndex,
2584 InitVecT->getNumElements(), E))
2585 return false;
2586 InitIndex += InitVecT->getNumElements();
2587 } else {
2588 if (!this->emitInitElem(ElemT, InitIndex, E))
2589 return false;
2590 ++InitIndex;
2591 }
2592 }
2593
2594 assert(InitIndex <= NumVecElements);
2595
2596 // Fill the rest with zeroes.
2597 for (; InitIndex != NumVecElements; ++InitIndex) {
2598 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2599 return false;
2600 if (!this->emitInitElem(ElemT, InitIndex, E))
2601 return false;
2602 }
2603 return true;
2604 }
2605
2606 if (const auto *MT = QT->getAs<ConstantMatrixType>()) {
2607 unsigned NumElems = MT->getNumElementsFlattened();
2608 assert(Inits.size() == NumElems);
2609
2610 QualType ElemQT = MT->getElementType();
2611 PrimType ElemT = classifyPrim(ElemQT);
2612
2613 // Matrix initializer list elements are in row-major order, which matches
2614 // the matrix APValue convention and therefore no index remapping is
2615 // required.
2616 for (unsigned I = 0; I != NumElems; ++I) {
2617 if (!this->visit(Inits[I]))
2618 return false;
2619 if (!this->emitInitElem(ElemT, I, E))
2620 return false;
2621 }
2622 return true;
2623 }
2624
2625 return false;
2626}
2627
2628/// Pointer to the array(not the element!) must be on the stack when calling
2629/// this.
2630template <class Emitter>
2631bool Compiler<Emitter>::visitArrayElemInit(unsigned ElemIndex, const Expr *Init,
2632 OptPrimType InitT) {
2633 if (InitT) {
2634 // Visit the primitive element like normal.
2635 if (!this->visit(Init))
2636 return false;
2637 return this->emitInitElem(*InitT, ElemIndex, Init);
2638 }
2639
2640 InitLinkScope<Emitter> ILS(this, InitLink::Elem(ElemIndex));
2641 // Advance the pointer currently on the stack to the given
2642 // dimension.
2643 if (!this->emitConstUint32(ElemIndex, Init))
2644 return false;
2645 if (!this->emitArrayElemPtrUint32(Init))
2646 return false;
2647 return this->visitInitializerPop(Init);
2648}
2649
2650template <class Emitter>
2652 const FunctionDecl *FuncDecl,
2653 bool Activate, bool IsOperatorCall) {
2654 assert(VarScope->getKind() == ScopeKind::Call);
2655 llvm::BitVector NonNullArgs;
2656 if (FuncDecl && FuncDecl->hasAttr<NonNullAttr>())
2657 NonNullArgs = collectNonNullArgs(FuncDecl, Args);
2658
2659 bool ExplicitMemberFn = false;
2660 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl))
2661 ExplicitMemberFn = MD->isExplicitObjectMemberFunction();
2662
2663 unsigned ArgIndex = 0;
2664 for (const Expr *Arg : Args) {
2665 if (canClassify(Arg)) {
2666 if (!this->visit(Arg))
2667 return false;
2668 } else {
2669
2670 DeclOrExpr Source = Arg;
2671 if (FuncDecl) {
2672 // Try to use the parameter declaration instead of the argument
2673 // expression as a source.
2674 unsigned DeclIndex = ArgIndex - IsOperatorCall + ExplicitMemberFn;
2675 if (DeclIndex < FuncDecl->getNumParams())
2676 Source = FuncDecl->getParamDecl(ArgIndex - IsOperatorCall +
2677 ExplicitMemberFn);
2678 }
2679
2680 UnsignedOrNone LocalIndex =
2681 allocateLocal(std::move(Source), Arg->getType(), ScopeKind::Call);
2682 if (!LocalIndex)
2683 return false;
2684
2685 if (!this->emitGetPtrLocal(*LocalIndex, Arg))
2686 return false;
2687 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
2688 if (!this->visitInitializer(Arg))
2689 return false;
2690 }
2691
2692 if (ArgIndex == 1 && Activate) {
2693 if (!this->emitActivate(Arg))
2694 return false;
2695 }
2696
2697 if (!NonNullArgs.empty() && NonNullArgs[ArgIndex]) {
2698 PrimType ArgT = classify(Arg).value_or(PT_Ptr);
2699 if (ArgT == PT_Ptr) {
2700 if (!this->emitCheckNonNullArg(ArgT, Arg))
2701 return false;
2702 }
2703 }
2704
2705 ++ArgIndex;
2706 }
2707
2708 return true;
2709}
2710
2711template <class Emitter>
2713 return this->visitInitList(E->inits(), E->getArrayFiller(), E);
2714}
2715
2716template <class Emitter>
2721
2722template <class Emitter>
2727
2728template <class Emitter>
2730 if (!E->hasAPValueResult())
2731 return this->delegate(E->getSubExpr());
2732
2733 if (OptPrimType T = classify(E)) {
2734 // Try to emit the APValue directly, without visiting the subexpr.
2735 // This will only fail if we can't emit the APValue, so won't emit any
2736 // diagnostics or any double values.
2737 if (DiscardResult)
2738 return true;
2739 return this->visitAPValue(E->getAPValueResult(), *T, E);
2740 }
2741
2742 // Fall back to the subexpr for non-primitive APValues.
2743 return this->delegate(E->getSubExpr());
2744}
2745
2746template <class Emitter>
2748 auto It = E->begin();
2749 return this->visit(*It);
2750}
2751
2753 UnaryExprOrTypeTrait Kind) {
2754 bool AlignOfReturnsPreferred =
2755 ASTCtx.getLangOpts().isCompatibleWith(LangOptions::ClangABI::Ver7);
2756
2757 // C++ [expr.alignof]p3:
2758 // When alignof is applied to a reference type, the result is the
2759 // alignment of the referenced type.
2760 if (const auto *Ref = T->getAs<ReferenceType>())
2761 T = Ref->getPointeeType();
2762
2763 if (T.getQualifiers().hasUnaligned())
2764 return CharUnits::One();
2765
2766 // __alignof is defined to return the preferred alignment.
2767 // Before 8, clang returned the preferred alignment for alignof and
2768 // _Alignof as well.
2769 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2770 return ASTCtx.toCharUnitsFromBits(ASTCtx.getPreferredTypeAlign(T));
2771
2772 return ASTCtx.getTypeAlignInChars(T);
2773}
2774
2775template <class Emitter>
2777 const UnaryExprOrTypeTraitExpr *E) {
2778
2779 UnaryExprOrTypeTrait Kind = E->getKind();
2780 const ASTContext &ASTCtx = Ctx.getASTContext();
2781
2782 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2784
2785 // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
2786 // the result is the size of the referenced type."
2787 if (const auto *Ref = ArgType->getAs<ReferenceType>())
2788 ArgType = Ref->getPointeeType();
2789
2790 CharUnits Size;
2791 if (ArgType->isVoidType() || ArgType->isFunctionType())
2792 Size = CharUnits::One();
2793 else {
2794 if (ArgType->isDependentType() || !ArgType->isConstantSizeType())
2795 return this->emitInvalid(E);
2796
2797 if (Kind == UETT_SizeOf)
2798 Size = ASTCtx.getTypeSizeInChars(ArgType);
2799 else
2801 }
2802
2803 if (DiscardResult)
2804 return true;
2805
2806 return this->emitConst(Size.getQuantity(), E);
2807 }
2808
2809 if (Kind == UETT_CountOf) {
2810 QualType Ty = E->getTypeOfArgument();
2811 assert(Ty->isArrayType());
2812
2813 // We don't need to worry about array element qualifiers, so getting the
2814 // unsafe array type is fine.
2815 if (const auto *CAT =
2816 dyn_cast<ConstantArrayType>(Ty->getAsArrayTypeUnsafe())) {
2817 if (DiscardResult)
2818 return true;
2819 return this->emitConst(CAT->getSize(), E);
2820 }
2821
2822 assert(!Ty->isConstantSizeType());
2823
2824 // If it's a variable-length array type, we need to check whether it is a
2825 // multidimensional array. If so, we need to check the size expression of
2826 // the VLA to see if it's a constant size. If so, we can return that value.
2827 const auto *VAT = ASTCtx.getAsVariableArrayType(Ty);
2828 assert(VAT);
2829 if (VAT->getElementType()->isArrayType()) {
2830 std::optional<APSInt> Res =
2831 VAT->getSizeExpr()
2832 ? VAT->getSizeExpr()->getIntegerConstantExpr(ASTCtx)
2833 : std::nullopt;
2834 if (Res) {
2835 if (DiscardResult)
2836 return true;
2837 return this->emitConst(*Res, E);
2838 }
2839 }
2840 }
2841
2842 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2843 CharUnits Size;
2844
2845 if (E->isArgumentType()) {
2847
2848 Size = AlignOfType(ArgType, ASTCtx, Kind);
2849 } else {
2850 // Argument is an expression, not a type.
2851 const Expr *Arg = E->getArgumentExpr()->IgnoreParens();
2852
2853 if (Arg->getType()->isDependentType())
2854 return false;
2855
2856 // The kinds of expressions that we have special-case logic here for
2857 // should be kept up to date with the special checks for those
2858 // expressions in Sema.
2859
2860 // alignof decl is always accepted, even if it doesn't make sense: we
2861 // default to 1 in those cases.
2862 if (const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2863 Size = ASTCtx.getDeclAlign(DRE->getDecl(),
2864 /*RefAsPointee*/ true);
2865 else if (const auto *ME = dyn_cast<MemberExpr>(Arg))
2866 Size = ASTCtx.getDeclAlign(ME->getMemberDecl(),
2867 /*RefAsPointee*/ true);
2868 else
2869 Size = AlignOfType(Arg->getType(), ASTCtx, Kind);
2870 }
2871
2872 if (DiscardResult)
2873 return true;
2874
2875 return this->emitConst(Size.getQuantity(), E);
2876 }
2877
2878 if (Kind == UETT_VectorElements) {
2879 if (E->containsErrors())
2880 return false;
2881
2882 if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>())
2883 return this->emitConst(VT->getNumElements(), E);
2885 return this->emitSizelessVectorElementSize(E);
2886 }
2887
2888 if (Kind == UETT_VecStep) {
2889 if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>()) {
2890 unsigned N = VT->getNumElements();
2891
2892 // The vec_step built-in functions that take a 3-component
2893 // vector return 4. (OpenCL 1.1 spec 6.11.12)
2894 if (N == 3)
2895 N = 4;
2896
2897 return this->emitConst(N, E);
2898 }
2899 return this->emitConst(1, E);
2900 }
2901
2902 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2903 if (E->containsErrors())
2904 return false;
2905 assert(E->isArgumentType());
2906 unsigned Bits = ASTCtx.getOpenMPDefaultSimdAlign(E->getArgumentType());
2907
2908 return this->emitConst(ASTCtx.toCharUnitsFromBits(Bits).getQuantity(), E);
2909 }
2910
2911 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2912 if (E->getArgumentType()->isDependentType())
2913 return this->emitInvalid(E);
2914
2915 return this->emitConst(
2916 const_cast<ASTContext &>(ASTCtx).getPointerAuthTypeDiscriminator(
2917 E->getArgumentType()),
2918 E);
2919 }
2920
2921 return false;
2922}
2923
2924template <class Emitter>
2926 // 'Base.Member'
2927 const Expr *Base = E->getBase();
2928 const ValueDecl *Member = E->getMemberDecl();
2929
2930 if (DiscardResult)
2931 return this->discard(Base);
2932
2933 if (const auto *VD = dyn_cast<VarDecl>(Member)) {
2934 // If the member is a VarDecl, this is a static variable.
2935 // We need to try to lazily evaluate its initializer here since the
2936 // variable might've been deserialized and not registered
2937 // as a global variable yet.
2938 if (VD->getInit() && !VD->getInit()->isValueDependent())
2939 VD->evaluateValue();
2940 if (auto GlobalIndex = P.getGlobal(VD)) {
2941 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2942 return false;
2943 if (Member->getType()->isReferenceType())
2944 return this->emitLoadPopPtr(E);
2945 return true;
2946 }
2947 return false;
2948 }
2949
2950 if (!isa<FieldDecl>(Member)) {
2951 // A non-static member function access only makes sense as part of the
2952 // enclosing call here. Don't try to evaluate it in isolation.
2953 if (const auto *MD = dyn_cast<CXXMethodDecl>(Member);
2954 MD && !MD->isStatic()) {
2955 return false;
2956 }
2957
2958 if (!this->discard(Base) && !this->emitSideEffect(E))
2959 return false;
2960
2961 return this->visitDeclRef(Member, E);
2962 }
2963
2964 if (!this->visit(Base))
2965 return false;
2966
2967 // Base above gives us a pointer on the stack.
2968 const auto *FD = cast<FieldDecl>(Member);
2969 const RecordDecl *RD = FD->getParent();
2970 const Record *R = getRecord(RD);
2971 if (!R)
2972 return false;
2973 const Record::Field *F = R->getField(FD);
2974
2975 // MemberExprs are almost always lvalues, in which case we don't need to
2976 // do the load. But sometimes they aren't.
2977 const auto maybeLoadValue = [&]() -> bool {
2978 if (E->isGLValue())
2979 return true;
2980 if (OptPrimType T = classify(E))
2981 return this->emitLoadPop(*T, E);
2982 return false;
2983 };
2984
2985 // Leave a pointer to the field on the stack.
2986 if (F->Decl->getType()->isReferenceType())
2987 return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue();
2988 return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue();
2989}
2990
2991template <class Emitter>
2993 assert(!DiscardResult);
2994 // ArrayIndex might not be set if a ArrayInitIndexExpr is being evaluated
2995 // stand-alone, e.g. via EvaluateAsInt().
2996 if (!ArrayIndex)
2997 return false;
2998 return this->emitConst(*ArrayIndex, E);
2999}
3000
3001template <class Emitter>
3003 assert(Initializing);
3004 assert(!DiscardResult);
3005
3006 const Expr *Common = E->getCommonExpr();
3007 const Expr *SubExpr = E->getSubExpr();
3008 OptPrimType SubExprT = classify(SubExpr);
3009 size_t Size = E->getArraySize().getZExtValue();
3010
3011 if (SubExprT) {
3012 // Unwrap the OpaqueValueExpr so we don't cache something we won't reuse.
3013 Common = cast<OpaqueValueExpr>(Common)->getSourceExpr();
3014
3015 if (!this->visit(Common))
3016 return false;
3017 return this->emitCopyArray(*SubExprT, 0, 0, Size, E);
3018 }
3019
3020 // We visit the common opaque expression here once so we have its value
3021 // cached.
3022 if (!this->discard(Common))
3023 return false;
3024
3025 // TODO: This compiles to quite a lot of bytecode if the array is larger.
3026 // Investigate compiling this to a loop.
3027
3028 // So, every iteration, we execute an assignment here
3029 // where the LHS is on the stack (the target array)
3030 // and the RHS is our SubExpr.
3031 for (size_t I = 0; I != Size; ++I) {
3032 ArrayIndexScope<Emitter> IndexScope(this, I);
3034
3035 if (!this->visitArrayElemInit(I, SubExpr, SubExprT))
3036 return false;
3037 if (!BS.destroyLocals())
3038 return false;
3039 }
3040 return true;
3041}
3042
3043template <class Emitter>
3045 const Expr *SourceExpr = E->getSourceExpr();
3046 if (!SourceExpr)
3047 return false;
3048
3049 if (Initializing) {
3050 assert(!DiscardResult);
3051 return this->visitInitializer(SourceExpr);
3052 }
3053
3054 PrimType SubExprT = classify(SourceExpr).value_or(PT_Ptr);
3055 if (auto It = OpaqueExprs.find(E); It != OpaqueExprs.end()) {
3056 if (DiscardResult)
3057 return true;
3058 return this->emitGetLocal(SubExprT, It->second, E);
3059 }
3060
3061 if (!this->visit(SourceExpr))
3062 return false;
3063
3064 // At this point we either have the evaluated source expression or a pointer
3065 // to an object on the stack. We want to create a local variable that stores
3066 // this value.
3067 unsigned LocalIndex = allocateLocalPrimitive(E, SubExprT, /*IsConst=*/true);
3068 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
3069 return false;
3070
3071 // This is cleaned up when the local variable is destroyed.
3072 OpaqueExprs.insert({E, LocalIndex});
3073
3074 // Here the local variable is created but the value is removed from the stack,
3075 // so we put it back if the caller needs it.
3076 if (!DiscardResult)
3077 return this->emitGetLocal(SubExprT, LocalIndex, E);
3078 return true;
3079}
3080
3081template <class Emitter>
3083 const AbstractConditionalOperator *E) {
3084 const Expr *Condition = E->getCond();
3085 const Expr *TrueExpr = E->getTrueExpr();
3086 const Expr *FalseExpr = E->getFalseExpr();
3087
3088 if (std::optional<bool> BoolValue = getBoolValue(Condition)) {
3089 if (*BoolValue)
3090 return this->delegate(TrueExpr);
3091 return this->delegate(FalseExpr);
3092 }
3093
3094 bool IsBcpCall = false;
3095 if (const auto *CE = dyn_cast<CallExpr>(Condition->IgnoreParenCasts());
3096 CE && CE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) {
3097 IsBcpCall = true;
3098 }
3099
3100 LabelTy LabelEnd = this->getLabel(); // Label after the operator.
3101 LabelTy LabelFalse = this->getLabel(); // Label for the false expr.
3102
3103 if (IsBcpCall) {
3104 if (!this->emitPushIgnoreDiags(E))
3105 return false;
3106 }
3107
3108 if (!this->visitBool(Condition)) {
3109 // If the condition failed and we're checking for undefined behavior
3110 // (which only happens with EvalEmitter) check the TrueExpr and FalseExpr
3111 // as well.
3112 if (this->checkingForUndefinedBehavior()) {
3113 if (!this->discard(TrueExpr))
3114 return false;
3115 if (!this->discard(FalseExpr))
3116 return false;
3117 }
3118 return false;
3119 }
3120
3121 // Force-init the scope, which creates a InitScope op. This is necessary so
3122 // the scope is not only initialized in one arm of the conditional operator.
3123 this->VarScope->forceInit();
3124 // The TrueExpr and FalseExpr of a conditional operator do _not_ create a
3125 // scope, which means the local variables created within them unconditionally
3126 // always exist. However, we need to later differentiate which branch was
3127 // taken and only destroy the varibles of the active branch. This is what the
3128 // "enabled" flags on local variables are used for.
3129 llvm::SaveAndRestore LAAA(this->VarScope->LocalsAlwaysEnabled,
3130 /*NewValue=*/false);
3131
3132 if (!this->jumpFalse(LabelFalse, E))
3133 return false;
3134 if (!this->delegate(TrueExpr))
3135 return false;
3136
3137 if (!this->jump(LabelEnd, E))
3138 return false;
3139 this->emitLabel(LabelFalse);
3140 if (!this->delegate(FalseExpr))
3141 return false;
3142
3143 this->fallthrough(LabelEnd);
3144 this->emitLabel(LabelEnd);
3145
3146 if (IsBcpCall)
3147 return this->emitPopIgnoreDiags(E);
3148 return true;
3149}
3150
3151template <class Emitter>
3153 if (DiscardResult)
3154 return true;
3155
3156 if (!Initializing)
3157 return this->emitGetStringPtr(E, E);
3158
3159 // We are initializing an array on the stack.
3160 const ConstantArrayType *CAT =
3161 Ctx.getASTContext().getAsConstantArrayType(E->getType());
3162 assert(CAT && "a string literal that's not a constant array?");
3163
3164 // If the initializer string is too long, a diagnostic has already been
3165 // emitted. Read only the array length from the string literal.
3166 unsigned ArraySize = CAT->getZExtSize();
3167 unsigned N = std::min(ArraySize, E->getLength());
3168 unsigned CharWidth = E->getCharByteWidth();
3169
3170 for (unsigned I = 0; I != N; ++I) {
3171 uint32_t CodeUnit = E->getCodeUnit(I);
3172
3173 if (CharWidth == 1) {
3174 this->emitConstSint8(CodeUnit, E);
3175 this->emitInitElemSint8(I, E);
3176 } else if (CharWidth == 2) {
3177 this->emitConstUint16(CodeUnit, E);
3178 this->emitInitElemUint16(I, E);
3179 } else if (CharWidth == 4) {
3180 this->emitConstUint32(CodeUnit, E);
3181 this->emitInitElemUint32(I, E);
3182 } else {
3183 llvm_unreachable("unsupported character width");
3184 }
3185 }
3186
3187 // Fill up the rest of the char array with NUL bytes.
3188 for (unsigned I = N; I != ArraySize; ++I) {
3189 if (CharWidth == 1) {
3190 this->emitConstSint8(0, E);
3191 this->emitInitElemSint8(I, E);
3192 } else if (CharWidth == 2) {
3193 this->emitConstUint16(0, E);
3194 this->emitInitElemUint16(I, E);
3195 } else if (CharWidth == 4) {
3196 this->emitConstUint32(0, E);
3197 this->emitInitElemUint32(I, E);
3198 } else {
3199 llvm_unreachable("unsupported character width");
3200 }
3201 }
3202
3203 return true;
3204}
3205
3206template <class Emitter>
3208 if (DiscardResult)
3209 return true;
3210 return this->emitDummyPtr(E, E);
3211}
3212
3213template <class Emitter>
3215 auto &A = Ctx.getASTContext();
3216 std::string Str;
3217 A.getObjCEncodingForType(E->getEncodedType(), Str);
3218 StringLiteral *SL =
3220 /*Pascal=*/false, E->getType(), E->getAtLoc());
3221 return this->delegate(SL);
3222}
3223
3224template <class Emitter>
3226 const SYCLUniqueStableNameExpr *E) {
3227 if (DiscardResult)
3228 return true;
3229
3230 assert(!Initializing);
3231
3232 auto &A = Ctx.getASTContext();
3233 std::string ResultStr = E->ComputeName(A);
3234
3235 QualType CharTy = A.CharTy.withConst();
3236 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
3237 QualType ArrayTy = A.getConstantArrayType(CharTy, Size, nullptr,
3239
3240 StringLiteral *SL =
3242 /*Pascal=*/false, ArrayTy, E->getLocation());
3243 return this->emitGetStringPtr(SL, E);
3244}
3245
3246template <class Emitter>
3248 if (DiscardResult)
3249 return true;
3250 return this->emitConst(E->getValue(), E);
3251}
3252
3253template <class Emitter>
3255 const CompoundAssignOperator *E) {
3256
3257 const Expr *LHS = E->getLHS();
3258 const Expr *RHS = E->getRHS();
3259 QualType LHSType = LHS->getType();
3260 QualType LHSComputationType = E->getComputationLHSType();
3261 QualType ResultType = E->getComputationResultType();
3262 OptPrimType LT = classify(LHSComputationType);
3263 OptPrimType RT = classify(ResultType);
3264
3265 assert(ResultType->isFloatingType());
3266
3267 if (!LT || !RT)
3268 return false;
3269
3270 PrimType LHST = classifyPrim(LHSType);
3271
3272 if (isSideEffectFree(RHS)) {
3273 if (!visit(LHS))
3274 return false;
3275 if (!this->emitLoad(LHST, E))
3276 return false;
3277 // If necessary, convert LHS to its computation type.
3278 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
3279 LHSComputationType, E))
3280 return false;
3281 if (!visit(RHS))
3282 return false;
3283
3284 } else {
3285 // C++17 onwards require that we evaluate the RHS first.
3286 // Compute RHS and save it in a temporary variable so we can
3287 // load it again later.
3288 if (!visit(RHS))
3289 return false;
3290
3291 unsigned TempOffset =
3292 this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
3293 if (!this->emitSetLocal(*RT, TempOffset, E))
3294 return false;
3295
3296 // First, visit LHS.
3297 if (!visit(LHS))
3298 return false;
3299 if (!this->emitLoad(LHST, E))
3300 return false;
3301
3302 // If necessary, convert LHS to its computation type.
3303 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
3304 LHSComputationType, E))
3305 return false;
3306
3307 // Now load RHS.
3308 if (!this->emitGetLocal(*RT, TempOffset, E))
3309 return false;
3310 }
3311
3312 switch (E->getOpcode()) {
3313 case BO_AddAssign:
3314 if (!this->emitAddf(getFPOptions(E), E))
3315 return false;
3316 break;
3317 case BO_SubAssign:
3318 if (!this->emitSubf(getFPOptions(E), E))
3319 return false;
3320 break;
3321 case BO_MulAssign:
3322 if (!this->emitMulf(getFPOptions(E), E))
3323 return false;
3324 break;
3325 case BO_DivAssign:
3326 if (!this->emitDivf(getFPOptions(E), E))
3327 return false;
3328 break;
3329 default:
3330 return false;
3331 }
3332
3333 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->getType(), E))
3334 return false;
3335
3336 if (DiscardResult)
3337 return this->emitStorePop(LHST, E);
3338 return this->emitStore(LHST, E);
3339}
3340
3341template <class Emitter>
3343 const CompoundAssignOperator *E) {
3344 BinaryOperatorKind Op = E->getOpcode();
3345 const Expr *LHS = E->getLHS();
3346 const Expr *RHS = E->getRHS();
3347 OptPrimType LT = classify(LHS->getType());
3348 OptPrimType RT = classify(RHS->getType());
3349
3350 if (Op != BO_AddAssign && Op != BO_SubAssign)
3351 return false;
3352
3353 if (!LT || !RT)
3354 return false;
3355
3356 if (!visit(LHS))
3357 return false;
3358
3359 if (!this->emitLoad(*LT, LHS))
3360 return false;
3361
3362 if (!visit(RHS))
3363 return false;
3364
3365 if (Op == BO_AddAssign) {
3366 if (!this->emitAddOffset(*RT, E))
3367 return false;
3368 } else {
3369 if (!this->emitSubOffset(*RT, E))
3370 return false;
3371 }
3372
3373 if (DiscardResult)
3374 return this->emitStorePopPtr(E);
3375 return this->emitStorePtr(E);
3376}
3377
3378template <class Emitter>
3380 const CompoundAssignOperator *E) {
3381 if (E->getType()->isVectorType())
3382 return VisitVectorBinOp(E);
3383
3384 const Expr *LHS = E->getLHS();
3385 const Expr *RHS = E->getRHS();
3386 OptPrimType LHSComputationT = classify(E->getComputationLHSType());
3387 OptPrimType LT = classify(LHS->getType());
3388 OptPrimType RT = classify(RHS->getType());
3389 OptPrimType ResultT = classify(E->getType());
3390
3391 if (!Ctx.getLangOpts().CPlusPlus14)
3392 return this->visit(RHS) && this->visit(LHS) && this->emitError(E);
3393
3394 if (!LT || !RT || !ResultT || !LHSComputationT)
3395 return false;
3396
3397 // Handle floating point operations separately here, since they
3398 // require special care.
3399 if (ResultT == PT_Float || RT == PT_Float)
3401
3402 if (E->getType()->isPointerType())
3404
3405 assert(!E->getType()->isPointerType() && "Handled above");
3406 assert(!E->getType()->isFloatingType() && "Handled above");
3407
3408 if (isSideEffectFree(RHS)) {
3409 if (!visit(LHS))
3410 return false;
3411 if (!this->emitLoad(*LT, E))
3412 return false;
3413 if (LT != LHSComputationT &&
3414 !this->emitIntegralCast(*LT, *LHSComputationT,
3415 E->getComputationLHSType(), E))
3416 return false;
3417 if (!visit(RHS))
3418 return false;
3419 } else {
3420 // C++17 onwards require that we evaluate the RHS first.
3421 // Compute RHS and save it in a temporary variable so we can
3422 // load it again later.
3423 // FIXME: Compound assignments are unsequenced in C, so we might
3424 // have to figure out how to reject them.
3425 if (!visit(RHS))
3426 return false;
3427
3428 unsigned TempOffset =
3429 this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
3430
3431 if (!this->emitSetLocal(*RT, TempOffset, E))
3432 return false;
3433
3434 // Get LHS pointer, load its value and cast it to the
3435 // computation type if necessary.
3436 if (!visit(LHS))
3437 return false;
3438 if (!this->emitLoad(*LT, E))
3439 return false;
3440 if (LT != LHSComputationT &&
3441 !this->emitIntegralCast(*LT, *LHSComputationT,
3442 E->getComputationLHSType(), E))
3443 return false;
3444
3445 // Get the RHS value on the stack.
3446 if (!this->emitGetLocal(*RT, TempOffset, E))
3447 return false;
3448 }
3449
3450 // Perform operation.
3451 switch (E->getOpcode()) {
3452 case BO_AddAssign:
3453 if (!this->emitAdd(*LHSComputationT, E))
3454 return false;
3455 break;
3456 case BO_SubAssign:
3457 if (!this->emitSub(*LHSComputationT, E))
3458 return false;
3459 break;
3460 case BO_MulAssign:
3461 if (!this->emitMul(*LHSComputationT, E))
3462 return false;
3463 break;
3464 case BO_DivAssign:
3465 if (!this->emitDiv(*LHSComputationT, E))
3466 return false;
3467 break;
3468 case BO_RemAssign:
3469 if (!this->emitRem(*LHSComputationT, E))
3470 return false;
3471 break;
3472 case BO_ShlAssign:
3473 if (!this->emitShl(*LHSComputationT, *RT, E))
3474 return false;
3475 break;
3476 case BO_ShrAssign:
3477 if (!this->emitShr(*LHSComputationT, *RT, E))
3478 return false;
3479 break;
3480 case BO_AndAssign:
3481 if (!this->emitBitAnd(*LHSComputationT, E))
3482 return false;
3483 break;
3484 case BO_XorAssign:
3485 if (!this->emitBitXor(*LHSComputationT, E))
3486 return false;
3487 break;
3488 case BO_OrAssign:
3489 if (!this->emitBitOr(*LHSComputationT, E))
3490 return false;
3491 break;
3492 default:
3493 llvm_unreachable("Unimplemented compound assign operator");
3494 }
3495
3496 // And now cast from LHSComputationT to ResultT.
3497 if (ResultT != LHSComputationT &&
3498 !this->emitIntegralCast(*LHSComputationT, *ResultT, E->getType(), E))
3499 return false;
3500
3501 // And store the result in LHS.
3502 if (DiscardResult) {
3503 if (LHS->refersToBitField())
3504 return this->emitStoreBitFieldPop(*ResultT, E);
3505 return this->emitStorePop(*ResultT, E);
3506 }
3507 if (LHS->refersToBitField())
3508 return this->emitStoreBitField(*ResultT, E);
3509 return this->emitStore(*ResultT, E);
3510}
3511
3512template <class Emitter>
3515 const Expr *SubExpr = E->getSubExpr();
3516
3517 return this->delegate(SubExpr) && ES.destroyLocals(E);
3518}
3519
3520template <class Emitter>
3522 const MaterializeTemporaryExpr *E) {
3523 if (Initializing) {
3524 // We already have a value, just initialize that.
3525 return this->delegate(E->getSubExpr());
3526 }
3527 // If we don't end up using the materialized temporary anyway, don't
3528 // bother creating it.
3529 if (DiscardResult)
3530 return this->discard(E->getSubExpr());
3531
3534 const Expr *Inner;
3535 if (!Ctx.getLangOpts().CPlusPlus11)
3536 Inner =
3537 E->getSubExpr()->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
3538 else
3539 Inner = E->getSubExpr();
3540
3541 // If we passed any comma operators, evaluate their LHSs.
3542 for (const Expr *LHS : CommaLHSs) {
3543 if (!this->discard(LHS))
3544 return false;
3545 }
3546
3547 // FIXME: Find a test case where Adjustments matters.
3548
3549 // When we're extending a global variable *or* the storage duration of
3550 // the temporary is explicitly static, create a global variable.
3551 OptPrimType InnerT = classify(Inner);
3552 const ValueDecl *ExtendingDecl = E->getExtendingDecl();
3553 bool IsStatic = E->getStorageDuration() == SD_Static;
3554 if (IsStatic ||
3555 (ExtendingDecl && Context::shouldBeGloballyIndexed(ExtendingDecl))) {
3556 UnsignedOrNone GlobalIndex = P.createGlobal(E, Inner->getType());
3557 if (!GlobalIndex)
3558 return false;
3559
3560 const LifetimeExtendedTemporaryDecl *TempDecl =
3562
3563 if (InnerT) {
3564 if (!this->visit(Inner))
3565 return false;
3566
3567 if (IsStatic) {
3568 assert(TempDecl);
3569 if (!this->emitInitGlobalTemp(*InnerT, *GlobalIndex, TempDecl, E))
3570 return false;
3571 } else {
3572 if (!this->emitInitGlobal(*InnerT, *GlobalIndex, E))
3573 return false;
3574 }
3575 return this->emitGetPtrGlobal(*GlobalIndex, E);
3576 }
3577
3578 if (!this->checkLiteralType(Inner))
3579 return false;
3580 // Non-primitive values.
3581 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3582 return false;
3583 if (!this->visitInitializer(Inner))
3584 return false;
3585 if (IsStatic) {
3586 assert(TempDecl);
3587 return this->emitInitGlobalTempComp(TempDecl, E);
3588 }
3589 return true;
3590 }
3591
3595
3596 // For everyhing else, use local variables.
3597 if (InnerT) {
3598 bool IsConst = Inner->getType().isConstQualified();
3599 bool IsVolatile = Inner->getType().isVolatileQualified();
3600 unsigned LocalIndex =
3601 allocateLocalPrimitive(E, *InnerT, IsConst, IsVolatile, VarScope);
3602 if (!this->VarScope->LocalsAlwaysEnabled &&
3603 !this->emitEnableLocal(LocalIndex, E))
3604 return false;
3605
3606 if (!this->visit(Inner))
3607 return false;
3608 if (!this->emitSetLocal(*InnerT, LocalIndex, E))
3609 return false;
3610
3611 return this->emitGetPtrLocal(LocalIndex, E);
3612 }
3613
3614 if (!this->checkLiteralType(Inner))
3615 return false;
3616
3617 if (UnsignedOrNone LocalIndex =
3618 allocateLocal(E, Inner->getType(), VarScope)) {
3619 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
3620
3621 if (!this->VarScope->LocalsAlwaysEnabled &&
3622 !this->emitEnableLocal(*LocalIndex, E))
3623 return false;
3624
3625 if (!this->emitGetPtrLocal(*LocalIndex, E))
3626 return false;
3627 return this->visitInitializer(Inner);
3628 }
3629 return false;
3630}
3631
3632template <class Emitter>
3634 const CXXBindTemporaryExpr *E) {
3635 const Expr *SubExpr = E->getSubExpr();
3636
3637 if (Initializing)
3638 return this->delegate(SubExpr);
3639
3640 // Make sure we create a temporary even if we're discarding, since that will
3641 // make sure we will also call the destructor.
3642
3643 if (!this->visit(SubExpr))
3644 return false;
3645
3646 if (DiscardResult)
3647 return this->emitPopPtr(E);
3648 return true;
3649}
3650
3651template <class Emitter>
3653 const Expr *Init = E->getInitializer();
3654 if (DiscardResult)
3655 return this->discard(Init);
3656
3657 if (Initializing) {
3658 // We already have a value, just initialize that.
3659 return this->visitInitializer(Init);
3660 }
3661
3662 OptPrimType T = classify(E->getType());
3663 if (E->isFileScope()) {
3664 // Avoid creating a variable if this is a primitive RValue anyway.
3665 if (T && !E->isLValue())
3666 return this->delegate(Init);
3667
3668 UnsignedOrNone GlobalIndex = P.createGlobal(E, E->getType());
3669 if (!GlobalIndex)
3670 return false;
3671
3672 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3673 return false;
3674
3675 // Since this is a global variable, we might've already seen,
3676 // don't do it again.
3677 if (P.isGlobalInitialized(*GlobalIndex))
3678 return true;
3679
3680 if (T) {
3681 if (!this->visit(Init))
3682 return false;
3683 return this->emitInitGlobal(*T, *GlobalIndex, E);
3684 }
3685
3686 return this->visitInitializer(Init);
3687 }
3688
3689 // Otherwise, use a local variable.
3690 if (T && !E->isLValue()) {
3691 // For primitive types, we just visit the initializer.
3692 return this->delegate(Init);
3693 }
3694
3695 unsigned LocalIndex;
3696 if (T)
3697 LocalIndex = this->allocateLocalPrimitive(Init, *T, /*IsConst=*/false);
3698 else if (UnsignedOrNone MaybeIndex = this->allocateLocal(Init))
3699 LocalIndex = *MaybeIndex;
3700 else
3701 return false;
3702
3703 if (!this->emitGetPtrLocal(LocalIndex, E))
3704 return false;
3705
3706 if (T)
3707 return this->visit(Init) && this->emitInit(*T, E);
3708 return this->visitInitializer(Init);
3709}
3710
3711template <class Emitter>
3713 if (DiscardResult)
3714 return true;
3715 if (E->isStoredAsBoolean()) {
3716 if (E->getType()->isBooleanType())
3717 return this->emitConstBool(E->getBoolValue(), E);
3718 return this->emitConst(E->getBoolValue(), E);
3719 }
3720 if (E->isStoredAsComparisonResult()) {
3721 const ComparisonCategoryInfo &CmpInfo =
3722 Ctx.getASTContext().CompCategories.getInfoForType(E->getType());
3723 const auto Result =
3724 ComparisonCategoryResult(E->getAPValue().getInt().getZExtValue());
3725 const Record *R = getRecord(E->getType());
3726 if (!R || R->getNumFields() == 0)
3727 return false;
3728 const Record::Field *Field = R->getField(0U);
3729 assert(Field->T);
3730 if (!this->emitConst(CmpInfo.getValueInfo(Result)->getIntValue(), *Field->T,
3731 E))
3732 return false;
3733 return this->emitInitField(*Field->T, Field->Offset, E);
3734 }
3735
3737 return this->visitAPValue(E->getAPValue(), T, E);
3738}
3739
3740template <class Emitter>
3742 if (DiscardResult)
3743 return true;
3744 return this->emitConst(E->getValue(), E);
3745}
3746
3747template <class Emitter>
3749 if (DiscardResult)
3750 return true;
3751
3752 assert(Initializing);
3753 const Record *R = P.getOrCreateRecord(E->getLambdaClass());
3754 if (!R)
3755 return false;
3756
3757 auto *CaptureInitIt = E->capture_init_begin();
3758 // Initialize all fields (which represent lambda captures) of the
3759 // record with their initializers.
3760 for (const Record::Field &F : R->fields()) {
3761 const Expr *Init = *CaptureInitIt;
3762 if (!Init || Init->containsErrors())
3763 continue;
3764 ++CaptureInitIt;
3765
3766 if (OptPrimType T = classify(Init)) {
3767 if (!this->visit(Init))
3768 return false;
3769
3770 if (!this->emitInitField(*T, F.Offset, E))
3771 return false;
3772 } else {
3773 if (!this->emitGetPtrField(F.Offset, E))
3774 return false;
3775
3776 if (!this->visitInitializerPop(Init))
3777 return false;
3778 }
3779 }
3780
3781 return true;
3782}
3783
3784template <class Emitter>
3786 if (DiscardResult)
3787 return true;
3788
3789 if (!Initializing)
3790 return this->emitGetStringPtr(E, E);
3791 return this->delegate(E->getFunctionName());
3792}
3793
3794template <class Emitter>
3796 if (E->getSubExpr() && !this->discard(E->getSubExpr()))
3797 return false;
3798
3799 return this->emitInvalid(E);
3800}
3801
3802template <class Emitter>
3804 const CXXReinterpretCastExpr *E) {
3805 const Expr *SubExpr = E->getSubExpr();
3806
3807 OptPrimType FromT = classify(SubExpr);
3808 OptPrimType ToT = classify(E);
3809
3810 if (!FromT || !ToT)
3811 return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, E);
3812
3813 if (FromT == PT_Ptr || ToT == PT_Ptr) {
3816 if (!this->emitInvalidCast(CastKind, /*Fatal=*/false, E))
3817 return false;
3818 if (E->getCastKind() == CK_LValueBitCast)
3819 return this->delegate(SubExpr);
3820 return this->VisitCastExpr(E);
3821 }
3822
3823 // Try to actually do the cast.
3824 bool Fatal = (ToT != FromT);
3825 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal, E))
3826 return false;
3827
3828 return this->VisitCastExpr(E);
3829}
3830
3831template <class Emitter>
3833 if (!Ctx.getLangOpts().CPlusPlus20) {
3834 if (!this->emitInvalidCast(CastKind::Dynamic, /*Fatal=*/false, E))
3835 return false;
3836 }
3837
3838 if (E->getCastKind() != CK_Dynamic)
3839 return this->VisitCastExpr(E);
3840
3841 QualType DestType = E->getType();
3842 // "target type must be a reference or pointer type to a defined class"
3843 if (DestType->isRecordType()) {
3844 assert(E->isGLValue());
3845 } else {
3846 assert(DestType->isPointerOrReferenceType());
3847 assert(DestType->isVoidPointerType() ||
3848 DestType->getPointeeType()->isRecordType());
3849 DestType = DestType->getPointeeType();
3850 }
3851
3852 if (!this->visit(E->getSubExpr()))
3853 return false;
3854 if (!this->emitDynamicCast(DestType.getTypePtr(),
3855 /*IsReferenceCast=*/E->isGLValue(), E))
3856 return false;
3857
3858 if (DiscardResult)
3859 return this->emitPopPtr(E);
3860 return true;
3861}
3862
3863template <class Emitter>
3865 assert(E->getType()->isBooleanType());
3866
3867 if (DiscardResult)
3868 return true;
3869 return this->emitConstBool(E->getValue(), E);
3870}
3871
3872template <class Emitter>
3874 QualType T = E->getType();
3875 assert(!canClassify(T));
3876
3877 if (T->isRecordType()) {
3878 const CXXConstructorDecl *Ctor = E->getConstructor();
3879
3880 // If we're discarding a construct expression, we still need
3881 // to allocate a variable and call the constructor and destructor.
3882 if (DiscardResult) {
3883 if (Ctor->isTrivial())
3884 return true;
3885 assert(!Initializing);
3886 UnsignedOrNone LocalIndex = allocateLocal(E);
3887
3888 if (!LocalIndex)
3889 return false;
3890
3891 if (!this->emitGetPtrLocal(*LocalIndex, E))
3892 return false;
3893 }
3894
3895 // Trivial copy/move constructor. Avoid copy.
3896 if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&
3897 Ctor->isTrivial() &&
3898 E->getArg(0)->isTemporaryObject(Ctx.getASTContext(),
3899 T->getAsCXXRecordDecl()))
3900 return this->visitInitializer(E->getArg(0));
3901
3902 // Zero initialization.
3903 bool ZeroInit = E->requiresZeroInitialization();
3904 if (ZeroInit) {
3905 const Record *R = getRecord(E->getType());
3906 if (!R)
3907 return false;
3908
3909 if (!this->visitZeroRecordInitializer(R, E))
3910 return false;
3911
3912 // If the constructor is trivial anyway, we're done.
3913 if (Ctor->isTrivial())
3914 return true;
3915 }
3916
3917 // Trivial default constructors might never be implicitly defined by the
3918 // AST, so we need to special-case them here.
3919 if (Ctor->isTrivial() && Ctor->isDefaultConstructor()) {
3920 if (!this->emitDefaultInit(Ctor, E))
3921 return false;
3922 if (DiscardResult)
3923 return this->emitPopPtr(E);
3924 return true;
3925 }
3926
3927 // Avoid materializing a temporary for an elidable copy/move constructor.
3928 if (!ZeroInit && E->isElidable()) {
3929 const Expr *SrcObj = E->getArg(0);
3930 assert(SrcObj->isTemporaryObject(Ctx.getASTContext(), Ctor->getParent()));
3931 assert(Ctx.getASTContext().hasSameUnqualifiedType(E->getType(),
3932 SrcObj->getType()));
3933 if (const auto *ME = dyn_cast<MaterializeTemporaryExpr>(SrcObj)) {
3934 if (!this->emitCheckFunctionDecl(Ctor, E))
3935 return false;
3936 return this->visitInitializer(ME->getSubExpr());
3937 }
3938 }
3939
3940 const Function *Func = getFunction(Ctor);
3941
3942 if (!Func)
3943 return false;
3944
3945 assert(Func->hasThisPointer());
3946 assert(!Func->hasRVO());
3947
3948 // The This pointer is already on the stack because this is an initializer,
3949 // but we need to dup() so the call() below has its own copy.
3950 if (!this->emitDupPtr(E))
3951 return false;
3952
3953 // Constructor arguments.
3954 for (const auto *Arg : E->arguments()) {
3955 if (!this->visit(Arg))
3956 return false;
3957 }
3958
3959 if (Func->isVariadic()) {
3960 uint32_t VarArgSize = 0;
3961 unsigned NumParams = Func->getNumWrittenParams();
3962 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I) {
3963 VarArgSize +=
3964 align(primSize(classify(E->getArg(I)->getType()).value_or(PT_Ptr)));
3965 }
3966 if (!this->emitCallVar(Func, VarArgSize, E))
3967 return false;
3968 } else {
3969 if (!this->emitCall(Func, 0, E)) {
3970 // When discarding, we don't need the result anyway, so clean up
3971 // the instance dup we did earlier in case surrounding code wants
3972 // to keep evaluating.
3973 if (DiscardResult)
3974 (void)this->emitPopPtr(E);
3975 return false;
3976 }
3977 }
3978
3979 if (DiscardResult)
3980 return this->emitPopPtr(E);
3981 return true;
3982 }
3983
3984 if (T->isArrayType()) {
3985 const Function *Func = getFunction(E->getConstructor());
3986 if (!Func)
3987 return false;
3988
3989 if (!this->emitDupPtr(E))
3990 return false;
3991
3992 std::function<bool(QualType)> initArrayDimension;
3993 initArrayDimension = [&](QualType T) -> bool {
3994 if (!T->isArrayType()) {
3995 // Constructor arguments.
3996 for (const auto *Arg : E->arguments()) {
3997 if (!this->visit(Arg))
3998 return false;
3999 }
4000
4001 return this->emitCall(Func, 0, E);
4002 }
4003
4004 const ConstantArrayType *CAT =
4005 Ctx.getASTContext().getAsConstantArrayType(T);
4006 if (!CAT)
4007 return false;
4008 QualType ElemTy = CAT->getElementType();
4009 unsigned NumElems = CAT->getZExtSize();
4010 for (size_t I = 0; I != NumElems; ++I) {
4011 if (!this->emitConstUint64(I, E))
4012 return false;
4013 if (!this->emitArrayElemPtrUint64(E))
4014 return false;
4015 if (!initArrayDimension(ElemTy))
4016 return false;
4017 }
4018 return this->emitPopPtr(E);
4019 };
4020
4021 return initArrayDimension(E->getType());
4022 }
4023
4024 return false;
4025}
4026
4027template <class Emitter>
4029 if (DiscardResult)
4030 return true;
4031
4032 const APValue Val =
4033 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
4034
4035 // Things like __builtin_LINE().
4036 if (E->getType()->isIntegerType()) {
4037 assert(Val.isInt());
4038 const APSInt &I = Val.getInt();
4039 return this->emitConst(I, E);
4040 }
4041 // Otherwise, the APValue is an LValue, with only one element.
4042 // Theoretically, we don't need the APValue at all of course.
4043 assert(E->getType()->isPointerType());
4044 assert(Val.isLValue());
4045 const APValue::LValueBase &Base = Val.getLValueBase();
4046 if (const Expr *LValueExpr = Base.dyn_cast<const Expr *>())
4047 return this->visit(LValueExpr);
4048
4049 // Otherwise, we have a decl (which is the case for
4050 // __builtin_source_location).
4051 assert(Base.is<const ValueDecl *>());
4052 assert(Val.getLValuePath().size() == 0);
4053 const auto *BaseDecl = Base.dyn_cast<const ValueDecl *>();
4054 assert(BaseDecl);
4055
4056 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
4057
4058 UnsignedOrNone GlobalIndex = P.getOrCreateGlobal(UGCD);
4059 if (!GlobalIndex)
4060 return false;
4061
4062 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4063 return false;
4064
4065 const Record *R = getRecord(E->getType());
4066 const APValue &V = UGCD->getValue();
4067 for (unsigned I = 0, N = R->getNumFields(); I != N; ++I) {
4068 const Record::Field *F = R->getField(I);
4069 const APValue &FieldValue = V.getStructField(I);
4070
4071 if (!this->visitAPValue(FieldValue, *F->T, E))
4072 return false;
4073 if (!this->emitInitField(*F->T, F->Offset, E))
4074 return false;
4075 }
4076
4077 // Leave the pointer to the global on the stack.
4078 return true;
4079}
4080
4081template <class Emitter>
4083 unsigned N = E->getNumComponents();
4084 if (N == 0)
4085 return false;
4086
4087 for (unsigned I = 0; I != N; ++I) {
4088 const OffsetOfNode &Node = E->getComponent(I);
4089 if (Node.getKind() == OffsetOfNode::Array) {
4090 const Expr *ArrayIndexExpr = E->getIndexExpr(Node.getArrayExprIndex());
4091 PrimType IndexT = classifyPrim(ArrayIndexExpr->getType());
4092
4093 if (DiscardResult) {
4094 if (!this->discard(ArrayIndexExpr))
4095 return false;
4096 continue;
4097 }
4098
4099 if (IndexT == PT_IntAP || IndexT == PT_IntAPS) {
4100 if (!this->visit(ArrayIndexExpr))
4101 return false;
4102 if (!this->emitCastAPToOffsetIndex(IndexT, E))
4103 return false;
4104 continue;
4105 }
4106 if (!this->visit(ArrayIndexExpr))
4107 return false;
4108 // Cast to Sint64.
4109 if (IndexT != PT_Sint64) {
4110 if (!this->emitCast(IndexT, PT_Sint64, E))
4111 return false;
4112 }
4113 }
4114 }
4115
4116 if (DiscardResult)
4117 return true;
4118
4120 return this->emitOffsetOf(T, E, E);
4121}
4122
4123template <class Emitter>
4125 const CXXScalarValueInitExpr *E) {
4126 QualType Ty = E->getType();
4127
4128 if (DiscardResult || Ty->isVoidType())
4129 return true;
4130
4131 if (OptPrimType T = classify(Ty))
4132 return this->visitZeroInitializer(*T, Ty, E);
4133
4134 if (Ty->isAnyComplexType() || Ty->isVectorType()) {
4135 if (!Initializing) {
4136 UnsignedOrNone LocalIndex = allocateLocal(E);
4137 if (!LocalIndex)
4138 return false;
4139 if (!this->emitGetPtrLocal(*LocalIndex, E))
4140 return false;
4141 }
4142
4143 QualType ElemQT;
4144 unsigned NumElems;
4145 if (const auto *CT = Ty->getAs<ComplexType>()) {
4146 NumElems = 2;
4147 ElemQT = CT->getElementType();
4148 } else {
4149 const auto *VT = Ty->castAs<VectorType>();
4150 NumElems = VT->getNumElements();
4151 ElemQT = VT->getElementType();
4152 }
4153
4154 PrimType ElemT = classifyPrim(ElemQT);
4155
4156 // Initialize all fields to 0.
4157 for (unsigned I = 0; I != NumElems; ++I) {
4158 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
4159 return false;
4160 if (!this->emitInitElem(ElemT, I, E))
4161 return false;
4162 }
4163 return true;
4164 }
4165
4166 return false;
4167}
4168
4169template <class Emitter>
4171 return this->emitConst(E->getPackLength(), E);
4172}
4173
4174template <class Emitter>
4179
4180template <class Emitter>
4182 return this->delegate(E->getChosenSubExpr());
4183}
4184
4185template <class Emitter>
4187 if (DiscardResult)
4188 return true;
4189
4190 return this->emitConst(E->getValue(), E);
4191}
4192
4193template <class Emitter>
4195 const CXXInheritedCtorInitExpr *E) {
4196 const CXXConstructorDecl *Ctor = E->getConstructor();
4197 assert(!Ctor->isTrivial() &&
4198 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
4199 const Function *F = this->getFunction(Ctor);
4200 if (!F)
4201 return false;
4202 assert(!F->hasRVO());
4203 assert(F->hasThisPointer());
4204
4205 if (!this->emitDupPtr(SourceInfo{}))
4206 return false;
4207
4208 // Forward all arguments of the current function (which should be a
4209 // constructor itself) to the inherited ctor.
4210 // This is necessary because the calling code has pushed the pointer
4211 // of the correct base for us already, but the arguments need
4212 // to come after.
4213 unsigned ParamIndex = 0;
4214 for (const ParmVarDecl *PD : Ctor->parameters()) {
4215 PrimType PT = this->classify(PD->getType()).value_or(PT_Ptr);
4216
4217 if (!this->emitGetParam(PT, ParamIndex, E))
4218 return false;
4219 ++ParamIndex;
4220 }
4221
4222 return this->emitCall(F, 0, E);
4223}
4224
4225// FIXME: This function has become rather unwieldy, especially
4226// the part where we initialize an array allocation of dynamic size.
4227template <class Emitter>
4229 assert(classifyPrim(E->getType()) == PT_Ptr);
4230 const Expr *Init = E->getInitializer();
4231 QualType ElementType = E->getAllocatedType();
4232 OptPrimType ElemT = classify(ElementType);
4233 unsigned PlacementArgs = E->getNumPlacementArgs();
4234 const FunctionDecl *OperatorNew = E->getOperatorNew();
4235 const Expr *PlacementDest = nullptr;
4236 bool IsNoThrow = false;
4237
4238 if (E->containsErrors())
4239 return false;
4240
4241 if (PlacementArgs != 0) {
4242 // FIXME: There is no restriction on this, but it's not clear that any
4243 // other form makes any sense. We get here for cases such as:
4244 //
4245 // new (std::align_val_t{N}) X(int)
4246 //
4247 // (which should presumably be valid only if N is a multiple of
4248 // alignof(int), and in any case can't be deallocated unless N is
4249 // alignof(X) and X has new-extended alignment).
4250 if (PlacementArgs == 1) {
4251 const Expr *Arg1 = E->getPlacementArg(0);
4252 if (Arg1->getType()->isNothrowT()) {
4253 if (!this->discard(Arg1))
4254 return false;
4255 IsNoThrow = true;
4256 } else {
4257 // Invalid unless we have C++26 or are in a std:: function.
4258 if (!this->emitInvalidNewDeleteExpr(E, E))
4259 return false;
4260
4261 // If we have a placement-new destination, we'll later use that instead
4262 // of allocating.
4263 if (OperatorNew->isReservedGlobalPlacementOperator())
4264 PlacementDest = Arg1;
4265 }
4266 } else {
4267 // Always invalid.
4268 return this->emitInvalid(E);
4269 }
4270 } else if (!OperatorNew
4271 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4272 return this->emitInvalidNewDeleteExpr(E, E);
4273
4274 const Descriptor *Desc;
4275 if (!PlacementDest) {
4276 if (ElemT) {
4277 if (E->isArray())
4278 Desc = nullptr; // We're not going to use it in this case.
4279 else
4280 Desc = P.createDescriptor(E, *ElemT);
4281 } else {
4282 Desc = P.createDescriptor(E, ElementType.getTypePtr(), /*IsConst=*/false,
4283 /*IsTemporary=*/false, /*IsMutable=*/false,
4284 /*IsVolatile=*/false, Init);
4285 }
4286 }
4287
4288 if (E->isArray()) {
4289 std::optional<const Expr *> ArraySizeExpr = E->getArraySize();
4290 if (!ArraySizeExpr)
4291 return false;
4292
4293 const Expr *Stripped = *ArraySizeExpr;
4294 for (; auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
4295 Stripped = ICE->getSubExpr())
4296 if (ICE->getCastKind() != CK_NoOp &&
4297 ICE->getCastKind() != CK_IntegralCast)
4298 break;
4299
4300 PrimType SizeT = classifyPrim(Stripped->getType());
4301
4302 // Save evaluated array size to a variable.
4303 unsigned ArrayLen =
4304 allocateLocalPrimitive(Stripped, SizeT, /*IsConst=*/false);
4305 if (!this->visit(Stripped))
4306 return false;
4307 if (!this->emitSetLocal(SizeT, ArrayLen, E))
4308 return false;
4309
4310 if (PlacementDest) {
4311 if (!this->visit(PlacementDest))
4312 return false;
4313 if (!this->emitGetLocal(SizeT, ArrayLen, E))
4314 return false;
4315 if (!this->emitCheckNewTypeMismatchArray(SizeT, E, E))
4316 return false;
4317 } else {
4318 if (!this->emitGetLocal(SizeT, ArrayLen, E))
4319 return false;
4320
4321 if (ElemT) {
4322 // N primitive elements.
4323 if (!this->emitAllocN(SizeT, *ElemT, E, IsNoThrow, E))
4324 return false;
4325 } else {
4326 // N Composite elements.
4327 if (!this->emitAllocCN(SizeT, Desc, IsNoThrow, E))
4328 return false;
4329 }
4330 }
4331
4332 if (Init) {
4333 QualType InitType = Init->getType();
4334 size_t StaticInitElems = 0;
4335 const Expr *DynamicInit = nullptr;
4336 OptPrimType ElemT;
4337
4338 if (const ConstantArrayType *CAT =
4339 Ctx.getASTContext().getAsConstantArrayType(InitType)) {
4340 StaticInitElems = CAT->getZExtSize();
4341 // Initialize the first S element from the initializer.
4342 if (!this->visitInitializer(Init))
4343 return false;
4344
4345 if (const auto *ILE = dyn_cast<InitListExpr>(Init)) {
4346 if (ILE->hasArrayFiller())
4347 DynamicInit = ILE->getArrayFiller();
4348 else if (StaticInitElems > 0 && isa<StringLiteral>(ILE->getInit(0)))
4349 ElemT = classifyPrim(CAT->getElementType());
4350 }
4351 }
4352
4353 // The initializer initializes a certain number of elements, S.
4354 // However, the complete number of elements, N, might be larger than that.
4355 // In this case, we need to get an initializer for the remaining elements.
4356 // There are three cases:
4357 // 1) For the form 'new Struct[n];', the initializer is a
4358 // CXXConstructExpr and its type is an IncompleteArrayType.
4359 // 2) For the form 'new Struct[n]{1,2,3}', the initializer is an
4360 // InitListExpr and the initializer for the remaining elements
4361 // is the array filler.
4362 // 3) StringLiterals don't have an array filler, so we need to zero
4363 // the remaining elements.
4364
4365 if (DynamicInit || ElemT || InitType->isIncompleteArrayType()) {
4366 const Function *CtorFunc = nullptr;
4367 if (const auto *CE = dyn_cast<CXXConstructExpr>(Init)) {
4368 CtorFunc = getFunction(CE->getConstructor());
4369 if (!CtorFunc)
4370 return false;
4371 } else if (!DynamicInit && !ElemT)
4372 DynamicInit = Init;
4373
4374 LabelTy EndLabel = this->getLabel();
4375 LabelTy StartLabel = this->getLabel();
4376
4377 // In the nothrow case, the alloc above might have returned nullptr.
4378 // Don't call any constructors that case.
4379 if (IsNoThrow) {
4380 if (!this->emitDupPtr(E))
4381 return false;
4382 if (!this->emitIsNonNullPtr(E))
4383 return false;
4384 if (!this->jumpFalse(EndLabel, E))
4385 return false;
4386 }
4387
4388 // Create loop variables.
4389 unsigned Iter =
4390 allocateLocalPrimitive(Stripped, SizeT, /*IsConst=*/false);
4391 if (!this->emitConst(StaticInitElems, SizeT, E))
4392 return false;
4393 if (!this->emitSetLocal(SizeT, Iter, E))
4394 return false;
4395
4396 this->fallthrough(StartLabel);
4397 this->emitLabel(StartLabel);
4398 // Condition. Iter < ArrayLen?
4399 if (!this->emitGetLocal(SizeT, Iter, E))
4400 return false;
4401 if (!this->emitGetLocal(SizeT, ArrayLen, E))
4402 return false;
4403 if (!this->emitLT(SizeT, E))
4404 return false;
4405 if (!this->jumpFalse(EndLabel, E))
4406 return false;
4407
4408 // Pointer to the allocated array is already on the stack.
4409 if (!this->emitGetLocal(SizeT, Iter, E))
4410 return false;
4411 if (!this->emitArrayElemPtr(SizeT, E))
4412 return false;
4413
4414 if (isa_and_nonnull<ImplicitValueInitExpr>(DynamicInit) &&
4415 DynamicInit->getType()->isArrayType()) {
4416 QualType ElemType =
4417 DynamicInit->getType()->getAsArrayTypeUnsafe()->getElementType();
4418 if (OptPrimType InitT = classify(ElemType)) {
4419 if (!this->visitZeroInitializer(*InitT, ElemType, E))
4420 return false;
4421 if (!this->emitStorePop(*InitT, E))
4422 return false;
4423 } else {
4424 assert(ElemType->isArrayType());
4425 if (!this->visitZeroArrayInitializer(ElemType, E))
4426 return false;
4427 }
4428 } else if (DynamicInit) {
4429 if (OptPrimType InitT = classify(DynamicInit)) {
4430 if (!this->visit(DynamicInit))
4431 return false;
4432 if (!this->emitStorePop(*InitT, E))
4433 return false;
4434 } else {
4435 if (!this->visitInitializerPop(DynamicInit))
4436 return false;
4437 }
4438 } else if (ElemT) {
4439 if (!this->visitZeroInitializer(
4440 *ElemT, InitType->getAsArrayTypeUnsafe()->getElementType(),
4441 Init))
4442 return false;
4443 if (!this->emitStorePop(*ElemT, E))
4444 return false;
4445 } else {
4446 assert(CtorFunc);
4447 if (!this->emitCall(CtorFunc, 0, E))
4448 return false;
4449 }
4450
4451 // ++Iter;
4452 if (!this->emitGetPtrLocal(Iter, E))
4453 return false;
4454 if (!this->emitIncPop(SizeT, false, E))
4455 return false;
4456
4457 if (!this->jump(StartLabel, E))
4458 return false;
4459
4460 this->fallthrough(EndLabel);
4461 this->emitLabel(EndLabel);
4462 }
4463 }
4464 } else { // Non-array.
4465 if (PlacementDest) {
4466 if (!this->visit(PlacementDest))
4467 return false;
4468 if (!this->emitCheckNewTypeMismatch(E, E))
4469 return false;
4470
4471 } else {
4472 // Allocate just one element.
4473 if (!this->emitAlloc(Desc, E))
4474 return false;
4475 }
4476
4477 if (Init) {
4478 if (ElemT) {
4479 if (!this->visit(Init))
4480 return false;
4481
4482 if (!this->emitInit(*ElemT, E))
4483 return false;
4484 } else {
4485 // Composite.
4486 if (!this->visitInitializer(Init))
4487 return false;
4488 }
4489 }
4490 }
4491
4492 if (DiscardResult)
4493 return this->emitPopPtr(E);
4494
4495 return true;
4496}
4497
4498template <class Emitter>
4500 if (E->containsErrors())
4501 return false;
4502 const FunctionDecl *OperatorDelete = E->getOperatorDelete();
4503
4504 if (!OperatorDelete->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4505 return this->emitInvalidNewDeleteExpr(E, E);
4506
4507 // Arg must be an lvalue.
4508 if (!this->visit(E->getArgument()))
4509 return false;
4510
4511 return this->emitFree(E->isArrayForm(), E->isGlobalDelete(), E);
4512}
4513
4514template <class Emitter>
4516 if (DiscardResult)
4517 return true;
4518
4519 const Function *Func = nullptr;
4520 if (const Function *F = Ctx.getOrCreateObjCBlock(E))
4521 Func = F;
4522
4523 if (!Func)
4524 return false;
4525 return this->emitGetFnPtr(Func, E);
4526}
4527
4528template <class Emitter>
4530 const Type *TypeInfoType = E->getType().getTypePtr();
4531
4532 auto canonType = [](const Type *T) {
4533 return T->getCanonicalTypeUnqualified().getTypePtr();
4534 };
4535
4536 if (!E->isPotentiallyEvaluated()) {
4537 if (DiscardResult)
4538 return true;
4539
4540 if (E->isTypeOperand())
4541 return this->emitGetTypeid(
4542 canonType(E->getTypeOperand(Ctx.getASTContext()).getTypePtr()),
4543 TypeInfoType, E);
4544
4545 return this->emitGetTypeid(
4546 canonType(E->getExprOperand()->getType().getTypePtr()), TypeInfoType,
4547 E);
4548 }
4549
4550 // Otherwise, we need to evaluate the expression operand.
4551 assert(E->getExprOperand());
4552 assert(E->getExprOperand()->isLValue());
4553
4554 if (!Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(E))
4555 return false;
4556
4557 if (!this->visit(E->getExprOperand()))
4558 return false;
4559
4560 if (!this->emitGetTypeidPtr(TypeInfoType, E))
4561 return false;
4562 if (DiscardResult)
4563 return this->emitPopPtr(E);
4564 return true;
4565}
4566
4567template <class Emitter>
4569 const ObjCDictionaryLiteral *E) {
4571 return this->emitDummyPtr(E, E);
4572 return this->emitError(E);
4573}
4574
4575template <class Emitter>
4578 return this->emitDummyPtr(E, E);
4579 return this->emitError(E);
4580}
4581
4582template <class Emitter>
4584 assert(Ctx.getLangOpts().CPlusPlus);
4585 return this->emitConstBool(E->getValue(), E);
4586}
4587
4588template <class Emitter>
4590 if (DiscardResult)
4591 return true;
4592 assert(!Initializing);
4593
4594 const MSGuidDecl *GuidDecl = E->getGuidDecl();
4595 const RecordDecl *RD = GuidDecl->getType()->getAsRecordDecl();
4596 assert(RD);
4597 // If the definiton of the result type is incomplete, just return a dummy.
4598 // If (and when) that is read from, we will fail, but not now.
4599 if (!RD->isCompleteDefinition())
4600 return this->emitDummyPtr(GuidDecl, E);
4601
4602 UnsignedOrNone GlobalIndex = P.getOrCreateGlobal(GuidDecl);
4603 if (!GlobalIndex)
4604 return false;
4605 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4606 return false;
4607
4608 assert(this->getRecord(E->getType()));
4609
4610 const APValue &V = GuidDecl->getAsAPValue();
4611 if (V.getKind() == APValue::None)
4612 return true;
4613
4614 assert(V.isStruct());
4615 assert(V.getStructNumBases() == 0);
4616 if (!this->visitAPValueInitializer(V, E, E->getType()))
4617 return false;
4618
4619 return this->emitFinishInit(E);
4620}
4621
4622template <class Emitter>
4624 assert(classifyPrim(E->getType()) == PT_Bool);
4625 if (E->isValueDependent())
4626 return false;
4627 if (DiscardResult)
4628 return true;
4629 return this->emitConstBool(E->isSatisfied(), E);
4630}
4631
4632template <class Emitter>
4634 const ConceptSpecializationExpr *E) {
4635 assert(classifyPrim(E->getType()) == PT_Bool);
4636 if (DiscardResult)
4637 return true;
4638 return this->emitConstBool(E->isSatisfied(), E);
4639}
4640
4641template <class Emitter>
4646
4647template <class Emitter>
4649
4650 for (const Expr *SemE : E->semantics()) {
4651 if (auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
4652 if (SemE == E->getResultExpr())
4653 return false;
4654
4655 if (OVE->isUnique())
4656 continue;
4657
4658 if (!this->discard(OVE))
4659 return false;
4660 } else if (SemE == E->getResultExpr()) {
4661 if (!this->delegate(SemE))
4662 return false;
4663 } else {
4664 if (!this->discard(SemE))
4665 return false;
4666 }
4667 }
4668 return true;
4669}
4670
4671template <class Emitter>
4675
4676template <class Emitter>
4678 return this->emitError(E);
4679}
4680
4681template <class Emitter>
4683 assert(E->getType()->isVoidPointerType());
4684 if (DiscardResult)
4685 return true;
4686
4687 return this->emitDummyPtr(E, E);
4688}
4689
4690template <class Emitter>
4691bool Compiler<Emitter>::emitVectorConversion(const Expr *Src, const Expr *E) {
4692 if (Src->containsErrors())
4693 return false;
4694
4695 const auto *VT = E->getType()->castAs<VectorType>();
4696 QualType ElemType = VT->getElementType();
4697 PrimType ElemT = classifyPrim(ElemType);
4698 QualType SrcType = Src->getType();
4699 PrimType SrcElemT = classifyVectorElementType(SrcType);
4700
4701 if (!Initializing) {
4702 UnsignedOrNone LocalIndex = allocateLocal(E);
4703 if (!LocalIndex)
4704 return false;
4705 if (!this->emitGetPtrLocal(*LocalIndex, E))
4706 return false;
4707 }
4708
4709 unsigned SrcOffset =
4710 this->allocateLocalPrimitive(Src, PT_Ptr, /*IsConst=*/true);
4711 if (!this->visit(Src))
4712 return false;
4713 if (!this->emitSetLocal(PT_Ptr, SrcOffset, E))
4714 return false;
4715
4716 for (unsigned I = 0; I != VT->getNumElements(); ++I) {
4717 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
4718 return false;
4719 if (!this->emitArrayElemPop(SrcElemT, I, E))
4720 return false;
4721
4722 // Cast to the desired result element type.
4723 if (SrcElemT != ElemT) {
4724 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
4725 return false;
4726 } else if (ElemType->isFloatingType() && SrcType != ElemType) {
4727 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
4728 if (!this->emitCastFP(TargetSemantics, getRoundingMode(E), E))
4729 return false;
4730 }
4731 if (!this->emitInitElem(ElemT, I, E))
4732 return false;
4733 }
4734 return true;
4735}
4736
4737template <class Emitter>
4739 return emitVectorConversion(E->getSrcExpr(), E);
4740}
4741
4742template <class Emitter>
4744 // FIXME: Unary shuffle with mask not currently supported.
4745 if (E->getNumSubExprs() == 2)
4746 return this->emitInvalid(E);
4747
4748 assert(E->getNumSubExprs() > 2);
4749
4750 const Expr *Vecs[] = {E->getExpr(0), E->getExpr(1)};
4751 const VectorType *VT = Vecs[0]->getType()->castAs<VectorType>();
4752 PrimType ElemT = classifyPrim(VT->getElementType());
4753 unsigned NumInputElems = VT->getNumElements();
4754 unsigned NumOutputElems = E->getNumSubExprs() - 2;
4755 assert(NumOutputElems > 0);
4756
4757 if (!Initializing) {
4758 UnsignedOrNone LocalIndex = allocateLocal(E);
4759 if (!LocalIndex)
4760 return false;
4761 if (!this->emitGetPtrLocal(*LocalIndex, E))
4762 return false;
4763 }
4764
4765 // Save both input vectors to a local variable.
4766 unsigned VectorOffsets[2];
4767 for (unsigned I = 0; I != 2; ++I) {
4768 VectorOffsets[I] =
4769 this->allocateLocalPrimitive(Vecs[I], PT_Ptr, /*IsConst=*/true);
4770 if (!this->visit(Vecs[I]))
4771 return false;
4772 if (!this->emitSetLocal(PT_Ptr, VectorOffsets[I], E))
4773 return false;
4774 }
4775 for (unsigned I = 0; I != NumOutputElems; ++I) {
4776 APSInt ShuffleIndex = E->getShuffleMaskIdx(I);
4777 assert(ShuffleIndex >= -1);
4778 if (ShuffleIndex == -1)
4779 return this->emitInvalidShuffleVectorIndex(I, E);
4780
4781 assert(ShuffleIndex < (NumInputElems * 2));
4782 if (!this->emitGetLocal(PT_Ptr,
4783 VectorOffsets[ShuffleIndex >= NumInputElems], E))
4784 return false;
4785 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
4786 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
4787 return false;
4788
4789 if (!this->emitInitElem(ElemT, I, E))
4790 return false;
4791 }
4792
4793 if (DiscardResult)
4794 return this->emitPopPtr(E);
4795
4796 return true;
4797}
4798
4799template <class Emitter>
4801 const ExtVectorElementExpr *E) {
4802 const Expr *Base = E->getBase();
4803 assert(
4804 Base->getType()->isVectorType() ||
4805 Base->getType()->getAs<PointerType>()->getPointeeType()->isVectorType());
4806
4808 E->getEncodedElementAccess(Indices);
4809
4810 if (Indices.size() == 1) {
4811 if (!this->visit(Base))
4812 return false;
4813
4814 if (E->isGLValue()) {
4815 if (!this->emitConstUint32(Indices[0], E))
4816 return false;
4817 return this->emitArrayElemPtrPop(PT_Uint32, E);
4818 }
4819 // Else, also load the value.
4820 return this->emitArrayElemPop(classifyPrim(E->getType()), Indices[0], E);
4821 }
4822
4823 // Create a local variable for the base.
4824 unsigned BaseOffset = allocateLocalPrimitive(Base, PT_Ptr, /*IsConst=*/true);
4825 if (!this->visit(Base))
4826 return false;
4827 if (!this->emitSetLocal(PT_Ptr, BaseOffset, E))
4828 return false;
4829
4830 // Now the vector variable for the return value.
4831 if (!Initializing) {
4832 UnsignedOrNone ResultIndex = allocateLocal(E);
4833 if (!ResultIndex)
4834 return false;
4835 if (!this->emitGetPtrLocal(*ResultIndex, E))
4836 return false;
4837 }
4838
4839 assert(Indices.size() == E->getType()->getAs<VectorType>()->getNumElements());
4840
4841 PrimType ElemT =
4843 uint32_t DstIndex = 0;
4844 for (uint32_t I : Indices) {
4845 if (!this->emitGetLocal(PT_Ptr, BaseOffset, E))
4846 return false;
4847 if (!this->emitArrayElemPop(ElemT, I, E))
4848 return false;
4849 if (!this->emitInitElem(ElemT, DstIndex, E))
4850 return false;
4851 ++DstIndex;
4852 }
4853
4854 // Leave the result pointer on the stack.
4855 assert(!DiscardResult);
4856 return true;
4857}
4858
4859template <class Emitter>
4861 const Expr *SubExpr = E->getSubExpr();
4863 return this->discard(SubExpr) && this->emitInvalid(E);
4864
4865 if (DiscardResult)
4866 return true;
4867
4868 assert(classifyPrim(E) == PT_Ptr);
4869 return this->emitDummyPtr(E, E);
4870}
4871
4872template <class Emitter>
4874 const CXXStdInitializerListExpr *E) {
4875 const Expr *SubExpr = E->getSubExpr();
4877 Ctx.getASTContext().getAsConstantArrayType(SubExpr->getType());
4878 const Record *R = getRecord(E->getType());
4879 assert(Initializing);
4880 assert(SubExpr->isGLValue());
4881
4882 if (!this->visit(SubExpr))
4883 return false;
4884 if (!this->emitConstUint8(0, E))
4885 return false;
4886 if (!this->emitArrayElemPtrPopUint8(E))
4887 return false;
4888 if (!this->emitInitFieldPtr(R->getField(0u)->Offset, E))
4889 return false;
4890
4891 PrimType SecondFieldT = *R->getField(1u)->T;
4892 if (isIntegerOrBoolType(SecondFieldT)) {
4893 if (!this->emitConst(ArrayType->getSize(), SecondFieldT, E))
4894 return false;
4895 return this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E);
4896 }
4897 assert(SecondFieldT == PT_Ptr);
4898
4899 if (!this->emitGetFieldPtr(R->getField(0u)->Offset, E))
4900 return false;
4901 if (!this->emitExpandPtr(E))
4902 return false;
4903 if (!this->emitConst(ArrayType->getSize(), PT_Uint64, E))
4904 return false;
4905 if (!this->emitArrayElemPtrPop(PT_Uint64, E))
4906 return false;
4907 return this->emitInitFieldPtr(R->getField(1u)->Offset, E);
4908}
4909
4910template <class Emitter>
4912 LocalScope<Emitter> BS(this);
4913 llvm::SaveAndRestore StmtExprSAR(this->InStmtExpr, true);
4914
4915 const CompoundStmt *CS = E->getSubStmt();
4916 const Stmt *Result = CS->body_back();
4917 for (const Stmt *S : CS->body()) {
4918 if (S != Result) {
4919 if (!this->visitStmt(S))
4920 return false;
4921 continue;
4922 }
4923
4924 assert(S == Result);
4925 if (const Expr *ResultExpr = dyn_cast<Expr>(S))
4926 return this->delegate(ResultExpr);
4927 if (!this->visitStmt(S))
4928 return false;
4929 return this->emitUnsupported(E);
4930 }
4931
4932 return BS.destroyLocals();
4933}
4934
4935template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {
4936 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
4937 /*NewInitializing=*/false, /*ToLValue=*/false);
4938 return this->Visit(E);
4939}
4940
4941template <class Emitter> bool Compiler<Emitter>::delegate(const Expr *E) {
4942 // We're basically doing:
4943 // OptionScope<Emitter> Scope(this, DicardResult, Initializing, ToLValue);
4944 // but that's unnecessary of course.
4945 return this->Visit(E);
4946}
4947
4949 if (const auto *PE = dyn_cast<ParenExpr>(E))
4950 return stripCheckedDerivedToBaseCasts(PE->getSubExpr());
4951
4952 if (const auto *CE = dyn_cast<CastExpr>(E);
4953 CE &&
4954 (CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp))
4955 return stripCheckedDerivedToBaseCasts(CE->getSubExpr());
4956
4957 return E;
4958}
4959
4960static const Expr *stripDerivedToBaseCasts(const Expr *E) {
4961 if (const auto *PE = dyn_cast<ParenExpr>(E))
4962 return stripDerivedToBaseCasts(PE->getSubExpr());
4963
4964 if (const auto *CE = dyn_cast<CastExpr>(E);
4965 CE && (CE->getCastKind() == CK_DerivedToBase ||
4966 CE->getCastKind() == CK_UncheckedDerivedToBase ||
4967 CE->getCastKind() == CK_NoOp))
4968 return stripDerivedToBaseCasts(CE->getSubExpr());
4969
4970 return E;
4971}
4972
4973template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) {
4974 if (E->getType().isNull())
4975 return false;
4976
4977 if (E->getType()->isVoidType())
4978 return this->discard(E);
4979
4980 // Create local variable to hold the return value.
4981 if (!E->isGLValue() && !canClassify(E->getType())) {
4982 UnsignedOrNone LocalIndex = allocateLocal(
4984 if (!LocalIndex)
4985 return false;
4986
4987 if (!this->emitGetPtrLocal(*LocalIndex, E))
4988 return false;
4989 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
4990 return this->visitInitializer(E);
4991 }
4992
4993 // Otherwise,we have a primitive return value, produce the value directly
4994 // and push it on the stack.
4995 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
4996 /*NewInitializing=*/false, /*ToLValue=*/ToLValue);
4997 return this->Visit(E);
4998}
4999
5000template <class Emitter>
5002 assert(!canClassify(E->getType()));
5003
5004 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
5005 /*NewInitializing=*/true, /*ToLValue=*/false);
5006 return this->Visit(E) && this->emitFinishInit(E);
5007}
5008
5009template <class Emitter>
5011 assert(!canClassify(E->getType()));
5012
5013 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
5014 /*NewInitializing=*/true, /*ToLValue=*/false);
5015 return this->Visit(E) && this->emitFinishInitPop(E);
5016}
5017
5018template <class Emitter> bool Compiler<Emitter>::visitAsLValue(const Expr *E) {
5019 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
5020 /*NewInitializing=*/false, /*ToLValue=*/true);
5021 return this->Visit(E);
5022}
5023
5024template <class Emitter> bool Compiler<Emitter>::visitBool(const Expr *E) {
5025 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
5026 /*NewInitializing=*/false, /*ToLValue=*/ToLValue);
5027
5028 OptPrimType T = classify(E->getType());
5029 if (!T) {
5030 // Convert complex values to bool.
5031 if (E->getType()->isAnyComplexType()) {
5032 if (!this->visit(E))
5033 return false;
5034 return this->emitComplexBoolCast(E);
5035 }
5036 return false;
5037 }
5038
5039 if (!this->visit(E))
5040 return false;
5041
5042 if (T == PT_Bool)
5043 return true;
5044
5045 // Convert pointers to bool.
5046 if (T == PT_Ptr)
5047 return this->emitIsNonNullPtr(E);
5048
5049 // Or Floats.
5050 if (T == PT_Float)
5051 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
5052
5053 // Or anything else we can.
5054 return this->emitCast(*T, PT_Bool, E);
5055}
5056
5057template <class Emitter>
5058bool Compiler<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
5059 const Expr *E) {
5060 if (const auto *AT = QT->getAs<AtomicType>())
5061 QT = AT->getValueType();
5062
5063 switch (T) {
5064 case PT_Bool:
5065 return this->emitZeroBool(E);
5066 case PT_Sint8:
5067 return this->emitZeroSint8(E);
5068 case PT_Uint8:
5069 return this->emitZeroUint8(E);
5070 case PT_Sint16:
5071 return this->emitZeroSint16(E);
5072 case PT_Uint16:
5073 return this->emitZeroUint16(E);
5074 case PT_Sint32:
5075 return this->emitZeroSint32(E);
5076 case PT_Uint32:
5077 return this->emitZeroUint32(E);
5078 case PT_Sint64:
5079 return this->emitZeroSint64(E);
5080 case PT_Uint64:
5081 return this->emitZeroUint64(E);
5082 case PT_IntAP:
5083 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
5084 case PT_IntAPS:
5085 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
5086 case PT_Ptr:
5087 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
5088 nullptr, E);
5089 case PT_MemberPtr:
5090 return this->emitNullMemberPtr(0, nullptr, E);
5091 case PT_Float: {
5092 APFloat F = APFloat::getZero(Ctx.getFloatSemantics(QT));
5093 return this->emitFloat(F, E);
5094 }
5095 case PT_FixedPoint: {
5096 auto Sem = Ctx.getASTContext().getFixedPointSemantics(QT);
5097 return this->emitConstFixedPoint(FixedPoint::zero(Sem), E);
5098 }
5099 }
5100 llvm_unreachable("unknown primitive type");
5101}
5102
5103template <class Emitter>
5104bool Compiler<Emitter>::visitZeroRecordInitializer(const Record *R,
5105 const Expr *E,
5106 bool IsCompleteClass) {
5107 assert(E);
5108 assert(R);
5109 // Fields
5110 for (const Record::Field &Field : R->fields()) {
5111 if (Field.isUnnamedBitField())
5112 continue;
5113
5114 const Descriptor *D = Field.Desc;
5115 if (D->isPrimitive()) {
5116 QualType QT = D->getType();
5117 PrimType T = D->getPrimType();
5118 if (!this->visitZeroInitializer(T, QT, E))
5119 return false;
5120 if (R->isUnion()) {
5121 if (!this->emitInitFieldActivate(T, Field.Offset, E))
5122 return false;
5123 break;
5124 }
5125 if (!this->emitInitField(T, Field.Offset, E))
5126 return false;
5127 continue;
5128 }
5129
5130 if (!this->emitGetPtrField(Field.Offset, E))
5131 return false;
5132
5133 if (D->isPrimitiveArray()) {
5134 QualType ET = D->getElemQualType();
5135 PrimType T = D->getPrimType();
5136 for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
5137 if (!this->visitZeroInitializer(T, ET, E))
5138 return false;
5139 if (!this->emitInitElem(T, I, E))
5140 return false;
5141 }
5142 } else if (D->isCompositeArray()) {
5143 // Can't be a vector or complex field.
5144 if (!this->visitZeroArrayInitializer(D->getType(), E))
5145 return false;
5146 } else if (D->isRecord()) {
5147 if (!this->visitZeroRecordInitializer(D->ElemRecord, E))
5148 return false;
5149 } else
5150 return false;
5151
5152 // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the
5153 // object's first non-static named data member is zero-initialized
5154 if (R->isUnion()) {
5155 if (!this->emitFinishInitActivatePop(E))
5156 return false;
5157 break;
5158 }
5159 if (!this->emitFinishInitPop(E))
5160 return false;
5161 }
5162
5163 for (const Record::Base &B : R->bases()) {
5164 if (!this->emitGetPtrBase(B.Offset, E))
5165 return false;
5166 if (!this->visitZeroRecordInitializer(B.R, E, /*IsCompleteClass=*/false))
5167 return false;
5168 if (!this->emitFinishInitPop(E))
5169 return false;
5170 }
5171
5172 if (IsCompleteClass) {
5173 for (const Record::Base &B : R->virtual_bases()) {
5174 if (!this->emitGetPtrVirtBase(cast<CXXRecordDecl>(B.R->getDecl()), E))
5175 return false;
5176 if (!this->visitZeroRecordInitializer(B.R, E, /*IsCompleteClass=*/false))
5177 return false;
5178 if (!this->emitFinishInitPop(E))
5179 return false;
5180 }
5181 }
5182
5183 return true;
5184}
5185
5186template <class Emitter>
5187bool Compiler<Emitter>::visitZeroArrayInitializer(QualType T, const Expr *E) {
5188 assert(T->isArrayType() || T->isAnyComplexType() || T->isVectorType());
5189 const ArrayType *AT = T->getAsArrayTypeUnsafe();
5190 QualType ElemType = AT->getElementType();
5191 size_t NumElems = cast<ConstantArrayType>(AT)->getZExtSize();
5192
5193 if (OptPrimType ElemT = classify(ElemType)) {
5194 for (size_t I = 0; I != NumElems; ++I) {
5195 if (!this->visitZeroInitializer(*ElemT, ElemType, E))
5196 return false;
5197 if (!this->emitInitElem(*ElemT, I, E))
5198 return false;
5199 }
5200 return true;
5201 }
5202 if (ElemType->isRecordType()) {
5203 const Record *R = getRecord(ElemType);
5204 if (!R)
5205 return false;
5206
5207 for (size_t I = 0; I != NumElems; ++I) {
5208 if (!this->emitConstUint32(I, E))
5209 return false;
5210 if (!this->emitArrayElemPtr(PT_Uint32, E))
5211 return false;
5212 if (!this->visitZeroRecordInitializer(R, E))
5213 return false;
5214 if (!this->emitPopPtr(E))
5215 return false;
5216 }
5217 return true;
5218 }
5219 if (ElemType->isArrayType()) {
5220 for (size_t I = 0; I != NumElems; ++I) {
5221 if (!this->emitConstUint32(I, E))
5222 return false;
5223 if (!this->emitArrayElemPtr(PT_Uint32, E))
5224 return false;
5225 if (!this->visitZeroArrayInitializer(ElemType, E))
5226 return false;
5227 if (!this->emitPopPtr(E))
5228 return false;
5229 }
5230 return true;
5231 }
5232
5233 return false;
5234}
5235
5236template <class Emitter>
5237bool Compiler<Emitter>::visitAssignment(const Expr *LHS, const Expr *RHS,
5238 const Expr *E) {
5239 if (!canClassify(E->getType()))
5240 return false;
5241
5242 bool NeedsFlip = !isSideEffectFree(RHS);
5243 if (!NeedsFlip) {
5244 if (!this->visit(LHS))
5245 return false;
5246 if (!this->visit(RHS))
5247 return false;
5248 } else {
5249 if (!this->visit(RHS))
5250 return false;
5251 if (!this->visit(LHS))
5252 return false;
5253 }
5254
5255 if (LHS->getType().isVolatileQualified())
5256 return this->emitInvalidStore(LHS->getType().getTypePtr(), E);
5257
5258 // We don't support assignments in C.
5259 if (!Ctx.getLangOpts().CPlusPlus && !this->emitInvalid(E))
5260 return false;
5261
5262 PrimType RHT = classifyPrim(RHS);
5263 bool Activates = refersToUnion(LHS);
5264 bool BitField = LHS->refersToBitField();
5265
5266 if (NeedsFlip && !this->emitFlip(PT_Ptr, RHT, E))
5267 return false;
5268
5269 if (DiscardResult) {
5270 if (BitField && Activates)
5271 return this->emitStoreBitFieldActivatePop(RHT, E);
5272 if (BitField)
5273 return this->emitStoreBitFieldPop(RHT, E);
5274 if (Activates)
5275 return this->emitStoreActivatePop(RHT, E);
5276 // Otherwise, regular non-activating store.
5277 return this->emitStorePop(RHT, E);
5278 }
5279
5280 auto maybeLoad = [&](bool Result) -> bool {
5281 if (!Result)
5282 return false;
5283 // Assignments aren't necessarily lvalues in C.
5284 // Load from them in that case.
5285 if (!E->isLValue())
5286 return this->emitLoadPop(RHT, E);
5287 return true;
5288 };
5289
5290 if (BitField && Activates)
5291 return maybeLoad(this->emitStoreBitFieldActivate(RHT, E));
5292 if (BitField)
5293 return maybeLoad(this->emitStoreBitField(RHT, E));
5294 if (Activates)
5295 return maybeLoad(this->emitStoreActivate(RHT, E));
5296 // Otherwise, regular non-activating store.
5297 return maybeLoad(this->emitStore(RHT, E));
5298}
5299
5300template <class Emitter>
5301template <typename T>
5302bool Compiler<Emitter>::emitConst(T Value, PrimType Ty, SourceInfo Info) {
5303 switch (Ty) {
5304 case PT_Sint8:
5305 return this->emitConstSint8(Value, Info);
5306 case PT_Uint8:
5307 return this->emitConstUint8(Value, Info);
5308 case PT_Sint16:
5309 return this->emitConstSint16(Value, Info);
5310 case PT_Uint16:
5311 return this->emitConstUint16(Value, Info);
5312 case PT_Sint32:
5313 return this->emitConstSint32(Value, Info);
5314 case PT_Uint32:
5315 return this->emitConstUint32(Value, Info);
5316 case PT_Sint64:
5317 return this->emitConstSint64(Value, Info);
5318 case PT_Uint64:
5319 return this->emitConstUint64(Value, Info);
5320 case PT_Bool:
5321 return this->emitConstBool(Value, Info);
5322 case PT_Ptr:
5323 case PT_MemberPtr:
5324 case PT_Float:
5325 case PT_IntAP:
5326 case PT_IntAPS:
5327 case PT_FixedPoint:
5328 llvm_unreachable("Invalid integral type");
5329 break;
5330 }
5331 llvm_unreachable("unknown primitive type");
5332}
5333
5334template <class Emitter>
5335template <typename T>
5336bool Compiler<Emitter>::emitConst(T Value, const Expr *E) {
5337 return this->emitConst(Value, classifyPrim(E->getType()), E);
5338}
5339
5340template <class Emitter>
5341bool Compiler<Emitter>::emitConst(const APSInt &Value, PrimType Ty,
5342 SourceInfo Info) {
5343 if (Ty == PT_IntAPS)
5344 return this->emitConstIntAPS(Value, Info);
5345 if (Ty == PT_IntAP)
5346 return this->emitConstIntAP(Value, Info);
5347
5348 if (Value.isSigned())
5349 return this->emitConst(Value.getSExtValue(), Ty, Info);
5350 return this->emitConst(Value.getZExtValue(), Ty, Info);
5351}
5352
5353template <class Emitter>
5354bool Compiler<Emitter>::emitConst(const APInt &Value, PrimType Ty,
5355 SourceInfo Info) {
5356 if (Ty == PT_IntAPS)
5357 return this->emitConstIntAPS(Value, Info);
5358 if (Ty == PT_IntAP)
5359 return this->emitConstIntAP(Value, Info);
5360
5361 if (isSignedType(Ty))
5362 return this->emitConst(Value.getSExtValue(), Ty, Info);
5363 return this->emitConst(Value.getZExtValue(), Ty, Info);
5364}
5365
5366template <class Emitter>
5367bool Compiler<Emitter>::emitConst(const APSInt &Value, const Expr *E) {
5368 return this->emitConst(Value, classifyPrim(E->getType()), E);
5369}
5370
5371template <class Emitter>
5373 bool IsConst,
5374 bool IsVolatile,
5375 ScopeKind SC) {
5376 // FIXME: There are cases where Src.isExpr() is wrong, e.g.
5377 // (int){12} in C. Consider using Expr::isTemporaryObject() instead
5378 // or isa<MaterializeTemporaryExpr>().
5379 Descriptor *D = P.createDescriptor(Src, Ty, nullptr, IsConst, Src.isExpr(),
5380 /*IsMutable=*/false, IsVolatile);
5382 Scope::Local Local = this->createLocal(D);
5383 if (auto *VD = Src.asValueDecl())
5384 Locals.insert({VD, Local});
5385 VarScope->addForScopeKind(Local, SC);
5386 return Local.Offset;
5387}
5388
5389template <class Emitter>
5391 ScopeKind SC) {
5392 const ValueDecl *Key = nullptr;
5393 const Expr *Init = nullptr;
5394 bool IsTemporary = false;
5395 if (auto *VD = Src.asValueDecl()) {
5396 Key = VD;
5397
5398 if (const auto *VarD = dyn_cast<VarDecl>(VD))
5399 Init = VarD->getInit();
5400 }
5401 if (const auto *E = Src.asExpr()) {
5402 IsTemporary = true;
5403 if (Ty.isNull())
5404 Ty = E->getType();
5405 }
5406
5407 Descriptor *D = P.createDescriptor(
5408 Src, Ty.getTypePtr(), Ty.isConstQualified(), IsTemporary,
5409 /*IsMutable=*/false, /*IsVolatile=*/Ty.isVolatileQualified(), Init);
5410 if (!D)
5411 return std::nullopt;
5413
5414 Scope::Local Local = this->createLocal(D);
5415 if (Key)
5416 Locals.insert({Key, Local});
5417 VarScope->addForScopeKind(Local, SC);
5418 return Local.Offset;
5419}
5420
5421template <class Emitter>
5423 QualType Ty = E->getType();
5424 assert(!Ty->isRecordType());
5425
5426 Descriptor *D = P.createDescriptor(E, Ty.getTypePtr(), Ty.isConstQualified(),
5427 /*IsTemporary=*/true);
5428
5429 if (!D)
5430 return std::nullopt;
5431
5432 Scope::Local Local = this->createLocal(D);
5434 assert(S);
5435 // Attach to topmost scope.
5436 while (S->getParent())
5437 S = S->getParent();
5438 assert(S && !S->getParent());
5439 S->addLocal(Local);
5440 return Local.Offset;
5441}
5442
5443template <class Emitter>
5445 if (const PointerType *PT = dyn_cast<PointerType>(Ty))
5446 return PT->getPointeeType()->getAsCanonical<RecordType>();
5447 return Ty->getAsCanonical<RecordType>();
5448}
5449
5450template <class Emitter> Record *Compiler<Emitter>::getRecord(QualType Ty) {
5451 if (const auto *RecordTy = getRecordTy(Ty))
5452 return getRecord(RecordTy->getDecl()->getDefinitionOrSelf());
5453 return nullptr;
5454}
5455
5456template <class Emitter>
5458 return P.getOrCreateRecord(RD);
5459}
5460
5461template <class Emitter>
5463 return Ctx.getOrCreateFunction(FD);
5464}
5465
5466template <class Emitter>
5467bool Compiler<Emitter>::visitExpr(const Expr *E, bool DestroyToplevelScope) {
5469
5470 auto maybeDestroyLocals = [&]() -> bool {
5471 if (DestroyToplevelScope)
5472 return RootScope.destroyLocals() && this->emitCheckAllocations(E);
5473 return this->emitCheckAllocations(E);
5474 };
5475
5476 // Void expressions.
5477 if (E->getType()->isVoidType()) {
5478 if (!visit(E))
5479 return false;
5480 return this->emitRetVoid(E) && maybeDestroyLocals();
5481 }
5482
5483 // Expressions with a primitive return type.
5484 if (OptPrimType T = classify(E)) {
5485 if (!visit(E))
5486 return false;
5487
5488 return this->emitRet(*T, E) && maybeDestroyLocals();
5489 }
5490
5491 // Expressions with a composite return type.
5492 // For us, that means everything we don't
5493 // have a PrimType for.
5494 if (UnsignedOrNone LocalOffset = this->allocateLocal(E)) {
5495 InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalOffset));
5496 if (!this->emitGetPtrLocal(*LocalOffset, E))
5497 return false;
5498
5499 if (!visitInitializer(E))
5500 return false;
5501 // We are destroying the locals AFTER the Ret op.
5502 // The Ret op needs to copy the (alive) values, but the
5503 // destructors may still turn the entire expression invalid.
5504 return this->emitRetValue(E) && maybeDestroyLocals();
5505 }
5506
5507 return maybeDestroyLocals() && false;
5508}
5509
5510template <class Emitter>
5512 bool DestroyToplevelScope) {
5513 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
5514 /*NewInitializing=*/false, /*ToLValue=*/true);
5515
5516 return this->visitExpr(E, DestroyToplevelScope);
5517}
5518
5519template <class Emitter>
5521
5522 auto R = this->visitVarDecl(VD, VD->getInit(), /*Toplevel=*/true);
5523
5524 if (R.notCreated())
5525 return R;
5526
5527 if (R)
5528 return true;
5529
5530 if (!R && Context::shouldBeGloballyIndexed(VD)) {
5531 if (auto GlobalIndex = P.getGlobal(VD)) {
5532 Block *GlobalBlock = P.getGlobal(*GlobalIndex);
5533 auto &GD = GlobalBlock->getBlockDesc<GlobalInlineDescriptor>();
5534
5536 GlobalBlock->invokeDtor();
5537 }
5538 }
5539
5540 return R;
5541}
5542
5543/// Toplevel visitDeclAndReturn().
5544/// We get here from evaluateAsInitializer().
5545/// We need to evaluate the initializer and return its value.
5546template <class Emitter>
5548 bool ConstantContext) {
5549 // We only create variables if we're evaluating in a constant context.
5550 // Otherwise, just evaluate the initializer and return it.
5551 if (!ConstantContext) {
5552 DeclScope<Emitter> LS(this, VD);
5553 if (!this->visit(Init))
5554 return false;
5555 return this->emitRet(classify(Init).value_or(PT_Ptr), VD) &&
5556 LS.destroyLocals() && this->emitCheckAllocations(VD);
5557 }
5558
5559 LocalScope<Emitter> VDScope(this);
5560 if (!this->visitVarDecl(VD, Init, /*Toplevel=*/true))
5561 return false;
5562
5563 OptPrimType VarT = classify(VD->getType());
5564 bool IsReference = VD->getType()->isReferenceType();
5566 auto GlobalIndex = P.getGlobal(VD);
5567 assert(GlobalIndex); // visitVarDecl() didn't return false.
5568 if (VarT) {
5569 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
5570 return false;
5571 } else {
5572 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
5573 return false;
5574 }
5575 } else {
5576 auto Local = Locals.find(VD);
5577 assert(Local != Locals.end()); // Same here.
5578 if (VarT) {
5579 if (IsReference) {
5580 if (!this->emitGetRefLocal(Local->second.Offset, VD))
5581 return false;
5582 } else if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
5583 return false;
5584 } else {
5585 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
5586 return false;
5587 }
5588 }
5589
5590 // Return the value.
5591 if (!this->emitRet(VarT.value_or(PT_Ptr), VD)) {
5592 // If the Ret above failed and this is a global variable, mark it as
5593 // uninitialized, even everything else succeeded.
5595 auto GlobalIndex = P.getGlobal(VD);
5596 assert(GlobalIndex);
5597 Block *GlobalBlock = P.getGlobal(*GlobalIndex);
5598 auto &GD = GlobalBlock->getBlockDesc<GlobalInlineDescriptor>();
5599
5601 GlobalBlock->invokeDtor();
5602 }
5603 return false;
5604 }
5605
5606 return VDScope.destroyLocals() && this->emitCheckAllocations(VD);
5607}
5608
5609template <class Emitter>
5611 const Expr *Init,
5612 bool Toplevel) {
5613 QualType VarTy = VD->getType();
5614 // We don't know what to do with these, so just return false.
5615 if (VarTy.isNull())
5616 return false;
5617
5618 // This case is EvalEmitter-only. If we won't create any instructions for the
5619 // initializer anyway, don't bother creating the variable in the first place.
5620 if (!this->isActive())
5622
5623 OptPrimType VarT = classify(VD->getType());
5624
5625 if (Init && Init->isValueDependent())
5626 return false;
5627
5629 auto checkDecl = [&]() -> bool {
5630 bool NeedsOp = !Toplevel && VD->isLocalVarDecl() && VD->isStaticLocal();
5631 return !NeedsOp || this->emitCheckDecl(VD, VD);
5632 };
5633
5635 UnsignedOrNone GlobalIndex = P.getGlobal(VD);
5636 if (GlobalIndex) {
5637 // The global was previously created but the initializer failed.
5638 if (!P.getGlobal(*GlobalIndex)->isInitialized())
5639 return false;
5640 // We've already seen and initialized this global.
5641 if (P.isGlobalInitialized(*GlobalIndex))
5642 return checkDecl();
5643 // The previous attempt at initialization might've been unsuccessful,
5644 // so let's try this one.
5645 } else if ((GlobalIndex =
5646 P.createGlobal(VD, Init, VariablesAreConstexprUnknown))) {
5647 } else {
5648 return false;
5649 }
5650 if (!Init)
5651 return true;
5652
5653 if (!checkDecl())
5654 return false;
5655
5656 if (VarT) {
5657 if (!this->visit(Init))
5658 return false;
5659
5660 return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
5661 }
5662
5663 if (!this->emitGetPtrGlobal(*GlobalIndex, Init))
5664 return false;
5665
5666 if (!this->emitStartInit(Init))
5667 return false;
5668
5669 if (!visitInitializer(Init))
5670 return false;
5671
5672 if (!this->emitEndInit(Init))
5673 return false;
5674
5675 return this->emitFinishInitGlobal(Init);
5676 }
5677 // Local variables.
5679
5680 if (VarT) {
5681 unsigned Offset = this->allocateLocalPrimitive(
5682 VD, *VarT, VarTy.isConstQualified(), VarTy.isVolatileQualified(),
5684
5685 if (!Init || Init->getType()->isVoidType())
5686 return true;
5687
5688 // If this is a toplevel declaration, create a scope for the
5689 // initializer.
5690 if (Toplevel) {
5692 if (!this->visit(Init))
5693 return false;
5694 return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals();
5695 }
5696 if (!this->visit(Init))
5697 return false;
5698
5699 if (VarTy->isReferenceType()) {
5700 // [C++26][decl.ref]
5701 // The object designated by such a glvalue can be outside its lifetime
5702 // Because a null pointer value or a pointer past the end of an object
5703 // does not point to an object, a reference in a well-defined program
5704 // cannot refer to such things;
5705 assert(classifyPrim(VarTy) == PT_Ptr);
5706 if (!this->emitCheckRefInit(Init))
5707 return false;
5708 }
5709
5710 return this->emitSetLocal(*VarT, Offset, VD);
5711 }
5712 // Local composite variables.
5713 if (UnsignedOrNone Offset =
5714 this->allocateLocal(VD, VarTy, ScopeKind::Block)) {
5715 if (!Init)
5716 return true;
5717
5718 if (!this->emitGetPtrLocal(*Offset, Init))
5719 return false;
5720
5721 return visitInitializerPop(Init);
5722 }
5723 return false;
5724}
5725
5726template <class Emitter>
5728 assert(!canClassify(VD->getType()));
5729
5731 // Create a local variable to use as the instance.
5732 QualType Ty = VD->getType();
5733 Descriptor *D =
5734 P.createDescriptor(VD, Ty.getTypePtr(), /*IsConst=*/Ty.isConstQualified(),
5735 /*IsTemporary=*/false, /*IsMutable=*/false,
5736 /*IsVolatile=*/Ty.isVolatileQualified(), nullptr);
5737 if (!D)
5738 return false;
5739
5740 // FIXME: Would be nice if we didn't allocate the descriptor at all in this
5741 // case.
5742 if (D->hasTrivialDtor())
5743 return true;
5744
5745 Scope::Local Local = this->createLocal(D);
5746 Locals.insert({VD, Local});
5747 VarScope->addForScopeKind(Local, ScopeKind::Block);
5748
5749 if (!this->emitGetPtrLocal(Local.Offset, VD))
5750 return false;
5751
5752 if (!this->visitAPValueInitializer(Value, VD, Ty))
5753 return false;
5754
5755 return this->emitDestructionPop(D, VD);
5756}
5757
5759public:
5761 explicit ParamFinder() {}
5762
5763 bool VisitDeclRefExpr(const DeclRefExpr *E) override {
5764 if (const auto *P = dyn_cast<ParmVarDecl>(E->getDecl()))
5765 FoundParams.insert(P);
5766 return true;
5767 }
5768};
5769
5770/// Evaluate the \p Condition as if it was in the body of \p Callee.
5771/// Specifically, all the parameters of the callee are available to use
5772/// for the condition, and their values are given by \p Args (and \p This).
5773///
5774// Since this is a somewhat niche feature, we're abusing a few other mechanisms
5775// to implement this.
5776//
5777// We don't create an actual function frame but instead register the parameters
5778// as local variables.
5779//
5780// So we evaluate something like:
5781//
5782// bool thisfunc() {
5783// auto Arg0 = Args[0];
5784// ...
5785// return Condition;
5786// }
5787//
5788template <class Emitter>
5791 const Expr *This,
5792 const Expr *Condition) {
5793 // Instead of evaluating all parameters and trying to ignore failure,
5794 // we collect all the parameters used in the condition and only evaluate
5795 // those. Note that we still ignore failure in the loop below because the
5796 // failure might be inconsequential in the end,
5797 // e.g. in the case of `true || x`.
5798 ParamFinder PF;
5800
5801 LocalScope<Emitter> ArgScope(this);
5802 for (const ParmVarDecl *PVD : PF.FoundParams) {
5803 unsigned ParamIndex = 0;
5804 for (const ParmVarDecl *P : Callee->parameters()) {
5805 if (P == PVD)
5806 break;
5807 ++ParamIndex;
5808 }
5809
5810 const Expr *Arg = Args[ParamIndex];
5811 const ParmVarDecl *Param = Callee->getParamDecl(ParamIndex);
5812 if (OptPrimType ParamT = classify(Param->getType())) {
5813 unsigned ArgOffset =
5814 allocateLocalPrimitive(Param, *ParamT, /*IsConst=*/true);
5815 if (!this->visit(Arg))
5816 continue;
5817 if (!this->emitSetLocal(*ParamT, ArgOffset, Arg))
5818 return false;
5819 } else {
5820 UnsignedOrNone ArgOffset = this->allocateLocal(Param, Param->getType());
5821 if (!ArgOffset)
5822 return false;
5823 if (!this->emitGetPtrLocal(*ArgOffset, Arg))
5824 return false;
5825 if (!this->visitInitializerPop(Arg))
5826 continue;
5827 }
5828 }
5829
5830 if (This) {
5831 // We abuse the init stack for this and tell it to use
5832 // either a local variable or another decl for the This pointer.
5833 this->InitStackActive = true;
5834
5835 if (This->getType()->isPointerType()) {
5836 // Nothing to do here, the evaluation will fail if the instance
5837 // pointer is used.
5838 } else if (const auto *DRE = dyn_cast<DeclRefExpr>(This)) {
5839 InitStack.push_back(InitLink::Decl(DRE->getDecl()));
5840 } else {
5841 assert(!canClassify(This->getType()));
5842 UnsignedOrNone ArgOffset = this->allocateLocal(This, This->getType());
5843 if (!ArgOffset)
5844 return false;
5845 if (!this->emitGetPtrLocal(*ArgOffset, This))
5846 return false;
5847 if (!this->visitInitializerPop(This))
5848 return false;
5849 this->InitStack.push_back(InitLink::Temp(*ArgOffset));
5850 }
5851 }
5852
5853 // Destruction of the argument values is part of the callee frame,
5854 // so we simply ignore them here.
5855 this->VarScope = nullptr;
5856
5857 LocalScope<Emitter> RetScope(this);
5858 if (!this->visit(Condition))
5859 return false;
5860 if (!RetScope.destroyLocals())
5861 return false;
5862
5863 // Result of the condition should be on the stack.
5864 return this->emitRet(PT_Bool, Condition);
5865}
5866
5867template <class Emitter>
5869 SourceInfo Info) {
5870 assert(!Val.isIndeterminate() && "Needs to be checked before");
5871 assert(!DiscardResult);
5872 if (Val.isInt())
5873 return this->emitConst(Val.getInt(), ValType, Info);
5874 if (Val.isFloat())
5875 return this->emitFloat(Val.getFloat(), Info);
5876
5877 if (Val.isMemberPointer()) {
5878 if (const ValueDecl *MemberDecl = Val.getMemberPointerDecl()) {
5879 if (!this->emitGetMemberPtr(MemberDecl, Info))
5880 return false;
5881
5882 bool IsDerived = Val.isMemberPointerToDerivedMember();
5883 // Apply the member pointer path.
5884 for (const CXXRecordDecl *PathEntry : Val.getMemberPointerPath()) {
5885 if (!this->emitCopyMemberPtrPath(PathEntry, IsDerived, Info))
5886 return false;
5887 }
5888
5889 return true;
5890 }
5891 return this->emitNullMemberPtr(0, nullptr, Info);
5892 }
5893
5894 if (Val.isLValue()) {
5895 if (Val.isNullPointer())
5896 return this->emitNull(ValType, 0, nullptr, Info);
5897
5900
5901 if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>())
5902 return this->visit(BaseExpr);
5903 if (const auto *VD = Base.dyn_cast<const ValueDecl *>()) {
5904 if (!this->visitDeclRef(VD, Info.asExpr()))
5905 return false;
5906
5907 QualType EntryType = VD->getType();
5908 for (auto &Entry : Path) {
5909 if (EntryType->isArrayType()) {
5910 uint64_t Index = Entry.getAsArrayIndex();
5911 QualType ElemType =
5912 EntryType->getAsArrayTypeUnsafe()->getElementType();
5913 if (!this->emitConst(Index, PT_Uint64, Info))
5914 return false;
5915 if (!this->emitArrayElemPtrPop(PT_Uint64, Info))
5916 return false;
5917 EntryType = ElemType;
5918 } else {
5919 assert(EntryType->isRecordType());
5920 const Record *EntryRecord = getRecord(EntryType);
5921 if (!EntryRecord)
5922 return false;
5923
5924 const Decl *BaseOrMember = Entry.getAsBaseOrMember().getPointer();
5925 if (const auto *FD = dyn_cast<FieldDecl>(BaseOrMember)) {
5926 unsigned EntryOffset = EntryRecord->getField(FD)->Offset;
5927 if (!this->emitGetPtrFieldPop(EntryOffset, Info))
5928 return false;
5929 EntryType = FD->getType();
5930 } else {
5931 const auto *Base = cast<CXXRecordDecl>(BaseOrMember);
5932 if (const Record::Base *B = EntryRecord->getBaseOrNull(Base)) {
5933 if (!this->emitGetPtrBasePop(B->Offset, /*NullOK=*/false, Info))
5934 return false;
5935 } else {
5936 // Must be a virtual base.
5937 assert(EntryRecord->findVirtualBase(Base));
5938 if (!this->emitGetPtrVirtBasePop(Base, Info))
5939 return false;
5940 }
5941 EntryType = Ctx.getASTContext().getCanonicalTagType(Base);
5942 }
5943 }
5944 }
5945
5946 return true;
5947 }
5948 }
5949
5950 return false;
5951}
5952
5953template <class Emitter>
5955 SourceInfo Info, QualType T,
5956 bool IsCompleteClass) {
5957 if (Val.isStruct()) {
5958 const Record *R = this->getRecord(T);
5959 assert(R);
5960
5961 assert(R->getNumBases() == Val.getStructNumBases());
5962 if (IsCompleteClass)
5963 assert(R->getNumVirtualBases() == Val.getStructNumVirtualBases());
5964
5965 for (unsigned I = 0, N = Val.getStructNumBases(); I != N; ++I) {
5966 const APValue &B = Val.getStructBase(I);
5967 if (B.isIndeterminate())
5968 continue;
5969 const Record::Base *RB = R->getBase(I);
5970 QualType BaseType = Ctx.getASTContext().getCanonicalTagType(RB->Decl);
5971
5972 if (!this->emitGetPtrBase(RB->Offset, Info))
5973 return false;
5974 if (!this->visitAPValueInitializer(B, Info, BaseType,
5975 /*IsCompleteClass=*/false))
5976 return false;
5977 if (!this->emitFinishInitPop(Info))
5978 return false;
5979 }
5980
5981 for (unsigned I = 0, N = Val.getStructNumFields(); I != N; ++I) {
5982 const APValue &F = Val.getStructField(I);
5983 if (F.isIndeterminate())
5984 continue;
5985 const Record::Field *RF = R->getField(I);
5986 QualType FieldType = RF->Decl->getType();
5987 // Fields.
5988 if (OptPrimType PT = RF->T) {
5989 if (!this->visitAPValue(F, *PT, Info))
5990 return false;
5991 if (!this->emitInitField(*PT, RF->Offset, Info))
5992 return false;
5993 } else {
5994 if (!this->emitGetPtrField(RF->Offset, Info))
5995 return false;
5996 if (!this->visitAPValueInitializer(F, Info, FieldType))
5997 return false;
5998 if (!this->emitFinishInitPop(Info))
5999 return false;
6000 }
6001 }
6002
6003 // Virtual Bases.
6004 if (IsCompleteClass) {
6005 for (unsigned I = 0, N = Val.getStructNumVirtualBases(); I != N; ++I) {
6006 const APValue &B = Val.getStructVirtualBase(I);
6007 if (B.isIndeterminate())
6008 continue;
6009 const Record::Base *RB = R->getVirtualBase(I);
6010 QualType BaseType = Ctx.getASTContext().getCanonicalTagType(RB->Decl);
6011
6012 if (!this->emitGetPtrVirtBase(cast<CXXRecordDecl>(RB->R->getDecl()),
6013 Info))
6014 return false;
6015 if (!this->visitAPValueInitializer(B, Info, BaseType,
6016 /*IsCompleteClass=*/false))
6017 return false;
6018 if (!this->emitFinishInitPop(Info))
6019 return false;
6020 }
6021 }
6022
6023 return true;
6024 }
6025 if (Val.isUnion()) {
6026 const FieldDecl *UnionField = Val.getUnionField();
6027 if (!UnionField)
6028 return true;
6029 const Record *R = this->getRecord(T);
6030 assert(R);
6031 const APValue &F = Val.getUnionValue();
6032 if (F.isIndeterminate())
6033 return true;
6034 const Record::Field *RF = R->getField(UnionField);
6035 QualType FieldType = RF->Decl->getType();
6036
6037 if (OptPrimType PT = RF->T) {
6038 if (!this->visitAPValue(F, *PT, Info))
6039 return false;
6040 if (RF->isBitField())
6041 return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(),
6042 Info);
6043 return this->emitInitFieldActivate(*PT, RF->Offset, Info);
6044 }
6045
6046 if (!this->emitGetPtrField(RF->Offset, Info))
6047 return false;
6048 if (!this->emitActivate(Info))
6049 return false;
6050 if (!this->visitAPValueInitializer(F, Info, FieldType))
6051 return false;
6052 return this->emitPopPtr(Info);
6053 }
6054 if (Val.isArray()) {
6055 unsigned InitializedElems = Val.getArrayInitializedElts();
6056 const auto *ArrType = T->getAsArrayTypeUnsafe();
6057 QualType ElemType = ArrType->getElementType();
6058 OptPrimType ElemT = classify(ElemType);
6059
6060 for (unsigned A = 0, AN = Val.getArraySize(); A != AN; ++A) {
6061 const APValue &Elem = A >= InitializedElems
6062 ? Val.getArrayFiller()
6063 : Val.getArrayInitializedElt(A);
6064 if (Elem.isIndeterminate())
6065 continue;
6066
6067 if (ElemT) {
6068 if (!this->visitAPValue(Elem, *ElemT, Info))
6069 return false;
6070 if (!this->emitInitElem(*ElemT, A, Info))
6071 return false;
6072 } else {
6073 if (!this->emitConstUint32(A, Info))
6074 return false;
6075 if (!this->emitArrayElemPtrUint32(Info))
6076 return false;
6077 if (!this->visitAPValueInitializer(Elem, Info, ElemType))
6078 return false;
6079 if (!this->emitPopPtr(Info))
6080 return false;
6081 }
6082 }
6083 return true;
6084 }
6085 // TODO: Other types.
6086
6087 return false;
6088}
6089
6090template <class Emitter>
6092 if (P.getGlobal(VD))
6093 return true;
6094
6095 UnsignedOrNone GlobalIndex = P.createGlobal(VD, /*Init=*/nullptr);
6096 if (!GlobalIndex) {
6097 llvm_unreachable("Why didn't that work?");
6098 }
6099
6100 assert(canClassify(VD->getType()) &&
6101 "registerRedecl should only be called with primitive values");
6102
6103 PrimType T = classifyPrim(VD->getType());
6104 if (!visitAPValue(Val, T, VD))
6105 return false;
6106 return this->emitInitGlobal(T, *GlobalIndex, {});
6107}
6108
6109template <class Emitter>
6111 unsigned BuiltinID) {
6112 if (BuiltinID == Builtin::BI__builtin_constant_p) {
6113 // Void argument is always invalid and harder to handle later.
6114 if (E->getArg(0)->getType()->isVoidType()) {
6115 if (DiscardResult)
6116 return true;
6117 return this->emitConst(0, E);
6118 }
6119
6120 if (!this->emitStartSpeculation(E))
6121 return false;
6122 LabelTy EndLabel = this->getLabel();
6123 if (!this->speculate(E, EndLabel))
6124 return false;
6125 if (!this->emitEndSpeculation(E))
6126 return false;
6127 this->fallthrough(EndLabel);
6128 if (DiscardResult)
6129 return this->emitPop(classifyPrim(E), E);
6130 return true;
6131 }
6132
6133 // For these, we're expected to ultimately return an APValue pointing
6134 // to the CallExpr. This is needed to get the correct codegen.
6135 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6136 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
6137 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
6138 BuiltinID == Builtin::BI__builtin_function_start) {
6139 if (DiscardResult)
6140 return true;
6141 return this->emitDummyPtr(E, E);
6142 }
6143
6145 OptPrimType ReturnT = classify(E);
6146
6147 // Non-primitive return type. Prepare storage.
6148 if (!Initializing && !ReturnT && !ReturnType->isVoidType()) {
6149 UnsignedOrNone LocalIndex = allocateLocal(E);
6150 if (!LocalIndex)
6151 return false;
6152 if (!this->emitGetPtrLocal(*LocalIndex, E))
6153 return false;
6154 }
6155
6156 // Prepare function arguments including special cases.
6157 switch (BuiltinID) {
6158 case Builtin::BI__builtin_object_size:
6159 case Builtin::BI__builtin_dynamic_object_size: {
6160 assert(E->getNumArgs() == 2);
6161 const Expr *Arg0 = E->getArg(0);
6162 if (Arg0->isGLValue()) {
6163 if (!this->visit(Arg0))
6164 return false;
6165
6166 } else {
6168 return false;
6169 }
6170 if (!this->visit(E->getArg(1)))
6171 return false;
6172
6173 } break;
6174 case Builtin::BI__assume:
6175 case Builtin::BI__builtin_assume:
6176 // Argument is not evaluated.
6177 break;
6178 case Builtin::BI__atomic_is_lock_free:
6179 case Builtin::BI__atomic_always_lock_free: {
6180 assert(E->getNumArgs() == 2);
6181 if (!this->visit(E->getArg(0)))
6182 return false;
6183 if (!this->visitAsLValue(E->getArg(1)))
6184 return false;
6185 } break;
6186
6187 default:
6188 if (!Context::isUnevaluatedBuiltin(BuiltinID)) {
6189 // Put arguments on the stack.
6190 for (const auto *Arg : E->arguments()) {
6191 if (!this->visit(Arg))
6192 return false;
6193 }
6194 }
6195 }
6196
6197 if (!this->emitCallBI(E, BuiltinID, E))
6198 return false;
6199
6200 if (DiscardResult && !ReturnType->isVoidType())
6201 return this->emitPop(ReturnT.value_or(PT_Ptr), E);
6202
6203 return true;
6204}
6205
6207 if (!MD || !MD->isDefaulted())
6208 return false;
6210 return false;
6211 return MD->getParent()->isUnion() ||
6213}
6214
6215template <class Emitter>
6217 if (E->containsErrors())
6218 return false;
6219 const FunctionDecl *FuncDecl = E->getDirectCallee();
6220
6221 if (FuncDecl) {
6222 if (unsigned BuiltinID = FuncDecl->getBuiltinID())
6223 return VisitBuiltinCallExpr(E, BuiltinID);
6224
6225 // Calls to replaceable operator new/operator delete.
6227 if (FuncDecl->getDeclName().isAnyOperatorNew())
6228 return VisitBuiltinCallExpr(E, Builtin::BI__builtin_operator_new);
6229 assert(FuncDecl->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
6230 FuncDecl->getDeclName().getCXXOverloadedOperator() ==
6231 OO_Array_Delete);
6232 return VisitBuiltinCallExpr(E, Builtin::BI__builtin_operator_delete);
6233 }
6234
6235 // Explicit calls to trivial destructors
6236 if (const auto *DD = dyn_cast<CXXDestructorDecl>(FuncDecl);
6237 DD && DD->isTrivial()) {
6238 const auto *MemberCall = cast<CXXMemberCallExpr>(E);
6239 if (!this->visit(MemberCall->getImplicitObjectArgument()))
6240 return false;
6241 return this->emitCheckDestruction(E) && this->emitEndLifetime(E) &&
6242 this->emitPopPtr(E);
6243 }
6244 }
6245
6246 LocalScope<Emitter> CallScope(this, ScopeKind::Call);
6247 ArrayRef<const Expr *> Args(E->getArgs(), E->getNumArgs());
6248 bool ActivateLHS = false;
6249
6250 // Emit a special op for trivial copy/move operators.
6251 if (isTrivialMemoryOperation(dyn_cast_if_present<CXXMethodDecl>(FuncDecl))) {
6252 const Function *Func = getFunction(FuncDecl);
6253 if (!Func)
6254 return false;
6255
6256 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
6257 OCE && OCE->isAssignmentOp()) {
6258 const CXXRecordDecl *LHSRecord = Args[0]->getType()->getAsCXXRecordDecl();
6259 ActivateLHS = LHSRecord && LHSRecord->hasTrivialDefaultConstructor();
6260 }
6261 if (const auto *MCE = dyn_cast<CXXMemberCallExpr>(E))
6262 if (!this->visit(MCE->getImplicitObjectArgument()))
6263 return false;
6264
6265 if (!this->visitCallArgs(Args, FuncDecl, /*ActivateLHS=*/ActivateLHS,
6267 return false;
6268
6269 if (!this->emitTrivialCopy(ActivateLHS, Func, E))
6270 return false;
6271
6272 if (!DiscardResult)
6273 return CallScope.destroyLocals();
6274 return this->emitPopPtr(E) && CallScope.destroyLocals();
6275 }
6276
6277 QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
6279 bool HasRVO = !ReturnType->isVoidType() && !T;
6280
6281 if (HasRVO) {
6282 if (DiscardResult) {
6283 // If we need to discard the return value but the function returns its
6284 // value via an RVO pointer, we need to create one such pointer just
6285 // for this call.
6286 if (UnsignedOrNone LocalIndex = allocateLocal(E)) {
6287 if (!this->emitGetPtrLocal(*LocalIndex, E))
6288 return false;
6289 }
6290 } else {
6291 // We need the result. Prepare a pointer to return or
6292 // dup the current one.
6293 if (!Initializing) {
6294 if (UnsignedOrNone LocalIndex = allocateLocal(E)) {
6295 if (!this->emitGetPtrLocal(*LocalIndex, E))
6296 return false;
6297 }
6298 }
6299 if (!this->emitDupPtr(E))
6300 return false;
6301 }
6302 }
6303
6304 const Expr *ReversedArgs[2];
6305 bool IsAssignmentOperatorCall = false;
6306 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
6307 OCE && OCE->isAssignmentOp()) {
6308 // Just like with regular assignments, we need to special-case assignment
6309 // operators here and evaluate the RHS (the second arg) before the LHS (the
6310 // first arg). We fix this by using a Flip op later.
6311 assert(Args.size() == 2);
6312 const CXXRecordDecl *LHSRecord = Args[0]->getType()->getAsCXXRecordDecl();
6313 ActivateLHS = LHSRecord && LHSRecord->hasTrivialDefaultConstructor();
6314 IsAssignmentOperatorCall = true;
6315 ReversedArgs[0] = Args[1];
6316 ReversedArgs[1] = Args[0];
6317 Args = ReversedArgs;
6318 }
6319
6320 // Calling a static operator will still
6321 // pass the instance, but we don't need it.
6322 // Discard it here.
6323 if (isa<CXXOperatorCallExpr>(E)) {
6324 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
6325 MD && MD->isStatic()) {
6326 if (!this->discard(E->getArg(0)))
6327 return false;
6328 // Drop first arg.
6329 Args = Args.drop_front();
6330 }
6331 }
6332
6333 bool Devirtualized = false;
6334 UnsignedOrNone CalleeOffset = std::nullopt;
6335 // Add the (optional, implicit) This pointer.
6336 if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
6337 if (!FuncDecl && classifyPrim(E->getCallee()) == PT_MemberPtr) {
6338 // If we end up creating a CallPtr op for this, we need the base of the
6339 // member pointer as the instance pointer, and later extract the function
6340 // decl as the function pointer.
6341 const Expr *Callee = E->getCallee();
6342 CalleeOffset =
6343 this->allocateLocalPrimitive(Callee, PT_MemberPtr, /*IsConst=*/true);
6344 if (!this->visit(Callee))
6345 return false;
6346 if (!this->emitSetLocal(PT_MemberPtr, *CalleeOffset, E))
6347 return false;
6348 if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
6349 return false;
6350 if (!this->emitGetMemberPtrBase(E))
6351 return false;
6352 } else {
6353 const auto *InstancePtr = MC->getImplicitObjectArgument();
6354 if (isa_and_nonnull<CXXDestructorDecl>(CompilingFunction) ||
6355 isa_and_nonnull<CXXConstructorDecl>(CompilingFunction)) {
6356 const auto *Stripped = stripCheckedDerivedToBaseCasts(InstancePtr);
6357 if (isa<CXXThisExpr>(Stripped)) {
6358 FuncDecl =
6359 cast<CXXMethodDecl>(FuncDecl)->getCorrespondingMethodInClass(
6360 Stripped->getType()->getPointeeType()->getAsCXXRecordDecl());
6361 Devirtualized = true;
6362 if (!this->visit(Stripped))
6363 return false;
6364 } else {
6365 if (!this->visit(InstancePtr))
6366 return false;
6367 }
6368 } else {
6369 if (!this->visit(InstancePtr))
6370 return false;
6371 }
6372 }
6373 } else if (const auto *PD =
6374 dyn_cast<CXXPseudoDestructorExpr>(E->getCallee())) {
6375 if (!this->emitCheckPseudoDtor(E))
6376 return false;
6377 const Expr *Base = PD->getBase();
6378 // E.g. `using T = int; 0.~T();`.
6379 if (OptPrimType BaseT = classify(Base); !BaseT || BaseT != PT_Ptr)
6380 return this->discard(Base);
6381 if (!this->visit(Base))
6382 return false;
6383 return this->emitPseudoDtor(E);
6384 } else if (!FuncDecl) {
6385 const Expr *Callee = E->getCallee();
6386 CalleeOffset =
6387 this->allocateLocalPrimitive(Callee, PT_Ptr, /*IsConst=*/true);
6388 if (!this->visit(Callee))
6389 return false;
6390 if (!this->emitSetLocal(PT_Ptr, *CalleeOffset, E))
6391 return false;
6392 }
6393
6394 if (!this->visitCallArgs(Args, FuncDecl, ActivateLHS,
6396 return false;
6397
6398 // Undo the argument reversal we did earlier.
6399 if (IsAssignmentOperatorCall) {
6400 assert(Args.size() == 2);
6401 PrimType Arg1T = classify(Args[0]).value_or(PT_Ptr);
6402 PrimType Arg2T = classify(Args[1]).value_or(PT_Ptr);
6403 if (!this->emitFlip(Arg2T, Arg1T, E))
6404 return false;
6405 }
6406
6407 if (FuncDecl) {
6408 const Function *Func = getFunction(FuncDecl);
6409 if (!Func)
6410 return false;
6411
6412 // In error cases, the function may be called with fewer arguments than
6413 // parameters.
6414 if (E->getNumArgs() < Func->getNumWrittenParams())
6415 return false;
6416
6417 assert(HasRVO == Func->hasRVO());
6418
6419 bool HasQualifier = false;
6420 if (const auto *ME = dyn_cast<MemberExpr>(E->getCallee()))
6421 HasQualifier = ME->hasQualifier();
6422
6423 bool IsVirtual = false;
6424 if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
6425 IsVirtual = !Devirtualized && MD->isVirtual();
6426
6427 // In any case call the function. The return value will end up on the stack
6428 // and if the function has RVO, we already have the pointer on the stack to
6429 // write the result into.
6430 if (IsVirtual && !HasQualifier) {
6431 uint32_t VarArgSize = 0;
6432 unsigned NumParams =
6433 Func->getNumWrittenParams() +
6434 (isa<CXXOperatorCallExpr>(E) && Func->hasImplicitThisPointer());
6435 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
6436 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
6437
6438 if (!this->emitCallVirt(Func, VarArgSize, E))
6439 return false;
6440 } else if (Func->isVariadic()) {
6441 uint32_t VarArgSize = 0;
6442 unsigned NumParams =
6443 Func->getNumWrittenParams() +
6444 (isa<CXXOperatorCallExpr>(E) && Func->hasImplicitThisPointer());
6445 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
6446 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
6447 if (!this->emitCallVar(Func, VarArgSize, E))
6448 return false;
6449 } else {
6450 if (!this->emitCall(Func, 0, E))
6451 return false;
6452 }
6453 } else {
6454 // Indirect call. Visit the callee, which will leave a FunctionPointer on
6455 // the stack. Cleanup of the returned value if necessary will be done after
6456 // the function call completed.
6457
6458 // Sum the size of all args from the call expr.
6459 uint32_t ArgSize = 0;
6460 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
6461 ArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
6462
6463 // Get the callee, either from a member pointer or function pointer saved in
6464 // CalleeOffset.
6465 if (isa<CXXMemberCallExpr>(E) && CalleeOffset) {
6466 if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
6467 return false;
6468 if (!this->emitGetMemberPtrDecl(E))
6469 return false;
6470 } else {
6471 if (!this->emitGetLocal(PT_Ptr, *CalleeOffset, E))
6472 return false;
6473 }
6474 if (!this->emitCallPtr(ArgSize, E, E))
6475 return false;
6476 }
6477
6478 // Cleanup for discarded return values.
6479 if (DiscardResult && !ReturnType->isVoidType() && T)
6480 return this->emitPop(*T, E) && CallScope.destroyLocals();
6481
6482 return CallScope.destroyLocals();
6483}
6484
6485template <class Emitter>
6487 SourceLocScope<Emitter> SLS(this, E);
6488
6489 return this->delegate(E->getExpr());
6490}
6491
6492template <class Emitter>
6494 SourceLocScope<Emitter> SLS(this, E);
6495
6496 return this->delegate(E->getExpr());
6497}
6498
6499template <class Emitter>
6501 if (DiscardResult)
6502 return true;
6503
6504 return this->emitConstBool(E->getValue(), E);
6505}
6506
6507template <class Emitter>
6509 const CXXNullPtrLiteralExpr *E) {
6510 if (DiscardResult)
6511 return true;
6512
6513 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(E->getType());
6514 return this->emitNullPtr(Val, nullptr, E);
6515}
6516
6517template <class Emitter>
6519 if (DiscardResult)
6520 return true;
6521
6522 assert(E->getType()->isIntegerType());
6523
6525 return this->emitZero(T, E);
6526}
6527
6528template <class Emitter>
6530 if (DiscardResult)
6531 return true;
6532
6533 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
6534 if (this->LambdaThisCapture.Offset > 0) {
6535 if (this->LambdaThisCapture.IsPtr)
6536 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
6537 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
6538 }
6539 }
6540
6541 // In some circumstances, the 'this' pointer does not actually refer to the
6542 // instance pointer of the current function frame, but e.g. to the declaration
6543 // currently being initialized. Here we emit the necessary instruction(s) for
6544 // this scenario.
6545 if (!InitStackActive || InitStack.empty())
6546 return this->emitThis(E);
6547
6548 // If our init stack is, for example:
6549 // 0 Stack: 3 (decl)
6550 // 1 Stack: 6 (init list)
6551 // 2 Stack: 1 (field)
6552 // 3 Stack: 6 (init list)
6553 // 4 Stack: 1 (field)
6554 //
6555 // We want to find the LAST element in it that's an init list,
6556 // which is marked with the K_InitList marker. The index right
6557 // before that points to an init list. We need to find the
6558 // elements before the K_InitList element that point to a base
6559 // (e.g. a decl or This), optionally followed by field, elem, etc.
6560 // In the example above, we want to emit elements [0..2].
6561 unsigned StartIndex = 0;
6562 unsigned EndIndex = 0;
6563 // Find the init list.
6564 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
6565 if (InitStack[StartIndex].Kind == InitLink::K_DIE) {
6566 EndIndex = StartIndex;
6567 --StartIndex;
6568 break;
6569 }
6570 }
6571
6572 // Walk backwards to find the base.
6573 for (; StartIndex > 0; --StartIndex) {
6574 if (InitStack[StartIndex].Kind == InitLink::K_InitList)
6575 continue;
6576
6577 if (InitStack[StartIndex].Kind != InitLink::K_Field &&
6578 InitStack[StartIndex].Kind != InitLink::K_Elem &&
6579 InitStack[StartIndex].Kind != InitLink::K_Base &&
6580 InitStack[StartIndex].Kind != InitLink::K_DIE)
6581 break;
6582 }
6583
6584 if (StartIndex == 0 && EndIndex == 0)
6585 EndIndex = InitStack.size() - 1;
6586
6587 assert(InitStack[StartIndex].Kind == InitLink::K_Decl ||
6588 InitStack[StartIndex].Kind == InitLink::K_This ||
6589 InitStack[StartIndex].Kind == InitLink::K_Temp ||
6590 InitStack[StartIndex].Kind == InitLink::K_RVO);
6591
6592 // NOTE: This could be StartIndex < EndIndex, but we're also abusing the
6593 // InitStack mechanism in visitWithSubstitutions to have the This pointer
6594 // _just_ be a local variable.
6595 assert(StartIndex <= EndIndex);
6596
6597 // Emit the instructions.
6598 for (unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
6599 if (InitStack[I].Kind == InitLink::K_InitList ||
6600 InitStack[I].Kind == InitLink::K_DIE)
6601 continue;
6602 if (!InitStack[I].template emit<Emitter>(this, E))
6603 return false;
6604 }
6605 return true;
6606}
6607
6608template <class Emitter> bool Compiler<Emitter>::visitStmt(const Stmt *S) {
6609 switch (S->getStmtClass()) {
6610 case Stmt::CompoundStmtClass:
6612 case Stmt::DeclStmtClass:
6613 return visitDeclStmt(cast<DeclStmt>(S), /*EvaluateConditionDecl=*/true);
6614 case Stmt::ReturnStmtClass:
6616 case Stmt::IfStmtClass:
6617 return visitIfStmt(cast<IfStmt>(S));
6618 case Stmt::WhileStmtClass:
6620 case Stmt::DoStmtClass:
6621 return visitDoStmt(cast<DoStmt>(S));
6622 case Stmt::ForStmtClass:
6623 return visitForStmt(cast<ForStmt>(S));
6624 case Stmt::CXXForRangeStmtClass:
6626 case Stmt::BreakStmtClass:
6628 case Stmt::ContinueStmtClass:
6630 case Stmt::SwitchStmtClass:
6632 case Stmt::CaseStmtClass:
6633 return visitCaseStmt(cast<CaseStmt>(S));
6634 case Stmt::DefaultStmtClass:
6636 case Stmt::AttributedStmtClass:
6638 case Stmt::CXXTryStmtClass:
6640 case Stmt::NullStmtClass:
6641 return true;
6642 // Always invalid statements.
6643 case Stmt::GCCAsmStmtClass:
6644 case Stmt::MSAsmStmtClass:
6645 case Stmt::GotoStmtClass:
6646 return this->emitInvalid(S);
6647 case Stmt::LabelStmtClass:
6648 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
6649 case Stmt::CXXExpansionStmtInstantiationClass:
6652 default: {
6653 if (const auto *E = dyn_cast<Expr>(S))
6654 return this->discard(E);
6655 return false;
6656 }
6657 }
6658}
6659
6660template <class Emitter>
6663 for (const auto *InnerStmt : S->body())
6664 if (!visitStmt(InnerStmt))
6665 return false;
6666 return Scope.destroyLocals();
6667}
6668
6669template <class Emitter>
6670bool Compiler<Emitter>::maybeEmitDeferredVarInit(const VarDecl *VD) {
6671 if (auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
6672 for (auto *BD : DD->flat_bindings())
6673 if (auto *KD = BD->getHoldingVar();
6674 KD && !this->visitVarDecl(KD, KD->getInit()))
6675 return false;
6676 }
6677 return true;
6678}
6679
6681 assert(FD);
6682 assert(FD->getParent()->isUnion());
6683 const CXXRecordDecl *CXXRD =
6685 return !CXXRD || CXXRD->hasTrivialDefaultConstructor();
6686}
6687
6688template <class Emitter> bool Compiler<Emitter>::refersToUnion(const Expr *E) {
6689 for (;;) {
6690 if (const auto *ME = dyn_cast<MemberExpr>(E)) {
6691 if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6692 FD && FD->getParent()->isUnion() && hasTrivialDefaultCtorParent(FD))
6693 return true;
6694 E = ME->getBase();
6695 continue;
6696 }
6697
6698 if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6699 E = ASE->getBase()->IgnoreImplicit();
6700 continue;
6701 }
6702
6703 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E);
6704 ICE && (ICE->getCastKind() == CK_NoOp ||
6705 ICE->getCastKind() == CK_DerivedToBase ||
6706 ICE->getCastKind() == CK_UncheckedDerivedToBase)) {
6707 E = ICE->getSubExpr();
6708 continue;
6709 }
6710
6711 if (const auto *This = dyn_cast<CXXThisExpr>(E)) {
6712 const auto *ThisRecord =
6713 This->getType()->getPointeeType()->getAsRecordDecl();
6714 if (!ThisRecord->isUnion())
6715 return false;
6716 // Otherwise, always activate if we're in the ctor.
6717 if (const auto *Ctor =
6718 dyn_cast_if_present<CXXConstructorDecl>(CompilingFunction))
6719 return Ctor->getParent() == ThisRecord;
6720 return false;
6721 }
6722
6723 break;
6724 }
6725 return false;
6726}
6727
6728template <class Emitter>
6730 bool EvaluateConditionDecl) {
6731 for (const auto *D : DS->decls()) {
6734 continue;
6735
6736 if (const auto *ESD = dyn_cast<CXXExpansionStmtDecl>(D)) {
6737 assert(ESD->getInstantiations() && "not expanded?");
6738 if (!this->visitStmt(ESD->getInstantiations()))
6739 return false;
6740 continue;
6741 }
6742
6743 const auto *VD = dyn_cast<VarDecl>(D);
6744 if (!VD)
6745 return false;
6746 if (!this->visitVarDecl(VD, VD->getInit()))
6747 return false;
6748
6749 // Register decomposition decl holding vars.
6750 if (EvaluateConditionDecl && !this->maybeEmitDeferredVarInit(VD))
6751 return false;
6752 }
6753
6754 return true;
6755}
6756
6757template <class Emitter>
6759 if (this->InStmtExpr)
6760 return this->emitUnsupported(RS);
6761
6762 if (const Expr *RE = RS->getRetValue()) {
6763 LocalScope<Emitter> RetScope(this);
6764 if (ReturnType) {
6765 // Primitive types are simply returned.
6766 if (!this->visit(RE))
6767 return false;
6768 this->emitCleanup();
6769 return this->emitRet(*ReturnType, RS);
6770 }
6771
6772 if (RE->getType()->isVoidType()) {
6773 if (!this->visit(RE))
6774 return false;
6775 } else {
6776 if (RE->containsErrors())
6777 return false;
6778
6780 // RVO - construct the value in the return location.
6781 if (!this->emitRVOPtr(RE))
6782 return false;
6783 if (!this->visitInitializerPop(RE))
6784 return false;
6785
6786 this->emitCleanup();
6787 return this->emitRetVoid(RS);
6788 }
6789 }
6790
6791 // Void return.
6792 this->emitCleanup();
6793 return this->emitRetVoid(RS);
6794}
6795
6796template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
6797 LocalScope<Emitter> IfScope(this);
6798
6799 auto visitChildStmt = [&](const Stmt *S) -> bool {
6800 LocalScope<Emitter> SScope(this);
6801 if (!visitStmt(S))
6802 return false;
6803 return SScope.destroyLocals();
6804 };
6805
6806 if (auto *CondInit = IS->getInit()) {
6807 if (!visitStmt(CondInit))
6808 return false;
6809 }
6810
6811 if (const DeclStmt *CondDecl = IS->getConditionVariableDeclStmt()) {
6812 if (!visitDeclStmt(CondDecl))
6813 return false;
6814 }
6815
6816 // Save ourselves compiling some code and the jumps, etc. if the condition is
6817 // stataically known to be either true or false. We could look at more cases
6818 // here, but I think all the ones that actually happen are using a
6819 // ConstantExpr.
6820 if (std::optional<bool> BoolValue = getBoolValue(IS->getCond())) {
6821 if (*BoolValue)
6822 return visitChildStmt(IS->getThen());
6823 if (const Stmt *Else = IS->getElse())
6824 return visitChildStmt(Else);
6825 return true;
6826 }
6827
6828 // Otherwise, compile the condition.
6829 if (IS->isNonNegatedConsteval()) {
6830 if (!this->emitIsConstantContext(IS))
6831 return false;
6832 } else if (IS->isNegatedConsteval()) {
6833 if (!this->emitIsConstantContext(IS))
6834 return false;
6835 if (!this->emitInv(IS))
6836 return false;
6837 } else {
6839 if (!this->visitBool(IS->getCond()))
6840 return false;
6841 if (!CondScope.destroyLocals())
6842 return false;
6843 }
6844
6845 if (!this->maybeEmitDeferredVarInit(IS->getConditionVariable()))
6846 return false;
6847
6848 if (const Stmt *Else = IS->getElse()) {
6849 LabelTy LabelElse = this->getLabel();
6850 LabelTy LabelEnd = this->getLabel();
6851 if (!this->jumpFalse(LabelElse, IS))
6852 return false;
6853 if (!visitChildStmt(IS->getThen()))
6854 return false;
6855 if (!this->jump(LabelEnd, IS))
6856 return false;
6857 this->emitLabel(LabelElse);
6858 if (!visitChildStmt(Else))
6859 return false;
6860 this->emitLabel(LabelEnd);
6861 } else {
6862 LabelTy LabelEnd = this->getLabel();
6863 if (!this->jumpFalse(LabelEnd, IS))
6864 return false;
6865 if (!visitChildStmt(IS->getThen()))
6866 return false;
6867 this->emitLabel(LabelEnd);
6868 }
6869
6870 if (!IfScope.destroyLocals())
6871 return false;
6872
6873 return true;
6874}
6875
6876template <class Emitter>
6878 const Expr *Cond = S->getCond();
6879 const Stmt *Body = S->getBody();
6880
6881 LabelTy CondLabel = this->getLabel(); // Label before the condition.
6882 LabelTy EndLabel = this->getLabel(); // Label after the loop.
6883 LocalScope<Emitter> WholeLoopScope(this);
6884 LoopScope<Emitter> LS(this, S, EndLabel, CondLabel);
6885
6886 this->fallthrough(CondLabel);
6887 this->emitLabel(CondLabel);
6888
6889 // Start of the loop body {
6890 LocalScope<Emitter> CondScope(this);
6891
6892 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt()) {
6893 if (!visitDeclStmt(CondDecl))
6894 return false;
6895 }
6896
6897 if (!this->visitBool(Cond))
6898 return false;
6899
6900 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
6901 return false;
6902
6903 if (!this->jumpFalse(EndLabel, S))
6904 return false;
6905
6906 if (!this->visitStmt(Body))
6907 return false;
6908
6909 if (!CondScope.destroyLocals())
6910 return false;
6911 // } End of loop body.
6912
6913 if (!this->jump(CondLabel, S))
6914 return false;
6915 this->fallthrough(EndLabel);
6916 this->emitLabel(EndLabel);
6917
6918 return CondScope.destroyLocals() && WholeLoopScope.destroyLocals();
6919}
6920
6921template <class Emitter> bool Compiler<Emitter>::visitDoStmt(const DoStmt *S) {
6922 const Expr *Cond = S->getCond();
6923 const Stmt *Body = S->getBody();
6924
6925 LabelTy StartLabel = this->getLabel();
6926 LabelTy EndLabel = this->getLabel();
6927 LabelTy CondLabel = this->getLabel();
6928 LocalScope<Emitter> WholeLoopScope(this);
6929 LoopScope<Emitter> LS(this, S, EndLabel, CondLabel);
6930
6931 this->fallthrough(StartLabel);
6932 this->emitLabel(StartLabel);
6933
6934 {
6935 LocalScope<Emitter> CondScope(this);
6936 if (!this->visitStmt(Body))
6937 return false;
6938 this->fallthrough(CondLabel);
6939 this->emitLabel(CondLabel);
6940 if (!this->visitBool(Cond))
6941 return false;
6942
6943 if (!CondScope.destroyLocals())
6944 return false;
6945 }
6946 if (!this->jumpTrue(StartLabel, S))
6947 return false;
6948
6949 this->fallthrough(EndLabel);
6950 this->emitLabel(EndLabel);
6951 return WholeLoopScope.destroyLocals();
6952}
6953
6954template <class Emitter>
6956 // for (Init; Cond; Inc) { Body }
6957 const Stmt *Init = S->getInit();
6958 const Expr *Cond = S->getCond();
6959 const Expr *Inc = S->getInc();
6960 const Stmt *Body = S->getBody();
6961
6962 LabelTy EndLabel = this->getLabel();
6963 LabelTy CondLabel = this->getLabel();
6964 LabelTy IncLabel = this->getLabel();
6965
6966 LocalScope<Emitter> WholeLoopScope(this);
6967 if (Init && !this->visitStmt(Init))
6968 return false;
6969
6970 // Start of the loop body {
6971 this->fallthrough(CondLabel);
6972 this->emitLabel(CondLabel);
6973
6974 LocalScope<Emitter> CondScope(this);
6975 LoopScope<Emitter> LS(this, S, EndLabel, IncLabel);
6976 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt()) {
6977 if (!visitDeclStmt(CondDecl))
6978 return false;
6979 }
6980
6981 if (Cond) {
6982 if (!this->visitBool(Cond))
6983 return false;
6984 if (!this->jumpFalse(EndLabel, S))
6985 return false;
6986 }
6987 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
6988 return false;
6989
6990 if (Body && !this->visitStmt(Body))
6991 return false;
6992
6993 this->fallthrough(IncLabel);
6994 this->emitLabel(IncLabel);
6995 if (Inc && !this->discard(Inc))
6996 return false;
6997
6998 if (!CondScope.destroyLocals())
6999 return false;
7000 if (!this->jump(CondLabel, S))
7001 return false;
7002 // } End of loop body.
7003
7004 this->emitLabel(EndLabel);
7005 // If we jumped out of the loop above, we still need to clean up the condition
7006 // scope.
7007 return CondScope.destroyLocals() && WholeLoopScope.destroyLocals();
7008}
7009
7010template <class Emitter>
7012 const Stmt *Init = S->getInit();
7013 const Expr *Cond = S->getCond();
7014 const Expr *Inc = S->getInc();
7015 const Stmt *Body = S->getBody();
7016 const Stmt *BeginStmt = S->getBeginStmt();
7017 const Stmt *RangeStmt = S->getRangeStmt();
7018 const Stmt *EndStmt = S->getEndStmt();
7019
7020 LabelTy EndLabel = this->getLabel();
7021 LabelTy CondLabel = this->getLabel();
7022 LabelTy IncLabel = this->getLabel();
7023 LocalScope<Emitter> WholeLoopScope(this);
7024 LoopScope<Emitter> LS(this, S, EndLabel, IncLabel);
7025
7026 // Emit declarations needed in the loop.
7027 if (Init && !this->visitStmt(Init))
7028 return false;
7029 if (!this->visitStmt(RangeStmt))
7030 return false;
7031 if (!this->visitStmt(BeginStmt))
7032 return false;
7033 if (!this->visitStmt(EndStmt))
7034 return false;
7035
7036 LocalScope<Emitter> CondScope(this);
7037 // Now the condition as well as the loop variable assignment.
7038 this->fallthrough(CondLabel);
7039 this->emitLabel(CondLabel);
7040 if (!this->visitBool(Cond))
7041 return false;
7042 if (!this->jumpFalse(EndLabel, S))
7043 return false;
7044
7045 if (!this->visitDeclStmt(S->getLoopVarStmt(), /*EvaluateConditionDecl=*/true))
7046 return false;
7047
7048 // Body.
7049 {
7050 if (!this->visitStmt(Body))
7051 return false;
7052
7053 this->fallthrough(IncLabel);
7054 this->emitLabel(IncLabel);
7055 if (!this->discard(Inc))
7056 return false;
7057 }
7058
7059 if (!CondScope.destroyLocals())
7060 return false;
7061 if (!this->jump(CondLabel, S))
7062 return false;
7063
7064 this->fallthrough(EndLabel);
7065 this->emitLabel(EndLabel);
7066 return WholeLoopScope.destroyLocals();
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> *BreakScope = nullptr;
7077
7078 if (!TargetLoop) {
7079 for (const auto &LI : llvm::reverse(LabelInfoStack)) {
7080 if (LI.BreakLabel) {
7081 TargetLabel = *LI.BreakLabel;
7082 BreakScope = LI.BreakOrContinueScope;
7083 break;
7084 }
7085 }
7086 } else {
7087 for (const auto &LI : LabelInfoStack) {
7088 if (LI.Name == TargetLoop) {
7089 TargetLabel = *LI.BreakLabel;
7090 BreakScope = LI.BreakOrContinueScope;
7091 break;
7092 }
7093 }
7094 }
7095
7096 // Faulty break statement (e.g. label redefined or named loops disabled).
7097 if (!TargetLabel)
7098 return false;
7099
7100 for (VariableScope<Emitter> *C = this->VarScope; C != BreakScope;
7101 C = C->getParent()) {
7102 if (!C->destroyLocals())
7103 return false;
7104 }
7105
7106 return this->jump(*TargetLabel, S);
7107}
7108
7109template <class Emitter>
7111 if (LabelInfoStack.empty())
7112 return false;
7113
7114 OptLabelTy TargetLabel = std::nullopt;
7115 const Stmt *TargetLoop = S->getNamedLoopOrSwitch();
7116 const VariableScope<Emitter> *ContinueScope = nullptr;
7117
7118 if (!TargetLoop) {
7119 for (const auto &LI : llvm::reverse(LabelInfoStack)) {
7120 if (LI.ContinueLabel) {
7121 TargetLabel = *LI.ContinueLabel;
7122 ContinueScope = LI.BreakOrContinueScope;
7123 break;
7124 }
7125 }
7126 } else {
7127 for (auto LI : LabelInfoStack) {
7128 if (LI.Name == TargetLoop) {
7129 TargetLabel = *LI.ContinueLabel;
7130 ContinueScope = LI.BreakOrContinueScope;
7131 break;
7132 }
7133 }
7134 }
7135
7136 if (!TargetLabel)
7137 return false;
7138
7139 for (VariableScope<Emitter> *C = VarScope; C != ContinueScope;
7140 C = C->getParent()) {
7141 if (!C->destroyLocals())
7142 return false;
7143 }
7144
7145 return this->jump(*TargetLabel, S);
7146}
7147
7148template <class Emitter>
7150 const Expr *Cond = S->getCond();
7151 if (Cond->containsErrors())
7152 return false;
7153
7154 PrimType CondT = this->classifyPrim(Cond->getType());
7155 LocalScope<Emitter> LS(this);
7156 llvm::SaveAndRestore StmtExprSAR(this->SwitchInStmtExpr, this->InStmtExpr);
7157
7158 LabelTy EndLabel = this->getLabel();
7159 UnsignedOrNone DefaultLabel = std::nullopt;
7160 unsigned CondVar =
7161 this->allocateLocalPrimitive(Cond, CondT, /*IsConst=*/true);
7162
7163 if (const auto *CondInit = S->getInit())
7164 if (!visitStmt(CondInit))
7165 return false;
7166
7167 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
7168 if (!visitDeclStmt(CondDecl))
7169 return false;
7170
7171 // Initialize condition variable.
7172 if (!this->visit(Cond))
7173 return false;
7174 if (!this->emitSetLocal(CondT, CondVar, S))
7175 return false;
7176
7177 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
7178 return false;
7179
7181 // Create labels and comparison ops for all case statements.
7182 for (const SwitchCase *SC = S->getSwitchCaseList(); SC;
7183 SC = SC->getNextSwitchCase()) {
7184 if (const auto *CS = dyn_cast<CaseStmt>(SC)) {
7185 CaseLabels[SC] = this->getLabel();
7186
7187 if (CS->caseStmtIsGNURange()) {
7188 LabelTy EndOfRangeCheck = this->getLabel();
7189 const Expr *Low = CS->getLHS();
7190 const Expr *High = CS->getRHS();
7191 if (Low->isValueDependent() || High->isValueDependent())
7192 return false;
7193
7194 if (!this->emitGetLocal(CondT, CondVar, CS))
7195 return false;
7196 if (!this->visit(Low))
7197 return false;
7198 PrimType LT = this->classifyPrim(Low->getType());
7199 if (!this->emitGE(LT, S))
7200 return false;
7201 if (!this->jumpFalse(EndOfRangeCheck, S))
7202 return false;
7203
7204 if (!this->emitGetLocal(CondT, CondVar, CS))
7205 return false;
7206 if (!this->visit(High))
7207 return false;
7208 PrimType HT = this->classifyPrim(High->getType());
7209 if (!this->emitLE(HT, S))
7210 return false;
7211 if (!this->jumpTrue(CaseLabels[CS], S))
7212 return false;
7213 this->emitLabel(EndOfRangeCheck);
7214 continue;
7215 }
7216
7217 const Expr *Value = CS->getLHS();
7218 if (Value->isValueDependent())
7219 return false;
7220 PrimType ValueT = this->classifyPrim(Value->getType());
7221
7222 // Compare the case statement's value to the switch condition.
7223 if (!this->emitGetLocal(CondT, CondVar, CS))
7224 return false;
7225 if (!this->visit(Value))
7226 return false;
7227
7228 // Compare and jump to the case label.
7229 if (!this->emitEQ(ValueT, S))
7230 return false;
7231 if (!this->jumpTrue(CaseLabels[CS], S))
7232 return false;
7233 } else {
7234 assert(!DefaultLabel);
7235 DefaultLabel = this->getLabel();
7236 }
7237 }
7238
7239 // If none of the conditions above were true, fall through to the default
7240 // statement or jump after the switch statement.
7241 if (DefaultLabel) {
7242 if (!this->jump(*DefaultLabel, S))
7243 return false;
7244 } else {
7245 if (!this->jump(EndLabel, S))
7246 return false;
7247 }
7248
7249 SwitchScope<Emitter> SS(this, S, std::move(CaseLabels), EndLabel,
7250 DefaultLabel);
7251 if (!this->visitStmt(S->getBody()))
7252 return false;
7253 this->fallthrough(EndLabel);
7254 this->emitLabel(EndLabel);
7255
7256 return LS.destroyLocals();
7257}
7258
7259template <class Emitter>
7261 this->fallthrough(CaseLabels[S]);
7262 this->emitLabel(CaseLabels[S]);
7263
7264 // We can't jump from an outer switch statement to a case label
7265 // that's inside a StmtExpr.
7266 if (this->InStmtExpr && !this->SwitchInStmtExpr)
7267 return this->emitUnsupported(S);
7268
7269 return this->visitStmt(S->getSubStmt());
7270}
7271
7272template <class Emitter>
7274 if (LabelInfoStack.empty())
7275 return false;
7276
7277 LabelTy DefaultLabel;
7278 for (const LabelInfo &LI : llvm::reverse(LabelInfoStack)) {
7279 if (LI.DefaultLabel) {
7280 DefaultLabel = *LI.DefaultLabel;
7281 break;
7282 }
7283 }
7284
7285 this->emitLabel(DefaultLabel);
7286 return this->visitStmt(S->getSubStmt());
7287}
7288
7289template <class Emitter>
7291 const Stmt *SubStmt = S->getSubStmt();
7292
7293 bool IsMSVCConstexprAttr = isa<ReturnStmt>(SubStmt) &&
7295
7296 if (IsMSVCConstexprAttr && !this->emitPushMSVCCE(S))
7297 return false;
7298
7299 if (this->Ctx.getLangOpts().CXXAssumptions &&
7300 !this->Ctx.getLangOpts().MSVCCompat) {
7301 for (const Attr *A : S->getAttrs()) {
7302 auto *AA = dyn_cast<CXXAssumeAttr>(A);
7303 if (!AA)
7304 continue;
7305
7306 assert(isa<NullStmt>(SubStmt));
7307
7308 const Expr *Assumption = AA->getAssumption();
7309 if (Assumption->isValueDependent())
7310 return false;
7311
7312 if (Assumption->HasSideEffects(this->Ctx.getASTContext()))
7313 continue;
7314
7315 // Evaluate assumption.
7316 if (!this->visitBool(Assumption))
7317 return false;
7318
7319 if (!this->emitAssume(Assumption))
7320 return false;
7321 }
7322 }
7323
7324 // Ignore other attributes.
7325 if (!this->visitStmt(SubStmt))
7326 return false;
7327
7328 if (IsMSVCConstexprAttr)
7329 return this->emitPopMSVCCE(S);
7330 return true;
7331}
7332
7333template <class Emitter>
7335 // Ignore all handlers.
7336 return this->visitStmt(S->getTryBlock());
7337}
7338
7339/// template for (auto x : {1, 2}) {}
7340///
7341/// This is not a loop from an AST perspective at all since it has already
7342/// been instantiated to a list of compound statements.
7343///
7344/// Since we can have control flow in those compound statements, we need to
7345/// handle it mostly like a loop though.
7346template <class Emitter>
7349 LocalScope<Emitter> WholeLoopScope(this, ScopeKind::Block);
7350
7351 for (const Stmt *PreambleStmt : S->getPreambleStmts()) {
7352 if (!this->visitDeclStmt(cast<DeclStmt>(PreambleStmt), true))
7353 return false;
7354 }
7355
7356 LabelTy EndLabel = this->getLabel();
7357 for (const Stmt *Instantiation : S->getInstantiations()) {
7358 LabelTy ContinueLabel = this->getLabel();
7359 LoopScope<Emitter> LS(this, S, EndLabel, ContinueLabel);
7360
7361 if (!this->visitStmt(Instantiation))
7362 return false;
7363 this->emitLabel(ContinueLabel);
7364 }
7365
7366 this->emitLabel(EndLabel);
7367
7368 return WholeLoopScope.destroyLocals();
7369}
7370
7371template <class Emitter>
7372bool Compiler<Emitter>::emitLambdaStaticInvokerBody(const CXXMethodDecl *MD) {
7373 assert(MD->isLambdaStaticInvoker());
7374 assert(MD->hasBody());
7375 assert(cast<CompoundStmt>(MD->getBody())->body_empty());
7376
7377 const CXXRecordDecl *ClosureClass = MD->getParent();
7378 const FunctionDecl *LambdaCallOp;
7379 assert(ClosureClass->captures().empty());
7380 if (ClosureClass->isGenericLambda()) {
7381 LambdaCallOp = ClosureClass->getLambdaCallOperator();
7382 assert(MD->isFunctionTemplateSpecialization() &&
7383 "A generic lambda's static-invoker function must be a "
7384 "template specialization");
7386 FunctionTemplateDecl *CallOpTemplate =
7387 LambdaCallOp->getDescribedFunctionTemplate();
7388 llvm::FoldingSetInsertToken InsertToken;
7389 const FunctionDecl *CorrespondingCallOpSpecialization =
7390 CallOpTemplate->findSpecialization(TAL->asArray(), InsertToken);
7391 assert(CorrespondingCallOpSpecialization);
7392 LambdaCallOp = CorrespondingCallOpSpecialization;
7393 } else {
7394 LambdaCallOp = ClosureClass->getLambdaCallOperator();
7395 }
7396 assert(ClosureClass->captures().empty());
7397 const Function *Func = this->getFunction(LambdaCallOp);
7398 if (!Func)
7399 return false;
7400 assert(Func->hasThisPointer());
7401 assert(Func->getNumParams() == (MD->getNumParams() + 1 + Func->hasRVO()));
7402
7403 if (Func->hasRVO()) {
7404 if (!this->emitRVOPtr(MD))
7405 return false;
7406 }
7407
7408 // The lambda call operator needs an instance pointer, but we don't have
7409 // one here, and we don't need one either because the lambda cannot have
7410 // any captures, as verified above. Emit a null pointer. This is then
7411 // special-cased when interpreting to not emit any misleading diagnostics.
7412 if (!this->emitNullPtr(0, nullptr, MD))
7413 return false;
7414
7415 // Forward all arguments from the static invoker to the lambda call operator.
7416 for (const ParmVarDecl *PVD : MD->parameters()) {
7417 auto It = this->Params.find(PVD);
7418 assert(It != this->Params.end());
7419
7420 // We do the lvalue-to-rvalue conversion manually here, so no need
7421 // to care about references.
7422 PrimType ParamType = this->classify(PVD->getType()).value_or(PT_Ptr);
7423 if (!this->emitGetParam(ParamType, It->second.Index, MD))
7424 return false;
7425 }
7426
7427 if (!this->emitCall(Func, 0, LambdaCallOp))
7428 return false;
7429
7430 this->emitCleanup();
7431 if (ReturnType)
7432 return this->emitRet(*ReturnType, MD);
7433
7434 // Nothing to do, since we emitted the RVO pointer above.
7435 return this->emitRetVoid(MD);
7436}
7437
7438template <class Emitter>
7439bool Compiler<Emitter>::checkLiteralType(const Expr *E) {
7440 if (Ctx.getLangOpts().CPlusPlus23)
7441 return true;
7442
7443 if (!E->isPRValue() || E->getType()->isLiteralType(Ctx.getASTContext()))
7444 return true;
7445
7446 return this->emitCheckLiteralType(E->getType().getTypePtr(), E);
7447}
7448
7450 const Expr *InitExpr = Init->getInit();
7451
7452 if (!Init->isWritten() && !Init->isInClassMemberInitializer() &&
7453 !isa<CXXConstructExpr>(InitExpr))
7454 return true;
7455
7456 if (const auto *CE = dyn_cast<CXXConstructExpr>(InitExpr)) {
7457 const CXXConstructorDecl *Ctor = CE->getConstructor();
7458 if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&
7459 Ctor->isTrivial())
7460 return true;
7461 }
7462
7463 return false;
7464}
7465
7466template <class Emitter>
7467bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
7468 assert(!ReturnType);
7469
7470 // Only start the lifetime of the instance pointer.
7471 if (!this->emitStartThisLifetime1(Ctor))
7472 return false;
7473
7474 auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
7475 const Expr *InitExpr,
7476 bool Activate = false) -> bool {
7477 // We don't know what to do with these, so just return false.
7478 if (InitExpr->getType().isNull())
7479 return false;
7480
7481 if (OptPrimType T = this->classify(InitExpr)) {
7482 if (Activate && !this->emitActivateThisField(FieldOffset, InitExpr))
7483 return false;
7484
7485 if (!this->visit(InitExpr))
7486 return false;
7487
7488 if (F->isBitField())
7489 return this->emitInitThisBitField(*T, FieldOffset, F->bitWidth(),
7490 InitExpr);
7491 return this->emitInitThisField(*T, FieldOffset, InitExpr);
7492 }
7493 // Non-primitive case. Get a pointer to the field-to-initialize
7494 // on the stack and call visitInitialzer() for it.
7495 InitLinkScope<Emitter> FieldScope(this, InitLink::Field(F->Offset));
7496 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
7497 return false;
7498
7499 if (Activate && !this->emitActivate(InitExpr))
7500 return false;
7501
7502 return this->visitInitializerPop(InitExpr);
7503 };
7504
7505 const RecordDecl *RD = Ctor->getParent();
7506 const Record *R = this->getRecord(RD);
7507 if (!R)
7508 return false;
7509 bool IsUnion = R->isUnion();
7510
7511 // Default union copy and move ctors are special.
7512 if (IsUnion && Ctor->isCopyOrMoveConstructor() && Ctor->isDefaulted()) {
7514
7515 // No special case for NumFields == 0 here, so the Memcpy op
7516 // below also does its checks in those cases.
7517
7518 assert(cast<CompoundStmt>(Ctor->getBody())->body_empty());
7519 if (!this->emitThis(Ctor))
7520 return false;
7521
7522 if (!this->emitGetParam(PT_Ptr, /*ParamIndex=*/0, Ctor))
7523 return false;
7524
7525 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
7526 this->emitRetVoid(Ctor);
7527 }
7528
7529 unsigned FieldInits = 0;
7531 // First, initialize virtual bases if the records has them.
7532 if (R->getNumVirtualBases() > 0) {
7533 if (!this->emitThis(Ctor))
7534 return false;
7535 LabelTy AfterVirtBasesLabel = this->getLabel();
7536
7537 // If the instance pointer is a base class, skip the virtual bases.
7538 if (!this->emitIsBaseClass({}))
7539 return false;
7540 if (!this->jumpTrue(AfterVirtBasesLabel, {}))
7541 return false;
7542
7543 for (const auto *Init : Ctor->inits()) {
7544 if (const Type *Base = Init->getBaseClass();
7545 Base && Init->isBaseVirtual()) {
7546 const auto *BaseDecl = Base->getAsCXXRecordDecl();
7547 assert(BaseDecl);
7548 assert(R->findVirtualBase(BaseDecl));
7549 if (!this->emitGetPtrThisVirtBase(BaseDecl, Ctor))
7550 return false;
7551 if (!this->visitInitializerPop(Init->getInit()))
7552 return false;
7553 }
7554 }
7555
7556 this->fallthrough(AfterVirtBasesLabel);
7557 this->emitLabel(AfterVirtBasesLabel);
7558
7559 if (!this->emitPopPtr(Ctor))
7560 return false;
7561 }
7562
7563 for (const auto *Init : Ctor->inits()) {
7564 // Scope needed for the initializers.
7565 LocalScope<Emitter> Scope(this, ScopeKind::FullExpression);
7566
7567 const Expr *InitExpr = Init->getInit();
7568 if (const FieldDecl *Member = Init->getMember()) {
7569 const Record::Field *F = R->getField(Member);
7570
7573 if (!emitFieldInitializer(F, F->Offset, InitExpr, IsUnion))
7574 return false;
7575 ++FieldInits;
7576 } else if (const Type *Base = Init->getBaseClass()) {
7577 const auto *BaseDecl = Base->getAsCXXRecordDecl();
7578 assert(BaseDecl);
7579
7580 if (Init->isBaseVirtual()) {
7581 // See above.
7582 continue;
7583 } else {
7584 // Base class initializer.
7585 // Get This Base and call initializer on it.
7586 const Record::Base *B = R->getBase(BaseDecl);
7587 assert(B);
7588 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
7589 return false;
7590 }
7591
7592 if (!this->visitInitializerPop(InitExpr))
7593 return false;
7594 } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {
7597 unsigned ChainSize = IFD->getChainingSize();
7598 assert(ChainSize >= 2);
7599
7600 unsigned NestedFieldOffset = 0;
7601 const Record::Field *NestedField = nullptr;
7602 for (unsigned I = 0; I != ChainSize; ++I) {
7603 const auto *FD = cast<FieldDecl>(IFD->chain()[I]);
7604 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
7605 assert(FieldRecord);
7606
7607 NestedField = FieldRecord->getField(FD);
7608 assert(NestedField);
7609 IsUnion = IsUnion || FieldRecord->isUnion();
7610
7611 NestedFieldOffset += NestedField->Offset;
7612
7613 // Add a new InitChainLink for the record, but not for the final field.
7614 if (I != ChainSize - 1)
7615 InitStack.push_back(InitLink::Field(NestedField->Offset));
7616 }
7617 assert(NestedField);
7618
7620 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
7621 IsUnion))
7622 return false;
7623
7624 // Mark all chain links as initialized.
7625 unsigned InitFieldOffset = 0;
7626 for (const NamedDecl *ND : IFD->chain().drop_back()) {
7627 const auto *FD = cast<FieldDecl>(ND);
7628 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
7629 assert(FieldRecord);
7630 NestedField = FieldRecord->getField(FD);
7631 InitFieldOffset += NestedField->Offset;
7632 assert(NestedField);
7633 if (!this->emitGetPtrThisField(InitFieldOffset, InitExpr))
7634 return false;
7635 if (!this->emitFinishInitPop(InitExpr))
7636 return false;
7637 }
7638
7639 InitStack.pop_back_n(ChainSize - 1);
7640
7641 } else {
7642 assert(Init->isDelegatingInitializer());
7643 if (!this->emitThis(InitExpr))
7644 return false;
7645 if (!this->visitInitializerPop(Init->getInit()))
7646 return false;
7647 }
7648
7649 if (!Scope.destroyLocals())
7650 return false;
7651 }
7652
7653 if (FieldInits != R->getNumFields()) {
7654 assert(FieldInits < R->getNumFields());
7655 // Start the lifetime of all members.
7656 if (!this->emitStartThisLifetime(Ctor))
7657 return false;
7658 }
7659
7660 if (const Stmt *Body = Ctor->getBody()) {
7661 // Only emit the CtorCheck op for non-empty CompoundStmt bodies.
7662 // For non-CompoundStmts, always assume they are non-empty and emit it.
7663 if (const auto *CS = dyn_cast<CompoundStmt>(Body)) {
7664 if (!CS->body_empty() && !this->emitCtorCheck(SourceInfo{}))
7665 return false;
7666 } else {
7667 if (!this->emitCtorCheck(SourceInfo{}))
7668 return false;
7669 }
7670
7671 if (!visitStmt(Body))
7672 return false;
7673 }
7674
7675 return this->emitRetVoid(SourceInfo{});
7676}
7677
7678template <class Emitter>
7679bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) {
7680 const RecordDecl *RD = Dtor->getParent();
7681 const Record *R = this->getRecord(RD);
7682 if (!R)
7683 return false;
7684
7685 if (!Dtor->isTrivial() && Dtor->getBody()) {
7686 if (!this->visitStmt(Dtor->getBody()))
7687 return false;
7688 }
7689
7690 if (!this->emitThis(Dtor))
7691 return false;
7692
7693 if (!this->emitCheckDestruction(Dtor))
7694 return false;
7695
7696 assert(R);
7697 if (!R->isUnion()) {
7698
7700 // First, destroy all fields.
7701 for (const Record::Field &Field : llvm::reverse(R->fields())) {
7702 const Descriptor *D = Field.Desc;
7703 if (D->hasTrivialDtor())
7704 continue;
7705 if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
7706 return false;
7707 if (!this->emitDestructionPop(D, SourceInfo{}))
7708 return false;
7709 }
7710 }
7711
7712 for (const Record::Base &Base : llvm::reverse(R->bases())) {
7713 if (Base.R->hasTrivialDtor())
7714 continue;
7715 if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
7716 return false;
7717 if (!this->emitRecordDestructionPop(Base.R, {}))
7718 return false;
7719 }
7720
7721 if (R->getNumVirtualBases() > 0) {
7722 LabelTy EndLabel = this->getLabel();
7723 // If this is a base class, skip the virtual bases.
7724 if (!this->emitIsBaseClass({}))
7725 return false;
7726 if (!this->jumpTrue(EndLabel, {}))
7727 return false;
7728
7729 for (const Record::Base &Base : llvm::reverse(R->virtual_bases())) {
7730 if (Base.R->hasTrivialDtor())
7731 continue;
7732 if (!this->emitGetPtrVirtBase(cast<CXXRecordDecl>(Base.R->getDecl()),
7733 SourceInfo{}))
7734 return false;
7735 if (!this->emitRecordDestructionPop(Base.R, {}))
7736 return false;
7737 }
7738
7739 this->fallthrough(EndLabel);
7740 this->emitLabel(EndLabel);
7741 }
7742
7743 if (!this->emitMarkDestroyed(Dtor))
7744 return false;
7745
7746 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
7747}
7748
7749template <class Emitter>
7750bool Compiler<Emitter>::compileUnionAssignmentOperator(
7751 const CXXMethodDecl *MD) {
7752 if (!this->emitThis(MD))
7753 return false;
7754
7755 if (!this->emitGetParam(PT_Ptr, /*ParamIndex=*/0, MD))
7756 return false;
7757
7758 return this->emitMemcpy(MD) && this->emitRet(PT_Ptr, MD);
7759}
7760
7761template <class Emitter>
7763 if (F->getReturnType()->isDependentType())
7764 return false;
7765
7766 // Classify the return type.
7767 ReturnType = this->classify(F->getReturnType());
7768
7769 this->CompilingFunction = F;
7770
7771 if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
7772 return this->compileConstructor(Ctor);
7773 if (const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
7774 return this->compileDestructor(Dtor);
7775
7776 // Emit custom code if this is a lambda static invoker.
7777 if (const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
7778 const RecordDecl *RD = MD->getParent();
7779
7780 if (RD->isUnion() &&
7782 return this->compileUnionAssignmentOperator(MD);
7783
7784 if (MD->isLambdaStaticInvoker())
7785 return this->emitLambdaStaticInvokerBody(MD);
7786 }
7787
7788 // Regular functions.
7789 if (const auto *Body = F->getBody())
7790 if (!visitStmt(Body))
7791 return false;
7792
7793 // Emit a guard return to protect against a code path missing one.
7794 if (F->getReturnType()->isVoidType())
7795 return this->emitRetVoid(SourceInfo{});
7796 return this->emitNoRet(SourceInfo{});
7797}
7798
7799static uint32_t getBitWidth(const Expr *E) {
7800 assert(E->refersToBitField());
7801 const auto *ME = cast<MemberExpr>(E);
7802 const auto *FD = cast<FieldDecl>(ME->getMemberDecl());
7803 return FD->getBitWidthValue();
7804}
7805
7806template <class Emitter>
7808 if (E->containsErrors())
7809 return false;
7810
7811 const Expr *SubExpr = E->getSubExpr();
7812 if (SubExpr->getType()->isAnyComplexType())
7813 return this->VisitComplexUnaryOperator(E);
7814 if (SubExpr->getType()->isVectorType())
7815 return this->VisitVectorUnaryOperator(E);
7816 if (SubExpr->getType()->isFixedPointType())
7817 return this->VisitFixedPointUnaryOperator(E);
7818 OptPrimType T = classify(SubExpr->getType());
7819
7820 switch (E->getOpcode()) {
7821 case UO_PostInc: { // x++
7822 if (!Ctx.getLangOpts().CPlusPlus14)
7823 return this->emitInvalid(E);
7824 if (!T)
7825 return this->emitError(E);
7826
7827 if (!this->visit(SubExpr))
7828 return false;
7829
7830 if (T == PT_Ptr) {
7831 if (!this->emitIncPtr(E))
7832 return false;
7833
7834 return DiscardResult ? this->emitPopPtr(E) : true;
7835 }
7836
7837 if (T == PT_Float)
7838 return DiscardResult ? this->emitIncfPop(getFPOptions(E), E)
7839 : this->emitIncf(getFPOptions(E), E);
7840
7841 if (SubExpr->refersToBitField())
7842 return DiscardResult ? this->emitIncPopBitfield(*T, E->canOverflow(),
7843 getBitWidth(SubExpr), E)
7844 : this->emitIncBitfield(*T, E->canOverflow(),
7845 getBitWidth(SubExpr), E);
7846
7847 return DiscardResult ? this->emitIncPop(*T, E->canOverflow(), E)
7848 : this->emitInc(*T, E->canOverflow(), E);
7849 }
7850 case UO_PostDec: { // x--
7851 if (!Ctx.getLangOpts().CPlusPlus14)
7852 return this->emitInvalid(E);
7853 if (!T)
7854 return this->emitError(E);
7855
7856 if (!this->visit(SubExpr))
7857 return false;
7858
7859 if (T == PT_Ptr) {
7860 if (!this->emitDecPtr(E))
7861 return false;
7862
7863 return DiscardResult ? this->emitPopPtr(E) : true;
7864 }
7865
7866 if (T == PT_Float)
7867 return DiscardResult ? this->emitDecfPop(getFPOptions(E), E)
7868 : this->emitDecf(getFPOptions(E), E);
7869
7870 if (SubExpr->refersToBitField()) {
7871 return DiscardResult ? this->emitDecPopBitfield(*T, E->canOverflow(),
7872 getBitWidth(SubExpr), E)
7873 : this->emitDecBitfield(*T, E->canOverflow(),
7874 getBitWidth(SubExpr), E);
7875 }
7876
7877 return DiscardResult ? this->emitDecPop(*T, E->canOverflow(), E)
7878 : this->emitDec(*T, E->canOverflow(), E);
7879 }
7880 case UO_PreInc: { // ++x
7881 if (!Ctx.getLangOpts().CPlusPlus14)
7882 return this->emitInvalid(E);
7883 if (!T)
7884 return this->emitError(E);
7885
7886 if (!this->visit(SubExpr))
7887 return false;
7888
7889 if (T == PT_Ptr) {
7890 if (!this->emitLoadPtr(E))
7891 return false;
7892 if (!this->emitConstUint8(1, E))
7893 return false;
7894 if (!this->emitAddOffsetUint8(E))
7895 return false;
7896 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7897 }
7898
7899 // Post-inc and pre-inc are the same if the value is to be discarded.
7900 if (DiscardResult) {
7901 if (T == PT_Float)
7902 return this->emitIncfPop(getFPOptions(E), E);
7903 if (SubExpr->refersToBitField())
7904 return DiscardResult ? this->emitIncPopBitfield(*T, E->canOverflow(),
7905 getBitWidth(SubExpr), E)
7906 : this->emitIncBitfield(*T, E->canOverflow(),
7907 getBitWidth(SubExpr), E);
7908 return this->emitIncPop(*T, E->canOverflow(), E);
7909 }
7910
7911 if (T == PT_Float) {
7912 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
7913 if (!this->emitLoadFloat(E))
7914 return false;
7915 APFloat F(TargetSemantics, 1);
7916 if (!this->emitFloat(F, E))
7917 return false;
7918
7919 if (!this->emitAddf(getFPOptions(E), E))
7920 return false;
7921 if (!this->emitStoreFloat(E))
7922 return false;
7923 } else if (SubExpr->refersToBitField()) {
7924 assert(isIntegerOrBoolType(*T));
7925 if (!this->emitPreIncBitfield(*T, E->canOverflow(), getBitWidth(SubExpr),
7926 E))
7927 return false;
7928 } else {
7929 assert(isIntegerOrBoolType(*T));
7930 if (!this->emitPreInc(*T, E->canOverflow(), E))
7931 return false;
7932 }
7933 return E->isGLValue() || this->emitLoadPop(*T, E);
7934 }
7935 case UO_PreDec: { // --x
7936 if (!Ctx.getLangOpts().CPlusPlus14)
7937 return this->emitInvalid(E);
7938 if (!T)
7939 return this->emitError(E);
7940
7941 if (!this->visit(SubExpr))
7942 return false;
7943
7944 if (T == PT_Ptr) {
7945 if (!this->emitLoadPtr(E))
7946 return false;
7947 if (!this->emitConstUint8(1, E))
7948 return false;
7949 if (!this->emitSubOffsetUint8(E))
7950 return false;
7951 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7952 }
7953
7954 // Post-dec and pre-dec are the same if the value is to be discarded.
7955 if (DiscardResult) {
7956 if (T == PT_Float)
7957 return this->emitDecfPop(getFPOptions(E), E);
7958 if (SubExpr->refersToBitField())
7959 return DiscardResult ? this->emitDecPopBitfield(*T, E->canOverflow(),
7960 getBitWidth(SubExpr), E)
7961 : this->emitDecBitfield(*T, E->canOverflow(),
7962 getBitWidth(SubExpr), E);
7963 return this->emitDecPop(*T, E->canOverflow(), E);
7964 }
7965
7966 if (T == PT_Float) {
7967 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
7968 if (!this->emitLoadFloat(E))
7969 return false;
7970 APFloat F(TargetSemantics, 1);
7971 if (!this->emitFloat(F, E))
7972 return false;
7973
7974 if (!this->emitSubf(getFPOptions(E), E))
7975 return false;
7976 if (!this->emitStoreFloat(E))
7977 return false;
7978 } else if (SubExpr->refersToBitField()) {
7979 assert(isIntegerOrBoolType(*T));
7980 if (!this->emitPreDecBitfield(*T, E->canOverflow(), getBitWidth(SubExpr),
7981 E))
7982 return false;
7983 } else {
7984 assert(isIntegerOrBoolType(*T));
7985 if (!this->emitPreDec(*T, E->canOverflow(), E))
7986 return false;
7987 }
7988 return E->isGLValue() || this->emitLoadPop(*T, E);
7989 }
7990 case UO_LNot: // !x
7991 if (!T)
7992 return this->emitError(E);
7993
7994 if (DiscardResult)
7995 return this->discard(SubExpr);
7996
7997 if (!this->visitBool(SubExpr))
7998 return false;
7999
8000 if (!this->emitInv(E))
8001 return false;
8002
8003 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
8004 return this->emitCast(PT_Bool, ET, E);
8005 return true;
8006 case UO_Minus: // -x
8007 if (!T)
8008 return this->emitError(E);
8009
8010 if (!this->visit(SubExpr))
8011 return false;
8012 return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
8013 case UO_Plus: // +x
8014 if (!T)
8015 return this->emitError(E);
8016
8017 if (!this->visit(SubExpr)) // noop
8018 return false;
8019 return DiscardResult ? this->emitPop(*T, E) : true;
8020 case UO_AddrOf: // &x
8021 if (E->getType()->isMemberPointerType()) {
8022 // C++11 [expr.unary.op]p3 has very strict rules on how the address of a
8023 // member can be formed.
8024 if (DiscardResult)
8025 return true;
8026 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(), E);
8027 }
8028 // [C11 6.5.3.2p3]: if the operand of '&' is the result of a unary '*'
8029 // operator, neither operator is evaluated and the result is as if both
8030 // were omitted. So '&*q' is just 'q' with no dereference; delegate to the
8031 // pointer operand directly instead of to the '*' (which would emit a null
8032 // check), so that e.g. '&*(int *)0' is not rejected.
8033 if (!Ctx.getLangOpts().CPlusPlus) {
8034 const Expr *Sub = SubExpr->IgnoreParens();
8035
8036 if (const auto *Deref = dyn_cast<UnaryOperator>(Sub);
8037 Deref && Deref->getOpcode() == UO_Deref) {
8038 if (DiscardResult)
8039 return this->discard(Deref->getSubExpr());
8040 return this->visit(Deref->getSubExpr()) && this->emitAddrOf(E);
8041 }
8042 }
8043 // We should already have a pointer when we get here.
8044 if (DiscardResult)
8045 return this->discard(SubExpr);
8046 return this->delegate(SubExpr) && this->emitAddrOf(E);
8047 case UO_Deref: // *x
8048 if (DiscardResult)
8049 return this->discard(SubExpr);
8050
8051 if (!this->visit(SubExpr))
8052 return false;
8053
8054 if (!SubExpr->getType()->isFunctionPointerType() && !this->emitCheckNull(E))
8055 return false;
8056
8057 if (classifyPrim(SubExpr) == PT_Ptr)
8058 return this->emitNarrowPtr(E);
8059 return true;
8060
8061 case UO_Not: // ~x
8062 if (!T)
8063 return this->emitError(E);
8064
8065 if (!this->visit(SubExpr))
8066 return false;
8067 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
8068 case UO_Real: // __real x
8069 if (!T)
8070 return false;
8071 return this->delegate(SubExpr);
8072 case UO_Imag: { // __imag x
8073 if (!T)
8074 return false;
8075 if (!this->discard(SubExpr))
8076 return false;
8077 return DiscardResult
8078 ? true
8079 : this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);
8080 }
8081 case UO_Extension:
8082 return this->delegate(SubExpr);
8083 case UO_Coawait:
8084 assert(false && "Unhandled opcode");
8085 }
8086
8087 return false;
8088}
8089
8090template <class Emitter>
8092 const Expr *SubExpr = E->getSubExpr();
8093 assert(SubExpr->getType()->isAnyComplexType());
8094
8095 if (DiscardResult)
8096 return this->discard(SubExpr);
8097
8098 OptPrimType ResT = classify(E);
8099 auto prepareResult = [=]() -> bool {
8100 if (!ResT && !Initializing) {
8101 UnsignedOrNone LocalIndex = allocateLocal(SubExpr);
8102 if (!LocalIndex)
8103 return false;
8104 return this->emitGetPtrLocal(*LocalIndex, E);
8105 }
8106
8107 return true;
8108 };
8109
8110 // The offset of the temporary, if we created one.
8111 unsigned SubExprOffset = ~0u;
8112 auto createTemp = [=, &SubExprOffset]() -> bool {
8113 SubExprOffset =
8114 this->allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
8115 if (!this->visit(SubExpr))
8116 return false;
8117 return this->emitSetLocal(PT_Ptr, SubExprOffset, E);
8118 };
8119
8120 PrimType ElemT = classifyComplexElementType(SubExpr->getType());
8121 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
8122 if (!this->emitGetLocal(PT_Ptr, Offset, E))
8123 return false;
8124 return this->emitArrayElemPop(ElemT, Index, E);
8125 };
8126
8127 switch (E->getOpcode()) {
8128 case UO_Minus: // -x
8129 if (!prepareResult())
8130 return false;
8131 if (!createTemp())
8132 return false;
8133 for (unsigned I = 0; I != 2; ++I) {
8134 if (!getElem(SubExprOffset, I))
8135 return false;
8136 if (!this->emitNeg(ElemT, E))
8137 return false;
8138 if (!this->emitInitElem(ElemT, I, E))
8139 return false;
8140 }
8141 break;
8142
8143 case UO_Plus: // +x
8144 case UO_AddrOf: // &x
8145 case UO_Deref: // *x
8146 return this->delegate(SubExpr);
8147
8148 case UO_LNot:
8149 if (!this->visit(SubExpr))
8150 return false;
8151 if (!this->emitComplexBoolCast(SubExpr))
8152 return false;
8153 if (!this->emitInv(E))
8154 return false;
8155 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
8156 return this->emitCast(PT_Bool, ET, E);
8157 return true;
8158
8159 case UO_Real:
8160 return this->emitComplexReal(SubExpr);
8161
8162 case UO_Imag:
8163 if (!this->visit(SubExpr))
8164 return false;
8165
8166 if (SubExpr->isLValue()) {
8167 if (!this->emitConstUint8(1, E))
8168 return false;
8169 return this->emitArrayElemPtrPopUint8(E);
8170 }
8171
8172 // Since our _Complex implementation does not map to a primitive type,
8173 // we sometimes have to do the lvalue-to-rvalue conversion here manually.
8174 return this->emitArrayElemPop(classifyPrim(E->getType()), 1, E);
8175
8176 case UO_Not: // ~x
8177 if (!this->delegate(SubExpr))
8178 return false;
8179 // Negate the imaginary component.
8180 if (!this->emitArrayElem(ElemT, 1, E))
8181 return false;
8182 if (!this->emitNeg(ElemT, E))
8183 return false;
8184 if (!this->emitInitElem(ElemT, 1, E))
8185 return false;
8186 return DiscardResult ? this->emitPopPtr(E) : true;
8187
8188 case UO_Extension:
8189 return this->delegate(SubExpr);
8190
8191 default:
8192 return this->emitInvalid(E);
8193 }
8194
8195 return true;
8196}
8197
8198template <class Emitter>
8200 const Expr *SubExpr = E->getSubExpr();
8201 assert(SubExpr->getType()->isVectorType());
8202
8203 if (DiscardResult)
8204 return this->discard(SubExpr);
8205
8206 auto UnaryOp = E->getOpcode();
8207 if (UnaryOp == UO_Extension)
8208 return this->delegate(SubExpr);
8209
8210 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
8211 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
8212 return this->emitInvalid(E);
8213
8214 // Nothing to do here.
8215 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
8216 return this->delegate(SubExpr);
8217
8218 if (!Initializing) {
8219 UnsignedOrNone LocalIndex = allocateLocal(SubExpr);
8220 if (!LocalIndex)
8221 return false;
8222 if (!this->emitGetPtrLocal(*LocalIndex, E))
8223 return false;
8224 }
8225
8226 // The offset of the temporary, if we created one.
8227 unsigned SubExprOffset =
8228 this->allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
8229 if (!this->visit(SubExpr))
8230 return false;
8231 if (!this->emitSetLocal(PT_Ptr, SubExprOffset, E))
8232 return false;
8233
8234 const auto *VecTy = SubExpr->getType()->getAs<VectorType>();
8235 PrimType ElemT = classifyVectorElementType(SubExpr->getType());
8236 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
8237 if (!this->emitGetLocal(PT_Ptr, Offset, E))
8238 return false;
8239 return this->emitArrayElemPop(ElemT, Index, E);
8240 };
8241
8242 switch (UnaryOp) {
8243 case UO_Minus:
8244 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8245 if (!getElem(SubExprOffset, I))
8246 return false;
8247 if (!this->emitNeg(ElemT, E))
8248 return false;
8249 if (!this->emitInitElem(ElemT, I, E))
8250 return false;
8251 }
8252 break;
8253 case UO_LNot: { // !x
8254 // In C++, the logic operators !, &&, || are available for vectors. !v is
8255 // equivalent to v == 0.
8256 //
8257 // The result of the comparison is a vector of the same width and number of
8258 // elements as the comparison operands with a signed integral element type.
8259 //
8260 // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
8261 QualType ResultVecTy = E->getType();
8262 PrimType ResultVecElemT =
8263 classifyPrim(ResultVecTy->getAs<VectorType>()->getElementType());
8264 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8265 if (!getElem(SubExprOffset, I))
8266 return false;
8267 // operator ! on vectors returns -1 for 'truth', so negate it.
8268 if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E))
8269 return false;
8270 if (!this->emitInv(E))
8271 return false;
8272 if (!this->emitPrimCast(PT_Bool, ElemT, VecTy->getElementType(), E))
8273 return false;
8274 if (!this->emitNeg(ElemT, E))
8275 return false;
8276 if (ElemT != ResultVecElemT &&
8277 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy, E))
8278 return false;
8279 if (!this->emitInitElem(ResultVecElemT, I, E))
8280 return false;
8281 }
8282 break;
8283 }
8284 case UO_Not: // ~x
8285 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8286 if (!getElem(SubExprOffset, I))
8287 return false;
8288 if (ElemT == PT_Bool) {
8289 if (!this->emitInv(E))
8290 return false;
8291 } else {
8292 if (!this->emitComp(ElemT, E))
8293 return false;
8294 }
8295 if (!this->emitInitElem(ElemT, I, E))
8296 return false;
8297 }
8298 break;
8299 default:
8300 llvm_unreachable("Unsupported unary operators should be handled up front");
8301 }
8302 return true;
8303}
8304
8305template <class Emitter>
8307 if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
8308 if (DiscardResult)
8309 return true;
8310 return this->emitConst(ECD->getInitVal(), E);
8311 }
8312 if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
8313 if (DiscardResult)
8314 return true;
8315 const Function *F = getFunction(FuncDecl);
8316 return F && this->emitGetFnPtr(F, E);
8317 }
8318 if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
8319 TPOD = TPOD->getFirstDecl();
8320 if (DiscardResult)
8321 return true;
8322 if (UnsignedOrNone GlobalIndex = P.getGlobal(TPOD))
8323 return this->emitGetPtrGlobal(*GlobalIndex, E);
8324
8325 if (UnsignedOrNone Index = P.getOrCreateGlobal(TPOD)) {
8326 if (OptPrimType T = classify(TPOD->getType())) {
8327 if (!this->visitAPValue(TPOD->getValue(), *T, E))
8328 return false;
8329 return this->emitInitGlobal(*T, *Index, E);
8330 }
8331
8332 if (!this->emitGetPtrGlobal(*Index, E))
8333 return false;
8334 if (!this->visitAPValueInitializer(TPOD->getValue(), E, TPOD->getType()))
8335 return false;
8336 return this->emitFinishInit(E);
8337 }
8338 return false;
8339 }
8340
8341 // References are implemented via pointers, so when we see a DeclRefExpr
8342 // pointing to a reference, we need to get its value directly (i.e. the
8343 // pointer to the actual value) instead of a pointer to the pointer to the
8344 // value.
8345 QualType DeclType = D->getType();
8346 bool IsReference = DeclType->isReferenceType();
8347
8348 auto maybePopPtr = [&]() -> bool {
8349 if (DiscardResult)
8350 return this->emitPopPtr(E);
8351 return true;
8352 };
8353
8354 // Function parameters.
8355 // Note that it's important to check them first since we might have a local
8356 // variable created for a ParmVarDecl as well.
8357 if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
8358 if (DiscardResult)
8359 return true;
8360
8361 if (Ctx.getLangOpts().CPlusPlus && !Ctx.getLangOpts().CPlusPlus11 &&
8362 !DeclType->isIntegralOrEnumerationType()) {
8363 return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
8364 /*InitializerFailed=*/false, E);
8365 }
8366 if (auto It = this->Params.find(PVD); It != this->Params.end()) {
8367 if (IsReference || !It->second.IsPtr)
8368 return this->emitGetParam(classifyPrim(E), It->second.Index, E);
8369
8370 return this->emitGetPtrParam(It->second.Index, E);
8371 }
8372
8373 if (!Ctx.getLangOpts().CPlusPlus23 && IsReference && !Locals.contains(D))
8374 return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
8375 /*InitializerFailed=*/false, E);
8376 }
8377
8378 // Local variables.
8379 if (auto It = Locals.find(D); It != Locals.end()) {
8380 const unsigned Offset = It->second.Offset;
8381 if (IsReference) {
8382 assert(classifyPrim(E) == PT_Ptr);
8383 return this->emitGetRefLocal(Offset, E) && maybePopPtr();
8384 }
8385 return this->emitGetPtrLocal(Offset, E) && maybePopPtr();
8386 }
8387 // Global variables.
8388 if (auto GlobalIndex = P.getGlobal(D)) {
8389 if (IsReference) {
8390 if (!Ctx.getLangOpts().CPlusPlus11)
8391 return this->emitGetGlobal(classifyPrim(E), *GlobalIndex, E);
8392 if (!Ctx.getLangOpts().CPlusPlus23)
8393 return this->emitGetGlobalUnchecked(classifyPrim(E), *GlobalIndex, E);
8394
8395 return this->emitGetRefGlobal(*GlobalIndex, E) && maybePopPtr();
8396 }
8397
8398 return this->emitGetPtrGlobal(*GlobalIndex, E) && maybePopPtr();
8399 }
8400
8401 // In case we need to re-visit a declaration.
8402 auto revisit = [&](const VarDecl *VD,
8403 bool IsConstexprUnknown = true) -> bool {
8405 IsConstexprUnknown);
8406 if constexpr (std::is_same_v<Emitter, EvalEmitter>) {
8407 if (!this->emitPushCC(VD->hasConstantInitialization(), E))
8408 return false;
8409 }
8410 auto VarState = this->visitDecl(VD);
8411
8412 if constexpr (std::is_same_v<Emitter, EvalEmitter>) {
8413 if (!this->emitPopCC(E))
8414 return false;
8415 }
8416
8417 if (VarState.notCreated())
8418 return true;
8419 if (!VarState)
8420 return false;
8421 // Retry.
8422 return this->visitDeclRef(D, E);
8423 };
8424
8425 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
8426 // Lambda captures.
8427 if (auto It = this->LambdaCaptures.find(D);
8428 It != this->LambdaCaptures.end()) {
8429 auto [Offset, IsPtr] = It->second;
8430
8431 if (IsPtr)
8432 return this->emitGetThisFieldPtr(Offset, E) && maybePopPtr();
8433 return this->emitGetPtrThisField(Offset, E) && maybePopPtr();
8434 }
8435 }
8436
8437 if (const auto *DRE = dyn_cast<DeclRefExpr>(E);
8438 DRE && DRE->refersToEnclosingVariableOrCapture()) {
8439 if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture())
8440 return revisit(VD);
8441 }
8442
8443 if (const auto *BD = dyn_cast<BindingDecl>(D))
8444 return this->delegate(BD->getBinding());
8445
8446 // Avoid infinite recursion.
8447 if (D == InitializingDecl) {
8448 if (DiscardResult)
8449 return true;
8450 return this->emitDummyPtr(D, E);
8451 }
8452
8453 // Try to lazily visit (or emit dummy pointers for) declarations
8454 // we haven't seen yet.
8455 const auto *VD = dyn_cast<VarDecl>(D);
8456 if (!VD)
8457 return this->emitError(E);
8458
8459 // For C.
8460 if (!Ctx.getLangOpts().CPlusPlus) {
8461 if (VD->getInit() && !VD->getInit()->isValueDependent() &&
8462 DeclType.isConstant(Ctx.getASTContext()) && !VD->isWeak() &&
8463 VD->evaluateValue())
8464 return revisit(VD, /*IsConstexprUnknown=*/false);
8465
8466 if (DiscardResult)
8467 return true;
8468 return this->emitDummyPtr(D, E);
8469 }
8470
8471 // ... and C++.
8472 const auto typeShouldBeVisited = [&](QualType T) -> bool {
8473 if (T.isConstant(Ctx.getASTContext()))
8474 return true;
8475 return T->isReferenceType();
8476 };
8477
8478 if ((VD->hasGlobalStorage() || VD->isStaticDataMember()) &&
8479 typeShouldBeVisited(DeclType)) {
8480 if (const Expr *Init = VD->getAnyInitializer();
8481 Init && !Init->isValueDependent()) {
8482 // Whether or not the evaluation is successul doesn't really matter
8483 // here -- we will create a global variable in any case, and that
8484 // will have the state of initializer evaluation attached.
8486 (void)Init->EvaluateAsInitializer(Ctx.getASTContext(), VD, Result, true);
8487 return this->visitDeclRef(D, E);
8488 }
8489 return revisit(VD, !VD->isConstexpr() && DeclType->isReferenceType());
8490 }
8491
8492 // FIXME: The evaluateValue() check here is a little ridiculous, since
8493 // it will ultimately call into Context::evaluateAsInitializer(). In
8494 // other words, we're evaluating the initializer, just to know if we can
8495 // evaluate the initializer.
8496 if (VD->isLocalVarDecl() && typeShouldBeVisited(DeclType) && VD->getInit() &&
8497 !VD->getInit()->isValueDependent()) {
8498 if (VD->evaluateValue()) {
8499 bool IsConstexprUnknown = !DeclType.isConstant(Ctx.getASTContext()) &&
8500 !DeclType->isReferenceType();
8501 // Revisit the variable declaration, but make sure it's associated with a
8502 // different evaluation, so e.g. mutable reads don't work on it.
8503 EvalIDScope _(Ctx);
8504 return revisit(VD, IsConstexprUnknown);
8505 } else if (Ctx.getLangOpts().CPlusPlus23 && IsReference)
8506 return revisit(VD, /*IsConstexprUnknown=*/true);
8507
8508 if (IsReference)
8509 return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
8510 /*InitializerFailed=*/true, E);
8511 }
8512
8513 if (DiscardResult)
8514 return true;
8515 return this->emitDummyPtr(
8516 D, E, Ctx.getLangOpts().CPlusPlus23 && DeclType->isReferenceType());
8517}
8518
8519template <class Emitter>
8521 const auto *D = E->getDecl();
8522 return this->visitDeclRef(D, E);
8523}
8524
8525template <class Emitter>
8527 const DesignatedInitUpdateExpr *E) {
8528 if (!this->visitInitializer(E->getBase()))
8529 return false;
8530 return this->visitInitializer(E->getUpdater());
8531}
8532
8533template <class Emitter> bool Compiler<Emitter>::emitCleanup() {
8534 for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent()) {
8535 if (!C->destroyLocals())
8536 return false;
8537 }
8538 return true;
8539}
8540
8541template <class Emitter>
8542unsigned Compiler<Emitter>::collectBaseOffset(const QualType BaseType,
8543 const QualType DerivedType) {
8544 const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
8545 if (const auto *R = Ty->getPointeeCXXRecordDecl())
8546 return R;
8547 return Ty->getAsCXXRecordDecl();
8548 };
8549 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
8550 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
8551
8552 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
8553}
8554
8555/// Emit casts from a PrimType to another PrimType.
8556template <class Emitter>
8557bool Compiler<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT,
8558 QualType ToQT, const Expr *E) {
8559
8560 if (FromT == PT_Float) {
8561 // Floating to floating.
8562 if (ToT == PT_Float) {
8563 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
8564 return this->emitCastFP(ToSem, getRoundingMode(E), E);
8565 }
8566
8567 if (ToT == PT_IntAP)
8568 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
8569 getFPOptions(E), E);
8570 if (ToT == PT_IntAPS)
8571 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
8572 getFPOptions(E), E);
8573
8574 // Float to integral.
8575 if (isIntegerOrBoolType(ToT) || ToT == PT_Bool)
8576 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
8577 }
8578
8579 if (isIntegerOrBoolType(FromT) || FromT == PT_Bool) {
8580 if (ToT == PT_IntAP)
8581 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
8582 if (ToT == PT_IntAPS)
8583 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
8584
8585 // Integral to integral.
8586 if (isIntegerOrBoolType(ToT) || ToT == PT_Bool)
8587 return FromT != ToT ? this->emitCast(FromT, ToT, E) : true;
8588
8589 if (ToT == PT_Float) {
8590 // Integral to floating.
8591 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
8592 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E);
8593 }
8594 }
8595
8596 return false;
8597}
8598
8599template <class Emitter>
8600bool Compiler<Emitter>::emitIntegralCast(PrimType FromT, PrimType ToT,
8601 QualType ToQT, const Expr *E) {
8602 assert(FromT != ToT);
8603
8604 if (ToT == PT_IntAP)
8605 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
8606 if (ToT == PT_IntAPS)
8607 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
8608
8609 return this->emitCast(FromT, ToT, E);
8610}
8611
8612/// Emits __real(SubExpr)
8613template <class Emitter>
8614bool Compiler<Emitter>::emitComplexReal(const Expr *SubExpr) {
8615 assert(SubExpr->getType()->isAnyComplexType());
8616
8617 if (DiscardResult)
8618 return this->discard(SubExpr);
8619
8620 if (!this->visit(SubExpr))
8621 return false;
8622 if (SubExpr->isLValue()) {
8623 if (!this->emitConstUint8(0, SubExpr))
8624 return false;
8625 return this->emitArrayElemPtrPopUint8(SubExpr);
8626 }
8627
8628 // Rvalue, load the actual element.
8629 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->getType()),
8630 0, SubExpr);
8631}
8632
8633template <class Emitter>
8634bool Compiler<Emitter>::emitComplexBoolCast(const Expr *E) {
8635 assert(!DiscardResult);
8636 PrimType ElemT = classifyComplexElementType(E->getType());
8637 // We emit the expression (__real(E) != 0 || __imag(E) != 0)
8638 // for us, that means (bool)E[0] || (bool)E[1]
8639 if (!this->emitArrayElem(ElemT, 0, E))
8640 return false;
8641 if (ElemT == PT_Float) {
8642 if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
8643 return false;
8644 } else {
8645 if (!this->emitCast(ElemT, PT_Bool, E))
8646 return false;
8647 }
8648
8649 // We now have the bool value of E[0] on the stack.
8650 LabelTy LabelTrue = this->getLabel();
8651 if (!this->jumpTrue(LabelTrue, E))
8652 return false;
8653
8654 if (!this->emitArrayElemPop(ElemT, 1, E))
8655 return false;
8656 if (ElemT == PT_Float) {
8657 if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
8658 return false;
8659 } else {
8660 if (!this->emitCast(ElemT, PT_Bool, E))
8661 return false;
8662 }
8663 // Leave the boolean value of E[1] on the stack.
8664 LabelTy EndLabel = this->getLabel();
8665 this->jump(EndLabel, E);
8666
8667 this->emitLabel(LabelTrue);
8668 if (!this->emitPopPtr(E))
8669 return false;
8670 if (!this->emitConstBool(true, E))
8671 return false;
8672
8673 this->fallthrough(EndLabel);
8674 this->emitLabel(EndLabel);
8675
8676 return true;
8677}
8678
8679template <class Emitter>
8680bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS,
8681 const BinaryOperator *E) {
8682 assert(E->isComparisonOp());
8683 assert(!Initializing);
8684 if (DiscardResult)
8685 return this->discard(LHS) && this->discard(RHS);
8686
8687 PrimType ElemT;
8688 bool LHSIsComplex;
8689 unsigned LHSOffset;
8690 if (LHS->getType()->isAnyComplexType()) {
8691 LHSIsComplex = true;
8692 ElemT = classifyComplexElementType(LHS->getType());
8693 LHSOffset = allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true);
8694 if (!this->visit(LHS))
8695 return false;
8696 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
8697 return false;
8698 } else {
8699 LHSIsComplex = false;
8700 PrimType LHST = classifyPrim(LHS->getType());
8701 LHSOffset = this->allocateLocalPrimitive(LHS, LHST, /*IsConst=*/true);
8702 if (!this->visit(LHS))
8703 return false;
8704 if (!this->emitSetLocal(LHST, LHSOffset, E))
8705 return false;
8706 }
8707
8708 bool RHSIsComplex;
8709 unsigned RHSOffset;
8710 if (RHS->getType()->isAnyComplexType()) {
8711 RHSIsComplex = true;
8712 ElemT = classifyComplexElementType(RHS->getType());
8713 RHSOffset = allocateLocalPrimitive(RHS, PT_Ptr, /*IsConst=*/true);
8714 if (!this->visit(RHS))
8715 return false;
8716 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
8717 return false;
8718 } else {
8719 RHSIsComplex = false;
8720 PrimType RHST = classifyPrim(RHS->getType());
8721 RHSOffset = this->allocateLocalPrimitive(RHS, RHST, /*IsConst=*/true);
8722 if (!this->visit(RHS))
8723 return false;
8724 if (!this->emitSetLocal(RHST, RHSOffset, E))
8725 return false;
8726 }
8727
8728 auto getElem = [&](unsigned LocalOffset, unsigned Index,
8729 bool IsComplex) -> bool {
8730 if (IsComplex) {
8731 if (!this->emitGetLocal(PT_Ptr, LocalOffset, E))
8732 return false;
8733 return this->emitArrayElemPop(ElemT, Index, E);
8734 }
8735 return this->emitGetLocal(ElemT, LocalOffset, E);
8736 };
8737
8738 for (unsigned I = 0; I != 2; ++I) {
8739 // Get both values.
8740 if (!getElem(LHSOffset, I, LHSIsComplex))
8741 return false;
8742 if (!getElem(RHSOffset, I, RHSIsComplex))
8743 return false;
8744 // And compare them.
8745 if (!this->emitEQ(ElemT, E))
8746 return false;
8747
8748 if (!this->emitCastBoolUint8(E))
8749 return false;
8750 }
8751
8752 // We now have two bool values on the stack. Compare those.
8753 if (!this->emitAddUint8(E))
8754 return false;
8755 if (!this->emitConstUint8(2, E))
8756 return false;
8757
8758 if (E->getOpcode() == BO_EQ) {
8759 if (!this->emitEQUint8(E))
8760 return false;
8761 } else if (E->getOpcode() == BO_NE) {
8762 if (!this->emitNEUint8(E))
8763 return false;
8764 } else
8765 return false;
8766
8767 // In C, this returns an int.
8768 if (PrimType ResT = classifyPrim(E->getType()); ResT != PT_Bool)
8769 return this->emitCast(PT_Bool, ResT, E);
8770 return true;
8771}
8772
8773/// When calling this, we have a pointer of the local-to-destroy
8774/// on the stack.
8775/// Emit destruction of record types (or arrays of record types).
8776template <class Emitter>
8777bool Compiler<Emitter>::emitRecordDestructionPop(const Record *R,
8778 SourceInfo Loc) {
8779 assert(R);
8780 assert(!R->hasTrivialDtor());
8781 const CXXDestructorDecl *Dtor = R->getDestructor();
8782 assert(Dtor);
8783 const Function *DtorFunc = getFunction(Dtor);
8784 if (!DtorFunc)
8785 return false;
8786 assert(DtorFunc->hasThisPointer());
8787 assert(DtorFunc->getNumParams() == 1);
8788 return this->emitCall(DtorFunc, 0, Loc);
8789}
8790/// When calling this, we have a pointer of the local-to-destroy
8791/// on the stack.
8792/// Emit destruction of record types (or arrays of record types).
8793template <class Emitter>
8794bool Compiler<Emitter>::emitDestructionPop(const Descriptor *Desc,
8795 SourceInfo Loc) {
8796 assert(Desc);
8797 assert(!Desc->hasTrivialDtor());
8798
8799 // Arrays.
8800 if (Desc->isArray()) {
8801 const Descriptor *ElemDesc = Desc->ElemDesc;
8802 assert(ElemDesc);
8803
8804 unsigned N = Desc->getNumElems();
8805 if (N == 0)
8806 return this->emitPopPtr(Loc);
8807
8808 for (ssize_t I = N - 1; I >= 1; --I) {
8809 if (!this->emitConstUint64(I, Loc))
8810 return false;
8811 if (!this->emitArrayElemPtrUint64(Loc))
8812 return false;
8813 if (!this->emitDestructionPop(ElemDesc, Loc))
8814 return false;
8815 }
8816 // Last iteration, removes the instance pointer from the stack.
8817 if (!this->emitConstUint64(0, Loc))
8818 return false;
8819 if (!this->emitArrayElemPtrPopUint64(Loc))
8820 return false;
8821 return this->emitDestructionPop(ElemDesc, Loc);
8822 }
8823
8824 assert(Desc->ElemRecord);
8825 assert(!Desc->ElemRecord->hasTrivialDtor());
8826 return this->emitRecordDestructionPop(Desc->ElemRecord, Loc);
8827}
8828
8829/// Create a dummy pointer for the given decl (or expr) and
8830/// push a pointer to it on the stack.
8831template <class Emitter>
8832bool Compiler<Emitter>::emitDummyPtr(DeclOrExpr D, const Expr *E, bool CU) {
8833 assert(!DiscardResult && "Should've been checked before");
8834 return this->emitGetOpaquePtr(D, CU, E);
8835}
8836
8837template <class Emitter>
8838bool Compiler<Emitter>::emitFloat(const APFloat &F, SourceInfo Info) {
8839 if (Floating::singleWord(F.getSemantics()))
8840 return this->emitConstFloat(Floating(F), Info);
8841
8842 APInt I = F.bitcastToAPInt();
8843 return this->emitConstFloat(
8844 Floating(const_cast<uint64_t *>(I.getRawData()),
8845 llvm::APFloatBase::SemanticsToEnum(F.getSemantics())),
8846 Info);
8847}
8848
8849// This function is constexpr if and only if To, From, and the types of
8850// all subobjects of To and From are types T such that...
8851// (3.1) - is_union_v<T> is false;
8852// (3.2) - is_pointer_v<T> is false;
8853// (3.3) - is_member_pointer_v<T> is false;
8854// (3.4) - is_volatile_v<T> is false; and
8855// (3.5) - T has no non-static data members of reference type
8856template <class Emitter>
8857bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) {
8858 const Expr *SubExpr = E->getSubExpr();
8859 QualType FromType = SubExpr->getType();
8860 QualType ToType = E->getType();
8861 OptPrimType ToT = classify(ToType);
8862
8863 assert(!ToType->isReferenceType());
8864
8865 // Prepare storage for the result in case we discard.
8866 if (DiscardResult && !Initializing && !ToT) {
8867 UnsignedOrNone LocalIndex = allocateLocal(E);
8868 if (!LocalIndex)
8869 return false;
8870 if (!this->emitGetPtrLocal(*LocalIndex, E))
8871 return false;
8872 }
8873
8874 // Get a pointer to the value-to-cast on the stack.
8875 // For CK_LValueToRValueBitCast, this is always an lvalue and
8876 // we later assume it to be one (i.e. a PT_Ptr). However,
8877 // we call this function for other utility methods where
8878 // a bitcast might be useful, so convert it to a PT_Ptr in that case.
8879 if (SubExpr->isGLValue() || FromType->isVectorType()) {
8880 if (!this->visit(SubExpr))
8881 return false;
8882 } else if (OptPrimType FromT = classify(SubExpr)) {
8883 unsigned TempOffset =
8884 allocateLocalPrimitive(SubExpr, *FromT, /*IsConst=*/true);
8885 if (!this->visit(SubExpr))
8886 return false;
8887 if (!this->emitSetLocal(*FromT, TempOffset, E))
8888 return false;
8889 if (!this->emitGetPtrLocal(TempOffset, E))
8890 return false;
8891 } else {
8892 return false;
8893 }
8894
8895 if (!ToT) {
8896 if (!this->emitBitCast(E))
8897 return false;
8898 return DiscardResult ? this->emitPopPtr(E) : true;
8899 }
8900 assert(ToT);
8901
8902 const llvm::fltSemantics *TargetSemantics = nullptr;
8903 if (ToT == PT_Float)
8904 TargetSemantics = &Ctx.getFloatSemantics(ToType);
8905
8906 // Conversion to a primitive type. FromType can be another
8907 // primitive type, or a record/array.
8908 bool ToTypeIsUChar = (ToType->isSpecificBuiltinType(BuiltinType::UChar) ||
8909 ToType->isSpecificBuiltinType(BuiltinType::Char_U));
8910 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
8911
8912 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->isStdByteType(),
8913 ResultBitWidth, TargetSemantics,
8914 ToType.getTypePtr(), E))
8915 return false;
8916
8917 if (DiscardResult)
8918 return this->emitPop(*ToT, E);
8919
8920 return true;
8921}
8922
8923/// Replicate a scalar value into every scalar element of an aggregate.
8924/// The scalar is stored in a local at \p SrcOffset and a pointer to the
8925/// destination must be on top of the interpreter stack. Each element receives
8926/// the scalar, cast to its own type.
8927template <class Emitter>
8928bool Compiler<Emitter>::emitHLSLAggregateSplat(PrimType SrcT,
8929 unsigned SrcOffset,
8930 QualType DestType,
8931 const Expr *E) {
8932 // Vectors and matrices are treated as flat sequences of elements.
8933 unsigned NumElems = 0;
8934 QualType ElemType;
8935 if (const auto *VT = DestType->getAs<VectorType>()) {
8936 NumElems = VT->getNumElements();
8937 ElemType = VT->getElementType();
8938 } else if (const auto *MT = DestType->getAs<ConstantMatrixType>()) {
8939 NumElems = MT->getNumElementsFlattened();
8940 ElemType = MT->getElementType();
8941 }
8942 if (NumElems > 0) {
8943 PrimType ElemT = classifyPrim(ElemType);
8944 for (unsigned I = 0; I != NumElems; ++I) {
8945 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8946 return false;
8947 if (!this->emitPrimCast(SrcT, ElemT, ElemType, E))
8948 return false;
8949 if (!this->emitInitElem(ElemT, I, E))
8950 return false;
8951 }
8952 return true;
8953 }
8954
8955 // Arrays: primitive elements are filled directly; composite elements
8956 // require recursion into each sub-aggregate.
8957 if (const auto *AT = DestType->getAsArrayTypeUnsafe()) {
8958 const auto *CAT = cast<ConstantArrayType>(AT);
8959 QualType ArrElemType = CAT->getElementType();
8960 unsigned ArrSize = CAT->getZExtSize();
8961
8962 if (OptPrimType ElemT = classify(ArrElemType)) {
8963 for (unsigned I = 0; I != ArrSize; ++I) {
8964 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8965 return false;
8966 if (!this->emitPrimCast(SrcT, *ElemT, ArrElemType, E))
8967 return false;
8968 if (!this->emitInitElem(*ElemT, I, E))
8969 return false;
8970 }
8971 } else {
8972 for (unsigned I = 0; I != ArrSize; ++I) {
8973 if (!this->emitConstUint32(I, E))
8974 return false;
8975 if (!this->emitArrayElemPtrUint32(E))
8976 return false;
8977 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, ArrElemType, E))
8978 return false;
8979 if (!this->emitFinishInitPop(E))
8980 return false;
8981 }
8982 }
8983 return true;
8984 }
8985
8986 // Records: fill base classes first, then named fields in declaration
8987 // order.
8988 if (DestType->isRecordType()) {
8989 const Record *R = getRecord(DestType);
8990 if (!R)
8991 return false;
8992
8993 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
8994 for (const CXXBaseSpecifier &BS : CXXRD->bases()) {
8995 const Record::Base *B = R->getBase(BS.getType());
8996 assert(B);
8997 if (!this->emitGetPtrBase(B->Offset, E))
8998 return false;
8999 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, BS.getType(), E))
9000 return false;
9001 if (!this->emitFinishInitPop(E))
9002 return false;
9003 }
9004 }
9005
9006 for (const Record::Field &F : R->fields()) {
9007 if (F.isUnnamedBitField())
9008 continue;
9009
9010 QualType FieldType = F.Decl->getType();
9011 if (OptPrimType FieldT = F.T) {
9012 if (!this->emitGetLocal(SrcT, SrcOffset, E))
9013 return false;
9014 if (!this->emitPrimCast(SrcT, *FieldT, FieldType, E))
9015 return false;
9016 if (F.isBitField()) {
9017 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
9018 return false;
9019 } else {
9020 if (!this->emitInitField(*FieldT, F.Offset, E))
9021 return false;
9022 }
9023 } else {
9024 if (!this->emitGetPtrField(F.Offset, E))
9025 return false;
9026 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, FieldType, E))
9027 return false;
9028 if (!this->emitPopPtr(E))
9029 return false;
9030 }
9031 }
9032 return true;
9033 }
9034
9035 return false;
9036}
9037
9038/// Return the total number of scalar elements in a type. This is used
9039/// to cap how many source elements are extracted during an elementwise cast,
9040/// so we never flatten more than the destination can hold.
9041template <class Emitter>
9042unsigned Compiler<Emitter>::countHLSLFlatElements(QualType Ty) {
9043 // Vector and matrix types are treated as flat sequences of elements.
9044 if (const auto *VT = Ty->getAs<VectorType>())
9045 return VT->getNumElements();
9046 if (const auto *MT = Ty->getAs<ConstantMatrixType>())
9047 return MT->getNumElementsFlattened();
9048 // Arrays: total count is array size * scalar elements per element.
9049 if (const auto *AT = Ty->getAsArrayTypeUnsafe()) {
9050 const auto *CAT = cast<ConstantArrayType>(AT);
9051 return CAT->getZExtSize() * countHLSLFlatElements(CAT->getElementType());
9052 }
9053 // Records: sum scalar element counts of base classes and named fields.
9054 if (Ty->isRecordType()) {
9055 const Record *R = getRecord(Ty);
9056 if (!R)
9057 return 0;
9058 unsigned Count = 0;
9059 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
9060 for (const CXXBaseSpecifier &BS : CXXRD->bases())
9061 Count += countHLSLFlatElements(BS.getType());
9062 }
9063 for (const Record::Field &F : R->fields()) {
9064 if (F.isUnnamedBitField())
9065 continue;
9066 Count += countHLSLFlatElements(F.Decl->getType());
9067 }
9068 return Count;
9069 }
9070 // Scalar primitive types contribute one element.
9071 if (canClassify(Ty))
9072 return 1;
9073 return 0;
9074}
9075
9076/// Walk a source aggregate and extract every scalar element into its own local
9077/// variable. The results are appended to \p Elements in declaration order,
9078/// stopping once \p MaxElements have been collected. A pointer to the
9079/// source aggregate must be stored in the local at \p SrcOffset.
9080template <class Emitter>
9081bool Compiler<Emitter>::emitHLSLFlattenAggregate(
9082 QualType SrcType, unsigned SrcOffset,
9083 SmallVectorImpl<HLSLFlatElement> &Elements, unsigned MaxElements,
9084 const Expr *E) {
9085
9086 // Save a scalar value from the stack into a new local and record it.
9087 auto saveToLocal = [&](PrimType T) -> bool {
9088 unsigned Offset = allocateLocalPrimitive(E, T, /*IsConst=*/true);
9089 if (!this->emitSetLocal(T, Offset, E))
9090 return false;
9091 Elements.push_back({Offset, T});
9092 return true;
9093 };
9094
9095 // Save a pointer from the stack into a new local for later use.
9096 auto savePtrToLocal = [&]() -> UnsignedOrNone {
9097 unsigned Offset = allocateLocalPrimitive(E, PT_Ptr, /*IsConst=*/true);
9098 if (!this->emitSetLocal(PT_Ptr, Offset, E))
9099 return std::nullopt;
9100 return Offset;
9101 };
9102
9103 // Vectors and matrices are flat sequences of elements.
9104 unsigned NumElems = 0;
9105 QualType ElemType;
9106 if (const auto *VT = SrcType->getAs<VectorType>()) {
9107 NumElems = VT->getNumElements();
9108 ElemType = VT->getElementType();
9109 } else if (const auto *MT = SrcType->getAs<ConstantMatrixType>()) {
9110 NumElems = MT->getNumElementsFlattened();
9111 ElemType = MT->getElementType();
9112 }
9113 if (NumElems > 0) {
9114 PrimType ElemT = classifyPrim(ElemType);
9115 for (unsigned I = 0; I != NumElems && Elements.size() < MaxElements; ++I) {
9116 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9117 return false;
9118 if (!this->emitArrayElemPop(ElemT, I, E))
9119 return false;
9120 if (!saveToLocal(ElemT))
9121 return false;
9122 }
9123 return true;
9124 }
9125
9126 // Arrays: primitive elements are extracted directly; composite elements
9127 // require recursion into each sub-aggregate.
9128 if (const auto *AT = SrcType->getAsArrayTypeUnsafe()) {
9129 const auto *CAT = cast<ConstantArrayType>(AT);
9130 QualType ArrElemType = CAT->getElementType();
9131 unsigned ArrSize = CAT->getZExtSize();
9132
9133 if (OptPrimType ElemT = classify(ArrElemType)) {
9134 for (unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
9135 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9136 return false;
9137 if (!this->emitArrayElemPop(*ElemT, I, E))
9138 return false;
9139 if (!saveToLocal(*ElemT))
9140 return false;
9141 }
9142 } else {
9143 for (unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
9144 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9145 return false;
9146 if (!this->emitConstUint32(I, E))
9147 return false;
9148 if (!this->emitArrayElemPtrPopUint32(E))
9149 return false;
9150 UnsignedOrNone ElemPtrOffset = savePtrToLocal();
9151 if (!ElemPtrOffset)
9152 return false;
9153 if (!emitHLSLFlattenAggregate(ArrElemType, *ElemPtrOffset, Elements,
9154 MaxElements, E))
9155 return false;
9156 }
9157 }
9158 return true;
9159 }
9160
9161 // Records: base classes come first, then named fields in declaration
9162 // order.
9163 if (SrcType->isRecordType()) {
9164 const Record *R = getRecord(SrcType);
9165 if (!R)
9166 return false;
9167
9168 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
9169 for (const CXXBaseSpecifier &BS : CXXRD->bases()) {
9170 if (Elements.size() >= MaxElements)
9171 break;
9172 const Record::Base *B = R->getBase(BS.getType());
9173 assert(B);
9174 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9175 return false;
9176 if (!this->emitGetPtrBasePop(B->Offset, /*NullOK=*/false, E))
9177 return false;
9178 UnsignedOrNone BasePtrOffset = savePtrToLocal();
9179 if (!BasePtrOffset)
9180 return false;
9181 if (!emitHLSLFlattenAggregate(BS.getType(), *BasePtrOffset, Elements,
9182 MaxElements, E))
9183 return false;
9184 }
9185 }
9186
9187 for (const Record::Field &F : R->fields()) {
9188 if (Elements.size() >= MaxElements)
9189 break;
9190 if (F.isUnnamedBitField())
9191 continue;
9192
9193 QualType FieldType = F.Decl->getType();
9194 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
9195 return false;
9196 if (!this->emitGetPtrFieldPop(F.Offset, E))
9197 return false;
9198
9199 if (OptPrimType FieldT = F.T) {
9200 if (!this->emitLoadPop(*FieldT, E))
9201 return false;
9202 if (!saveToLocal(*FieldT))
9203 return false;
9204 } else {
9205 UnsignedOrNone FieldPtrOffset = savePtrToLocal();
9206 if (!FieldPtrOffset)
9207 return false;
9208 if (!emitHLSLFlattenAggregate(FieldType, *FieldPtrOffset, Elements,
9209 MaxElements, E))
9210 return false;
9211 }
9212 }
9213 return true;
9214 }
9215
9216 return false;
9217}
9218
9219/// Populate an HLSL aggregate from a flat list of previously extracted source
9220/// elements, casting each to the corresponding destination element type.
9221/// \p ElemIdx tracks the current position in \p Elements and is advanced as
9222/// elements are consumed. A pointer to the destination must be on top of the
9223/// interpreter stack.
9224template <class Emitter>
9225bool Compiler<Emitter>::emitHLSLConstructAggregate(
9226 QualType DestType, ArrayRef<HLSLFlatElement> Elements, unsigned &ElemIdx,
9227 const Expr *E) {
9228
9229 // Consume the next source element, cast it, and leave it on the stack.
9230 auto loadAndCast = [&](PrimType DestT, QualType DestQT) -> bool {
9231 const auto &Src = Elements[ElemIdx++];
9232 if (!this->emitGetLocal(Src.Type, Src.LocalOffset, E))
9233 return false;
9234 return this->emitPrimCast(Src.Type, DestT, DestQT, E);
9235 };
9236
9237 // Vectors and matrices are flat sequences of elements.
9238 unsigned NumElems = 0;
9239 QualType ElemType;
9240 if (const auto *VT = DestType->getAs<VectorType>()) {
9241 NumElems = VT->getNumElements();
9242 ElemType = VT->getElementType();
9243 } else if (const auto *MT = DestType->getAs<ConstantMatrixType>()) {
9244 NumElems = MT->getNumElementsFlattened();
9245 ElemType = MT->getElementType();
9246 }
9247 if (NumElems > 0) {
9248 PrimType DestElemT = classifyPrim(ElemType);
9249 for (unsigned I = 0; I != NumElems; ++I) {
9250 if (!loadAndCast(DestElemT, ElemType))
9251 return false;
9252 if (!this->emitInitElem(DestElemT, I, E))
9253 return false;
9254 }
9255 return true;
9256 }
9257
9258 // Arrays: primitive elements are filled directly; composite elements
9259 // require recursion into each sub-aggregate.
9260 if (const auto *AT = DestType->getAsArrayTypeUnsafe()) {
9261 const auto *CAT = cast<ConstantArrayType>(AT);
9262 QualType ArrElemType = CAT->getElementType();
9263 unsigned ArrSize = CAT->getZExtSize();
9264
9265 if (OptPrimType ElemT = classify(ArrElemType)) {
9266 for (unsigned I = 0; I != ArrSize; ++I) {
9267 if (!loadAndCast(*ElemT, ArrElemType))
9268 return false;
9269 if (!this->emitInitElem(*ElemT, I, E))
9270 return false;
9271 }
9272 } else {
9273 for (unsigned I = 0; I != ArrSize; ++I) {
9274 if (!this->emitConstUint32(I, E))
9275 return false;
9276 if (!this->emitArrayElemPtrUint32(E))
9277 return false;
9278 if (!emitHLSLConstructAggregate(ArrElemType, Elements, ElemIdx, E))
9279 return false;
9280 if (!this->emitFinishInitPop(E))
9281 return false;
9282 }
9283 }
9284 return true;
9285 }
9286
9287 // Records: base classes come first, then named fields in declaration
9288 // order.
9289 if (DestType->isRecordType()) {
9290 const Record *R = getRecord(DestType);
9291 if (!R)
9292 return false;
9293
9294 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(R->getDecl())) {
9295 for (const CXXBaseSpecifier &BS : CXXRD->bases()) {
9296 const Record::Base *B = R->getBase(BS.getType());
9297 assert(B);
9298 if (!this->emitGetPtrBase(B->Offset, E))
9299 return false;
9300 if (!emitHLSLConstructAggregate(BS.getType(), Elements, ElemIdx, E))
9301 return false;
9302 if (!this->emitFinishInitPop(E))
9303 return false;
9304 }
9305 }
9306
9307 for (const Record::Field &F : R->fields()) {
9308 if (F.isUnnamedBitField())
9309 continue;
9310
9311 QualType FieldType = F.Decl->getType();
9312 if (OptPrimType FieldT = F.T) {
9313 if (!loadAndCast(*FieldT, FieldType))
9314 return false;
9315 if (F.isBitField()) {
9316 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
9317 return false;
9318 } else {
9319 if (!this->emitInitField(*FieldT, F.Offset, E))
9320 return false;
9321 }
9322 } else {
9323 if (!this->emitGetPtrField(F.Offset, E))
9324 return false;
9325 if (!emitHLSLConstructAggregate(FieldType, Elements, ElemIdx, E))
9326 return false;
9327 if (!this->emitPopPtr(E))
9328 return false;
9329 }
9330 }
9331 return true;
9332 }
9333
9334 return false;
9335}
9336
9337namespace clang {
9338namespace interp {
9339
9340template class Compiler<ByteCodeEmitter>;
9341template class Compiler<EvalEmitter>;
9342
9343} // namespace interp
9344} // namespace clang
#define V(N, I)
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static void emitCleanup(CIRGenFunction &cgf, cir::CleanupScopeOp cleanupScope, EHScopeStack::Cleanup *cleanup, EHScopeStack::Cleanup::Flags flags, Address activeFlag)
static uint32_t getBitWidth(const Expr *E)
#define EMIT_ARITH_OP(OP)
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
static const Expr * stripDerivedToBaseCasts(const Expr *E)
static bool isTrivialMemoryOperation(const CXXMethodDecl *MD)
static const Expr * stripCheckedDerivedToBaseCasts(const Expr *E)
static bool hasTrivialDefaultCtorParent(const FieldDecl *FD)
static bool initNeedsOverridenLoc(const CXXCtorInitializer *Init)
llvm::APSInt APSInt
Definition Compiler.cpp:26
const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. This ignores some c...
bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
Result
Implement __builtin_bit_cast and related operations.
llvm::SmallPtrSet< const ParmVarDecl *, 1 > FoundParams
bool VisitDeclRefExpr(const DeclRefExpr *E) override
a trap message and trap category.
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
const LValueBase getLValueBase() const
Definition APValue.cpp:1018
APValue & getArrayInitializedElt(unsigned I)
Definition APValue.h:629
ArrayRef< LValuePathEntry > getLValuePath() const
Definition APValue.cpp:1038
APSInt & getInt()
Definition APValue.h:511
APValue & getStructField(unsigned i)
Definition APValue.h:674
const FieldDecl * getUnionField() const
Definition APValue.h:695
unsigned getStructNumFields() const
Definition APValue.h:661
APValue & getStructVirtualBase(unsigned i)
Definition APValue.h:679
bool isArray() const
Definition APValue.h:496
bool isMemberPointerToDerivedMember() const
Definition APValue.cpp:1108
unsigned getArrayInitializedElts() const
Definition APValue.h:648
bool isFloat() const
Definition APValue.h:489
unsigned getStructNumBases() const
Definition APValue.h:657
unsigned getStructNumVirtualBases() const
Definition APValue.h:665
const ValueDecl * getMemberPointerDecl() const
Definition APValue.cpp:1101
APValue & getUnionValue()
Definition APValue.h:699
APValue & getArrayFiller()
Definition APValue.h:640
bool isLValue() const
Definition APValue.h:493
bool isIndeterminate() const
Definition APValue.h:485
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
Definition APValue.cpp:1115
bool isMemberPointer() const
Definition APValue.h:499
bool isInt() const
Definition APValue.h:488
unsigned getArraySize() const
Definition APValue.h:652
bool isUnion() const
Definition APValue.h:498
@ None
There is no such object (it's outside its lifetime).
Definition APValue.h:129
bool isStruct() const
Definition APValue.h:497
bool isNullPointer() const
Definition APValue.cpp:1054
APFloat & getFloat()
Definition APValue.h:525
APValue & getStructBase(unsigned i)
Definition APValue.h:669
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:239
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
const LangOptions & getLangOpts() const
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const VariableArrayType * getAsVariableArrayType(QualType T) const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Definition Expr.h:4397
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Definition Expr.h:4575
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Definition Expr.h:4581
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Definition Expr.h:4587
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition Expr.h:4594
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition Expr.h:6071
Represents a loop initializing the elements of an array.
Definition Expr.h:6018
llvm::APInt getArraySize() const
Definition Expr.h:6040
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Definition Expr.h:6033
Expr * getSubExpr() const
Get the initializer to use for each array element.
Definition Expr.h:6038
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition Expr.h:2765
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Definition Expr.h:2794
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition ExprCXX.h:3010
uint64_t getValue() const
Definition ExprCXX.h:3058
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3813
QualType getElementType() const
Definition TypeBase.h:3825
Attr - This represents one attribute.
Definition Attr.h:46
Represents an attribute applied to a statement.
Definition Stmt.h:2215
Stmt * getSubStmt()
Definition Stmt.h:2251
ArrayRef< const Attr * > getAttrs() const
Definition Stmt.h:2247
Represents a C++ declaration that introduces decls from somewhere else.
Definition DeclCXX.h:3525
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4082
static bool isLogicalOp(Opcode Opc)
Definition Expr.h:4215
Expr * getLHS() const
Definition Expr.h:4132
static bool isComparisonOp(Opcode Opc)
Definition Expr.h:4182
static bool isShiftOp(Opcode Opc)
Definition Expr.h:4170
static bool isCommaOp(Opcode Opc)
Definition Expr.h:4185
static Opcode getOpForCompoundAssignment(Opcode Opc)
Definition Expr.h:4229
Expr * getRHS() const
Definition Expr.h:4134
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
Definition Expr.h:4159
static bool isAssignmentOp(Opcode Opc)
Definition Expr.h:4218
static bool isCompoundAssignmentOp(Opcode Opc)
Definition Expr.h:4223
Opcode getOpcode() const
Definition Expr.h:4127
static bool isBitwiseOp(Opcode Opc)
Definition Expr.h:4173
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6722
BreakStmt - This represents a break.
Definition Stmt.h:3147
Represents a C++2a __builtin_bit_cast(T, v) expression.
Definition ExprCXX.h:5529
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents binding an expression to a temporary.
Definition ExprCXX.h:1497
const Expr * getSubExpr() const
Definition ExprCXX.h:1519
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition ExprCXX.h:727
bool getValue() const
Definition ExprCXX.h:744
Represents a call to a C++ constructor.
Definition ExprCXX.h:1552
bool isElidable() const
Whether this construction is elidable.
Definition ExprCXX.h:1621
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition ExprCXX.h:1695
arg_range arguments()
Definition ExprCXX.h:1676
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
Definition ExprCXX.h:1654
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition ExprCXX.h:1615
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Definition ExprCXX.h:1692
Represents a C++ constructor within a class.
Definition DeclCXX.h:2641
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Definition DeclCXX.cpp:3049
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
Definition DeclCXX.cpp:3069
Represents a C++ base or member initializer.
Definition DeclCXX.h:2406
A default argument (C++ [dcl.fct.default]).
Definition ExprCXX.h:1274
A use of a default initializer in a constructor or in aggregate initialization.
Definition ExprCXX.h:1381
Expr * getExpr()
Get the initialization expression that will be used.
Definition ExprCXX.cpp:1138
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition ExprCXX.h:2630
FunctionDecl * getOperatorDelete() const
Definition ExprCXX.h:2669
bool isArrayForm() const
Definition ExprCXX.h:2656
bool isGlobalDelete() const
Definition ExprCXX.h:2655
Represents a C++ destructor within a class.
Definition DeclCXX.h:2906
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Definition ExprCXX.h:485
Represents the code generated for an expanded expansion statement.
Definition StmtCXX.h:1028
ArrayRef< Stmt * > getInstantiations() const
Definition StmtCXX.h:1069
ArrayRef< Stmt * > getPreambleStmts() const
Definition StmtCXX.h:1073
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Definition StmtCXX.h:136
DeclStmt * getBeginStmt()
Definition StmtCXX.h:164
DeclStmt * getLoopVarStmt()
Definition StmtCXX.h:170
DeclStmt * getEndStmt()
Definition StmtCXX.h:167
DeclStmt * getRangeStmt()
Definition StmtCXX.h:163
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition ExprCXX.h:1755
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Definition ExprCXX.h:1792
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2149
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition DeclCXX.h:2292
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
Definition DeclCXX.cpp:2751
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Definition DeclCXX.cpp:2730
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
Definition DeclCXX.cpp:2895
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2359
bool isArray() const
Definition ExprCXX.h:2468
QualType getAllocatedType() const
Definition ExprCXX.h:2438
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Definition ExprCXX.h:2473
Expr * getPlacementArg(unsigned I)
Definition ExprCXX.h:2507
unsigned getNumPlacementArgs() const
Definition ExprCXX.h:2498
FunctionDecl * getOperatorNew() const
Definition ExprCXX.h:2463
Expr * getInitializer()
The initializer of this new-expression.
Definition ExprCXX.h:2537
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition ExprCXX.h:4362
bool getValue() const
Definition ExprCXX.h:4385
The null pointer literal (C++11 [lex.nullptr])
Definition ExprCXX.h:772
Represents a list-initialization with parenthesis.
Definition ExprCXX.h:5194
MutableArrayRef< Expr * > getInitExprs()
Definition ExprCXX.h:5234
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
Definition DeclCXX.h:1255
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
Definition DeclCXX.cpp:1681
capture_const_range captures() const
Definition DeclCXX.h:1106
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
Definition DeclCXX.cpp:1744
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
Definition ExprCXX.h:530
A rewritten comparison expression that was originally written using operator syntax.
Definition ExprCXX.h:290
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
Definition ExprCXX.h:308
An expression "T()" which creates an rvalue of a non-class type T.
Definition ExprCXX.h:2200
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Definition ExprCXX.h:804
Represents the this expression in C++.
Definition ExprCXX.h:1158
A C++ throw-expression (C++ [except.throw]).
Definition ExprCXX.h:1212
const Expr * getSubExpr() const
Definition ExprCXX.h:1232
CXXTryStmt - A C++ try block, including all handlers.
Definition StmtCXX.h:70
CompoundStmt * getTryBlock()
Definition StmtCXX.h:101
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition ExprCXX.h:852
bool isTypeOperand() const
Definition ExprCXX.h:888
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Definition ExprCXX.cpp:167
Expr * getExprOperand() const
Definition ExprCXX.h:899
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
Definition ExprCXX.cpp:135
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Definition ExprCXX.h:1072
MSGuidDecl * getGuidDecl() const
Definition ExprCXX.h:1118
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2987
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3191
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3170
Expr * getCallee()
Definition Expr.h:3134
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition Expr.h:3178
Expr ** getArgs()
Retrieve the call arguments.
Definition Expr.h:3181
arg_range arguments()
Definition Expr.h:3239
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition Expr.cpp:1631
CaseStmt - Represent a case statement.
Definition Stmt.h:1932
Stmt * getSubStmt()
Definition Stmt.h:2045
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition Expr.h:3720
path_iterator path_begin()
Definition Expr.h:3790
CastKind getCastKind() const
Definition Expr.h:3764
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
Definition Expr.h:3807
const FieldDecl * getTargetUnionField() const
Definition Expr.h:3814
path_iterator path_end()
Definition Expr.h:3791
Expr * getSubExpr()
Definition Expr.h:3770
CharUnits - This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
static CharUnits One()
One - Construct a CharUnits quantity of one.
Definition CharUnits.h:58
unsigned getValue() const
Definition Expr.h:1649
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition Expr.h:4892
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Definition Expr.h:4928
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
Complex values, per C99 6.2.5p11.
Definition TypeBase.h:3355
QualType getElementType() const
Definition TypeBase.h:3365
CompoundAssignOperator - For compound assignments (e.g.
Definition Expr.h:4344
QualType getComputationLHSType() const
Definition Expr.h:4378
QualType getComputationResultType() const
Definition Expr.h:4381
CompoundLiteralExpr - [C99 6.5.2.5].
Definition Expr.h:3649
bool isFileScope() const
Definition Expr.h:3681
const Expr * getInitializer() const
Definition Expr.h:3677
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition Stmt.h:1752
body_range body()
Definition Stmt.h:1815
Stmt * body_back()
Definition Stmt.h:1820
Represents the specialization of a concept - evaluates to a prvalue of type bool.
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3851
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
Definition TypeBase.h:3927
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition Expr.h:1102
APValue getAPValueResult() const
Definition Expr.cpp:419
bool hasAPValueResult() const
Definition Expr.h:1177
Represents a concrete matrix type with constant number of rows and columns.
Definition TypeBase.h:4478
ContinueStmt - This represents a continue.
Definition Stmt.h:3131
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition Expr.h:4763
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Definition Expr.h:4853
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2126
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1290
ValueDecl * getDecl()
Definition Expr.h:1358
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition Stmt.h:1643
decl_range decls()
Definition Stmt.h:1691
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool isInvalidDecl() const
Definition DeclBase.h:596
bool hasAttr() const
Definition DeclBase.h:585
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
Stmt * getSubStmt()
Definition Stmt.h:2093
InitListExpr * getUpdater() const
Definition Expr.h:5986
DoStmt - This represents a 'do/while' stmt.
Definition Stmt.h:2844
Stmt * getBody()
Definition Stmt.h:2869
Expr * getCond()
Definition Stmt.h:2862
virtual bool TraverseStmt(MaybeConst< Stmt > *S)
Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...
const Expr * getBase() const
Definition Expr.h:6631
Represents a reference to emded data.
Definition Expr.h:5179
ChildElementIter< false > begin()
Definition Expr.h:5285
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition ExprCXX.h:3714
This represents one expression.
Definition Expr.h:113
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
Definition Expr.cpp:85
bool isGLValue() const
Definition Expr.h:288
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition Expr.h:178
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3111
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
Definition Expr.h:247
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3119
bool isPRValue() const
Definition Expr.h:286
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
Definition Expr.h:285
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
Definition Expr.cpp:3722
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
Definition Expr.cpp:3286
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
Definition Expr.h:480
QualType getType() const
Definition Expr.h:145
An expression trait intrinsic.
Definition ExprCXX.h:3083
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Definition Expr.h:6660
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
Definition Expr.cpp:4585
Represents a member of a struct/union/class.
Definition Decl.h:3295
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Definition Decl.h:3531
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
Definition Expr.h:1595
llvm::APFloat getValue() const
Definition Expr.h:1686
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition Stmt.h:2900
Stmt * getInit()
Definition Stmt.h:2915
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
Definition Stmt.cpp:1120
Stmt * getBody()
Definition Stmt.h:2944
Expr * getInc()
Definition Stmt.h:2943
Expr * getCond()
Definition Stmt.h:2942
DeclStmt * getConditionVariableDeclStmt()
If this ForStmt has a condition variable, return the faux DeclStmt associated with the creation of th...
Definition Stmt.h:2930
const Expr * getSubExpr() const
Definition Expr.h:1082
Represents a function declaration or definition.
Definition Decl.h:2059
const ParmVarDecl * getParamDecl(unsigned i) const
Definition Decl.h:2928
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition Decl.cpp:3266
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition Decl.cpp:4244
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition Decl.cpp:4232
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3804
QualType getReturnType() const
Definition Decl.h:2976
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:2905
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2504
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition Decl.cpp:4368
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
Definition Decl.cpp:3468
bool isDefaulted() const
Whether this function is defaulted.
Definition Decl.h:2512
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition Decl.cpp:3868
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Definition Decl.cpp:3186
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition Expr.h:4967
Represents a C11 generic selection.
Definition Expr.h:6232
Expr * getResultExpr()
Return the result expression of this controlling expression.
Definition Expr.h:6518
IfStmt - This represents an if/then/else.
Definition Stmt.h:2271
Stmt * getThen()
Definition Stmt.h:2360
Stmt * getInit()
Definition Stmt.h:2421
bool isNonNegatedConsteval() const
Definition Stmt.h:2456
Expr * getCond()
Definition Stmt.h:2348
bool isNegatedConsteval() const
Definition Stmt.h:2460
Stmt * getElse()
Definition Stmt.h:2369
DeclStmt * getConditionVariableDeclStmt()
If this IfStmt has a condition variable, return the faux DeclStmt associated with the creation of tha...
Definition Stmt.h:2404
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
Definition Stmt.cpp:1068
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition Expr.h:1751
const Expr * getSubExpr() const
Definition Expr.h:1763
Represents an implicitly-generated value initialization of an object of a given type.
Definition Expr.h:6107
Represents a field injected from an anonymous union/struct into the parent scope.
Definition Decl.h:3602
Describes an C or C++ initializer list.
Definition Expr.h:5352
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
Definition Expr.h:5455
ArrayRef< Expr * > inits() const
Definition Expr.h:5405
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition ExprCXX.h:1972
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
Definition ExprCXX.h:2098
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Definition ExprCXX.cpp:1433
bool isCompatibleWith(ClangABI Version) const
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
Definition DeclCXX.h:3337
const Stmt * getNamedLoopOrSwitch() const
If this is a named break/continue, get the loop or switch statement that this targets.
Definition Stmt.cpp:1535
A global _GUID constant.
Definition DeclCXX.h:4432
APValue & getAsAPValue() const
Get the value of this MSGuidDecl as an APValue.
Definition DeclCXX.cpp:3872
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition ExprCXX.h:4973
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Definition ExprCXX.h:4998
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition ExprCXX.h:4990
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
Definition ExprCXX.h:5023
LifetimeExtendedTemporaryDecl * getLifetimeExtendedTemporaryDecl()
Definition ExprCXX.h:5013
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition Expr.h:3408
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition Expr.h:3491
Expr * getBase() const
Definition Expr.h:3485
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3744
This represents a decl that may have a name.
Definition Decl.h:275
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:341
Represents a C++ namespace alias.
Definition DeclCXX.h:3230
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Definition ExprObjC.h:219
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition ExprObjC.h:118
ObjCBoxedExpr - used for generalized expression boxing.
Definition ExprObjC.h:158
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition ExprObjC.h:341
ObjCEncodeExpr, used for @encode in Objective-C.
Definition ExprObjC.h:440
QualType getEncodedType() const
Definition ExprObjC.h:459
SourceLocation getAtLoc() const
Definition ExprObjC.h:454
bool isExpressibleAsConstantInitializer() const
Definition ExprObjC.h:67
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition ExprObjC.h:83
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition Expr.h:2571
Expr * getIndexExpr(unsigned Idx)
Definition Expr.h:2630
const OffsetOfNode & getComponent(unsigned Idx) const
Definition Expr.h:2618
unsigned getNumComponents() const
Definition Expr.h:2626
Helper class for OffsetOfExpr.
Definition Expr.h:2465
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
Definition Expr.h:2523
@ Array
An index into an array.
Definition Expr.h:2470
Kind getKind() const
Determine what kind of offsetof node this is.
Definition Expr.h:2519
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1198
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition Expr.h:1248
Expr * getSelectedExpr() const
Definition ExprCXX.h:4692
ParenExpr - This represents a parenthesized expression, e.g.
Definition Expr.h:2226
const Expr * getSubExpr() const
Definition Expr.h:2243
Represents a parameter to a function.
Definition Decl.h:1820
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3396
QualType getPointeeType() const
Definition TypeBase.h:3406
[C99 6.4.2.2] - A predefined identifier such as func.
Definition Expr.h:2049
StringLiteral * getFunctionName()
Definition Expr.h:2093
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition Expr.h:6854
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
Definition Expr.h:6902
ArrayRef< Expr * > semantics()
Definition Expr.h:6926
A (possibly-)qualified type.
Definition TypeBase.h:938
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
Definition TypeBase.h:8512
QualType withConst() const
Definition TypeBase.h:1175
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1005
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8428
bool isConstant(const ASTContext &Ctx) const
Definition TypeBase.h:1098
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition TypeBase.h:8501
Represents a struct/union/class.
Definition Decl.h:4460
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Definition Expr.h:7553
Base for LValueReferenceType and RValueReferenceType.
Definition TypeBase.h:3671
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
bool isSatisfied() const
Whether or not the requires clause is satisfied.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition Stmt.h:3172
Expr * getRetValue()
Definition Stmt.h:3199
SourceLocation getLocation() const
Definition Expr.h:2199
std::string ComputeName(ASTContext &Context) const
Definition Expr.cpp:593
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Definition Expr.h:4687
llvm::APSInt getShuffleMaskIdx(unsigned N) const
Definition Expr.h:4739
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Definition Expr.h:4720
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Definition Expr.h:4726
Represents an expression that computes the length of a parameter pack.
Definition ExprCXX.h:4494
unsigned getPackLength() const
Retrieve the length of the parameter pack.
Definition ExprCXX.h:4568
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition Expr.h:5070
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Definition Expr.cpp:2313
Represents a C++11 static_assert declaration.
Definition DeclCXX.h:4165
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition Expr.h:4639
CompoundStmt * getSubStmt()
Definition Expr.h:4656
Stmt - This represents one statement.
Definition Stmt.h:85
StmtClass getStmtClass() const
Definition Stmt.h:1505
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1819
unsigned getLength() const
Definition Expr.h:1944
uint32_t getCodeUnit(size_t I) const
Return the code unit at the given position.
Definition Expr.h:1906
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, ArrayRef< SourceLocation > Locs)
This is the "fully general" constructor that allows representation of strings formed from one or more...
Definition Expr.cpp:1194
unsigned getCharByteWidth() const
Definition Expr.h:1946
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition ExprCXX.h:4717
const SwitchCase * getNextSwitchCase() const
Definition Stmt.h:1905
SwitchStmt - This represents a 'switch' stmt.
Definition Stmt.h:2521
Expr * getCond()
Definition Stmt.h:2584
Stmt * getBody()
Definition Stmt.h:2596
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
Definition Stmt.cpp:1186
Stmt * getInit()
Definition Stmt.h:2601
SwitchCase * getSwitchCaseList()
Definition Stmt.h:2652
DeclStmt * getConditionVariableDeclStmt()
If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...
Definition Stmt.h:2635
Represents the declaration of a struct/union/class/enum.
Definition Decl.h:3852
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition Decl.h:3953
bool isUnion() const
Definition Decl.h:4063
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition ExprCXX.h:2900
bool getBoolValue() const
Definition ExprCXX.h:2961
bool isStoredAsComparisonResult() const
Definition ExprCXX.h:2957
const APValue & getAPValue() const
Definition ExprCXX.h:2966
bool isStoredAsBoolean() const
Definition ExprCXX.h:2953
The base class of the type hierarchy.
Definition TypeBase.h:1879
bool isVoidType() const
Definition TypeBase.h:9037
bool isBooleanType() const
Definition TypeBase.h:9174
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
Definition Type.cpp:3237
bool isIncompleteArrayType() const
Definition TypeBase.h:8772
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
bool isNothrowT() const
Definition Type.cpp:3421
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
bool isVoidPointerType() const
Definition Type.cpp:841
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
Definition Type.cpp:2641
bool isArrayType() const
Definition TypeBase.h:8764
bool isFunctionPointerType() const
Definition TypeBase.h:8732
bool isConstantMatrixType() const
Definition TypeBase.h:8832
bool isPointerType() const
Definition TypeBase.h:8665
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition TypeBase.h:9081
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9331
bool isReferenceType() const
Definition TypeBase.h:8689
bool isEnumeralType() const
Definition TypeBase.h:8796
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:881
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition TypeBase.h:9159
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Definition TypeBase.h:9006
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2859
bool isAnyComplexType() const
Definition TypeBase.h:8800
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
Definition TypeBase.h:9097
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
Definition TypeBase.h:9217
bool isMemberPointerType() const
Definition TypeBase.h:8746
bool isAtomicType() const
Definition TypeBase.h:8857
EnumDecl * castAsEnumDecl() const
Definition Type.h:59
bool isStdByteType() const
Definition Type.cpp:3440
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition TypeBase.h:9317
bool isPointerOrReferenceType() const
Definition TypeBase.h:8669
bool isFunctionType() const
Definition TypeBase.h:8661
bool isVectorType() const
Definition TypeBase.h:8804
bool isRealFloatingType() const
Floating point categories.
Definition Type.cpp:2529
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2998
bool isFloatingType() const
Definition Type.cpp:2513
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9264
bool isRecordType() const
Definition TypeBase.h:8792
bool isSizelessVectorType() const
Returns true for all scalable vector types.
Definition Type.cpp:2787
bool hasBooleanRepresentation() const
Determine whether this type has a boolean representation – i.e., it is a boolean type,...
Definition Type.cpp:2568
Base class for declarations which introduce a typedef-name.
Definition Decl.h:3697
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition Expr.h:2669
QualType getArgumentType() const
Definition Expr.h:2712
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
Definition Expr.h:2738
UnaryExprOrTypeTrait getKind() const
Definition Expr.h:2701
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2288
Expr * getSubExpr() const
Definition Expr.h:2329
Opcode getOpcode() const
Definition Expr.h:2324
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Definition Expr.h:2342
Represents C++ using-directive.
Definition DeclCXX.h:3125
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:713
QualType getType() const
Definition Decl.h:724
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Definition Decl.cpp:5646
QualType getType() const
Definition Value.cpp:238
Represents a variable declaration or definition.
Definition Decl.h:933
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition Decl.h:1594
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
Definition Decl.h:1603
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition Decl.h:1307
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition Decl.h:1248
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
Definition Decl.cpp:2639
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition Decl.h:1215
const Expr * getInit() const
Definition Decl.h:1392
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
Definition Decl.cpp:2555
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
Definition Decl.h:1275
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Definition Decl.h:1382
Represents a GCC generic vector type.
Definition TypeBase.h:4266
unsigned getNumElements() const
Definition TypeBase.h:4281
QualType getElementType() const
Definition TypeBase.h:4280
WhileStmt - This represents a 'while' stmt.
Definition Stmt.h:2709
Expr * getCond()
Definition Stmt.h:2761
DeclStmt * getConditionVariableDeclStmt()
If this WhileStmt has a condition variable, return the faux DeclStmt associated with the creation of ...
Definition Stmt.h:2797
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
Definition Stmt.cpp:1247
Stmt * getBody()
Definition Stmt.h:2773
ArrayIndexScope(Compiler< Emitter > *Ctx, uint64_t Index)
Definition Compiler.cpp:222
A memory block, either on the stack or in the heap.
Definition InterpBlock.h:43
void invokeDtor()
Invokes the Destructor.
Compilation context for expressions.
Definition Compiler.h:119
llvm::SmallVector< InitLink > InitStack
Definition Compiler.h:508
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E)
bool VisitCXXDeleteExpr(const CXXDeleteExpr *E)
bool VisitOffsetOfExpr(const OffsetOfExpr *E)
bool visitContinueStmt(const ContinueStmt *S)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init, OptPrimType InitT)
Pointer to the array(not the element!) must be on the stack when calling this.
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E)
bool visitInitializerPop(const Expr *E)
Similar, but will also pop the pointer.
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
PrimType classifyPrim(QualType Ty) const
Classifies a known primitive type.
Definition Compiler.h:299
bool VisitTypeTraitExpr(const TypeTraitExpr *E)
bool VisitLambdaExpr(const LambdaExpr *E)
bool VisitMemberExpr(const MemberExpr *E)
llvm::DenseMap< const OpaqueValueExpr *, unsigned > OpaqueExprs
OpaqueValueExpr to location mapping.
Definition Compiler.h:483
bool VisitBinaryOperator(const BinaryOperator *E)
bool visitCXXExpansionStmtInstantiation(const CXXExpansionStmtInstantiation *S)
template for (auto x : {1, 2}) {}
bool visitAttributedStmt(const AttributedStmt *S)
bool VisitPackIndexingExpr(const PackIndexingExpr *E)
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
bool VisitCallExpr(const CallExpr *E)
std::optional< uint64_t > ArrayIndex
Current argument index. Needed to emit ArrayInitIndexExpr.
Definition Compiler.h:489
bool VisitPseudoObjectExpr(const PseudoObjectExpr *E)
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E)
bool visitAPValueInitializer(const APValue &Val, SourceInfo Info, QualType T, bool IsCompleteClass=true)
const Function * getFunction(const FunctionDecl *FD)
Returns a function for the given FunctionDecl.
bool VisitFixedPointBinOp(const BinaryOperator *E)
bool VisitCastExpr(const CastExpr *E)
Definition Compiler.cpp:453
bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E)
bool VisitFixedPointUnaryOperator(const UnaryOperator *E)
bool VisitComplexUnaryOperator(const UnaryOperator *E)
llvm::DenseMap< const SwitchCase *, LabelTy > CaseMap
Definition Compiler.h:125
bool VisitBlockExpr(const BlockExpr *E)
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
bool VisitLogicalBinOp(const BinaryOperator *E)
bool visitCompoundStmt(const CompoundStmt *S)
Context & Ctx
Current compilation context.
Definition Compiler.h:142
const VarDecl * InitializingDecl
Definition Compiler.h:506
bool visitDeclRef(const ValueDecl *D, const Expr *E)
Visit the given decl as if we have a reference to it.
bool visitBreakStmt(const BreakStmt *S)
bool visitExpr(const Expr *E, bool DestroyToplevelScope) override
bool visitForStmt(const ForStmt *S)
bool VisitDeclRefExpr(const DeclRefExpr *E)
bool VisitOpaqueValueExpr(const OpaqueValueExpr *E)
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E)
bool visitAPValue(const APValue &Val, PrimType ValType, SourceInfo Info)
Visit an APValue.
bool VisitStmtExpr(const StmtExpr *E)
bool VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *E)
bool VisitFixedPointLiteral(const FixedPointLiteral *E)
const FunctionDecl * CompilingFunction
Definition Compiler.h:519
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
VarCreationState visitVarDecl(const VarDecl *VD, const Expr *Init, bool Toplevel=false)
Creates and initializes a variable from the given decl.
VariableScope< Emitter > * VarScope
Current scope.
Definition Compiler.h:486
bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init, bool ConstantContext) override
Toplevel visitDeclAndReturn().
bool VisitCXXNewExpr(const CXXNewExpr *E)
bool VisitCompoundAssignOperator(const CompoundAssignOperator *E)
bool visit(const Expr *E) override
Evaluates an expression and places the result on the stack.
bool delegate(const Expr *E)
Just pass evaluation on to E.
bool visitLValueExpr(const Expr *E, bool DestroyToplevelScope) override
bool discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
CaseMap CaseLabels
Switch case mapping.
Definition Compiler.h:515
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
const RecordType * getRecordTy(QualType Ty)
Returns a record type from a record or pointer type.
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E)
bool visitInitList(ArrayRef< const Expr * > Inits, const Expr *ArrayFiller, const Expr *E)
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E)
bool VisitPredefinedExpr(const PredefinedExpr *E)
bool VisitSourceLocExpr(const SourceLocExpr *E)
bool visitDeclStmt(const DeclStmt *DS, bool EvaluateConditionDecl=false)
bool registerRedecl(const VarDecl *VD, const APValue &V)
bool emitCleanup()
Emits scope cleanup instructions.
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E)
bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E)
bool visitInitializer(const Expr *E)
Compiles an initializer.
bool visitDtorCall(const VarDecl *VD, const APValue &Value) override
const Expr * SourceLocDefaultExpr
DefaultInit- or DefaultArgExpr, needed for SourceLocExpr.
Definition Compiler.h:492
bool VisitObjCArrayLiteral(const ObjCArrayLiteral *E)
UnsignedOrNone OptLabelTy
Definition Compiler.h:124
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E)
bool VisitPointerArithBinOp(const BinaryOperator *E)
Perform addition/subtraction of a pointer and an integer or subtraction of two pointers.
bool visitCallArgs(ArrayRef< const Expr * > Args, const FunctionDecl *FuncDecl, bool Activate, bool IsOperatorCall)
bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E)
bool visitDefaultStmt(const DefaultStmt *S)
bool VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
bool visitWithSubstitutions(const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This, const Expr *Condition) override
Evaluate the Condition as if it was in the body of Callee.
typename Emitter::LabelTy LabelTy
Definition Compiler.h:122
VarCreationState visitDecl(const VarDecl *VD)
bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E)
bool visitStmt(const Stmt *S)
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
bool VisitVectorUnaryOperator(const UnaryOperator *E)
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
bool VisitDesignatedInitUpdateExpr(const DesignatedInitUpdateExpr *E)
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
bool VisitRecoveryExpr(const RecoveryExpr *E)
bool VisitRequiresExpr(const RequiresExpr *E)
bool Initializing
Flag inidicating if we're initializing an already created variable.
Definition Compiler.h:505
bool visitReturnStmt(const ReturnStmt *RS)
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitChooseExpr(const ChooseExpr *E)
bool visitFunc(const FunctionDecl *F) override
bool visitCXXForRangeStmt(const CXXForRangeStmt *S)
bool visitCaseStmt(const CaseStmt *S)
bool VisitComplexBinOp(const BinaryOperator *E)
llvm::DenseMap< const ValueDecl *, Scope::Local > Locals
Variable to storage mapping.
Definition Compiler.h:480
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
bool VisitCXXTypeidExpr(const CXXTypeidExpr *E)
UnsignedOrNone allocateTemporary(const Expr *E)
bool VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinID)
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
OptPrimType ReturnType
Type of the expression returned by the function.
Definition Compiler.h:512
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
OptPrimType classify(const Expr *E) const
Definition Compiler.h:293
llvm::SmallVector< LabelInfo > LabelInfoStack
Stack of label information for loops and switch statements.
Definition Compiler.h:517
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
bool visitDoStmt(const DoStmt *S)
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitInitListExpr(const InitListExpr *E)
bool VisitVectorBinOp(const BinaryOperator *E)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
bool DiscardResult
Flag indicating if return value is to be discarded.
Definition Compiler.h:495
bool VisitEmbedExpr(const EmbedExpr *E)
UnsignedOrNone allocateLocal(DeclOrExpr Decl, QualType Ty=QualType(), ScopeKind=ScopeKind::Block)
Allocates a space storing a local given its type.
bool VisitConvertVectorExpr(const ConvertVectorExpr *E)
bool VisitCXXThisExpr(const CXXThisExpr *E)
bool VisitConstantExpr(const ConstantExpr *E)
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool visitSwitchStmt(const SwitchStmt *S)
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E)
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool visitAsLValue(const Expr *E)
unsigned allocateLocalPrimitive(DeclOrExpr Decl, PrimType Ty, bool IsConst, bool IsVolatile=false, ScopeKind SC=ScopeKind::Block)
Creates a local primitive value.
bool visitWhileStmt(const WhileStmt *S)
bool visitIfStmt(const IfStmt *IS)
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
bool canClassify(const Expr *E) const
Definition Compiler.h:295
bool VisitFloatingLiteral(const FloatingLiteral *E)
Program & P
Program to link to.
Definition Compiler.h:144
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
bool VisitGNUNullExpr(const GNUNullExpr *E)
bool VisitImaginaryLiteral(const ImaginaryLiteral *E)
bool VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E)
bool visitCXXTryStmt(const CXXTryStmt *S)
static bool isUnevaluatedBuiltin(unsigned ID)
Unevaluated builtins don't get their arguments put on the stack automatically.
Definition Context.cpp:828
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Definition Context.h:168
Scope used to handle temporaries in toplevel variable declarations.
Definition Compiler.cpp:291
DeclScope(Compiler< Emitter > *Ctx, const VarDecl *VD)
Definition Compiler.cpp:293
Wrapper around fixed point types.
Definition FixedPoint.h:23
static FixedPoint zero(llvm::FixedPointSemantics Sem)
Definition FixedPoint.h:36
If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY.
Definition Floating.h:35
bool singleWord() const
Definition Floating.h:107
Bytecode function.
Definition Function.h:98
bool hasThisPointer() const
Definition Function.h:225
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Definition Function.h:155
InitLinkScope(Compiler< Emitter > *Ctx, InitLink &&Link)
Definition Compiler.cpp:257
Compiler< Emitter > * Ctx
Definition Compiler.cpp:264
InitStackScope(Compiler< Emitter > *Ctx, bool Active)
Definition Compiler.cpp:269
When generating code for e.g.
Definition Compiler.cpp:428
LocOverrideScope(Compiler< Emitter > *Ctx, SourceInfo NewValue, bool Enabled=true)
Definition Compiler.cpp:430
Generic scope for local variables.
Definition Compiler.cpp:113
UnsignedOrNone Idx
Index of the scope in the chain.
Definition Compiler.cpp:216
~LocalScope() override
Emit a Destroy op for this scope.
Definition Compiler.cpp:119
bool destroyLocals(const Expr *E=nullptr) override
Explicit destruction of local variables.
Definition Compiler.cpp:126
bool emitDestructors(const Expr *E=nullptr) override
Definition Compiler.cpp:162
void removeIfStoredOpaqueValue(const Scope::Local &Local)
Definition Compiler.cpp:208
void addLocal(Scope::Local Local) override
Definition Compiler.cpp:138
void forceInit() override
Force-initialize this scope.
Definition Compiler.cpp:154
LocalScope(Compiler< Emitter > *Ctx, ScopeKind Kind=ScopeKind::Block)
Definition Compiler.cpp:115
Sets the context for break/continue statements.
Definition Compiler.cpp:367
typename Compiler< Emitter >::LabelTy LabelTy
Definition Compiler.cpp:369
typename Compiler< Emitter >::OptLabelTy OptLabelTy
Definition Compiler.cpp:370
typename Compiler< Emitter >::LabelInfo LabelInfo
Definition Compiler.cpp:371
LoopScope(Compiler< Emitter > *Ctx, const Stmt *Name, LabelTy BreakLabel, LabelTy ContinueLabel)
Definition Compiler.cpp:373
PrimType value_or(PrimType PT) const
Definition PrimType.h:88
Scope used to handle initialization methods.
Definition Compiler.cpp:311
OptionScope(Compiler< Emitter > *Ctx, bool NewDiscardResult, bool NewInitializing, bool NewToLValue)
Root constructor, compiling or discarding primitives.
Definition Compiler.cpp:314
Context to manage declaration lifetimes.
Definition Program.h:138
Structure/Class descriptor.
Definition Record.h:27
bool isUnion() const
Checks if the record is a union.
Definition Record.h:71
const Field * getField(unsigned I) const
Definition Record.h:97
const Base * getBaseOrNull(const RecordDecl *RD) const
Definition Record.cpp:56
bool hasTrivialDtor() const
Returns true for anonymous unions and records with no destructor or for those with a trivial destruct...
Definition Record.cpp:34
const Base * findVirtualBase(const RecordDecl *RD) const
Returns a virtual base descriptor.
Definition Record.cpp:75
Describes a scope block.
Definition Function.h:35
Describes the statement/declaration an opcode was generated from.
Definition Source.h:77
const Expr * asExpr() const
Definition Source.h:92
SourceLocScope(Compiler< Emitter > *Ctx, const Expr *DefaultExpr)
Definition Compiler.cpp:236
typename Compiler< Emitter >::LabelTy LabelTy
Definition Compiler.cpp:395
typename Compiler< Emitter >::OptLabelTy OptLabelTy
Definition Compiler.cpp:396
typename Compiler< Emitter >::LabelInfo LabelInfo
Definition Compiler.cpp:398
typename Compiler< Emitter >::CaseMap CaseMap
Definition Compiler.cpp:397
SwitchScope(Compiler< Emitter > *Ctx, const Stmt *Name, CaseMap &&CaseLabels, LabelTy BreakLabel, OptLabelTy DefaultLabel)
Definition Compiler.cpp:400
Scope chain managing the variable lifetimes.
Definition Compiler.cpp:55
void addForScopeKind(const Scope::Local &Local, ScopeKind Kind)
Like addExtended, but adds to the nearest scope of the given kind.
Definition Compiler.cpp:70
bool LocalsAlwaysEnabled
Whether locals added to this scope are enabled by default.
Definition Compiler.cpp:102
Compiler< Emitter > * Ctx
Compiler instance.
Definition Compiler.cpp:106
virtual bool emitDestructors(const Expr *E=nullptr)
Definition Compiler.cpp:93
VariableScope(Compiler< Emitter > *Ctx, ScopeKind Kind=ScopeKind::Block)
Definition Compiler.cpp:57
virtual bool destroyLocals(const Expr *E=nullptr)
Definition Compiler.cpp:94
virtual void addLocal(Scope::Local Local)
Definition Compiler.cpp:66
VariableScope * Parent
Link to the parent scope.
Definition Compiler.cpp:108
ScopeKind getKind() const
Definition Compiler.cpp:97
VariableScope * getParent() const
Definition Compiler.cpp:96
bool Sub(InterpState &S, CodePtr OpPC)
Definition Interp.h:436
bool LT(InterpState &S, CodePtr OpPC)
Definition Interp.h:1528
static llvm::RoundingMode getRoundingMode(FPOptions FPO)
constexpr bool isSignedType(PrimType T)
Definition PrimType.h:59
bool Div(InterpState &S, CodePtr OpPC)
1) Pops the RHS from the stack.
Definition Interp.h:781
constexpr bool isPtrType(PrimType T)
Definition PrimType.h:55
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition PrimType.h:213
bool This(InterpState &S, CodePtr OpPC)
Definition Interp.h:3222
constexpr bool isIntegerOrBoolType(PrimType T)
Definition PrimType.h:52
llvm::APFloat APFloat
Definition Floating.h:27
bool InitScope(InterpState &S, uint32_t I)
Definition Interp.h:2869
static void discard(InterpStack &Stk, PrimType T)
static bool isSideEffectFree(const Expr *E)
Check if E has side-effects.
Definition Compiler.cpp:44
llvm::APInt APInt
Definition FixedPoint.h:19
bool LE(InterpState &S, CodePtr OpPC)
Definition Interp.h:1535
PrimType
Enumeration of the primitive types of the VM.
Definition PrimType.h:34
static std::optional< bool > getBoolValue(const Expr *E)
Definition Compiler.cpp:31
static bool Activate(InterpState &S)
Definition Interp.h:2315
bool Init(InterpState &S, CodePtr OpPC)
Definition Interp.h:2432
bool DefaultInit(InterpState &S, CodePtr OpPC, const CXXConstructorDecl *Ctor)
Definition Interp.cpp:2725
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