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"
19
20using namespace clang;
21using namespace clang::interp;
22
23using APSInt = llvm::APSInt;
24
25namespace clang {
26namespace interp {
27
28static std::optional<bool> getBoolValue(const Expr *E) {
29 if (const auto *CE = dyn_cast_if_present<ConstantExpr>(Val: E);
30 CE && CE->hasAPValueResult() &&
31 CE->getResultAPValueKind() == APValue::ValueKind::Int) {
32 return CE->getResultAsAPSInt().getBoolValue();
33 }
34
35 return std::nullopt;
36}
37
38/// Scope used to handle temporaries in toplevel variable declarations.
39template <class Emitter> class DeclScope final : public LocalScope<Emitter> {
40public:
41 DeclScope(Compiler<Emitter> *Ctx, const ValueDecl *VD)
42 : LocalScope<Emitter>(Ctx, VD), Scope(Ctx->P),
43 OldInitializingDecl(Ctx->InitializingDecl) {
44 Ctx->InitializingDecl = VD;
45 Ctx->InitStack.push_back(InitLink::Decl(D: VD));
46 }
47
48 ~DeclScope() {
49 this->Ctx->InitializingDecl = OldInitializingDecl;
50 this->Ctx->InitStack.pop_back();
51 }
52
53private:
54 Program::DeclScope Scope;
55 const ValueDecl *OldInitializingDecl;
56};
57
58/// Scope used to handle initialization methods.
59template <class Emitter> class OptionScope final {
60public:
61 /// Root constructor, compiling or discarding primitives.
62 OptionScope(Compiler<Emitter> *Ctx, bool NewDiscardResult,
63 bool NewInitializing)
64 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
65 OldInitializing(Ctx->Initializing) {
66 Ctx->DiscardResult = NewDiscardResult;
67 Ctx->Initializing = NewInitializing;
68 }
69
70 ~OptionScope() {
71 Ctx->DiscardResult = OldDiscardResult;
72 Ctx->Initializing = OldInitializing;
73 }
74
75private:
76 /// Parent context.
77 Compiler<Emitter> *Ctx;
78 /// Old discard flag to restore.
79 bool OldDiscardResult;
80 bool OldInitializing;
81};
82
83template <class Emitter>
84bool InitLink::emit(Compiler<Emitter> *Ctx, const Expr *E) const {
85 switch (Kind) {
86 case K_This:
87 return Ctx->emitThis(E);
88 case K_Field:
89 // We're assuming there's a base pointer on the stack already.
90 return Ctx->emitGetPtrFieldPop(Offset, E);
91 case K_Temp:
92 return Ctx->emitGetPtrLocal(Offset, E);
93 case K_Decl:
94 return Ctx->visitDeclRef(D, E);
95 case K_Elem:
96 if (!Ctx->emitConstUint32(Offset, E))
97 return false;
98 return Ctx->emitArrayElemPtrPopUint32(E);
99 case K_RVO:
100 return Ctx->emitRVOPtr(E);
101 case K_InitList:
102 return true;
103 default:
104 llvm_unreachable("Unhandled InitLink kind");
105 }
106 return true;
107}
108
109/// Scope managing label targets.
110template <class Emitter> class LabelScope {
111public:
112 virtual ~LabelScope() {}
113
114protected:
115 LabelScope(Compiler<Emitter> *Ctx) : Ctx(Ctx) {}
116 /// Compiler instance.
117 Compiler<Emitter> *Ctx;
118};
119
120/// Sets the context for break/continue statements.
121template <class Emitter> class LoopScope final : public LabelScope<Emitter> {
122public:
123 using LabelTy = typename Compiler<Emitter>::LabelTy;
124 using OptLabelTy = typename Compiler<Emitter>::OptLabelTy;
125
126 LoopScope(Compiler<Emitter> *Ctx, LabelTy BreakLabel, LabelTy ContinueLabel)
127 : LabelScope<Emitter>(Ctx), OldBreakLabel(Ctx->BreakLabel),
128 OldContinueLabel(Ctx->ContinueLabel),
129 OldBreakVarScope(Ctx->BreakVarScope),
130 OldContinueVarScope(Ctx->ContinueVarScope) {
131 this->Ctx->BreakLabel = BreakLabel;
132 this->Ctx->ContinueLabel = ContinueLabel;
133 this->Ctx->BreakVarScope = this->Ctx->VarScope;
134 this->Ctx->ContinueVarScope = this->Ctx->VarScope;
135 }
136
137 ~LoopScope() {
138 this->Ctx->BreakLabel = OldBreakLabel;
139 this->Ctx->ContinueLabel = OldContinueLabel;
140 this->Ctx->ContinueVarScope = OldContinueVarScope;
141 this->Ctx->BreakVarScope = OldBreakVarScope;
142 }
143
144private:
145 OptLabelTy OldBreakLabel;
146 OptLabelTy OldContinueLabel;
147 VariableScope<Emitter> *OldBreakVarScope;
148 VariableScope<Emitter> *OldContinueVarScope;
149};
150
151// Sets the context for a switch scope, mapping labels.
152template <class Emitter> class SwitchScope final : public LabelScope<Emitter> {
153public:
154 using LabelTy = typename Compiler<Emitter>::LabelTy;
155 using OptLabelTy = typename Compiler<Emitter>::OptLabelTy;
156 using CaseMap = typename Compiler<Emitter>::CaseMap;
157
158 SwitchScope(Compiler<Emitter> *Ctx, CaseMap &&CaseLabels, LabelTy BreakLabel,
159 OptLabelTy DefaultLabel)
160 : LabelScope<Emitter>(Ctx), OldBreakLabel(Ctx->BreakLabel),
161 OldDefaultLabel(this->Ctx->DefaultLabel),
162 OldCaseLabels(std::move(this->Ctx->CaseLabels)),
163 OldLabelVarScope(Ctx->BreakVarScope) {
164 this->Ctx->BreakLabel = BreakLabel;
165 this->Ctx->DefaultLabel = DefaultLabel;
166 this->Ctx->CaseLabels = std::move(CaseLabels);
167 this->Ctx->BreakVarScope = this->Ctx->VarScope;
168 }
169
170 ~SwitchScope() {
171 this->Ctx->BreakLabel = OldBreakLabel;
172 this->Ctx->DefaultLabel = OldDefaultLabel;
173 this->Ctx->CaseLabels = std::move(OldCaseLabels);
174 this->Ctx->BreakVarScope = OldLabelVarScope;
175 }
176
177private:
178 OptLabelTy OldBreakLabel;
179 OptLabelTy OldDefaultLabel;
180 CaseMap OldCaseLabels;
181 VariableScope<Emitter> *OldLabelVarScope;
182};
183
184template <class Emitter> class StmtExprScope final {
185public:
186 StmtExprScope(Compiler<Emitter> *Ctx) : Ctx(Ctx), OldFlag(Ctx->InStmtExpr) {
187 Ctx->InStmtExpr = true;
188 }
189
190 ~StmtExprScope() { Ctx->InStmtExpr = OldFlag; }
191
192private:
193 Compiler<Emitter> *Ctx;
194 bool OldFlag;
195};
196
197} // namespace interp
198} // namespace clang
199
200template <class Emitter>
201bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
202 const Expr *SubExpr = CE->getSubExpr();
203
204 if (DiscardResult)
205 return this->delegate(SubExpr);
206
207 switch (CE->getCastKind()) {
208 case CK_LValueToRValue: {
209 if (SubExpr->getType().isVolatileQualified())
210 return this->emitInvalidCast(CastKind::Volatile, /*Fatal=*/true, CE);
211
212 std::optional<PrimType> SubExprT = classify(SubExpr->getType());
213 // Prepare storage for the result.
214 if (!Initializing && !SubExprT) {
215 std::optional<unsigned> LocalIndex = allocateLocal(Decl: SubExpr);
216 if (!LocalIndex)
217 return false;
218 if (!this->emitGetPtrLocal(*LocalIndex, CE))
219 return false;
220 }
221
222 if (!this->visit(SubExpr))
223 return false;
224
225 if (SubExprT)
226 return this->emitLoadPop(*SubExprT, CE);
227
228 // If the subexpr type is not primitive, we need to perform a copy here.
229 // This happens for example in C when dereferencing a pointer of struct
230 // type.
231 return this->emitMemcpy(CE);
232 }
233
234 case CK_DerivedToBaseMemberPointer: {
235 assert(classifyPrim(CE->getType()) == PT_MemberPtr);
236 assert(classifyPrim(SubExpr->getType()) == PT_MemberPtr);
237 const auto *FromMP = SubExpr->getType()->castAs<MemberPointerType>();
238 const auto *ToMP = CE->getType()->castAs<MemberPointerType>();
239
240 unsigned DerivedOffset =
241 Ctx.collectBaseOffset(BaseDecl: ToMP->getMostRecentCXXRecordDecl(),
242 DerivedDecl: FromMP->getMostRecentCXXRecordDecl());
243
244 if (!this->delegate(SubExpr))
245 return false;
246
247 return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
248 }
249
250 case CK_BaseToDerivedMemberPointer: {
251 assert(classifyPrim(CE) == PT_MemberPtr);
252 assert(classifyPrim(SubExpr) == PT_MemberPtr);
253 const auto *FromMP = SubExpr->getType()->castAs<MemberPointerType>();
254 const auto *ToMP = CE->getType()->castAs<MemberPointerType>();
255
256 unsigned DerivedOffset =
257 Ctx.collectBaseOffset(BaseDecl: FromMP->getMostRecentCXXRecordDecl(),
258 DerivedDecl: ToMP->getMostRecentCXXRecordDecl());
259
260 if (!this->delegate(SubExpr))
261 return false;
262 return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
263 }
264
265 case CK_UncheckedDerivedToBase:
266 case CK_DerivedToBase: {
267 if (!this->delegate(SubExpr))
268 return false;
269
270 const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
271 if (const auto *PT = dyn_cast<PointerType>(Val&: Ty))
272 return PT->getPointeeType()->getAsCXXRecordDecl();
273 return Ty->getAsCXXRecordDecl();
274 };
275
276 // FIXME: We can express a series of non-virtual casts as a single
277 // GetPtrBasePop op.
278 QualType CurType = SubExpr->getType();
279 for (const CXXBaseSpecifier *B : CE->path()) {
280 if (B->isVirtual()) {
281 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))
282 return false;
283 CurType = B->getType();
284 } else {
285 unsigned DerivedOffset = collectBaseOffset(BaseType: B->getType(), DerivedType: CurType);
286 if (!this->emitGetPtrBasePop(
287 DerivedOffset, /*NullOK=*/CE->getType()->isPointerType(), CE))
288 return false;
289 CurType = B->getType();
290 }
291 }
292
293 return true;
294 }
295
296 case CK_BaseToDerived: {
297 if (!this->delegate(SubExpr))
298 return false;
299 unsigned DerivedOffset =
300 collectBaseOffset(BaseType: SubExpr->getType(), DerivedType: CE->getType());
301
302 const Type *TargetType = CE->getType().getTypePtr();
303 if (TargetType->isPointerOrReferenceType())
304 TargetType = TargetType->getPointeeType().getTypePtr();
305 return this->emitGetPtrDerivedPop(DerivedOffset,
306 /*NullOK=*/CE->getType()->isPointerType(),
307 TargetType, CE);
308 }
309
310 case CK_FloatingCast: {
311 // HLSL uses CK_FloatingCast to cast between vectors.
312 if (!SubExpr->getType()->isFloatingType() ||
313 !CE->getType()->isFloatingType())
314 return false;
315 if (!this->visit(SubExpr))
316 return false;
317 const auto *TargetSemantics = &Ctx.getFloatSemantics(T: CE->getType());
318 return this->emitCastFP(TargetSemantics, getRoundingMode(E: CE), CE);
319 }
320
321 case CK_IntegralToFloating: {
322 if (!CE->getType()->isRealFloatingType())
323 return false;
324 if (!this->visit(SubExpr))
325 return false;
326 const auto *TargetSemantics = &Ctx.getFloatSemantics(T: CE->getType());
327 return this->emitCastIntegralFloating(
328 classifyPrim(SubExpr), TargetSemantics, getFPOptions(E: CE), CE);
329 }
330
331 case CK_FloatingToBoolean: {
332 if (!SubExpr->getType()->isRealFloatingType() ||
333 !CE->getType()->isBooleanType())
334 return false;
335 if (const auto *FL = dyn_cast<FloatingLiteral>(Val: SubExpr))
336 return this->emitConstBool(FL->getValue().isNonZero(), CE);
337 if (!this->visit(SubExpr))
338 return false;
339 return this->emitCastFloatingIntegralBool(getFPOptions(E: CE), CE);
340 }
341
342 case CK_FloatingToIntegral: {
343 if (!this->visit(SubExpr))
344 return false;
345 PrimType ToT = classifyPrim(CE);
346 if (ToT == PT_IntAP)
347 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(T: CE->getType()),
348 getFPOptions(E: CE), CE);
349 if (ToT == PT_IntAPS)
350 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(T: CE->getType()),
351 getFPOptions(E: CE), CE);
352
353 return this->emitCastFloatingIntegral(ToT, getFPOptions(E: CE), CE);
354 }
355
356 case CK_NullToPointer:
357 case CK_NullToMemberPointer: {
358 if (!this->discard(SubExpr))
359 return false;
360 const Descriptor *Desc = nullptr;
361 const QualType PointeeType = CE->getType()->getPointeeType();
362 if (!PointeeType.isNull()) {
363 if (std::optional<PrimType> T = classify(PointeeType))
364 Desc = P.createDescriptor(D: SubExpr, T: *T);
365 else
366 Desc = P.createDescriptor(D: SubExpr, Ty: PointeeType.getTypePtr(),
367 MDSize: std::nullopt, /*IsConst=*/true);
368 }
369
370 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(QT: CE->getType());
371 return this->emitNull(classifyPrim(CE->getType()), Val, Desc, CE);
372 }
373
374 case CK_PointerToIntegral: {
375 if (!this->visit(SubExpr))
376 return false;
377
378 // If SubExpr doesn't result in a pointer, make it one.
379 if (PrimType FromT = classifyPrim(SubExpr->getType()); FromT != PT_Ptr) {
380 assert(isPtrType(FromT));
381 if (!this->emitDecayPtr(FromT, PT_Ptr, CE))
382 return false;
383 }
384
385 PrimType T = classifyPrim(CE->getType());
386 if (T == PT_IntAP)
387 return this->emitCastPointerIntegralAP(Ctx.getBitWidth(T: CE->getType()),
388 CE);
389 if (T == PT_IntAPS)
390 return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(T: CE->getType()),
391 CE);
392 return this->emitCastPointerIntegral(T, CE);
393 }
394
395 case CK_ArrayToPointerDecay: {
396 if (!this->visit(SubExpr))
397 return false;
398 return this->emitArrayDecay(CE);
399 }
400
401 case CK_IntegralToPointer: {
402 QualType IntType = SubExpr->getType();
403 assert(IntType->isIntegralOrEnumerationType());
404 if (!this->visit(SubExpr))
405 return false;
406 // FIXME: I think the discard is wrong since the int->ptr cast might cause a
407 // diagnostic.
408 PrimType T = classifyPrim(IntType);
409 QualType PtrType = CE->getType();
410 const Descriptor *Desc;
411 if (std::optional<PrimType> T = classify(PtrType->getPointeeType()))
412 Desc = P.createDescriptor(D: SubExpr, T: *T);
413 else if (PtrType->getPointeeType()->isVoidType())
414 Desc = nullptr;
415 else
416 Desc = P.createDescriptor(D: CE, Ty: PtrType->getPointeeType().getTypePtr(),
417 MDSize: Descriptor::InlineDescMD, /*IsConst=*/true);
418
419 if (!this->emitGetIntPtr(T, Desc, CE))
420 return false;
421
422 PrimType DestPtrT = classifyPrim(PtrType);
423 if (DestPtrT == PT_Ptr)
424 return true;
425
426 // In case we're converting the integer to a non-Pointer.
427 return this->emitDecayPtr(PT_Ptr, DestPtrT, CE);
428 }
429
430 case CK_AtomicToNonAtomic:
431 case CK_ConstructorConversion:
432 case CK_FunctionToPointerDecay:
433 case CK_NonAtomicToAtomic:
434 case CK_NoOp:
435 case CK_UserDefinedConversion:
436 case CK_AddressSpaceConversion:
437 case CK_CPointerToObjCPointerCast:
438 return this->delegate(SubExpr);
439
440 case CK_BitCast: {
441 // Reject bitcasts to atomic types.
442 if (CE->getType()->isAtomicType()) {
443 if (!this->discard(SubExpr))
444 return false;
445 return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, CE);
446 }
447 QualType SubExprTy = SubExpr->getType();
448 std::optional<PrimType> FromT = classify(SubExprTy);
449 // Casts from integer/vector to vector.
450 if (CE->getType()->isVectorType())
451 return this->emitBuiltinBitCast(CE);
452
453 std::optional<PrimType> ToT = classify(CE->getType());
454 if (!FromT || !ToT)
455 return false;
456
457 assert(isPtrType(*FromT));
458 assert(isPtrType(*ToT));
459 if (FromT == ToT) {
460 if (CE->getType()->isVoidPointerType())
461 return this->delegate(SubExpr);
462
463 if (!this->visit(SubExpr))
464 return false;
465 if (CE->getType()->isFunctionPointerType())
466 return true;
467 if (FromT == PT_Ptr)
468 return this->emitPtrPtrCast(SubExprTy->isVoidPointerType(), CE);
469 return true;
470 }
471
472 if (!this->visit(SubExpr))
473 return false;
474 return this->emitDecayPtr(*FromT, *ToT, CE);
475 }
476 case CK_IntegralToBoolean:
477 case CK_FixedPointToBoolean: {
478 // HLSL uses this to cast to one-element vectors.
479 std::optional<PrimType> FromT = classify(SubExpr->getType());
480 if (!FromT)
481 return false;
482
483 if (const auto *IL = dyn_cast<IntegerLiteral>(Val: SubExpr))
484 return this->emitConst(IL->getValue(), CE);
485 if (!this->visit(SubExpr))
486 return false;
487 return this->emitCast(*FromT, classifyPrim(CE), CE);
488 }
489
490 case CK_BooleanToSignedIntegral:
491 case CK_IntegralCast: {
492 std::optional<PrimType> FromT = classify(SubExpr->getType());
493 std::optional<PrimType> ToT = classify(CE->getType());
494 if (!FromT || !ToT)
495 return false;
496
497 // Try to emit a casted known constant value directly.
498 if (const auto *IL = dyn_cast<IntegerLiteral>(Val: SubExpr)) {
499 if (ToT != PT_IntAP && ToT != PT_IntAPS && FromT != PT_IntAP &&
500 FromT != PT_IntAPS && !CE->getType()->isEnumeralType())
501 return this->emitConst(IL->getValue(), CE);
502 if (!this->emitConst(IL->getValue(), SubExpr))
503 return false;
504 } else {
505 if (!this->visit(SubExpr))
506 return false;
507 }
508
509 // Possibly diagnose casts to enum types if the target type does not
510 // have a fixed size.
511 if (Ctx.getLangOpts().CPlusPlus && CE->getType()->isEnumeralType()) {
512 if (const auto *ET = CE->getType().getCanonicalType()->castAs<EnumType>();
513 !ET->getDecl()->isFixed()) {
514 if (!this->emitCheckEnumValue(*FromT, ET->getDecl(), CE))
515 return false;
516 }
517 }
518
519 if (ToT == PT_IntAP) {
520 if (!this->emitCastAP(*FromT, Ctx.getBitWidth(T: CE->getType()), CE))
521 return false;
522 } else if (ToT == PT_IntAPS) {
523 if (!this->emitCastAPS(*FromT, Ctx.getBitWidth(T: CE->getType()), CE))
524 return false;
525 } else {
526 if (FromT == ToT)
527 return true;
528 if (!this->emitCast(*FromT, *ToT, CE))
529 return false;
530 }
531 if (CE->getCastKind() == CK_BooleanToSignedIntegral)
532 return this->emitNeg(*ToT, CE);
533 return true;
534 }
535
536 case CK_PointerToBoolean:
537 case CK_MemberPointerToBoolean: {
538 PrimType PtrT = classifyPrim(SubExpr->getType());
539
540 if (!this->visit(SubExpr))
541 return false;
542 return this->emitIsNonNull(PtrT, CE);
543 }
544
545 case CK_IntegralComplexToBoolean:
546 case CK_FloatingComplexToBoolean: {
547 if (!this->visit(SubExpr))
548 return false;
549 return this->emitComplexBoolCast(SubExpr);
550 }
551
552 case CK_IntegralComplexToReal:
553 case CK_FloatingComplexToReal:
554 return this->emitComplexReal(SubExpr);
555
556 case CK_IntegralRealToComplex:
557 case CK_FloatingRealToComplex: {
558 // We're creating a complex value here, so we need to
559 // allocate storage for it.
560 if (!Initializing) {
561 std::optional<unsigned> LocalIndex = allocateTemporary(E: CE);
562 if (!LocalIndex)
563 return false;
564 if (!this->emitGetPtrLocal(*LocalIndex, CE))
565 return false;
566 }
567
568 PrimType T = classifyPrim(SubExpr->getType());
569 // Init the complex value to {SubExpr, 0}.
570 if (!this->visitArrayElemInit(0, SubExpr, T))
571 return false;
572 // Zero-init the second element.
573 if (!this->visitZeroInitializer(T, SubExpr->getType(), SubExpr))
574 return false;
575 return this->emitInitElem(T, 1, SubExpr);
576 }
577
578 case CK_IntegralComplexCast:
579 case CK_FloatingComplexCast:
580 case CK_IntegralComplexToFloatingComplex:
581 case CK_FloatingComplexToIntegralComplex: {
582 assert(CE->getType()->isAnyComplexType());
583 assert(SubExpr->getType()->isAnyComplexType());
584 if (!Initializing) {
585 std::optional<unsigned> LocalIndex = allocateLocal(Decl: CE);
586 if (!LocalIndex)
587 return false;
588 if (!this->emitGetPtrLocal(*LocalIndex, CE))
589 return false;
590 }
591
592 // Location for the SubExpr.
593 // Since SubExpr is of complex type, visiting it results in a pointer
594 // anyway, so we just create a temporary pointer variable.
595 unsigned SubExprOffset =
596 allocateLocalPrimitive(Decl: SubExpr, Ty: PT_Ptr, /*IsConst=*/true);
597 if (!this->visit(SubExpr))
598 return false;
599 if (!this->emitSetLocal(PT_Ptr, SubExprOffset, CE))
600 return false;
601
602 PrimType SourceElemT = classifyComplexElementType(T: SubExpr->getType());
603 QualType DestElemType =
604 CE->getType()->getAs<ComplexType>()->getElementType();
605 PrimType DestElemT = classifyPrim(DestElemType);
606 // Cast both elements individually.
607 for (unsigned I = 0; I != 2; ++I) {
608 if (!this->emitGetLocal(PT_Ptr, SubExprOffset, CE))
609 return false;
610 if (!this->emitArrayElemPop(SourceElemT, I, CE))
611 return false;
612
613 // Do the cast.
614 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
615 return false;
616
617 // Save the value.
618 if (!this->emitInitElem(DestElemT, I, CE))
619 return false;
620 }
621 return true;
622 }
623
624 case CK_VectorSplat: {
625 assert(!classify(CE->getType()));
626 assert(classify(SubExpr->getType()));
627 assert(CE->getType()->isVectorType());
628
629 if (!Initializing) {
630 std::optional<unsigned> LocalIndex = allocateLocal(Decl: CE);
631 if (!LocalIndex)
632 return false;
633 if (!this->emitGetPtrLocal(*LocalIndex, CE))
634 return false;
635 }
636
637 const auto *VT = CE->getType()->getAs<VectorType>();
638 PrimType ElemT = classifyPrim(SubExpr->getType());
639 unsigned ElemOffset =
640 allocateLocalPrimitive(Decl: SubExpr, Ty: ElemT, /*IsConst=*/true);
641
642 // Prepare a local variable for the scalar value.
643 if (!this->visit(SubExpr))
644 return false;
645 if (classifyPrim(SubExpr) == PT_Ptr && !this->emitLoadPop(ElemT, CE))
646 return false;
647
648 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
649 return false;
650
651 for (unsigned I = 0; I != VT->getNumElements(); ++I) {
652 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
653 return false;
654 if (!this->emitInitElem(ElemT, I, CE))
655 return false;
656 }
657
658 return true;
659 }
660
661 case CK_HLSLVectorTruncation: {
662 assert(SubExpr->getType()->isVectorType());
663 if (std::optional<PrimType> ResultT = classify(CE)) {
664 assert(!DiscardResult);
665 // Result must be either a float or integer. Take the first element.
666 if (!this->visit(SubExpr))
667 return false;
668 return this->emitArrayElemPop(*ResultT, 0, CE);
669 }
670 // Otherwise, this truncates from one vector type to another.
671 assert(CE->getType()->isVectorType());
672
673 if (!Initializing) {
674 std::optional<unsigned> LocalIndex = allocateTemporary(E: CE);
675 if (!LocalIndex)
676 return false;
677 if (!this->emitGetPtrLocal(*LocalIndex, CE))
678 return false;
679 }
680 unsigned ToSize = CE->getType()->getAs<VectorType>()->getNumElements();
681 assert(SubExpr->getType()->getAs<VectorType>()->getNumElements() > ToSize);
682 if (!this->visit(SubExpr))
683 return false;
684 return this->emitCopyArray(classifyVectorElementType(T: CE->getType()), 0, 0,
685 ToSize, CE);
686 };
687
688 case CK_IntegralToFixedPoint: {
689 if (!this->visit(SubExpr))
690 return false;
691
692 auto Sem =
693 Ctx.getASTContext().getFixedPointSemantics(Ty: CE->getType()).toOpaqueInt();
694 return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->getType()),
695 Sem, CE);
696 }
697 case CK_FloatingToFixedPoint: {
698 if (!this->visit(SubExpr))
699 return false;
700
701 auto Sem =
702 Ctx.getASTContext().getFixedPointSemantics(Ty: CE->getType()).toOpaqueInt();
703 return this->emitCastFloatingFixedPoint(Sem, CE);
704 }
705 case CK_FixedPointToFloating: {
706 if (!this->visit(SubExpr))
707 return false;
708 const auto *TargetSemantics = &Ctx.getFloatSemantics(T: CE->getType());
709 return this->emitCastFixedPointFloating(TargetSemantics, CE);
710 }
711 case CK_FixedPointToIntegral: {
712 if (!this->visit(SubExpr))
713 return false;
714 return this->emitCastFixedPointIntegral(classifyPrim(CE->getType()), CE);
715 }
716 case CK_FixedPointCast: {
717 if (!this->visit(SubExpr))
718 return false;
719 auto Sem =
720 Ctx.getASTContext().getFixedPointSemantics(Ty: CE->getType()).toOpaqueInt();
721 return this->emitCastFixedPoint(Sem, CE);
722 }
723
724 case CK_ToVoid:
725 return discard(E: SubExpr);
726
727 default:
728 return this->emitInvalid(CE);
729 }
730 llvm_unreachable("Unhandled clang::CastKind enum");
731}
732
733template <class Emitter>
734bool Compiler<Emitter>::VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *E) {
735 return this->emitBuiltinBitCast(E);
736}
737
738template <class Emitter>
739bool Compiler<Emitter>::VisitIntegerLiteral(const IntegerLiteral *LE) {
740 if (DiscardResult)
741 return true;
742
743 return this->emitConst(LE->getValue(), LE);
744}
745
746template <class Emitter>
747bool Compiler<Emitter>::VisitFloatingLiteral(const FloatingLiteral *E) {
748 if (DiscardResult)
749 return true;
750
751 APFloat F = E->getValue();
752 return this->emitFloat(F, E);
753}
754
755template <class Emitter>
756bool Compiler<Emitter>::VisitImaginaryLiteral(const ImaginaryLiteral *E) {
757 assert(E->getType()->isAnyComplexType());
758 if (DiscardResult)
759 return true;
760
761 if (!Initializing) {
762 std::optional<unsigned> LocalIndex = allocateTemporary(E);
763 if (!LocalIndex)
764 return false;
765 if (!this->emitGetPtrLocal(*LocalIndex, E))
766 return false;
767 }
768
769 const Expr *SubExpr = E->getSubExpr();
770 PrimType SubExprT = classifyPrim(SubExpr->getType());
771
772 if (!this->visitZeroInitializer(SubExprT, SubExpr->getType(), SubExpr))
773 return false;
774 if (!this->emitInitElem(SubExprT, 0, SubExpr))
775 return false;
776 return this->visitArrayElemInit(1, SubExpr, SubExprT);
777}
778
779template <class Emitter>
780bool Compiler<Emitter>::VisitFixedPointLiteral(const FixedPointLiteral *E) {
781 assert(E->getType()->isFixedPointType());
782 assert(classifyPrim(E) == PT_FixedPoint);
783
784 if (DiscardResult)
785 return true;
786
787 auto Sem = Ctx.getASTContext().getFixedPointSemantics(Ty: E->getType());
788 APInt Value = E->getValue();
789 return this->emitConstFixedPoint(FixedPoint(Value, Sem), E);
790}
791
792template <class Emitter>
793bool Compiler<Emitter>::VisitParenExpr(const ParenExpr *E) {
794 return this->delegate(E->getSubExpr());
795}
796
797template <class Emitter>
798bool Compiler<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
799 // Need short-circuiting for these.
800 if (BO->isLogicalOp() && !BO->getType()->isVectorType())
801 return this->VisitLogicalBinOp(BO);
802
803 const Expr *LHS = BO->getLHS();
804 const Expr *RHS = BO->getRHS();
805
806 // Handle comma operators. Just discard the LHS
807 // and delegate to RHS.
808 if (BO->isCommaOp()) {
809 if (!this->discard(LHS))
810 return false;
811 if (RHS->getType()->isVoidType())
812 return this->discard(RHS);
813
814 return this->delegate(RHS);
815 }
816
817 if (BO->getType()->isAnyComplexType())
818 return this->VisitComplexBinOp(BO);
819 if (BO->getType()->isVectorType())
820 return this->VisitVectorBinOp(BO);
821 if ((LHS->getType()->isAnyComplexType() ||
822 RHS->getType()->isAnyComplexType()) &&
823 BO->isComparisonOp())
824 return this->emitComplexComparison(LHS, RHS, BO);
825 if (LHS->getType()->isFixedPointType() || RHS->getType()->isFixedPointType())
826 return this->VisitFixedPointBinOp(BO);
827
828 if (BO->isPtrMemOp()) {
829 if (!this->visit(LHS))
830 return false;
831
832 if (!this->visit(RHS))
833 return false;
834
835 if (!this->emitToMemberPtr(BO))
836 return false;
837
838 if (classifyPrim(BO) == PT_MemberPtr)
839 return true;
840
841 if (!this->emitCastMemberPtrPtr(BO))
842 return false;
843 return DiscardResult ? this->emitPopPtr(BO) : true;
844 }
845
846 // Typecheck the args.
847 std::optional<PrimType> LT = classify(LHS);
848 std::optional<PrimType> RT = classify(RHS);
849 std::optional<PrimType> T = classify(BO->getType());
850
851 // Special case for C++'s three-way/spaceship operator <=>, which
852 // returns a std::{strong,weak,partial}_ordering (which is a class, so doesn't
853 // have a PrimType).
854 if (!T && BO->getOpcode() == BO_Cmp) {
855 if (DiscardResult)
856 return true;
857 const ComparisonCategoryInfo *CmpInfo =
858 Ctx.getASTContext().CompCategories.lookupInfoForType(Ty: BO->getType());
859 assert(CmpInfo);
860
861 // We need a temporary variable holding our return value.
862 if (!Initializing) {
863 std::optional<unsigned> ResultIndex = this->allocateLocal(BO);
864 if (!this->emitGetPtrLocal(*ResultIndex, BO))
865 return false;
866 }
867
868 if (!visit(E: LHS) || !visit(E: RHS))
869 return false;
870
871 return this->emitCMP3(*LT, CmpInfo, BO);
872 }
873
874 if (!LT || !RT || !T)
875 return false;
876
877 // Pointer arithmetic special case.
878 if (BO->getOpcode() == BO_Add || BO->getOpcode() == BO_Sub) {
879 if (isPtrType(T: *T) || (isPtrType(T: *LT) && isPtrType(T: *RT)))
880 return this->VisitPointerArithBinOp(BO);
881 }
882
883 // Assignments require us to evalute the RHS first.
884 if (BO->getOpcode() == BO_Assign) {
885
886 if (!visit(E: RHS) || !visit(E: LHS))
887 return false;
888
889 // We don't support assignments in C.
890 if (!Ctx.getLangOpts().CPlusPlus && !this->emitInvalid(BO))
891 return false;
892
893 if (!this->emitFlip(*LT, *RT, BO))
894 return false;
895 } else {
896 if (!visit(E: LHS) || !visit(E: RHS))
897 return false;
898 }
899
900 // For languages such as C, cast the result of one
901 // of our comparision opcodes to T (which is usually int).
902 auto MaybeCastToBool = [this, T, BO](bool Result) {
903 if (!Result)
904 return false;
905 if (DiscardResult)
906 return this->emitPop(*T, BO);
907 if (T != PT_Bool)
908 return this->emitCast(PT_Bool, *T, BO);
909 return true;
910 };
911
912 auto Discard = [this, T, BO](bool Result) {
913 if (!Result)
914 return false;
915 return DiscardResult ? this->emitPop(*T, BO) : true;
916 };
917
918 switch (BO->getOpcode()) {
919 case BO_EQ:
920 return MaybeCastToBool(this->emitEQ(*LT, BO));
921 case BO_NE:
922 return MaybeCastToBool(this->emitNE(*LT, BO));
923 case BO_LT:
924 return MaybeCastToBool(this->emitLT(*LT, BO));
925 case BO_LE:
926 return MaybeCastToBool(this->emitLE(*LT, BO));
927 case BO_GT:
928 return MaybeCastToBool(this->emitGT(*LT, BO));
929 case BO_GE:
930 return MaybeCastToBool(this->emitGE(*LT, BO));
931 case BO_Sub:
932 if (BO->getType()->isFloatingType())
933 return Discard(this->emitSubf(getFPOptions(E: BO), BO));
934 return Discard(this->emitSub(*T, BO));
935 case BO_Add:
936 if (BO->getType()->isFloatingType())
937 return Discard(this->emitAddf(getFPOptions(E: BO), BO));
938 return Discard(this->emitAdd(*T, BO));
939 case BO_Mul:
940 if (BO->getType()->isFloatingType())
941 return Discard(this->emitMulf(getFPOptions(E: BO), BO));
942 return Discard(this->emitMul(*T, BO));
943 case BO_Rem:
944 return Discard(this->emitRem(*T, BO));
945 case BO_Div:
946 if (BO->getType()->isFloatingType())
947 return Discard(this->emitDivf(getFPOptions(E: BO), BO));
948 return Discard(this->emitDiv(*T, BO));
949 case BO_Assign:
950 if (DiscardResult)
951 return LHS->refersToBitField() ? this->emitStoreBitFieldPop(*T, BO)
952 : this->emitStorePop(*T, BO);
953 if (LHS->refersToBitField()) {
954 if (!this->emitStoreBitField(*T, BO))
955 return false;
956 } else {
957 if (!this->emitStore(*T, BO))
958 return false;
959 }
960 // Assignments aren't necessarily lvalues in C.
961 // Load from them in that case.
962 if (!BO->isLValue())
963 return this->emitLoadPop(*T, BO);
964 return true;
965 case BO_And:
966 return Discard(this->emitBitAnd(*T, BO));
967 case BO_Or:
968 return Discard(this->emitBitOr(*T, BO));
969 case BO_Shl:
970 return Discard(this->emitShl(*LT, *RT, BO));
971 case BO_Shr:
972 return Discard(this->emitShr(*LT, *RT, BO));
973 case BO_Xor:
974 return Discard(this->emitBitXor(*T, BO));
975 case BO_LOr:
976 case BO_LAnd:
977 llvm_unreachable("Already handled earlier");
978 default:
979 return false;
980 }
981
982 llvm_unreachable("Unhandled binary op");
983}
984
985/// Perform addition/subtraction of a pointer and an integer or
986/// subtraction of two pointers.
987template <class Emitter>
988bool Compiler<Emitter>::VisitPointerArithBinOp(const BinaryOperator *E) {
989 BinaryOperatorKind Op = E->getOpcode();
990 const Expr *LHS = E->getLHS();
991 const Expr *RHS = E->getRHS();
992
993 if ((Op != BO_Add && Op != BO_Sub) ||
994 (!LHS->getType()->isPointerType() && !RHS->getType()->isPointerType()))
995 return false;
996
997 std::optional<PrimType> LT = classify(LHS);
998 std::optional<PrimType> RT = classify(RHS);
999
1000 if (!LT || !RT)
1001 return false;
1002
1003 // Visit the given pointer expression and optionally convert to a PT_Ptr.
1004 auto visitAsPointer = [&](const Expr *E, PrimType T) -> bool {
1005 if (!this->visit(E))
1006 return false;
1007 if (T != PT_Ptr)
1008 return this->emitDecayPtr(T, PT_Ptr, E);
1009 return true;
1010 };
1011
1012 if (LHS->getType()->isPointerType() && RHS->getType()->isPointerType()) {
1013 if (Op != BO_Sub)
1014 return false;
1015
1016 assert(E->getType()->isIntegerType());
1017 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *LT))
1018 return false;
1019
1020 PrimType IntT = classifyPrim(E->getType());
1021 if (!this->emitSubPtr(IntT, E))
1022 return false;
1023 return DiscardResult ? this->emitPop(IntT, E) : true;
1024 }
1025
1026 PrimType OffsetType;
1027 if (LHS->getType()->isIntegerType()) {
1028 if (!visitAsPointer(RHS, *RT))
1029 return false;
1030 if (!this->visit(LHS))
1031 return false;
1032 OffsetType = *LT;
1033 } else if (RHS->getType()->isIntegerType()) {
1034 if (!visitAsPointer(LHS, *LT))
1035 return false;
1036 if (!this->visit(RHS))
1037 return false;
1038 OffsetType = *RT;
1039 } else {
1040 return false;
1041 }
1042
1043 // Do the operation and optionally transform to
1044 // result pointer type.
1045 if (Op == BO_Add) {
1046 if (!this->emitAddOffset(OffsetType, E))
1047 return false;
1048
1049 if (classifyPrim(E) != PT_Ptr)
1050 return this->emitDecayPtr(PT_Ptr, classifyPrim(E), E);
1051 return true;
1052 } else if (Op == BO_Sub) {
1053 if (!this->emitSubOffset(OffsetType, E))
1054 return false;
1055
1056 if (classifyPrim(E) != PT_Ptr)
1057 return this->emitDecayPtr(PT_Ptr, classifyPrim(E), E);
1058 return true;
1059 }
1060
1061 return false;
1062}
1063
1064template <class Emitter>
1065bool Compiler<Emitter>::VisitLogicalBinOp(const BinaryOperator *E) {
1066 assert(E->isLogicalOp());
1067 BinaryOperatorKind Op = E->getOpcode();
1068 const Expr *LHS = E->getLHS();
1069 const Expr *RHS = E->getRHS();
1070 std::optional<PrimType> T = classify(E->getType());
1071
1072 if (Op == BO_LOr) {
1073 // Logical OR. Visit LHS and only evaluate RHS if LHS was FALSE.
1074 LabelTy LabelTrue = this->getLabel();
1075 LabelTy LabelEnd = this->getLabel();
1076
1077 if (!this->visitBool(LHS))
1078 return false;
1079 if (!this->jumpTrue(LabelTrue))
1080 return false;
1081
1082 if (!this->visitBool(RHS))
1083 return false;
1084 if (!this->jump(LabelEnd))
1085 return false;
1086
1087 this->emitLabel(LabelTrue);
1088 this->emitConstBool(true, E);
1089 this->fallthrough(LabelEnd);
1090 this->emitLabel(LabelEnd);
1091
1092 } else {
1093 assert(Op == BO_LAnd);
1094 // Logical AND.
1095 // Visit LHS. Only visit RHS if LHS was TRUE.
1096 LabelTy LabelFalse = this->getLabel();
1097 LabelTy LabelEnd = this->getLabel();
1098
1099 if (!this->visitBool(LHS))
1100 return false;
1101 if (!this->jumpFalse(LabelFalse))
1102 return false;
1103
1104 if (!this->visitBool(RHS))
1105 return false;
1106 if (!this->jump(LabelEnd))
1107 return false;
1108
1109 this->emitLabel(LabelFalse);
1110 this->emitConstBool(false, E);
1111 this->fallthrough(LabelEnd);
1112 this->emitLabel(LabelEnd);
1113 }
1114
1115 if (DiscardResult)
1116 return this->emitPopBool(E);
1117
1118 // For C, cast back to integer type.
1119 assert(T);
1120 if (T != PT_Bool)
1121 return this->emitCast(PT_Bool, *T, E);
1122 return true;
1123}
1124
1125template <class Emitter>
1126bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
1127 // Prepare storage for result.
1128 if (!Initializing) {
1129 std::optional<unsigned> LocalIndex = allocateTemporary(E);
1130 if (!LocalIndex)
1131 return false;
1132 if (!this->emitGetPtrLocal(*LocalIndex, E))
1133 return false;
1134 }
1135
1136 // Both LHS and RHS might _not_ be of complex type, but one of them
1137 // needs to be.
1138 const Expr *LHS = E->getLHS();
1139 const Expr *RHS = E->getRHS();
1140
1141 PrimType ResultElemT = this->classifyComplexElementType(E->getType());
1142 unsigned ResultOffset = ~0u;
1143 if (!DiscardResult)
1144 ResultOffset = this->allocateLocalPrimitive(E, PT_Ptr, /*IsConst=*/true);
1145
1146 // Save result pointer in ResultOffset
1147 if (!this->DiscardResult) {
1148 if (!this->emitDupPtr(E))
1149 return false;
1150 if (!this->emitSetLocal(PT_Ptr, ResultOffset, E))
1151 return false;
1152 }
1153 QualType LHSType = LHS->getType();
1154 if (const auto *AT = LHSType->getAs<AtomicType>())
1155 LHSType = AT->getValueType();
1156 QualType RHSType = RHS->getType();
1157 if (const auto *AT = RHSType->getAs<AtomicType>())
1158 RHSType = AT->getValueType();
1159
1160 bool LHSIsComplex = LHSType->isAnyComplexType();
1161 unsigned LHSOffset;
1162 bool RHSIsComplex = RHSType->isAnyComplexType();
1163
1164 // For ComplexComplex Mul, we have special ops to make their implementation
1165 // easier.
1166 BinaryOperatorKind Op = E->getOpcode();
1167 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1168 assert(classifyPrim(LHSType->getAs<ComplexType>()->getElementType()) ==
1169 classifyPrim(RHSType->getAs<ComplexType>()->getElementType()));
1170 PrimType ElemT =
1171 classifyPrim(LHSType->getAs<ComplexType>()->getElementType());
1172 if (!this->visit(LHS))
1173 return false;
1174 if (!this->visit(RHS))
1175 return false;
1176 return this->emitMulc(ElemT, E);
1177 }
1178
1179 if (Op == BO_Div && RHSIsComplex) {
1180 QualType ElemQT = RHSType->getAs<ComplexType>()->getElementType();
1181 PrimType ElemT = classifyPrim(ElemQT);
1182 // If the LHS is not complex, we still need to do the full complex
1183 // division, so just stub create a complex value and stub it out with
1184 // the LHS and a zero.
1185
1186 if (!LHSIsComplex) {
1187 // This is using the RHS type for the fake-complex LHS.
1188 std::optional<unsigned> LocalIndex = allocateTemporary(E: RHS);
1189 if (!LocalIndex)
1190 return false;
1191 LHSOffset = *LocalIndex;
1192
1193 if (!this->emitGetPtrLocal(LHSOffset, E))
1194 return false;
1195
1196 if (!this->visit(LHS))
1197 return false;
1198 // real is LHS
1199 if (!this->emitInitElem(ElemT, 0, E))
1200 return false;
1201 // imag is zero
1202 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1203 return false;
1204 if (!this->emitInitElem(ElemT, 1, E))
1205 return false;
1206 } else {
1207 if (!this->visit(LHS))
1208 return false;
1209 }
1210
1211 if (!this->visit(RHS))
1212 return false;
1213 return this->emitDivc(ElemT, E);
1214 }
1215
1216 // Evaluate LHS and save value to LHSOffset.
1217 if (LHSType->isAnyComplexType()) {
1218 LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true);
1219 if (!this->visit(LHS))
1220 return false;
1221 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
1222 return false;
1223 } else {
1224 PrimType LHST = classifyPrim(LHSType);
1225 LHSOffset = this->allocateLocalPrimitive(LHS, LHST, /*IsConst=*/true);
1226 if (!this->visit(LHS))
1227 return false;
1228 if (!this->emitSetLocal(LHST, LHSOffset, E))
1229 return false;
1230 }
1231
1232 // Same with RHS.
1233 unsigned RHSOffset;
1234 if (RHSType->isAnyComplexType()) {
1235 RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, /*IsConst=*/true);
1236 if (!this->visit(RHS))
1237 return false;
1238 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
1239 return false;
1240 } else {
1241 PrimType RHST = classifyPrim(RHSType);
1242 RHSOffset = this->allocateLocalPrimitive(RHS, RHST, /*IsConst=*/true);
1243 if (!this->visit(RHS))
1244 return false;
1245 if (!this->emitSetLocal(RHST, RHSOffset, E))
1246 return false;
1247 }
1248
1249 // For both LHS and RHS, either load the value from the complex pointer, or
1250 // directly from the local variable. For index 1 (i.e. the imaginary part),
1251 // just load 0 and do the operation anyway.
1252 auto loadComplexValue = [this](bool IsComplex, bool LoadZero,
1253 unsigned ElemIndex, unsigned Offset,
1254 const Expr *E) -> bool {
1255 if (IsComplex) {
1256 if (!this->emitGetLocal(PT_Ptr, Offset, E))
1257 return false;
1258 return this->emitArrayElemPop(classifyComplexElementType(T: E->getType()),
1259 ElemIndex, E);
1260 }
1261 if (ElemIndex == 0 || !LoadZero)
1262 return this->emitGetLocal(classifyPrim(E->getType()), Offset, E);
1263 return this->visitZeroInitializer(classifyPrim(E->getType()), E->getType(),
1264 E);
1265 };
1266
1267 // Now we can get pointers to the LHS and RHS from the offsets above.
1268 for (unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1269 // Result pointer for the store later.
1270 if (!this->DiscardResult) {
1271 if (!this->emitGetLocal(PT_Ptr, ResultOffset, E))
1272 return false;
1273 }
1274
1275 // The actual operation.
1276 switch (Op) {
1277 case BO_Add:
1278 if (!loadComplexValue(LHSIsComplex, true, ElemIndex, LHSOffset, LHS))
1279 return false;
1280
1281 if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))
1282 return false;
1283 if (ResultElemT == PT_Float) {
1284 if (!this->emitAddf(getFPOptions(E), E))
1285 return false;
1286 } else {
1287 if (!this->emitAdd(ResultElemT, E))
1288 return false;
1289 }
1290 break;
1291 case BO_Sub:
1292 if (!loadComplexValue(LHSIsComplex, true, ElemIndex, LHSOffset, LHS))
1293 return false;
1294
1295 if (!loadComplexValue(RHSIsComplex, true, ElemIndex, RHSOffset, RHS))
1296 return false;
1297 if (ResultElemT == PT_Float) {
1298 if (!this->emitSubf(getFPOptions(E), E))
1299 return false;
1300 } else {
1301 if (!this->emitSub(ResultElemT, E))
1302 return false;
1303 }
1304 break;
1305 case BO_Mul:
1306 if (!loadComplexValue(LHSIsComplex, false, ElemIndex, LHSOffset, LHS))
1307 return false;
1308
1309 if (!loadComplexValue(RHSIsComplex, false, ElemIndex, RHSOffset, RHS))
1310 return false;
1311
1312 if (ResultElemT == PT_Float) {
1313 if (!this->emitMulf(getFPOptions(E), E))
1314 return false;
1315 } else {
1316 if (!this->emitMul(ResultElemT, E))
1317 return false;
1318 }
1319 break;
1320 case BO_Div:
1321 assert(!RHSIsComplex);
1322 if (!loadComplexValue(LHSIsComplex, false, ElemIndex, LHSOffset, LHS))
1323 return false;
1324
1325 if (!loadComplexValue(RHSIsComplex, false, ElemIndex, RHSOffset, RHS))
1326 return false;
1327
1328 if (ResultElemT == PT_Float) {
1329 if (!this->emitDivf(getFPOptions(E), E))
1330 return false;
1331 } else {
1332 if (!this->emitDiv(ResultElemT, E))
1333 return false;
1334 }
1335 break;
1336
1337 default:
1338 return false;
1339 }
1340
1341 if (!this->DiscardResult) {
1342 // Initialize array element with the value we just computed.
1343 if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))
1344 return false;
1345 } else {
1346 if (!this->emitPop(ResultElemT, E))
1347 return false;
1348 }
1349 }
1350 return true;
1351}
1352
1353template <class Emitter>
1354bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
1355 assert(!E->isCommaOp() &&
1356 "Comma op should be handled in VisitBinaryOperator");
1357 assert(E->getType()->isVectorType());
1358 assert(E->getLHS()->getType()->isVectorType());
1359 assert(E->getRHS()->getType()->isVectorType());
1360
1361 // Prepare storage for result.
1362 if (!Initializing && !E->isCompoundAssignmentOp()) {
1363 std::optional<unsigned> LocalIndex = allocateTemporary(E);
1364 if (!LocalIndex)
1365 return false;
1366 if (!this->emitGetPtrLocal(*LocalIndex, E))
1367 return false;
1368 }
1369
1370 const Expr *LHS = E->getLHS();
1371 const Expr *RHS = E->getRHS();
1372 const auto *VecTy = E->getType()->getAs<VectorType>();
1373 auto Op = E->isCompoundAssignmentOp()
1374 ? BinaryOperator::getOpForCompoundAssignment(Opc: E->getOpcode())
1375 : E->getOpcode();
1376
1377 PrimType ElemT = this->classifyVectorElementType(LHS->getType());
1378 PrimType RHSElemT = this->classifyVectorElementType(RHS->getType());
1379 PrimType ResultElemT = this->classifyVectorElementType(E->getType());
1380
1381 // Evaluate LHS and save value to LHSOffset.
1382 unsigned LHSOffset =
1383 this->allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true);
1384 if (!this->visit(LHS))
1385 return false;
1386 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
1387 return false;
1388
1389 // Evaluate RHS and save value to RHSOffset.
1390 unsigned RHSOffset =
1391 this->allocateLocalPrimitive(RHS, PT_Ptr, /*IsConst=*/true);
1392 if (!this->visit(RHS))
1393 return false;
1394 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
1395 return false;
1396
1397 if (E->isCompoundAssignmentOp() && !this->emitGetLocal(PT_Ptr, LHSOffset, E))
1398 return false;
1399
1400 // BitAdd/BitOr/BitXor/Shl/Shr doesn't support bool type, we need perform the
1401 // integer promotion.
1402 bool NeedIntPromot = ElemT == PT_Bool && (E->isBitwiseOp() || E->isShiftOp());
1403 QualType PromotTy =
1404 Ctx.getASTContext().getPromotedIntegerType(PromotableType: Ctx.getASTContext().BoolTy);
1405 PrimType PromotT = classifyPrim(PromotTy);
1406 PrimType OpT = NeedIntPromot ? PromotT : ElemT;
1407
1408 auto getElem = [=](unsigned Offset, PrimType ElemT, unsigned Index) {
1409 if (!this->emitGetLocal(PT_Ptr, Offset, E))
1410 return false;
1411 if (!this->emitArrayElemPop(ElemT, Index, E))
1412 return false;
1413 if (E->isLogicalOp()) {
1414 if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E))
1415 return false;
1416 if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E))
1417 return false;
1418 } else if (NeedIntPromot) {
1419 if (!this->emitPrimCast(ElemT, PromotT, PromotTy, E))
1420 return false;
1421 }
1422 return true;
1423 };
1424
1425#define EMIT_ARITH_OP(OP) \
1426 { \
1427 if (ElemT == PT_Float) { \
1428 if (!this->emit##OP##f(getFPOptions(E), E)) \
1429 return false; \
1430 } else { \
1431 if (!this->emit##OP(ElemT, E)) \
1432 return false; \
1433 } \
1434 break; \
1435 }
1436
1437 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
1438 if (!getElem(LHSOffset, ElemT, I))
1439 return false;
1440 if (!getElem(RHSOffset, RHSElemT, I))
1441 return false;
1442 switch (Op) {
1443 case BO_Add:
1444 EMIT_ARITH_OP(Add)
1445 case BO_Sub:
1446 EMIT_ARITH_OP(Sub)
1447 case BO_Mul:
1448 EMIT_ARITH_OP(Mul)
1449 case BO_Div:
1450 EMIT_ARITH_OP(Div)
1451 case BO_Rem:
1452 if (!this->emitRem(ElemT, E))
1453 return false;
1454 break;
1455 case BO_And:
1456 if (!this->emitBitAnd(OpT, E))
1457 return false;
1458 break;
1459 case BO_Or:
1460 if (!this->emitBitOr(OpT, E))
1461 return false;
1462 break;
1463 case BO_Xor:
1464 if (!this->emitBitXor(OpT, E))
1465 return false;
1466 break;
1467 case BO_Shl:
1468 if (!this->emitShl(OpT, RHSElemT, E))
1469 return false;
1470 break;
1471 case BO_Shr:
1472 if (!this->emitShr(OpT, RHSElemT, E))
1473 return false;
1474 break;
1475 case BO_EQ:
1476 if (!this->emitEQ(ElemT, E))
1477 return false;
1478 break;
1479 case BO_NE:
1480 if (!this->emitNE(ElemT, E))
1481 return false;
1482 break;
1483 case BO_LE:
1484 if (!this->emitLE(ElemT, E))
1485 return false;
1486 break;
1487 case BO_LT:
1488 if (!this->emitLT(ElemT, E))
1489 return false;
1490 break;
1491 case BO_GE:
1492 if (!this->emitGE(ElemT, E))
1493 return false;
1494 break;
1495 case BO_GT:
1496 if (!this->emitGT(ElemT, E))
1497 return false;
1498 break;
1499 case BO_LAnd:
1500 // a && b is equivalent to a!=0 & b!=0
1501 if (!this->emitBitAnd(ResultElemT, E))
1502 return false;
1503 break;
1504 case BO_LOr:
1505 // a || b is equivalent to a!=0 | b!=0
1506 if (!this->emitBitOr(ResultElemT, E))
1507 return false;
1508 break;
1509 default:
1510 return this->emitInvalid(E);
1511 }
1512
1513 // The result of the comparison is a vector of the same width and number
1514 // of elements as the comparison operands with a signed integral element
1515 // type.
1516 //
1517 // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
1518 if (E->isComparisonOp()) {
1519 if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E))
1520 return false;
1521 if (!this->emitNeg(ResultElemT, E))
1522 return false;
1523 }
1524
1525 // If we performed an integer promotion, we need to cast the compute result
1526 // into result vector element type.
1527 if (NeedIntPromot &&
1528 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(), E))
1529 return false;
1530
1531 // Initialize array element with the value we just computed.
1532 if (!this->emitInitElem(ResultElemT, I, E))
1533 return false;
1534 }
1535
1536 if (DiscardResult && E->isCompoundAssignmentOp() && !this->emitPopPtr(E))
1537 return false;
1538 return true;
1539}
1540
1541template <class Emitter>
1542bool Compiler<Emitter>::VisitFixedPointBinOp(const BinaryOperator *E) {
1543 const Expr *LHS = E->getLHS();
1544 const Expr *RHS = E->getRHS();
1545 const ASTContext &ASTCtx = Ctx.getASTContext();
1546
1547 assert(LHS->getType()->isFixedPointType() ||
1548 RHS->getType()->isFixedPointType());
1549
1550 auto LHSSema = ASTCtx.getFixedPointSemantics(Ty: LHS->getType());
1551 auto LHSSemaInt = LHSSema.toOpaqueInt();
1552 auto RHSSema = ASTCtx.getFixedPointSemantics(Ty: RHS->getType());
1553 auto RHSSemaInt = RHSSema.toOpaqueInt();
1554
1555 if (!this->visit(LHS))
1556 return false;
1557 if (!LHS->getType()->isFixedPointType()) {
1558 if (!this->emitCastIntegralFixedPoint(classifyPrim(LHS->getType()),
1559 LHSSemaInt, E))
1560 return false;
1561 }
1562
1563 if (!this->visit(RHS))
1564 return false;
1565 if (!RHS->getType()->isFixedPointType()) {
1566 if (!this->emitCastIntegralFixedPoint(classifyPrim(RHS->getType()),
1567 RHSSemaInt, E))
1568 return false;
1569 }
1570
1571 // Convert the result to the target semantics.
1572 auto ConvertResult = [&](bool R) -> bool {
1573 if (!R)
1574 return false;
1575 auto ResultSema = ASTCtx.getFixedPointSemantics(Ty: E->getType()).toOpaqueInt();
1576 auto CommonSema = LHSSema.getCommonSemantics(Other: RHSSema).toOpaqueInt();
1577 if (ResultSema != CommonSema)
1578 return this->emitCastFixedPoint(ResultSema, E);
1579 return true;
1580 };
1581
1582 auto MaybeCastToBool = [&](bool Result) {
1583 if (!Result)
1584 return false;
1585 PrimType T = classifyPrim(E);
1586 if (DiscardResult)
1587 return this->emitPop(T, E);
1588 if (T != PT_Bool)
1589 return this->emitCast(PT_Bool, T, E);
1590 return true;
1591 };
1592
1593 switch (E->getOpcode()) {
1594 case BO_EQ:
1595 return MaybeCastToBool(this->emitEQFixedPoint(E));
1596 case BO_NE:
1597 return MaybeCastToBool(this->emitNEFixedPoint(E));
1598 case BO_LT:
1599 return MaybeCastToBool(this->emitLTFixedPoint(E));
1600 case BO_LE:
1601 return MaybeCastToBool(this->emitLEFixedPoint(E));
1602 case BO_GT:
1603 return MaybeCastToBool(this->emitGTFixedPoint(E));
1604 case BO_GE:
1605 return MaybeCastToBool(this->emitGEFixedPoint(E));
1606 case BO_Add:
1607 return ConvertResult(this->emitAddFixedPoint(E));
1608 case BO_Sub:
1609 return ConvertResult(this->emitSubFixedPoint(E));
1610 case BO_Mul:
1611 return ConvertResult(this->emitMulFixedPoint(E));
1612 case BO_Div:
1613 return ConvertResult(this->emitDivFixedPoint(E));
1614 case BO_Shl:
1615 return ConvertResult(this->emitShiftFixedPoint(/*Left=*/true, E));
1616 case BO_Shr:
1617 return ConvertResult(this->emitShiftFixedPoint(/*Left=*/false, E));
1618
1619 default:
1620 return this->emitInvalid(E);
1621 }
1622
1623 llvm_unreachable("unhandled binop opcode");
1624}
1625
1626template <class Emitter>
1627bool Compiler<Emitter>::VisitFixedPointUnaryOperator(const UnaryOperator *E) {
1628 const Expr *SubExpr = E->getSubExpr();
1629 assert(SubExpr->getType()->isFixedPointType());
1630
1631 switch (E->getOpcode()) {
1632 case UO_Plus:
1633 return this->delegate(SubExpr);
1634 case UO_Minus:
1635 if (!this->visit(SubExpr))
1636 return false;
1637 return this->emitNegFixedPoint(E);
1638 default:
1639 return false;
1640 }
1641
1642 llvm_unreachable("Unhandled unary opcode");
1643}
1644
1645template <class Emitter>
1646bool Compiler<Emitter>::VisitImplicitValueInitExpr(
1647 const ImplicitValueInitExpr *E) {
1648 QualType QT = E->getType();
1649
1650 if (std::optional<PrimType> T = classify(QT))
1651 return this->visitZeroInitializer(*T, QT, E);
1652
1653 if (QT->isRecordType()) {
1654 const RecordDecl *RD = QT->getAsRecordDecl();
1655 assert(RD);
1656 if (RD->isInvalidDecl())
1657 return false;
1658
1659 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(Val: RD);
1660 CXXRD && CXXRD->getNumVBases() > 0) {
1661 // TODO: Diagnose.
1662 return false;
1663 }
1664
1665 const Record *R = getRecord(QT);
1666 if (!R)
1667 return false;
1668
1669 assert(Initializing);
1670 return this->visitZeroRecordInitializer(R, E);
1671 }
1672
1673 if (QT->isIncompleteArrayType())
1674 return true;
1675
1676 if (QT->isArrayType())
1677 return this->visitZeroArrayInitializer(QT, E);
1678
1679 if (const auto *ComplexTy = E->getType()->getAs<ComplexType>()) {
1680 assert(Initializing);
1681 QualType ElemQT = ComplexTy->getElementType();
1682 PrimType ElemT = classifyPrim(ElemQT);
1683 for (unsigned I = 0; I < 2; ++I) {
1684 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1685 return false;
1686 if (!this->emitInitElem(ElemT, I, E))
1687 return false;
1688 }
1689 return true;
1690 }
1691
1692 if (const auto *VecT = E->getType()->getAs<VectorType>()) {
1693 unsigned NumVecElements = VecT->getNumElements();
1694 QualType ElemQT = VecT->getElementType();
1695 PrimType ElemT = classifyPrim(ElemQT);
1696
1697 for (unsigned I = 0; I < NumVecElements; ++I) {
1698 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1699 return false;
1700 if (!this->emitInitElem(ElemT, I, E))
1701 return false;
1702 }
1703 return true;
1704 }
1705
1706 return false;
1707}
1708
1709template <class Emitter>
1710bool Compiler<Emitter>::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
1711 const Expr *LHS = E->getLHS();
1712 const Expr *RHS = E->getRHS();
1713 const Expr *Index = E->getIdx();
1714 const Expr *Base = E->getBase();
1715
1716 // C++17's rules require us to evaluate the LHS first, regardless of which
1717 // side is the base.
1718 bool Success = true;
1719 for (const Expr *SubExpr : {LHS, RHS}) {
1720 if (!this->visit(SubExpr)) {
1721 Success = false;
1722 continue;
1723 }
1724
1725 // Expand the base if this is a subscript on a
1726 // pointer expression.
1727 if (SubExpr == Base && Base->getType()->isPointerType()) {
1728 if (!this->emitExpandPtr(E))
1729 Success = false;
1730 }
1731 }
1732
1733 if (!Success)
1734 return false;
1735
1736 std::optional<PrimType> IndexT = classify(Index->getType());
1737 // In error-recovery cases, the index expression has a dependent type.
1738 if (!IndexT)
1739 return this->emitError(E);
1740 // If the index is first, we need to change that.
1741 if (LHS == Index) {
1742 if (!this->emitFlip(PT_Ptr, *IndexT, E))
1743 return false;
1744 }
1745
1746 if (!this->emitArrayElemPtrPop(*IndexT, E))
1747 return false;
1748 if (DiscardResult)
1749 return this->emitPopPtr(E);
1750 return true;
1751}
1752
1753template <class Emitter>
1754bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
1755 const Expr *ArrayFiller, const Expr *E) {
1756 InitLinkScope<Emitter> ILS(this, InitLink::InitList());
1757
1758 QualType QT = E->getType();
1759 if (const auto *AT = QT->getAs<AtomicType>())
1760 QT = AT->getValueType();
1761
1762 if (QT->isVoidType()) {
1763 if (Inits.size() == 0)
1764 return true;
1765 return this->emitInvalid(E);
1766 }
1767
1768 // Handle discarding first.
1769 if (DiscardResult) {
1770 for (const Expr *Init : Inits) {
1771 if (!this->discard(Init))
1772 return false;
1773 }
1774 return true;
1775 }
1776
1777 // Primitive values.
1778 if (std::optional<PrimType> T = classify(QT)) {
1779 assert(!DiscardResult);
1780 if (Inits.size() == 0)
1781 return this->visitZeroInitializer(*T, QT, E);
1782 assert(Inits.size() == 1);
1783 return this->delegate(Inits[0]);
1784 }
1785
1786 if (QT->isRecordType()) {
1787 const Record *R = getRecord(QT);
1788
1789 if (Inits.size() == 1 && E->getType() == Inits[0]->getType())
1790 return this->delegate(Inits[0]);
1791
1792 auto initPrimitiveField = [=](const Record::Field *FieldToInit,
1793 const Expr *Init, PrimType T) -> bool {
1794 InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(Val: Init));
1795 InitLinkScope<Emitter> ILS(this, InitLink::Field(Offset: FieldToInit->Offset));
1796 if (!this->visit(Init))
1797 return false;
1798
1799 if (FieldToInit->isBitField())
1800 return this->emitInitBitField(T, FieldToInit, E);
1801 return this->emitInitField(T, FieldToInit->Offset, E);
1802 };
1803
1804 auto initCompositeField = [=](const Record::Field *FieldToInit,
1805 const Expr *Init) -> bool {
1806 InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(Val: Init));
1807 InitLinkScope<Emitter> ILS(this, InitLink::Field(Offset: FieldToInit->Offset));
1808
1809 // Non-primitive case. Get a pointer to the field-to-initialize
1810 // on the stack and recurse into visitInitializer().
1811 if (!this->emitGetPtrField(FieldToInit->Offset, Init))
1812 return false;
1813 if (!this->visitInitializer(Init))
1814 return false;
1815 return this->emitPopPtr(E);
1816 };
1817
1818 if (R->isUnion()) {
1819 if (Inits.size() == 0) {
1820 if (!this->visitZeroRecordInitializer(R, E))
1821 return false;
1822 } else {
1823 const Expr *Init = Inits[0];
1824 const FieldDecl *FToInit = nullptr;
1825 if (const auto *ILE = dyn_cast<InitListExpr>(Val: E))
1826 FToInit = ILE->getInitializedFieldInUnion();
1827 else
1828 FToInit = cast<CXXParenListInitExpr>(Val: E)->getInitializedFieldInUnion();
1829
1830 const Record::Field *FieldToInit = R->getField(FD: FToInit);
1831 if (std::optional<PrimType> T = classify(Init)) {
1832 if (!initPrimitiveField(FieldToInit, Init, *T))
1833 return false;
1834 } else {
1835 if (!initCompositeField(FieldToInit, Init))
1836 return false;
1837 }
1838 }
1839 return this->emitFinishInit(E);
1840 }
1841
1842 assert(!R->isUnion());
1843 unsigned InitIndex = 0;
1844 for (const Expr *Init : Inits) {
1845 // Skip unnamed bitfields.
1846 while (InitIndex < R->getNumFields() &&
1847 R->getField(I: InitIndex)->isUnnamedBitField())
1848 ++InitIndex;
1849
1850 if (std::optional<PrimType> T = classify(Init)) {
1851 const Record::Field *FieldToInit = R->getField(I: InitIndex);
1852 if (!initPrimitiveField(FieldToInit, Init, *T))
1853 return false;
1854 ++InitIndex;
1855 } else {
1856 // Initializer for a direct base class.
1857 if (const Record::Base *B = R->getBase(T: Init->getType())) {
1858 if (!this->emitGetPtrBase(B->Offset, Init))
1859 return false;
1860
1861 if (!this->visitInitializer(Init))
1862 return false;
1863
1864 if (!this->emitFinishInitPop(E))
1865 return false;
1866 // Base initializers don't increase InitIndex, since they don't count
1867 // into the Record's fields.
1868 } else {
1869 const Record::Field *FieldToInit = R->getField(I: InitIndex);
1870 if (!initCompositeField(FieldToInit, Init))
1871 return false;
1872 ++InitIndex;
1873 }
1874 }
1875 }
1876 return this->emitFinishInit(E);
1877 }
1878
1879 if (QT->isArrayType()) {
1880 if (Inits.size() == 1 && QT == Inits[0]->getType())
1881 return this->delegate(Inits[0]);
1882
1883 const ConstantArrayType *CAT =
1884 Ctx.getASTContext().getAsConstantArrayType(T: QT);
1885 uint64_t NumElems = CAT->getZExtSize();
1886
1887 if (!this->emitCheckArraySize(NumElems, E))
1888 return false;
1889
1890 std::optional<PrimType> InitT = classify(CAT->getElementType());
1891 unsigned ElementIndex = 0;
1892 for (const Expr *Init : Inits) {
1893 if (const auto *EmbedS =
1894 dyn_cast<EmbedExpr>(Val: Init->IgnoreParenImpCasts())) {
1895 PrimType TargetT = classifyPrim(Init->getType());
1896
1897 auto Eval = [&](const Expr *Init, unsigned ElemIndex) {
1898 PrimType InitT = classifyPrim(Init->getType());
1899 if (!this->visit(Init))
1900 return false;
1901 if (InitT != TargetT) {
1902 if (!this->emitCast(InitT, TargetT, E))
1903 return false;
1904 }
1905 return this->emitInitElem(TargetT, ElemIndex, Init);
1906 };
1907 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
1908 return false;
1909 } else {
1910 if (!this->visitArrayElemInit(ElementIndex, Init, InitT))
1911 return false;
1912 ++ElementIndex;
1913 }
1914 }
1915
1916 // Expand the filler expression.
1917 // FIXME: This should go away.
1918 if (ArrayFiller) {
1919 for (; ElementIndex != NumElems; ++ElementIndex) {
1920 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller, InitT))
1921 return false;
1922 }
1923 }
1924
1925 return this->emitFinishInit(E);
1926 }
1927
1928 if (const auto *ComplexTy = QT->getAs<ComplexType>()) {
1929 unsigned NumInits = Inits.size();
1930
1931 if (NumInits == 1)
1932 return this->delegate(Inits[0]);
1933
1934 QualType ElemQT = ComplexTy->getElementType();
1935 PrimType ElemT = classifyPrim(ElemQT);
1936 if (NumInits == 0) {
1937 // Zero-initialize both elements.
1938 for (unsigned I = 0; I < 2; ++I) {
1939 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1940 return false;
1941 if (!this->emitInitElem(ElemT, I, E))
1942 return false;
1943 }
1944 } else if (NumInits == 2) {
1945 unsigned InitIndex = 0;
1946 for (const Expr *Init : Inits) {
1947 if (!this->visit(Init))
1948 return false;
1949
1950 if (!this->emitInitElem(ElemT, InitIndex, E))
1951 return false;
1952 ++InitIndex;
1953 }
1954 }
1955 return true;
1956 }
1957
1958 if (const auto *VecT = QT->getAs<VectorType>()) {
1959 unsigned NumVecElements = VecT->getNumElements();
1960 assert(NumVecElements >= Inits.size());
1961
1962 QualType ElemQT = VecT->getElementType();
1963 PrimType ElemT = classifyPrim(ElemQT);
1964
1965 // All initializer elements.
1966 unsigned InitIndex = 0;
1967 for (const Expr *Init : Inits) {
1968 if (!this->visit(Init))
1969 return false;
1970
1971 // If the initializer is of vector type itself, we have to deconstruct
1972 // that and initialize all the target fields from the initializer fields.
1973 if (const auto *InitVecT = Init->getType()->getAs<VectorType>()) {
1974 if (!this->emitCopyArray(ElemT, 0, InitIndex,
1975 InitVecT->getNumElements(), E))
1976 return false;
1977 InitIndex += InitVecT->getNumElements();
1978 } else {
1979 if (!this->emitInitElem(ElemT, InitIndex, E))
1980 return false;
1981 ++InitIndex;
1982 }
1983 }
1984
1985 assert(InitIndex <= NumVecElements);
1986
1987 // Fill the rest with zeroes.
1988 for (; InitIndex != NumVecElements; ++InitIndex) {
1989 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1990 return false;
1991 if (!this->emitInitElem(ElemT, InitIndex, E))
1992 return false;
1993 }
1994 return true;
1995 }
1996
1997 return false;
1998}
1999
2000/// Pointer to the array(not the element!) must be on the stack when calling
2001/// this.
2002template <class Emitter>
2003bool Compiler<Emitter>::visitArrayElemInit(unsigned ElemIndex, const Expr *Init,
2004 std::optional<PrimType> InitT) {
2005 if (InitT) {
2006 // Visit the primitive element like normal.
2007 if (!this->visit(Init))
2008 return false;
2009 return this->emitInitElem(*InitT, ElemIndex, Init);
2010 }
2011
2012 InitLinkScope<Emitter> ILS(this, InitLink::Elem(Index: ElemIndex));
2013 // Advance the pointer currently on the stack to the given
2014 // dimension.
2015 if (!this->emitConstUint32(ElemIndex, Init))
2016 return false;
2017 if (!this->emitArrayElemPtrUint32(Init))
2018 return false;
2019 if (!this->visitInitializer(Init))
2020 return false;
2021 return this->emitFinishInitPop(Init);
2022}
2023
2024template <class Emitter>
2025bool Compiler<Emitter>::visitCallArgs(ArrayRef<const Expr *> Args,
2026 const FunctionDecl *FuncDecl) {
2027 assert(VarScope->getKind() == ScopeKind::Call);
2028 llvm::BitVector NonNullArgs = collectNonNullArgs(F: FuncDecl, Args);
2029
2030 unsigned ArgIndex = 0;
2031 for (const Expr *Arg : Args) {
2032 if (std::optional<PrimType> T = classify(Arg)) {
2033 if (!this->visit(Arg))
2034 return false;
2035 } else {
2036
2037 std::optional<unsigned> LocalIndex = allocateLocal(
2038 Decl: Arg, Ty: Arg->getType(), /*ExtendingDecl=*/nullptr, ScopeKind::Call);
2039 if (!LocalIndex)
2040 return false;
2041
2042 if (!this->emitGetPtrLocal(*LocalIndex, Arg))
2043 return false;
2044 InitLinkScope<Emitter> ILS(this, InitLink::Temp(Offset: *LocalIndex));
2045 if (!this->visitInitializer(Arg))
2046 return false;
2047 }
2048
2049 if (FuncDecl && NonNullArgs[ArgIndex]) {
2050 PrimType ArgT = classify(Arg).value_or(PT_Ptr);
2051 if (ArgT == PT_Ptr) {
2052 if (!this->emitCheckNonNullArg(ArgT, Arg))
2053 return false;
2054 }
2055 }
2056
2057 ++ArgIndex;
2058 }
2059
2060 return true;
2061}
2062
2063template <class Emitter>
2064bool Compiler<Emitter>::VisitInitListExpr(const InitListExpr *E) {
2065 return this->visitInitList(E->inits(), E->getArrayFiller(), E);
2066}
2067
2068template <class Emitter>
2069bool Compiler<Emitter>::VisitCXXParenListInitExpr(
2070 const CXXParenListInitExpr *E) {
2071 return this->visitInitList(E->getInitExprs(), E->getArrayFiller(), E);
2072}
2073
2074template <class Emitter>
2075bool Compiler<Emitter>::VisitSubstNonTypeTemplateParmExpr(
2076 const SubstNonTypeTemplateParmExpr *E) {
2077 return this->delegate(E->getReplacement());
2078}
2079
2080template <class Emitter>
2081bool Compiler<Emitter>::VisitConstantExpr(const ConstantExpr *E) {
2082 std::optional<PrimType> T = classify(E->getType());
2083 if (T && E->hasAPValueResult()) {
2084 // Try to emit the APValue directly, without visiting the subexpr.
2085 // This will only fail if we can't emit the APValue, so won't emit any
2086 // diagnostics or any double values.
2087 if (DiscardResult)
2088 return true;
2089
2090 if (this->visitAPValue(E->getAPValueResult(), *T, E))
2091 return true;
2092 }
2093 return this->delegate(E->getSubExpr());
2094}
2095
2096template <class Emitter>
2097bool Compiler<Emitter>::VisitEmbedExpr(const EmbedExpr *E) {
2098 auto It = E->begin();
2099 return this->visit(*It);
2100}
2101
2102static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx,
2103 UnaryExprOrTypeTrait Kind) {
2104 bool AlignOfReturnsPreferred =
2105 ASTCtx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
2106
2107 // C++ [expr.alignof]p3:
2108 // When alignof is applied to a reference type, the result is the
2109 // alignment of the referenced type.
2110 if (const auto *Ref = T->getAs<ReferenceType>())
2111 T = Ref->getPointeeType();
2112
2113 if (T.getQualifiers().hasUnaligned())
2114 return CharUnits::One();
2115
2116 // __alignof is defined to return the preferred alignment.
2117 // Before 8, clang returned the preferred alignment for alignof and
2118 // _Alignof as well.
2119 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2120 return ASTCtx.toCharUnitsFromBits(BitSize: ASTCtx.getPreferredTypeAlign(T));
2121
2122 return ASTCtx.getTypeAlignInChars(T);
2123}
2124
2125template <class Emitter>
2126bool Compiler<Emitter>::VisitUnaryExprOrTypeTraitExpr(
2127 const UnaryExprOrTypeTraitExpr *E) {
2128 UnaryExprOrTypeTrait Kind = E->getKind();
2129 const ASTContext &ASTCtx = Ctx.getASTContext();
2130
2131 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2132 QualType ArgType = E->getTypeOfArgument();
2133
2134 // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
2135 // the result is the size of the referenced type."
2136 if (const auto *Ref = ArgType->getAs<ReferenceType>())
2137 ArgType = Ref->getPointeeType();
2138
2139 CharUnits Size;
2140 if (ArgType->isVoidType() || ArgType->isFunctionType())
2141 Size = CharUnits::One();
2142 else {
2143 if (ArgType->isDependentType() || !ArgType->isConstantSizeType())
2144 return this->emitInvalid(E);
2145
2146 if (Kind == UETT_SizeOf)
2147 Size = ASTCtx.getTypeSizeInChars(T: ArgType);
2148 else
2149 Size = ASTCtx.getTypeInfoDataSizeInChars(T: ArgType).Width;
2150 }
2151
2152 if (DiscardResult)
2153 return true;
2154
2155 return this->emitConst(Size.getQuantity(), E);
2156 }
2157
2158 if (Kind == UETT_CountOf) {
2159 QualType Ty = E->getTypeOfArgument();
2160 assert(Ty->isArrayType());
2161
2162 // We don't need to worry about array element qualifiers, so getting the
2163 // unsafe array type is fine.
2164 if (const auto *CAT =
2165 dyn_cast<ConstantArrayType>(Val: Ty->getAsArrayTypeUnsafe())) {
2166 if (DiscardResult)
2167 return true;
2168 return this->emitConst(CAT->getSize(), E);
2169 }
2170
2171 assert(!Ty->isConstantSizeType());
2172
2173 // If it's a variable-length array type, we need to check whether it is a
2174 // multidimensional array. If so, we need to check the size expression of
2175 // the VLA to see if it's a constant size. If so, we can return that value.
2176 const auto *VAT = ASTCtx.getAsVariableArrayType(T: Ty);
2177 assert(VAT);
2178 if (VAT->getElementType()->isArrayType()) {
2179 std::optional<APSInt> Res =
2180 VAT->getSizeExpr()->getIntegerConstantExpr(Ctx: ASTCtx);
2181 if (Res) {
2182 if (DiscardResult)
2183 return true;
2184 return this->emitConst(*Res, E);
2185 }
2186 }
2187 }
2188
2189 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2190 CharUnits Size;
2191
2192 if (E->isArgumentType()) {
2193 QualType ArgType = E->getTypeOfArgument();
2194
2195 Size = AlignOfType(T: ArgType, ASTCtx, Kind);
2196 } else {
2197 // Argument is an expression, not a type.
2198 const Expr *Arg = E->getArgumentExpr()->IgnoreParens();
2199
2200 // The kinds of expressions that we have special-case logic here for
2201 // should be kept up to date with the special checks for those
2202 // expressions in Sema.
2203
2204 // alignof decl is always accepted, even if it doesn't make sense: we
2205 // default to 1 in those cases.
2206 if (const auto *DRE = dyn_cast<DeclRefExpr>(Val: Arg))
2207 Size = ASTCtx.getDeclAlign(D: DRE->getDecl(),
2208 /*RefAsPointee*/ ForAlignof: true);
2209 else if (const auto *ME = dyn_cast<MemberExpr>(Val: Arg))
2210 Size = ASTCtx.getDeclAlign(D: ME->getMemberDecl(),
2211 /*RefAsPointee*/ ForAlignof: true);
2212 else
2213 Size = AlignOfType(T: Arg->getType(), ASTCtx, Kind);
2214 }
2215
2216 if (DiscardResult)
2217 return true;
2218
2219 return this->emitConst(Size.getQuantity(), E);
2220 }
2221
2222 if (Kind == UETT_VectorElements) {
2223 if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>())
2224 return this->emitConst(VT->getNumElements(), E);
2225 assert(E->getTypeOfArgument()->isSizelessVectorType());
2226 return this->emitSizelessVectorElementSize(E);
2227 }
2228
2229 if (Kind == UETT_VecStep) {
2230 if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>()) {
2231 unsigned N = VT->getNumElements();
2232
2233 // The vec_step built-in functions that take a 3-component
2234 // vector return 4. (OpenCL 1.1 spec 6.11.12)
2235 if (N == 3)
2236 N = 4;
2237
2238 return this->emitConst(N, E);
2239 }
2240 return this->emitConst(1, E);
2241 }
2242
2243 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2244 assert(E->isArgumentType());
2245 unsigned Bits = ASTCtx.getOpenMPDefaultSimdAlign(T: E->getArgumentType());
2246
2247 return this->emitConst(ASTCtx.toCharUnitsFromBits(BitSize: Bits).getQuantity(), E);
2248 }
2249
2250 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2251 if (E->getArgumentType()->isDependentType())
2252 return this->emitInvalid(E);
2253
2254 return this->emitConst(
2255 const_cast<ASTContext &>(ASTCtx).getPointerAuthTypeDiscriminator(
2256 T: E->getArgumentType()),
2257 E);
2258 }
2259
2260 return false;
2261}
2262
2263template <class Emitter>
2264bool Compiler<Emitter>::VisitMemberExpr(const MemberExpr *E) {
2265 // 'Base.Member'
2266 const Expr *Base = E->getBase();
2267 const ValueDecl *Member = E->getMemberDecl();
2268
2269 if (DiscardResult)
2270 return this->discard(Base);
2271
2272 // MemberExprs are almost always lvalues, in which case we don't need to
2273 // do the load. But sometimes they aren't.
2274 const auto maybeLoadValue = [&]() -> bool {
2275 if (E->isGLValue())
2276 return true;
2277 if (std::optional<PrimType> T = classify(E))
2278 return this->emitLoadPop(*T, E);
2279 return false;
2280 };
2281
2282 if (const auto *VD = dyn_cast<VarDecl>(Val: Member)) {
2283 // I am almost confident in saying that a var decl must be static
2284 // and therefore registered as a global variable. But this will probably
2285 // turn out to be wrong some time in the future, as always.
2286 if (auto GlobalIndex = P.getGlobal(VD))
2287 return this->emitGetPtrGlobal(*GlobalIndex, E) && maybeLoadValue();
2288 return false;
2289 }
2290
2291 if (!isa<FieldDecl>(Val: Member)) {
2292 if (!this->discard(Base) && !this->emitSideEffect(E))
2293 return false;
2294
2295 return this->visitDeclRef(Member, E);
2296 }
2297
2298 if (Initializing) {
2299 if (!this->delegate(Base))
2300 return false;
2301 } else {
2302 if (!this->visit(Base))
2303 return false;
2304 }
2305
2306 // Base above gives us a pointer on the stack.
2307 const auto *FD = cast<FieldDecl>(Val: Member);
2308 const RecordDecl *RD = FD->getParent();
2309 const Record *R = getRecord(RD);
2310 if (!R)
2311 return false;
2312 const Record::Field *F = R->getField(FD);
2313 // Leave a pointer to the field on the stack.
2314 if (F->Decl->getType()->isReferenceType())
2315 return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue();
2316 return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue();
2317}
2318
2319template <class Emitter>
2320bool Compiler<Emitter>::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E) {
2321 // ArrayIndex might not be set if a ArrayInitIndexExpr is being evaluated
2322 // stand-alone, e.g. via EvaluateAsInt().
2323 if (!ArrayIndex)
2324 return false;
2325 return this->emitConst(*ArrayIndex, E);
2326}
2327
2328template <class Emitter>
2329bool Compiler<Emitter>::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
2330 assert(Initializing);
2331 assert(!DiscardResult);
2332
2333 // We visit the common opaque expression here once so we have its value
2334 // cached.
2335 if (!this->discard(E->getCommonExpr()))
2336 return false;
2337
2338 // TODO: This compiles to quite a lot of bytecode if the array is larger.
2339 // Investigate compiling this to a loop.
2340 const Expr *SubExpr = E->getSubExpr();
2341 size_t Size = E->getArraySize().getZExtValue();
2342 std::optional<PrimType> SubExprT = classify(SubExpr);
2343
2344 // So, every iteration, we execute an assignment here
2345 // where the LHS is on the stack (the target array)
2346 // and the RHS is our SubExpr.
2347 for (size_t I = 0; I != Size; ++I) {
2348 ArrayIndexScope<Emitter> IndexScope(this, I);
2349 BlockScope<Emitter> BS(this);
2350
2351 if (!this->visitArrayElemInit(I, SubExpr, SubExprT))
2352 return false;
2353 if (!BS.destroyLocals())
2354 return false;
2355 }
2356 return true;
2357}
2358
2359template <class Emitter>
2360bool Compiler<Emitter>::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
2361 const Expr *SourceExpr = E->getSourceExpr();
2362 if (!SourceExpr)
2363 return false;
2364
2365 if (Initializing)
2366 return this->visitInitializer(SourceExpr);
2367
2368 PrimType SubExprT = classify(SourceExpr).value_or(PT_Ptr);
2369 if (auto It = OpaqueExprs.find(Val: E); It != OpaqueExprs.end())
2370 return this->emitGetLocal(SubExprT, It->second, E);
2371
2372 if (!this->visit(SourceExpr))
2373 return false;
2374
2375 // At this point we either have the evaluated source expression or a pointer
2376 // to an object on the stack. We want to create a local variable that stores
2377 // this value.
2378 unsigned LocalIndex = allocateLocalPrimitive(Decl: E, Ty: SubExprT, /*IsConst=*/true);
2379 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
2380 return false;
2381
2382 // Here the local variable is created but the value is removed from the stack,
2383 // so we put it back if the caller needs it.
2384 if (!DiscardResult) {
2385 if (!this->emitGetLocal(SubExprT, LocalIndex, E))
2386 return false;
2387 }
2388
2389 // This is cleaned up when the local variable is destroyed.
2390 OpaqueExprs.insert(KV: {E, LocalIndex});
2391
2392 return true;
2393}
2394
2395template <class Emitter>
2396bool Compiler<Emitter>::VisitAbstractConditionalOperator(
2397 const AbstractConditionalOperator *E) {
2398 const Expr *Condition = E->getCond();
2399 const Expr *TrueExpr = E->getTrueExpr();
2400 const Expr *FalseExpr = E->getFalseExpr();
2401
2402 auto visitChildExpr = [&](const Expr *E) -> bool {
2403 LocalScope<Emitter> S(this);
2404 if (!this->delegate(E))
2405 return false;
2406 return S.destroyLocals();
2407 };
2408
2409 if (std::optional<bool> BoolValue = getBoolValue(E: Condition)) {
2410 if (BoolValue)
2411 return visitChildExpr(TrueExpr);
2412 return visitChildExpr(FalseExpr);
2413 }
2414
2415 bool IsBcpCall = false;
2416 if (const auto *CE = dyn_cast<CallExpr>(Val: Condition->IgnoreParenCasts());
2417 CE && CE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) {
2418 IsBcpCall = true;
2419 }
2420
2421 LabelTy LabelEnd = this->getLabel(); // Label after the operator.
2422 LabelTy LabelFalse = this->getLabel(); // Label for the false expr.
2423
2424 if (IsBcpCall) {
2425 if (!this->emitStartSpeculation(E))
2426 return false;
2427 }
2428
2429 if (!this->visitBool(Condition)) {
2430 // If the condition failed and we're checking for undefined behavior
2431 // (which only happens with EvalEmitter) check the TrueExpr and FalseExpr
2432 // as well.
2433 if (this->checkingForUndefinedBehavior()) {
2434 if (!this->discard(TrueExpr))
2435 return false;
2436 if (!this->discard(FalseExpr))
2437 return false;
2438 }
2439 return false;
2440 }
2441
2442 if (!this->jumpFalse(LabelFalse))
2443 return false;
2444 if (!visitChildExpr(TrueExpr))
2445 return false;
2446 if (!this->jump(LabelEnd))
2447 return false;
2448 this->emitLabel(LabelFalse);
2449 if (!visitChildExpr(FalseExpr))
2450 return false;
2451 this->fallthrough(LabelEnd);
2452 this->emitLabel(LabelEnd);
2453
2454 if (IsBcpCall)
2455 return this->emitEndSpeculation(E);
2456 return true;
2457}
2458
2459template <class Emitter>
2460bool Compiler<Emitter>::VisitStringLiteral(const StringLiteral *E) {
2461 if (DiscardResult)
2462 return true;
2463
2464 if (!Initializing) {
2465 unsigned StringIndex = P.createGlobalString(S: E);
2466 return this->emitGetPtrGlobal(StringIndex, E);
2467 }
2468
2469 // We are initializing an array on the stack.
2470 const ConstantArrayType *CAT =
2471 Ctx.getASTContext().getAsConstantArrayType(T: E->getType());
2472 assert(CAT && "a string literal that's not a constant array?");
2473
2474 // If the initializer string is too long, a diagnostic has already been
2475 // emitted. Read only the array length from the string literal.
2476 unsigned ArraySize = CAT->getZExtSize();
2477 unsigned N = std::min(a: ArraySize, b: E->getLength());
2478 unsigned CharWidth = E->getCharByteWidth();
2479
2480 for (unsigned I = 0; I != N; ++I) {
2481 uint32_t CodeUnit = E->getCodeUnit(i: I);
2482
2483 if (CharWidth == 1) {
2484 this->emitConstSint8(CodeUnit, E);
2485 this->emitInitElemSint8(I, E);
2486 } else if (CharWidth == 2) {
2487 this->emitConstUint16(CodeUnit, E);
2488 this->emitInitElemUint16(I, E);
2489 } else if (CharWidth == 4) {
2490 this->emitConstUint32(CodeUnit, E);
2491 this->emitInitElemUint32(I, E);
2492 } else {
2493 llvm_unreachable("unsupported character width");
2494 }
2495 }
2496
2497 // Fill up the rest of the char array with NUL bytes.
2498 for (unsigned I = N; I != ArraySize; ++I) {
2499 if (CharWidth == 1) {
2500 this->emitConstSint8(0, E);
2501 this->emitInitElemSint8(I, E);
2502 } else if (CharWidth == 2) {
2503 this->emitConstUint16(0, E);
2504 this->emitInitElemUint16(I, E);
2505 } else if (CharWidth == 4) {
2506 this->emitConstUint32(0, E);
2507 this->emitInitElemUint32(I, E);
2508 } else {
2509 llvm_unreachable("unsupported character width");
2510 }
2511 }
2512
2513 return true;
2514}
2515
2516template <class Emitter>
2517bool Compiler<Emitter>::VisitObjCStringLiteral(const ObjCStringLiteral *E) {
2518 if (DiscardResult)
2519 return true;
2520 return this->emitDummyPtr(E, E);
2521}
2522
2523template <class Emitter>
2524bool Compiler<Emitter>::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
2525 auto &A = Ctx.getASTContext();
2526 std::string Str;
2527 A.getObjCEncodingForType(T: E->getEncodedType(), S&: Str);
2528 StringLiteral *SL =
2529 StringLiteral::Create(Ctx: A, Str, Kind: StringLiteralKind::Ordinary,
2530 /*Pascal=*/false, Ty: E->getType(), Locs: E->getAtLoc());
2531 return this->delegate(SL);
2532}
2533
2534template <class Emitter>
2535bool Compiler<Emitter>::VisitSYCLUniqueStableNameExpr(
2536 const SYCLUniqueStableNameExpr *E) {
2537 if (DiscardResult)
2538 return true;
2539
2540 assert(!Initializing);
2541
2542 auto &A = Ctx.getASTContext();
2543 std::string ResultStr = E->ComputeName(Context&: A);
2544
2545 QualType CharTy = A.CharTy.withConst();
2546 APInt Size(A.getTypeSize(T: A.getSizeType()), ResultStr.size() + 1);
2547 QualType ArrayTy = A.getConstantArrayType(EltTy: CharTy, ArySize: Size, SizeExpr: nullptr,
2548 ASM: ArraySizeModifier::Normal, IndexTypeQuals: 0);
2549
2550 StringLiteral *SL =
2551 StringLiteral::Create(Ctx: A, Str: ResultStr, Kind: StringLiteralKind::Ordinary,
2552 /*Pascal=*/false, Ty: ArrayTy, Locs: E->getLocation());
2553
2554 unsigned StringIndex = P.createGlobalString(S: SL);
2555 return this->emitGetPtrGlobal(StringIndex, E);
2556}
2557
2558template <class Emitter>
2559bool Compiler<Emitter>::VisitCharacterLiteral(const CharacterLiteral *E) {
2560 if (DiscardResult)
2561 return true;
2562 return this->emitConst(E->getValue(), E);
2563}
2564
2565template <class Emitter>
2566bool Compiler<Emitter>::VisitFloatCompoundAssignOperator(
2567 const CompoundAssignOperator *E) {
2568
2569 const Expr *LHS = E->getLHS();
2570 const Expr *RHS = E->getRHS();
2571 QualType LHSType = LHS->getType();
2572 QualType LHSComputationType = E->getComputationLHSType();
2573 QualType ResultType = E->getComputationResultType();
2574 std::optional<PrimType> LT = classify(LHSComputationType);
2575 std::optional<PrimType> RT = classify(ResultType);
2576
2577 assert(ResultType->isFloatingType());
2578
2579 if (!LT || !RT)
2580 return false;
2581
2582 PrimType LHST = classifyPrim(LHSType);
2583
2584 // C++17 onwards require that we evaluate the RHS first.
2585 // Compute RHS and save it in a temporary variable so we can
2586 // load it again later.
2587 if (!visit(E: RHS))
2588 return false;
2589
2590 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
2591 if (!this->emitSetLocal(*RT, TempOffset, E))
2592 return false;
2593
2594 // First, visit LHS.
2595 if (!visit(E: LHS))
2596 return false;
2597 if (!this->emitLoad(LHST, E))
2598 return false;
2599
2600 // If necessary, convert LHS to its computation type.
2601 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
2602 LHSComputationType, E))
2603 return false;
2604
2605 // Now load RHS.
2606 if (!this->emitGetLocal(*RT, TempOffset, E))
2607 return false;
2608
2609 switch (E->getOpcode()) {
2610 case BO_AddAssign:
2611 if (!this->emitAddf(getFPOptions(E), E))
2612 return false;
2613 break;
2614 case BO_SubAssign:
2615 if (!this->emitSubf(getFPOptions(E), E))
2616 return false;
2617 break;
2618 case BO_MulAssign:
2619 if (!this->emitMulf(getFPOptions(E), E))
2620 return false;
2621 break;
2622 case BO_DivAssign:
2623 if (!this->emitDivf(getFPOptions(E), E))
2624 return false;
2625 break;
2626 default:
2627 return false;
2628 }
2629
2630 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->getType(), E))
2631 return false;
2632
2633 if (DiscardResult)
2634 return this->emitStorePop(LHST, E);
2635 return this->emitStore(LHST, E);
2636}
2637
2638template <class Emitter>
2639bool Compiler<Emitter>::VisitPointerCompoundAssignOperator(
2640 const CompoundAssignOperator *E) {
2641 BinaryOperatorKind Op = E->getOpcode();
2642 const Expr *LHS = E->getLHS();
2643 const Expr *RHS = E->getRHS();
2644 std::optional<PrimType> LT = classify(LHS->getType());
2645 std::optional<PrimType> RT = classify(RHS->getType());
2646
2647 if (Op != BO_AddAssign && Op != BO_SubAssign)
2648 return false;
2649
2650 if (!LT || !RT)
2651 return false;
2652
2653 if (!visit(E: LHS))
2654 return false;
2655
2656 if (!this->emitLoad(*LT, LHS))
2657 return false;
2658
2659 if (!visit(E: RHS))
2660 return false;
2661
2662 if (Op == BO_AddAssign) {
2663 if (!this->emitAddOffset(*RT, E))
2664 return false;
2665 } else {
2666 if (!this->emitSubOffset(*RT, E))
2667 return false;
2668 }
2669
2670 if (DiscardResult)
2671 return this->emitStorePopPtr(E);
2672 return this->emitStorePtr(E);
2673}
2674
2675template <class Emitter>
2676bool Compiler<Emitter>::VisitCompoundAssignOperator(
2677 const CompoundAssignOperator *E) {
2678 if (E->getType()->isVectorType())
2679 return VisitVectorBinOp(E);
2680
2681 const Expr *LHS = E->getLHS();
2682 const Expr *RHS = E->getRHS();
2683 std::optional<PrimType> LHSComputationT =
2684 classify(E->getComputationLHSType());
2685 std::optional<PrimType> LT = classify(LHS->getType());
2686 std::optional<PrimType> RT = classify(RHS->getType());
2687 std::optional<PrimType> ResultT = classify(E->getType());
2688
2689 if (!Ctx.getLangOpts().CPlusPlus14)
2690 return this->visit(RHS) && this->visit(LHS) && this->emitError(E);
2691
2692 if (!LT || !RT || !ResultT || !LHSComputationT)
2693 return false;
2694
2695 // Handle floating point operations separately here, since they
2696 // require special care.
2697
2698 if (ResultT == PT_Float || RT == PT_Float)
2699 return VisitFloatCompoundAssignOperator(E);
2700
2701 if (E->getType()->isPointerType())
2702 return VisitPointerCompoundAssignOperator(E);
2703
2704 assert(!E->getType()->isPointerType() && "Handled above");
2705 assert(!E->getType()->isFloatingType() && "Handled above");
2706
2707 // C++17 onwards require that we evaluate the RHS first.
2708 // Compute RHS and save it in a temporary variable so we can
2709 // load it again later.
2710 // FIXME: Compound assignments are unsequenced in C, so we might
2711 // have to figure out how to reject them.
2712 if (!visit(E: RHS))
2713 return false;
2714
2715 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
2716
2717 if (!this->emitSetLocal(*RT, TempOffset, E))
2718 return false;
2719
2720 // Get LHS pointer, load its value and cast it to the
2721 // computation type if necessary.
2722 if (!visit(E: LHS))
2723 return false;
2724 if (!this->emitLoad(*LT, E))
2725 return false;
2726 if (LT != LHSComputationT) {
2727 if (!this->emitCast(*LT, *LHSComputationT, E))
2728 return false;
2729 }
2730
2731 // Get the RHS value on the stack.
2732 if (!this->emitGetLocal(*RT, TempOffset, E))
2733 return false;
2734
2735 // Perform operation.
2736 switch (E->getOpcode()) {
2737 case BO_AddAssign:
2738 if (!this->emitAdd(*LHSComputationT, E))
2739 return false;
2740 break;
2741 case BO_SubAssign:
2742 if (!this->emitSub(*LHSComputationT, E))
2743 return false;
2744 break;
2745 case BO_MulAssign:
2746 if (!this->emitMul(*LHSComputationT, E))
2747 return false;
2748 break;
2749 case BO_DivAssign:
2750 if (!this->emitDiv(*LHSComputationT, E))
2751 return false;
2752 break;
2753 case BO_RemAssign:
2754 if (!this->emitRem(*LHSComputationT, E))
2755 return false;
2756 break;
2757 case BO_ShlAssign:
2758 if (!this->emitShl(*LHSComputationT, *RT, E))
2759 return false;
2760 break;
2761 case BO_ShrAssign:
2762 if (!this->emitShr(*LHSComputationT, *RT, E))
2763 return false;
2764 break;
2765 case BO_AndAssign:
2766 if (!this->emitBitAnd(*LHSComputationT, E))
2767 return false;
2768 break;
2769 case BO_XorAssign:
2770 if (!this->emitBitXor(*LHSComputationT, E))
2771 return false;
2772 break;
2773 case BO_OrAssign:
2774 if (!this->emitBitOr(*LHSComputationT, E))
2775 return false;
2776 break;
2777 default:
2778 llvm_unreachable("Unimplemented compound assign operator");
2779 }
2780
2781 // And now cast from LHSComputationT to ResultT.
2782 if (ResultT != LHSComputationT) {
2783 if (!this->emitCast(*LHSComputationT, *ResultT, E))
2784 return false;
2785 }
2786
2787 // And store the result in LHS.
2788 if (DiscardResult) {
2789 if (LHS->refersToBitField())
2790 return this->emitStoreBitFieldPop(*ResultT, E);
2791 return this->emitStorePop(*ResultT, E);
2792 }
2793 if (LHS->refersToBitField())
2794 return this->emitStoreBitField(*ResultT, E);
2795 return this->emitStore(*ResultT, E);
2796}
2797
2798template <class Emitter>
2799bool Compiler<Emitter>::VisitExprWithCleanups(const ExprWithCleanups *E) {
2800 LocalScope<Emitter> ES(this);
2801 const Expr *SubExpr = E->getSubExpr();
2802
2803 return this->delegate(SubExpr) && ES.destroyLocals(E);
2804}
2805
2806template <class Emitter>
2807bool Compiler<Emitter>::VisitMaterializeTemporaryExpr(
2808 const MaterializeTemporaryExpr *E) {
2809 const Expr *SubExpr = E->getSubExpr();
2810
2811 if (Initializing) {
2812 // We already have a value, just initialize that.
2813 return this->delegate(SubExpr);
2814 }
2815 // If we don't end up using the materialized temporary anyway, don't
2816 // bother creating it.
2817 if (DiscardResult)
2818 return this->discard(SubExpr);
2819
2820 // When we're initializing a global variable *or* the storage duration of
2821 // the temporary is explicitly static, create a global variable.
2822 std::optional<PrimType> SubExprT = classify(SubExpr);
2823 bool IsStatic = E->getStorageDuration() == SD_Static;
2824 if (IsStatic) {
2825 std::optional<unsigned> GlobalIndex = P.createGlobal(E);
2826 if (!GlobalIndex)
2827 return false;
2828
2829 const LifetimeExtendedTemporaryDecl *TempDecl =
2830 E->getLifetimeExtendedTemporaryDecl();
2831 if (IsStatic)
2832 assert(TempDecl);
2833
2834 if (SubExprT) {
2835 if (!this->visit(SubExpr))
2836 return false;
2837 if (IsStatic) {
2838 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl, E))
2839 return false;
2840 } else {
2841 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex, E))
2842 return false;
2843 }
2844 return this->emitGetPtrGlobal(*GlobalIndex, E);
2845 }
2846
2847 if (!this->checkLiteralType(SubExpr))
2848 return false;
2849 // Non-primitive values.
2850 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2851 return false;
2852 if (!this->visitInitializer(SubExpr))
2853 return false;
2854 if (IsStatic)
2855 return this->emitInitGlobalTempComp(TempDecl, E);
2856 return true;
2857 }
2858
2859 // For everyhing else, use local variables.
2860 if (SubExprT) {
2861 bool IsConst = SubExpr->getType().isConstQualified();
2862 unsigned LocalIndex =
2863 allocateLocalPrimitive(Decl: E, Ty: *SubExprT, IsConst, ExtendingDecl: E->getExtendingDecl());
2864 if (!this->visit(SubExpr))
2865 return false;
2866 if (!this->emitSetLocal(*SubExprT, LocalIndex, E))
2867 return false;
2868 return this->emitGetPtrLocal(LocalIndex, E);
2869 } else {
2870
2871 if (!this->checkLiteralType(SubExpr))
2872 return false;
2873
2874 const Expr *Inner = E->getSubExpr()->skipRValueSubobjectAdjustments();
2875 if (std::optional<unsigned> LocalIndex =
2876 allocateLocal(Decl: E, Ty: Inner->getType(), ExtendingDecl: E->getExtendingDecl())) {
2877 InitLinkScope<Emitter> ILS(this, InitLink::Temp(Offset: *LocalIndex));
2878 if (!this->emitGetPtrLocal(*LocalIndex, E))
2879 return false;
2880 return this->visitInitializer(SubExpr) && this->emitFinishInit(E);
2881 }
2882 }
2883 return false;
2884}
2885
2886template <class Emitter>
2887bool Compiler<Emitter>::VisitCXXBindTemporaryExpr(
2888 const CXXBindTemporaryExpr *E) {
2889 return this->delegate(E->getSubExpr());
2890}
2891
2892template <class Emitter>
2893bool Compiler<Emitter>::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
2894 const Expr *Init = E->getInitializer();
2895 if (DiscardResult)
2896 return this->discard(Init);
2897
2898 if (Initializing) {
2899 // We already have a value, just initialize that.
2900 return this->visitInitializer(Init) && this->emitFinishInit(E);
2901 }
2902
2903 std::optional<PrimType> T = classify(E->getType());
2904 if (E->isFileScope()) {
2905 // Avoid creating a variable if this is a primitive RValue anyway.
2906 if (T && !E->isLValue())
2907 return this->delegate(Init);
2908
2909 if (std::optional<unsigned> GlobalIndex = P.createGlobal(E)) {
2910 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2911 return false;
2912
2913 if (T) {
2914 if (!this->visit(Init))
2915 return false;
2916 return this->emitInitGlobal(*T, *GlobalIndex, E);
2917 }
2918
2919 return this->visitInitializer(Init) && this->emitFinishInit(E);
2920 }
2921
2922 return false;
2923 }
2924
2925 // Otherwise, use a local variable.
2926 if (T && !E->isLValue()) {
2927 // For primitive types, we just visit the initializer.
2928 return this->delegate(Init);
2929 }
2930
2931 unsigned LocalIndex;
2932 if (T)
2933 LocalIndex = this->allocateLocalPrimitive(Init, *T, /*IsConst=*/false);
2934 else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(Init))
2935 LocalIndex = *MaybeIndex;
2936 else
2937 return false;
2938
2939 if (!this->emitGetPtrLocal(LocalIndex, E))
2940 return false;
2941
2942 if (T)
2943 return this->visit(Init) && this->emitInit(*T, E);
2944 return this->visitInitializer(Init) && this->emitFinishInit(E);
2945}
2946
2947template <class Emitter>
2948bool Compiler<Emitter>::VisitTypeTraitExpr(const TypeTraitExpr *E) {
2949 if (DiscardResult)
2950 return true;
2951 if (E->isStoredAsBoolean()) {
2952 if (E->getType()->isBooleanType())
2953 return this->emitConstBool(E->getBoolValue(), E);
2954 return this->emitConst(E->getBoolValue(), E);
2955 }
2956 PrimType T = classifyPrim(E->getType());
2957 return this->visitAPValue(E->getAPValue(), T, E);
2958}
2959
2960template <class Emitter>
2961bool Compiler<Emitter>::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
2962 if (DiscardResult)
2963 return true;
2964 return this->emitConst(E->getValue(), E);
2965}
2966
2967template <class Emitter>
2968bool Compiler<Emitter>::VisitLambdaExpr(const LambdaExpr *E) {
2969 if (DiscardResult)
2970 return true;
2971
2972 assert(Initializing);
2973 const Record *R = P.getOrCreateRecord(RD: E->getLambdaClass());
2974 if (!R)
2975 return false;
2976
2977 auto *CaptureInitIt = E->capture_init_begin();
2978 // Initialize all fields (which represent lambda captures) of the
2979 // record with their initializers.
2980 for (const Record::Field &F : R->fields()) {
2981 const Expr *Init = *CaptureInitIt;
2982 if (!Init || Init->containsErrors())
2983 continue;
2984 ++CaptureInitIt;
2985
2986 if (std::optional<PrimType> T = classify(Init)) {
2987 if (!this->visit(Init))
2988 return false;
2989
2990 if (!this->emitInitField(*T, F.Offset, E))
2991 return false;
2992 } else {
2993 if (!this->emitGetPtrField(F.Offset, E))
2994 return false;
2995
2996 if (!this->visitInitializer(Init))
2997 return false;
2998
2999 if (!this->emitPopPtr(E))
3000 return false;
3001 }
3002 }
3003
3004 return true;
3005}
3006
3007template <class Emitter>
3008bool Compiler<Emitter>::VisitPredefinedExpr(const PredefinedExpr *E) {
3009 if (DiscardResult)
3010 return true;
3011
3012 if (!Initializing) {
3013 unsigned StringIndex = P.createGlobalString(S: E->getFunctionName(), Base: E);
3014 return this->emitGetPtrGlobal(StringIndex, E);
3015 }
3016
3017 return this->delegate(E->getFunctionName());
3018}
3019
3020template <class Emitter>
3021bool Compiler<Emitter>::VisitCXXThrowExpr(const CXXThrowExpr *E) {
3022 if (E->getSubExpr() && !this->discard(E->getSubExpr()))
3023 return false;
3024
3025 return this->emitInvalid(E);
3026}
3027
3028template <class Emitter>
3029bool Compiler<Emitter>::VisitCXXReinterpretCastExpr(
3030 const CXXReinterpretCastExpr *E) {
3031 const Expr *SubExpr = E->getSubExpr();
3032
3033 std::optional<PrimType> FromT = classify(SubExpr);
3034 std::optional<PrimType> ToT = classify(E);
3035
3036 if (!FromT || !ToT)
3037 return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, E);
3038
3039 if (FromT == PT_Ptr || ToT == PT_Ptr) {
3040 // Both types could be PT_Ptr because their expressions are glvalues.
3041 std::optional<PrimType> PointeeFromT;
3042 if (SubExpr->getType()->isPointerOrReferenceType())
3043 PointeeFromT = classify(SubExpr->getType()->getPointeeType());
3044 else
3045 PointeeFromT = classify(SubExpr->getType());
3046
3047 std::optional<PrimType> PointeeToT;
3048 if (E->getType()->isPointerOrReferenceType())
3049 PointeeToT = classify(E->getType()->getPointeeType());
3050 else
3051 PointeeToT = classify(E->getType());
3052
3053 bool Fatal = true;
3054 if (PointeeToT && PointeeFromT) {
3055 if (isIntegralType(T: *PointeeFromT) && isIntegralType(T: *PointeeToT))
3056 Fatal = false;
3057 } else {
3058 Fatal = SubExpr->getType().getTypePtr() != E->getType().getTypePtr();
3059 }
3060
3061 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal, E))
3062 return false;
3063
3064 if (E->getCastKind() == CK_LValueBitCast)
3065 return this->delegate(SubExpr);
3066 return this->VisitCastExpr(E);
3067 }
3068
3069 // Try to actually do the cast.
3070 bool Fatal = (ToT != FromT);
3071 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal, E))
3072 return false;
3073
3074 return this->VisitCastExpr(E);
3075}
3076
3077template <class Emitter>
3078bool Compiler<Emitter>::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E) {
3079
3080 if (!Ctx.getLangOpts().CPlusPlus20) {
3081 if (!this->emitInvalidCast(CastKind::Dynamic, /*Fatal=*/false, E))
3082 return false;
3083 }
3084
3085 return this->VisitCastExpr(E);
3086}
3087
3088template <class Emitter>
3089bool Compiler<Emitter>::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {
3090 assert(E->getType()->isBooleanType());
3091
3092 if (DiscardResult)
3093 return true;
3094 return this->emitConstBool(E->getValue(), E);
3095}
3096
3097template <class Emitter>
3098bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) {
3099 QualType T = E->getType();
3100 assert(!classify(T));
3101
3102 if (T->isRecordType()) {
3103 const CXXConstructorDecl *Ctor = E->getConstructor();
3104
3105 // Trivial copy/move constructor. Avoid copy.
3106 if (Ctor->isDefaulted() && Ctor->isCopyOrMoveConstructor() &&
3107 Ctor->isTrivial() &&
3108 E->getArg(Arg: 0)->isTemporaryObject(Ctx&: Ctx.getASTContext(),
3109 TempTy: T->getAsCXXRecordDecl()))
3110 return this->visitInitializer(E->getArg(Arg: 0));
3111
3112 // If we're discarding a construct expression, we still need
3113 // to allocate a variable and call the constructor and destructor.
3114 if (DiscardResult) {
3115 if (Ctor->isTrivial())
3116 return true;
3117 assert(!Initializing);
3118 std::optional<unsigned> LocalIndex = allocateLocal(Decl: E);
3119
3120 if (!LocalIndex)
3121 return false;
3122
3123 if (!this->emitGetPtrLocal(*LocalIndex, E))
3124 return false;
3125 }
3126
3127 // Zero initialization.
3128 if (E->requiresZeroInitialization()) {
3129 const Record *R = getRecord(E->getType());
3130
3131 if (!this->visitZeroRecordInitializer(R, E))
3132 return false;
3133
3134 // If the constructor is trivial anyway, we're done.
3135 if (Ctor->isTrivial())
3136 return true;
3137 }
3138
3139 const Function *Func = getFunction(FD: Ctor);
3140
3141 if (!Func)
3142 return false;
3143
3144 assert(Func->hasThisPointer());
3145 assert(!Func->hasRVO());
3146
3147 // The This pointer is already on the stack because this is an initializer,
3148 // but we need to dup() so the call() below has its own copy.
3149 if (!this->emitDupPtr(E))
3150 return false;
3151
3152 // Constructor arguments.
3153 for (const auto *Arg : E->arguments()) {
3154 if (!this->visit(Arg))
3155 return false;
3156 }
3157
3158 if (Func->isVariadic()) {
3159 uint32_t VarArgSize = 0;
3160 unsigned NumParams = Func->getNumWrittenParams();
3161 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I) {
3162 VarArgSize +=
3163 align(primSize(classify(E->getArg(Arg: I)->getType()).value_or(PT_Ptr)));
3164 }
3165 if (!this->emitCallVar(Func, VarArgSize, E))
3166 return false;
3167 } else {
3168 if (!this->emitCall(Func, 0, E)) {
3169 // When discarding, we don't need the result anyway, so clean up
3170 // the instance dup we did earlier in case surrounding code wants
3171 // to keep evaluating.
3172 if (DiscardResult)
3173 (void)this->emitPopPtr(E);
3174 return false;
3175 }
3176 }
3177
3178 if (DiscardResult)
3179 return this->emitPopPtr(E);
3180 return this->emitFinishInit(E);
3181 }
3182
3183 if (T->isArrayType()) {
3184 const ConstantArrayType *CAT =
3185 Ctx.getASTContext().getAsConstantArrayType(T: E->getType());
3186 if (!CAT)
3187 return false;
3188
3189 size_t NumElems = CAT->getZExtSize();
3190 const Function *Func = getFunction(FD: E->getConstructor());
3191 if (!Func)
3192 return false;
3193
3194 // FIXME(perf): We're calling the constructor once per array element here,
3195 // in the old intepreter we had a special-case for trivial constructors.
3196 for (size_t I = 0; I != NumElems; ++I) {
3197 if (!this->emitConstUint64(I, E))
3198 return false;
3199 if (!this->emitArrayElemPtrUint64(E))
3200 return false;
3201
3202 // Constructor arguments.
3203 for (const auto *Arg : E->arguments()) {
3204 if (!this->visit(Arg))
3205 return false;
3206 }
3207
3208 if (!this->emitCall(Func, 0, E))
3209 return false;
3210 }
3211 return true;
3212 }
3213
3214 return false;
3215}
3216
3217template <class Emitter>
3218bool Compiler<Emitter>::VisitSourceLocExpr(const SourceLocExpr *E) {
3219 if (DiscardResult)
3220 return true;
3221
3222 const APValue Val =
3223 E->EvaluateInContext(Ctx: Ctx.getASTContext(), DefaultExpr: SourceLocDefaultExpr);
3224
3225 // Things like __builtin_LINE().
3226 if (E->getType()->isIntegerType()) {
3227 assert(Val.isInt());
3228 const APSInt &I = Val.getInt();
3229 return this->emitConst(I, E);
3230 }
3231 // Otherwise, the APValue is an LValue, with only one element.
3232 // Theoretically, we don't need the APValue at all of course.
3233 assert(E->getType()->isPointerType());
3234 assert(Val.isLValue());
3235 const APValue::LValueBase &Base = Val.getLValueBase();
3236 if (const Expr *LValueExpr = Base.dyn_cast<const Expr *>())
3237 return this->visit(LValueExpr);
3238
3239 // Otherwise, we have a decl (which is the case for
3240 // __builtin_source_location).
3241 assert(Base.is<const ValueDecl *>());
3242 assert(Val.getLValuePath().size() == 0);
3243 const auto *BaseDecl = Base.dyn_cast<const ValueDecl *>();
3244 assert(BaseDecl);
3245
3246 auto *UGCD = cast<UnnamedGlobalConstantDecl>(Val: BaseDecl);
3247
3248 std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(VD: UGCD);
3249 if (!GlobalIndex)
3250 return false;
3251
3252 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3253 return false;
3254
3255 const Record *R = getRecord(E->getType());
3256 const APValue &V = UGCD->getValue();
3257 for (unsigned I = 0, N = R->getNumFields(); I != N; ++I) {
3258 const Record::Field *F = R->getField(I);
3259 const APValue &FieldValue = V.getStructField(i: I);
3260
3261 PrimType FieldT = classifyPrim(F->Decl->getType());
3262
3263 if (!this->visitAPValue(FieldValue, FieldT, E))
3264 return false;
3265 if (!this->emitInitField(FieldT, F->Offset, E))
3266 return false;
3267 }
3268
3269 // Leave the pointer to the global on the stack.
3270 return true;
3271}
3272
3273template <class Emitter>
3274bool Compiler<Emitter>::VisitOffsetOfExpr(const OffsetOfExpr *E) {
3275 unsigned N = E->getNumComponents();
3276 if (N == 0)
3277 return false;
3278
3279 for (unsigned I = 0; I != N; ++I) {
3280 const OffsetOfNode &Node = E->getComponent(Idx: I);
3281 if (Node.getKind() == OffsetOfNode::Array) {
3282 const Expr *ArrayIndexExpr = E->getIndexExpr(Idx: Node.getArrayExprIndex());
3283 PrimType IndexT = classifyPrim(ArrayIndexExpr->getType());
3284
3285 if (DiscardResult) {
3286 if (!this->discard(ArrayIndexExpr))
3287 return false;
3288 continue;
3289 }
3290
3291 if (!this->visit(ArrayIndexExpr))
3292 return false;
3293 // Cast to Sint64.
3294 if (IndexT != PT_Sint64) {
3295 if (!this->emitCast(IndexT, PT_Sint64, E))
3296 return false;
3297 }
3298 }
3299 }
3300
3301 if (DiscardResult)
3302 return true;
3303
3304 PrimType T = classifyPrim(E->getType());
3305 return this->emitOffsetOf(T, E, E);
3306}
3307
3308template <class Emitter>
3309bool Compiler<Emitter>::VisitCXXScalarValueInitExpr(
3310 const CXXScalarValueInitExpr *E) {
3311 QualType Ty = E->getType();
3312
3313 if (DiscardResult || Ty->isVoidType())
3314 return true;
3315
3316 if (std::optional<PrimType> T = classify(Ty))
3317 return this->visitZeroInitializer(*T, Ty, E);
3318
3319 if (const auto *CT = Ty->getAs<ComplexType>()) {
3320 if (!Initializing) {
3321 std::optional<unsigned> LocalIndex = allocateLocal(Decl: E);
3322 if (!LocalIndex)
3323 return false;
3324 if (!this->emitGetPtrLocal(*LocalIndex, E))
3325 return false;
3326 }
3327
3328 // Initialize both fields to 0.
3329 QualType ElemQT = CT->getElementType();
3330 PrimType ElemT = classifyPrim(ElemQT);
3331
3332 for (unsigned I = 0; I != 2; ++I) {
3333 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
3334 return false;
3335 if (!this->emitInitElem(ElemT, I, E))
3336 return false;
3337 }
3338 return true;
3339 }
3340
3341 if (const auto *VT = Ty->getAs<VectorType>()) {
3342 // FIXME: Code duplication with the _Complex case above.
3343 if (!Initializing) {
3344 std::optional<unsigned> LocalIndex = allocateLocal(Decl: E);
3345 if (!LocalIndex)
3346 return false;
3347 if (!this->emitGetPtrLocal(*LocalIndex, E))
3348 return false;
3349 }
3350
3351 // Initialize all fields to 0.
3352 QualType ElemQT = VT->getElementType();
3353 PrimType ElemT = classifyPrim(ElemQT);
3354
3355 for (unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
3356 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
3357 return false;
3358 if (!this->emitInitElem(ElemT, I, E))
3359 return false;
3360 }
3361 return true;
3362 }
3363
3364 return false;
3365}
3366
3367template <class Emitter>
3368bool Compiler<Emitter>::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
3369 return this->emitConst(E->getPackLength(), E);
3370}
3371
3372template <class Emitter>
3373bool Compiler<Emitter>::VisitGenericSelectionExpr(
3374 const GenericSelectionExpr *E) {
3375 return this->delegate(E->getResultExpr());
3376}
3377
3378template <class Emitter>
3379bool Compiler<Emitter>::VisitChooseExpr(const ChooseExpr *E) {
3380 return this->delegate(E->getChosenSubExpr());
3381}
3382
3383template <class Emitter>
3384bool Compiler<Emitter>::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) {
3385 if (DiscardResult)
3386 return true;
3387
3388 return this->emitConst(E->getValue(), E);
3389}
3390
3391template <class Emitter>
3392bool Compiler<Emitter>::VisitCXXInheritedCtorInitExpr(
3393 const CXXInheritedCtorInitExpr *E) {
3394 const CXXConstructorDecl *Ctor = E->getConstructor();
3395 assert(!Ctor->isTrivial() &&
3396 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
3397 const Function *F = this->getFunction(Ctor);
3398 assert(F);
3399 assert(!F->hasRVO());
3400 assert(F->hasThisPointer());
3401
3402 if (!this->emitDupPtr(SourceInfo{}))
3403 return false;
3404
3405 // Forward all arguments of the current function (which should be a
3406 // constructor itself) to the inherited ctor.
3407 // This is necessary because the calling code has pushed the pointer
3408 // of the correct base for us already, but the arguments need
3409 // to come after.
3410 unsigned Offset = align(Size: primSize(Type: PT_Ptr)); // instance pointer.
3411 for (const ParmVarDecl *PD : Ctor->parameters()) {
3412 PrimType PT = this->classify(PD->getType()).value_or(PT_Ptr);
3413
3414 if (!this->emitGetParam(PT, Offset, E))
3415 return false;
3416 Offset += align(Size: primSize(Type: PT));
3417 }
3418
3419 return this->emitCall(F, 0, E);
3420}
3421
3422// FIXME: This function has become rather unwieldy, especially
3423// the part where we initialize an array allocation of dynamic size.
3424template <class Emitter>
3425bool Compiler<Emitter>::VisitCXXNewExpr(const CXXNewExpr *E) {
3426 assert(classifyPrim(E->getType()) == PT_Ptr);
3427 const Expr *Init = E->getInitializer();
3428 QualType ElementType = E->getAllocatedType();
3429 std::optional<PrimType> ElemT = classify(ElementType);
3430 unsigned PlacementArgs = E->getNumPlacementArgs();
3431 const FunctionDecl *OperatorNew = E->getOperatorNew();
3432 const Expr *PlacementDest = nullptr;
3433 bool IsNoThrow = false;
3434
3435 if (PlacementArgs != 0) {
3436 // FIXME: There is no restriction on this, but it's not clear that any
3437 // other form makes any sense. We get here for cases such as:
3438 //
3439 // new (std::align_val_t{N}) X(int)
3440 //
3441 // (which should presumably be valid only if N is a multiple of
3442 // alignof(int), and in any case can't be deallocated unless N is
3443 // alignof(X) and X has new-extended alignment).
3444 if (PlacementArgs == 1) {
3445 const Expr *Arg1 = E->getPlacementArg(I: 0);
3446 if (Arg1->getType()->isNothrowT()) {
3447 if (!this->discard(Arg1))
3448 return false;
3449 IsNoThrow = true;
3450 } else {
3451 // Invalid unless we have C++26 or are in a std:: function.
3452 if (!this->emitInvalidNewDeleteExpr(E, E))
3453 return false;
3454
3455 // If we have a placement-new destination, we'll later use that instead
3456 // of allocating.
3457 if (OperatorNew->isReservedGlobalPlacementOperator())
3458 PlacementDest = Arg1;
3459 }
3460 } else {
3461 // Always invalid.
3462 return this->emitInvalid(E);
3463 }
3464 } else if (!OperatorNew
3465 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
3466 return this->emitInvalidNewDeleteExpr(E, E);
3467
3468 const Descriptor *Desc;
3469 if (!PlacementDest) {
3470 if (ElemT) {
3471 if (E->isArray())
3472 Desc = nullptr; // We're not going to use it in this case.
3473 else
3474 Desc = P.createDescriptor(D: E, T: *ElemT, /*SourceTy=*/nullptr,
3475 MDSize: Descriptor::InlineDescMD);
3476 } else {
3477 Desc = P.createDescriptor(
3478 D: E, Ty: ElementType.getTypePtr(),
3479 MDSize: E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
3480 /*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false,
3481 /*IsVolatile=*/false, Init);
3482 }
3483 }
3484
3485 if (E->isArray()) {
3486 std::optional<const Expr *> ArraySizeExpr = E->getArraySize();
3487 if (!ArraySizeExpr)
3488 return false;
3489
3490 const Expr *Stripped = *ArraySizeExpr;
3491 for (; auto *ICE = dyn_cast<ImplicitCastExpr>(Val: Stripped);
3492 Stripped = ICE->getSubExpr())
3493 if (ICE->getCastKind() != CK_NoOp &&
3494 ICE->getCastKind() != CK_IntegralCast)
3495 break;
3496
3497 PrimType SizeT = classifyPrim(Stripped->getType());
3498
3499 // Save evaluated array size to a variable.
3500 unsigned ArrayLen =
3501 allocateLocalPrimitive(Decl: Stripped, Ty: SizeT, /*IsConst=*/false);
3502 if (!this->visit(Stripped))
3503 return false;
3504 if (!this->emitSetLocal(SizeT, ArrayLen, E))
3505 return false;
3506
3507 if (PlacementDest) {
3508 if (!this->visit(PlacementDest))
3509 return false;
3510 if (!this->emitStartLifetime(E))
3511 return false;
3512 if (!this->emitGetLocal(SizeT, ArrayLen, E))
3513 return false;
3514 if (!this->emitCheckNewTypeMismatchArray(SizeT, E, E))
3515 return false;
3516 } else {
3517 if (!this->emitGetLocal(SizeT, ArrayLen, E))
3518 return false;
3519
3520 if (ElemT) {
3521 // N primitive elements.
3522 if (!this->emitAllocN(SizeT, *ElemT, E, IsNoThrow, E))
3523 return false;
3524 } else {
3525 // N Composite elements.
3526 if (!this->emitAllocCN(SizeT, Desc, IsNoThrow, E))
3527 return false;
3528 }
3529 }
3530
3531 if (Init) {
3532 QualType InitType = Init->getType();
3533 size_t StaticInitElems = 0;
3534 const Expr *DynamicInit = nullptr;
3535 if (const ConstantArrayType *CAT =
3536 Ctx.getASTContext().getAsConstantArrayType(T: InitType)) {
3537 StaticInitElems = CAT->getZExtSize();
3538 if (!this->visitInitializer(Init))
3539 return false;
3540
3541 if (const auto *ILE = dyn_cast<InitListExpr>(Val: Init);
3542 ILE && ILE->hasArrayFiller())
3543 DynamicInit = ILE->getArrayFiller();
3544 }
3545
3546 // The initializer initializes a certain number of elements, S.
3547 // However, the complete number of elements, N, might be larger than that.
3548 // In this case, we need to get an initializer for the remaining elements.
3549 // There are to cases:
3550 // 1) For the form 'new Struct[n];', the initializer is a
3551 // CXXConstructExpr and its type is an IncompleteArrayType.
3552 // 2) For the form 'new Struct[n]{1,2,3}', the initializer is an
3553 // InitListExpr and the initializer for the remaining elements
3554 // is the array filler.
3555
3556 if (DynamicInit || InitType->isIncompleteArrayType()) {
3557 const Function *CtorFunc = nullptr;
3558 if (const auto *CE = dyn_cast<CXXConstructExpr>(Val: Init)) {
3559 CtorFunc = getFunction(FD: CE->getConstructor());
3560 if (!CtorFunc)
3561 return false;
3562 } else if (!DynamicInit)
3563 DynamicInit = Init;
3564
3565 LabelTy EndLabel = this->getLabel();
3566 LabelTy StartLabel = this->getLabel();
3567
3568 // In the nothrow case, the alloc above might have returned nullptr.
3569 // Don't call any constructors that case.
3570 if (IsNoThrow) {
3571 if (!this->emitDupPtr(E))
3572 return false;
3573 if (!this->emitNullPtr(0, nullptr, E))
3574 return false;
3575 if (!this->emitEQPtr(E))
3576 return false;
3577 if (!this->jumpTrue(EndLabel))
3578 return false;
3579 }
3580
3581 // Create loop variables.
3582 unsigned Iter =
3583 allocateLocalPrimitive(Decl: Stripped, Ty: SizeT, /*IsConst=*/false);
3584 if (!this->emitConst(StaticInitElems, SizeT, E))
3585 return false;
3586 if (!this->emitSetLocal(SizeT, Iter, E))
3587 return false;
3588
3589 this->fallthrough(StartLabel);
3590 this->emitLabel(StartLabel);
3591 // Condition. Iter < ArrayLen?
3592 if (!this->emitGetLocal(SizeT, Iter, E))
3593 return false;
3594 if (!this->emitGetLocal(SizeT, ArrayLen, E))
3595 return false;
3596 if (!this->emitLT(SizeT, E))
3597 return false;
3598 if (!this->jumpFalse(EndLabel))
3599 return false;
3600
3601 // Pointer to the allocated array is already on the stack.
3602 if (!this->emitGetLocal(SizeT, Iter, E))
3603 return false;
3604 if (!this->emitArrayElemPtr(SizeT, E))
3605 return false;
3606
3607 if (isa_and_nonnull<ImplicitValueInitExpr>(Val: DynamicInit) &&
3608 DynamicInit->getType()->isArrayType()) {
3609 QualType ElemType =
3610 DynamicInit->getType()->getAsArrayTypeUnsafe()->getElementType();
3611 PrimType InitT = classifyPrim(ElemType);
3612 if (!this->visitZeroInitializer(InitT, ElemType, E))
3613 return false;
3614 if (!this->emitStorePop(InitT, E))
3615 return false;
3616 } else if (DynamicInit) {
3617 if (std::optional<PrimType> InitT = classify(DynamicInit)) {
3618 if (!this->visit(DynamicInit))
3619 return false;
3620 if (!this->emitStorePop(*InitT, E))
3621 return false;
3622 } else {
3623 if (!this->visitInitializer(DynamicInit))
3624 return false;
3625 if (!this->emitPopPtr(E))
3626 return false;
3627 }
3628 } else {
3629 assert(CtorFunc);
3630 if (!this->emitCall(CtorFunc, 0, E))
3631 return false;
3632 }
3633
3634 // ++Iter;
3635 if (!this->emitGetPtrLocal(Iter, E))
3636 return false;
3637 if (!this->emitIncPop(SizeT, false, E))
3638 return false;
3639
3640 if (!this->jump(StartLabel))
3641 return false;
3642
3643 this->fallthrough(EndLabel);
3644 this->emitLabel(EndLabel);
3645 }
3646 }
3647 } else { // Non-array.
3648 if (PlacementDest) {
3649 if (!this->visit(PlacementDest))
3650 return false;
3651 if (!this->emitStartLifetime(E))
3652 return false;
3653 if (!this->emitCheckNewTypeMismatch(E, E))
3654 return false;
3655 } else {
3656 // Allocate just one element.
3657 if (!this->emitAlloc(Desc, E))
3658 return false;
3659 }
3660
3661 if (Init) {
3662 if (ElemT) {
3663 if (!this->visit(Init))
3664 return false;
3665
3666 if (!this->emitInit(*ElemT, E))
3667 return false;
3668 } else {
3669 // Composite.
3670 if (!this->visitInitializer(Init))
3671 return false;
3672 }
3673 }
3674 }
3675
3676 if (DiscardResult)
3677 return this->emitPopPtr(E);
3678
3679 return true;
3680}
3681
3682template <class Emitter>
3683bool Compiler<Emitter>::VisitCXXDeleteExpr(const CXXDeleteExpr *E) {
3684 const Expr *Arg = E->getArgument();
3685
3686 const FunctionDecl *OperatorDelete = E->getOperatorDelete();
3687
3688 if (!OperatorDelete->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
3689 return this->emitInvalidNewDeleteExpr(E, E);
3690
3691 // Arg must be an lvalue.
3692 if (!this->visit(Arg))
3693 return false;
3694
3695 return this->emitFree(E->isArrayForm(), E->isGlobalDelete(), E);
3696}
3697
3698template <class Emitter>
3699bool Compiler<Emitter>::VisitBlockExpr(const BlockExpr *E) {
3700 if (DiscardResult)
3701 return true;
3702
3703 const Function *Func = nullptr;
3704 if (auto F = Ctx.getOrCreateObjCBlock(E))
3705 Func = F;
3706
3707 if (!Func)
3708 return false;
3709 return this->emitGetFnPtr(Func, E);
3710}
3711
3712template <class Emitter>
3713bool Compiler<Emitter>::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
3714 const Type *TypeInfoType = E->getType().getTypePtr();
3715
3716 auto canonType = [](const Type *T) {
3717 return T->getCanonicalTypeUnqualified().getTypePtr();
3718 };
3719
3720 if (!E->isPotentiallyEvaluated()) {
3721 if (DiscardResult)
3722 return true;
3723
3724 if (E->isTypeOperand())
3725 return this->emitGetTypeid(
3726 canonType(E->getTypeOperand(Context: Ctx.getASTContext()).getTypePtr()),
3727 TypeInfoType, E);
3728
3729 return this->emitGetTypeid(
3730 canonType(E->getExprOperand()->getType().getTypePtr()), TypeInfoType,
3731 E);
3732 }
3733
3734 // Otherwise, we need to evaluate the expression operand.
3735 assert(E->getExprOperand());
3736 assert(E->getExprOperand()->isLValue());
3737
3738 if (!Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(E))
3739 return false;
3740
3741 if (!this->visit(E->getExprOperand()))
3742 return false;
3743
3744 if (!this->emitGetTypeidPtr(TypeInfoType, E))
3745 return false;
3746 if (DiscardResult)
3747 return this->emitPopPtr(E);
3748 return true;
3749}
3750
3751template <class Emitter>
3752bool Compiler<Emitter>::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
3753 assert(Ctx.getLangOpts().CPlusPlus);
3754 return this->emitConstBool(E->getValue(), E);
3755}
3756
3757template <class Emitter>
3758bool Compiler<Emitter>::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
3759 if (DiscardResult)
3760 return true;
3761 assert(!Initializing);
3762
3763 const MSGuidDecl *GuidDecl = E->getGuidDecl();
3764 const RecordDecl *RD = GuidDecl->getType()->getAsRecordDecl();
3765 assert(RD);
3766 // If the definiton of the result type is incomplete, just return a dummy.
3767 // If (and when) that is read from, we will fail, but not now.
3768 if (!RD->isCompleteDefinition())
3769 return this->emitDummyPtr(GuidDecl, E);
3770
3771 std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(VD: GuidDecl);
3772 if (!GlobalIndex)
3773 return false;
3774 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3775 return false;
3776
3777 assert(this->getRecord(E->getType()));
3778
3779 const APValue &V = GuidDecl->getAsAPValue();
3780 if (V.getKind() == APValue::None)
3781 return true;
3782
3783 assert(V.isStruct());
3784 assert(V.getStructNumBases() == 0);
3785 if (!this->visitAPValueInitializer(V, E, E->getType()))
3786 return false;
3787
3788 return this->emitFinishInit(E);
3789}
3790
3791template <class Emitter>
3792bool Compiler<Emitter>::VisitRequiresExpr(const RequiresExpr *E) {
3793 assert(classifyPrim(E->getType()) == PT_Bool);
3794 if (DiscardResult)
3795 return true;
3796 return this->emitConstBool(E->isSatisfied(), E);
3797}
3798
3799template <class Emitter>
3800bool Compiler<Emitter>::VisitConceptSpecializationExpr(
3801 const ConceptSpecializationExpr *E) {
3802 assert(classifyPrim(E->getType()) == PT_Bool);
3803 if (DiscardResult)
3804 return true;
3805 return this->emitConstBool(E->isSatisfied(), E);
3806}
3807
3808template <class Emitter>
3809bool Compiler<Emitter>::VisitCXXRewrittenBinaryOperator(
3810 const CXXRewrittenBinaryOperator *E) {
3811 return this->delegate(E->getSemanticForm());
3812}
3813
3814template <class Emitter>
3815bool Compiler<Emitter>::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
3816
3817 for (const Expr *SemE : E->semantics()) {
3818 if (auto *OVE = dyn_cast<OpaqueValueExpr>(Val: SemE)) {
3819 if (SemE == E->getResultExpr())
3820 return false;
3821
3822 if (OVE->isUnique())
3823 continue;
3824
3825 if (!this->discard(OVE))
3826 return false;
3827 } else if (SemE == E->getResultExpr()) {
3828 if (!this->delegate(SemE))
3829 return false;
3830 } else {
3831 if (!this->discard(SemE))
3832 return false;
3833 }
3834 }
3835 return true;
3836}
3837
3838template <class Emitter>
3839bool Compiler<Emitter>::VisitPackIndexingExpr(const PackIndexingExpr *E) {
3840 return this->delegate(E->getSelectedExpr());
3841}
3842
3843template <class Emitter>
3844bool Compiler<Emitter>::VisitRecoveryExpr(const RecoveryExpr *E) {
3845 return this->emitError(E);
3846}
3847
3848template <class Emitter>
3849bool Compiler<Emitter>::VisitAddrLabelExpr(const AddrLabelExpr *E) {
3850 assert(E->getType()->isVoidPointerType());
3851
3852 unsigned Offset =
3853 allocateLocalPrimitive(Decl: E->getLabel(), Ty: PT_Ptr, /*IsConst=*/true);
3854
3855 return this->emitGetLocal(PT_Ptr, Offset, E);
3856}
3857
3858template <class Emitter>
3859bool Compiler<Emitter>::VisitConvertVectorExpr(const ConvertVectorExpr *E) {
3860 assert(Initializing);
3861 const auto *VT = E->getType()->castAs<VectorType>();
3862 QualType ElemType = VT->getElementType();
3863 PrimType ElemT = classifyPrim(ElemType);
3864 const Expr *Src = E->getSrcExpr();
3865 QualType SrcType = Src->getType();
3866 PrimType SrcElemT = classifyVectorElementType(T: SrcType);
3867
3868 unsigned SrcOffset =
3869 this->allocateLocalPrimitive(Src, PT_Ptr, /*IsConst=*/true);
3870 if (!this->visit(Src))
3871 return false;
3872 if (!this->emitSetLocal(PT_Ptr, SrcOffset, E))
3873 return false;
3874
3875 for (unsigned I = 0; I != VT->getNumElements(); ++I) {
3876 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
3877 return false;
3878 if (!this->emitArrayElemPop(SrcElemT, I, E))
3879 return false;
3880
3881 // Cast to the desired result element type.
3882 if (SrcElemT != ElemT) {
3883 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
3884 return false;
3885 } else if (ElemType->isFloatingType() && SrcType != ElemType) {
3886 const auto *TargetSemantics = &Ctx.getFloatSemantics(T: ElemType);
3887 if (!this->emitCastFP(TargetSemantics, getRoundingMode(E), E))
3888 return false;
3889 }
3890 if (!this->emitInitElem(ElemT, I, E))
3891 return false;
3892 }
3893
3894 return true;
3895}
3896
3897template <class Emitter>
3898bool Compiler<Emitter>::VisitShuffleVectorExpr(const ShuffleVectorExpr *E) {
3899 assert(Initializing);
3900 assert(E->getNumSubExprs() > 2);
3901
3902 const Expr *Vecs[] = {E->getExpr(Index: 0), E->getExpr(Index: 1)};
3903 const VectorType *VT = Vecs[0]->getType()->castAs<VectorType>();
3904 PrimType ElemT = classifyPrim(VT->getElementType());
3905 unsigned NumInputElems = VT->getNumElements();
3906 unsigned NumOutputElems = E->getNumSubExprs() - 2;
3907 assert(NumOutputElems > 0);
3908
3909 // Save both input vectors to a local variable.
3910 unsigned VectorOffsets[2];
3911 for (unsigned I = 0; I != 2; ++I) {
3912 VectorOffsets[I] =
3913 this->allocateLocalPrimitive(Vecs[I], PT_Ptr, /*IsConst=*/true);
3914 if (!this->visit(Vecs[I]))
3915 return false;
3916 if (!this->emitSetLocal(PT_Ptr, VectorOffsets[I], E))
3917 return false;
3918 }
3919 for (unsigned I = 0; I != NumOutputElems; ++I) {
3920 APSInt ShuffleIndex = E->getShuffleMaskIdx(N: I);
3921 assert(ShuffleIndex >= -1);
3922 if (ShuffleIndex == -1)
3923 return this->emitInvalidShuffleVectorIndex(I, E);
3924
3925 assert(ShuffleIndex < (NumInputElems * 2));
3926 if (!this->emitGetLocal(PT_Ptr,
3927 VectorOffsets[ShuffleIndex >= NumInputElems], E))
3928 return false;
3929 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
3930 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
3931 return false;
3932
3933 if (!this->emitInitElem(ElemT, I, E))
3934 return false;
3935 }
3936
3937 return true;
3938}
3939
3940template <class Emitter>
3941bool Compiler<Emitter>::VisitExtVectorElementExpr(
3942 const ExtVectorElementExpr *E) {
3943 const Expr *Base = E->getBase();
3944 assert(
3945 Base->getType()->isVectorType() ||
3946 Base->getType()->getAs<PointerType>()->getPointeeType()->isVectorType());
3947
3948 SmallVector<uint32_t, 4> Indices;
3949 E->getEncodedElementAccess(Elts&: Indices);
3950
3951 if (Indices.size() == 1) {
3952 if (!this->visit(Base))
3953 return false;
3954
3955 if (E->isGLValue()) {
3956 if (!this->emitConstUint32(Indices[0], E))
3957 return false;
3958 return this->emitArrayElemPtrPop(PT_Uint32, E);
3959 }
3960 // Else, also load the value.
3961 return this->emitArrayElemPop(classifyPrim(E->getType()), Indices[0], E);
3962 }
3963
3964 // Create a local variable for the base.
3965 unsigned BaseOffset = allocateLocalPrimitive(Decl: Base, Ty: PT_Ptr, /*IsConst=*/true);
3966 if (!this->visit(Base))
3967 return false;
3968 if (!this->emitSetLocal(PT_Ptr, BaseOffset, E))
3969 return false;
3970
3971 // Now the vector variable for the return value.
3972 if (!Initializing) {
3973 std::optional<unsigned> ResultIndex;
3974 ResultIndex = allocateLocal(Decl: E);
3975 if (!ResultIndex)
3976 return false;
3977 if (!this->emitGetPtrLocal(*ResultIndex, E))
3978 return false;
3979 }
3980
3981 assert(Indices.size() == E->getType()->getAs<VectorType>()->getNumElements());
3982
3983 PrimType ElemT =
3984 classifyPrim(E->getType()->getAs<VectorType>()->getElementType());
3985 uint32_t DstIndex = 0;
3986 for (uint32_t I : Indices) {
3987 if (!this->emitGetLocal(PT_Ptr, BaseOffset, E))
3988 return false;
3989 if (!this->emitArrayElemPop(ElemT, I, E))
3990 return false;
3991 if (!this->emitInitElem(ElemT, DstIndex, E))
3992 return false;
3993 ++DstIndex;
3994 }
3995
3996 // Leave the result pointer on the stack.
3997 assert(!DiscardResult);
3998 return true;
3999}
4000
4001template <class Emitter>
4002bool Compiler<Emitter>::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
4003 const Expr *SubExpr = E->getSubExpr();
4004 if (!E->isExpressibleAsConstantInitializer())
4005 return this->discard(SubExpr) && this->emitInvalid(E);
4006
4007 if (DiscardResult)
4008 return true;
4009
4010 assert(classifyPrim(E) == PT_Ptr);
4011 return this->emitDummyPtr(E, E);
4012}
4013
4014template <class Emitter>
4015bool Compiler<Emitter>::VisitCXXStdInitializerListExpr(
4016 const CXXStdInitializerListExpr *E) {
4017 const Expr *SubExpr = E->getSubExpr();
4018 const ConstantArrayType *ArrayType =
4019 Ctx.getASTContext().getAsConstantArrayType(T: SubExpr->getType());
4020 const Record *R = getRecord(E->getType());
4021 assert(Initializing);
4022 assert(SubExpr->isGLValue());
4023
4024 if (!this->visit(SubExpr))
4025 return false;
4026 if (!this->emitConstUint8(0, E))
4027 return false;
4028 if (!this->emitArrayElemPtrPopUint8(E))
4029 return false;
4030 if (!this->emitInitFieldPtr(R->getField(I: 0u)->Offset, E))
4031 return false;
4032
4033 PrimType SecondFieldT = classifyPrim(R->getField(I: 1u)->Decl->getType());
4034 if (isIntegralType(T: SecondFieldT)) {
4035 if (!this->emitConst(static_cast<APSInt>(ArrayType->getSize()),
4036 SecondFieldT, E))
4037 return false;
4038 return this->emitInitField(SecondFieldT, R->getField(I: 1u)->Offset, E);
4039 }
4040 assert(SecondFieldT == PT_Ptr);
4041
4042 if (!this->emitGetFieldPtr(R->getField(I: 0u)->Offset, E))
4043 return false;
4044 if (!this->emitExpandPtr(E))
4045 return false;
4046 if (!this->emitConst(static_cast<APSInt>(ArrayType->getSize()), PT_Uint64, E))
4047 return false;
4048 if (!this->emitArrayElemPtrPop(PT_Uint64, E))
4049 return false;
4050 return this->emitInitFieldPtr(R->getField(I: 1u)->Offset, E);
4051}
4052
4053template <class Emitter>
4054bool Compiler<Emitter>::VisitStmtExpr(const StmtExpr *E) {
4055 BlockScope<Emitter> BS(this);
4056 StmtExprScope<Emitter> SS(this);
4057
4058 const CompoundStmt *CS = E->getSubStmt();
4059 const Stmt *Result = CS->getStmtExprResult();
4060 for (const Stmt *S : CS->body()) {
4061 if (S != Result) {
4062 if (!this->visitStmt(S))
4063 return false;
4064 continue;
4065 }
4066
4067 assert(S == Result);
4068 if (const Expr *ResultExpr = dyn_cast<Expr>(Val: S))
4069 return this->delegate(ResultExpr);
4070 return this->emitUnsupported(E);
4071 }
4072
4073 return BS.destroyLocals();
4074}
4075
4076template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {
4077 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
4078 /*NewInitializing=*/false);
4079 return this->Visit(E);
4080}
4081
4082template <class Emitter> bool Compiler<Emitter>::delegate(const Expr *E) {
4083 // We're basically doing:
4084 // OptionScope<Emitter> Scope(this, DicardResult, Initializing);
4085 // but that's unnecessary of course.
4086 return this->Visit(E);
4087}
4088
4089template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) {
4090 if (E->getType().isNull())
4091 return false;
4092
4093 if (E->getType()->isVoidType())
4094 return this->discard(E);
4095
4096 // Create local variable to hold the return value.
4097 if (!E->isGLValue() && !E->getType()->isAnyComplexType() &&
4098 !classify(E->getType())) {
4099 std::optional<unsigned> LocalIndex = allocateLocal(Decl: E);
4100 if (!LocalIndex)
4101 return false;
4102
4103 if (!this->emitGetPtrLocal(*LocalIndex, E))
4104 return false;
4105 InitLinkScope<Emitter> ILS(this, InitLink::Temp(Offset: *LocalIndex));
4106 return this->visitInitializer(E);
4107 }
4108
4109 // Otherwise,we have a primitive return value, produce the value directly
4110 // and push it on the stack.
4111 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
4112 /*NewInitializing=*/false);
4113 return this->Visit(E);
4114}
4115
4116template <class Emitter>
4117bool Compiler<Emitter>::visitInitializer(const Expr *E) {
4118 assert(!classify(E->getType()));
4119
4120 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
4121 /*NewInitializing=*/true);
4122 return this->Visit(E);
4123}
4124
4125template <class Emitter> bool Compiler<Emitter>::visitBool(const Expr *E) {
4126 std::optional<PrimType> T = classify(E->getType());
4127 if (!T) {
4128 // Convert complex values to bool.
4129 if (E->getType()->isAnyComplexType()) {
4130 if (!this->visit(E))
4131 return false;
4132 return this->emitComplexBoolCast(E);
4133 }
4134 return false;
4135 }
4136
4137 if (!this->visit(E))
4138 return false;
4139
4140 if (T == PT_Bool)
4141 return true;
4142
4143 // Convert pointers to bool.
4144 if (T == PT_Ptr)
4145 return this->emitIsNonNullPtr(E);
4146
4147 // Or Floats.
4148 if (T == PT_Float)
4149 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
4150
4151 // Or anything else we can.
4152 return this->emitCast(*T, PT_Bool, E);
4153}
4154
4155template <class Emitter>
4156bool Compiler<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
4157 const Expr *E) {
4158 if (const auto *AT = QT->getAs<AtomicType>())
4159 QT = AT->getValueType();
4160
4161 switch (T) {
4162 case PT_Bool:
4163 return this->emitZeroBool(E);
4164 case PT_Sint8:
4165 return this->emitZeroSint8(E);
4166 case PT_Uint8:
4167 return this->emitZeroUint8(E);
4168 case PT_Sint16:
4169 return this->emitZeroSint16(E);
4170 case PT_Uint16:
4171 return this->emitZeroUint16(E);
4172 case PT_Sint32:
4173 return this->emitZeroSint32(E);
4174 case PT_Uint32:
4175 return this->emitZeroUint32(E);
4176 case PT_Sint64:
4177 return this->emitZeroSint64(E);
4178 case PT_Uint64:
4179 return this->emitZeroUint64(E);
4180 case PT_IntAP:
4181 return this->emitZeroIntAP(Ctx.getBitWidth(T: QT), E);
4182 case PT_IntAPS:
4183 return this->emitZeroIntAPS(Ctx.getBitWidth(T: QT), E);
4184 case PT_Ptr:
4185 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
4186 nullptr, E);
4187 case PT_MemberPtr:
4188 return this->emitNullMemberPtr(0, nullptr, E);
4189 case PT_Float: {
4190 APFloat F = APFloat::getZero(Sem: Ctx.getFloatSemantics(T: QT));
4191 return this->emitFloat(F, E);
4192 }
4193 case PT_FixedPoint: {
4194 auto Sem = Ctx.getASTContext().getFixedPointSemantics(Ty: E->getType());
4195 return this->emitConstFixedPoint(FixedPoint::zero(Sem), E);
4196 }
4197 }
4198 llvm_unreachable("unknown primitive type");
4199}
4200
4201template <class Emitter>
4202bool Compiler<Emitter>::visitZeroRecordInitializer(const Record *R,
4203 const Expr *E) {
4204 assert(E);
4205 assert(R);
4206 // Fields
4207 for (const Record::Field &Field : R->fields()) {
4208 if (Field.isUnnamedBitField())
4209 continue;
4210
4211 const Descriptor *D = Field.Desc;
4212 if (D->isPrimitive()) {
4213 QualType QT = D->getType();
4214 PrimType T = classifyPrim(D->getType());
4215 if (!this->visitZeroInitializer(T, QT, E))
4216 return false;
4217 if (!this->emitInitField(T, Field.Offset, E))
4218 return false;
4219 if (R->isUnion())
4220 break;
4221 continue;
4222 }
4223
4224 if (!this->emitGetPtrField(Field.Offset, E))
4225 return false;
4226
4227 if (D->isPrimitiveArray()) {
4228 QualType ET = D->getElemQualType();
4229 PrimType T = classifyPrim(ET);
4230 for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
4231 if (!this->visitZeroInitializer(T, ET, E))
4232 return false;
4233 if (!this->emitInitElem(T, I, E))
4234 return false;
4235 }
4236 } else if (D->isCompositeArray()) {
4237 // Can't be a vector or complex field.
4238 if (!this->visitZeroArrayInitializer(D->getType(), E))
4239 return false;
4240 } else if (D->isRecord()) {
4241 if (!this->visitZeroRecordInitializer(D->ElemRecord, E))
4242 return false;
4243 } else
4244 return false;
4245
4246 if (!this->emitFinishInitPop(E))
4247 return false;
4248
4249 // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the
4250 // object's first non-static named data member is zero-initialized
4251 if (R->isUnion())
4252 break;
4253 }
4254
4255 for (const Record::Base &B : R->bases()) {
4256 if (!this->emitGetPtrBase(B.Offset, E))
4257 return false;
4258 if (!this->visitZeroRecordInitializer(B.R, E))
4259 return false;
4260 if (!this->emitFinishInitPop(E))
4261 return false;
4262 }
4263
4264 // FIXME: Virtual bases.
4265
4266 return true;
4267}
4268
4269template <class Emitter>
4270bool Compiler<Emitter>::visitZeroArrayInitializer(QualType T, const Expr *E) {
4271 assert(T->isArrayType() || T->isAnyComplexType() || T->isVectorType());
4272 const ArrayType *AT = T->getAsArrayTypeUnsafe();
4273 QualType ElemType = AT->getElementType();
4274 size_t NumElems = cast<ConstantArrayType>(Val: AT)->getZExtSize();
4275
4276 if (std::optional<PrimType> ElemT = classify(ElemType)) {
4277 for (size_t I = 0; I != NumElems; ++I) {
4278 if (!this->visitZeroInitializer(*ElemT, ElemType, E))
4279 return false;
4280 if (!this->emitInitElem(*ElemT, I, E))
4281 return false;
4282 }
4283 return true;
4284 } else if (ElemType->isRecordType()) {
4285 const Record *R = getRecord(ElemType);
4286
4287 for (size_t I = 0; I != NumElems; ++I) {
4288 if (!this->emitConstUint32(I, E))
4289 return false;
4290 if (!this->emitArrayElemPtr(PT_Uint32, E))
4291 return false;
4292 if (!this->visitZeroRecordInitializer(R, E))
4293 return false;
4294 if (!this->emitPopPtr(E))
4295 return false;
4296 }
4297 return true;
4298 } else if (ElemType->isArrayType()) {
4299 for (size_t I = 0; I != NumElems; ++I) {
4300 if (!this->emitConstUint32(I, E))
4301 return false;
4302 if (!this->emitArrayElemPtr(PT_Uint32, E))
4303 return false;
4304 if (!this->visitZeroArrayInitializer(ElemType, E))
4305 return false;
4306 if (!this->emitPopPtr(E))
4307 return false;
4308 }
4309 return true;
4310 }
4311
4312 return false;
4313}
4314
4315template <class Emitter>
4316template <typename T>
4317bool Compiler<Emitter>::emitConst(T Value, PrimType Ty, const Expr *E) {
4318 switch (Ty) {
4319 case PT_Sint8:
4320 return this->emitConstSint8(Value, E);
4321 case PT_Uint8:
4322 return this->emitConstUint8(Value, E);
4323 case PT_Sint16:
4324 return this->emitConstSint16(Value, E);
4325 case PT_Uint16:
4326 return this->emitConstUint16(Value, E);
4327 case PT_Sint32:
4328 return this->emitConstSint32(Value, E);
4329 case PT_Uint32:
4330 return this->emitConstUint32(Value, E);
4331 case PT_Sint64:
4332 return this->emitConstSint64(Value, E);
4333 case PT_Uint64:
4334 return this->emitConstUint64(Value, E);
4335 case PT_Bool:
4336 return this->emitConstBool(Value, E);
4337 case PT_Ptr:
4338 case PT_MemberPtr:
4339 case PT_Float:
4340 case PT_IntAP:
4341 case PT_IntAPS:
4342 case PT_FixedPoint:
4343 llvm_unreachable("Invalid integral type");
4344 break;
4345 }
4346 llvm_unreachable("unknown primitive type");
4347}
4348
4349template <class Emitter>
4350template <typename T>
4351bool Compiler<Emitter>::emitConst(T Value, const Expr *E) {
4352 return this->emitConst(Value, classifyPrim(E->getType()), E);
4353}
4354
4355template <class Emitter>
4356bool Compiler<Emitter>::emitConst(const APSInt &Value, PrimType Ty,
4357 const Expr *E) {
4358 if (Ty == PT_IntAPS)
4359 return this->emitConstIntAPS(Value, E);
4360 if (Ty == PT_IntAP)
4361 return this->emitConstIntAP(Value, E);
4362
4363 if (Value.isSigned())
4364 return this->emitConst(Value.getSExtValue(), Ty, E);
4365 return this->emitConst(Value.getZExtValue(), Ty, E);
4366}
4367
4368template <class Emitter>
4369bool Compiler<Emitter>::emitConst(const APSInt &Value, const Expr *E) {
4370 return this->emitConst(Value, classifyPrim(E->getType()), E);
4371}
4372
4373template <class Emitter>
4374unsigned Compiler<Emitter>::allocateLocalPrimitive(
4375 DeclTy &&Src, PrimType Ty, bool IsConst, const ValueDecl *ExtendingDecl,
4376 ScopeKind SC, bool IsConstexprUnknown) {
4377 // Make sure we don't accidentally register the same decl twice.
4378 if (const auto *VD =
4379 dyn_cast_if_present<ValueDecl>(Val: Src.dyn_cast<const Decl *>())) {
4380 assert(!P.getGlobal(VD));
4381 assert(!Locals.contains(VD));
4382 (void)VD;
4383 }
4384
4385 // FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
4386 // (int){12} in C. Consider using Expr::isTemporaryObject() instead
4387 // or isa<MaterializeTemporaryExpr>().
4388 Descriptor *D = P.createDescriptor(D: Src, T: Ty, SourceTy: nullptr, MDSize: Descriptor::InlineDescMD,
4389 IsConst, IsTemporary: isa<const Expr *>(Val: Src));
4390 D->IsConstexprUnknown = IsConstexprUnknown;
4391 Scope::Local Local = this->createLocal(D);
4392 if (auto *VD = dyn_cast_if_present<ValueDecl>(Val: Src.dyn_cast<const Decl *>()))
4393 Locals.insert(KV: {VD, Local});
4394 if (ExtendingDecl)
4395 VarScope->addExtended(Local, ExtendingDecl);
4396 else
4397 VarScope->addForScopeKind(Local, SC);
4398 return Local.Offset;
4399}
4400
4401template <class Emitter>
4402std::optional<unsigned>
4403Compiler<Emitter>::allocateLocal(DeclTy &&Src, QualType Ty,
4404 const ValueDecl *ExtendingDecl, ScopeKind SC,
4405 bool IsConstexprUnknown) {
4406 // Make sure we don't accidentally register the same decl twice.
4407 if ([[maybe_unused]] const auto *VD =
4408 dyn_cast_if_present<ValueDecl>(Val: Src.dyn_cast<const Decl *>())) {
4409 assert(!P.getGlobal(VD));
4410 assert(!Locals.contains(VD));
4411 }
4412
4413 const ValueDecl *Key = nullptr;
4414 const Expr *Init = nullptr;
4415 bool IsTemporary = false;
4416 if (auto *VD = dyn_cast_if_present<ValueDecl>(Val: Src.dyn_cast<const Decl *>())) {
4417 Key = VD;
4418 Ty = VD->getType();
4419
4420 if (const auto *VarD = dyn_cast<VarDecl>(Val: VD))
4421 Init = VarD->getInit();
4422 }
4423 if (auto *E = Src.dyn_cast<const Expr *>()) {
4424 IsTemporary = true;
4425 if (Ty.isNull())
4426 Ty = E->getType();
4427 }
4428
4429 Descriptor *D = P.createDescriptor(
4430 D: Src, Ty: Ty.getTypePtr(), MDSize: Descriptor::InlineDescMD, IsConst: Ty.isConstQualified(),
4431 IsTemporary, /*IsMutable=*/false, /*IsVolatile=*/false, Init);
4432 if (!D)
4433 return std::nullopt;
4434 D->IsConstexprUnknown = IsConstexprUnknown;
4435
4436 Scope::Local Local = this->createLocal(D);
4437 if (Key)
4438 Locals.insert(KV: {Key, Local});
4439 if (ExtendingDecl)
4440 VarScope->addExtended(Local, ExtendingDecl);
4441 else
4442 VarScope->addForScopeKind(Local, SC);
4443 return Local.Offset;
4444}
4445
4446template <class Emitter>
4447std::optional<unsigned> Compiler<Emitter>::allocateTemporary(const Expr *E) {
4448 QualType Ty = E->getType();
4449 assert(!Ty->isRecordType());
4450
4451 Descriptor *D = P.createDescriptor(
4452 D: E, Ty: Ty.getTypePtr(), MDSize: Descriptor::InlineDescMD, IsConst: Ty.isConstQualified(),
4453 /*IsTemporary=*/true);
4454
4455 if (!D)
4456 return std::nullopt;
4457
4458 Scope::Local Local = this->createLocal(D);
4459 VariableScope<Emitter> *S = VarScope;
4460 assert(S);
4461 // Attach to topmost scope.
4462 while (S->getParent())
4463 S = S->getParent();
4464 assert(S && !S->getParent());
4465 S->addLocal(Local);
4466 return Local.Offset;
4467}
4468
4469template <class Emitter>
4470const RecordType *Compiler<Emitter>::getRecordTy(QualType Ty) {
4471 if (const PointerType *PT = dyn_cast<PointerType>(Val&: Ty))
4472 return PT->getPointeeType()->getAs<RecordType>();
4473 return Ty->getAs<RecordType>();
4474}
4475
4476template <class Emitter> Record *Compiler<Emitter>::getRecord(QualType Ty) {
4477 if (const auto *RecordTy = getRecordTy(Ty))
4478 return getRecord(RecordTy->getDecl());
4479 return nullptr;
4480}
4481
4482template <class Emitter>
4483Record *Compiler<Emitter>::getRecord(const RecordDecl *RD) {
4484 return P.getOrCreateRecord(RD);
4485}
4486
4487template <class Emitter>
4488const Function *Compiler<Emitter>::getFunction(const FunctionDecl *FD) {
4489 return Ctx.getOrCreateFunction(FuncDecl: FD);
4490}
4491
4492template <class Emitter>
4493bool Compiler<Emitter>::visitExpr(const Expr *E, bool DestroyToplevelScope) {
4494 LocalScope<Emitter> RootScope(this);
4495
4496 // If we won't destroy the toplevel scope, check for memory leaks first.
4497 if (!DestroyToplevelScope) {
4498 if (!this->emitCheckAllocations(E))
4499 return false;
4500 }
4501
4502 auto maybeDestroyLocals = [&]() -> bool {
4503 if (DestroyToplevelScope)
4504 return RootScope.destroyLocals() && this->emitCheckAllocations(E);
4505 return this->emitCheckAllocations(E);
4506 };
4507
4508 // Void expressions.
4509 if (E->getType()->isVoidType()) {
4510 if (!visit(E))
4511 return false;
4512 return this->emitRetVoid(E) && maybeDestroyLocals();
4513 }
4514
4515 // Expressions with a primitive return type.
4516 if (std::optional<PrimType> T = classify(E)) {
4517 if (!visit(E))
4518 return false;
4519
4520 return this->emitRet(*T, E) && maybeDestroyLocals();
4521 }
4522
4523 // Expressions with a composite return type.
4524 // For us, that means everything we don't
4525 // have a PrimType for.
4526 if (std::optional<unsigned> LocalOffset = this->allocateLocal(E)) {
4527 InitLinkScope<Emitter> ILS(this, InitLink::Temp(Offset: *LocalOffset));
4528 if (!this->emitGetPtrLocal(*LocalOffset, E))
4529 return false;
4530
4531 if (!visitInitializer(E))
4532 return false;
4533
4534 if (!this->emitFinishInit(E))
4535 return false;
4536 // We are destroying the locals AFTER the Ret op.
4537 // The Ret op needs to copy the (alive) values, but the
4538 // destructors may still turn the entire expression invalid.
4539 return this->emitRetValue(E) && maybeDestroyLocals();
4540 }
4541
4542 return maybeDestroyLocals() && this->emitCheckAllocations(E) && false;
4543}
4544
4545template <class Emitter>
4546VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD,
4547 bool IsConstexprUnknown) {
4548
4549 auto R = this->visitVarDecl(VD, /*Toplevel=*/true, IsConstexprUnknown);
4550
4551 if (R.notCreated())
4552 return R;
4553
4554 if (R)
4555 return true;
4556
4557 if (!R && Context::shouldBeGloballyIndexed(VD)) {
4558 if (auto GlobalIndex = P.getGlobal(VD)) {
4559 Block *GlobalBlock = P.getGlobal(Idx: *GlobalIndex);
4560 GlobalInlineDescriptor &GD =
4561 *reinterpret_cast<GlobalInlineDescriptor *>(GlobalBlock->rawData());
4562
4563 GD.InitState = GlobalInitState::InitializerFailed;
4564 GlobalBlock->invokeDtor();
4565 }
4566 }
4567
4568 return R;
4569}
4570
4571/// Toplevel visitDeclAndReturn().
4572/// We get here from evaluateAsInitializer().
4573/// We need to evaluate the initializer and return its value.
4574template <class Emitter>
4575bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
4576 bool ConstantContext) {
4577
4578 // We only create variables if we're evaluating in a constant context.
4579 // Otherwise, just evaluate the initializer and return it.
4580 if (!ConstantContext) {
4581 DeclScope<Emitter> LS(this, VD);
4582 const Expr *Init = VD->getInit();
4583 if (!this->visit(Init))
4584 return false;
4585 return this->emitRet(classify(Init).value_or(PT_Ptr), VD) &&
4586 LS.destroyLocals() && this->emitCheckAllocations(VD);
4587 }
4588
4589 LocalScope<Emitter> VDScope(this, VD);
4590 if (!this->visitVarDecl(VD, /*Toplevel=*/true))
4591 return false;
4592
4593 std::optional<PrimType> VarT = classify(VD->getType());
4594 if (Context::shouldBeGloballyIndexed(VD)) {
4595 auto GlobalIndex = P.getGlobal(VD);
4596 assert(GlobalIndex); // visitVarDecl() didn't return false.
4597 if (VarT) {
4598 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
4599 return false;
4600 } else {
4601 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
4602 return false;
4603 }
4604 } else {
4605 auto Local = Locals.find(Val: VD);
4606 assert(Local != Locals.end()); // Same here.
4607 if (VarT) {
4608 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
4609 return false;
4610 } else {
4611 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
4612 return false;
4613 }
4614 }
4615
4616 // Return the value.
4617 if (!this->emitRet(VarT.value_or(u: PT_Ptr), VD)) {
4618 // If the Ret above failed and this is a global variable, mark it as
4619 // uninitialized, even everything else succeeded.
4620 if (Context::shouldBeGloballyIndexed(VD)) {
4621 auto GlobalIndex = P.getGlobal(VD);
4622 assert(GlobalIndex);
4623 Block *GlobalBlock = P.getGlobal(Idx: *GlobalIndex);
4624 GlobalInlineDescriptor &GD =
4625 *reinterpret_cast<GlobalInlineDescriptor *>(GlobalBlock->rawData());
4626
4627 GD.InitState = GlobalInitState::InitializerFailed;
4628 GlobalBlock->invokeDtor();
4629 }
4630 return false;
4631 }
4632
4633 return VDScope.destroyLocals() && this->emitCheckAllocations(VD);
4634}
4635
4636template <class Emitter>
4637VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD,
4638 bool Toplevel,
4639 bool IsConstexprUnknown) {
4640 // We don't know what to do with these, so just return false.
4641 if (VD->getType().isNull())
4642 return false;
4643
4644 // This case is EvalEmitter-only. If we won't create any instructions for the
4645 // initializer anyway, don't bother creating the variable in the first place.
4646 if (!this->isActive())
4647 return VarCreationState::NotCreated();
4648
4649 const Expr *Init = VD->getInit();
4650 std::optional<PrimType> VarT = classify(VD->getType());
4651
4652 if (Init && Init->isValueDependent())
4653 return false;
4654
4655 if (Context::shouldBeGloballyIndexed(VD)) {
4656 auto checkDecl = [&]() -> bool {
4657 bool NeedsOp = !Toplevel && VD->isLocalVarDecl() && VD->isStaticLocal();
4658 return !NeedsOp || this->emitCheckDecl(VD, VD);
4659 };
4660
4661 auto initGlobal = [&](unsigned GlobalIndex) -> bool {
4662 assert(Init);
4663
4664 if (VarT) {
4665 if (!this->visit(Init))
4666 return checkDecl() && false;
4667
4668 return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
4669 }
4670
4671 if (!checkDecl())
4672 return false;
4673
4674 if (!this->emitGetPtrGlobal(GlobalIndex, Init))
4675 return false;
4676
4677 if (!visitInitializer(E: Init))
4678 return false;
4679
4680 return this->emitFinishInitGlobal(Init);
4681 };
4682
4683 DeclScope<Emitter> LocalScope(this, VD);
4684
4685 // We've already seen and initialized this global.
4686 if (std::optional<unsigned> GlobalIndex = P.getGlobal(VD)) {
4687 if (P.getPtrGlobal(Idx: *GlobalIndex).isInitialized())
4688 return checkDecl();
4689
4690 // The previous attempt at initialization might've been unsuccessful,
4691 // so let's try this one.
4692 return Init && checkDecl() && initGlobal(*GlobalIndex);
4693 }
4694
4695 std::optional<unsigned> GlobalIndex = P.createGlobal(VD, Init);
4696
4697 if (!GlobalIndex)
4698 return false;
4699
4700 return !Init || (checkDecl() && initGlobal(*GlobalIndex));
4701 }
4702 // Local variables.
4703 InitLinkScope<Emitter> ILS(this, InitLink::Decl(D: VD));
4704
4705 if (VarT) {
4706 unsigned Offset = this->allocateLocalPrimitive(
4707 VD, *VarT, VD->getType().isConstQualified(), nullptr, ScopeKind::Block,
4708 IsConstexprUnknown);
4709 if (Init) {
4710 // If this is a toplevel declaration, create a scope for the
4711 // initializer.
4712 if (Toplevel) {
4713 LocalScope<Emitter> Scope(this);
4714 if (!this->visit(Init))
4715 return false;
4716 return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals();
4717 } else {
4718 if (!this->visit(Init))
4719 return false;
4720 return this->emitSetLocal(*VarT, Offset, VD);
4721 }
4722 }
4723 } else {
4724 if (std::optional<unsigned> Offset = this->allocateLocal(
4725 VD, VD->getType(), nullptr, ScopeKind::Block, IsConstexprUnknown)) {
4726 if (!Init)
4727 return true;
4728
4729 if (!this->emitGetPtrLocal(*Offset, Init))
4730 return false;
4731
4732 if (!visitInitializer(E: Init))
4733 return false;
4734
4735 return this->emitFinishInitPop(Init);
4736 }
4737 return false;
4738 }
4739 return true;
4740}
4741
4742template <class Emitter>
4743bool Compiler<Emitter>::visitAPValue(const APValue &Val, PrimType ValType,
4744 const Expr *E) {
4745 assert(!DiscardResult);
4746 if (Val.isInt())
4747 return this->emitConst(Val.getInt(), ValType, E);
4748 else if (Val.isFloat()) {
4749 APFloat F = Val.getFloat();
4750 return this->emitFloat(F, E);
4751 }
4752
4753 if (Val.isLValue()) {
4754 if (Val.isNullPointer())
4755 return this->emitNull(ValType, 0, nullptr, E);
4756 APValue::LValueBase Base = Val.getLValueBase();
4757 if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>())
4758 return this->visit(BaseExpr);
4759 else if (const auto *VD = Base.dyn_cast<const ValueDecl *>()) {
4760 return this->visitDeclRef(VD, E);
4761 }
4762 } else if (Val.isMemberPointer()) {
4763 if (const ValueDecl *MemberDecl = Val.getMemberPointerDecl())
4764 return this->emitGetMemberPtr(MemberDecl, E);
4765 return this->emitNullMemberPtr(0, nullptr, E);
4766 }
4767
4768 return false;
4769}
4770
4771template <class Emitter>
4772bool Compiler<Emitter>::visitAPValueInitializer(const APValue &Val,
4773 const Expr *E, QualType T) {
4774 if (Val.isStruct()) {
4775 const Record *R = this->getRecord(T);
4776 assert(R);
4777 for (unsigned I = 0, N = Val.getStructNumFields(); I != N; ++I) {
4778 const APValue &F = Val.getStructField(i: I);
4779 const Record::Field *RF = R->getField(I);
4780 QualType FieldType = RF->Decl->getType();
4781
4782 if (std::optional<PrimType> PT = classify(FieldType)) {
4783 if (!this->visitAPValue(F, *PT, E))
4784 return false;
4785 if (!this->emitInitField(*PT, RF->Offset, E))
4786 return false;
4787 } else {
4788 if (!this->emitGetPtrField(RF->Offset, E))
4789 return false;
4790 if (!this->visitAPValueInitializer(F, E, FieldType))
4791 return false;
4792 if (!this->emitPopPtr(E))
4793 return false;
4794 }
4795 }
4796 return true;
4797 } else if (Val.isUnion()) {
4798 const FieldDecl *UnionField = Val.getUnionField();
4799 const Record *R = this->getRecord(UnionField->getParent());
4800 assert(R);
4801 const APValue &F = Val.getUnionValue();
4802 const Record::Field *RF = R->getField(FD: UnionField);
4803 PrimType T = classifyPrim(RF->Decl->getType());
4804 if (!this->visitAPValue(F, T, E))
4805 return false;
4806 return this->emitInitField(T, RF->Offset, E);
4807 } else if (Val.isArray()) {
4808 const auto *ArrType = T->getAsArrayTypeUnsafe();
4809 QualType ElemType = ArrType->getElementType();
4810 for (unsigned A = 0, AN = Val.getArraySize(); A != AN; ++A) {
4811 const APValue &Elem = Val.getArrayInitializedElt(I: A);
4812 if (std::optional<PrimType> ElemT = classify(ElemType)) {
4813 if (!this->visitAPValue(Elem, *ElemT, E))
4814 return false;
4815 if (!this->emitInitElem(*ElemT, A, E))
4816 return false;
4817 } else {
4818 if (!this->emitConstUint32(A, E))
4819 return false;
4820 if (!this->emitArrayElemPtrUint32(E))
4821 return false;
4822 if (!this->visitAPValueInitializer(Elem, E, ElemType))
4823 return false;
4824 if (!this->emitPopPtr(E))
4825 return false;
4826 }
4827 }
4828 return true;
4829 }
4830 // TODO: Other types.
4831
4832 return false;
4833}
4834
4835template <class Emitter>
4836bool Compiler<Emitter>::VisitBuiltinCallExpr(const CallExpr *E,
4837 unsigned BuiltinID) {
4838
4839 if (BuiltinID == Builtin::BI__builtin_constant_p) {
4840 // Void argument is always invalid and harder to handle later.
4841 if (E->getArg(Arg: 0)->getType()->isVoidType()) {
4842 if (DiscardResult)
4843 return true;
4844 return this->emitConst(0, E);
4845 }
4846
4847 if (!this->emitStartSpeculation(E))
4848 return false;
4849 LabelTy EndLabel = this->getLabel();
4850 if (!this->speculate(E, EndLabel))
4851 return false;
4852 this->fallthrough(EndLabel);
4853 if (!this->emitEndSpeculation(E))
4854 return false;
4855 if (DiscardResult)
4856 return this->emitPop(classifyPrim(E), E);
4857 return true;
4858 }
4859
4860 // For these, we're expected to ultimately return an APValue pointing
4861 // to the CallExpr. This is needed to get the correct codegen.
4862 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
4863 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
4864 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
4865 BuiltinID == Builtin::BI__builtin_function_start) {
4866 if (DiscardResult)
4867 return true;
4868 return this->emitDummyPtr(E, E);
4869 }
4870
4871 QualType ReturnType = E->getType();
4872 std::optional<PrimType> ReturnT = classify(E);
4873
4874 // Non-primitive return type. Prepare storage.
4875 if (!Initializing && !ReturnT && !ReturnType->isVoidType()) {
4876 std::optional<unsigned> LocalIndex = allocateLocal(Src: E);
4877 if (!LocalIndex)
4878 return false;
4879 if (!this->emitGetPtrLocal(*LocalIndex, E))
4880 return false;
4881 }
4882
4883 if (!Context::isUnevaluatedBuiltin(ID: BuiltinID)) {
4884 // Put arguments on the stack.
4885 for (const auto *Arg : E->arguments()) {
4886 if (!this->visit(Arg))
4887 return false;
4888 }
4889 }
4890
4891 if (!this->emitCallBI(E, BuiltinID, E))
4892 return false;
4893
4894 if (DiscardResult && !ReturnType->isVoidType()) {
4895 assert(ReturnT);
4896 return this->emitPop(*ReturnT, E);
4897 }
4898
4899 return true;
4900}
4901
4902template <class Emitter>
4903bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
4904 const FunctionDecl *FuncDecl = E->getDirectCallee();
4905
4906 if (FuncDecl) {
4907 if (unsigned BuiltinID = FuncDecl->getBuiltinID())
4908 return VisitBuiltinCallExpr(E, BuiltinID);
4909
4910 // Calls to replaceable operator new/operator delete.
4911 if (FuncDecl->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
4912 if (FuncDecl->getDeclName().isAnyOperatorNew()) {
4913 return VisitBuiltinCallExpr(E, BuiltinID: Builtin::BI__builtin_operator_new);
4914 } else {
4915 assert(FuncDecl->getDeclName().getCXXOverloadedOperator() == OO_Delete);
4916 return VisitBuiltinCallExpr(E, BuiltinID: Builtin::BI__builtin_operator_delete);
4917 }
4918 }
4919
4920 // Explicit calls to trivial destructors
4921 if (const auto *DD = dyn_cast<CXXDestructorDecl>(Val: FuncDecl);
4922 DD && DD->isTrivial()) {
4923 const auto *MemberCall = cast<CXXMemberCallExpr>(Val: E);
4924 if (!this->visit(MemberCall->getImplicitObjectArgument()))
4925 return false;
4926 return this->emitCheckDestruction(E) && this->emitEndLifetime(E) &&
4927 this->emitPopPtr(E);
4928 }
4929 }
4930
4931 BlockScope<Emitter> CallScope(this, ScopeKind::Call);
4932
4933 QualType ReturnType = E->getCallReturnType(Ctx: Ctx.getASTContext());
4934 std::optional<PrimType> T = classify(ReturnType);
4935 bool HasRVO = !ReturnType->isVoidType() && !T;
4936
4937 if (HasRVO) {
4938 if (DiscardResult) {
4939 // If we need to discard the return value but the function returns its
4940 // value via an RVO pointer, we need to create one such pointer just
4941 // for this call.
4942 if (std::optional<unsigned> LocalIndex = allocateLocal(Src: E)) {
4943 if (!this->emitGetPtrLocal(*LocalIndex, E))
4944 return false;
4945 }
4946 } else {
4947 // We need the result. Prepare a pointer to return or
4948 // dup the current one.
4949 if (!Initializing) {
4950 if (std::optional<unsigned> LocalIndex = allocateLocal(Src: E)) {
4951 if (!this->emitGetPtrLocal(*LocalIndex, E))
4952 return false;
4953 }
4954 }
4955 if (!this->emitDupPtr(E))
4956 return false;
4957 }
4958 }
4959
4960 SmallVector<const Expr *, 8> Args(ArrayRef(E->getArgs(), E->getNumArgs()));
4961
4962 bool IsAssignmentOperatorCall = false;
4963 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(Val: E);
4964 OCE && OCE->isAssignmentOp()) {
4965 // Just like with regular assignments, we need to special-case assignment
4966 // operators here and evaluate the RHS (the second arg) before the LHS (the
4967 // first arg). We fix this by using a Flip op later.
4968 assert(Args.size() == 2);
4969 IsAssignmentOperatorCall = true;
4970 std::reverse(first: Args.begin(), last: Args.end());
4971 }
4972 // Calling a static operator will still
4973 // pass the instance, but we don't need it.
4974 // Discard it here.
4975 if (isa<CXXOperatorCallExpr>(Val: E)) {
4976 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(Val: FuncDecl);
4977 MD && MD->isStatic()) {
4978 if (!this->discard(E->getArg(Arg: 0)))
4979 return false;
4980 // Drop first arg.
4981 Args.erase(CI: Args.begin());
4982 }
4983 }
4984
4985 std::optional<unsigned> CalleeOffset;
4986 // Add the (optional, implicit) This pointer.
4987 if (const auto *MC = dyn_cast<CXXMemberCallExpr>(Val: E)) {
4988 if (!FuncDecl && classifyPrim(E->getCallee()) == PT_MemberPtr) {
4989 // If we end up creating a CallPtr op for this, we need the base of the
4990 // member pointer as the instance pointer, and later extract the function
4991 // decl as the function pointer.
4992 const Expr *Callee = E->getCallee();
4993 CalleeOffset =
4994 this->allocateLocalPrimitive(Callee, PT_MemberPtr, /*IsConst=*/true);
4995 if (!this->visit(Callee))
4996 return false;
4997 if (!this->emitSetLocal(PT_MemberPtr, *CalleeOffset, E))
4998 return false;
4999 if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
5000 return false;
5001 if (!this->emitGetMemberPtrBase(E))
5002 return false;
5003 } else if (!this->visit(MC->getImplicitObjectArgument())) {
5004 return false;
5005 }
5006 } else if (const auto *PD =
5007 dyn_cast<CXXPseudoDestructorExpr>(Val: E->getCallee())) {
5008 if (!this->emitCheckPseudoDtor(E))
5009 return false;
5010 const Expr *Base = PD->getBase();
5011 if (!Base->isGLValue())
5012 return this->discard(Base);
5013 if (!this->visit(Base))
5014 return false;
5015 return this->emitEndLifetimePop(E);
5016 } else if (!FuncDecl) {
5017 const Expr *Callee = E->getCallee();
5018 CalleeOffset =
5019 this->allocateLocalPrimitive(Callee, PT_Ptr, /*IsConst=*/true);
5020 if (!this->visit(Callee))
5021 return false;
5022 if (!this->emitSetLocal(PT_Ptr, *CalleeOffset, E))
5023 return false;
5024 }
5025
5026 if (!this->visitCallArgs(Args, FuncDecl))
5027 return false;
5028
5029 // Undo the argument reversal we did earlier.
5030 if (IsAssignmentOperatorCall) {
5031 assert(Args.size() == 2);
5032 PrimType Arg1T = classify(Args[0]).value_or(PT_Ptr);
5033 PrimType Arg2T = classify(Args[1]).value_or(PT_Ptr);
5034 if (!this->emitFlip(Arg2T, Arg1T, E))
5035 return false;
5036 }
5037
5038 if (FuncDecl) {
5039 const Function *Func = getFunction(FD: FuncDecl);
5040 if (!Func)
5041 return false;
5042 assert(HasRVO == Func->hasRVO());
5043
5044 bool HasQualifier = false;
5045 if (const auto *ME = dyn_cast<MemberExpr>(Val: E->getCallee()))
5046 HasQualifier = ME->hasQualifier();
5047
5048 bool IsVirtual = false;
5049 if (const auto *MD = dyn_cast<CXXMethodDecl>(Val: FuncDecl))
5050 IsVirtual = MD->isVirtual();
5051
5052 // In any case call the function. The return value will end up on the stack
5053 // and if the function has RVO, we already have the pointer on the stack to
5054 // write the result into.
5055 if (IsVirtual && !HasQualifier) {
5056 uint32_t VarArgSize = 0;
5057 unsigned NumParams =
5058 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(Val: E);
5059 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
5060 VarArgSize += align(primSize(classify(E->getArg(Arg: I)).value_or(PT_Ptr)));
5061
5062 if (!this->emitCallVirt(Func, VarArgSize, E))
5063 return false;
5064 } else if (Func->isVariadic()) {
5065 uint32_t VarArgSize = 0;
5066 unsigned NumParams =
5067 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(Val: E);
5068 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
5069 VarArgSize += align(primSize(classify(E->getArg(Arg: I)).value_or(PT_Ptr)));
5070 if (!this->emitCallVar(Func, VarArgSize, E))
5071 return false;
5072 } else {
5073 if (!this->emitCall(Func, 0, E))
5074 return false;
5075 }
5076 } else {
5077 // Indirect call. Visit the callee, which will leave a FunctionPointer on
5078 // the stack. Cleanup of the returned value if necessary will be done after
5079 // the function call completed.
5080
5081 // Sum the size of all args from the call expr.
5082 uint32_t ArgSize = 0;
5083 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
5084 ArgSize += align(primSize(classify(E->getArg(Arg: I)).value_or(PT_Ptr)));
5085
5086 // Get the callee, either from a member pointer or function pointer saved in
5087 // CalleeOffset.
5088 if (isa<CXXMemberCallExpr>(Val: E) && CalleeOffset) {
5089 if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
5090 return false;
5091 if (!this->emitGetMemberPtrDecl(E))
5092 return false;
5093 } else {
5094 if (!this->emitGetLocal(PT_Ptr, *CalleeOffset, E))
5095 return false;
5096 }
5097 if (!this->emitCallPtr(ArgSize, E, E))
5098 return false;
5099 }
5100
5101 // Cleanup for discarded return values.
5102 if (DiscardResult && !ReturnType->isVoidType() && T)
5103 return this->emitPop(*T, E) && CallScope.destroyLocals();
5104
5105 return CallScope.destroyLocals();
5106}
5107
5108template <class Emitter>
5109bool Compiler<Emitter>::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) {
5110 SourceLocScope<Emitter> SLS(this, E);
5111
5112 return this->delegate(E->getExpr());
5113}
5114
5115template <class Emitter>
5116bool Compiler<Emitter>::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) {
5117 SourceLocScope<Emitter> SLS(this, E);
5118
5119 return this->delegate(E->getExpr());
5120}
5121
5122template <class Emitter>
5123bool Compiler<Emitter>::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
5124 if (DiscardResult)
5125 return true;
5126
5127 return this->emitConstBool(E->getValue(), E);
5128}
5129
5130template <class Emitter>
5131bool Compiler<Emitter>::VisitCXXNullPtrLiteralExpr(
5132 const CXXNullPtrLiteralExpr *E) {
5133 if (DiscardResult)
5134 return true;
5135
5136 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(QT: E->getType());
5137 return this->emitNullPtr(Val, nullptr, E);
5138}
5139
5140template <class Emitter>
5141bool Compiler<Emitter>::VisitGNUNullExpr(const GNUNullExpr *E) {
5142 if (DiscardResult)
5143 return true;
5144
5145 assert(E->getType()->isIntegerType());
5146
5147 PrimType T = classifyPrim(E->getType());
5148 return this->emitZero(T, E);
5149}
5150
5151template <class Emitter>
5152bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
5153 if (DiscardResult)
5154 return true;
5155
5156 if (this->LambdaThisCapture.Offset > 0) {
5157 if (this->LambdaThisCapture.IsPtr)
5158 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
5159 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
5160 }
5161
5162 // In some circumstances, the 'this' pointer does not actually refer to the
5163 // instance pointer of the current function frame, but e.g. to the declaration
5164 // currently being initialized. Here we emit the necessary instruction(s) for
5165 // this scenario.
5166 if (!InitStackActive)
5167 return this->emitThis(E);
5168
5169 if (!InitStack.empty()) {
5170 // If our init stack is, for example:
5171 // 0 Stack: 3 (decl)
5172 // 1 Stack: 6 (init list)
5173 // 2 Stack: 1 (field)
5174 // 3 Stack: 6 (init list)
5175 // 4 Stack: 1 (field)
5176 //
5177 // We want to find the LAST element in it that's an init list,
5178 // which is marked with the K_InitList marker. The index right
5179 // before that points to an init list. We need to find the
5180 // elements before the K_InitList element that point to a base
5181 // (e.g. a decl or This), optionally followed by field, elem, etc.
5182 // In the example above, we want to emit elements [0..2].
5183 unsigned StartIndex = 0;
5184 unsigned EndIndex = 0;
5185 // Find the init list.
5186 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
5187 if (InitStack[StartIndex].Kind == InitLink::K_InitList ||
5188 InitStack[StartIndex].Kind == InitLink::K_This) {
5189 EndIndex = StartIndex;
5190 --StartIndex;
5191 break;
5192 }
5193 }
5194
5195 // Walk backwards to find the base.
5196 for (; StartIndex > 0; --StartIndex) {
5197 if (InitStack[StartIndex].Kind == InitLink::K_InitList)
5198 continue;
5199
5200 if (InitStack[StartIndex].Kind != InitLink::K_Field &&
5201 InitStack[StartIndex].Kind != InitLink::K_Elem)
5202 break;
5203 }
5204
5205 // Emit the instructions.
5206 for (unsigned I = StartIndex; I != EndIndex; ++I) {
5207 if (InitStack[I].Kind == InitLink::K_InitList)
5208 continue;
5209 if (!InitStack[I].template emit<Emitter>(this, E))
5210 return false;
5211 }
5212 return true;
5213 }
5214 return this->emitThis(E);
5215}
5216
5217template <class Emitter> bool Compiler<Emitter>::visitStmt(const Stmt *S) {
5218 switch (S->getStmtClass()) {
5219 case Stmt::CompoundStmtClass:
5220 return visitCompoundStmt(S: cast<CompoundStmt>(Val: S));
5221 case Stmt::DeclStmtClass:
5222 return visitDeclStmt(DS: cast<DeclStmt>(Val: S), /*EvaluateConditionDecl=*/true);
5223 case Stmt::ReturnStmtClass:
5224 return visitReturnStmt(RS: cast<ReturnStmt>(Val: S));
5225 case Stmt::IfStmtClass:
5226 return visitIfStmt(IS: cast<IfStmt>(Val: S));
5227 case Stmt::WhileStmtClass:
5228 return visitWhileStmt(S: cast<WhileStmt>(Val: S));
5229 case Stmt::DoStmtClass:
5230 return visitDoStmt(S: cast<DoStmt>(Val: S));
5231 case Stmt::ForStmtClass:
5232 return visitForStmt(S: cast<ForStmt>(Val: S));
5233 case Stmt::CXXForRangeStmtClass:
5234 return visitCXXForRangeStmt(S: cast<CXXForRangeStmt>(Val: S));
5235 case Stmt::BreakStmtClass:
5236 return visitBreakStmt(S: cast<BreakStmt>(Val: S));
5237 case Stmt::ContinueStmtClass:
5238 return visitContinueStmt(S: cast<ContinueStmt>(Val: S));
5239 case Stmt::SwitchStmtClass:
5240 return visitSwitchStmt(S: cast<SwitchStmt>(Val: S));
5241 case Stmt::CaseStmtClass:
5242 return visitCaseStmt(S: cast<CaseStmt>(Val: S));
5243 case Stmt::DefaultStmtClass:
5244 return visitDefaultStmt(S: cast<DefaultStmt>(Val: S));
5245 case Stmt::AttributedStmtClass:
5246 return visitAttributedStmt(S: cast<AttributedStmt>(Val: S));
5247 case Stmt::CXXTryStmtClass:
5248 return visitCXXTryStmt(S: cast<CXXTryStmt>(Val: S));
5249 case Stmt::NullStmtClass:
5250 return true;
5251 // Always invalid statements.
5252 case Stmt::GCCAsmStmtClass:
5253 case Stmt::MSAsmStmtClass:
5254 case Stmt::GotoStmtClass:
5255 return this->emitInvalid(S);
5256 case Stmt::LabelStmtClass:
5257 return this->visitStmt(cast<LabelStmt>(Val: S)->getSubStmt());
5258 default: {
5259 if (const auto *E = dyn_cast<Expr>(Val: S))
5260 return this->discard(E);
5261 return false;
5262 }
5263 }
5264}
5265
5266template <class Emitter>
5267bool Compiler<Emitter>::visitCompoundStmt(const CompoundStmt *S) {
5268 BlockScope<Emitter> Scope(this);
5269 for (const auto *InnerStmt : S->body())
5270 if (!visitStmt(S: InnerStmt))
5271 return false;
5272 return Scope.destroyLocals();
5273}
5274
5275template <class Emitter>
5276bool Compiler<Emitter>::maybeEmitDeferredVarInit(const VarDecl *VD) {
5277 if (auto *DD = dyn_cast_if_present<DecompositionDecl>(Val: VD)) {
5278 for (auto *BD : DD->flat_bindings())
5279 if (auto *KD = BD->getHoldingVar(); KD && !this->visitVarDecl(KD))
5280 return false;
5281 }
5282 return true;
5283}
5284
5285template <class Emitter>
5286bool Compiler<Emitter>::visitDeclStmt(const DeclStmt *DS,
5287 bool EvaluateConditionDecl) {
5288 for (const auto *D : DS->decls()) {
5289 if (isa<StaticAssertDecl, TagDecl, TypedefNameDecl, BaseUsingDecl,
5290 FunctionDecl, NamespaceAliasDecl, UsingDirectiveDecl>(Val: D))
5291 continue;
5292
5293 const auto *VD = dyn_cast<VarDecl>(Val: D);
5294 if (!VD)
5295 return false;
5296 if (!this->visitVarDecl(VD))
5297 return false;
5298
5299 // Register decomposition decl holding vars.
5300 if (EvaluateConditionDecl && !this->maybeEmitDeferredVarInit(VD))
5301 return false;
5302 }
5303
5304 return true;
5305}
5306
5307template <class Emitter>
5308bool Compiler<Emitter>::visitReturnStmt(const ReturnStmt *RS) {
5309 if (this->InStmtExpr)
5310 return this->emitUnsupported(RS);
5311
5312 if (const Expr *RE = RS->getRetValue()) {
5313 LocalScope<Emitter> RetScope(this);
5314 if (ReturnType) {
5315 // Primitive types are simply returned.
5316 if (!this->visit(RE))
5317 return false;
5318 this->emitCleanup();
5319 return this->emitRet(*ReturnType, RS);
5320 } else if (RE->getType()->isVoidType()) {
5321 if (!this->visit(RE))
5322 return false;
5323 } else {
5324 InitLinkScope<Emitter> ILS(this, InitLink::RVO());
5325 // RVO - construct the value in the return location.
5326 if (!this->emitRVOPtr(RE))
5327 return false;
5328 if (!this->visitInitializer(RE))
5329 return false;
5330 if (!this->emitPopPtr(RE))
5331 return false;
5332
5333 this->emitCleanup();
5334 return this->emitRetVoid(RS);
5335 }
5336 }
5337
5338 // Void return.
5339 this->emitCleanup();
5340 return this->emitRetVoid(RS);
5341}
5342
5343template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
5344 auto visitChildStmt = [&](const Stmt *S) -> bool {
5345 LocalScope<Emitter> SScope(this);
5346 if (!visitStmt(S))
5347 return false;
5348 return SScope.destroyLocals();
5349 };
5350 if (auto *CondInit = IS->getInit())
5351 if (!visitStmt(S: CondInit))
5352 return false;
5353
5354 if (const DeclStmt *CondDecl = IS->getConditionVariableDeclStmt())
5355 if (!visitDeclStmt(DS: CondDecl))
5356 return false;
5357
5358 // Save ourselves compiling some code and the jumps, etc. if the condition is
5359 // stataically known to be either true or false. We could look at more cases
5360 // here, but I think all the ones that actually happen are using a
5361 // ConstantExpr.
5362 if (std::optional<bool> BoolValue = getBoolValue(E: IS->getCond())) {
5363 if (*BoolValue)
5364 return visitChildStmt(IS->getThen());
5365 else if (const Stmt *Else = IS->getElse())
5366 return visitChildStmt(Else);
5367 return true;
5368 }
5369
5370 // Otherwise, compile the condition.
5371 if (IS->isNonNegatedConsteval()) {
5372 if (!this->emitIsConstantContext(IS))
5373 return false;
5374 } else if (IS->isNegatedConsteval()) {
5375 if (!this->emitIsConstantContext(IS))
5376 return false;
5377 if (!this->emitInv(IS))
5378 return false;
5379 } else {
5380 if (!this->visitBool(IS->getCond()))
5381 return false;
5382 }
5383
5384 if (!this->maybeEmitDeferredVarInit(IS->getConditionVariable()))
5385 return false;
5386
5387 if (const Stmt *Else = IS->getElse()) {
5388 LabelTy LabelElse = this->getLabel();
5389 LabelTy LabelEnd = this->getLabel();
5390 if (!this->jumpFalse(LabelElse))
5391 return false;
5392 if (!visitChildStmt(IS->getThen()))
5393 return false;
5394 if (!this->jump(LabelEnd))
5395 return false;
5396 this->emitLabel(LabelElse);
5397 if (!visitChildStmt(Else))
5398 return false;
5399 this->emitLabel(LabelEnd);
5400 } else {
5401 LabelTy LabelEnd = this->getLabel();
5402 if (!this->jumpFalse(LabelEnd))
5403 return false;
5404 if (!visitChildStmt(IS->getThen()))
5405 return false;
5406 this->emitLabel(LabelEnd);
5407 }
5408
5409 return true;
5410}
5411
5412template <class Emitter>
5413bool Compiler<Emitter>::visitWhileStmt(const WhileStmt *S) {
5414 const Expr *Cond = S->getCond();
5415 const Stmt *Body = S->getBody();
5416
5417 LabelTy CondLabel = this->getLabel(); // Label before the condition.
5418 LabelTy EndLabel = this->getLabel(); // Label after the loop.
5419 LoopScope<Emitter> LS(this, EndLabel, CondLabel);
5420
5421 this->fallthrough(CondLabel);
5422 this->emitLabel(CondLabel);
5423
5424 {
5425 LocalScope<Emitter> CondScope(this);
5426 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5427 if (!visitDeclStmt(DS: CondDecl))
5428 return false;
5429
5430 if (!this->visitBool(Cond))
5431 return false;
5432
5433 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
5434 return false;
5435
5436 if (!this->jumpFalse(EndLabel))
5437 return false;
5438
5439 if (!this->visitStmt(Body))
5440 return false;
5441
5442 if (!CondScope.destroyLocals())
5443 return false;
5444 }
5445 if (!this->jump(CondLabel))
5446 return false;
5447 this->fallthrough(EndLabel);
5448 this->emitLabel(EndLabel);
5449
5450 return true;
5451}
5452
5453template <class Emitter> bool Compiler<Emitter>::visitDoStmt(const DoStmt *S) {
5454 const Expr *Cond = S->getCond();
5455 const Stmt *Body = S->getBody();
5456
5457 LabelTy StartLabel = this->getLabel();
5458 LabelTy EndLabel = this->getLabel();
5459 LabelTy CondLabel = this->getLabel();
5460 LoopScope<Emitter> LS(this, EndLabel, CondLabel);
5461
5462 this->fallthrough(StartLabel);
5463 this->emitLabel(StartLabel);
5464
5465 {
5466 LocalScope<Emitter> CondScope(this);
5467 if (!this->visitStmt(Body))
5468 return false;
5469 this->fallthrough(CondLabel);
5470 this->emitLabel(CondLabel);
5471 if (!this->visitBool(Cond))
5472 return false;
5473
5474 if (!CondScope.destroyLocals())
5475 return false;
5476 }
5477 if (!this->jumpTrue(StartLabel))
5478 return false;
5479
5480 this->fallthrough(EndLabel);
5481 this->emitLabel(EndLabel);
5482 return true;
5483}
5484
5485template <class Emitter>
5486bool Compiler<Emitter>::visitForStmt(const ForStmt *S) {
5487 // for (Init; Cond; Inc) { Body }
5488 const Stmt *Init = S->getInit();
5489 const Expr *Cond = S->getCond();
5490 const Expr *Inc = S->getInc();
5491 const Stmt *Body = S->getBody();
5492
5493 LabelTy EndLabel = this->getLabel();
5494 LabelTy CondLabel = this->getLabel();
5495 LabelTy IncLabel = this->getLabel();
5496 LoopScope<Emitter> LS(this, EndLabel, IncLabel);
5497
5498 if (Init && !this->visitStmt(Init))
5499 return false;
5500
5501 this->fallthrough(CondLabel);
5502 this->emitLabel(CondLabel);
5503
5504 // Start of loop body.
5505 LocalScope<Emitter> CondScope(this);
5506 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5507 if (!visitDeclStmt(DS: CondDecl))
5508 return false;
5509
5510 if (Cond) {
5511 if (!this->visitBool(Cond))
5512 return false;
5513 if (!this->jumpFalse(EndLabel))
5514 return false;
5515 }
5516 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
5517 return false;
5518
5519 if (Body && !this->visitStmt(Body))
5520 return false;
5521
5522 this->fallthrough(IncLabel);
5523 this->emitLabel(IncLabel);
5524 if (Inc && !this->discard(Inc))
5525 return false;
5526
5527 if (!CondScope.destroyLocals())
5528 return false;
5529 if (!this->jump(CondLabel))
5530 return false;
5531 // End of loop body.
5532
5533 this->emitLabel(EndLabel);
5534 // If we jumped out of the loop above, we still need to clean up the condition
5535 // scope.
5536 return CondScope.destroyLocals();
5537}
5538
5539template <class Emitter>
5540bool Compiler<Emitter>::visitCXXForRangeStmt(const CXXForRangeStmt *S) {
5541 const Stmt *Init = S->getInit();
5542 const Expr *Cond = S->getCond();
5543 const Expr *Inc = S->getInc();
5544 const Stmt *Body = S->getBody();
5545 const Stmt *BeginStmt = S->getBeginStmt();
5546 const Stmt *RangeStmt = S->getRangeStmt();
5547 const Stmt *EndStmt = S->getEndStmt();
5548 const VarDecl *LoopVar = S->getLoopVariable();
5549
5550 LabelTy EndLabel = this->getLabel();
5551 LabelTy CondLabel = this->getLabel();
5552 LabelTy IncLabel = this->getLabel();
5553 LoopScope<Emitter> LS(this, EndLabel, IncLabel);
5554
5555 // Emit declarations needed in the loop.
5556 if (Init && !this->visitStmt(Init))
5557 return false;
5558 if (!this->visitStmt(RangeStmt))
5559 return false;
5560 if (!this->visitStmt(BeginStmt))
5561 return false;
5562 if (!this->visitStmt(EndStmt))
5563 return false;
5564
5565 // Now the condition as well as the loop variable assignment.
5566 this->fallthrough(CondLabel);
5567 this->emitLabel(CondLabel);
5568 if (!this->visitBool(Cond))
5569 return false;
5570 if (!this->jumpFalse(EndLabel))
5571 return false;
5572
5573 if (!this->visitVarDecl(LoopVar))
5574 return false;
5575
5576 // Body.
5577 {
5578 if (!this->visitStmt(Body))
5579 return false;
5580
5581 this->fallthrough(IncLabel);
5582 this->emitLabel(IncLabel);
5583 if (!this->discard(Inc))
5584 return false;
5585 }
5586
5587 if (!this->jump(CondLabel))
5588 return false;
5589
5590 this->fallthrough(EndLabel);
5591 this->emitLabel(EndLabel);
5592 return true;
5593}
5594
5595template <class Emitter>
5596bool Compiler<Emitter>::visitBreakStmt(const BreakStmt *S) {
5597 if (!BreakLabel)
5598 return false;
5599
5600 for (VariableScope<Emitter> *C = VarScope; C != BreakVarScope;
5601 C = C->getParent())
5602 C->emitDestruction();
5603 return this->jump(*BreakLabel);
5604}
5605
5606template <class Emitter>
5607bool Compiler<Emitter>::visitContinueStmt(const ContinueStmt *S) {
5608 if (!ContinueLabel)
5609 return false;
5610
5611 for (VariableScope<Emitter> *C = VarScope;
5612 C && C->getParent() != ContinueVarScope; C = C->getParent())
5613 C->emitDestruction();
5614 return this->jump(*ContinueLabel);
5615}
5616
5617template <class Emitter>
5618bool Compiler<Emitter>::visitSwitchStmt(const SwitchStmt *S) {
5619 const Expr *Cond = S->getCond();
5620 PrimType CondT = this->classifyPrim(Cond->getType());
5621 LocalScope<Emitter> LS(this);
5622
5623 LabelTy EndLabel = this->getLabel();
5624 OptLabelTy DefaultLabel = std::nullopt;
5625 unsigned CondVar =
5626 this->allocateLocalPrimitive(Cond, CondT, /*IsConst=*/true);
5627
5628 if (const auto *CondInit = S->getInit())
5629 if (!visitStmt(S: CondInit))
5630 return false;
5631
5632 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5633 if (!visitDeclStmt(DS: CondDecl))
5634 return false;
5635
5636 // Initialize condition variable.
5637 if (!this->visit(Cond))
5638 return false;
5639 if (!this->emitSetLocal(CondT, CondVar, S))
5640 return false;
5641
5642 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
5643 return false;
5644
5645 CaseMap CaseLabels;
5646 // Create labels and comparison ops for all case statements.
5647 for (const SwitchCase *SC = S->getSwitchCaseList(); SC;
5648 SC = SC->getNextSwitchCase()) {
5649 if (const auto *CS = dyn_cast<CaseStmt>(Val: SC)) {
5650 // FIXME: Implement ranges.
5651 if (CS->caseStmtIsGNURange())
5652 return false;
5653 CaseLabels[SC] = this->getLabel();
5654
5655 const Expr *Value = CS->getLHS();
5656 PrimType ValueT = this->classifyPrim(Value->getType());
5657
5658 // Compare the case statement's value to the switch condition.
5659 if (!this->emitGetLocal(CondT, CondVar, CS))
5660 return false;
5661 if (!this->visit(Value))
5662 return false;
5663
5664 // Compare and jump to the case label.
5665 if (!this->emitEQ(ValueT, S))
5666 return false;
5667 if (!this->jumpTrue(CaseLabels[CS]))
5668 return false;
5669 } else {
5670 assert(!DefaultLabel);
5671 DefaultLabel = this->getLabel();
5672 }
5673 }
5674
5675 // If none of the conditions above were true, fall through to the default
5676 // statement or jump after the switch statement.
5677 if (DefaultLabel) {
5678 if (!this->jump(*DefaultLabel))
5679 return false;
5680 } else {
5681 if (!this->jump(EndLabel))
5682 return false;
5683 }
5684
5685 SwitchScope<Emitter> SS(this, std::move(CaseLabels), EndLabel, DefaultLabel);
5686 if (!this->visitStmt(S->getBody()))
5687 return false;
5688 this->emitLabel(EndLabel);
5689
5690 return LS.destroyLocals();
5691}
5692
5693template <class Emitter>
5694bool Compiler<Emitter>::visitCaseStmt(const CaseStmt *S) {
5695 this->emitLabel(CaseLabels[S]);
5696 return this->visitStmt(S->getSubStmt());
5697}
5698
5699template <class Emitter>
5700bool Compiler<Emitter>::visitDefaultStmt(const DefaultStmt *S) {
5701 this->emitLabel(*DefaultLabel);
5702 return this->visitStmt(S->getSubStmt());
5703}
5704
5705template <class Emitter>
5706bool Compiler<Emitter>::visitAttributedStmt(const AttributedStmt *S) {
5707 if (this->Ctx.getLangOpts().CXXAssumptions &&
5708 !this->Ctx.getLangOpts().MSVCCompat) {
5709 for (const Attr *A : S->getAttrs()) {
5710 auto *AA = dyn_cast<CXXAssumeAttr>(Val: A);
5711 if (!AA)
5712 continue;
5713
5714 assert(isa<NullStmt>(S->getSubStmt()));
5715
5716 const Expr *Assumption = AA->getAssumption();
5717 if (Assumption->isValueDependent())
5718 return false;
5719
5720 if (Assumption->HasSideEffects(Ctx: this->Ctx.getASTContext()))
5721 continue;
5722
5723 // Evaluate assumption.
5724 if (!this->visitBool(Assumption))
5725 return false;
5726
5727 if (!this->emitAssume(Assumption))
5728 return false;
5729 }
5730 }
5731
5732 // Ignore other attributes.
5733 return this->visitStmt(S->getSubStmt());
5734}
5735
5736template <class Emitter>
5737bool Compiler<Emitter>::visitCXXTryStmt(const CXXTryStmt *S) {
5738 // Ignore all handlers.
5739 return this->visitStmt(S->getTryBlock());
5740}
5741
5742template <class Emitter>
5743bool Compiler<Emitter>::emitLambdaStaticInvokerBody(const CXXMethodDecl *MD) {
5744 assert(MD->isLambdaStaticInvoker());
5745 assert(MD->hasBody());
5746 assert(cast<CompoundStmt>(MD->getBody())->body_empty());
5747
5748 const CXXRecordDecl *ClosureClass = MD->getParent();
5749 const CXXMethodDecl *LambdaCallOp = ClosureClass->getLambdaCallOperator();
5750 assert(ClosureClass->captures_begin() == ClosureClass->captures_end());
5751 const Function *Func = this->getFunction(LambdaCallOp);
5752 if (!Func)
5753 return false;
5754 assert(Func->hasThisPointer());
5755 assert(Func->getNumParams() == (MD->getNumParams() + 1 + Func->hasRVO()));
5756
5757 if (Func->hasRVO()) {
5758 if (!this->emitRVOPtr(MD))
5759 return false;
5760 }
5761
5762 // The lambda call operator needs an instance pointer, but we don't have
5763 // one here, and we don't need one either because the lambda cannot have
5764 // any captures, as verified above. Emit a null pointer. This is then
5765 // special-cased when interpreting to not emit any misleading diagnostics.
5766 if (!this->emitNullPtr(0, nullptr, MD))
5767 return false;
5768
5769 // Forward all arguments from the static invoker to the lambda call operator.
5770 for (const ParmVarDecl *PVD : MD->parameters()) {
5771 auto It = this->Params.find(PVD);
5772 assert(It != this->Params.end());
5773
5774 // We do the lvalue-to-rvalue conversion manually here, so no need
5775 // to care about references.
5776 PrimType ParamType = this->classify(PVD->getType()).value_or(PT_Ptr);
5777 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
5778 return false;
5779 }
5780
5781 if (!this->emitCall(Func, 0, LambdaCallOp))
5782 return false;
5783
5784 this->emitCleanup();
5785 if (ReturnType)
5786 return this->emitRet(*ReturnType, MD);
5787
5788 // Nothing to do, since we emitted the RVO pointer above.
5789 return this->emitRetVoid(MD);
5790}
5791
5792template <class Emitter>
5793bool Compiler<Emitter>::checkLiteralType(const Expr *E) {
5794 if (Ctx.getLangOpts().CPlusPlus23)
5795 return true;
5796
5797 if (!E->isPRValue() || E->getType()->isLiteralType(Ctx: Ctx.getASTContext()))
5798 return true;
5799
5800 return this->emitCheckLiteralType(E->getType().getTypePtr(), E);
5801}
5802
5803template <class Emitter>
5804bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
5805 assert(!ReturnType);
5806
5807 auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
5808 const Expr *InitExpr) -> bool {
5809 // We don't know what to do with these, so just return false.
5810 if (InitExpr->getType().isNull())
5811 return false;
5812
5813 if (std::optional<PrimType> T = this->classify(InitExpr)) {
5814 if (!this->visit(InitExpr))
5815 return false;
5816
5817 if (F->isBitField())
5818 return this->emitInitThisBitField(*T, F, FieldOffset, InitExpr);
5819 return this->emitInitThisField(*T, FieldOffset, InitExpr);
5820 }
5821 // Non-primitive case. Get a pointer to the field-to-initialize
5822 // on the stack and call visitInitialzer() for it.
5823 InitLinkScope<Emitter> FieldScope(this, InitLink::Field(Offset: F->Offset));
5824 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
5825 return false;
5826
5827 if (!this->visitInitializer(InitExpr))
5828 return false;
5829
5830 return this->emitFinishInitPop(InitExpr);
5831 };
5832
5833 const RecordDecl *RD = Ctor->getParent();
5834 const Record *R = this->getRecord(RD);
5835 if (!R)
5836 return false;
5837
5838 if (R->isUnion() && Ctor->isCopyOrMoveConstructor()) {
5839 // union copy and move ctors are special.
5840 assert(cast<CompoundStmt>(Ctor->getBody())->body_empty());
5841 if (!this->emitThis(Ctor))
5842 return false;
5843
5844 auto PVD = Ctor->getParamDecl(i: 0);
5845 ParamOffset PO = this->Params[PVD]; // Must exist.
5846
5847 if (!this->emitGetParam(PT_Ptr, PO.Offset, Ctor))
5848 return false;
5849
5850 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
5851 this->emitRetVoid(Ctor);
5852 }
5853
5854 InitLinkScope<Emitter> InitScope(this, InitLink::This());
5855 for (const auto *Init : Ctor->inits()) {
5856 // Scope needed for the initializers.
5857 BlockScope<Emitter> Scope(this);
5858
5859 const Expr *InitExpr = Init->getInit();
5860 if (const FieldDecl *Member = Init->getMember()) {
5861 const Record::Field *F = R->getField(FD: Member);
5862
5863 if (!emitFieldInitializer(F, F->Offset, InitExpr))
5864 return false;
5865 } else if (const Type *Base = Init->getBaseClass()) {
5866 const auto *BaseDecl = Base->getAsCXXRecordDecl();
5867 assert(BaseDecl);
5868
5869 if (Init->isBaseVirtual()) {
5870 assert(R->getVirtualBase(BaseDecl));
5871 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
5872 return false;
5873
5874 } else {
5875 // Base class initializer.
5876 // Get This Base and call initializer on it.
5877 const Record::Base *B = R->getBase(FD: BaseDecl);
5878 assert(B);
5879 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
5880 return false;
5881 }
5882
5883 if (!this->visitInitializer(InitExpr))
5884 return false;
5885 if (!this->emitFinishInitPop(InitExpr))
5886 return false;
5887 } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {
5888 assert(IFD->getChainingSize() >= 2);
5889
5890 unsigned NestedFieldOffset = 0;
5891 const Record::Field *NestedField = nullptr;
5892 for (const NamedDecl *ND : IFD->chain()) {
5893 const auto *FD = cast<FieldDecl>(Val: ND);
5894 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
5895 assert(FieldRecord);
5896
5897 NestedField = FieldRecord->getField(FD);
5898 assert(NestedField);
5899
5900 NestedFieldOffset += NestedField->Offset;
5901 }
5902 assert(NestedField);
5903
5904 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
5905 return false;
5906
5907 // Mark all chain links as initialized.
5908 unsigned InitFieldOffset = 0;
5909 for (const NamedDecl *ND : IFD->chain().drop_back()) {
5910 const auto *FD = cast<FieldDecl>(Val: ND);
5911 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
5912 assert(FieldRecord);
5913 NestedField = FieldRecord->getField(FD);
5914 InitFieldOffset += NestedField->Offset;
5915 assert(NestedField);
5916 if (!this->emitGetPtrThisField(InitFieldOffset, InitExpr))
5917 return false;
5918 if (!this->emitFinishInitPop(InitExpr))
5919 return false;
5920 }
5921
5922 } else {
5923 assert(Init->isDelegatingInitializer());
5924 if (!this->emitThis(InitExpr))
5925 return false;
5926 if (!this->visitInitializer(Init->getInit()))
5927 return false;
5928 if (!this->emitPopPtr(InitExpr))
5929 return false;
5930 }
5931
5932 if (!Scope.destroyLocals())
5933 return false;
5934 }
5935
5936 if (const auto *Body = Ctor->getBody())
5937 if (!visitStmt(S: Body))
5938 return false;
5939
5940 return this->emitRetVoid(SourceInfo{});
5941}
5942
5943template <class Emitter>
5944bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) {
5945 const RecordDecl *RD = Dtor->getParent();
5946 const Record *R = this->getRecord(RD);
5947 if (!R)
5948 return false;
5949
5950 if (!Dtor->isTrivial() && Dtor->getBody()) {
5951 if (!this->visitStmt(Dtor->getBody()))
5952 return false;
5953 }
5954
5955 if (!this->emitThis(Dtor))
5956 return false;
5957
5958 if (!this->emitCheckDestruction(Dtor))
5959 return false;
5960
5961 assert(R);
5962 if (!R->isUnion()) {
5963 // First, destroy all fields.
5964 for (const Record::Field &Field : llvm::reverse(C: R->fields())) {
5965 const Descriptor *D = Field.Desc;
5966 if (!D->isPrimitive() && !D->isPrimitiveArray()) {
5967 if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
5968 return false;
5969 if (!this->emitDestruction(D, SourceInfo{}))
5970 return false;
5971 if (!this->emitPopPtr(SourceInfo{}))
5972 return false;
5973 }
5974 }
5975 }
5976
5977 for (const Record::Base &Base : llvm::reverse(C: R->bases())) {
5978 if (Base.R->isAnonymousUnion())
5979 continue;
5980
5981 if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
5982 return false;
5983 if (!this->emitRecordDestruction(Base.R, {}))
5984 return false;
5985 if (!this->emitPopPtr(SourceInfo{}))
5986 return false;
5987 }
5988
5989 // FIXME: Virtual bases.
5990 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
5991}
5992
5993template <class Emitter>
5994bool Compiler<Emitter>::compileUnionAssignmentOperator(
5995 const CXXMethodDecl *MD) {
5996 if (!this->emitThis(MD))
5997 return false;
5998
5999 auto PVD = MD->getParamDecl(i: 0);
6000 ParamOffset PO = this->Params[PVD]; // Must exist.
6001
6002 if (!this->emitGetParam(PT_Ptr, PO.Offset, MD))
6003 return false;
6004
6005 return this->emitMemcpy(MD) && this->emitRet(PT_Ptr, MD);
6006}
6007
6008template <class Emitter>
6009bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {
6010 // Classify the return type.
6011 ReturnType = this->classify(F->getReturnType());
6012
6013 if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(Val: F))
6014 return this->compileConstructor(Ctor);
6015 if (const auto *Dtor = dyn_cast<CXXDestructorDecl>(Val: F))
6016 return this->compileDestructor(Dtor);
6017
6018 // Emit custom code if this is a lambda static invoker.
6019 if (const auto *MD = dyn_cast<CXXMethodDecl>(Val: F)) {
6020 const RecordDecl *RD = MD->getParent();
6021
6022 if (RD->isUnion() &&
6023 (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()))
6024 return this->compileUnionAssignmentOperator(MD);
6025
6026 if (MD->isLambdaStaticInvoker())
6027 return this->emitLambdaStaticInvokerBody(MD);
6028 }
6029
6030 // Regular functions.
6031 if (const auto *Body = F->getBody())
6032 if (!visitStmt(S: Body))
6033 return false;
6034
6035 // Emit a guard return to protect against a code path missing one.
6036 if (F->getReturnType()->isVoidType())
6037 return this->emitRetVoid(SourceInfo{});
6038 return this->emitNoRet(SourceInfo{});
6039}
6040
6041template <class Emitter>
6042bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
6043 const Expr *SubExpr = E->getSubExpr();
6044 if (SubExpr->getType()->isAnyComplexType())
6045 return this->VisitComplexUnaryOperator(E);
6046 if (SubExpr->getType()->isVectorType())
6047 return this->VisitVectorUnaryOperator(E);
6048 if (SubExpr->getType()->isFixedPointType())
6049 return this->VisitFixedPointUnaryOperator(E);
6050 std::optional<PrimType> T = classify(SubExpr->getType());
6051
6052 switch (E->getOpcode()) {
6053 case UO_PostInc: { // x++
6054 if (!Ctx.getLangOpts().CPlusPlus14)
6055 return this->emitInvalid(E);
6056 if (!T)
6057 return this->emitError(E);
6058
6059 if (!this->visit(SubExpr))
6060 return false;
6061
6062 if (T == PT_Ptr) {
6063 if (!this->emitIncPtr(E))
6064 return false;
6065
6066 return DiscardResult ? this->emitPopPtr(E) : true;
6067 }
6068
6069 if (T == PT_Float) {
6070 return DiscardResult ? this->emitIncfPop(getFPOptions(E), E)
6071 : this->emitIncf(getFPOptions(E), E);
6072 }
6073
6074 return DiscardResult ? this->emitIncPop(*T, E->canOverflow(), E)
6075 : this->emitInc(*T, E->canOverflow(), E);
6076 }
6077 case UO_PostDec: { // x--
6078 if (!Ctx.getLangOpts().CPlusPlus14)
6079 return this->emitInvalid(E);
6080 if (!T)
6081 return this->emitError(E);
6082
6083 if (!this->visit(SubExpr))
6084 return false;
6085
6086 if (T == PT_Ptr) {
6087 if (!this->emitDecPtr(E))
6088 return false;
6089
6090 return DiscardResult ? this->emitPopPtr(E) : true;
6091 }
6092
6093 if (T == PT_Float) {
6094 return DiscardResult ? this->emitDecfPop(getFPOptions(E), E)
6095 : this->emitDecf(getFPOptions(E), E);
6096 }
6097
6098 return DiscardResult ? this->emitDecPop(*T, E->canOverflow(), E)
6099 : this->emitDec(*T, E->canOverflow(), E);
6100 }
6101 case UO_PreInc: { // ++x
6102 if (!Ctx.getLangOpts().CPlusPlus14)
6103 return this->emitInvalid(E);
6104 if (!T)
6105 return this->emitError(E);
6106
6107 if (!this->visit(SubExpr))
6108 return false;
6109
6110 if (T == PT_Ptr) {
6111 if (!this->emitLoadPtr(E))
6112 return false;
6113 if (!this->emitConstUint8(1, E))
6114 return false;
6115 if (!this->emitAddOffsetUint8(E))
6116 return false;
6117 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
6118 }
6119
6120 // Post-inc and pre-inc are the same if the value is to be discarded.
6121 if (DiscardResult) {
6122 if (T == PT_Float)
6123 return this->emitIncfPop(getFPOptions(E), E);
6124 return this->emitIncPop(*T, E->canOverflow(), E);
6125 }
6126
6127 if (T == PT_Float) {
6128 const auto &TargetSemantics = Ctx.getFloatSemantics(T: E->getType());
6129 if (!this->emitLoadFloat(E))
6130 return false;
6131 APFloat F(TargetSemantics, 1);
6132 if (!this->emitFloat(F, E))
6133 return false;
6134
6135 if (!this->emitAddf(getFPOptions(E), E))
6136 return false;
6137 if (!this->emitStoreFloat(E))
6138 return false;
6139 } else {
6140 assert(isIntegralType(*T));
6141 if (!this->emitPreInc(*T, E->canOverflow(), E))
6142 return false;
6143 }
6144 return E->isGLValue() || this->emitLoadPop(*T, E);
6145 }
6146 case UO_PreDec: { // --x
6147 if (!Ctx.getLangOpts().CPlusPlus14)
6148 return this->emitInvalid(E);
6149 if (!T)
6150 return this->emitError(E);
6151
6152 if (!this->visit(SubExpr))
6153 return false;
6154
6155 if (T == PT_Ptr) {
6156 if (!this->emitLoadPtr(E))
6157 return false;
6158 if (!this->emitConstUint8(1, E))
6159 return false;
6160 if (!this->emitSubOffsetUint8(E))
6161 return false;
6162 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
6163 }
6164
6165 // Post-dec and pre-dec are the same if the value is to be discarded.
6166 if (DiscardResult) {
6167 if (T == PT_Float)
6168 return this->emitDecfPop(getFPOptions(E), E);
6169 return this->emitDecPop(*T, E->canOverflow(), E);
6170 }
6171
6172 if (T == PT_Float) {
6173 const auto &TargetSemantics = Ctx.getFloatSemantics(T: E->getType());
6174 if (!this->emitLoadFloat(E))
6175 return false;
6176 APFloat F(TargetSemantics, 1);
6177 if (!this->emitFloat(F, E))
6178 return false;
6179
6180 if (!this->emitSubf(getFPOptions(E), E))
6181 return false;
6182 if (!this->emitStoreFloat(E))
6183 return false;
6184 } else {
6185 assert(isIntegralType(*T));
6186 if (!this->emitPreDec(*T, E->canOverflow(), E))
6187 return false;
6188 }
6189 return E->isGLValue() || this->emitLoadPop(*T, E);
6190 }
6191 case UO_LNot: // !x
6192 if (!T)
6193 return this->emitError(E);
6194
6195 if (DiscardResult)
6196 return this->discard(SubExpr);
6197
6198 if (!this->visitBool(SubExpr))
6199 return false;
6200
6201 if (!this->emitInv(E))
6202 return false;
6203
6204 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
6205 return this->emitCast(PT_Bool, ET, E);
6206 return true;
6207 case UO_Minus: // -x
6208 if (!T)
6209 return this->emitError(E);
6210
6211 if (!this->visit(SubExpr))
6212 return false;
6213 return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
6214 case UO_Plus: // +x
6215 if (!T)
6216 return this->emitError(E);
6217
6218 if (!this->visit(SubExpr)) // noop
6219 return false;
6220 return DiscardResult ? this->emitPop(*T, E) : true;
6221 case UO_AddrOf: // &x
6222 if (E->getType()->isMemberPointerType()) {
6223 // C++11 [expr.unary.op]p3 has very strict rules on how the address of a
6224 // member can be formed.
6225 return this->emitGetMemberPtr(cast<DeclRefExpr>(Val: SubExpr)->getDecl(), E);
6226 }
6227 // We should already have a pointer when we get here.
6228 return this->delegate(SubExpr);
6229 case UO_Deref: // *x
6230 if (DiscardResult)
6231 return this->discard(SubExpr);
6232
6233 if (!this->visit(SubExpr))
6234 return false;
6235
6236 if (classifyPrim(SubExpr) == PT_Ptr)
6237 return this->emitNarrowPtr(E);
6238 return true;
6239
6240 case UO_Not: // ~x
6241 if (!T)
6242 return this->emitError(E);
6243
6244 if (!this->visit(SubExpr))
6245 return false;
6246 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
6247 case UO_Real: // __real x
6248 assert(T);
6249 return this->delegate(SubExpr);
6250 case UO_Imag: { // __imag x
6251 assert(T);
6252 if (!this->discard(SubExpr))
6253 return false;
6254 return this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);
6255 }
6256 case UO_Extension:
6257 return this->delegate(SubExpr);
6258 case UO_Coawait:
6259 assert(false && "Unhandled opcode");
6260 }
6261
6262 return false;
6263}
6264
6265template <class Emitter>
6266bool Compiler<Emitter>::VisitComplexUnaryOperator(const UnaryOperator *E) {
6267 const Expr *SubExpr = E->getSubExpr();
6268 assert(SubExpr->getType()->isAnyComplexType());
6269
6270 if (DiscardResult)
6271 return this->discard(SubExpr);
6272
6273 std::optional<PrimType> ResT = classify(E);
6274 auto prepareResult = [=]() -> bool {
6275 if (!ResT && !Initializing) {
6276 std::optional<unsigned> LocalIndex = allocateLocal(Src: SubExpr);
6277 if (!LocalIndex)
6278 return false;
6279 return this->emitGetPtrLocal(*LocalIndex, E);
6280 }
6281
6282 return true;
6283 };
6284
6285 // The offset of the temporary, if we created one.
6286 unsigned SubExprOffset = ~0u;
6287 auto createTemp = [=, &SubExprOffset]() -> bool {
6288 SubExprOffset =
6289 this->allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
6290 if (!this->visit(SubExpr))
6291 return false;
6292 return this->emitSetLocal(PT_Ptr, SubExprOffset, E);
6293 };
6294
6295 PrimType ElemT = classifyComplexElementType(T: SubExpr->getType());
6296 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
6297 if (!this->emitGetLocal(PT_Ptr, Offset, E))
6298 return false;
6299 return this->emitArrayElemPop(ElemT, Index, E);
6300 };
6301
6302 switch (E->getOpcode()) {
6303 case UO_Minus:
6304 if (!prepareResult())
6305 return false;
6306 if (!createTemp())
6307 return false;
6308 for (unsigned I = 0; I != 2; ++I) {
6309 if (!getElem(SubExprOffset, I))
6310 return false;
6311 if (!this->emitNeg(ElemT, E))
6312 return false;
6313 if (!this->emitInitElem(ElemT, I, E))
6314 return false;
6315 }
6316 break;
6317
6318 case UO_Plus: // +x
6319 case UO_AddrOf: // &x
6320 case UO_Deref: // *x
6321 return this->delegate(SubExpr);
6322
6323 case UO_LNot:
6324 if (!this->visit(SubExpr))
6325 return false;
6326 if (!this->emitComplexBoolCast(SubExpr))
6327 return false;
6328 if (!this->emitInv(E))
6329 return false;
6330 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
6331 return this->emitCast(PT_Bool, ET, E);
6332 return true;
6333
6334 case UO_Real:
6335 return this->emitComplexReal(SubExpr);
6336
6337 case UO_Imag:
6338 if (!this->visit(SubExpr))
6339 return false;
6340
6341 if (SubExpr->isLValue()) {
6342 if (!this->emitConstUint8(1, E))
6343 return false;
6344 return this->emitArrayElemPtrPopUint8(E);
6345 }
6346
6347 // Since our _Complex implementation does not map to a primitive type,
6348 // we sometimes have to do the lvalue-to-rvalue conversion here manually.
6349 return this->emitArrayElemPop(classifyPrim(E->getType()), 1, E);
6350
6351 case UO_Not: // ~x
6352 if (!this->visit(SubExpr))
6353 return false;
6354 // Negate the imaginary component.
6355 if (!this->emitArrayElem(ElemT, 1, E))
6356 return false;
6357 if (!this->emitNeg(ElemT, E))
6358 return false;
6359 if (!this->emitInitElem(ElemT, 1, E))
6360 return false;
6361 return DiscardResult ? this->emitPopPtr(E) : true;
6362
6363 case UO_Extension:
6364 return this->delegate(SubExpr);
6365
6366 default:
6367 return this->emitInvalid(E);
6368 }
6369
6370 return true;
6371}
6372
6373template <class Emitter>
6374bool Compiler<Emitter>::VisitVectorUnaryOperator(const UnaryOperator *E) {
6375 const Expr *SubExpr = E->getSubExpr();
6376 assert(SubExpr->getType()->isVectorType());
6377
6378 if (DiscardResult)
6379 return this->discard(SubExpr);
6380
6381 auto UnaryOp = E->getOpcode();
6382 if (UnaryOp == UO_Extension)
6383 return this->delegate(SubExpr);
6384
6385 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
6386 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
6387 return this->emitInvalid(E);
6388
6389 // Nothing to do here.
6390 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
6391 return this->delegate(SubExpr);
6392
6393 if (!Initializing) {
6394 std::optional<unsigned> LocalIndex = allocateLocal(Src: SubExpr);
6395 if (!LocalIndex)
6396 return false;
6397 if (!this->emitGetPtrLocal(*LocalIndex, E))
6398 return false;
6399 }
6400
6401 // The offset of the temporary, if we created one.
6402 unsigned SubExprOffset =
6403 this->allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true);
6404 if (!this->visit(SubExpr))
6405 return false;
6406 if (!this->emitSetLocal(PT_Ptr, SubExprOffset, E))
6407 return false;
6408
6409 const auto *VecTy = SubExpr->getType()->getAs<VectorType>();
6410 PrimType ElemT = classifyVectorElementType(T: SubExpr->getType());
6411 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
6412 if (!this->emitGetLocal(PT_Ptr, Offset, E))
6413 return false;
6414 return this->emitArrayElemPop(ElemT, Index, E);
6415 };
6416
6417 switch (UnaryOp) {
6418 case UO_Minus:
6419 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6420 if (!getElem(SubExprOffset, I))
6421 return false;
6422 if (!this->emitNeg(ElemT, E))
6423 return false;
6424 if (!this->emitInitElem(ElemT, I, E))
6425 return false;
6426 }
6427 break;
6428 case UO_LNot: { // !x
6429 // In C++, the logic operators !, &&, || are available for vectors. !v is
6430 // equivalent to v == 0.
6431 //
6432 // The result of the comparison is a vector of the same width and number of
6433 // elements as the comparison operands with a signed integral element type.
6434 //
6435 // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
6436 QualType ResultVecTy = E->getType();
6437 PrimType ResultVecElemT =
6438 classifyPrim(ResultVecTy->getAs<VectorType>()->getElementType());
6439 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6440 if (!getElem(SubExprOffset, I))
6441 return false;
6442 // operator ! on vectors returns -1 for 'truth', so negate it.
6443 if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E))
6444 return false;
6445 if (!this->emitInv(E))
6446 return false;
6447 if (!this->emitPrimCast(PT_Bool, ElemT, VecTy->getElementType(), E))
6448 return false;
6449 if (!this->emitNeg(ElemT, E))
6450 return false;
6451 if (ElemT != ResultVecElemT &&
6452 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy, E))
6453 return false;
6454 if (!this->emitInitElem(ResultVecElemT, I, E))
6455 return false;
6456 }
6457 break;
6458 }
6459 case UO_Not: // ~x
6460 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6461 if (!getElem(SubExprOffset, I))
6462 return false;
6463 if (ElemT == PT_Bool) {
6464 if (!this->emitInv(E))
6465 return false;
6466 } else {
6467 if (!this->emitComp(ElemT, E))
6468 return false;
6469 }
6470 if (!this->emitInitElem(ElemT, I, E))
6471 return false;
6472 }
6473 break;
6474 default:
6475 llvm_unreachable("Unsupported unary operators should be handled up front");
6476 }
6477 return true;
6478}
6479
6480template <class Emitter>
6481bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
6482 if (DiscardResult)
6483 return true;
6484
6485 if (const auto *ECD = dyn_cast<EnumConstantDecl>(Val: D)) {
6486 return this->emitConst(ECD->getInitVal(), E);
6487 } else if (const auto *BD = dyn_cast<BindingDecl>(Val: D)) {
6488 return this->visit(BD->getBinding());
6489 } else if (const auto *FuncDecl = dyn_cast<FunctionDecl>(Val: D)) {
6490 const Function *F = getFunction(FD: FuncDecl);
6491 return F && this->emitGetFnPtr(F, E);
6492 } else if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(Val: D)) {
6493 if (std::optional<unsigned> Index = P.getOrCreateGlobal(VD: D)) {
6494 if (!this->emitGetPtrGlobal(*Index, E))
6495 return false;
6496 if (std::optional<PrimType> T = classify(E->getType())) {
6497 if (!this->visitAPValue(TPOD->getValue(), *T, E))
6498 return false;
6499 return this->emitInitGlobal(*T, *Index, E);
6500 }
6501 return this->visitAPValueInitializer(TPOD->getValue(), E,
6502 TPOD->getType());
6503 }
6504 return false;
6505 }
6506
6507 // References are implemented via pointers, so when we see a DeclRefExpr
6508 // pointing to a reference, we need to get its value directly (i.e. the
6509 // pointer to the actual value) instead of a pointer to the pointer to the
6510 // value.
6511 bool IsReference = D->getType()->isReferenceType();
6512
6513 // Check for local/global variables and parameters.
6514 if (auto It = Locals.find(Val: D); It != Locals.end()) {
6515 const unsigned Offset = It->second.Offset;
6516 if (IsReference)
6517 return this->emitGetLocal(classifyPrim(E), Offset, E);
6518 return this->emitGetPtrLocal(Offset, E);
6519 } else if (auto GlobalIndex = P.getGlobal(VD: D)) {
6520 if (IsReference) {
6521 if (!Ctx.getLangOpts().CPlusPlus11)
6522 return this->emitGetGlobal(classifyPrim(E), *GlobalIndex, E);
6523 return this->emitGetGlobalUnchecked(classifyPrim(E), *GlobalIndex, E);
6524 }
6525
6526 return this->emitGetPtrGlobal(*GlobalIndex, E);
6527 } else if (const auto *PVD = dyn_cast<ParmVarDecl>(Val: D)) {
6528 if (auto It = this->Params.find(PVD); It != this->Params.end()) {
6529 if (IsReference || !It->second.IsPtr)
6530 return this->emitGetParam(classifyPrim(E), It->second.Offset, E);
6531
6532 return this->emitGetPtrParam(It->second.Offset, E);
6533 }
6534 }
6535
6536 // In case we need to re-visit a declaration.
6537 auto revisit = [&](const VarDecl *VD) -> bool {
6538 if (!this->emitPushCC(VD->hasConstantInitialization(), E))
6539 return false;
6540 auto VarState = this->visitDecl(VD, /*IsConstexprUnknown=*/true);
6541
6542 if (!this->emitPopCC(E))
6543 return false;
6544
6545 if (VarState.notCreated())
6546 return true;
6547 if (!VarState)
6548 return false;
6549 // Retry.
6550 return this->visitDeclRef(D, E);
6551 };
6552
6553 // Handle lambda captures.
6554 if (auto It = this->LambdaCaptures.find(D);
6555 It != this->LambdaCaptures.end()) {
6556 auto [Offset, IsPtr] = It->second;
6557
6558 if (IsPtr)
6559 return this->emitGetThisFieldPtr(Offset, E);
6560 return this->emitGetPtrThisField(Offset, E);
6561 } else if (const auto *DRE = dyn_cast<DeclRefExpr>(Val: E);
6562 DRE && DRE->refersToEnclosingVariableOrCapture()) {
6563 if (const auto *VD = dyn_cast<VarDecl>(Val: D); VD && VD->isInitCapture())
6564 return revisit(VD);
6565 }
6566
6567 // Avoid infinite recursion.
6568 if (D == InitializingDecl)
6569 return this->emitDummyPtr(D, E);
6570
6571 // Try to lazily visit (or emit dummy pointers for) declarations
6572 // we haven't seen yet.
6573 // For C.
6574 if (!Ctx.getLangOpts().CPlusPlus) {
6575 if (const auto *VD = dyn_cast<VarDecl>(Val: D);
6576 VD && VD->getAnyInitializer() &&
6577 VD->getType().isConstant(Ctx: Ctx.getASTContext()) && !VD->isWeak())
6578 return revisit(VD);
6579 return this->emitDummyPtr(D, E);
6580 }
6581
6582 // ... and C++.
6583 const auto *VD = dyn_cast<VarDecl>(Val: D);
6584 if (!VD)
6585 return this->emitDummyPtr(D, E);
6586
6587 const auto typeShouldBeVisited = [&](QualType T) -> bool {
6588 if (T.isConstant(Ctx: Ctx.getASTContext()))
6589 return true;
6590 return T->isReferenceType();
6591 };
6592
6593 if ((VD->hasGlobalStorage() || VD->isStaticDataMember()) &&
6594 typeShouldBeVisited(VD->getType())) {
6595 if (const Expr *Init = VD->getAnyInitializer();
6596 Init && !Init->isValueDependent()) {
6597 // Whether or not the evaluation is successul doesn't really matter
6598 // here -- we will create a global variable in any case, and that
6599 // will have the state of initializer evaluation attached.
6600 APValue V;
6601 SmallVector<PartialDiagnosticAt> Notes;
6602 (void)Init->EvaluateAsInitializer(Result&: V, Ctx: Ctx.getASTContext(), VD, Notes,
6603 IsConstantInitializer: true);
6604 return this->visitDeclRef(D, E);
6605 }
6606 return revisit(VD);
6607 }
6608
6609 // FIXME: The evaluateValue() check here is a little ridiculous, since
6610 // it will ultimately call into Context::evaluateAsInitializer(). In
6611 // other words, we're evaluating the initializer, just to know if we can
6612 // evaluate the initializer.
6613 if (VD->isLocalVarDecl() && typeShouldBeVisited(VD->getType()) &&
6614 VD->getInit() && !VD->getInit()->isValueDependent()) {
6615
6616 if (VD->evaluateValue())
6617 return revisit(VD);
6618
6619 if (!D->getType()->isReferenceType())
6620 return this->emitDummyPtr(D, E);
6621
6622 return this->emitInvalidDeclRef(cast<DeclRefExpr>(Val: E),
6623 /*InitializerFailed=*/true, E);
6624 }
6625
6626 return this->emitDummyPtr(D, E);
6627}
6628
6629template <class Emitter>
6630bool Compiler<Emitter>::VisitDeclRefExpr(const DeclRefExpr *E) {
6631 const auto *D = E->getDecl();
6632 return this->visitDeclRef(D, E);
6633}
6634
6635template <class Emitter> void Compiler<Emitter>::emitCleanup() {
6636 for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent())
6637 C->emitDestruction();
6638}
6639
6640template <class Emitter>
6641unsigned Compiler<Emitter>::collectBaseOffset(const QualType BaseType,
6642 const QualType DerivedType) {
6643 const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
6644 if (const auto *R = Ty->getPointeeCXXRecordDecl())
6645 return R;
6646 return Ty->getAsCXXRecordDecl();
6647 };
6648 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
6649 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
6650
6651 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
6652}
6653
6654/// Emit casts from a PrimType to another PrimType.
6655template <class Emitter>
6656bool Compiler<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT,
6657 QualType ToQT, const Expr *E) {
6658
6659 if (FromT == PT_Float) {
6660 // Floating to floating.
6661 if (ToT == PT_Float) {
6662 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(T: ToQT);
6663 return this->emitCastFP(ToSem, getRoundingMode(E), E);
6664 }
6665
6666 if (ToT == PT_IntAP)
6667 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(T: ToQT),
6668 getFPOptions(E), E);
6669 if (ToT == PT_IntAPS)
6670 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(T: ToQT),
6671 getFPOptions(E), E);
6672
6673 // Float to integral.
6674 if (isIntegralType(T: ToT) || ToT == PT_Bool)
6675 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
6676 }
6677
6678 if (isIntegralType(T: FromT) || FromT == PT_Bool) {
6679 if (ToT == PT_IntAP)
6680 return this->emitCastAP(FromT, Ctx.getBitWidth(T: ToQT), E);
6681 if (ToT == PT_IntAPS)
6682 return this->emitCastAPS(FromT, Ctx.getBitWidth(T: ToQT), E);
6683
6684 // Integral to integral.
6685 if (isIntegralType(T: ToT) || ToT == PT_Bool)
6686 return FromT != ToT ? this->emitCast(FromT, ToT, E) : true;
6687
6688 if (ToT == PT_Float) {
6689 // Integral to floating.
6690 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(T: ToQT);
6691 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E);
6692 }
6693 }
6694
6695 return false;
6696}
6697
6698/// Emits __real(SubExpr)
6699template <class Emitter>
6700bool Compiler<Emitter>::emitComplexReal(const Expr *SubExpr) {
6701 assert(SubExpr->getType()->isAnyComplexType());
6702
6703 if (DiscardResult)
6704 return this->discard(SubExpr);
6705
6706 if (!this->visit(SubExpr))
6707 return false;
6708 if (SubExpr->isLValue()) {
6709 if (!this->emitConstUint8(0, SubExpr))
6710 return false;
6711 return this->emitArrayElemPtrPopUint8(SubExpr);
6712 }
6713
6714 // Rvalue, load the actual element.
6715 return this->emitArrayElemPop(classifyComplexElementType(T: SubExpr->getType()),
6716 0, SubExpr);
6717}
6718
6719template <class Emitter>
6720bool Compiler<Emitter>::emitComplexBoolCast(const Expr *E) {
6721 assert(!DiscardResult);
6722 PrimType ElemT = classifyComplexElementType(T: E->getType());
6723 // We emit the expression (__real(E) != 0 || __imag(E) != 0)
6724 // for us, that means (bool)E[0] || (bool)E[1]
6725 if (!this->emitArrayElem(ElemT, 0, E))
6726 return false;
6727 if (ElemT == PT_Float) {
6728 if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
6729 return false;
6730 } else {
6731 if (!this->emitCast(ElemT, PT_Bool, E))
6732 return false;
6733 }
6734
6735 // We now have the bool value of E[0] on the stack.
6736 LabelTy LabelTrue = this->getLabel();
6737 if (!this->jumpTrue(LabelTrue))
6738 return false;
6739
6740 if (!this->emitArrayElemPop(ElemT, 1, E))
6741 return false;
6742 if (ElemT == PT_Float) {
6743 if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
6744 return false;
6745 } else {
6746 if (!this->emitCast(ElemT, PT_Bool, E))
6747 return false;
6748 }
6749 // Leave the boolean value of E[1] on the stack.
6750 LabelTy EndLabel = this->getLabel();
6751 this->jump(EndLabel);
6752
6753 this->emitLabel(LabelTrue);
6754 if (!this->emitPopPtr(E))
6755 return false;
6756 if (!this->emitConstBool(true, E))
6757 return false;
6758
6759 this->fallthrough(EndLabel);
6760 this->emitLabel(EndLabel);
6761
6762 return true;
6763}
6764
6765template <class Emitter>
6766bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS,
6767 const BinaryOperator *E) {
6768 assert(E->isComparisonOp());
6769 assert(!Initializing);
6770 assert(!DiscardResult);
6771
6772 PrimType ElemT;
6773 bool LHSIsComplex;
6774 unsigned LHSOffset;
6775 if (LHS->getType()->isAnyComplexType()) {
6776 LHSIsComplex = true;
6777 ElemT = classifyComplexElementType(T: LHS->getType());
6778 LHSOffset = allocateLocalPrimitive(Src: LHS, Ty: PT_Ptr, /*IsConst=*/true);
6779 if (!this->visit(LHS))
6780 return false;
6781 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
6782 return false;
6783 } else {
6784 LHSIsComplex = false;
6785 PrimType LHST = classifyPrim(LHS->getType());
6786 LHSOffset = this->allocateLocalPrimitive(LHS, LHST, /*IsConst=*/true);
6787 if (!this->visit(LHS))
6788 return false;
6789 if (!this->emitSetLocal(LHST, LHSOffset, E))
6790 return false;
6791 }
6792
6793 bool RHSIsComplex;
6794 unsigned RHSOffset;
6795 if (RHS->getType()->isAnyComplexType()) {
6796 RHSIsComplex = true;
6797 ElemT = classifyComplexElementType(T: RHS->getType());
6798 RHSOffset = allocateLocalPrimitive(Src: RHS, Ty: PT_Ptr, /*IsConst=*/true);
6799 if (!this->visit(RHS))
6800 return false;
6801 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
6802 return false;
6803 } else {
6804 RHSIsComplex = false;
6805 PrimType RHST = classifyPrim(RHS->getType());
6806 RHSOffset = this->allocateLocalPrimitive(RHS, RHST, /*IsConst=*/true);
6807 if (!this->visit(RHS))
6808 return false;
6809 if (!this->emitSetLocal(RHST, RHSOffset, E))
6810 return false;
6811 }
6812
6813 auto getElem = [&](unsigned LocalOffset, unsigned Index,
6814 bool IsComplex) -> bool {
6815 if (IsComplex) {
6816 if (!this->emitGetLocal(PT_Ptr, LocalOffset, E))
6817 return false;
6818 return this->emitArrayElemPop(ElemT, Index, E);
6819 }
6820 return this->emitGetLocal(ElemT, LocalOffset, E);
6821 };
6822
6823 for (unsigned I = 0; I != 2; ++I) {
6824 // Get both values.
6825 if (!getElem(LHSOffset, I, LHSIsComplex))
6826 return false;
6827 if (!getElem(RHSOffset, I, RHSIsComplex))
6828 return false;
6829 // And compare them.
6830 if (!this->emitEQ(ElemT, E))
6831 return false;
6832
6833 if (!this->emitCastBoolUint8(E))
6834 return false;
6835 }
6836
6837 // We now have two bool values on the stack. Compare those.
6838 if (!this->emitAddUint8(E))
6839 return false;
6840 if (!this->emitConstUint8(2, E))
6841 return false;
6842
6843 if (E->getOpcode() == BO_EQ) {
6844 if (!this->emitEQUint8(E))
6845 return false;
6846 } else if (E->getOpcode() == BO_NE) {
6847 if (!this->emitNEUint8(E))
6848 return false;
6849 } else
6850 return false;
6851
6852 // In C, this returns an int.
6853 if (PrimType ResT = classifyPrim(E->getType()); ResT != PT_Bool)
6854 return this->emitCast(PT_Bool, ResT, E);
6855 return true;
6856}
6857
6858/// When calling this, we have a pointer of the local-to-destroy
6859/// on the stack.
6860/// Emit destruction of record types (or arrays of record types).
6861template <class Emitter>
6862bool Compiler<Emitter>::emitRecordDestruction(const Record *R, SourceInfo Loc) {
6863 assert(R);
6864 assert(!R->isAnonymousUnion());
6865 const CXXDestructorDecl *Dtor = R->getDestructor();
6866 if (!Dtor || Dtor->isTrivial())
6867 return true;
6868
6869 assert(Dtor);
6870 const Function *DtorFunc = getFunction(FD: Dtor);
6871 if (!DtorFunc)
6872 return false;
6873 assert(DtorFunc->hasThisPointer());
6874 assert(DtorFunc->getNumParams() == 1);
6875 if (!this->emitDupPtr(Loc))
6876 return false;
6877 return this->emitCall(DtorFunc, 0, Loc);
6878}
6879/// When calling this, we have a pointer of the local-to-destroy
6880/// on the stack.
6881/// Emit destruction of record types (or arrays of record types).
6882template <class Emitter>
6883bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc,
6884 SourceInfo Loc) {
6885 assert(Desc);
6886 assert(!Desc->isPrimitive());
6887 assert(!Desc->isPrimitiveArray());
6888
6889 // Can happen if the decl is invalid.
6890 if (Desc->isDummy())
6891 return true;
6892
6893 // Arrays.
6894 if (Desc->isArray()) {
6895 const Descriptor *ElemDesc = Desc->ElemDesc;
6896 assert(ElemDesc);
6897
6898 // Don't need to do anything for these.
6899 if (ElemDesc->isPrimitiveArray())
6900 return true;
6901
6902 // If this is an array of record types, check if we need
6903 // to call the element destructors at all. If not, try
6904 // to save the work.
6905 if (const Record *ElemRecord = ElemDesc->ElemRecord) {
6906 if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
6907 !Dtor || Dtor->isTrivial())
6908 return true;
6909 }
6910
6911 if (unsigned N = Desc->getNumElems()) {
6912 for (ssize_t I = N - 1; I >= 0; --I) {
6913 if (!this->emitConstUint64(I, Loc))
6914 return false;
6915 if (!this->emitArrayElemPtrUint64(Loc))
6916 return false;
6917 if (!this->emitDestruction(ElemDesc, Loc))
6918 return false;
6919 if (!this->emitPopPtr(Loc))
6920 return false;
6921 }
6922 }
6923 return true;
6924 }
6925
6926 assert(Desc->ElemRecord);
6927 if (Desc->ElemRecord->isAnonymousUnion())
6928 return true;
6929
6930 return this->emitRecordDestruction(Desc->ElemRecord, Loc);
6931}
6932
6933/// Create a dummy pointer for the given decl (or expr) and
6934/// push a pointer to it on the stack.
6935template <class Emitter>
6936bool Compiler<Emitter>::emitDummyPtr(const DeclTy &D, const Expr *E) {
6937 assert(!DiscardResult && "Should've been checked before");
6938
6939 unsigned DummyID = P.getOrCreateDummy(D);
6940
6941 if (!this->emitGetPtrGlobal(DummyID, E))
6942 return false;
6943 if (E->getType()->isVoidType())
6944 return true;
6945
6946 // Convert the dummy pointer to another pointer type if we have to.
6947 if (PrimType PT = classifyPrim(E); PT != PT_Ptr) {
6948 if (isPtrType(T: PT))
6949 return this->emitDecayPtr(PT_Ptr, PT, E);
6950 return false;
6951 }
6952 return true;
6953}
6954
6955template <class Emitter>
6956bool Compiler<Emitter>::emitFloat(const APFloat &F, const Expr *E) {
6957 assert(!DiscardResult && "Should've been checked before");
6958
6959 if (Floating::singleWord(F.getSemantics()))
6960 return this->emitConstFloat(Floating(F), E);
6961
6962 APInt I = F.bitcastToAPInt();
6963 return this->emitConstFloat(
6964 Floating(const_cast<uint64_t *>(I.getRawData()),
6965 llvm::APFloatBase::SemanticsToEnum(Sem: F.getSemantics())),
6966 E);
6967}
6968
6969// This function is constexpr if and only if To, From, and the types of
6970// all subobjects of To and From are types T such that...
6971// (3.1) - is_union_v<T> is false;
6972// (3.2) - is_pointer_v<T> is false;
6973// (3.3) - is_member_pointer_v<T> is false;
6974// (3.4) - is_volatile_v<T> is false; and
6975// (3.5) - T has no non-static data members of reference type
6976template <class Emitter>
6977bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) {
6978 const Expr *SubExpr = E->getSubExpr();
6979 QualType FromType = SubExpr->getType();
6980 QualType ToType = E->getType();
6981 std::optional<PrimType> ToT = classify(ToType);
6982
6983 assert(!ToType->isReferenceType());
6984
6985 // Prepare storage for the result in case we discard.
6986 if (DiscardResult && !Initializing && !ToT) {
6987 std::optional<unsigned> LocalIndex = allocateLocal(Src: E);
6988 if (!LocalIndex)
6989 return false;
6990 if (!this->emitGetPtrLocal(*LocalIndex, E))
6991 return false;
6992 }
6993
6994 // Get a pointer to the value-to-cast on the stack.
6995 // For CK_LValueToRValueBitCast, this is always an lvalue and
6996 // we later assume it to be one (i.e. a PT_Ptr). However,
6997 // we call this function for other utility methods where
6998 // a bitcast might be useful, so convert it to a PT_Ptr in that case.
6999 if (SubExpr->isGLValue() || FromType->isVectorType()) {
7000 if (!this->visit(SubExpr))
7001 return false;
7002 } else if (std::optional<PrimType> FromT = classify(SubExpr)) {
7003 unsigned TempOffset =
7004 allocateLocalPrimitive(Src: SubExpr, Ty: *FromT, /*IsConst=*/true);
7005 if (!this->visit(SubExpr))
7006 return false;
7007 if (!this->emitSetLocal(*FromT, TempOffset, E))
7008 return false;
7009 if (!this->emitGetPtrLocal(TempOffset, E))
7010 return false;
7011 } else {
7012 return false;
7013 }
7014
7015 if (!ToT) {
7016 if (!this->emitBitCast(E))
7017 return false;
7018 return DiscardResult ? this->emitPopPtr(E) : true;
7019 }
7020 assert(ToT);
7021
7022 const llvm::fltSemantics *TargetSemantics = nullptr;
7023 if (ToT == PT_Float)
7024 TargetSemantics = &Ctx.getFloatSemantics(T: ToType);
7025
7026 // Conversion to a primitive type. FromType can be another
7027 // primitive type, or a record/array.
7028 bool ToTypeIsUChar = (ToType->isSpecificBuiltinType(K: BuiltinType::UChar) ||
7029 ToType->isSpecificBuiltinType(K: BuiltinType::Char_U));
7030 uint32_t ResultBitWidth = std::max(a: Ctx.getBitWidth(T: ToType), b: 8u);
7031
7032 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->isStdByteType(),
7033 ResultBitWidth, TargetSemantics, E))
7034 return false;
7035
7036 if (DiscardResult)
7037 return this->emitPop(*ToT, E);
7038
7039 return true;
7040}
7041
7042namespace clang {
7043namespace interp {
7044
7045template class Compiler<ByteCodeEmitter>;
7046template class Compiler<EvalEmitter>;
7047
7048} // namespace interp
7049} // namespace clang
7050