32 OldInitializingDecl(
Ctx->InitializingDecl) {
33 Ctx->InitializingDecl = VD;
42 this->
Ctx->InitializingDecl = OldInitializingDecl;
43 this->
Ctx->InitStack.pop_back();
57 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
58 OldInitializing(Ctx->Initializing) {
64 Ctx->DiscardResult = OldDiscardResult;
65 Ctx->Initializing = OldInitializing;
72 bool OldDiscardResult;
76template <
class Emitter>
80 return Ctx->emitThis(
E);
83 return Ctx->emitGetPtrFieldPop(
Offset,
E);
85 return Ctx->emitGetPtrLocal(
Offset,
E);
89 if (!Ctx->emitConstUint32(
Offset,
E))
91 return Ctx->emitArrayElemPtrPopUint32(
E);
93 llvm_unreachable(
"Unhandled InitLink kind");
117 OldContinueLabel(
Ctx->ContinueLabel) {
123 this->
Ctx->BreakLabel = OldBreakLabel;
124 this->
Ctx->ContinueLabel = OldContinueLabel;
142 OldDefaultLabel(this->
Ctx->DefaultLabel),
143 OldCaseLabels(
std::move(this->
Ctx->CaseLabels)) {
146 this->Ctx->
CaseLabels = std::move(CaseLabels);
150 this->
Ctx->BreakLabel = OldBreakLabel;
151 this->
Ctx->DefaultLabel = OldDefaultLabel;
152 this->
Ctx->CaseLabels = std::move(OldCaseLabels);
177template <
class Emitter>
182 case CK_LValueToRValue: {
184 return this->discard(SubExpr);
186 std::optional<PrimType> SubExprT = classify(SubExpr->
getType());
188 if (!Initializing && !SubExprT) {
189 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
192 if (!this->emitGetPtrLocal(*LocalIndex, CE))
196 if (!this->visit(SubExpr))
200 return this->emitLoadPop(*SubExprT, CE);
205 return this->emitMemcpy(CE);
208 case CK_DerivedToBaseMemberPointer: {
217 if (!this->delegate(SubExpr))
220 return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
223 case CK_BaseToDerivedMemberPointer: {
229 unsigned DerivedOffset = collectBaseOffset(
QualType(FromMP->getClass(), 0),
232 if (!this->delegate(SubExpr))
234 return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
237 case CK_UncheckedDerivedToBase:
238 case CK_DerivedToBase: {
239 if (!this->delegate(SubExpr))
243 if (
const auto *PT = dyn_cast<PointerType>(Ty))
244 return PT->getPointeeType()->getAsCXXRecordDecl();
245 return Ty->getAsCXXRecordDecl();
252 if (B->isVirtual()) {
253 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))
255 CurType = B->getType();
257 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
258 if (!this->emitGetPtrBasePop(DerivedOffset, CE))
260 CurType = B->getType();
267 case CK_BaseToDerived: {
268 if (!this->delegate(SubExpr))
271 unsigned DerivedOffset =
274 return this->emitGetPtrDerivedPop(DerivedOffset, CE);
277 case CK_FloatingCast: {
283 return this->discard(SubExpr);
284 if (!this->visit(SubExpr))
286 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
287 return this->emitCastFP(TargetSemantics, getRoundingMode(CE), CE);
290 case CK_IntegralToFloating: {
292 return this->discard(SubExpr);
293 std::optional<PrimType> FromT = classify(SubExpr->
getType());
297 if (!this->visit(SubExpr))
300 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
301 llvm::RoundingMode RM = getRoundingMode(CE);
302 return this->emitCastIntegralFloating(*FromT, TargetSemantics, RM, CE);
305 case CK_FloatingToBoolean:
306 case CK_FloatingToIntegral: {
308 return this->discard(SubExpr);
310 std::optional<PrimType> ToT = classify(CE->
getType());
315 if (!this->visit(SubExpr))
319 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->
getType()),
322 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->
getType()),
325 return this->emitCastFloatingIntegral(*ToT, CE);
328 case CK_NullToPointer:
329 case CK_NullToMemberPointer: {
330 if (!this->discard(SubExpr))
337 if (!PointeeType.
isNull()) {
338 if (std::optional<PrimType>
T = classify(PointeeType))
339 Desc =
P.createDescriptor(SubExpr, *
T);
341 Desc =
P.createDescriptor(SubExpr, PointeeType.
getTypePtr(),
342 std::nullopt,
true,
false,
345 return this->emitNull(classifyPrim(CE->
getType()), Desc, CE);
348 case CK_PointerToIntegral: {
350 return this->discard(SubExpr);
352 if (!this->visit(SubExpr))
358 if (!this->emitDecayPtr(FromT,
PT_Ptr, CE))
364 return this->emitCastPointerIntegralAP(Ctx.getBitWidth(CE->
getType()),
367 return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(CE->
getType()),
369 return this->emitCastPointerIntegral(
T, CE);
372 case CK_ArrayToPointerDecay: {
373 if (!this->visit(SubExpr))
375 if (!this->emitArrayDecay(CE))
378 return this->emitPopPtr(CE);
382 case CK_IntegralToPointer: {
385 if (!this->visit(SubExpr))
391 return this->emitPop(
T, CE);
396 Desc =
P.createDescriptor(SubExpr, *
T);
404 if (!this->emitGetIntPtr(
T, Desc, CE))
407 PrimType DestPtrT = classifyPrim(PtrType);
412 return this->emitDecayPtr(
PT_Ptr, DestPtrT, CE);
415 case CK_AtomicToNonAtomic:
416 case CK_ConstructorConversion:
417 case CK_FunctionToPointerDecay:
418 case CK_NonAtomicToAtomic:
420 case CK_UserDefinedConversion:
421 case CK_AddressSpaceConversion:
422 return this->delegate(SubExpr);
427 if (!this->discard(SubExpr))
429 return this->emitInvalidCast(CastKind::Reinterpret,
true, CE);
433 return this->discard(SubExpr);
436 std::optional<PrimType> FromT = classify(SubExprTy);
437 std::optional<PrimType> ToT = classify(CE->
getType());
445 return this->delegate(SubExpr);
447 if (!this->visit(SubExpr))
454 if (!this->visit(SubExpr))
456 return this->emitDecayPtr(*FromT, *ToT, CE);
459 case CK_IntegralToBoolean:
460 case CK_BooleanToSignedIntegral:
461 case CK_IntegralCast: {
463 return this->discard(SubExpr);
464 std::optional<PrimType> FromT = classify(SubExpr->
getType());
465 std::optional<PrimType> ToT = classify(CE->
getType());
470 if (!this->visit(SubExpr))
478 if (!this->emitCheckEnumValue(*FromT, ET->getDecl(), CE))
483 auto maybeNegate = [&]() ->
bool {
484 if (CE->
getCastKind() == CK_BooleanToSignedIntegral)
485 return this->emitNeg(*ToT, CE);
490 return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->
getType()), CE) &&
493 return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->
getType()), CE) &&
498 if (!this->emitCast(*FromT, *ToT, CE))
501 return maybeNegate();
504 case CK_PointerToBoolean:
505 case CK_MemberPointerToBoolean: {
509 if (!this->visit(SubExpr))
512 if (!this->emitNull(PtrT,
nullptr, CE))
515 return this->emitNE(PtrT, CE);
518 case CK_IntegralComplexToBoolean:
519 case CK_FloatingComplexToBoolean: {
521 return this->discard(SubExpr);
522 if (!this->visit(SubExpr))
524 return this->emitComplexBoolCast(SubExpr);
527 case CK_IntegralComplexToReal:
528 case CK_FloatingComplexToReal:
529 return this->emitComplexReal(SubExpr);
531 case CK_IntegralRealToComplex:
532 case CK_FloatingRealToComplex: {
536 unsigned LocalIndex = allocateTemporary(CE);
537 if (!this->emitGetPtrLocal(LocalIndex, CE))
542 if (!this->visitArrayElemInit(0, SubExpr))
546 if (!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
548 return this->emitInitElem(
T, 1, SubExpr);
551 case CK_IntegralComplexCast:
552 case CK_FloatingComplexCast:
553 case CK_IntegralComplexToFloatingComplex:
554 case CK_FloatingComplexToIntegralComplex: {
558 return this->discard(SubExpr);
561 std::optional<unsigned> LocalIndex = allocateLocal(CE);
564 if (!this->emitGetPtrLocal(*LocalIndex, CE))
571 unsigned SubExprOffset = allocateLocalPrimitive(
572 SubExpr,
PT_Ptr,
true,
false);
573 if (!this->visit(SubExpr))
575 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, CE))
581 PrimType DestElemT = classifyPrim(DestElemType);
583 for (
unsigned I = 0; I != 2; ++I) {
584 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, CE))
586 if (!this->emitArrayElemPop(SourceElemT, I, CE))
590 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
594 if (!this->emitInitElem(DestElemT, I, CE))
600 case CK_VectorSplat: {
601 assert(!classify(CE->
getType()));
602 assert(classify(SubExpr->
getType()));
606 return this->discard(SubExpr);
609 std::optional<unsigned> LocalIndex = allocateLocal(CE);
612 if (!this->emitGetPtrLocal(*LocalIndex, CE))
618 unsigned ElemOffset = allocateLocalPrimitive(
619 SubExpr, ElemT,
true,
false);
622 if (!this->visit(SubExpr))
624 if (classifyPrim(SubExpr) ==
PT_Ptr && !this->emitLoadPop(ElemT, CE))
627 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
630 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
631 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
633 if (!this->emitInitElem(ElemT, I, CE))
641 return discard(SubExpr);
644 return this->emitInvalid(CE);
646 llvm_unreachable(
"Unhandled clang::CastKind enum");
649template <
class Emitter>
654 return this->emitConst(
LE->getValue(),
LE);
657template <
class Emitter>
662 return this->emitConstFloat(
E->getValue(),
E);
665template <
class Emitter>
672 unsigned LocalIndex = allocateTemporary(
E);
673 if (!this->emitGetPtrLocal(LocalIndex,
E))
677 const Expr *SubExpr =
E->getSubExpr();
680 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
682 if (!this->emitInitElem(SubExprT, 0, SubExpr))
684 return this->visitArrayElemInit(1, SubExpr);
687template <
class Emitter>
689 return this->delegate(
E->getSubExpr());
692template <
class Emitter>
696 return this->VisitLogicalBinOp(BO);
704 if (!this->discard(LHS))
707 return this->discard(RHS);
709 return this->delegate(RHS);
713 return this->VisitComplexBinOp(BO);
717 return this->emitComplexComparison(LHS, RHS, BO);
720 if (!this->visit(LHS))
723 if (!this->visit(RHS))
726 if (!this->emitToMemberPtr(BO))
732 if (!this->emitCastMemberPtrPtr(BO))
734 return DiscardResult ? this->emitPopPtr(BO) :
true;
738 std::optional<PrimType>
LT = classify(LHS);
739 std::optional<PrimType> RT = classify(RHS);
740 std::optional<PrimType>
T = classify(BO->
getType());
749 Ctx.getASTContext().CompCategories.lookupInfoForType(BO->
getType());
754 std::optional<unsigned> ResultIndex = this->allocateLocal(BO);
755 if (!this->emitGetPtrLocal(*ResultIndex, BO))
759 if (!visit(LHS) || !visit(RHS))
762 return this->emitCMP3(*
LT, CmpInfo, BO);
765 if (!
LT || !RT || !
T)
771 return this->VisitPointerArithBinOp(BO);
776 if (!visit(RHS) || !visit(LHS))
778 if (!this->emitFlip(*
LT, *RT, BO))
781 if (!visit(LHS) || !visit(RHS))
787 auto MaybeCastToBool = [
this,
T, BO](
bool Result) {
791 return this->emitPop(*
T, BO);
793 return this->emitCast(
PT_Bool, *
T, BO);
797 auto Discard = [
this,
T, BO](
bool Result) {
800 return DiscardResult ? this->emitPop(*
T, BO) :
true;
805 return MaybeCastToBool(this->emitEQ(*
LT, BO));
807 return MaybeCastToBool(this->emitNE(*
LT, BO));
809 return MaybeCastToBool(this->emitLT(*
LT, BO));
811 return MaybeCastToBool(this->emitLE(*
LT, BO));
813 return MaybeCastToBool(this->emitGT(*
LT, BO));
815 return MaybeCastToBool(this->emitGE(*
LT, BO));
818 return Discard(this->emitSubf(getRoundingMode(BO), BO));
819 return Discard(this->emitSub(*
T, BO));
822 return Discard(this->emitAddf(getRoundingMode(BO), BO));
823 return Discard(this->emitAdd(*
T, BO));
826 return Discard(this->emitMulf(getRoundingMode(BO), BO));
827 return Discard(this->emitMul(*
T, BO));
829 return Discard(this->emitRem(*
T, BO));
832 return Discard(this->emitDivf(getRoundingMode(BO), BO));
833 return Discard(this->emitDiv(*
T, BO));
837 : this->emitStorePop(*
T, BO);
839 if (!this->emitStoreBitField(*
T, BO))
842 if (!this->emitStore(*
T, BO))
848 return this->emitLoadPop(*
T, BO);
851 return Discard(this->emitBitAnd(*
T, BO));
853 return Discard(this->emitBitOr(*
T, BO));
855 return Discard(this->emitShl(*
LT, *RT, BO));
857 return Discard(this->emitShr(*
LT, *RT, BO));
859 return Discard(this->emitBitXor(*
T, BO));
862 llvm_unreachable(
"Already handled earlier");
867 llvm_unreachable(
"Unhandled binary op");
872template <
class Emitter>
875 const Expr *LHS =
E->getLHS();
876 const Expr *RHS =
E->getRHS();
878 if ((Op != BO_Add && Op != BO_Sub) ||
882 std::optional<PrimType>
LT = classify(LHS);
883 std::optional<PrimType> RT = classify(RHS);
893 if (!visit(RHS) || !visit(LHS))
896 return this->emitSubPtr(classifyPrim(
E->
getType()),
E);
901 if (!visit(RHS) || !visit(LHS))
905 if (!visit(LHS) || !visit(RHS))
913 return this->emitAddOffset(OffsetType,
E);
914 else if (Op == BO_Sub)
915 return this->emitSubOffset(OffsetType,
E);
920template <
class Emitter>
922 assert(
E->isLogicalOp());
924 const Expr *LHS =
E->getLHS();
925 const Expr *RHS =
E->getRHS();
926 std::optional<PrimType>
T = classify(
E->
getType());
930 LabelTy LabelTrue = this->getLabel();
931 LabelTy LabelEnd = this->getLabel();
933 if (!this->visitBool(LHS))
935 if (!this->jumpTrue(LabelTrue))
938 if (!this->visitBool(RHS))
940 if (!this->jump(LabelEnd))
943 this->emitLabel(LabelTrue);
944 this->emitConstBool(
true,
E);
945 this->fallthrough(LabelEnd);
946 this->emitLabel(LabelEnd);
949 assert(Op == BO_LAnd);
952 LabelTy LabelFalse = this->getLabel();
953 LabelTy LabelEnd = this->getLabel();
955 if (!this->visitBool(LHS))
957 if (!this->jumpFalse(LabelFalse))
960 if (!this->visitBool(RHS))
962 if (!this->jump(LabelEnd))
965 this->emitLabel(LabelFalse);
966 this->emitConstBool(
false,
E);
967 this->fallthrough(LabelEnd);
968 this->emitLabel(LabelEnd);
972 return this->emitPopBool(
E);
981template <
class Emitter>
985 unsigned LocalIndex = allocateTemporary(
E);
986 if (!this->emitGetPtrLocal(LocalIndex,
E))
992 const Expr *LHS =
E->getLHS();
993 const Expr *RHS =
E->getRHS();
996 unsigned ResultOffset = ~0u;
998 ResultOffset = this->allocateLocalPrimitive(
E,
PT_Ptr,
true,
false);
1001 if (!this->DiscardResult) {
1002 if (!this->emitDupPtr(
E))
1004 if (!this->emitSetLocal(
PT_Ptr, ResultOffset,
E))
1009 LHSType = AT->getValueType();
1012 RHSType = AT->getValueType();
1021 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1026 if (!this->visit(LHS))
1028 if (!this->visit(RHS))
1030 return this->emitMulc(ElemT,
E);
1033 if (Op == BO_Div && RHSIsComplex) {
1035 PrimType ElemT = classifyPrim(ElemQT);
1040 if (!LHSIsComplex) {
1042 LHSOffset = allocateTemporary(RHS);
1044 if (!this->emitGetPtrLocal(LHSOffset,
E))
1047 if (!this->visit(LHS))
1050 if (!this->emitInitElem(ElemT, 0,
E))
1053 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1055 if (!this->emitInitElem(ElemT, 1,
E))
1058 if (!this->visit(LHS))
1062 if (!this->visit(RHS))
1064 return this->emitDivc(ElemT,
E);
1069 LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
1070 if (!this->visit(LHS))
1072 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1075 PrimType LHST = classifyPrim(LHSType);
1076 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
1077 if (!this->visit(LHS))
1079 if (!this->emitSetLocal(LHST, LHSOffset,
E))
1086 RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
1087 if (!this->visit(RHS))
1089 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1092 PrimType RHST = classifyPrim(RHSType);
1093 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
1094 if (!this->visit(RHS))
1096 if (!this->emitSetLocal(RHST, RHSOffset,
E))
1103 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1104 unsigned ElemIndex,
unsigned Offset,
1105 const Expr *
E) ->
bool {
1107 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
1109 return this->emitArrayElemPop(classifyComplexElementType(
E->
getType()),
1112 if (ElemIndex == 0 || !LoadZero)
1113 return this->emitGetLocal(classifyPrim(
E->
getType()), Offset,
E);
1114 return this->visitZeroInitializer(classifyPrim(
E->
getType()),
E->
getType(),
1119 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1121 if (!this->DiscardResult) {
1122 if (!this->emitGetLocal(
PT_Ptr, ResultOffset,
E))
1129 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1132 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1135 if (!this->emitAddf(getRoundingMode(
E),
E))
1138 if (!this->emitAdd(ResultElemT,
E))
1143 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1146 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1149 if (!this->emitSubf(getRoundingMode(
E),
E))
1152 if (!this->emitSub(ResultElemT,
E))
1157 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1160 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1164 if (!this->emitMulf(getRoundingMode(
E),
E))
1167 if (!this->emitMul(ResultElemT,
E))
1172 assert(!RHSIsComplex);
1173 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1176 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1180 if (!this->emitDivf(getRoundingMode(
E),
E))
1183 if (!this->emitDiv(ResultElemT,
E))
1192 if (!this->DiscardResult) {
1194 if (!this->emitInitElemPop(ResultElemT, ElemIndex,
E))
1197 if (!this->emitPop(ResultElemT,
E))
1204template <
class Emitter>
1209 if (std::optional<PrimType>
T = classify(QT))
1210 return this->visitZeroInitializer(*
T, QT,
E);
1224 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1225 CXXRD && CXXRD->getNumVBases() > 0) {
1230 const Record *R = getRecord(QT);
1234 assert(Initializing);
1235 return this->visitZeroRecordInitializer(R,
E);
1244 const auto *CAT = cast<ConstantArrayType>(AT);
1245 size_t NumElems = CAT->getZExtSize();
1246 PrimType ElemT = classifyPrim(CAT->getElementType());
1248 for (
size_t I = 0; I != NumElems; ++I) {
1249 if (!this->visitZeroInitializer(ElemT, CAT->getElementType(),
E))
1251 if (!this->emitInitElem(ElemT, I,
E))
1259 assert(Initializing);
1260 QualType ElemQT = ComplexTy->getElementType();
1261 PrimType ElemT = classifyPrim(ElemQT);
1262 for (
unsigned I = 0; I < 2; ++I) {
1263 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1265 if (!this->emitInitElem(ElemT, I,
E))
1272 unsigned NumVecElements = VecT->getNumElements();
1273 QualType ElemQT = VecT->getElementType();
1274 PrimType ElemT = classifyPrim(ElemQT);
1276 for (
unsigned I = 0; I < NumVecElements; ++I) {
1277 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1279 if (!this->emitInitElem(ElemT, I,
E))
1288template <
class Emitter>
1290 const Expr *LHS =
E->getLHS();
1291 const Expr *RHS =
E->getRHS();
1292 const Expr *Index =
E->getIdx();
1295 return this->discard(LHS) && this->discard(RHS);
1300 for (
const Expr *SubExpr : {LHS, RHS}) {
1301 if (!this->visit(SubExpr))
1308 PrimType IndexT = classifyPrim(Index->getType());
1311 if (!this->emitFlip(
PT_Ptr, IndexT,
E))
1315 return this->emitArrayElemPtrPop(IndexT,
E);
1318template <
class Emitter>
1320 const Expr *ArrayFiller,
const Expr *
E) {
1325 QT = AT->getValueType();
1328 return this->emitInvalid(
E);
1331 if (DiscardResult) {
1333 if (!this->discard(
Init))
1340 if (std::optional<PrimType>
T = classify(QT)) {
1341 assert(!DiscardResult);
1342 if (Inits.size() == 0)
1343 return this->visitZeroInitializer(*
T, QT,
E);
1344 assert(Inits.size() == 1);
1345 return this->delegate(Inits[0]);
1349 const Record *R = getRecord(QT);
1351 if (Inits.size() == 1 &&
E->
getType() == Inits[0]->getType())
1352 return this->delegate(Inits[0]);
1354 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
1357 if (!this->visit(
Init))
1360 if (FieldToInit->isBitField())
1361 return this->emitInitBitField(
T, FieldToInit,
E);
1362 return this->emitInitField(
T, FieldToInit->Offset,
E);
1365 auto initCompositeField = [=](
const Record::Field *FieldToInit,
1371 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
1373 if (!this->visitInitializer(
Init))
1375 return this->emitPopPtr(
E);
1379 if (Inits.size() == 0) {
1380 if (!this->visitZeroRecordInitializer(R,
E))
1385 if (
const auto *ILE = dyn_cast<InitListExpr>(
E))
1386 FToInit = ILE->getInitializedFieldInUnion();
1388 FToInit = cast<CXXParenListInitExpr>(
E)->getInitializedFieldInUnion();
1390 const Record::Field *FieldToInit = R->
getField(FToInit);
1391 if (std::optional<PrimType>
T = classify(
Init)) {
1392 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1395 if (!initCompositeField(FieldToInit,
Init))
1399 return this->emitFinishInit(
E);
1403 unsigned InitIndex = 0;
1406 while (InitIndex < R->getNumFields() &&
1410 if (std::optional<PrimType>
T = classify(
Init)) {
1411 const Record::Field *FieldToInit = R->
getField(InitIndex);
1412 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1417 if (
const Record::Base *B = R->
getBase(
Init->getType())) {
1418 if (!this->emitGetPtrBase(B->Offset,
Init))
1421 if (!this->visitInitializer(
Init))
1424 if (!this->emitFinishInitPop(
E))
1429 const Record::Field *FieldToInit = R->
getField(InitIndex);
1430 if (!initCompositeField(FieldToInit,
Init))
1436 return this->emitFinishInit(
E);
1440 if (Inits.size() == 1 && QT == Inits[0]->getType())
1441 return this->delegate(Inits[0]);
1443 unsigned ElementIndex = 0;
1445 if (
const auto *EmbedS =
1446 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1449 auto Eval = [&](
const Expr *
Init,
unsigned ElemIndex) {
1451 if (!this->visit(
Init))
1453 if (InitT != TargetT) {
1454 if (!this->emitCast(InitT, TargetT,
E))
1457 return this->emitInitElem(TargetT, ElemIndex,
Init);
1459 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
1462 if (!this->visitArrayElemInit(ElementIndex,
Init))
1472 Ctx.getASTContext().getAsConstantArrayType(QT);
1475 for (; ElementIndex != NumElems; ++ElementIndex) {
1476 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller))
1481 return this->emitFinishInit(
E);
1485 unsigned NumInits = Inits.size();
1488 return this->delegate(Inits[0]);
1490 QualType ElemQT = ComplexTy->getElementType();
1491 PrimType ElemT = classifyPrim(ElemQT);
1492 if (NumInits == 0) {
1494 for (
unsigned I = 0; I < 2; ++I) {
1495 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1497 if (!this->emitInitElem(ElemT, I,
E))
1500 }
else if (NumInits == 2) {
1501 unsigned InitIndex = 0;
1503 if (!this->visit(
Init))
1506 if (!this->emitInitElem(ElemT, InitIndex,
E))
1515 unsigned NumVecElements = VecT->getNumElements();
1516 assert(NumVecElements >= Inits.size());
1518 QualType ElemQT = VecT->getElementType();
1519 PrimType ElemT = classifyPrim(ElemQT);
1522 unsigned InitIndex = 0;
1524 if (!this->visit(
Init))
1529 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
1530 if (!this->emitCopyArray(ElemT, 0, InitIndex,
1531 InitVecT->getNumElements(),
E))
1533 InitIndex += InitVecT->getNumElements();
1535 if (!this->emitInitElem(ElemT, InitIndex,
E))
1541 assert(InitIndex <= NumVecElements);
1544 for (; InitIndex != NumVecElements; ++InitIndex) {
1545 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1547 if (!this->emitInitElem(ElemT, InitIndex,
E))
1558template <
class Emitter>
1561 if (std::optional<PrimType>
T = classify(
Init->getType())) {
1563 if (!this->visit(
Init))
1565 return this->emitInitElem(*
T, ElemIndex,
Init);
1571 if (!this->emitConstUint32(ElemIndex,
Init))
1573 if (!this->emitArrayElemPtrUint32(
Init))
1575 if (!this->visitInitializer(
Init))
1577 return this->emitFinishInitPop(
Init);
1580template <
class Emitter>
1582 return this->visitInitList(
E->inits(),
E->getArrayFiller(),
E);
1585template <
class Emitter>
1588 return this->visitInitList(
E->getInitExprs(),
E->getArrayFiller(),
E);
1591template <
class Emitter>
1594 return this->delegate(
E->getReplacement());
1597template <
class Emitter>
1599 std::optional<PrimType>
T = classify(
E->
getType());
1600 if (
T &&
E->hasAPValueResult()) {
1607 if (this->visitAPValue(
E->getAPValueResult(), *
T,
E))
1610 return this->delegate(
E->getSubExpr());
1613template <
class Emitter>
1615 auto It =
E->begin();
1616 return this->visit(*It);
1621 bool AlignOfReturnsPreferred =
1622 ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
1630 if (
T.getQualifiers().hasUnaligned())
1636 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
1642template <
class Emitter>
1646 const ASTContext &ASTCtx = Ctx.getASTContext();
1648 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
1649 QualType ArgType =
E->getTypeOfArgument();
1663 if (Kind == UETT_SizeOf)
1672 return this->emitConst(Size.getQuantity(),
E);
1675 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
1678 if (
E->isArgumentType()) {
1679 QualType ArgType =
E->getTypeOfArgument();
1692 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
1695 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
1705 return this->emitConst(Size.getQuantity(),
E);
1708 if (Kind == UETT_VectorElements) {
1709 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>())
1710 return this->emitConst(VT->getNumElements(),
E);
1711 assert(
E->getTypeOfArgument()->isSizelessVectorType());
1712 return this->emitSizelessVectorElementSize(
E);
1715 if (Kind == UETT_VecStep) {
1716 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>()) {
1717 unsigned N = VT->getNumElements();
1724 return this->emitConst(N,
E);
1726 return this->emitConst(1,
E);
1732template <
class Emitter>
1739 return this->discard(
Base);
1743 const auto maybeLoadValue = [&]() ->
bool {
1746 if (std::optional<PrimType>
T = classify(
E))
1747 return this->emitLoadPop(*
T,
E);
1751 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
1755 if (
auto GlobalIndex =
P.getGlobal(VD))
1756 return this->emitGetPtrGlobal(*GlobalIndex,
E) && maybeLoadValue();
1760 if (!isa<FieldDecl>(
Member))
1761 return this->discard(
Base) && this->visitDeclRef(
Member,
E);
1764 if (!this->delegate(
Base))
1767 if (!this->visit(
Base))
1772 const auto *FD = cast<FieldDecl>(
Member);
1774 const Record *R = getRecord(RD);
1777 const Record::Field *F = R->
getField(FD);
1779 if (F->Decl->getType()->isReferenceType())
1780 return this->emitGetFieldPop(
PT_Ptr, F->Offset,
E) && maybeLoadValue();
1781 return this->emitGetPtrFieldPop(F->Offset,
E) && maybeLoadValue();
1784template <
class Emitter>
1790 return this->emitConst(*ArrayIndex,
E);
1793template <
class Emitter>
1795 assert(Initializing);
1796 assert(!DiscardResult);
1800 if (!this->discard(
E->getCommonExpr()))
1805 const Expr *SubExpr =
E->getSubExpr();
1806 size_t Size =
E->getArraySize().getZExtValue();
1811 for (
size_t I = 0; I != Size; ++I) {
1815 if (!this->visitArrayElemInit(I, SubExpr))
1823template <
class Emitter>
1825 const Expr *SourceExpr =
E->getSourceExpr();
1830 return this->visitInitializer(SourceExpr);
1833 if (
auto It = OpaqueExprs.find(
E); It != OpaqueExprs.end())
1834 return this->emitGetLocal(SubExprT, It->second,
E);
1836 if (!this->visit(SourceExpr))
1842 unsigned LocalIndex = allocateLocalPrimitive(
E, SubExprT,
true);
1843 if (!this->emitSetLocal(SubExprT, LocalIndex,
E))
1848 if (!DiscardResult) {
1849 if (!this->emitGetLocal(SubExprT, LocalIndex,
E))
1854 OpaqueExprs.insert({
E, LocalIndex});
1859template <
class Emitter>
1863 const Expr *TrueExpr =
E->getTrueExpr();
1864 const Expr *FalseExpr =
E->getFalseExpr();
1866 LabelTy LabelEnd = this->getLabel();
1867 LabelTy LabelFalse = this->getLabel();
1872 if (!this->jumpFalse(LabelFalse))
1877 if (!this->delegate(TrueExpr))
1879 if (!S.destroyLocals())
1883 if (!this->jump(LabelEnd))
1886 this->emitLabel(LabelFalse);
1890 if (!this->delegate(FalseExpr))
1892 if (!S.destroyLocals())
1896 this->fallthrough(LabelEnd);
1897 this->emitLabel(LabelEnd);
1902template <
class Emitter>
1907 if (!Initializing) {
1908 unsigned StringIndex =
P.createGlobalString(
E);
1909 return this->emitGetPtrGlobal(StringIndex,
E);
1914 Ctx.getASTContext().getAsConstantArrayType(
E->
getType());
1915 assert(CAT &&
"a string literal that's not a constant array?");
1920 unsigned N = std::min(ArraySize,
E->getLength());
1921 size_t CharWidth =
E->getCharByteWidth();
1923 for (
unsigned I = 0; I != N; ++I) {
1924 uint32_t CodeUnit =
E->getCodeUnit(I);
1926 if (CharWidth == 1) {
1927 this->emitConstSint8(CodeUnit,
E);
1928 this->emitInitElemSint8(I,
E);
1929 }
else if (CharWidth == 2) {
1930 this->emitConstUint16(CodeUnit,
E);
1931 this->emitInitElemUint16(I,
E);
1932 }
else if (CharWidth == 4) {
1933 this->emitConstUint32(CodeUnit,
E);
1934 this->emitInitElemUint32(I,
E);
1936 llvm_unreachable(
"unsupported character width");
1941 for (
unsigned I = N; I != ArraySize; ++I) {
1942 if (CharWidth == 1) {
1943 this->emitConstSint8(0,
E);
1944 this->emitInitElemSint8(I,
E);
1945 }
else if (CharWidth == 2) {
1946 this->emitConstUint16(0,
E);
1947 this->emitInitElemUint16(I,
E);
1948 }
else if (CharWidth == 4) {
1949 this->emitConstUint32(0,
E);
1950 this->emitInitElemUint32(I,
E);
1952 llvm_unreachable(
"unsupported character width");
1959template <
class Emitter>
1961 return this->delegate(
E->getString());
1964template <
class Emitter>
1966 auto &A = Ctx.getASTContext();
1968 A.getObjCEncodingForType(
E->getEncodedType(), Str);
1972 return this->delegate(SL);
1975template <
class Emitter>
1981 assert(!Initializing);
1983 auto &A = Ctx.getASTContext();
1984 std::string ResultStr =
E->ComputeName(A);
1987 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
1988 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
1989 ArraySizeModifier::Normal, 0);
1993 false, ArrayTy,
E->getLocation());
1995 unsigned StringIndex =
P.createGlobalString(SL);
1996 return this->emitGetPtrGlobal(StringIndex,
E);
1999template <
class Emitter>
2003 return this->emitConst(
E->getValue(),
E);
2006template <
class Emitter>
2010 const Expr *LHS =
E->getLHS();
2011 const Expr *RHS =
E->getRHS();
2013 QualType LHSComputationType =
E->getComputationLHSType();
2014 QualType ResultType =
E->getComputationResultType();
2015 std::optional<PrimType>
LT = classify(LHSComputationType);
2016 std::optional<PrimType> RT = classify(ResultType);
2023 PrimType LHST = classifyPrim(LHSType);
2031 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2032 if (!this->emitSetLocal(*RT, TempOffset,
E))
2038 if (!this->emitLoad(LHST,
E))
2042 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
2043 LHSComputationType,
E))
2047 if (!this->emitGetLocal(*RT, TempOffset,
E))
2050 llvm::RoundingMode RM = getRoundingMode(
E);
2051 switch (
E->getOpcode()) {
2053 if (!this->emitAddf(RM,
E))
2057 if (!this->emitSubf(RM,
E))
2061 if (!this->emitMulf(RM,
E))
2065 if (!this->emitDivf(RM,
E))
2072 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->
getType(),
E))
2076 return this->emitStorePop(LHST,
E);
2077 return this->emitStore(LHST,
E);
2080template <
class Emitter>
2084 const Expr *LHS =
E->getLHS();
2085 const Expr *RHS =
E->getRHS();
2086 std::optional<PrimType>
LT = classify(LHS->
getType());
2087 std::optional<PrimType> RT = classify(RHS->
getType());
2089 if (Op != BO_AddAssign && Op != BO_SubAssign)
2098 if (!this->emitLoad(*
LT, LHS))
2104 if (Op == BO_AddAssign) {
2105 if (!this->emitAddOffset(*RT,
E))
2108 if (!this->emitSubOffset(*RT,
E))
2113 return this->emitStorePopPtr(
E);
2114 return this->emitStorePtr(
E);
2117template <
class Emitter>
2121 const Expr *LHS =
E->getLHS();
2122 const Expr *RHS =
E->getRHS();
2123 std::optional<PrimType> LHSComputationT =
2124 classify(
E->getComputationLHSType());
2125 std::optional<PrimType>
LT = classify(LHS->
getType());
2126 std::optional<PrimType> RT = classify(RHS->
getType());
2127 std::optional<PrimType> ResultT = classify(
E->
getType());
2129 if (!Ctx.getLangOpts().CPlusPlus14)
2130 return this->visit(RHS) && this->visit(LHS) && this->emitError(
E);
2132 if (!
LT || !RT || !ResultT || !LHSComputationT)
2139 return VisitFloatCompoundAssignOperator(
E);
2142 return VisitPointerCompoundAssignOperator(
E);
2155 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2157 if (!this->emitSetLocal(*RT, TempOffset,
E))
2164 if (!this->emitLoad(*
LT,
E))
2166 if (
LT != LHSComputationT) {
2167 if (!this->emitCast(*
LT, *LHSComputationT,
E))
2172 if (!this->emitGetLocal(*RT, TempOffset,
E))
2176 switch (
E->getOpcode()) {
2178 if (!this->emitAdd(*LHSComputationT,
E))
2182 if (!this->emitSub(*LHSComputationT,
E))
2186 if (!this->emitMul(*LHSComputationT,
E))
2190 if (!this->emitDiv(*LHSComputationT,
E))
2194 if (!this->emitRem(*LHSComputationT,
E))
2198 if (!this->emitShl(*LHSComputationT, *RT,
E))
2202 if (!this->emitShr(*LHSComputationT, *RT,
E))
2206 if (!this->emitBitAnd(*LHSComputationT,
E))
2210 if (!this->emitBitXor(*LHSComputationT,
E))
2214 if (!this->emitBitOr(*LHSComputationT,
E))
2218 llvm_unreachable(
"Unimplemented compound assign operator");
2222 if (ResultT != LHSComputationT) {
2223 if (!this->emitCast(*LHSComputationT, *ResultT,
E))
2228 if (DiscardResult) {
2230 return this->emitStoreBitFieldPop(*ResultT,
E);
2231 return this->emitStorePop(*ResultT,
E);
2234 return this->emitStoreBitField(*ResultT,
E);
2235 return this->emitStore(*ResultT,
E);
2238template <
class Emitter>
2241 const Expr *SubExpr =
E->getSubExpr();
2246template <
class Emitter>
2249 const Expr *SubExpr =
E->getSubExpr();
2253 return this->delegate(SubExpr);
2258 return this->discard(SubExpr);
2262 std::optional<PrimType> SubExprT = classify(SubExpr);
2265 std::optional<unsigned> GlobalIndex =
P.createGlobal(
E);
2270 E->getLifetimeExtendedTemporaryDecl();
2275 if (!this->visit(SubExpr))
2278 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl,
E))
2281 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex,
E))
2284 return this->emitGetPtrGlobal(*GlobalIndex,
E);
2288 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2290 if (!this->visitInitializer(SubExpr))
2293 return this->emitInitGlobalTempComp(TempDecl,
E);
2299 unsigned LocalIndex = allocateLocalPrimitive(
2300 SubExpr, *SubExprT,
true,
true);
2301 if (!this->visit(SubExpr))
2303 if (!this->emitSetLocal(*SubExprT, LocalIndex,
E))
2305 return this->emitGetPtrLocal(LocalIndex,
E);
2308 if (std::optional<unsigned> LocalIndex =
2309 allocateLocal(Inner,
E->getExtendingDecl())) {
2311 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2313 return this->visitInitializer(SubExpr);
2319template <
class Emitter>
2322 return this->delegate(
E->getSubExpr());
2325template <
class Emitter>
2329 return this->discard(
Init);
2333 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2336 std::optional<PrimType>
T = classify(
E->
getType());
2337 if (
E->isFileScope()) {
2340 return this->delegate(
Init);
2342 if (std::optional<unsigned> GlobalIndex =
P.createGlobal(
E)) {
2343 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2347 if (!this->visit(
Init))
2349 return this->emitInitGlobal(*
T, *GlobalIndex,
E);
2352 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2361 return this->delegate(
Init);
2363 unsigned LocalIndex;
2366 LocalIndex = this->allocateLocalPrimitive(
Init, *
T,
false,
false);
2367 else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(
Init))
2368 LocalIndex = *MaybeIndex;
2372 if (!this->emitGetPtrLocal(LocalIndex,
E))
2376 if (!this->visit(
Init)) {
2379 return this->emitInit(*
T,
E);
2381 if (!this->visitInitializer(
Init) || !this->emitFinishInit(
E))
2390template <
class Emitter>
2395 return this->emitConstBool(
E->getValue(),
E);
2396 return this->emitConst(
E->getValue(),
E);
2399template <
class Emitter>
2403 return this->emitConst(
E->getValue(),
E);
2406template <
class Emitter>
2411 assert(Initializing);
2412 const Record *R =
P.getOrCreateRecord(
E->getLambdaClass());
2414 auto *CaptureInitIt =
E->capture_init_begin();
2417 for (
const Record::Field &F : R->
fields()) {
2424 if (std::optional<PrimType>
T = classify(
Init)) {
2425 if (!this->visit(
Init))
2428 if (!this->emitInitField(*
T, F.Offset,
E))
2431 if (!this->emitGetPtrField(F.Offset,
E))
2434 if (!this->visitInitializer(
Init))
2437 if (!this->emitPopPtr(
E))
2445template <
class Emitter>
2450 return this->delegate(
E->getFunctionName());
2453template <
class Emitter>
2455 if (
E->getSubExpr() && !this->discard(
E->getSubExpr()))
2458 return this->emitInvalid(
E);
2461template <
class Emitter>
2464 const Expr *SubExpr =
E->getSubExpr();
2466 bool TypesMatch = classify(
E) == classify(SubExpr);
2467 if (!this->emitInvalidCast(CastKind::Reinterpret, !TypesMatch,
E))
2470 return this->delegate(SubExpr);
2473template <
class Emitter>
2479 return this->emitConstBool(
E->getValue(),
E);
2482template <
class Emitter>
2485 assert(!classify(
T));
2495 return this->visitInitializer(
E->getArg(0));
2499 if (DiscardResult) {
2502 assert(!Initializing);
2503 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2508 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2513 if (
E->requiresZeroInitialization()) {
2516 if (!this->visitZeroRecordInitializer(R,
E))
2529 assert(
Func->hasThisPointer());
2530 assert(!
Func->hasRVO());
2534 if (!this->emitDupPtr(
E))
2538 for (
const auto *Arg :
E->arguments()) {
2539 if (!this->visit(Arg))
2543 if (
Func->isVariadic()) {
2544 uint32_t VarArgSize = 0;
2545 unsigned NumParams =
Func->getNumWrittenParams();
2546 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I) {
2550 if (!this->emitCallVar(
Func, VarArgSize,
E))
2553 if (!this->emitCall(
Func, 0,
E))
2558 return this->emitPopPtr(
E);
2559 return this->emitFinishInit(
E);
2564 Ctx.getASTContext().getAsConstantArrayType(
E->
getType());
2575 for (
size_t I = 0; I != NumElems; ++I) {
2576 if (!this->emitConstUint64(I,
E))
2578 if (!this->emitArrayElemPtrUint64(
E))
2582 for (
const auto *Arg :
E->arguments()) {
2583 if (!this->visit(Arg))
2587 if (!this->emitCall(
Func, 0,
E))
2596template <
class Emitter>
2602 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
2606 assert(Val.
isInt());
2608 return this->emitConst(I,
E);
2615 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
2616 return this->visit(LValueExpr);
2625 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
2627 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(UGCD);
2631 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2635 const APValue &
V = UGCD->getValue();
2636 for (
unsigned I = 0, N = R->
getNumFields(); I != N; ++I) {
2637 const Record::Field *F = R->
getField(I);
2638 const APValue &FieldValue =
V.getStructField(I);
2640 PrimType FieldT = classifyPrim(F->Decl->getType());
2642 if (!this->visitAPValue(FieldValue, FieldT,
E))
2644 if (!this->emitInitField(FieldT, F->Offset,
E))
2652template <
class Emitter>
2654 unsigned N =
E->getNumComponents();
2658 for (
unsigned I = 0; I != N; ++I) {
2661 const Expr *ArrayIndexExpr =
E->getIndexExpr(
Node.getArrayExprIndex());
2664 if (DiscardResult) {
2665 if (!this->discard(ArrayIndexExpr))
2670 if (!this->visit(ArrayIndexExpr))
2684 return this->emitOffsetOf(
T,
E,
E);
2687template <
class Emitter>
2695 if (std::optional<PrimType>
T = classify(Ty))
2696 return this->visitZeroInitializer(*
T, Ty,
E);
2699 if (!Initializing) {
2700 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2703 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2708 QualType ElemQT = CT->getElementType();
2709 PrimType ElemT = classifyPrim(ElemQT);
2711 for (
unsigned I = 0; I != 2; ++I) {
2712 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
2714 if (!this->emitInitElem(ElemT, I,
E))
2722 if (!Initializing) {
2723 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2726 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2731 QualType ElemQT = VT->getElementType();
2732 PrimType ElemT = classifyPrim(ElemQT);
2734 for (
unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
2735 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
2737 if (!this->emitInitElem(ElemT, I,
E))
2746template <
class Emitter>
2748 return this->emitConst(
E->getPackLength(),
E);
2751template <
class Emitter>
2754 return this->delegate(
E->getResultExpr());
2757template <
class Emitter>
2759 return this->delegate(
E->getChosenSubExpr());
2762template <
class Emitter>
2767 return this->emitConst(
E->getValue(),
E);
2770template <
class Emitter>
2775 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
2776 const Function *F = this->getFunction(Ctor);
2793 if (!this->emitGetParam(PT, Offset,
E))
2798 return this->emitCall(F, 0,
E);
2801template <
class Emitter>
2805 QualType ElementType =
E->getAllocatedType();
2806 std::optional<PrimType> ElemT = classify(ElementType);
2807 unsigned PlacementArgs =
E->getNumPlacementArgs();
2808 bool IsNoThrow =
false;
2811 if (PlacementArgs != 0) {
2823 return this->emitInvalid(
E);
2825 if (!this->discard(
E->getPlacementArg(0)))
2839 Desc =
P.createDescriptor(
2842 false,
false,
false,
Init);
2846 std::optional<const Expr *> ArraySizeExpr =
E->getArraySize();
2850 const Expr *Stripped = *ArraySizeExpr;
2851 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
2852 Stripped = ICE->getSubExpr())
2853 if (ICE->getCastKind() != CK_NoOp &&
2854 ICE->getCastKind() != CK_IntegralCast)
2859 if (!this->visit(Stripped))
2864 if (!this->emitAllocN(SizeT, *ElemT,
E, IsNoThrow,
E))
2868 if (!this->emitAllocCN(SizeT, Desc, IsNoThrow,
E))
2872 if (
Init && !this->visitInitializer(
Init))
2877 if (!this->emitAlloc(Desc,
E))
2882 if (!this->visit(
Init))
2885 if (!this->emitInit(*ElemT,
E))
2889 if (!this->visitInitializer(
Init))
2896 return this->emitPopPtr(
E);
2901template <
class Emitter>
2903 const Expr *Arg =
E->getArgument();
2906 if (!this->visit(Arg))
2909 return this->emitFree(
E->isArrayForm(),
E);
2912template <
class Emitter>
2920 return this->emitGetFnPtr(
Func,
E);
2923template <
class Emitter>
2925 assert(Ctx.getLangOpts().CPlusPlus);
2926 return this->emitConstBool(
E->getValue(),
E);
2929template <
class Emitter>
2933 assert(!Initializing);
2941 if (std::optional<unsigned> I =
P.getOrCreateDummy(GuidDecl))
2942 return this->emitGetPtrGlobal(*I,
E);
2946 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(GuidDecl);
2949 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2952 assert(this->getRecord(
E->
getType()));
2958 assert(
V.isStruct());
2959 assert(
V.getStructNumBases() == 0);
2960 if (!this->visitAPValueInitializer(
V,
E))
2963 return this->emitFinishInit(
E);
2966template <
class Emitter>
2971 return this->emitConstBool(
E->isSatisfied(),
E);
2974template <
class Emitter>
2980 return this->emitConstBool(
E->isSatisfied(),
E);
2983template <
class Emitter>
2986 return this->delegate(
E->getSemanticForm());
2989template <
class Emitter>
2992 for (
const Expr *SemE :
E->semantics()) {
2993 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
2994 if (SemE ==
E->getResultExpr())
2997 if (OVE->isUnique())
3000 if (!this->discard(OVE))
3002 }
else if (SemE ==
E->getResultExpr()) {
3003 if (!this->delegate(SemE))
3006 if (!this->discard(SemE))
3013template <
class Emitter>
3015 return this->delegate(
E->getSelectedExpr());
3018template <
class Emitter>
3020 return this->emitError(
E);
3023template <
class Emitter>
3027 unsigned Offset = allocateLocalPrimitive(
3028 E->getLabel(),
PT_Ptr,
true,
false);
3030 return this->emitGetLocal(
PT_Ptr, Offset,
E);
3033template <
class Emitter>
3035 assert(Initializing);
3037 QualType ElemType = VT->getElementType();
3038 PrimType ElemT = classifyPrim(ElemType);
3039 const Expr *Src =
E->getSrcExpr();
3043 unsigned SrcOffset = this->allocateLocalPrimitive(Src,
PT_Ptr,
true,
false);
3044 if (!this->visit(Src))
3046 if (!this->emitSetLocal(
PT_Ptr, SrcOffset,
E))
3049 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
3050 if (!this->emitGetLocal(
PT_Ptr, SrcOffset,
E))
3052 if (!this->emitArrayElemPop(SrcElemT, I,
E))
3054 if (SrcElemT != ElemT) {
3055 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType,
E))
3058 if (!this->emitInitElem(ElemT, I,
E))
3065template <
class Emitter>
3067 assert(Initializing);
3068 assert(
E->getNumSubExprs() > 2);
3070 const Expr *Vecs[] = {
E->getExpr(0),
E->getExpr(1)};
3074 unsigned NumOutputElems =
E->getNumSubExprs() - 2;
3075 assert(NumOutputElems > 0);
3078 unsigned VectorOffsets[2];
3079 for (
unsigned I = 0; I != 2; ++I) {
3080 VectorOffsets[I] = this->allocateLocalPrimitive(
3081 Vecs[I],
PT_Ptr,
true,
false);
3082 if (!this->visit(Vecs[I]))
3084 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I],
E))
3087 for (
unsigned I = 0; I != NumOutputElems; ++I) {
3088 APSInt ShuffleIndex =
E->getShuffleMaskIdx(Ctx.getASTContext(), I);
3089 if (ShuffleIndex == -1)
3090 return this->emitInvalid(
E);
3092 assert(ShuffleIndex < (NumInputElems * 2));
3093 if (!this->emitGetLocal(
PT_Ptr,
3094 VectorOffsets[ShuffleIndex >= NumInputElems],
E))
3096 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
3097 if (!this->emitArrayElemPop(ElemT, InputVectorIndex,
E))
3100 if (!this->emitInitElem(ElemT, I,
E))
3107template <
class Emitter>
3112 Base->getType()->isVectorType() ||
3116 E->getEncodedElementAccess(Indices);
3118 if (Indices.size() == 1) {
3119 if (!this->visit(
Base))
3123 if (!this->emitConstUint32(Indices[0],
E))
3125 return this->emitArrayElemPtrPop(
PT_Uint32,
E);
3128 return this->emitArrayElemPop(classifyPrim(
E->
getType()), Indices[0],
E);
3132 unsigned BaseOffset = allocateLocalPrimitive(
Base,
PT_Ptr,
true,
3134 if (!this->visit(
Base))
3136 if (!this->emitSetLocal(
PT_Ptr, BaseOffset,
E))
3140 if (!Initializing) {
3141 std::optional<unsigned> ResultIndex;
3142 ResultIndex = allocateLocal(
E);
3145 if (!this->emitGetPtrLocal(*ResultIndex,
E))
3153 uint32_t DstIndex = 0;
3154 for (uint32_t I : Indices) {
3155 if (!this->emitGetLocal(
PT_Ptr, BaseOffset,
E))
3157 if (!this->emitArrayElemPop(ElemT, I,
E))
3159 if (!this->emitInitElem(ElemT, DstIndex,
E))
3165 assert(!DiscardResult);
3169template <
class Emitter>
3171 const Expr *SubExpr =
E->getSubExpr();
3172 if (!
E->isExpressibleAsConstantInitializer())
3173 return this->discard(SubExpr) && this->emitInvalid(
E);
3175 return this->delegate(SubExpr);
3178template <
class Emitter>
3181 const Expr *SubExpr =
E->getSubExpr();
3183 Ctx.getASTContext().getAsConstantArrayType(SubExpr->
getType());
3185 assert(Initializing);
3188 if (!this->visit(SubExpr))
3200 assert(SecondFieldT ==
PT_Ptr);
3206 if (!this->emitArrayElemPtrPop(
PT_Uint64,
E))
3211template <
class Emitter>
3220 if (!this->visitStmt(S))
3225 assert(S == Result);
3226 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
3227 return this->delegate(ResultExpr);
3228 return this->emitUnsupported(
E);
3237 return this->Visit(
E);
3242 return this->emitError(
E);
3247 return this->Visit(
E);
3255 return this->discard(
E);
3260 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3264 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3266 return this->visitInitializer(
E);
3273 return this->Visit(
E);
3276template <
class Emitter>
3281 return this->emitError(
E);
3283 if (!this->checkLiteralType(
E))
3288 return this->Visit(
E);
3292 std::optional<PrimType>
T = classify(
E->
getType());
3296 if (!this->visit(
E))
3298 return this->emitComplexBoolCast(
E);
3303 if (!this->visit(
E))
3311 if (!this->emitNull(*
T,
nullptr,
E))
3313 return this->emitNE(*
T,
E);
3318 return this->emitCastFloatingIntegralBool(
E);
3324template <
class Emitter>
3329 return this->emitZeroBool(
E);
3331 return this->emitZeroSint8(
E);
3333 return this->emitZeroUint8(
E);
3335 return this->emitZeroSint16(
E);
3337 return this->emitZeroUint16(
E);
3339 return this->emitZeroSint32(
E);
3341 return this->emitZeroUint32(
E);
3343 return this->emitZeroSint64(
E);
3345 return this->emitZeroUint64(
E);
3347 return this->emitZeroIntAP(Ctx.getBitWidth(QT),
E);
3349 return this->emitZeroIntAPS(Ctx.getBitWidth(QT),
E);
3351 return this->emitNullPtr(
nullptr,
E);
3353 return this->emitNullFnPtr(
nullptr,
E);
3355 return this->emitNullMemberPtr(
nullptr,
E);
3357 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)),
E);
3360 llvm_unreachable(
"unknown primitive type");
3363template <
class Emitter>
3369 for (
const Record::Field &Field : R->
fields()) {
3370 if (
Field.Decl->isUnnamedBitField())
3374 if (
D->isPrimitive()) {
3377 if (!this->visitZeroInitializer(
T, QT,
E))
3379 if (!this->emitInitField(
T,
Field.Offset,
E))
3386 if (!this->emitGetPtrField(
Field.Offset,
E))
3389 if (
D->isPrimitiveArray()) {
3392 for (uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
3393 if (!this->visitZeroInitializer(
T, ET,
E))
3395 if (!this->emitInitElem(
T, I,
E))
3398 }
else if (
D->isCompositeArray()) {
3399 const Record *ElemRecord =
D->ElemDesc->ElemRecord;
3400 assert(
D->ElemDesc->ElemRecord);
3401 for (uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
3402 if (!this->emitConstUint32(I,
E))
3406 if (!this->visitZeroRecordInitializer(ElemRecord,
E))
3408 if (!this->emitPopPtr(
E))
3411 }
else if (
D->isRecord()) {
3412 if (!this->visitZeroRecordInitializer(
D->ElemRecord,
E))
3418 if (!this->emitFinishInitPop(
E))
3425 for (
const Record::Base &B : R->
bases()) {
3426 if (!this->emitGetPtrBase(B.Offset,
E))
3428 if (!this->visitZeroRecordInitializer(B.R,
E))
3430 if (!this->emitFinishInitPop(
E))
3439template <
class Emitter>
3440template <
typename T>
3444 return this->emitConstSint8(
Value,
E);
3446 return this->emitConstUint8(
Value,
E);
3448 return this->emitConstSint16(
Value,
E);
3450 return this->emitConstUint16(
Value,
E);
3452 return this->emitConstSint32(
Value,
E);
3454 return this->emitConstUint32(
Value,
E);
3456 return this->emitConstSint64(
Value,
E);
3458 return this->emitConstUint64(
Value,
E);
3460 return this->emitConstBool(
Value,
E);
3467 llvm_unreachable(
"Invalid integral type");
3470 llvm_unreachable(
"unknown primitive type");
3473template <
class Emitter>
3474template <
typename T>
3479template <
class Emitter>
3483 return this->emitConstIntAPS(
Value,
E);
3485 return this->emitConstIntAP(
Value,
E);
3487 if (
Value.isSigned())
3488 return this->emitConst(
Value.getSExtValue(), Ty,
E);
3489 return this->emitConst(
Value.getZExtValue(), Ty,
E);
3492template <
class Emitter>
3497template <
class Emitter>
3502 if (
const auto *VD =
3503 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
3504 assert(!
P.getGlobal(VD));
3505 assert(!Locals.contains(VD));
3513 Src.is<
const Expr *>());
3515 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
3516 Locals.insert({VD, Local});
3517 VarScope->add(Local, IsExtended);
3518 return Local.Offset;
3521template <
class Emitter>
3522std::optional<unsigned>
3525 if ([[maybe_unused]]
const auto *VD =
3526 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
3527 assert(!
P.getGlobal(VD));
3528 assert(!Locals.contains(VD));
3534 bool IsTemporary =
false;
3535 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
3539 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
3540 Init = VarD->getInit();
3542 if (
auto *
E = Src.dyn_cast<
const Expr *>()) {
3549 IsTemporary,
false,
Init);
3551 return std::nullopt;
3555 Locals.insert({Key, Local});
3557 VarScope->addExtended(Local, ExtendingDecl);
3559 VarScope->add(Local,
false);
3560 return Local.Offset;
3563template <
class Emitter>
3570 true,
false,
nullptr);
3577 while (S->getParent())
3579 assert(S && !S->getParent());
3581 return Local.Offset;
3584template <
class Emitter>
3586 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
3592 if (
const auto *RecordTy = getRecordTy(Ty))
3593 return getRecord(RecordTy->getDecl());
3597template <
class Emitter>
3599 return P.getOrCreateRecord(RD);
3602template <
class Emitter>
3604 return Ctx.getOrCreateFunction(FD);
3617 if (std::optional<PrimType>
T = classify(
E)) {
3626 if (std::optional<unsigned> LocalOffset = this->allocateLocal(
E)) {
3627 if (!this->emitGetPtrLocal(*LocalOffset,
E))
3630 if (!visitInitializer(
E))
3633 if (!this->emitFinishInit(
E))
3645template <
class Emitter>
3648 auto R = this->visitVarDecl(VD,
true);
3657 if (
auto GlobalIndex =
P.getGlobal(VD)) {
3658 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
3662 GD.
InitState = GlobalInitState::InitializerFailed;
3673template <
class Emitter>
3675 bool ConstantContext) {
3676 std::optional<PrimType> VarT = classify(VD->
getType());
3680 if (!ConstantContext) {
3688 if (!this->visitVarDecl(VD,
true))
3692 auto GlobalIndex =
P.getGlobal(VD);
3693 assert(GlobalIndex);
3695 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
3698 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
3702 auto Local = Locals.find(VD);
3703 assert(Local != Locals.end());
3705 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
3708 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
3714 if (!this->emitRet(VarT.value_or(
PT_Ptr), VD)) {
3718 auto GlobalIndex =
P.getGlobal(VD);
3719 assert(GlobalIndex);
3720 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
3724 GD.
InitState = GlobalInitState::InitializerFailed;
3733template <
class Emitter>
3742 if (!this->isActive())
3746 std::optional<PrimType> VarT = classify(VD->
getType());
3748 if (
Init &&
Init->isValueDependent())
3752 auto checkDecl = [&]() ->
bool {
3754 return !NeedsOp || this->emitCheckDecl(VD, VD);
3757 auto initGlobal = [&](
unsigned GlobalIndex) ->
bool {
3762 if (!this->visit(
Init))
3763 return checkDecl() &&
false;
3765 return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
3771 if (!this->emitGetPtrGlobal(GlobalIndex,
Init))
3774 if (!visitInitializer(
Init))
3777 if (!this->emitFinishInit(
Init))
3780 return this->emitPopPtr(
Init);
3784 if (std::optional<unsigned> GlobalIndex =
P.getGlobal(VD)) {
3785 if (
P.getPtrGlobal(*GlobalIndex).isInitialized())
3790 return Init && checkDecl() && initGlobal(*GlobalIndex);
3793 std::optional<unsigned> GlobalIndex =
P.createGlobal(VD,
Init);
3798 return !
Init || (checkDecl() && initGlobal(*GlobalIndex));
3803 unsigned Offset = this->allocateLocalPrimitive(
3810 if (!this->visit(
Init))
3812 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
3814 if (!this->visit(
Init))
3816 return this->emitSetLocal(*VarT, Offset, VD);
3820 if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
3824 if (!this->emitGetPtrLocal(*Offset,
Init))
3827 if (!visitInitializer(
Init))
3830 if (!this->emitFinishInit(
Init))
3833 return this->emitPopPtr(
Init);
3843template <
class Emitter>
3846 assert(!DiscardResult);
3848 return this->emitConst(Val.
getInt(), ValType,
E);
3850 return this->emitConstFloat(Val.
getFloat(),
E);
3854 return this->emitNull(ValType,
nullptr,
E);
3856 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
3857 return this->visit(BaseExpr);
3858 else if (
const auto *VD =
Base.dyn_cast<
const ValueDecl *>()) {
3859 return this->visitDeclRef(VD,
E);
3863 return this->emitGetMemberPtr(MemberDecl,
E);
3864 return this->emitNullMemberPtr(
nullptr,
E);
3870template <
class Emitter>
3879 const Record::Field *RF = R->
getField(I);
3882 PrimType T = classifyPrim(RF->Decl->getType());
3883 if (!this->visitAPValue(F,
T,
E))
3885 if (!this->emitInitField(
T, RF->Offset,
E))
3888 assert(RF->Desc->isPrimitiveArray());
3889 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
3890 PrimType ElemT = classifyPrim(ArrType->getElementType());
3893 if (!this->emitGetPtrField(RF->Offset,
E))
3896 for (
unsigned A = 0, AN = F.
getArraySize(); A != AN; ++A) {
3899 if (!this->emitInitElem(ElemT, A,
E))
3903 if (!this->emitPopPtr(
E))
3906 if (!this->emitGetPtrField(RF->Offset,
E))
3908 if (!this->visitAPValueInitializer(F,
E))
3910 if (!this->emitPopPtr(
E))
3913 assert(
false &&
"I don't think this should be possible");
3922 const Record::Field *RF = R->
getField(UnionField);
3923 PrimType T = classifyPrim(RF->Decl->getType());
3924 if (!this->visitAPValue(F,
T,
E))
3926 return this->emitInitField(
T, RF->Offset,
E);
3933template <
class Emitter>
3941 unsigned Builtin =
E->getBuiltinCallee();
3942 if (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
3943 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
3944 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
3945 Builtin == Builtin::BI__builtin_function_start) {
3946 if (std::optional<unsigned> GlobalOffset =
P.createGlobal(
E)) {
3947 if (!this->emitGetPtrGlobal(*GlobalOffset,
E))
3951 return this->emitDecayPtr(
PT_Ptr, PT,
E);
3958 std::optional<PrimType> ReturnT = classify(
E);
3961 if (!Initializing && !ReturnT && !ReturnType->
isVoidType()) {
3962 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3965 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3969 if (!
Func->isUnevaluatedBuiltin()) {
3971 for (
const auto *Arg :
E->arguments()) {
3972 if (!this->visit(Arg))
3977 if (!this->emitCallBI(
Func,
E,
E))
3980 if (DiscardResult && !ReturnType->
isVoidType()) {
3982 return this->emitPop(*ReturnT,
E);
3988template <
class Emitter>
3990 if (
E->getBuiltinCallee())
3991 return VisitBuiltinCallExpr(
E);
3993 QualType ReturnType =
E->getCallReturnType(Ctx.getASTContext());
3994 std::optional<PrimType>
T = classify(ReturnType);
3999 if (DiscardResult) {
4003 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4004 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4010 if (!Initializing) {
4011 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4012 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4016 if (!this->emitDupPtr(
E))
4024 bool IsAssignmentOperatorCall =
false;
4025 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
4026 OCE && OCE->isAssignmentOp()) {
4030 assert(Args.size() == 2);
4031 IsAssignmentOperatorCall =
true;
4032 std::reverse(Args.begin(), Args.end());
4037 if (isa<CXXOperatorCallExpr>(
E)) {
4038 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
4039 MD && MD->isStatic()) {
4040 if (!this->discard(
E->getArg(0)))
4043 Args.erase(Args.begin());
4047 std::optional<unsigned> CalleeOffset;
4049 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(
E)) {
4050 if (!FuncDecl && classifyPrim(
E->getCallee()) ==
PT_MemberPtr) {
4054 const Expr *Callee =
E->getCallee();
4056 this->allocateLocalPrimitive(Callee,
PT_MemberPtr,
true,
false);
4057 if (!this->visit(Callee))
4063 if (!this->emitGetMemberPtrBase(
E))
4065 }
else if (!this->visit(MC->getImplicitObjectArgument())) {
4068 }
else if (!FuncDecl) {
4069 const Expr *Callee =
E->getCallee();
4070 CalleeOffset = this->allocateLocalPrimitive(Callee,
PT_FnPtr,
true,
false);
4071 if (!this->visit(Callee))
4073 if (!this->emitSetLocal(
PT_FnPtr, *CalleeOffset,
E))
4079 unsigned ArgIndex = 0;
4080 for (
const auto *Arg : Args) {
4081 if (!this->visit(Arg))
4085 if (FuncDecl && NonNullArgs[ArgIndex]) {
4088 if (!this->emitCheckNonNullArg(ArgT, Arg))
4096 if (IsAssignmentOperatorCall) {
4097 assert(Args.size() == 2);
4100 if (!this->emitFlip(Arg2T, Arg1T,
E))
4108 assert(HasRVO ==
Func->hasRVO());
4110 bool HasQualifier =
false;
4111 if (
const auto *ME = dyn_cast<MemberExpr>(
E->getCallee()))
4112 HasQualifier = ME->hasQualifier();
4114 bool IsVirtual =
false;
4115 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
4116 IsVirtual = MD->isVirtual();
4121 if (IsVirtual && !HasQualifier) {
4122 uint32_t VarArgSize = 0;
4123 unsigned NumParams =
4124 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4125 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4128 if (!this->emitCallVirt(
Func, VarArgSize,
E))
4130 }
else if (
Func->isVariadic()) {
4131 uint32_t VarArgSize = 0;
4132 unsigned NumParams =
4133 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4134 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4136 if (!this->emitCallVar(
Func, VarArgSize,
E))
4139 if (!this->emitCall(
Func, 0,
E))
4148 uint32_t ArgSize = 0;
4149 for (
unsigned I = 0, N =
E->getNumArgs(); I != N; ++I)
4154 if (isa<CXXMemberCallExpr>(
E) && CalleeOffset) {
4157 if (!this->emitGetMemberPtrDecl(
E))
4160 if (!this->emitGetLocal(
PT_FnPtr, *CalleeOffset,
E))
4163 if (!this->emitCallPtr(ArgSize,
E,
E))
4168 if (DiscardResult && !ReturnType->
isVoidType() &&
T)
4169 return this->emitPop(*
T,
E);
4174template <
class Emitter>
4178 return this->delegate(
E->getExpr());
4181template <
class Emitter>
4185 const Expr *SubExpr =
E->getExpr();
4186 if (std::optional<PrimType>
T = classify(
E->getExpr()))
4187 return this->visit(SubExpr);
4189 assert(Initializing);
4190 return this->visitInitializer(SubExpr);
4193template <
class Emitter>
4198 return this->emitConstBool(
E->getValue(),
E);
4201template <
class Emitter>
4207 return this->emitNullPtr(
nullptr,
E);
4210template <
class Emitter>
4218 return this->emitZero(
T,
E);
4221template <
class Emitter>
4226 if (this->LambdaThisCapture.Offset > 0) {
4227 if (this->LambdaThisCapture.IsPtr)
4228 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset,
E);
4229 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset,
E);
4236 if (!InitStackActive || !
E->isImplicit())
4237 return this->emitThis(
E);
4239 if (InitStackActive && !InitStack.empty()) {
4240 unsigned StartIndex = 0;
4241 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
4247 for (
unsigned I = StartIndex, N = InitStack.size(); I != N; ++I) {
4248 if (!InitStack[I].
template emit<Emitter>(
this,
E))
4253 return this->emitThis(
E);
4257 switch (S->getStmtClass()) {
4258 case Stmt::CompoundStmtClass:
4259 return visitCompoundStmt(cast<CompoundStmt>(S));
4260 case Stmt::DeclStmtClass:
4261 return visitDeclStmt(cast<DeclStmt>(S));
4262 case Stmt::ReturnStmtClass:
4263 return visitReturnStmt(cast<ReturnStmt>(S));
4264 case Stmt::IfStmtClass:
4265 return visitIfStmt(cast<IfStmt>(S));
4266 case Stmt::WhileStmtClass:
4267 return visitWhileStmt(cast<WhileStmt>(S));
4268 case Stmt::DoStmtClass:
4269 return visitDoStmt(cast<DoStmt>(S));
4270 case Stmt::ForStmtClass:
4271 return visitForStmt(cast<ForStmt>(S));
4272 case Stmt::CXXForRangeStmtClass:
4273 return visitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
4274 case Stmt::BreakStmtClass:
4275 return visitBreakStmt(cast<BreakStmt>(S));
4276 case Stmt::ContinueStmtClass:
4277 return visitContinueStmt(cast<ContinueStmt>(S));
4278 case Stmt::SwitchStmtClass:
4279 return visitSwitchStmt(cast<SwitchStmt>(S));
4280 case Stmt::CaseStmtClass:
4281 return visitCaseStmt(cast<CaseStmt>(S));
4282 case Stmt::DefaultStmtClass:
4283 return visitDefaultStmt(cast<DefaultStmt>(S));
4284 case Stmt::AttributedStmtClass:
4285 return visitAttributedStmt(cast<AttributedStmt>(S));
4286 case Stmt::CXXTryStmtClass:
4287 return visitCXXTryStmt(cast<CXXTryStmt>(S));
4288 case Stmt::NullStmtClass:
4291 case Stmt::GCCAsmStmtClass:
4292 case Stmt::MSAsmStmtClass:
4293 case Stmt::GotoStmtClass:
4294 return this->emitInvalid(S);
4295 case Stmt::LabelStmtClass:
4296 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
4298 if (
const auto *
E = dyn_cast<Expr>(S))
4299 return this->discard(
E);
4305template <
class Emitter>
4308 for (
const auto *InnerStmt : S->body())
4309 if (!visitStmt(InnerStmt))
4311 return Scope.destroyLocals();
4314template <
class Emitter>
4316 for (
const auto *
D : DS->
decls()) {
4321 const auto *VD = dyn_cast<VarDecl>(
D);
4324 if (!this->visitVarDecl(VD))
4331template <
class Emitter>
4333 if (this->InStmtExpr)
4334 return this->emitUnsupported(RS);
4340 if (!this->visit(RE))
4342 this->emitCleanup();
4343 return this->emitRet(*ReturnType, RS);
4344 }
else if (RE->getType()->isVoidType()) {
4345 if (!this->visit(RE))
4349 if (!this->emitRVOPtr(RE))
4351 if (!this->visitInitializer(RE))
4353 if (!this->emitPopPtr(RE))
4356 this->emitCleanup();
4357 return this->emitRetVoid(RS);
4362 this->emitCleanup();
4363 return this->emitRetVoid(RS);
4368 return visitStmt(IS->
getThen());
4372 if (
auto *CondInit = IS->
getInit())
4373 if (!visitStmt(CondInit))
4377 if (!visitDeclStmt(CondDecl))
4380 if (!this->visitBool(IS->
getCond()))
4384 LabelTy LabelElse = this->getLabel();
4385 LabelTy LabelEnd = this->getLabel();
4386 if (!this->jumpFalse(LabelElse))
4388 if (!visitStmt(IS->
getThen()))
4390 if (!this->jump(LabelEnd))
4392 this->emitLabel(LabelElse);
4393 if (!visitStmt(Else))
4395 this->emitLabel(LabelEnd);
4397 LabelTy LabelEnd = this->getLabel();
4398 if (!this->jumpFalse(LabelEnd))
4400 if (!visitStmt(IS->
getThen()))
4402 this->emitLabel(LabelEnd);
4408template <
class Emitter>
4410 const Expr *Cond = S->getCond();
4411 const Stmt *Body = S->getBody();
4413 LabelTy CondLabel = this->getLabel();
4414 LabelTy EndLabel = this->getLabel();
4417 this->fallthrough(CondLabel);
4418 this->emitLabel(CondLabel);
4420 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
4421 if (!visitDeclStmt(CondDecl))
4424 if (!this->visitBool(Cond))
4426 if (!this->jumpFalse(EndLabel))
4429 if (!this->visitStmt(Body))
4432 if (!this->jump(CondLabel))
4434 this->fallthrough(EndLabel);
4435 this->emitLabel(EndLabel);
4441 const Expr *Cond = S->getCond();
4442 const Stmt *Body = S->getBody();
4444 LabelTy StartLabel = this->getLabel();
4445 LabelTy EndLabel = this->getLabel();
4446 LabelTy CondLabel = this->getLabel();
4449 this->fallthrough(StartLabel);
4450 this->emitLabel(StartLabel);
4452 if (!this->visitStmt(Body))
4454 this->fallthrough(CondLabel);
4455 this->emitLabel(CondLabel);
4456 if (!this->visitBool(Cond))
4459 if (!this->jumpTrue(StartLabel))
4462 this->fallthrough(EndLabel);
4463 this->emitLabel(EndLabel);
4467template <
class Emitter>
4471 const Expr *Cond = S->getCond();
4472 const Expr *
Inc = S->getInc();
4473 const Stmt *Body = S->getBody();
4475 LabelTy EndLabel = this->getLabel();
4476 LabelTy CondLabel = this->getLabel();
4477 LabelTy IncLabel = this->getLabel();
4480 if (
Init && !this->visitStmt(
Init))
4483 this->fallthrough(CondLabel);
4484 this->emitLabel(CondLabel);
4486 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
4487 if (!visitDeclStmt(CondDecl))
4491 if (!this->visitBool(Cond))
4493 if (!this->jumpFalse(EndLabel))
4498 if (Body && !this->visitStmt(Body))
4501 this->fallthrough(IncLabel);
4502 this->emitLabel(IncLabel);
4503 if (
Inc && !this->discard(
Inc))
4507 if (!this->jump(CondLabel))
4509 this->fallthrough(EndLabel);
4510 this->emitLabel(EndLabel);
4514template <
class Emitter>
4517 const Expr *Cond = S->getCond();
4518 const Expr *
Inc = S->getInc();
4519 const Stmt *Body = S->getBody();
4520 const Stmt *BeginStmt = S->getBeginStmt();
4521 const Stmt *RangeStmt = S->getRangeStmt();
4522 const Stmt *EndStmt = S->getEndStmt();
4523 const VarDecl *LoopVar = S->getLoopVariable();
4525 LabelTy EndLabel = this->getLabel();
4526 LabelTy CondLabel = this->getLabel();
4527 LabelTy IncLabel = this->getLabel();
4531 if (
Init && !this->visitStmt(
Init))
4533 if (!this->visitStmt(RangeStmt))
4535 if (!this->visitStmt(BeginStmt))
4537 if (!this->visitStmt(EndStmt))
4541 this->fallthrough(CondLabel);
4542 this->emitLabel(CondLabel);
4543 if (!this->visitBool(Cond))
4545 if (!this->jumpFalse(EndLabel))
4548 if (!this->visitVarDecl(LoopVar))
4553 if (!this->visitStmt(Body))
4556 this->fallthrough(IncLabel);
4557 this->emitLabel(IncLabel);
4558 if (!this->discard(
Inc))
4562 if (!this->jump(CondLabel))
4565 this->fallthrough(EndLabel);
4566 this->emitLabel(EndLabel);
4570template <
class Emitter>
4575 this->emitCleanup();
4576 return this->jump(*BreakLabel);
4579template <
class Emitter>
4584 this->emitCleanup();
4585 return this->jump(*ContinueLabel);
4588template <
class Emitter>
4590 const Expr *Cond = S->getCond();
4593 LabelTy EndLabel = this->getLabel();
4595 unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT,
true,
false);
4597 if (
const auto *CondInit = S->getInit())
4598 if (!visitStmt(CondInit))
4601 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
4602 if (!visitDeclStmt(CondDecl))
4606 if (!this->visit(Cond))
4608 if (!this->emitSetLocal(CondT, CondVar, S))
4613 for (
const SwitchCase *SC = S->getSwitchCaseList(); SC;
4614 SC = SC->getNextSwitchCase()) {
4615 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
4617 if (CS->caseStmtIsGNURange())
4619 CaseLabels[SC] = this->getLabel();
4625 if (!this->emitGetLocal(CondT, CondVar, CS))
4627 if (!this->visit(
Value))
4631 if (!this->emitEQ(ValueT, S))
4633 if (!this->jumpTrue(CaseLabels[CS]))
4636 assert(!DefaultLabel);
4637 DefaultLabel = this->getLabel();
4644 if (!this->jump(*DefaultLabel))
4647 if (!this->jump(EndLabel))
4652 if (!this->visitStmt(S->getBody()))
4654 this->emitLabel(EndLabel);
4658template <
class Emitter>
4660 this->emitLabel(CaseLabels[S]);
4661 return this->visitStmt(S->getSubStmt());
4664template <
class Emitter>
4666 this->emitLabel(*DefaultLabel);
4667 return this->visitStmt(S->getSubStmt());
4670template <
class Emitter>
4672 if (this->Ctx.getLangOpts().CXXAssumptions &&
4673 !this->Ctx.getLangOpts().MSVCCompat) {
4674 for (
const Attr *A : S->getAttrs()) {
4675 auto *AA = dyn_cast<CXXAssumeAttr>(A);
4679 assert(isa<NullStmt>(S->getSubStmt()));
4681 const Expr *Assumption = AA->getAssumption();
4689 if (!this->visitBool(Assumption))
4692 if (!this->emitAssume(Assumption))
4698 return this->visitStmt(S->getSubStmt());
4701template <
class Emitter>
4704 return this->visitStmt(S->getTryBlock());
4707template <
class Emitter>
4711 assert(cast<CompoundStmt>(MD->
getBody())->body_empty());
4716 const Function *
Func = this->getFunction(LambdaCallOp);
4719 assert(
Func->hasThisPointer());
4722 if (
Func->hasRVO()) {
4723 if (!this->emitRVOPtr(MD))
4731 if (!this->emitNullPtr(
nullptr, MD))
4736 auto It = this->Params.find(PVD);
4737 assert(It != this->Params.end());
4741 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
4742 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
4746 if (!this->emitCall(
Func, 0, LambdaCallOp))
4749 this->emitCleanup();
4751 return this->emitRet(*ReturnType, MD);
4754 return this->emitRetVoid(MD);
4757template <
class Emitter>
4759 if (Ctx.getLangOpts().CPlusPlus23)
4768template <
class Emitter>
4770 assert(!ReturnType);
4772 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
4773 const Expr *InitExpr) ->
bool {
4775 if (InitExpr->getType().isNull())
4778 if (std::optional<PrimType>
T = this->classify(InitExpr)) {
4779 if (!this->visit(InitExpr))
4782 if (F->isBitField())
4783 return this->emitInitThisBitField(*
T, F, FieldOffset, InitExpr);
4784 return this->emitInitThisField(*
T, FieldOffset, InitExpr);
4789 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
4792 if (!this->visitInitializer(InitExpr))
4795 return this->emitFinishInitPop(InitExpr);
4799 const Record *R = this->getRecord(RD);
4805 assert(cast<CompoundStmt>(Ctor->
getBody())->body_empty());
4806 if (!this->emitThis(Ctor))
4815 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
4816 this->emitRetVoid(Ctor);
4820 for (
const auto *
Init : Ctor->
inits()) {
4824 const Expr *InitExpr =
Init->getInit();
4828 if (!emitFieldInitializer(F, F->Offset, InitExpr))
4831 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
4834 if (
Init->isBaseVirtual()) {
4836 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
4842 const Record::Base *B = R->
getBase(BaseDecl);
4844 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
4848 if (!this->visitInitializer(InitExpr))
4850 if (!this->emitFinishInitPop(InitExpr))
4853 assert(IFD->getChainingSize() >= 2);
4855 unsigned NestedFieldOffset = 0;
4856 const Record::Field *NestedField =
nullptr;
4857 for (
const NamedDecl *ND : IFD->chain()) {
4858 const auto *FD = cast<FieldDecl>(ND);
4859 const Record *FieldRecord = this->
P.getOrCreateRecord(FD->getParent());
4860 assert(FieldRecord);
4862 NestedField = FieldRecord->
getField(FD);
4863 assert(NestedField);
4865 NestedFieldOffset += NestedField->Offset;
4867 assert(NestedField);
4869 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
4872 assert(
Init->isDelegatingInitializer());
4873 if (!this->emitThis(InitExpr))
4875 if (!this->visitInitializer(
Init->getInit()))
4877 if (!this->emitPopPtr(InitExpr))
4881 if (!
Scope.destroyLocals())
4885 if (
const auto *Body = Ctor->
getBody())
4886 if (!visitStmt(Body))
4892template <
class Emitter>
4895 const Record *R = this->getRecord(RD);
4900 if (!this->visitStmt(Dtor->
getBody()))
4904 if (!this->emitThis(Dtor))
4910 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
4912 if (!
D->isPrimitive() && !
D->isPrimitiveArray()) {
4915 if (!this->emitDestruction(
D))
4923 for (
const Record::Base &
Base : llvm::reverse(R->
bases())) {
4926 if (!this->emitRecordDestruction(
Base.R))
4933 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
4936template <
class Emitter>
4941 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
4942 return this->compileConstructor(Ctor);
4943 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
4944 return this->compileDestructor(Dtor);
4947 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F);
4949 return this->emitLambdaStaticInvokerBody(MD);
4952 if (
const auto *Body = F->
getBody())
4953 if (!visitStmt(Body))
4962template <
class Emitter>
4964 const Expr *SubExpr =
E->getSubExpr();
4966 return this->VisitComplexUnaryOperator(
E);
4967 std::optional<PrimType>
T = classify(SubExpr->
getType());
4969 switch (
E->getOpcode()) {
4971 if (!Ctx.getLangOpts().CPlusPlus14)
4972 return this->emitInvalid(
E);
4974 return this->emitError(
E);
4976 if (!this->visit(SubExpr))
4980 if (!this->emitIncPtr(
E))
4983 return DiscardResult ? this->emitPopPtr(
E) :
true;
4987 return DiscardResult ? this->emitIncfPop(getRoundingMode(
E),
E)
4988 : this->emitIncf(getRoundingMode(
E),
E);
4991 return DiscardResult ? this->emitIncPop(*
T,
E) : this->emitInc(*
T,
E);
4994 if (!Ctx.getLangOpts().CPlusPlus14)
4995 return this->emitInvalid(
E);
4997 return this->emitError(
E);
4999 if (!this->visit(SubExpr))
5003 if (!this->emitDecPtr(
E))
5006 return DiscardResult ? this->emitPopPtr(
E) :
true;
5010 return DiscardResult ? this->emitDecfPop(getRoundingMode(
E),
E)
5011 : this->emitDecf(getRoundingMode(
E),
E);
5014 return DiscardResult ? this->emitDecPop(*
T,
E) : this->emitDec(*
T,
E);
5017 if (!Ctx.getLangOpts().CPlusPlus14)
5018 return this->emitInvalid(
E);
5020 return this->emitError(
E);
5022 if (!this->visit(SubExpr))
5026 if (!this->emitLoadPtr(
E))
5028 if (!this->emitConstUint8(1,
E))
5030 if (!this->emitAddOffsetUint8(
E))
5032 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5036 if (DiscardResult) {
5038 return this->emitIncfPop(getRoundingMode(
E),
E);
5039 return this->emitIncPop(*
T,
E);
5043 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5044 if (!this->emitLoadFloat(
E))
5046 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5048 if (!this->emitAddf(getRoundingMode(
E),
E))
5050 if (!this->emitStoreFloat(
E))
5054 if (!this->emitLoad(*
T,
E))
5056 if (!this->emitConst(1,
E))
5058 if (!this->emitAdd(*
T,
E))
5060 if (!this->emitStore(*
T,
E))
5066 if (!Ctx.getLangOpts().CPlusPlus14)
5067 return this->emitInvalid(
E);
5069 return this->emitError(
E);
5071 if (!this->visit(SubExpr))
5075 if (!this->emitLoadPtr(
E))
5077 if (!this->emitConstUint8(1,
E))
5079 if (!this->emitSubOffsetUint8(
E))
5081 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5085 if (DiscardResult) {
5087 return this->emitDecfPop(getRoundingMode(
E),
E);
5088 return this->emitDecPop(*
T,
E);
5092 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5093 if (!this->emitLoadFloat(
E))
5095 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5097 if (!this->emitSubf(getRoundingMode(
E),
E))
5099 if (!this->emitStoreFloat(
E))
5103 if (!this->emitLoad(*
T,
E))
5105 if (!this->emitConst(1,
E))
5107 if (!this->emitSub(*
T,
E))
5109 if (!this->emitStore(*
T,
E))
5116 return this->emitError(
E);
5119 return this->discard(SubExpr);
5121 if (!this->visitBool(SubExpr))
5124 if (!this->emitInv(
E))
5128 return this->emitCast(
PT_Bool, ET,
E);
5132 return this->emitError(
E);
5134 if (!this->visit(SubExpr))
5136 return DiscardResult ? this->emitPop(*
T,
E) : this->emitNeg(*
T,
E);
5139 return this->emitError(
E);
5141 if (!this->visit(SubExpr))
5143 return DiscardResult ? this->emitPop(*
T,
E) :
true;
5148 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(),
E);
5151 return this->delegate(SubExpr);
5154 return this->discard(SubExpr);
5155 return this->visit(SubExpr);
5158 return this->emitError(
E);
5160 if (!this->visit(SubExpr))
5162 return DiscardResult ? this->emitPop(*
T,
E) : this->emitComp(*
T,
E);
5165 return this->delegate(SubExpr);
5168 if (!this->discard(SubExpr))
5170 return this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
5173 return this->delegate(SubExpr);
5175 assert(
false &&
"Unhandled opcode");
5181template <
class Emitter>
5183 const Expr *SubExpr =
E->getSubExpr();
5187 return this->discard(SubExpr);
5189 std::optional<PrimType> ResT = classify(
E);
5190 auto prepareResult = [=]() ->
bool {
5191 if (!ResT && !Initializing) {
5192 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5195 return this->emitGetPtrLocal(*LocalIndex,
E);
5202 unsigned SubExprOffset = ~0u;
5203 auto createTemp = [=, &SubExprOffset]() ->
bool {
5204 SubExprOffset = this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
5205 if (!this->visit(SubExpr))
5207 return this->emitSetLocal(
PT_Ptr, SubExprOffset,
E);
5211 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
5212 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
5214 return this->emitArrayElemPop(ElemT, Index,
E);
5217 switch (
E->getOpcode()) {
5219 if (!prepareResult())
5223 for (
unsigned I = 0; I != 2; ++I) {
5224 if (!getElem(SubExprOffset, I))
5226 if (!this->emitNeg(ElemT,
E))
5228 if (!this->emitInitElem(ElemT, I,
E))
5236 return this->delegate(SubExpr);
5239 if (!this->visit(SubExpr))
5241 if (!this->emitComplexBoolCast(SubExpr))
5243 if (!this->emitInv(
E))
5246 return this->emitCast(
PT_Bool, ET,
E);
5250 return this->emitComplexReal(SubExpr);
5253 if (!this->visit(SubExpr))
5257 if (!this->emitConstUint8(1,
E))
5259 return this->emitArrayElemPtrPopUint8(
E);
5264 return this->emitArrayElemPop(classifyPrim(
E->
getType()), 1,
E);
5267 if (!this->visit(SubExpr))
5270 if (!this->emitArrayElem(ElemT, 1,
E))
5272 if (!this->emitNeg(ElemT,
E))
5274 if (!this->emitInitElem(ElemT, 1,
E))
5276 return DiscardResult ? this->emitPopPtr(
E) :
true;
5279 return this->delegate(SubExpr);
5282 return this->emitInvalid(
E);
5288template <
class Emitter>
5293 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(
D)) {
5294 return this->emitConst(ECD->getInitVal(),
E);
5295 }
else if (
const auto *BD = dyn_cast<BindingDecl>(
D)) {
5296 return this->visit(BD->getBinding());
5297 }
else if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(
D)) {
5298 const Function *F = getFunction(FuncDecl);
5299 return F && this->emitGetFnPtr(F,
E);
5300 }
else if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(
D)) {
5301 if (std::optional<unsigned> Index =
P.getOrCreateGlobal(
D)) {
5302 if (!this->emitGetPtrGlobal(*Index,
E))
5304 if (std::optional<PrimType>
T = classify(
E->
getType())) {
5305 if (!this->visitAPValue(TPOD->getValue(), *
T,
E))
5307 return this->emitInitGlobal(*
T, *Index,
E);
5309 return this->visitAPValueInitializer(TPOD->getValue(),
E);
5318 bool IsReference =
D->getType()->isReferenceType();
5321 if (
auto It = Locals.find(
D); It != Locals.end()) {
5322 const unsigned Offset = It->second.Offset;
5324 return this->emitGetLocal(
PT_Ptr, Offset,
E);
5325 return this->emitGetPtrLocal(Offset,
E);
5326 }
else if (
auto GlobalIndex =
P.getGlobal(
D)) {
5328 if (!Ctx.getLangOpts().CPlusPlus11)
5329 return this->emitGetGlobal(classifyPrim(
E), *GlobalIndex,
E);
5330 return this->emitGetGlobalUnchecked(classifyPrim(
E), *GlobalIndex,
E);
5333 return this->emitGetPtrGlobal(*GlobalIndex,
E);
5334 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(
D)) {
5335 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
5336 if (IsReference || !It->second.IsPtr)
5337 return this->emitGetParam(classifyPrim(
E), It->second.Offset,
E);
5339 return this->emitGetPtrParam(It->second.Offset,
E);
5344 auto revisit = [&](
const VarDecl *VD) ->
bool {
5345 auto VarState = this->visitDecl(VD);
5347 if (VarState.notCreated())
5352 return this->visitDeclRef(
D,
E);
5356 if (
auto It = this->LambdaCaptures.find(
D);
5357 It != this->LambdaCaptures.end()) {
5358 auto [Offset, IsPtr] = It->second;
5361 return this->emitGetThisFieldPtr(Offset,
E);
5362 return this->emitGetPtrThisField(Offset,
E);
5363 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E);
5364 DRE && DRE->refersToEnclosingVariableOrCapture()) {
5365 if (
const auto *VD = dyn_cast<VarDecl>(
D); VD && VD->isInitCapture())
5369 if (
D != InitializingDecl) {
5372 if (Ctx.getLangOpts().CPlusPlus) {
5373 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
5374 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
5375 if (
T.isConstant(Ctx.getASTContext()))
5378 return RT->getPointeeType().isConstQualified();
5383 if (isa<DecompositionDecl>(VD))
5387 if ((VD->hasGlobalStorage() || VD->isLocalVarDecl() ||
5388 VD->isStaticDataMember()) &&
5389 typeShouldBeVisited(VD->getType()))
5393 if (
const auto *VD = dyn_cast<VarDecl>(
D);
5394 VD && VD->getAnyInitializer() &&
5395 VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak())
5400 if (std::optional<unsigned> I =
P.getOrCreateDummy(
D)) {
5401 if (!this->emitGetPtrGlobal(*I,
E))
5408 return this->emitDecayPtr(
PT_Ptr, PT,
E);
5414 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E))
5415 return this->emitInvalidDeclRef(DRE,
E);
5419template <
class Emitter>
5421 const auto *
D =
E->getDecl();
5422 return this->visitDeclRef(
D,
E);
5427 C->emitDestruction();
5430template <
class Emitter>
5434 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
5436 return Ty->getAsCXXRecordDecl();
5438 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
5439 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
5441 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
5445template <
class Emitter>
5452 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
5453 return this->emitCastFP(ToSem, getRoundingMode(
E),
E);
5457 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
E);
5459 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
E);
5463 return this->emitCastFloatingIntegral(ToT,
E);
5468 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT),
E);
5470 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT),
E);
5474 return FromT != ToT ? this->emitCast(FromT, ToT,
E) :
true;
5478 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
5479 return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(
E),
5488template <
class Emitter>
5493 return this->discard(SubExpr);
5495 if (!this->visit(SubExpr))
5498 if (!this->emitConstUint8(0, SubExpr))
5500 return this->emitArrayElemPtrPopUint8(SubExpr);
5504 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
5508template <
class Emitter>
5510 assert(!DiscardResult);
5514 if (!this->emitArrayElem(ElemT, 0,
E))
5517 if (!this->emitCastFloatingIntegral(
PT_Bool,
E))
5520 if (!this->emitCast(ElemT,
PT_Bool,
E))
5525 LabelTy LabelTrue = this->getLabel();
5526 if (!this->jumpTrue(LabelTrue))
5529 if (!this->emitArrayElemPop(ElemT, 1,
E))
5532 if (!this->emitCastFloatingIntegral(
PT_Bool,
E))
5535 if (!this->emitCast(ElemT,
PT_Bool,
E))
5539 LabelTy EndLabel = this->getLabel();
5540 this->jump(EndLabel);
5542 this->emitLabel(LabelTrue);
5543 if (!this->emitPopPtr(
E))
5545 if (!this->emitConstBool(
true,
E))
5548 this->fallthrough(EndLabel);
5549 this->emitLabel(EndLabel);
5554template <
class Emitter>
5557 assert(
E->isComparisonOp());
5558 assert(!Initializing);
5559 assert(!DiscardResult);
5565 LHSIsComplex =
true;
5566 ElemT = classifyComplexElementType(LHS->
getType());
5567 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true,
5569 if (!this->visit(LHS))
5571 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
5574 LHSIsComplex =
false;
5576 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
5577 if (!this->visit(LHS))
5579 if (!this->emitSetLocal(LHST, LHSOffset,
E))
5586 RHSIsComplex =
true;
5587 ElemT = classifyComplexElementType(RHS->
getType());
5588 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true,
5590 if (!this->visit(RHS))
5592 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
5595 RHSIsComplex =
false;
5597 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
5598 if (!this->visit(RHS))
5600 if (!this->emitSetLocal(RHST, RHSOffset,
E))
5604 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
5605 bool IsComplex) ->
bool {
5607 if (!this->emitGetLocal(
PT_Ptr, LocalOffset,
E))
5609 return this->emitArrayElemPop(ElemT, Index,
E);
5611 return this->emitGetLocal(ElemT, LocalOffset,
E);
5614 for (
unsigned I = 0; I != 2; ++I) {
5616 if (!getElem(LHSOffset, I, LHSIsComplex))
5618 if (!getElem(RHSOffset, I, RHSIsComplex))
5621 if (!this->emitEQ(ElemT,
E))
5624 if (!this->emitCastBoolUint8(
E))
5629 if (!this->emitAddUint8(
E))
5631 if (!this->emitConstUint8(2,
E))
5634 if (
E->getOpcode() == BO_EQ) {
5635 if (!this->emitEQUint8(
E))
5637 }
else if (
E->getOpcode() == BO_NE) {
5638 if (!this->emitNEUint8(
E))
5645 return this->emitCast(
PT_Bool, ResT,
E);
5652template <
class Emitter>
5660 const Function *DtorFunc = getFunction(Dtor);
5667 return this->emitCall(DtorFunc, 0,
SourceInfo{});
5672template <
class Emitter>
5696 for (ssize_t I = Desc->
getNumElems() - 1; I >= 0; --I) {
5699 if (!this->emitArrayElemPtrUint64(
SourceInfo{}))
5701 if (!this->emitDestruction(ElemDesc))
5710 return this->emitRecordDestruction(Desc->
ElemRecord);
ASTImporterLookupTable & LT
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
ArrayRef< LValuePathEntry > getLValuePath() const
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
unsigned getStructNumFields() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
bool isMemberPointer() const
unsigned getArraySize() const
@ None
There is no such object (it's outside its lifetime).
bool isNullPointer() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
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.
const LangOptions & getLangOpts() const
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...
AddrLabelExpr - The GNU address of label extension, representing &&label.
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Represents a loop initializing the elements of an array.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Attr - This represents one attribute.
Represents an attribute applied to a statement.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
static bool isCommaOp(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
BreakStmt - This represents a break.
Represents a base class of a C++ class.
Represents binding an expression to a temporary.
A boolean literal, per ([C++ lex.bool] Boolean literals).
Represents a call to a C++ constructor.
Represents a C++ constructor within a class.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Represents a delete expression for memory deallocation and destructor calls, e.g.
Represents a C++ destructor within a class.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Represents a call to an inherited base class constructor from an inheriting constructor.
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a list-initialization with parenthesis.
Represents a C++ struct/union/class.
capture_const_iterator captures_end() const
capture_const_iterator captures_begin() const
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
A rewritten comparison expression that was originally written using operator syntax.
An expression "T()" which creates an rvalue of a non-class type T.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Represents the this expression in C++.
A C++ throw-expression (C++ [except.throw]).
CXXTryStmt - A C++ try block, including all handlers.
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
CharUnits - This is an opaque type for sizes expressed in character units.
static CharUnits One()
One - Construct a CharUnits quantity of one.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
CompoundLiteralExpr - [C99 6.5.2.5].
CompoundStmt - This represents a group of statements like { stmt stmt }.
Stmt * getStmtExprResult()
Represents the specialization of a concept - evaluates to a prvalue of type bool.
Represents the canonical version of C arrays with a specified constant size.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
ContinueStmt - This represents a continue.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInvalidDecl() const
DoStmt - This represents a 'do/while' stmt.
Represents a reference to #emded data.
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
EnumDecl * getDecl() const
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
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...
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
An expression trait intrinsic.
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Represents a member of a struct/union/class.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isDefaulted() const
Whether this function is defaulted.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
bool isNegatedConsteval() const
DeclStmt * getConditionVariableDeclStmt()
If this IfStmt has a condition variable, return the faux DeclStmt associated with the creation of tha...
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
Describes an C or C++ initializer list.
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
APValue & getAsAPValue() const
Get the value of this MSGuidDecl as an APValue.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A pointer to member type per C++ 8.3.3 - Pointers to members.
const Type * getClass() const
This represents a decl that may have a name.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
ObjCEncodeExpr, used for @encode in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Helper class for OffsetOfExpr.
@ Array
An index into an array.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
[C99 6.4.2.2] - A predefined identifier such as func.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
QualType withConst() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getCanonicalType() const
bool isConstQualified() const
Determine whether this type is const-qualified.
Represents a struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Base for LValueReferenceType and RValueReferenceType.
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Represents an expression that computes the length of a parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Represents a C++11 static_assert declaration.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Stmt - This represents one statement.
StringLiteral - This represents a string literal expression, e.g.
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...
Represents a reference to a non-type template parameter that has been substituted with a template arg...
SwitchStmt - This represents a 'switch' stmt.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBooleanType() const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isEnumeralType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isMemberPointerType() const
bool isAtomicType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isFunctionType() const
bool isVectorType() const
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represents a C++ using-enum-declaration.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
const Expr * getInit() const
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
Scope for storage declared in a compound statement.
A memory block, either on the stack or in the heap.
void invokeDtor()
Invokes the Destructor.
std::byte * rawData()
Returns a pointer to the raw data, including metadata.
Compilation context for expressions.
OptLabelTy BreakLabel
Point to break to.
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E)
bool VisitCXXDeleteExpr(const CXXDeleteExpr *E)
bool VisitOffsetOfExpr(const OffsetOfExpr *E)
bool visitContinueStmt(const ContinueStmt *S)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E)
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
bool visitDeclAndReturn(const VarDecl *VD, bool ConstantContext) override
Toplevel visitDeclAndReturn().
bool visitExpr(const Expr *E) override
bool VisitTypeTraitExpr(const TypeTraitExpr *E)
bool VisitLambdaExpr(const LambdaExpr *E)
bool VisitMemberExpr(const MemberExpr *E)
bool VisitBinaryOperator(const BinaryOperator *E)
bool visitAttributedStmt(const AttributedStmt *S)
bool VisitPackIndexingExpr(const PackIndexingExpr *E)
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
bool VisitCallExpr(const CallExpr *E)
bool VisitPseudoObjectExpr(const PseudoObjectExpr *E)
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E)
const Function * getFunction(const FunctionDecl *FD)
Returns a function for the given FunctionDecl.
void emitCleanup()
Emits scope cleanup instructions.
bool VisitCastExpr(const CastExpr *E)
bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E)
bool VisitComplexUnaryOperator(const UnaryOperator *E)
llvm::DenseMap< const SwitchCase *, LabelTy > CaseMap
bool visitDeclStmt(const DeclStmt *DS)
bool VisitBlockExpr(const BlockExpr *E)
bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E)
Visit an APValue.
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
bool VisitLogicalBinOp(const BinaryOperator *E)
bool visitCompoundStmt(const CompoundStmt *S)
bool visitDeclRef(const ValueDecl *D, const Expr *E)
Visit the given decl as if we have a reference to it.
bool visitBreakStmt(const BreakStmt *S)
bool visitForStmt(const ForStmt *S)
bool VisitDeclRefExpr(const DeclRefExpr *E)
bool VisitOpaqueValueExpr(const OpaqueValueExpr *E)
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E)
OptLabelTy DefaultLabel
Default case label.
bool VisitStmtExpr(const StmtExpr *E)
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
bool VisitCXXNewExpr(const CXXNewExpr *E)
bool VisitCompoundAssignOperator(const CompoundAssignOperator *E)
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init)
Pointer to the array(not the element!) must be on the stack when calling this.
bool delegate(const Expr *E)
Just pass evaluation on to E.
bool discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
CaseMap CaseLabels
Switch case mapping.
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
bool visit(const Expr *E)
Evaluates an expression and places the result on the stack.
const RecordType * getRecordTy(QualType Ty)
Returns a record type from a record or pointer type.
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E)
std::optional< unsigned > allocateLocal(DeclTy &&Decl, const ValueDecl *ExtendingDecl=nullptr)
Allocates a space storing a local given its type.
bool visitInitList(ArrayRef< const Expr * > Inits, const Expr *ArrayFiller, const Expr *E)
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E)
bool VisitPredefinedExpr(const PredefinedExpr *E)
bool VisitSourceLocExpr(const SourceLocExpr *E)
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E)
bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E)
bool visitInitializer(const Expr *E)
Compiles an initializer.
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E)
bool VisitPointerArithBinOp(const BinaryOperator *E)
Perform addition/subtraction of a pointer and an integer or subtraction of two pointers.
bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E)
bool visitDefaultStmt(const DefaultStmt *S)
typename Emitter::LabelTy LabelTy
VarCreationState visitDecl(const VarDecl *VD)
bool visitStmt(const Stmt *S)
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
bool visitAPValueInitializer(const APValue &Val, const Expr *E)
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
bool VisitRecoveryExpr(const RecoveryExpr *E)
bool VisitRequiresExpr(const RequiresExpr *E)
bool Initializing
Flag inidicating if we're initializing an already created variable.
bool visitReturnStmt(const ReturnStmt *RS)
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitChooseExpr(const ChooseExpr *E)
bool visitFunc(const FunctionDecl *F) override
bool visitCXXForRangeStmt(const CXXForRangeStmt *S)
bool visitCaseStmt(const CaseStmt *S)
bool VisitComplexBinOp(const BinaryOperator *E)
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
OptLabelTy ContinueLabel
Point to continue to.
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
bool visitDoStmt(const DoStmt *S)
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitInitListExpr(const InitListExpr *E)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
std::optional< LabelTy > OptLabelTy
bool DiscardResult
Flag indicating if return value is to be discarded.
bool VisitEmbedExpr(const EmbedExpr *E)
bool VisitConvertVectorExpr(const ConvertVectorExpr *E)
bool VisitCXXThisExpr(const CXXThisExpr *E)
bool VisitConstantExpr(const ConstantExpr *E)
unsigned allocateTemporary(const Expr *E)
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool visitSwitchStmt(const SwitchStmt *S)
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E)
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsExtended=false)
Creates a local primitive value.
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool visitWhileStmt(const WhileStmt *S)
bool visitIfStmt(const IfStmt *IS)
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
bool VisitFloatingLiteral(const FloatingLiteral *E)
bool VisitBuiltinCallExpr(const CallExpr *E)
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
bool VisitGNUNullExpr(const GNUNullExpr *E)
bool VisitImaginaryLiteral(const ImaginaryLiteral *E)
bool VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E)
VarCreationState visitVarDecl(const VarDecl *VD, bool Toplevel=false)
Creates and initializes a variable from the given decl.
bool visitCXXTryStmt(const CXXTryStmt *S)
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Scope used to handle temporaries in toplevel variable declarations.
void addExtended(const Scope::Local &Local) override
DeclScope(Compiler< Emitter > *Ctx, const ValueDecl *VD)
unsigned getNumParams() const
bool hasThisPointer() const
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Scope managing label targets.
LabelScope(Compiler< Emitter > *Ctx)
Compiler< Emitter > * Ctx
Compiler instance.
Generic scope for local variables.
bool destroyLocals(const Expr *E=nullptr) override
Explicit destruction of local variables.
void addLocal(const Scope::Local &Local) override
Sets the context for break/continue statements.
typename Compiler< Emitter >::LabelTy LabelTy
LoopScope(Compiler< Emitter > *Ctx, LabelTy BreakLabel, LabelTy ContinueLabel)
typename Compiler< Emitter >::OptLabelTy OptLabelTy
Scope used to handle initialization methods.
OptionScope(Compiler< Emitter > *Ctx, bool NewDiscardResult, bool NewInitializing)
Root constructor, compiling or discarding primitives.
Context to manage declaration lifetimes.
Structure/Class descriptor.
bool isUnion() const
Checks if the record is a union.
const CXXDestructorDecl * getDestructor() const
Returns the destructor of the record, if any.
const Field * getField(const FieldDecl *FD) const
Returns a field.
llvm::iterator_range< const_base_iter > bases() const
const Base * getVirtualBase(const RecordDecl *RD) const
Returns a virtual base descriptor.
unsigned getNumFields() const
llvm::iterator_range< const_field_iter > fields() const
const Base * getBase(const RecordDecl *FD) const
Returns a base descriptor.
Describes the statement/declaration an opcode was generated from.
StmtExprScope(Compiler< Emitter > *Ctx)
typename Compiler< Emitter >::LabelTy LabelTy
typename Compiler< Emitter >::OptLabelTy OptLabelTy
SwitchScope(Compiler< Emitter > *Ctx, CaseMap &&CaseLabels, LabelTy BreakLabel, OptLabelTy DefaultLabel)
typename Compiler< Emitter >::CaseMap CaseMap
Scope chain managing the variable lifetimes.
Compiler< Emitter > * Ctx
Compiler instance.
constexpr bool isPtrType(PrimType T)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool InitScope(InterpState &S, CodePtr OpPC, uint32_t I)
bool LE(InterpState &S, CodePtr OpPC)
PrimType
Enumeration of the primitive types of the VM.
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.
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
constexpr bool isIntegralType(PrimType T)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
@ SD_Static
Static storage duration.
const FunctionProtoType * T
@ Success
Template argument deduction was successful.
Describes a memory block created by an allocation site.
unsigned getNumElems() const
Returns the number of elements stored in the block.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
const Descriptor *const ElemDesc
Descriptor of the array element.
static constexpr MetadataSize InlineDescMD
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
const Record *const ElemRecord
Pointer to the record, if block contains records.
bool isArray() const
Checks if the descriptor is of an array.
Descriptor used for global variables.
GlobalInitState InitState
static InitLink Elem(unsigned Index)
bool emit(Compiler< Emitter > *Ctx, const Expr *E) const
static InitLink Field(unsigned Offset)
static InitLink Decl(const ValueDecl *D)
static InitLink Temp(unsigned Offset)
Information about a local's storage.
State encapsulating if a the variable creation has been successful, unsuccessful, or no variable has ...
static VarCreationState NotCreated()