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