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