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