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