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 const Type *TypeInfoType = E->getType().getTypePtr();
3432
3433 if (!E->isPotentiallyEvaluated()) {
3434 if (DiscardResult)
3435 return true;
3436
3437 if (E->isTypeOperand())
3438 return this->emitGetTypeid(
3439 E->getTypeOperand(Ctx.getASTContext()).getTypePtr(), TypeInfoType, E);
3440 return this->emitGetTypeid(E->getExprOperand()->getType().getTypePtr(),
3441 TypeInfoType, E);
3442 }
3443
3444 // Otherwise, we need to evaluate the expression operand.
3445 assert(E->getExprOperand());
3446 assert(E->getExprOperand()->isLValue());
3447
3448 if (!Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(E))
3449 return false;
3450
3451 if (!this->visit(E->getExprOperand()))
3452 return false;
3453
3454 if (!this->emitGetTypeidPtr(TypeInfoType, E))
3455 return false;
3456 if (DiscardResult)
3457 return this->emitPopPtr(E);
3458 return true;
3459}
3460
3461template <class Emitter>
3463 assert(Ctx.getLangOpts().CPlusPlus);
3464 return this->emitConstBool(E->getValue(), E);
3465}
3466
3467template <class Emitter>
3469 if (DiscardResult)
3470 return true;
3471 assert(!Initializing);
3472
3473 const MSGuidDecl *GuidDecl = E->getGuidDecl();
3474 const RecordDecl *RD = GuidDecl->getType()->getAsRecordDecl();
3475 assert(RD);
3476 // If the definiton of the result type is incomplete, just return a dummy.
3477 // If (and when) that is read from, we will fail, but not now.
3478 if (!RD->isCompleteDefinition())
3479 return this->emitDummyPtr(GuidDecl, E);
3480
3481 std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(GuidDecl);
3482 if (!GlobalIndex)
3483 return false;
3484 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3485 return false;
3486
3487 assert(this->getRecord(E->getType()));
3488
3489 const APValue &V = GuidDecl->getAsAPValue();
3490 if (V.getKind() == APValue::None)
3491 return true;
3492
3493 assert(V.isStruct());
3494 assert(V.getStructNumBases() == 0);
3495 if (!this->visitAPValueInitializer(V, E))
3496 return false;
3497
3498 return this->emitFinishInit(E);
3499}
3500
3501template <class Emitter>
3503 assert(classifyPrim(E->getType()) == PT_Bool);
3504 if (DiscardResult)
3505 return true;
3506 return this->emitConstBool(E->isSatisfied(), E);
3507}
3508
3509template <class Emitter>
3512 assert(classifyPrim(E->getType()) == PT_Bool);
3513 if (DiscardResult)
3514 return true;
3515 return this->emitConstBool(E->isSatisfied(), E);
3516}
3517
3518template <class Emitter>
3521 return this->delegate(E->getSemanticForm());
3522}
3523
3524template <class Emitter>
3526
3527 for (const Expr *SemE : E->semantics()) {
3528 if (auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
3529 if (SemE == E->getResultExpr())
3530 return false;
3531
3532 if (OVE->isUnique())
3533 continue;
3534
3535 if (!this->discard(OVE))
3536 return false;
3537 } else if (SemE == E->getResultExpr()) {
3538 if (!this->delegate(SemE))
3539 return false;
3540 } else {
3541 if (!this->discard(SemE))
3542 return false;
3543 }
3544 }
3545 return true;
3546}
3547
3548template <class Emitter>
3550 return this->delegate(E->getSelectedExpr());
3551}
3552
3553template <class Emitter>
3555 return this->emitError(E);
3556}
3557
3558template <class Emitter>
3560 assert(E->getType()->isVoidPointerType());
3561
3562 unsigned Offset = allocateLocalPrimitive(
3563 E->getLabel(), PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false);
3564
3565 return this->emitGetLocal(PT_Ptr, Offset, E);
3566}
3567
3568template <class Emitter>
3570 assert(Initializing);
3571 const auto *VT = E->getType()->castAs<VectorType>();
3572 QualType ElemType = VT->getElementType();
3573 PrimType ElemT = classifyPrim(ElemType);
3574 const Expr *Src = E->getSrcExpr();
3575 QualType SrcType = Src->getType();
3576 PrimType SrcElemT = classifyVectorElementType(SrcType);
3577
3578 unsigned SrcOffset = this->allocateLocalPrimitive(Src, PT_Ptr, true, false);
3579 if (!this->visit(Src))
3580 return false;
3581 if (!this->emitSetLocal(PT_Ptr, SrcOffset, E))
3582 return false;
3583
3584 for (unsigned I = 0; I != VT->getNumElements(); ++I) {
3585 if (!this->emitGetLocal(PT_Ptr, SrcOffset, E))
3586 return false;
3587 if (!this->emitArrayElemPop(SrcElemT, I, E))
3588 return false;
3589
3590 // Cast to the desired result element type.
3591 if (SrcElemT != ElemT) {
3592 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
3593 return false;
3594 } else if (ElemType->isFloatingType() && SrcType != ElemType) {
3595 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
3596 if (!this->emitCastFP(TargetSemantics, getRoundingMode(E), E))
3597 return false;
3598 }
3599 if (!this->emitInitElem(ElemT, I, E))
3600 return false;
3601 }
3602
3603 return true;
3604}
3605
3606template <class Emitter>
3608 assert(Initializing);
3609 assert(E->getNumSubExprs() > 2);
3610
3611 const Expr *Vecs[] = {E->getExpr(0), E->getExpr(1)};
3612 const VectorType *VT = Vecs[0]->getType()->castAs<VectorType>();
3613 PrimType ElemT = classifyPrim(VT->getElementType());
3614 unsigned NumInputElems = VT->getNumElements();
3615 unsigned NumOutputElems = E->getNumSubExprs() - 2;
3616 assert(NumOutputElems > 0);
3617
3618 // Save both input vectors to a local variable.
3619 unsigned VectorOffsets[2];
3620 for (unsigned I = 0; I != 2; ++I) {
3621 VectorOffsets[I] = this->allocateLocalPrimitive(
3622 Vecs[I], PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false);
3623 if (!this->visit(Vecs[I]))
3624 return false;
3625 if (!this->emitSetLocal(PT_Ptr, VectorOffsets[I], E))
3626 return false;
3627 }
3628 for (unsigned I = 0; I != NumOutputElems; ++I) {
3629 APSInt ShuffleIndex = E->getShuffleMaskIdx(Ctx.getASTContext(), I);
3630 assert(ShuffleIndex >= -1);
3631 if (ShuffleIndex == -1)
3632 return this->emitInvalidShuffleVectorIndex(I, E);
3633
3634 assert(ShuffleIndex < (NumInputElems * 2));
3635 if (!this->emitGetLocal(PT_Ptr,
3636 VectorOffsets[ShuffleIndex >= NumInputElems], E))
3637 return false;
3638 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
3639 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
3640 return false;
3641
3642 if (!this->emitInitElem(ElemT, I, E))
3643 return false;
3644 }
3645
3646 return true;
3647}
3648
3649template <class Emitter>
3651 const ExtVectorElementExpr *E) {
3652 const Expr *Base = E->getBase();
3653 assert(
3654 Base->getType()->isVectorType() ||
3655 Base->getType()->getAs<PointerType>()->getPointeeType()->isVectorType());
3656
3658 E->getEncodedElementAccess(Indices);
3659
3660 if (Indices.size() == 1) {
3661 if (!this->visit(Base))
3662 return false;
3663
3664 if (E->isGLValue()) {
3665 if (!this->emitConstUint32(Indices[0], E))
3666 return false;
3667 return this->emitArrayElemPtrPop(PT_Uint32, E);
3668 }
3669 // Else, also load the value.
3670 return this->emitArrayElemPop(classifyPrim(E->getType()), Indices[0], E);
3671 }
3672
3673 // Create a local variable for the base.
3674 unsigned BaseOffset = allocateLocalPrimitive(Base, PT_Ptr, /*IsConst=*/true,
3675 /*IsExtended=*/false);
3676 if (!this->visit(Base))
3677 return false;
3678 if (!this->emitSetLocal(PT_Ptr, BaseOffset, E))
3679 return false;
3680
3681 // Now the vector variable for the return value.
3682 if (!Initializing) {
3683 std::optional<unsigned> ResultIndex;
3684 ResultIndex = allocateLocal(E);
3685 if (!ResultIndex)
3686 return false;
3687 if (!this->emitGetPtrLocal(*ResultIndex, E))
3688 return false;
3689 }
3690
3691 assert(Indices.size() == E->getType()->getAs<VectorType>()->getNumElements());
3692
3693 PrimType ElemT =
3694 classifyPrim(E->getType()->getAs<VectorType>()->getElementType());
3695 uint32_t DstIndex = 0;
3696 for (uint32_t I : Indices) {
3697 if (!this->emitGetLocal(PT_Ptr, BaseOffset, E))
3698 return false;
3699 if (!this->emitArrayElemPop(ElemT, I, E))
3700 return false;
3701 if (!this->emitInitElem(ElemT, DstIndex, E))
3702 return false;
3703 ++DstIndex;
3704 }
3705
3706 // Leave the result pointer on the stack.
3707 assert(!DiscardResult);
3708 return true;
3709}
3710
3711template <class Emitter>
3713 const Expr *SubExpr = E->getSubExpr();
3714 if (!E->isExpressibleAsConstantInitializer())
3715 return this->discard(SubExpr) && this->emitInvalid(E);
3716
3717 if (DiscardResult)
3718 return true;
3719
3720 assert(classifyPrim(E) == PT_Ptr);
3721 return this->emitDummyPtr(E, E);
3722}
3723
3724template <class Emitter>
3727 const Expr *SubExpr = E->getSubExpr();
3729 Ctx.getASTContext().getAsConstantArrayType(SubExpr->getType());
3730 const Record *R = getRecord(E->getType());
3731 assert(Initializing);
3732 assert(SubExpr->isGLValue());
3733
3734 if (!this->visit(SubExpr))
3735 return false;
3736 if (!this->emitConstUint8(0, E))
3737 return false;
3738 if (!this->emitArrayElemPtrPopUint8(E))
3739 return false;
3740 if (!this->emitInitFieldPtr(R->getField(0u)->Offset, E))
3741 return false;
3742
3743 PrimType SecondFieldT = classifyPrim(R->getField(1u)->Decl->getType());
3744 if (isIntegralType(SecondFieldT)) {
3745 if (!this->emitConst(static_cast<APSInt>(ArrayType->getSize()),
3746 SecondFieldT, E))
3747 return false;
3748 return this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E);
3749 }
3750 assert(SecondFieldT == PT_Ptr);
3751
3752 if (!this->emitGetFieldPtr(R->getField(0u)->Offset, E))
3753 return false;
3754 if (!this->emitExpandPtr(E))
3755 return false;
3756 if (!this->emitConst(static_cast<APSInt>(ArrayType->getSize()), PT_Uint64, E))
3757 return false;
3758 if (!this->emitArrayElemPtrPop(PT_Uint64, E))
3759 return false;
3760 return this->emitInitFieldPtr(R->getField(1u)->Offset, E);
3761}
3762
3763template <class Emitter>
3765 BlockScope<Emitter> BS(this);
3766 StmtExprScope<Emitter> SS(this);
3767
3768 const CompoundStmt *CS = E->getSubStmt();
3769 const Stmt *Result = CS->getStmtExprResult();
3770 for (const Stmt *S : CS->body()) {
3771 if (S != Result) {
3772 if (!this->visitStmt(S))
3773 return false;
3774 continue;
3775 }
3776
3777 assert(S == Result);
3778 if (const Expr *ResultExpr = dyn_cast<Expr>(S))
3779 return this->delegate(ResultExpr);
3780 return this->emitUnsupported(E);
3781 }
3782
3783 return BS.destroyLocals();
3784}
3785
3786template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {
3787 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
3788 /*NewInitializing=*/false);
3789 return this->Visit(E);
3790}
3791
3792template <class Emitter> bool Compiler<Emitter>::delegate(const Expr *E) {
3793 // We're basically doing:
3794 // OptionScope<Emitter> Scope(this, DicardResult, Initializing);
3795 // but that's unnecessary of course.
3796 return this->Visit(E);
3797}
3798
3799template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) {
3800 if (E->getType().isNull())
3801 return false;
3802
3803 if (E->getType()->isVoidType())
3804 return this->discard(E);
3805
3806 // Create local variable to hold the return value.
3807 if (!E->isGLValue() && !E->getType()->isAnyComplexType() &&
3808 !classify(E->getType())) {
3809 std::optional<unsigned> LocalIndex = allocateLocal(E);
3810 if (!LocalIndex)
3811 return false;
3812
3813 if (!this->emitGetPtrLocal(*LocalIndex, E))
3814 return false;
3815 return this->visitInitializer(E);
3816 }
3817
3818 // Otherwise,we have a primitive return value, produce the value directly
3819 // and push it on the stack.
3820 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
3821 /*NewInitializing=*/false);
3822 return this->Visit(E);
3823}
3824
3825template <class Emitter>
3827 assert(!classify(E->getType()));
3828
3829 OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
3830 /*NewInitializing=*/true);
3831 return this->Visit(E);
3832}
3833
3834template <class Emitter> bool Compiler<Emitter>::visitBool(const Expr *E) {
3835 std::optional<PrimType> T = classify(E->getType());
3836 if (!T) {
3837 // Convert complex values to bool.
3838 if (E->getType()->isAnyComplexType()) {
3839 if (!this->visit(E))
3840 return false;
3841 return this->emitComplexBoolCast(E);
3842 }
3843 return false;
3844 }
3845
3846 if (!this->visit(E))
3847 return false;
3848
3849 if (T == PT_Bool)
3850 return true;
3851
3852 // Convert pointers to bool.
3853 if (T == PT_Ptr || T == PT_FnPtr) {
3854 if (!this->emitNull(*T, 0, nullptr, E))
3855 return false;
3856 return this->emitNE(*T, E);
3857 }
3858
3859 // Or Floats.
3860 if (T == PT_Float)
3861 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
3862
3863 // Or anything else we can.
3864 return this->emitCast(*T, PT_Bool, E);
3865}
3866
3867template <class Emitter>
3869 const Expr *E) {
3870 switch (T) {
3871 case PT_Bool:
3872 return this->emitZeroBool(E);
3873 case PT_Sint8:
3874 return this->emitZeroSint8(E);
3875 case PT_Uint8:
3876 return this->emitZeroUint8(E);
3877 case PT_Sint16:
3878 return this->emitZeroSint16(E);
3879 case PT_Uint16:
3880 return this->emitZeroUint16(E);
3881 case PT_Sint32:
3882 return this->emitZeroSint32(E);
3883 case PT_Uint32:
3884 return this->emitZeroUint32(E);
3885 case PT_Sint64:
3886 return this->emitZeroSint64(E);
3887 case PT_Uint64:
3888 return this->emitZeroUint64(E);
3889 case PT_IntAP:
3890 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
3891 case PT_IntAPS:
3892 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
3893 case PT_Ptr:
3894 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
3895 nullptr, E);
3896 case PT_FnPtr:
3897 return this->emitNullFnPtr(0, nullptr, E);
3898 case PT_MemberPtr:
3899 return this->emitNullMemberPtr(0, nullptr, E);
3900 case PT_Float:
3901 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E);
3902 case PT_FixedPoint: {
3903 auto Sem = Ctx.getASTContext().getFixedPointSemantics(E->getType());
3904 return this->emitConstFixedPoint(FixedPoint::zero(Sem), E);
3905 }
3906 llvm_unreachable("Implement");
3907 }
3908 llvm_unreachable("unknown primitive type");
3909}
3910
3911template <class Emitter>
3913 const Expr *E) {
3914 assert(E);
3915 assert(R);
3916 // Fields
3917 for (const Record::Field &Field : R->fields()) {
3918 if (Field.Decl->isUnnamedBitField())
3919 continue;
3920
3921 const Descriptor *D = Field.Desc;
3922 if (D->isPrimitive()) {
3923 QualType QT = D->getType();
3924 PrimType T = classifyPrim(D->getType());
3925 if (!this->visitZeroInitializer(T, QT, E))
3926 return false;
3927 if (!this->emitInitField(T, Field.Offset, E))
3928 return false;
3929 if (R->isUnion())
3930 break;
3931 continue;
3932 }
3933
3934 if (!this->emitGetPtrField(Field.Offset, E))
3935 return false;
3936
3937 if (D->isPrimitiveArray()) {
3938 QualType ET = D->getElemQualType();
3939 PrimType T = classifyPrim(ET);
3940 for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
3941 if (!this->visitZeroInitializer(T, ET, E))
3942 return false;
3943 if (!this->emitInitElem(T, I, E))
3944 return false;
3945 }
3946 } else if (D->isCompositeArray()) {
3947 // Can't be a vector or complex field.
3948 if (!this->visitZeroArrayInitializer(D->getType(), E))
3949 return false;
3950 } else if (D->isRecord()) {
3951 if (!this->visitZeroRecordInitializer(D->ElemRecord, E))
3952 return false;
3953 } else {
3954 assert(false);
3955 }
3956
3957 if (!this->emitFinishInitPop(E))
3958 return false;
3959
3960 // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the
3961 // object's first non-static named data member is zero-initialized
3962 if (R->isUnion())
3963 break;
3964 }
3965
3966 for (const Record::Base &B : R->bases()) {
3967 if (!this->emitGetPtrBase(B.Offset, E))
3968 return false;
3969 if (!this->visitZeroRecordInitializer(B.R, E))
3970 return false;
3971 if (!this->emitFinishInitPop(E))
3972 return false;
3973 }
3974
3975 // FIXME: Virtual bases.
3976
3977 return true;
3978}
3979
3980template <class Emitter>
3982 assert(T->isArrayType() || T->isAnyComplexType() || T->isVectorType());
3983 const ArrayType *AT = T->getAsArrayTypeUnsafe();
3984 QualType ElemType = AT->getElementType();
3985 size_t NumElems = cast<ConstantArrayType>(AT)->getZExtSize();
3986
3987 if (std::optional<PrimType> ElemT = classify(ElemType)) {
3988 for (size_t I = 0; I != NumElems; ++I) {
3989 if (!this->visitZeroInitializer(*ElemT, ElemType, E))
3990 return false;
3991 if (!this->emitInitElem(*ElemT, I, E))
3992 return false;
3993 }
3994 return true;
3995 } else if (ElemType->isRecordType()) {
3996 const Record *R = getRecord(ElemType);
3997
3998 for (size_t I = 0; I != NumElems; ++I) {
3999 if (!this->emitConstUint32(I, E))
4000 return false;
4001 if (!this->emitArrayElemPtr(PT_Uint32, E))
4002 return false;
4003 if (!this->visitZeroRecordInitializer(R, E))
4004 return false;
4005 if (!this->emitPopPtr(E))
4006 return false;
4007 }
4008 return true;
4009 } else if (ElemType->isArrayType()) {
4010 for (size_t I = 0; I != NumElems; ++I) {
4011 if (!this->emitConstUint32(I, E))
4012 return false;
4013 if (!this->emitArrayElemPtr(PT_Uint32, E))
4014 return false;
4015 if (!this->visitZeroArrayInitializer(ElemType, E))
4016 return false;
4017 if (!this->emitPopPtr(E))
4018 return false;
4019 }
4020 return true;
4021 }
4022
4023 return false;
4024}
4025
4026template <class Emitter>
4027template <typename T>
4029 switch (Ty) {
4030 case PT_Sint8:
4031 return this->emitConstSint8(Value, E);
4032 case PT_Uint8:
4033 return this->emitConstUint8(Value, E);
4034 case PT_Sint16:
4035 return this->emitConstSint16(Value, E);
4036 case PT_Uint16:
4037 return this->emitConstUint16(Value, E);
4038 case PT_Sint32:
4039 return this->emitConstSint32(Value, E);
4040 case PT_Uint32:
4041 return this->emitConstUint32(Value, E);
4042 case PT_Sint64:
4043 return this->emitConstSint64(Value, E);
4044 case PT_Uint64:
4045 return this->emitConstUint64(Value, E);
4046 case PT_Bool:
4047 return this->emitConstBool(Value, E);
4048 case PT_Ptr:
4049 case PT_FnPtr:
4050 case PT_MemberPtr:
4051 case PT_Float:
4052 case PT_IntAP:
4053 case PT_IntAPS:
4054 case PT_FixedPoint:
4055 llvm_unreachable("Invalid integral type");
4056 break;
4057 }
4058 llvm_unreachable("unknown primitive type");
4059}
4060
4061template <class Emitter>
4062template <typename T>
4064 return this->emitConst(Value, classifyPrim(E->getType()), E);
4065}
4066
4067template <class Emitter>
4069 const Expr *E) {
4070 if (Ty == PT_IntAPS)
4071 return this->emitConstIntAPS(Value, E);
4072 if (Ty == PT_IntAP)
4073 return this->emitConstIntAP(Value, E);
4074
4075 if (Value.isSigned())
4076 return this->emitConst(Value.getSExtValue(), Ty, E);
4077 return this->emitConst(Value.getZExtValue(), Ty, E);
4078}
4079
4080template <class Emitter>
4081bool Compiler<Emitter>::emitConst(const APSInt &Value, const Expr *E) {
4082 return this->emitConst(Value, classifyPrim(E->getType()), E);
4083}
4084
4085template <class Emitter>
4087 bool IsConst,
4088 bool IsExtended) {
4089 // Make sure we don't accidentally register the same decl twice.
4090 if (const auto *VD =
4091 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
4092 assert(!P.getGlobal(VD));
4093 assert(!Locals.contains(VD));
4094 (void)VD;
4095 }
4096
4097 // FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
4098 // (int){12} in C. Consider using Expr::isTemporaryObject() instead
4099 // or isa<MaterializeTemporaryExpr>().
4100 Descriptor *D = P.createDescriptor(Src, Ty, Descriptor::InlineDescMD, IsConst,
4101 isa<const Expr *>(Src));
4102 Scope::Local Local = this->createLocal(D);
4103 if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>()))
4104 Locals.insert({VD, Local});
4105 VarScope->add(Local, IsExtended);
4106 return Local.Offset;
4107}
4108
4109template <class Emitter>
4110std::optional<unsigned>
4112 const ValueDecl *ExtendingDecl) {
4113 // Make sure we don't accidentally register the same decl twice.
4114 if ([[maybe_unused]] const auto *VD =
4115 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
4116 assert(!P.getGlobal(VD));
4117 assert(!Locals.contains(VD));
4118 }
4119
4120 const ValueDecl *Key = nullptr;
4121 const Expr *Init = nullptr;
4122 bool IsTemporary = false;
4123 if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
4124 Key = VD;
4125 Ty = VD->getType();
4126
4127 if (const auto *VarD = dyn_cast<VarDecl>(VD))
4128 Init = VarD->getInit();
4129 }
4130 if (auto *E = Src.dyn_cast<const Expr *>()) {
4131 IsTemporary = true;
4132 if (Ty.isNull())
4133 Ty = E->getType();
4134 }
4135
4136 Descriptor *D = P.createDescriptor(
4138 IsTemporary, /*IsMutable=*/false, Init);
4139 if (!D)
4140 return std::nullopt;
4141
4142 Scope::Local Local = this->createLocal(D);
4143 if (Key)
4144 Locals.insert({Key, Local});
4145 if (ExtendingDecl)
4146 VarScope->addExtended(Local, ExtendingDecl);
4147 else
4148 VarScope->add(Local, false);
4149 return Local.Offset;
4150}
4151
4152template <class Emitter>
4154 QualType Ty = E->getType();
4155 assert(!Ty->isRecordType());
4156
4157 Descriptor *D = P.createDescriptor(
4159 /*IsTemporary=*/true, /*IsMutable=*/false, /*Init=*/nullptr);
4160 assert(D);
4161
4162 Scope::Local Local = this->createLocal(D);
4163 VariableScope<Emitter> *S = VarScope;
4164 assert(S);
4165 // Attach to topmost scope.
4166 while (S->getParent())
4167 S = S->getParent();
4168 assert(S && !S->getParent());
4169 S->addLocal(Local);
4170 return Local.Offset;
4171}
4172
4173template <class Emitter>
4175 if (const PointerType *PT = dyn_cast<PointerType>(Ty))
4176 return PT->getPointeeType()->getAs<RecordType>();
4177 return Ty->getAs<RecordType>();
4178}
4179
4180template <class Emitter> Record *Compiler<Emitter>::getRecord(QualType Ty) {
4181 if (const auto *RecordTy = getRecordTy(Ty))
4182 return getRecord(RecordTy->getDecl());
4183 return nullptr;
4184}
4185
4186template <class Emitter>
4188 return P.getOrCreateRecord(RD);
4189}
4190
4191template <class Emitter>
4193 return Ctx.getOrCreateFunction(FD);
4194}
4195
4196template <class Emitter>
4197bool Compiler<Emitter>::visitExpr(const Expr *E, bool DestroyToplevelScope) {
4198 LocalScope<Emitter> RootScope(this);
4199
4200 // If we won't destroy the toplevel scope, check for memory leaks first.
4201 if (!DestroyToplevelScope) {
4202 if (!this->emitCheckAllocations(E))
4203 return false;
4204 }
4205
4206 auto maybeDestroyLocals = [&]() -> bool {
4207 if (DestroyToplevelScope)
4208 return RootScope.destroyLocals() && this->emitCheckAllocations(E);
4209 return this->emitCheckAllocations(E);
4210 };
4211
4212 // Void expressions.
4213 if (E->getType()->isVoidType()) {
4214 if (!visit(E))
4215 return false;
4216 return this->emitRetVoid(E) && maybeDestroyLocals();
4217 }
4218
4219 // Expressions with a primitive return type.
4220 if (std::optional<PrimType> T = classify(E)) {
4221 if (!visit(E))
4222 return false;
4223
4224 return this->emitRet(*T, E) && maybeDestroyLocals();
4225 }
4226
4227 // Expressions with a composite return type.
4228 // For us, that means everything we don't
4229 // have a PrimType for.
4230 if (std::optional<unsigned> LocalOffset = this->allocateLocal(E)) {
4231 if (!this->emitGetPtrLocal(*LocalOffset, E))
4232 return false;
4233
4234 if (!visitInitializer(E))
4235 return false;
4236
4237 if (!this->emitFinishInit(E))
4238 return false;
4239 // We are destroying the locals AFTER the Ret op.
4240 // The Ret op needs to copy the (alive) values, but the
4241 // destructors may still turn the entire expression invalid.
4242 return this->emitRetValue(E) && maybeDestroyLocals();
4243 }
4244
4245 return maybeDestroyLocals() && this->emitCheckAllocations(E) && false;
4246}
4247
4248template <class Emitter>
4250
4251 auto R = this->visitVarDecl(VD, /*Toplevel=*/true);
4252
4253 if (R.notCreated())
4254 return R;
4255
4256 if (R)
4257 return true;
4258
4259 if (!R && Context::shouldBeGloballyIndexed(VD)) {
4260 if (auto GlobalIndex = P.getGlobal(VD)) {
4261 Block *GlobalBlock = P.getGlobal(*GlobalIndex);
4263 *reinterpret_cast<GlobalInlineDescriptor *>(GlobalBlock->rawData());
4264
4265 GD.InitState = GlobalInitState::InitializerFailed;
4266 GlobalBlock->invokeDtor();
4267 }
4268 }
4269
4270 return R;
4271}
4272
4273/// Toplevel visitDeclAndReturn().
4274/// We get here from evaluateAsInitializer().
4275/// We need to evaluate the initializer and return its value.
4276template <class Emitter>
4278 bool ConstantContext) {
4279 std::optional<PrimType> VarT = classify(VD->getType());
4280
4281 // We only create variables if we're evaluating in a constant context.
4282 // Otherwise, just evaluate the initializer and return it.
4283 if (!ConstantContext) {
4284 DeclScope<Emitter> LS(this, VD);
4285 if (!this->visit(VD->getAnyInitializer()))
4286 return false;
4287 return this->emitRet(VarT.value_or(PT_Ptr), VD) && LS.destroyLocals() &&
4288 this->emitCheckAllocations(VD);
4289 }
4290
4291 LocalScope<Emitter> VDScope(this, VD);
4292 if (!this->visitVarDecl(VD, /*Toplevel=*/true))
4293 return false;
4294
4296 auto GlobalIndex = P.getGlobal(VD);
4297 assert(GlobalIndex); // visitVarDecl() didn't return false.
4298 if (VarT) {
4299 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
4300 return false;
4301 } else {
4302 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
4303 return false;
4304 }
4305 } else {
4306 auto Local = Locals.find(VD);
4307 assert(Local != Locals.end()); // Same here.
4308 if (VarT) {
4309 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
4310 return false;
4311 } else {
4312 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
4313 return false;
4314 }
4315 }
4316
4317 // Return the value.
4318 if (!this->emitRet(VarT.value_or(PT_Ptr), VD)) {
4319 // If the Ret above failed and this is a global variable, mark it as
4320 // uninitialized, even everything else succeeded.
4322 auto GlobalIndex = P.getGlobal(VD);
4323 assert(GlobalIndex);
4324 Block *GlobalBlock = P.getGlobal(*GlobalIndex);
4326 *reinterpret_cast<GlobalInlineDescriptor *>(GlobalBlock->rawData());
4327
4328 GD.InitState = GlobalInitState::InitializerFailed;
4329 GlobalBlock->invokeDtor();
4330 }
4331 return false;
4332 }
4333
4334 return VDScope.destroyLocals() && this->emitCheckAllocations(VD);
4335}
4336
4337template <class Emitter>
4339 bool Toplevel) {
4340 // We don't know what to do with these, so just return false.
4341 if (VD->getType().isNull())
4342 return false;
4343
4344 // This case is EvalEmitter-only. If we won't create any instructions for the
4345 // initializer anyway, don't bother creating the variable in the first place.
4346 if (!this->isActive())
4348
4349 const Expr *Init = VD->getInit();
4350 std::optional<PrimType> VarT = classify(VD->getType());
4351
4352 if (Init && Init->isValueDependent())
4353 return false;
4354
4356 auto checkDecl = [&]() -> bool {
4357 bool NeedsOp = !Toplevel && VD->isLocalVarDecl() && VD->isStaticLocal();
4358 return !NeedsOp || this->emitCheckDecl(VD, VD);
4359 };
4360
4361 auto initGlobal = [&](unsigned GlobalIndex) -> bool {
4362 assert(Init);
4363
4364 if (VarT) {
4365 if (!this->visit(Init))
4366 return checkDecl() && false;
4367
4368 return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
4369 }
4370
4371 if (!checkDecl())
4372 return false;
4373
4374 if (!this->emitGetPtrGlobal(GlobalIndex, Init))
4375 return false;
4376
4377 if (!visitInitializer(Init))
4378 return false;
4379
4380 if (!this->emitFinishInit(Init))
4381 return false;
4382
4383 return this->emitPopPtr(Init);
4384 };
4385
4387
4388 // We've already seen and initialized this global.
4389 if (std::optional<unsigned> GlobalIndex = P.getGlobal(VD)) {
4390 if (P.getPtrGlobal(*GlobalIndex).isInitialized())
4391 return checkDecl();
4392
4393 // The previous attempt at initialization might've been unsuccessful,
4394 // so let's try this one.
4395 return Init && checkDecl() && initGlobal(*GlobalIndex);
4396 }
4397
4398 std::optional<unsigned> GlobalIndex = P.createGlobal(VD, Init);
4399
4400 if (!GlobalIndex)
4401 return false;
4402
4403 return !Init || (checkDecl() && initGlobal(*GlobalIndex));
4404 } else {
4406
4407 if (VarT) {
4408 unsigned Offset = this->allocateLocalPrimitive(
4409 VD, *VarT, VD->getType().isConstQualified());
4410 if (Init) {
4411 // If this is a toplevel declaration, create a scope for the
4412 // initializer.
4413 if (Toplevel) {
4415 if (!this->visit(Init))
4416 return false;
4417 return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals();
4418 } else {
4419 if (!this->visit(Init))
4420 return false;
4421 return this->emitSetLocal(*VarT, Offset, VD);
4422 }
4423 }
4424 } else {
4425 if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
4426 if (!Init)
4427 return true;
4428
4429 if (!this->emitGetPtrLocal(*Offset, Init))
4430 return false;
4431
4432 if (!visitInitializer(Init))
4433 return false;
4434
4435 if (!this->emitFinishInit(Init))
4436 return false;
4437
4438 return this->emitPopPtr(Init);
4439 }
4440 return false;
4441 }
4442 return true;
4443 }
4444
4445 return false;
4446}
4447
4448template <class Emitter>
4450 const Expr *E) {
4451 assert(!DiscardResult);
4452 if (Val.isInt())
4453 return this->emitConst(Val.getInt(), ValType, E);
4454 else if (Val.isFloat())
4455 return this->emitConstFloat(Val.getFloat(), E);
4456
4457 if (Val.isLValue()) {
4458 if (Val.isNullPointer())
4459 return this->emitNull(ValType, 0, nullptr, E);
4461 if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>())
4462 return this->visit(BaseExpr);
4463 else if (const auto *VD = Base.dyn_cast<const ValueDecl *>()) {
4464 return this->visitDeclRef(VD, E);
4465 }
4466 } else if (Val.isMemberPointer()) {
4467 if (const ValueDecl *MemberDecl = Val.getMemberPointerDecl())
4468 return this->emitGetMemberPtr(MemberDecl, E);
4469 return this->emitNullMemberPtr(0, nullptr, E);
4470 }
4471
4472 return false;
4473}
4474
4475template <class Emitter>
4477 const Expr *E) {
4478
4479 if (Val.isStruct()) {
4480 const Record *R = this->getRecord(E->getType());
4481 assert(R);
4482 for (unsigned I = 0, N = Val.getStructNumFields(); I != N; ++I) {
4483 const APValue &F = Val.getStructField(I);
4484 const Record::Field *RF = R->getField(I);
4485
4486 if (F.isInt() || F.isFloat() || F.isLValue() || F.isMemberPointer()) {
4487 PrimType T = classifyPrim(RF->Decl->getType());
4488 if (!this->visitAPValue(F, T, E))
4489 return false;
4490 if (!this->emitInitField(T, RF->Offset, E))
4491 return false;
4492 } else if (F.isArray()) {
4493 assert(RF->Desc->isPrimitiveArray());
4494 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
4495 PrimType ElemT = classifyPrim(ArrType->getElementType());
4496 assert(ArrType);
4497
4498 if (!this->emitGetPtrField(RF->Offset, E))
4499 return false;
4500
4501 for (unsigned A = 0, AN = F.getArraySize(); A != AN; ++A) {
4502 if (!this->visitAPValue(F.getArrayInitializedElt(A), ElemT, E))
4503 return false;
4504 if (!this->emitInitElem(ElemT, A, E))
4505 return false;
4506 }
4507
4508 if (!this->emitPopPtr(E))
4509 return false;
4510 } else if (F.isStruct() || F.isUnion()) {
4511 if (!this->emitGetPtrField(RF->Offset, E))
4512 return false;
4513 if (!this->visitAPValueInitializer(F, E))
4514 return false;
4515 if (!this->emitPopPtr(E))
4516 return false;
4517 } else {
4518 assert(false && "I don't think this should be possible");
4519 }
4520 }
4521 return true;
4522 } else if (Val.isUnion()) {
4523 const FieldDecl *UnionField = Val.getUnionField();
4524 const Record *R = this->getRecord(UnionField->getParent());
4525 assert(R);
4526 const APValue &F = Val.getUnionValue();
4527 const Record::Field *RF = R->getField(UnionField);
4528 PrimType T = classifyPrim(RF->Decl->getType());
4529 if (!this->visitAPValue(F, T, E))
4530 return false;
4531 return this->emitInitField(T, RF->Offset, E);
4532 }
4533 // TODO: Other types.
4534
4535 return false;
4536}
4537
4538template <class Emitter>
4540 unsigned BuiltinID) {
4541 const Function *Func = getFunction(E->getDirectCallee());
4542 if (!Func)
4543 return false;
4544
4545 // For these, we're expected to ultimately return an APValue pointing
4546 // to the CallExpr. This is needed to get the correct codegen.
4547 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
4548 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
4549 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
4550 BuiltinID == Builtin::BI__builtin_function_start) {
4551 if (DiscardResult)
4552 return true;
4553 return this->emitDummyPtr(E, E);
4554 }
4555
4556 QualType ReturnType = E->getType();
4557 std::optional<PrimType> ReturnT = classify(E);
4558
4559 // Non-primitive return type. Prepare storage.
4560 if (!Initializing && !ReturnT && !ReturnType->isVoidType()) {
4561 std::optional<unsigned> LocalIndex = allocateLocal(E);
4562 if (!LocalIndex)
4563 return false;
4564 if (!this->emitGetPtrLocal(*LocalIndex, E))
4565 return false;
4566 }
4567
4568 if (!Func->isUnevaluatedBuiltin()) {
4569 // Put arguments on the stack.
4570 for (const auto *Arg : E->arguments()) {
4571 if (!this->visit(Arg))
4572 return false;
4573 }
4574 }
4575
4576 if (!this->emitCallBI(Func, E, BuiltinID, E))
4577 return false;
4578
4579 if (DiscardResult && !ReturnType->isVoidType()) {
4580 assert(ReturnT);
4581 return this->emitPop(*ReturnT, E);
4582 }
4583
4584 return true;
4585}
4586
4587template <class Emitter>
4589 if (unsigned BuiltinID = E->getBuiltinCallee())
4590 return VisitBuiltinCallExpr(E, BuiltinID);
4591
4592 const FunctionDecl *FuncDecl = E->getDirectCallee();
4593 // Calls to replaceable operator new/operator delete.
4594 if (FuncDecl && FuncDecl->isReplaceableGlobalAllocationFunction()) {
4595 if (FuncDecl->getDeclName().getCXXOverloadedOperator() == OO_New ||
4596 FuncDecl->getDeclName().getCXXOverloadedOperator() == OO_Array_New) {
4597 return VisitBuiltinCallExpr(E, Builtin::BI__builtin_operator_new);
4598 } else {
4599 assert(FuncDecl->getDeclName().getCXXOverloadedOperator() == OO_Delete);
4600 return VisitBuiltinCallExpr(E, Builtin::BI__builtin_operator_delete);
4601 }
4602 }
4603 // Explicit calls to trivial destructors
4604 if (const auto *DD = dyn_cast_if_present<CXXDestructorDecl>(FuncDecl);
4605 DD && DD->isTrivial())
4606 return true;
4607
4608 QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
4609 std::optional<PrimType> T = classify(ReturnType);
4610 bool HasRVO = !ReturnType->isVoidType() && !T;
4611
4612 if (HasRVO) {
4613 if (DiscardResult) {
4614 // If we need to discard the return value but the function returns its
4615 // value via an RVO pointer, we need to create one such pointer just
4616 // for this call.
4617 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
4618 if (!this->emitGetPtrLocal(*LocalIndex, E))
4619 return false;
4620 }
4621 } else {
4622 // We need the result. Prepare a pointer to return or
4623 // dup the current one.
4624 if (!Initializing) {
4625 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
4626 if (!this->emitGetPtrLocal(*LocalIndex, E))
4627 return false;
4628 }
4629 }
4630 if (!this->emitDupPtr(E))
4631 return false;
4632 }
4633 }
4634
4636 llvm::ArrayRef(E->getArgs(), E->getNumArgs()));
4637
4638 bool IsAssignmentOperatorCall = false;
4639 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
4640 OCE && OCE->isAssignmentOp()) {
4641 // Just like with regular assignments, we need to special-case assignment
4642 // operators here and evaluate the RHS (the second arg) before the LHS (the
4643 // first arg. We fix this by using a Flip op later.
4644 assert(Args.size() == 2);
4645 IsAssignmentOperatorCall = true;
4646 std::reverse(Args.begin(), Args.end());
4647 }
4648 // Calling a static operator will still
4649 // pass the instance, but we don't need it.
4650 // Discard it here.
4651 if (isa<CXXOperatorCallExpr>(E)) {
4652 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
4653 MD && MD->isStatic()) {
4654 if (!this->discard(E->getArg(0)))
4655 return false;
4656 // Drop first arg.
4657 Args.erase(Args.begin());
4658 }
4659 }
4660
4661 std::optional<unsigned> CalleeOffset;
4662 // Add the (optional, implicit) This pointer.
4663 if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
4664 if (!FuncDecl && classifyPrim(E->getCallee()) == PT_MemberPtr) {
4665 // If we end up creating a CallPtr op for this, we need the base of the
4666 // member pointer as the instance pointer, and later extract the function
4667 // decl as the function pointer.
4668 const Expr *Callee = E->getCallee();
4669 CalleeOffset =
4670 this->allocateLocalPrimitive(Callee, PT_MemberPtr, true, false);
4671 if (!this->visit(Callee))
4672 return false;
4673 if (!this->emitSetLocal(PT_MemberPtr, *CalleeOffset, E))
4674 return false;
4675 if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
4676 return false;
4677 if (!this->emitGetMemberPtrBase(E))
4678 return false;
4679 } else if (!this->visit(MC->getImplicitObjectArgument())) {
4680 return false;
4681 }
4682 } else if (!FuncDecl) {
4683 const Expr *Callee = E->getCallee();
4684 CalleeOffset = this->allocateLocalPrimitive(Callee, PT_FnPtr, true, false);
4685 if (!this->visit(Callee))
4686 return false;
4687 if (!this->emitSetLocal(PT_FnPtr, *CalleeOffset, E))
4688 return false;
4689 }
4690
4691 llvm::BitVector NonNullArgs = collectNonNullArgs(FuncDecl, Args);
4692 // Put arguments on the stack.
4693 unsigned ArgIndex = 0;
4694 for (const auto *Arg : Args) {
4695 if (!this->visit(Arg))
4696 return false;
4697
4698 // If we know the callee already, check the known parametrs for nullability.
4699 if (FuncDecl && NonNullArgs[ArgIndex]) {
4700 PrimType ArgT = classify(Arg).value_or(PT_Ptr);
4701 if (ArgT == PT_Ptr || ArgT == PT_FnPtr) {
4702 if (!this->emitCheckNonNullArg(ArgT, Arg))
4703 return false;
4704 }
4705 }
4706 ++ArgIndex;
4707 }
4708
4709 // Undo the argument reversal we did earlier.
4710 if (IsAssignmentOperatorCall) {
4711 assert(Args.size() == 2);
4712 PrimType Arg1T = classify(Args[0]).value_or(PT_Ptr);
4713 PrimType Arg2T = classify(Args[1]).value_or(PT_Ptr);
4714 if (!this->emitFlip(Arg2T, Arg1T, E))
4715 return false;
4716 }
4717
4718 if (FuncDecl) {
4719 const Function *Func = getFunction(FuncDecl);
4720 if (!Func)
4721 return false;
4722 assert(HasRVO == Func->hasRVO());
4723
4724 bool HasQualifier = false;
4725 if (const auto *ME = dyn_cast<MemberExpr>(E->getCallee()))
4726 HasQualifier = ME->hasQualifier();
4727
4728 bool IsVirtual = false;
4729 if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
4730 IsVirtual = MD->isVirtual();
4731
4732 // In any case call the function. The return value will end up on the stack
4733 // and if the function has RVO, we already have the pointer on the stack to
4734 // write the result into.
4735 if (IsVirtual && !HasQualifier) {
4736 uint32_t VarArgSize = 0;
4737 unsigned NumParams =
4738 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(E);
4739 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
4740 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
4741
4742 if (!this->emitCallVirt(Func, VarArgSize, E))
4743 return false;
4744 } else if (Func->isVariadic()) {
4745 uint32_t VarArgSize = 0;
4746 unsigned NumParams =
4747 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(E);
4748 for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I)
4749 VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
4750 if (!this->emitCallVar(Func, VarArgSize, E))
4751 return false;
4752 } else {
4753 if (!this->emitCall(Func, 0, E))
4754 return false;
4755 }
4756 } else {
4757 // Indirect call. Visit the callee, which will leave a FunctionPointer on
4758 // the stack. Cleanup of the returned value if necessary will be done after
4759 // the function call completed.
4760
4761 // Sum the size of all args from the call expr.
4762 uint32_t ArgSize = 0;
4763 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
4764 ArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
4765
4766 // Get the callee, either from a member pointer or function pointer saved in
4767 // CalleeOffset.
4768 if (isa<CXXMemberCallExpr>(E) && CalleeOffset) {
4769 if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
4770 return false;
4771 if (!this->emitGetMemberPtrDecl(E))
4772 return false;
4773 } else {
4774 if (!this->emitGetLocal(PT_FnPtr, *CalleeOffset, E))
4775 return false;
4776 }
4777 if (!this->emitCallPtr(ArgSize, E, E))
4778 return false;
4779 }
4780
4781 // Cleanup for discarded return values.
4782 if (DiscardResult && !ReturnType->isVoidType() && T)
4783 return this->emitPop(*T, E);
4784
4785 return true;
4786}
4787
4788template <class Emitter>
4790 SourceLocScope<Emitter> SLS(this, E);
4791
4792 return this->delegate(E->getExpr());
4793}
4794
4795template <class Emitter>
4797 SourceLocScope<Emitter> SLS(this, E);
4798
4799 const Expr *SubExpr = E->getExpr();
4800 if (std::optional<PrimType> T = classify(E->getExpr()))
4801 return this->visit(SubExpr);
4802
4803 assert(Initializing);
4804 return this->visitInitializer(SubExpr);
4805}
4806
4807template <class Emitter>
4809 if (DiscardResult)
4810 return true;
4811
4812 return this->emitConstBool(E->getValue(), E);
4813}
4814
4815template <class Emitter>
4817 const CXXNullPtrLiteralExpr *E) {
4818 if (DiscardResult)
4819 return true;
4820
4821 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(E->getType());
4822 return this->emitNullPtr(Val, nullptr, E);
4823}
4824
4825template <class Emitter>
4827 if (DiscardResult)
4828 return true;
4829
4830 assert(E->getType()->isIntegerType());
4831
4832 PrimType T = classifyPrim(E->getType());
4833 return this->emitZero(T, E);
4834}
4835
4836template <class Emitter>
4838 if (DiscardResult)
4839 return true;
4840
4841 if (this->LambdaThisCapture.Offset > 0) {
4842 if (this->LambdaThisCapture.IsPtr)
4843 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
4844 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
4845 }
4846
4847 // In some circumstances, the 'this' pointer does not actually refer to the
4848 // instance pointer of the current function frame, but e.g. to the declaration
4849 // currently being initialized. Here we emit the necessary instruction(s) for
4850 // this scenario.
4851 if (!InitStackActive || !E->isImplicit())
4852 return this->emitThis(E);
4853
4854 if (InitStackActive && !InitStack.empty()) {
4855 unsigned StartIndex = 0;
4856 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
4857 if (InitStack[StartIndex].Kind != InitLink::K_Field &&
4858 InitStack[StartIndex].Kind != InitLink::K_Elem)
4859 break;
4860 }
4861
4862 for (unsigned I = StartIndex, N = InitStack.size(); I != N; ++I) {
4863 if (!InitStack[I].template emit<Emitter>(this, E))
4864 return false;
4865 }
4866 return true;
4867 }
4868 return this->emitThis(E);
4869}
4870
4871template <class Emitter> bool Compiler<Emitter>::visitStmt(const Stmt *S) {
4872 switch (S->getStmtClass()) {
4873 case Stmt::CompoundStmtClass:
4874 return visitCompoundStmt(cast<CompoundStmt>(S));
4875 case Stmt::DeclStmtClass:
4876 return visitDeclStmt(cast<DeclStmt>(S));
4877 case Stmt::ReturnStmtClass:
4878 return visitReturnStmt(cast<ReturnStmt>(S));
4879 case Stmt::IfStmtClass:
4880 return visitIfStmt(cast<IfStmt>(S));
4881 case Stmt::WhileStmtClass:
4882 return visitWhileStmt(cast<WhileStmt>(S));
4883 case Stmt::DoStmtClass:
4884 return visitDoStmt(cast<DoStmt>(S));
4885 case Stmt::ForStmtClass:
4886 return visitForStmt(cast<ForStmt>(S));
4887 case Stmt::CXXForRangeStmtClass:
4888 return visitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
4889 case Stmt::BreakStmtClass:
4890 return visitBreakStmt(cast<BreakStmt>(S));
4891 case Stmt::ContinueStmtClass:
4892 return visitContinueStmt(cast<ContinueStmt>(S));
4893 case Stmt::SwitchStmtClass:
4894 return visitSwitchStmt(cast<SwitchStmt>(S));
4895 case Stmt::CaseStmtClass:
4896 return visitCaseStmt(cast<CaseStmt>(S));
4897 case Stmt::DefaultStmtClass:
4898 return visitDefaultStmt(cast<DefaultStmt>(S));
4899 case Stmt::AttributedStmtClass:
4900 return visitAttributedStmt(cast<AttributedStmt>(S));
4901 case Stmt::CXXTryStmtClass:
4902 return visitCXXTryStmt(cast<CXXTryStmt>(S));
4903 case Stmt::NullStmtClass:
4904 return true;
4905 // Always invalid statements.
4906 case Stmt::GCCAsmStmtClass:
4907 case Stmt::MSAsmStmtClass:
4908 case Stmt::GotoStmtClass:
4909 return this->emitInvalid(S);
4910 case Stmt::LabelStmtClass:
4911 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
4912 default: {
4913 if (const auto *E = dyn_cast<Expr>(S))
4914 return this->discard(E);
4915 return false;
4916 }
4917 }
4918}
4919
4920template <class Emitter>
4923 for (const auto *InnerStmt : S->body())
4924 if (!visitStmt(InnerStmt))
4925 return false;
4926 return Scope.destroyLocals();
4927}
4928
4929template <class Emitter>
4931 for (const auto *D : DS->decls()) {
4933 FunctionDecl>(D))
4934 continue;
4935
4936 const auto *VD = dyn_cast<VarDecl>(D);
4937 if (!VD)
4938 return false;
4939 if (!this->visitVarDecl(VD))
4940 return false;
4941 }
4942
4943 return true;
4944}
4945
4946template <class Emitter>
4948 if (this->InStmtExpr)
4949 return this->emitUnsupported(RS);
4950
4951 if (const Expr *RE = RS->getRetValue()) {
4952 LocalScope<Emitter> RetScope(this);
4953 if (ReturnType) {
4954 // Primitive types are simply returned.
4955 if (!this->visit(RE))
4956 return false;
4957 this->emitCleanup();
4958 return this->emitRet(*ReturnType, RS);
4959 } else if (RE->getType()->isVoidType()) {
4960 if (!this->visit(RE))
4961 return false;
4962 } else {
4963 // RVO - construct the value in the return location.
4964 if (!this->emitRVOPtr(RE))
4965 return false;
4966 if (!this->visitInitializer(RE))
4967 return false;
4968 if (!this->emitPopPtr(RE))
4969 return false;
4970
4971 this->emitCleanup();
4972 return this->emitRetVoid(RS);
4973 }
4974 }
4975
4976 // Void return.
4977 this->emitCleanup();
4978 return this->emitRetVoid(RS);
4979}
4980
4981template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
4982 if (auto *CondInit = IS->getInit())
4983 if (!visitStmt(CondInit))
4984 return false;
4985
4986 if (const DeclStmt *CondDecl = IS->getConditionVariableDeclStmt())
4987 if (!visitDeclStmt(CondDecl))
4988 return false;
4989
4990 // Compile condition.
4991 if (IS->isNonNegatedConsteval()) {
4992 if (!this->emitIsConstantContext(IS))
4993 return false;
4994 } else if (IS->isNegatedConsteval()) {
4995 if (!this->emitIsConstantContext(IS))
4996 return false;
4997 if (!this->emitInv(IS))
4998 return false;
4999 } else {
5000 if (!this->visitBool(IS->getCond()))
5001 return false;
5002 }
5003
5004 if (const Stmt *Else = IS->getElse()) {
5005 LabelTy LabelElse = this->getLabel();
5006 LabelTy LabelEnd = this->getLabel();
5007 if (!this->jumpFalse(LabelElse))
5008 return false;
5009 {
5010 LocalScope<Emitter> ThenScope(this);
5011 if (!visitStmt(IS->getThen()))
5012 return false;
5013 if (!ThenScope.destroyLocals())
5014 return false;
5015 }
5016 if (!this->jump(LabelEnd))
5017 return false;
5018 this->emitLabel(LabelElse);
5019 {
5020 LocalScope<Emitter> ElseScope(this);
5021 if (!visitStmt(Else))
5022 return false;
5023 if (!ElseScope.destroyLocals())
5024 return false;
5025 }
5026 this->emitLabel(LabelEnd);
5027 } else {
5028 LabelTy LabelEnd = this->getLabel();
5029 if (!this->jumpFalse(LabelEnd))
5030 return false;
5031 {
5032 LocalScope<Emitter> ThenScope(this);
5033 if (!visitStmt(IS->getThen()))
5034 return false;
5035 if (!ThenScope.destroyLocals())
5036 return false;
5037 }
5038 this->emitLabel(LabelEnd);
5039 }
5040
5041 return true;
5042}
5043
5044template <class Emitter>
5046 const Expr *Cond = S->getCond();
5047 const Stmt *Body = S->getBody();
5048
5049 LabelTy CondLabel = this->getLabel(); // Label before the condition.
5050 LabelTy EndLabel = this->getLabel(); // Label after the loop.
5051 LoopScope<Emitter> LS(this, EndLabel, CondLabel);
5052
5053 this->fallthrough(CondLabel);
5054 this->emitLabel(CondLabel);
5055
5056 {
5057 LocalScope<Emitter> CondScope(this);
5058 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5059 if (!visitDeclStmt(CondDecl))
5060 return false;
5061
5062 if (!this->visitBool(Cond))
5063 return false;
5064 if (!this->jumpFalse(EndLabel))
5065 return false;
5066
5067 if (!this->visitStmt(Body))
5068 return false;
5069
5070 if (!CondScope.destroyLocals())
5071 return false;
5072 }
5073 if (!this->jump(CondLabel))
5074 return false;
5075 this->fallthrough(EndLabel);
5076 this->emitLabel(EndLabel);
5077
5078 return true;
5079}
5080
5081template <class Emitter> bool Compiler<Emitter>::visitDoStmt(const DoStmt *S) {
5082 const Expr *Cond = S->getCond();
5083 const Stmt *Body = S->getBody();
5084
5085 LabelTy StartLabel = this->getLabel();
5086 LabelTy EndLabel = this->getLabel();
5087 LabelTy CondLabel = this->getLabel();
5088 LoopScope<Emitter> LS(this, EndLabel, CondLabel);
5089
5090 this->fallthrough(StartLabel);
5091 this->emitLabel(StartLabel);
5092
5093 {
5094 LocalScope<Emitter> CondScope(this);
5095 if (!this->visitStmt(Body))
5096 return false;
5097 this->fallthrough(CondLabel);
5098 this->emitLabel(CondLabel);
5099 if (!this->visitBool(Cond))
5100 return false;
5101
5102 if (!CondScope.destroyLocals())
5103 return false;
5104 }
5105 if (!this->jumpTrue(StartLabel))
5106 return false;
5107
5108 this->fallthrough(EndLabel);
5109 this->emitLabel(EndLabel);
5110 return true;
5111}
5112
5113template <class Emitter>
5115 // for (Init; Cond; Inc) { Body }
5116 const Stmt *Init = S->getInit();
5117 const Expr *Cond = S->getCond();
5118 const Expr *Inc = S->getInc();
5119 const Stmt *Body = S->getBody();
5120
5121 LabelTy EndLabel = this->getLabel();
5122 LabelTy CondLabel = this->getLabel();
5123 LabelTy IncLabel = this->getLabel();
5124 LoopScope<Emitter> LS(this, EndLabel, IncLabel);
5125
5126 if (Init && !this->visitStmt(Init))
5127 return false;
5128
5129 this->fallthrough(CondLabel);
5130 this->emitLabel(CondLabel);
5131
5132 {
5133 LocalScope<Emitter> CondScope(this);
5134 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5135 if (!visitDeclStmt(CondDecl))
5136 return false;
5137
5138 if (Cond) {
5139 if (!this->visitBool(Cond))
5140 return false;
5141 if (!this->jumpFalse(EndLabel))
5142 return false;
5143 }
5144
5145 if (Body && !this->visitStmt(Body))
5146 return false;
5147
5148 this->fallthrough(IncLabel);
5149 this->emitLabel(IncLabel);
5150 if (Inc && !this->discard(Inc))
5151 return false;
5152
5153 if (!CondScope.destroyLocals())
5154 return false;
5155 }
5156 if (!this->jump(CondLabel))
5157 return false;
5158
5159 this->fallthrough(EndLabel);
5160 this->emitLabel(EndLabel);
5161 return true;
5162}
5163
5164template <class Emitter>
5166 const Stmt *Init = S->getInit();
5167 const Expr *Cond = S->getCond();
5168 const Expr *Inc = S->getInc();
5169 const Stmt *Body = S->getBody();
5170 const Stmt *BeginStmt = S->getBeginStmt();
5171 const Stmt *RangeStmt = S->getRangeStmt();
5172 const Stmt *EndStmt = S->getEndStmt();
5173 const VarDecl *LoopVar = S->getLoopVariable();
5174
5175 LabelTy EndLabel = this->getLabel();
5176 LabelTy CondLabel = this->getLabel();
5177 LabelTy IncLabel = this->getLabel();
5178 LoopScope<Emitter> LS(this, EndLabel, IncLabel);
5179
5180 // Emit declarations needed in the loop.
5181 if (Init && !this->visitStmt(Init))
5182 return false;
5183 if (!this->visitStmt(RangeStmt))
5184 return false;
5185 if (!this->visitStmt(BeginStmt))
5186 return false;
5187 if (!this->visitStmt(EndStmt))
5188 return false;
5189
5190 // Now the condition as well as the loop variable assignment.
5191 this->fallthrough(CondLabel);
5192 this->emitLabel(CondLabel);
5193 if (!this->visitBool(Cond))
5194 return false;
5195 if (!this->jumpFalse(EndLabel))
5196 return false;
5197
5198 if (!this->visitVarDecl(LoopVar))
5199 return false;
5200
5201 // Body.
5202 {
5203 if (!this->visitStmt(Body))
5204 return false;
5205
5206 this->fallthrough(IncLabel);
5207 this->emitLabel(IncLabel);
5208 if (!this->discard(Inc))
5209 return false;
5210 }
5211
5212 if (!this->jump(CondLabel))
5213 return false;
5214
5215 this->fallthrough(EndLabel);
5216 this->emitLabel(EndLabel);
5217 return true;
5218}
5219
5220template <class Emitter>
5222 if (!BreakLabel)
5223 return false;
5224
5225 for (VariableScope<Emitter> *C = VarScope; C != BreakVarScope;
5226 C = C->getParent())
5227 C->emitDestruction();
5228 return this->jump(*BreakLabel);
5229}
5230
5231template <class Emitter>
5233 if (!ContinueLabel)
5234 return false;
5235
5236 for (VariableScope<Emitter> *C = VarScope;
5237 C && C->getParent() != ContinueVarScope; C = C->getParent())
5238 C->emitDestruction();
5239 return this->jump(*ContinueLabel);
5240}
5241
5242template <class Emitter>
5244 const Expr *Cond = S->getCond();
5245 PrimType CondT = this->classifyPrim(Cond->getType());
5246 LocalScope<Emitter> LS(this);
5247
5248 LabelTy EndLabel = this->getLabel();
5249 OptLabelTy DefaultLabel = std::nullopt;
5250 unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT, true, false);
5251
5252 if (const auto *CondInit = S->getInit())
5253 if (!visitStmt(CondInit))
5254 return false;
5255
5256 if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5257 if (!visitDeclStmt(CondDecl))
5258 return false;
5259
5260 // Initialize condition variable.
5261 if (!this->visit(Cond))
5262 return false;
5263 if (!this->emitSetLocal(CondT, CondVar, S))
5264 return false;
5265
5266 CaseMap CaseLabels;
5267 // Create labels and comparison ops for all case statements.
5268 for (const SwitchCase *SC = S->getSwitchCaseList(); SC;
5269 SC = SC->getNextSwitchCase()) {
5270 if (const auto *CS = dyn_cast<CaseStmt>(SC)) {
5271 // FIXME: Implement ranges.
5272 if (CS->caseStmtIsGNURange())
5273 return false;
5274 CaseLabels[SC] = this->getLabel();
5275
5276 const Expr *Value = CS->getLHS();
5277 PrimType ValueT = this->classifyPrim(Value->getType());
5278
5279 // Compare the case statement's value to the switch condition.
5280 if (!this->emitGetLocal(CondT, CondVar, CS))
5281 return false;
5282 if (!this->visit(Value))
5283 return false;
5284
5285 // Compare and jump to the case label.
5286 if (!this->emitEQ(ValueT, S))
5287 return false;
5288 if (!this->jumpTrue(CaseLabels[CS]))
5289 return false;
5290 } else {
5291 assert(!DefaultLabel);
5292 DefaultLabel = this->getLabel();
5293 }
5294 }
5295
5296 // If none of the conditions above were true, fall through to the default
5297 // statement or jump after the switch statement.
5298 if (DefaultLabel) {
5299 if (!this->jump(*DefaultLabel))
5300 return false;
5301 } else {
5302 if (!this->jump(EndLabel))
5303 return false;
5304 }
5305
5306 SwitchScope<Emitter> SS(this, std::move(CaseLabels), EndLabel, DefaultLabel);
5307 if (!this->visitStmt(S->getBody()))
5308 return false;
5309 this->emitLabel(EndLabel);
5310
5311 return LS.destroyLocals();
5312}
5313
5314template <class Emitter>
5316 this->emitLabel(CaseLabels[S]);
5317 return this->visitStmt(S->getSubStmt());
5318}
5319
5320template <class Emitter>
5322 this->emitLabel(*DefaultLabel);
5323 return this->visitStmt(S->getSubStmt());
5324}
5325
5326template <class Emitter>
5328 if (this->Ctx.getLangOpts().CXXAssumptions &&
5329 !this->Ctx.getLangOpts().MSVCCompat) {
5330 for (const Attr *A : S->getAttrs()) {
5331 auto *AA = dyn_cast<CXXAssumeAttr>(A);
5332 if (!AA)
5333 continue;
5334
5335 assert(isa<NullStmt>(S->getSubStmt()));
5336
5337 const Expr *Assumption = AA->getAssumption();
5338 if (Assumption->isValueDependent())
5339 return false;
5340
5341 if (Assumption->HasSideEffects(this->Ctx.getASTContext()))
5342 continue;
5343
5344 // Evaluate assumption.
5345 if (!this->visitBool(Assumption))
5346 return false;
5347
5348 if (!this->emitAssume(Assumption))
5349 return false;
5350 }
5351 }
5352
5353 // Ignore other attributes.
5354 return this->visitStmt(S->getSubStmt());
5355}
5356
5357template <class Emitter>
5359 // Ignore all handlers.
5360 return this->visitStmt(S->getTryBlock());
5361}
5362
5363template <class Emitter>
5365 assert(MD->isLambdaStaticInvoker());
5366 assert(MD->hasBody());
5367 assert(cast<CompoundStmt>(MD->getBody())->body_empty());
5368
5369 const CXXRecordDecl *ClosureClass = MD->getParent();
5370 const CXXMethodDecl *LambdaCallOp = ClosureClass->getLambdaCallOperator();
5371 assert(ClosureClass->captures_begin() == ClosureClass->captures_end());
5372 const Function *Func = this->getFunction(LambdaCallOp);
5373 if (!Func)
5374 return false;
5375 assert(Func->hasThisPointer());
5376 assert(Func->getNumParams() == (MD->getNumParams() + 1 + Func->hasRVO()));
5377
5378 if (Func->hasRVO()) {
5379 if (!this->emitRVOPtr(MD))
5380 return false;
5381 }
5382
5383 // The lambda call operator needs an instance pointer, but we don't have
5384 // one here, and we don't need one either because the lambda cannot have
5385 // any captures, as verified above. Emit a null pointer. This is then
5386 // special-cased when interpreting to not emit any misleading diagnostics.
5387 if (!this->emitNullPtr(0, nullptr, MD))
5388 return false;
5389
5390 // Forward all arguments from the static invoker to the lambda call operator.
5391 for (const ParmVarDecl *PVD : MD->parameters()) {
5392 auto It = this->Params.find(PVD);
5393 assert(It != this->Params.end());
5394
5395 // We do the lvalue-to-rvalue conversion manually here, so no need
5396 // to care about references.
5397 PrimType ParamType = this->classify(PVD->getType()).value_or(PT_Ptr);
5398 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
5399 return false;
5400 }
5401
5402 if (!this->emitCall(Func, 0, LambdaCallOp))
5403 return false;
5404
5405 this->emitCleanup();
5406 if (ReturnType)
5407 return this->emitRet(*ReturnType, MD);
5408
5409 // Nothing to do, since we emitted the RVO pointer above.
5410 return this->emitRetVoid(MD);
5411}
5412
5413template <class Emitter>
5415 if (Ctx.getLangOpts().CPlusPlus23)
5416 return true;
5417
5418 if (!E->isPRValue() || E->getType()->isLiteralType(Ctx.getASTContext()))
5419 return true;
5420
5421 return this->emitCheckLiteralType(E->getType().getTypePtr(), E);
5422}
5423
5424template <class Emitter>
5426 assert(!ReturnType);
5427
5428 auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
5429 const Expr *InitExpr) -> bool {
5430 // We don't know what to do with these, so just return false.
5431 if (InitExpr->getType().isNull())
5432 return false;
5433
5434 if (std::optional<PrimType> T = this->classify(InitExpr)) {
5435 if (!this->visit(InitExpr))
5436 return false;
5437
5438 if (F->isBitField())
5439 return this->emitInitThisBitField(*T, F, FieldOffset, InitExpr);
5440 return this->emitInitThisField(*T, FieldOffset, InitExpr);
5441 }
5442 // Non-primitive case. Get a pointer to the field-to-initialize
5443 // on the stack and call visitInitialzer() for it.
5444 InitLinkScope<Emitter> FieldScope(this, InitLink::Field(F->Offset));
5445 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
5446 return false;
5447
5448 if (!this->visitInitializer(InitExpr))
5449 return false;
5450
5451 return this->emitFinishInitPop(InitExpr);
5452 };
5453
5454 const RecordDecl *RD = Ctor->getParent();
5455 const Record *R = this->getRecord(RD);
5456 if (!R)
5457 return false;
5458
5459 if (R->isUnion() && Ctor->isCopyOrMoveConstructor()) {
5460 // union copy and move ctors are special.
5461 assert(cast<CompoundStmt>(Ctor->getBody())->body_empty());
5462 if (!this->emitThis(Ctor))
5463 return false;
5464
5465 auto PVD = Ctor->getParamDecl(0);
5466 ParamOffset PO = this->Params[PVD]; // Must exist.
5467
5468 if (!this->emitGetParam(PT_Ptr, PO.Offset, Ctor))
5469 return false;
5470
5471 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
5472 this->emitRetVoid(Ctor);
5473 }
5474
5476 for (const auto *Init : Ctor->inits()) {
5477 // Scope needed for the initializers.
5479
5480 const Expr *InitExpr = Init->getInit();
5481 if (const FieldDecl *Member = Init->getMember()) {
5482 const Record::Field *F = R->getField(Member);
5483
5484 if (!emitFieldInitializer(F, F->Offset, InitExpr))
5485 return false;
5486 } else if (const Type *Base = Init->getBaseClass()) {
5487 const auto *BaseDecl = Base->getAsCXXRecordDecl();
5488 assert(BaseDecl);
5489
5490 if (Init->isBaseVirtual()) {
5491 assert(R->getVirtualBase(BaseDecl));
5492 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
5493 return false;
5494
5495 } else {
5496 // Base class initializer.
5497 // Get This Base and call initializer on it.
5498 const Record::Base *B = R->getBase(BaseDecl);
5499 assert(B);
5500 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
5501 return false;
5502 }
5503
5504 if (!this->visitInitializer(InitExpr))
5505 return false;
5506 if (!this->emitFinishInitPop(InitExpr))
5507 return false;
5508 } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {
5509 assert(IFD->getChainingSize() >= 2);
5510
5511 unsigned NestedFieldOffset = 0;
5512 const Record::Field *NestedField = nullptr;
5513 for (const NamedDecl *ND : IFD->chain()) {
5514 const auto *FD = cast<FieldDecl>(ND);
5515 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
5516 assert(FieldRecord);
5517
5518 NestedField = FieldRecord->getField(FD);
5519 assert(NestedField);
5520
5521 NestedFieldOffset += NestedField->Offset;
5522 }
5523 assert(NestedField);
5524
5525 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
5526 return false;
5527 } else {
5528 assert(Init->isDelegatingInitializer());
5529 if (!this->emitThis(InitExpr))
5530 return false;
5531 if (!this->visitInitializer(Init->getInit()))
5532 return false;
5533 if (!this->emitPopPtr(InitExpr))
5534 return false;
5535 }
5536
5537 if (!Scope.destroyLocals())
5538 return false;
5539 }
5540
5541 if (const auto *Body = Ctor->getBody())
5542 if (!visitStmt(Body))
5543 return false;
5544
5545 return this->emitRetVoid(SourceInfo{});
5546}
5547
5548template <class Emitter>
5550 const RecordDecl *RD = Dtor->getParent();
5551 const Record *R = this->getRecord(RD);
5552 if (!R)
5553 return false;
5554
5555 if (!Dtor->isTrivial() && Dtor->getBody()) {
5556 if (!this->visitStmt(Dtor->getBody()))
5557 return false;
5558 }
5559
5560 if (!this->emitThis(Dtor))
5561 return false;
5562
5563 assert(R);
5564 if (!R->isUnion()) {
5565 // First, destroy all fields.
5566 for (const Record::Field &Field : llvm::reverse(R->fields())) {
5567 const Descriptor *D = Field.Desc;
5568 if (!D->isPrimitive() && !D->isPrimitiveArray()) {
5569 if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
5570 return false;
5571 if (!this->emitDestruction(D, SourceInfo{}))
5572 return false;
5573 if (!this->emitPopPtr(SourceInfo{}))
5574 return false;
5575 }
5576 }
5577 }
5578
5579 for (const Record::Base &Base : llvm::reverse(R->bases())) {
5580 if (Base.R->isAnonymousUnion())
5581 continue;
5582
5583 if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
5584 return false;
5585 if (!this->emitRecordDestruction(Base.R, {}))
5586 return false;
5587 if (!this->emitPopPtr(SourceInfo{}))
5588 return false;
5589 }
5590
5591 // FIXME: Virtual bases.
5592 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
5593}
5594
5595template <class Emitter>
5597 // Classify the return type.
5598 ReturnType = this->classify(F->getReturnType());
5599
5600 if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
5601 return this->compileConstructor(Ctor);
5602 if (const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
5603 return this->compileDestructor(Dtor);
5604
5605 // Emit custom code if this is a lambda static invoker.
5606 if (const auto *MD = dyn_cast<CXXMethodDecl>(F);
5607 MD && MD->isLambdaStaticInvoker())
5608 return this->emitLambdaStaticInvokerBody(MD);
5609
5610 // Regular functions.
5611 if (const auto *Body = F->getBody())
5612 if (!visitStmt(Body))
5613 return false;
5614
5615 // Emit a guard return to protect against a code path missing one.
5616 if (F->getReturnType()->isVoidType())
5617 return this->emitRetVoid(SourceInfo{});
5618 return this->emitNoRet(SourceInfo{});
5619}
5620
5621template <class Emitter>
5623 const Expr *SubExpr = E->getSubExpr();
5624 if (SubExpr->getType()->isAnyComplexType())
5625 return this->VisitComplexUnaryOperator(E);
5626 if (SubExpr->getType()->isVectorType())
5627 return this->VisitVectorUnaryOperator(E);
5628 if (SubExpr->getType()->isFixedPointType())
5629 return this->VisitFixedPointUnaryOperator(E);
5630 std::optional<PrimType> T = classify(SubExpr->getType());
5631
5632 switch (E->getOpcode()) {
5633 case UO_PostInc: { // x++
5634 if (!Ctx.getLangOpts().CPlusPlus14)
5635 return this->emitInvalid(E);
5636 if (!T)
5637 return this->emitError(E);
5638
5639 if (!this->visit(SubExpr))
5640 return false;
5641
5642 if (T == PT_Ptr || T == PT_FnPtr) {
5643 if (!this->emitIncPtr(E))
5644 return false;
5645
5646 return DiscardResult ? this->emitPopPtr(E) : true;
5647 }
5648
5649 if (T == PT_Float) {
5650 return DiscardResult ? this->emitIncfPop(getFPOptions(E), E)
5651 : this->emitIncf(getFPOptions(E), E);
5652 }
5653
5654 return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E);
5655 }
5656 case UO_PostDec: { // x--
5657 if (!Ctx.getLangOpts().CPlusPlus14)
5658 return this->emitInvalid(E);
5659 if (!T)
5660 return this->emitError(E);
5661
5662 if (!this->visit(SubExpr))
5663 return false;
5664
5665 if (T == PT_Ptr || T == PT_FnPtr) {
5666 if (!this->emitDecPtr(E))
5667 return false;
5668
5669 return DiscardResult ? this->emitPopPtr(E) : true;
5670 }
5671
5672 if (T == PT_Float) {
5673 return DiscardResult ? this->emitDecfPop(getFPOptions(E), E)
5674 : this->emitDecf(getFPOptions(E), E);
5675 }
5676
5677 return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E);
5678 }
5679 case UO_PreInc: { // ++x
5680 if (!Ctx.getLangOpts().CPlusPlus14)
5681 return this->emitInvalid(E);
5682 if (!T)
5683 return this->emitError(E);
5684
5685 if (!this->visit(SubExpr))
5686 return false;
5687
5688 if (T == PT_Ptr || T == PT_FnPtr) {
5689 if (!this->emitLoadPtr(E))
5690 return false;
5691 if (!this->emitConstUint8(1, E))
5692 return false;
5693 if (!this->emitAddOffsetUint8(E))
5694 return false;
5695 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
5696 }
5697
5698 // Post-inc and pre-inc are the same if the value is to be discarded.
5699 if (DiscardResult) {
5700 if (T == PT_Float)
5701 return this->emitIncfPop(getFPOptions(E), E);
5702 return this->emitIncPop(*T, E);
5703 }
5704
5705 if (T == PT_Float) {
5706 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
5707 if (!this->emitLoadFloat(E))
5708 return false;
5709 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
5710 return false;
5711 if (!this->emitAddf(getFPOptions(E), E))
5712 return false;
5713 if (!this->emitStoreFloat(E))
5714 return false;
5715 } else {
5716 assert(isIntegralType(*T));
5717 if (!this->emitLoad(*T, E))
5718 return false;
5719 if (!this->emitConst(1, E))
5720 return false;
5721 if (!this->emitAdd(*T, E))
5722 return false;
5723 if (!this->emitStore(*T, E))
5724 return false;
5725 }
5726 return E->isGLValue() || this->emitLoadPop(*T, E);
5727 }
5728 case UO_PreDec: { // --x
5729 if (!Ctx.getLangOpts().CPlusPlus14)
5730 return this->emitInvalid(E);
5731 if (!T)
5732 return this->emitError(E);
5733
5734 if (!this->visit(SubExpr))
5735 return false;
5736
5737 if (T == PT_Ptr || T == PT_FnPtr) {
5738 if (!this->emitLoadPtr(E))
5739 return false;
5740 if (!this->emitConstUint8(1, E))
5741 return false;
5742 if (!this->emitSubOffsetUint8(E))
5743 return false;
5744 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
5745 }
5746
5747 // Post-dec and pre-dec are the same if the value is to be discarded.
5748 if (DiscardResult) {
5749 if (T == PT_Float)
5750 return this->emitDecfPop(getFPOptions(E), E);
5751 return this->emitDecPop(*T, E);
5752 }
5753
5754 if (T == PT_Float) {
5755 const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
5756 if (!this->emitLoadFloat(E))
5757 return false;
5758 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
5759 return false;
5760 if (!this->emitSubf(getFPOptions(E), E))
5761 return false;
5762 if (!this->emitStoreFloat(E))
5763 return false;
5764 } else {
5765 assert(isIntegralType(*T));
5766 if (!this->emitLoad(*T, E))
5767 return false;
5768 if (!this->emitConst(1, E))
5769 return false;
5770 if (!this->emitSub(*T, E))
5771 return false;
5772 if (!this->emitStore(*T, E))
5773 return false;
5774 }
5775 return E->isGLValue() || this->emitLoadPop(*T, E);
5776 }
5777 case UO_LNot: // !x
5778 if (!T)
5779 return this->emitError(E);
5780
5781 if (DiscardResult)
5782 return this->discard(SubExpr);
5783
5784 if (!this->visitBool(SubExpr))
5785 return false;
5786
5787 if (!this->emitInv(E))
5788 return false;
5789
5790 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
5791 return this->emitCast(PT_Bool, ET, E);
5792 return true;
5793 case UO_Minus: // -x
5794 if (!T)
5795 return this->emitError(E);
5796
5797 if (!this->visit(SubExpr))
5798 return false;
5799 return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
5800 case UO_Plus: // +x
5801 if (!T)
5802 return this->emitError(E);
5803
5804 if (!this->visit(SubExpr)) // noop
5805 return false;
5806 return DiscardResult ? this->emitPop(*T, E) : true;
5807 case UO_AddrOf: // &x
5808 if (E->getType()->isMemberPointerType()) {
5809 // C++11 [expr.unary.op]p3 has very strict rules on how the address of a
5810 // member can be formed.
5811 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(), E);
5812 }
5813 // We should already have a pointer when we get here.
5814 return this->delegate(SubExpr);
5815 case UO_Deref: // *x
5816 if (DiscardResult) {
5817 // assert(false);
5818 return this->discard(SubExpr);
5819 }
5820
5821 if (!this->visit(SubExpr))
5822 return false;
5823 if (classifyPrim(SubExpr) == PT_Ptr)
5824 return this->emitNarrowPtr(E);
5825 return true;
5826
5827 case UO_Not: // ~x
5828 if (!T)
5829 return this->emitError(E);
5830
5831 if (!this->visit(SubExpr))
5832 return false;
5833 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
5834 case UO_Real: // __real x
5835 assert(T);
5836 return this->delegate(SubExpr);
5837 case UO_Imag: { // __imag x
5838 assert(T);
5839 if (!this->discard(SubExpr))
5840 return false;
5841 return this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);
5842 }
5843 case UO_Extension:
5844 return this->delegate(SubExpr);
5845 case UO_Coawait:
5846 assert(false && "Unhandled opcode");
5847 }
5848
5849 return false;
5850}
5851
5852template <class Emitter>
5854 const Expr *SubExpr = E->getSubExpr();
5855 assert(SubExpr->getType()->isAnyComplexType());
5856
5857 if (DiscardResult)
5858 return this->discard(SubExpr);
5859
5860 std::optional<PrimType> ResT = classify(E);
5861 auto prepareResult = [=]() -> bool {
5862 if (!ResT && !Initializing) {
5863 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5864 if (!LocalIndex)
5865 return false;
5866 return this->emitGetPtrLocal(*LocalIndex, E);
5867 }
5868
5869 return true;
5870 };
5871
5872 // The offset of the temporary, if we created one.
5873 unsigned SubExprOffset = ~0u;
5874 auto createTemp = [=, &SubExprOffset]() -> bool {
5875 SubExprOffset = this->allocateLocalPrimitive(SubExpr, PT_Ptr, true, false);
5876 if (!this->visit(SubExpr))
5877 return false;
5878 return this->emitSetLocal(PT_Ptr, SubExprOffset, E);
5879 };
5880
5881 PrimType ElemT = classifyComplexElementType(SubExpr->getType());
5882 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
5883 if (!this->emitGetLocal(PT_Ptr, Offset, E))
5884 return false;
5885 return this->emitArrayElemPop(ElemT, Index, E);
5886 };
5887
5888 switch (E->getOpcode()) {
5889 case UO_Minus:
5890 if (!prepareResult())
5891 return false;
5892 if (!createTemp())
5893 return false;
5894 for (unsigned I = 0; I != 2; ++I) {
5895 if (!getElem(SubExprOffset, I))
5896 return false;
5897 if (!this->emitNeg(ElemT, E))
5898 return false;
5899 if (!this->emitInitElem(ElemT, I, E))
5900 return false;
5901 }
5902 break;
5903
5904 case UO_Plus: // +x
5905 case UO_AddrOf: // &x
5906 case UO_Deref: // *x
5907 return this->delegate(SubExpr);
5908
5909 case UO_LNot:
5910 if (!this->visit(SubExpr))
5911 return false;
5912 if (!this->emitComplexBoolCast(SubExpr))
5913 return false;
5914 if (!this->emitInv(E))
5915 return false;
5916 if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
5917 return this->emitCast(PT_Bool, ET, E);
5918 return true;
5919
5920 case UO_Real:
5921 return this->emitComplexReal(SubExpr);
5922
5923 case UO_Imag:
5924 if (!this->visit(SubExpr))
5925 return false;
5926
5927 if (SubExpr->isLValue()) {
5928 if (!this->emitConstUint8(1, E))
5929 return false;
5930 return this->emitArrayElemPtrPopUint8(E);
5931 }
5932
5933 // Since our _Complex implementation does not map to a primitive type,
5934 // we sometimes have to do the lvalue-to-rvalue conversion here manually.
5935 return this->emitArrayElemPop(classifyPrim(E->getType()), 1, E);
5936
5937 case UO_Not: // ~x
5938 if (!this->visit(SubExpr))
5939 return false;
5940 // Negate the imaginary component.
5941 if (!this->emitArrayElem(ElemT, 1, E))
5942 return false;
5943 if (!this->emitNeg(ElemT, E))
5944 return false;
5945 if (!this->emitInitElem(ElemT, 1, E))
5946 return false;
5947 return DiscardResult ? this->emitPopPtr(E) : true;
5948
5949 case UO_Extension:
5950 return this->delegate(SubExpr);
5951
5952 default:
5953 return this->emitInvalid(E);
5954 }
5955
5956 return true;
5957}
5958
5959template <class Emitter>
5961 const Expr *SubExpr = E->getSubExpr();
5962 assert(SubExpr->getType()->isVectorType());
5963
5964 if (DiscardResult)
5965 return this->discard(SubExpr);
5966
5967 auto UnaryOp = E->getOpcode();
5968 if (UnaryOp == UO_Extension)
5969 return this->delegate(SubExpr);
5970
5971 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
5972 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
5973 return this->emitInvalid(E);
5974
5975 // Nothing to do here.
5976 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
5977 return this->delegate(SubExpr);
5978
5979 if (!Initializing) {
5980 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5981 if (!LocalIndex)
5982 return false;
5983 if (!this->emitGetPtrLocal(*LocalIndex, E))
5984 return false;
5985 }
5986
5987 // The offset of the temporary, if we created one.
5988 unsigned SubExprOffset =
5989 this->allocateLocalPrimitive(SubExpr, PT_Ptr, true, false);
5990 if (!this->visit(SubExpr))
5991 return false;
5992 if (!this->emitSetLocal(PT_Ptr, SubExprOffset, E))
5993 return false;
5994
5995 const auto *VecTy = SubExpr->getType()->getAs<VectorType>();
5996 PrimType ElemT = classifyVectorElementType(SubExpr->getType());
5997 auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
5998 if (!this->emitGetLocal(PT_Ptr, Offset, E))
5999 return false;
6000 return this->emitArrayElemPop(ElemT, Index, E);
6001 };
6002
6003 switch (UnaryOp) {
6004 case UO_Minus:
6005 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6006 if (!getElem(SubExprOffset, I))
6007 return false;
6008 if (!this->emitNeg(ElemT, E))
6009 return false;
6010 if (!this->emitInitElem(ElemT, I, E))
6011 return false;
6012 }
6013 break;
6014 case UO_LNot: { // !x
6015 // In C++, the logic operators !, &&, || are available for vectors. !v is
6016 // equivalent to v == 0.
6017 //
6018 // The result of the comparison is a vector of the same width and number of
6019 // elements as the comparison operands with a signed integral element type.
6020 //
6021 // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
6022 QualType ResultVecTy = E->getType();
6023 PrimType ResultVecElemT =
6024 classifyPrim(ResultVecTy->getAs<VectorType>()->getElementType());
6025 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6026 if (!getElem(SubExprOffset, I))
6027 return false;
6028 // operator ! on vectors returns -1 for 'truth', so negate it.
6029 if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E))
6030 return false;
6031 if (!this->emitInv(E))
6032 return false;
6033 if (!this->emitPrimCast(PT_Bool, ElemT, VecTy->getElementType(), E))
6034 return false;
6035 if (!this->emitNeg(ElemT, E))
6036 return false;
6037 if (ElemT != ResultVecElemT &&
6038 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy, E))
6039 return false;
6040 if (!this->emitInitElem(ResultVecElemT, I, E))
6041 return false;
6042 }
6043 break;
6044 }
6045 case UO_Not: // ~x
6046 for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6047 if (!getElem(SubExprOffset, I))
6048 return false;
6049 if (ElemT == PT_Bool) {
6050 if (!this->emitInv(E))
6051 return false;
6052 } else {
6053 if (!this->emitComp(ElemT, E))
6054 return false;
6055 }
6056 if (!this->emitInitElem(ElemT, I, E))
6057 return false;
6058 }
6059 break;
6060 default:
6061 llvm_unreachable("Unsupported unary operators should be handled up front");
6062 }
6063 return true;
6064}
6065
6066template <class Emitter>
6068 if (DiscardResult)
6069 return true;
6070
6071 if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
6072 return this->emitConst(ECD->getInitVal(), E);
6073 } else if (const auto *BD = dyn_cast<BindingDecl>(D)) {
6074 return this->visit(BD->getBinding());
6075 } else if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
6076 const Function *F = getFunction(FuncDecl);
6077 return F && this->emitGetFnPtr(F, E);
6078 } else if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
6079 if (std::optional<unsigned> Index = P.getOrCreateGlobal(D)) {
6080 if (!this->emitGetPtrGlobal(*Index, E))
6081 return false;
6082 if (std::optional<PrimType> T = classify(E->getType())) {
6083 if (!this->visitAPValue(TPOD->getValue(), *T, E))
6084 return false;
6085 return this->emitInitGlobal(*T, *Index, E);
6086 }
6087 return this->visitAPValueInitializer(TPOD->getValue(), E);
6088 }
6089 return false;
6090 }
6091
6092 // References are implemented via pointers, so when we see a DeclRefExpr
6093 // pointing to a reference, we need to get its value directly (i.e. the
6094 // pointer to the actual value) instead of a pointer to the pointer to the
6095 // value.
6096 bool IsReference = D->getType()->isReferenceType();
6097
6098 // Check for local/global variables and parameters.
6099 if (auto It = Locals.find(D); It != Locals.end()) {
6100 const unsigned Offset = It->second.Offset;
6101 if (IsReference)
6102 return this->emitGetLocal(PT_Ptr, Offset, E);
6103 return this->emitGetPtrLocal(Offset, E);
6104 } else if (auto GlobalIndex = P.getGlobal(D)) {
6105 if (IsReference) {
6106 if (!Ctx.getLangOpts().CPlusPlus11)
6107 return this->emitGetGlobal(classifyPrim(E), *GlobalIndex, E);
6108 return this->emitGetGlobalUnchecked(classifyPrim(E), *GlobalIndex, E);
6109 }
6110
6111 return this->emitGetPtrGlobal(*GlobalIndex, E);
6112 } else if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
6113 if (auto It = this->Params.find(PVD); It != this->Params.end()) {
6114 if (IsReference || !It->second.IsPtr)
6115 return this->emitGetParam(classifyPrim(E), It->second.Offset, E);
6116
6117 return this->emitGetPtrParam(It->second.Offset, E);
6118 }
6119
6120 if (D->getType()->isReferenceType())
6121 return false; // FIXME: Do we need to emit InvalidDeclRef?
6122 }
6123
6124 // In case we need to re-visit a declaration.
6125 auto revisit = [&](const VarDecl *VD) -> bool {
6126 auto VarState = this->visitDecl(VD);
6127
6128 if (VarState.notCreated())
6129 return true;
6130 if (!VarState)
6131 return false;
6132 // Retry.
6133 return this->visitDeclRef(D, E);
6134 };
6135
6136 // Handle lambda captures.
6137 if (auto It = this->LambdaCaptures.find(D);
6138 It != this->LambdaCaptures.end()) {
6139 auto [Offset, IsPtr] = It->second;
6140
6141 if (IsPtr)
6142 return this->emitGetThisFieldPtr(Offset, E);
6143 return this->emitGetPtrThisField(Offset, E);
6144 } else if (const auto *DRE = dyn_cast<DeclRefExpr>(E);
6145 DRE && DRE->refersToEnclosingVariableOrCapture()) {
6146 if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture())
6147 return revisit(VD);
6148 }
6149
6150 if (D != InitializingDecl) {
6151 // Try to lazily visit (or emit dummy pointers for) declarations
6152 // we haven't seen yet.
6153 if (Ctx.getLangOpts().CPlusPlus) {
6154 if (const auto *VD = dyn_cast<VarDecl>(D)) {
6155 const auto typeShouldBeVisited = [&](QualType T) -> bool {
6156 if (T.isConstant(Ctx.getASTContext()))
6157 return true;
6158 return T->isReferenceType();
6159 };
6160
6161 // DecompositionDecls are just proxies for us.
6162 if (isa<DecompositionDecl>(VD))
6163 return revisit(VD);
6164
6165 if ((VD->hasGlobalStorage() || VD->isStaticDataMember()) &&
6166 typeShouldBeVisited(VD->getType()))
6167 return revisit(VD);
6168
6169 // FIXME: The evaluateValue() check here is a little ridiculous, since
6170 // it will ultimately call into Context::evaluateAsInitializer(). In
6171 // other words, we're evaluating the initializer, just to know if we can
6172 // evaluate the initializer.
6173 if (VD->isLocalVarDecl() && typeShouldBeVisited(VD->getType()) &&
6174 VD->getInit() && !VD->getInit()->isValueDependent()) {
6175
6176 if (VD->evaluateValue())
6177 return revisit(VD);
6178
6179 if (!D->getType()->isReferenceType())
6180 return this->emitDummyPtr(D, E);
6181
6182 return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
6183 /*InitializerFailed=*/true, E);
6184 }
6185 }
6186 } else {
6187 if (const auto *VD = dyn_cast<VarDecl>(D);
6188 VD && VD->getAnyInitializer() &&
6189 VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak())
6190 return revisit(VD);
6191 }
6192 }
6193
6194 return this->emitDummyPtr(D, E);
6195}
6196
6197template <class Emitter>
6199 const auto *D = E->getDecl();
6200 return this->visitDeclRef(D, E);
6201}
6202
6203template <class Emitter> void Compiler<Emitter>::emitCleanup() {
6204 for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent())
6205 C->emitDestruction();
6206}
6207
6208template <class Emitter>
6209unsigned Compiler<Emitter>::collectBaseOffset(const QualType BaseType,
6210 const QualType DerivedType) {
6211 const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
6212 if (const auto *R = Ty->getPointeeCXXRecordDecl())
6213 return R;
6214 return Ty->getAsCXXRecordDecl();
6215 };
6216 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
6217 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
6218
6219 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
6220}
6221
6222/// Emit casts from a PrimType to another PrimType.
6223template <class Emitter>
6225 QualType ToQT, const Expr *E) {
6226
6227 if (FromT == PT_Float) {
6228 // Floating to floating.
6229 if (ToT == PT_Float) {
6230 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6231 return this->emitCastFP(ToSem, getRoundingMode(E), E);
6232 }
6233
6234 if (ToT == PT_IntAP)
6235 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
6236 getFPOptions(E), E);
6237 if (ToT == PT_IntAPS)
6238 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
6239 getFPOptions(E), E);
6240
6241 // Float to integral.
6242 if (isIntegralType(ToT) || ToT == PT_Bool)
6243 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
6244 }
6245
6246 if (isIntegralType(FromT) || FromT == PT_Bool) {
6247 if (ToT == PT_IntAP)
6248 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
6249 if (ToT == PT_IntAPS)
6250 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
6251
6252 // Integral to integral.
6253 if (isIntegralType(ToT) || ToT == PT_Bool)
6254 return FromT != ToT ? this->emitCast(FromT, ToT, E) : true;
6255
6256 if (ToT == PT_Float) {
6257 // Integral to floating.
6258 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6259 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E);
6260 }
6261 }
6262
6263 return false;
6264}
6265
6266/// Emits __real(SubExpr)
6267template <class Emitter>
6268bool Compiler<Emitter>::emitComplexReal(const Expr *SubExpr) {
6269 assert(SubExpr->getType()->isAnyComplexType());
6270
6271 if (DiscardResult)
6272 return this->discard(SubExpr);
6273
6274 if (!this->visit(SubExpr))
6275 return false;
6276 if (SubExpr->isLValue()) {
6277 if (!this->emitConstUint8(0, SubExpr))
6278 return false;
6279 return this->emitArrayElemPtrPopUint8(SubExpr);
6280 }
6281
6282 // Rvalue, load the actual element.
6283 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->getType()),
6284 0, SubExpr);
6285}
6286
6287template <class Emitter>
6289 assert(!DiscardResult);
6290 PrimType ElemT = classifyComplexElementType(E->getType());
6291 // We emit the expression (__real(E) != 0 || __imag(E) != 0)
6292 // for us, that means (bool)E[0] || (bool)E[1]
6293 if (!this->emitArrayElem(ElemT, 0, E))
6294 return false;
6295 if (ElemT == PT_Float) {
6296 if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
6297 return false;
6298 } else {
6299 if (!this->emitCast(ElemT, PT_Bool, E))
6300 return false;
6301 }
6302
6303 // We now have the bool value of E[0] on the stack.
6304 LabelTy LabelTrue = this->getLabel();
6305 if (!this->jumpTrue(LabelTrue))
6306 return false;
6307
6308 if (!this->emitArrayElemPop(ElemT, 1, E))
6309 return false;
6310 if (ElemT == PT_Float) {
6311 if (!this->emitCastFloatingIntegral(PT_Bool, getFPOptions(E), E))
6312 return false;
6313 } else {
6314 if (!this->emitCast(ElemT, PT_Bool, E))
6315 return false;
6316 }
6317 // Leave the boolean value of E[1] on the stack.
6318 LabelTy EndLabel = this->getLabel();
6319 this->jump(EndLabel);
6320
6321 this->emitLabel(LabelTrue);
6322 if (!this->emitPopPtr(E))
6323 return false;
6324 if (!this->emitConstBool(true, E))
6325 return false;
6326
6327 this->fallthrough(EndLabel);
6328 this->emitLabel(EndLabel);
6329
6330 return true;
6331}
6332
6333template <class Emitter>
6334bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS,
6335 const BinaryOperator *E) {
6336 assert(E->isComparisonOp());
6337 assert(!Initializing);
6338 assert(!DiscardResult);
6339
6340 PrimType ElemT;
6341 bool LHSIsComplex;
6342 unsigned LHSOffset;
6343 if (LHS->getType()->isAnyComplexType()) {
6344 LHSIsComplex = true;
6345 ElemT = classifyComplexElementType(LHS->getType());
6346 LHSOffset = allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true,
6347 /*IsExtended=*/false);
6348 if (!this->visit(LHS))
6349 return false;
6350 if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
6351 return false;
6352 } else {
6353 LHSIsComplex = false;
6354 PrimType LHST = classifyPrim(LHS->getType());
6355 LHSOffset = this->allocateLocalPrimitive(LHS, LHST, true, false);
6356 if (!this->visit(LHS))
6357 return false;
6358 if (!this->emitSetLocal(LHST, LHSOffset, E))
6359 return false;
6360 }
6361
6362 bool RHSIsComplex;
6363 unsigned RHSOffset;
6364 if (RHS->getType()->isAnyComplexType()) {
6365 RHSIsComplex = true;
6366 ElemT = classifyComplexElementType(RHS->getType());
6367 RHSOffset = allocateLocalPrimitive(RHS, PT_Ptr, /*IsConst=*/true,
6368 /*IsExtended=*/false);
6369 if (!this->visit(RHS))
6370 return false;
6371 if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
6372 return false;
6373 } else {
6374 RHSIsComplex = false;
6375 PrimType RHST = classifyPrim(RHS->getType());
6376 RHSOffset = this->allocateLocalPrimitive(RHS, RHST, true, false);
6377 if (!this->visit(RHS))
6378 return false;
6379 if (!this->emitSetLocal(RHST, RHSOffset, E))
6380 return false;
6381 }
6382
6383 auto getElem = [&](unsigned LocalOffset, unsigned Index,
6384 bool IsComplex) -> bool {
6385 if (IsComplex) {
6386 if (!this->emitGetLocal(PT_Ptr, LocalOffset, E))
6387 return false;
6388 return this->emitArrayElemPop(ElemT, Index, E);
6389 }
6390 return this->emitGetLocal(ElemT, LocalOffset, E);
6391 };
6392
6393 for (unsigned I = 0; I != 2; ++I) {
6394 // Get both values.
6395 if (!getElem(LHSOffset, I, LHSIsComplex))
6396 return false;
6397 if (!getElem(RHSOffset, I, RHSIsComplex))
6398 return false;
6399 // And compare them.
6400 if (!this->emitEQ(ElemT, E))
6401 return false;
6402
6403 if (!this->emitCastBoolUint8(E))
6404 return false;
6405 }
6406
6407 // We now have two bool values on the stack. Compare those.
6408 if (!this->emitAddUint8(E))
6409 return false;
6410 if (!this->emitConstUint8(2, E))
6411 return false;
6412
6413 if (E->getOpcode() == BO_EQ) {
6414 if (!this->emitEQUint8(E))
6415 return false;
6416 } else if (E->getOpcode() == BO_NE) {
6417 if (!this->emitNEUint8(E))
6418 return false;
6419 } else
6420 return false;
6421
6422 // In C, this returns an int.
6423 if (PrimType ResT = classifyPrim(E->getType()); ResT != PT_Bool)
6424 return this->emitCast(PT_Bool, ResT, E);
6425 return true;
6426}
6427
6428/// When calling this, we have a pointer of the local-to-destroy
6429/// on the stack.
6430/// Emit destruction of record types (or arrays of record types).
6431template <class Emitter>
6433 assert(R);
6434 assert(!R->isAnonymousUnion());
6435 const CXXDestructorDecl *Dtor = R->getDestructor();
6436 if (!Dtor || Dtor->isTrivial())
6437 return true;
6438
6439 assert(Dtor);
6440 const Function *DtorFunc = getFunction(Dtor);
6441 if (!DtorFunc)
6442 return false;
6443 assert(DtorFunc->hasThisPointer());
6444 assert(DtorFunc->getNumParams() == 1);
6445 if (!this->emitDupPtr(Loc))
6446 return false;
6447 return this->emitCall(DtorFunc, 0, Loc);
6448}
6449/// When calling this, we have a pointer of the local-to-destroy
6450/// on the stack.
6451/// Emit destruction of record types (or arrays of record types).
6452template <class Emitter>
6454 SourceInfo Loc) {
6455 assert(Desc);
6456 assert(!Desc->isPrimitive());
6457 assert(!Desc->isPrimitiveArray());
6458
6459 // Arrays.
6460 if (Desc->isArray()) {
6461 const Descriptor *ElemDesc = Desc->ElemDesc;
6462 assert(ElemDesc);
6463
6464 // Don't need to do anything for these.
6465 if (ElemDesc->isPrimitiveArray())
6466 return true;
6467
6468 // If this is an array of record types, check if we need
6469 // to call the element destructors at all. If not, try
6470 // to save the work.
6471 if (const Record *ElemRecord = ElemDesc->ElemRecord) {
6472 if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
6473 !Dtor || Dtor->isTrivial())
6474 return true;
6475 }
6476
6477 for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) {
6478 if (!this->emitConstUint64(I, Loc))
6479 return false;
6480 if (!this->emitArrayElemPtrUint64(Loc))
6481 return false;
6482 if (!this->emitDestruction(ElemDesc, Loc))
6483 return false;
6484 if (!this->emitPopPtr(Loc))
6485 return false;
6486 }
6487 return true;
6488 }
6489
6490 assert(Desc->ElemRecord);
6491 if (Desc->ElemRecord->isAnonymousUnion())
6492 return true;
6493
6494 return this->emitRecordDestruction(Desc->ElemRecord, Loc);
6495}
6496
6497/// Create a dummy pointer for the given decl (or expr) and
6498/// push a pointer to it on the stack.
6499template <class Emitter>
6500bool Compiler<Emitter>::emitDummyPtr(const DeclTy &D, const Expr *E) {
6501 assert(!DiscardResult && "Should've been checked before");
6502
6503 unsigned DummyID = P.getOrCreateDummy(D);
6504
6505 if (!this->emitGetPtrGlobal(DummyID, E))
6506 return false;
6507 if (E->getType()->isVoidType())
6508 return true;
6509
6510 // Convert the dummy pointer to another pointer type if we have to.
6511 if (PrimType PT = classifyPrim(E); PT != PT_Ptr) {
6512 if (isPtrType(PT))
6513 return this->emitDecayPtr(PT_Ptr, PT, E);
6514 return false;
6515 }
6516 return true;
6517}
6518
6519// This function is constexpr if and only if To, From, and the types of
6520// all subobjects of To and From are types T such that...
6521// (3.1) - is_union_v<T> is false;
6522// (3.2) - is_pointer_v<T> is false;
6523// (3.3) - is_member_pointer_v<T> is false;
6524// (3.4) - is_volatile_v<T> is false; and
6525// (3.5) - T has no non-static data members of reference type
6526template <class Emitter>
6528 const Expr *SubExpr = E->getSubExpr();
6529 QualType FromType = SubExpr->getType();
6530 QualType ToType = E->getType();
6531 std::optional<PrimType> ToT = classify(ToType);
6532
6533 assert(!ToType->isReferenceType());
6534
6535 // Prepare storage for the result in case we discard.
6536 if (DiscardResult && !Initializing && !ToT) {
6537 std::optional<unsigned> LocalIndex = allocateLocal(E);
6538 if (!LocalIndex)
6539 return false;
6540 if (!this->emitGetPtrLocal(*LocalIndex, E))
6541 return false;
6542 }
6543
6544 // Get a pointer to the value-to-cast on the stack.
6545 // For CK_LValueToRValueBitCast, this is always an lvalue and
6546 // we later assume it to be one (i.e. a PT_Ptr). However,
6547 // we call this function for other utility methods where
6548 // a bitcast might be useful, so convert it to a PT_Ptr in that case.
6549 if (SubExpr->isGLValue() || FromType->isVectorType()) {
6550 if (!this->visit(SubExpr))
6551 return false;
6552 } else if (std::optional<PrimType> FromT = classify(SubExpr)) {
6553 unsigned TempOffset = allocateLocalPrimitive(
6554 SubExpr, *FromT, /*IsConst=*/true, /*IsExtended=*/false);
6555 if (!this->visit(SubExpr))
6556 return false;
6557 if (!this->emitSetLocal(*FromT, TempOffset, E))
6558 return false;
6559 if (!this->emitGetPtrLocal(TempOffset, E))
6560 return false;
6561 } else {
6562 return false;
6563 }
6564
6565 if (!ToT) {
6566 if (!this->emitBitCast(E))
6567 return false;
6568 return DiscardResult ? this->emitPopPtr(E) : true;
6569 }
6570 assert(ToT);
6571
6572 const llvm::fltSemantics *TargetSemantics = nullptr;
6573 if (ToT == PT_Float)
6574 TargetSemantics = &Ctx.getFloatSemantics(ToType);
6575
6576 // Conversion to a primitive type. FromType can be another
6577 // primitive type, or a record/array.
6578 bool ToTypeIsUChar = (ToType->isSpecificBuiltinType(BuiltinType::UChar) ||
6579 ToType->isSpecificBuiltinType(BuiltinType::Char_U));
6580 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
6581
6582 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->isStdByteType(),
6583 ResultBitWidth, TargetSemantics, E))
6584 return false;
6585
6586 if (DiscardResult)
6587 return this->emitPop(*ToT, E);
6588
6589 return true;
6590}
6591
6592namespace clang {
6593namespace interp {
6594
6595template class Compiler<ByteCodeEmitter>;
6596template class Compiler<EvalEmitter>;
6597
6598} // namespace interp
6599} // 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:3048
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 C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition: ExprCXX.h:845
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:585
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:423
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:5232
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:3510
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:3834
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
Definition: Compiler.cpp:4789
bool visitDeclAndReturn(const VarDecl *VD, bool ConstantContext) override
Toplevel visitDeclAndReturn().
Definition: Compiler.cpp:4277
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:5327
bool VisitPackIndexingExpr(const PackIndexingExpr *E)
Definition: Compiler.cpp:3549
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
Definition: Compiler.cpp:1688
bool VisitCallExpr(const CallExpr *E)
Definition: Compiler.cpp:4588
bool VisitPseudoObjectExpr(const PseudoObjectExpr *E)
Definition: Compiler.cpp:3525
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:4192
void emitCleanup()
Emits scope cleanup instructions.
Definition: Compiler.cpp:6203
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:5853
llvm::DenseMap< const SwitchCase *, LabelTy > CaseMap
Definition: Compiler.h:110
bool visitDeclStmt(const DeclStmt *DS)
Definition: Compiler.cpp:4930
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:4449
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:4921
bool visitDeclRef(const ValueDecl *D, const Expr *E)
Visit the given decl as if we have a reference to it.
Definition: Compiler.cpp:6067
bool visitBreakStmt(const BreakStmt *S)
Definition: Compiler.cpp:5221
bool visitExpr(const Expr *E, bool DestroyToplevelScope) override
Definition: Compiler.cpp:4197
bool visitForStmt(const ForStmt *S)
Definition: Compiler.cpp:5114
bool VisitDeclRefExpr(const DeclRefExpr *E)
Definition: Compiler.cpp:6198
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:429
bool VisitStmtExpr(const StmtExpr *E)
Definition: Compiler.cpp:3764
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:4111
bool VisitFixedPointLiteral(const FixedPointLiteral *E)
Definition: Compiler.cpp:771
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
Definition: Compiler.cpp:4808
VariableScope< Emitter > * VarScope
Current scope.
Definition: Compiler.h:393
VariableScope< Emitter > * ContinueVarScope
Scope to cleanup until when we see a continue statement.
Definition: Compiler.h:425
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:3792
bool discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
Definition: Compiler.cpp:3786
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
Definition: Compiler.cpp:4796
CaseMap CaseLabels
Switch case mapping.
Definition: Compiler.h:418
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
Definition: Compiler.cpp:4180
bool visit(const Expr *E)
Evaluates an expression and places the result on the stack.
Definition: Compiler.cpp:3799
const RecordType * getRecordTy(QualType Ty)
Returns a record type from a record or pointer type.
Definition: Compiler.cpp:4174
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E)
Definition: Compiler.cpp:3725
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:3650
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:3826
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:5321
typename Emitter::LabelTy LabelTy
Definition: Compiler.h:107
VarCreationState visitDecl(const VarDecl *VD)
Definition: Compiler.cpp:4249
bool visitStmt(const Stmt *S)
Definition: Compiler.cpp:4871
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
Definition: Compiler.cpp:3462
bool visitAPValueInitializer(const APValue &Val, const Expr *E)
Definition: Compiler.cpp:4476
bool VisitVectorUnaryOperator(const UnaryOperator *E)
Definition: Compiler.cpp:5960
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
Definition: Compiler.cpp:2943
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
Definition: Compiler.cpp:4816
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
Definition: Compiler.cpp:3712
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
Definition: Compiler.cpp:3237
bool VisitRecoveryExpr(const RecoveryExpr *E)
Definition: Compiler.cpp:3554
bool VisitRequiresExpr(const RequiresExpr *E)
Definition: Compiler.cpp:3502
bool Initializing
Flag inidicating if we're initializing an already created variable.
Definition: Compiler.h:408
bool visitReturnStmt(const ReturnStmt *RS)
Definition: Compiler.cpp:4947
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:5596
bool visitCXXForRangeStmt(const CXXForRangeStmt *S)
Definition: Compiler.cpp:5165
bool visitCaseStmt(const CaseStmt *S)
Definition: Compiler.cpp:5315
bool VisitComplexBinOp(const BinaryOperator *E)
Definition: Compiler.cpp:1111
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
Definition: Compiler.cpp:2271
bool VisitCXXTypeidExpr(const CXXTypeidExpr *E)
Definition: Compiler.cpp:3430
bool VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinID)
Definition: Compiler.cpp:4539
OptLabelTy ContinueLabel
Point to continue to.
Definition: Compiler.h:427
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
Definition: Compiler.cpp:1624
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
Definition: Compiler.cpp:3519
bool VisitUnaryOperator(const UnaryOperator *E)
Definition: Compiler.cpp:5622
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:5081
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:3607
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:421
std::optional< LabelTy > OptLabelTy
Definition: Compiler.h:109
bool DiscardResult
Flag indicating if return value is to be discarded.
Definition: Compiler.h:402
bool VisitEmbedExpr(const EmbedExpr *E)
Definition: Compiler.cpp:2014
bool VisitConvertVectorExpr(const ConvertVectorExpr *E)
Definition: Compiler.cpp:3569
bool VisitCXXThisExpr(const CXXThisExpr *E)
Definition: Compiler.cpp:4837
bool VisitConstantExpr(const ConstantExpr *E)
Definition: Compiler.cpp:1998
unsigned allocateTemporary(const Expr *E)
Definition: Compiler.cpp:4153
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
Definition: Compiler.cpp:2043
bool visitSwitchStmt(const SwitchStmt *S)
Definition: Compiler.cpp:5243
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E)
Definition: Compiler.cpp:3468
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsExtended=false)
Creates a local primitive value.
Definition: Compiler.cpp:4086
bool VisitExprWithCleanups(const ExprWithCleanups *E)
Definition: Compiler.cpp:2653
bool visitWhileStmt(const WhileStmt *S)
Definition: Compiler.cpp:5045
bool visitIfStmt(const IfStmt *IS)
Definition: Compiler.cpp:4981
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
Definition: Compiler.cpp:3559
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:4826
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:4338
bool visitCXXTryStmt(const CXXTryStmt *S)
Definition: Compiler.cpp:5358
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:497
bool destroyLocals(const Expr *E=nullptr) override
Explicit destruction of local variables.
Definition: Compiler.h:521
void addLocal(const Scope::Local &Local) override
Definition: Compiler.h:531
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:436
Compiler< Emitter > * Ctx
Compiler instance.
Definition: Compiler.h:490
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:2119
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