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 return this->emitDecayPtr(
T,
PT_Ptr,
E);
902 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *
LT))
905 return this->emitSubPtr(classifyPrim(
E->
getType()),
E);
910 if (!visitAsPointer(RHS, *RT))
912 if (!this->visit(LHS))
916 if (!visitAsPointer(LHS, *
LT))
918 if (!this->visit(RHS))
928 if (!this->emitAddOffset(OffsetType,
E))
932 return this->emitDecayPtr(
PT_Ptr, classifyPrim(
E),
E);
934 }
else if (Op == BO_Sub) {
935 if (!this->emitSubOffset(OffsetType,
E))
939 return this->emitDecayPtr(
PT_Ptr, classifyPrim(
E),
E);
946template <
class Emitter>
948 assert(
E->isLogicalOp());
950 const Expr *LHS =
E->getLHS();
951 const Expr *RHS =
E->getRHS();
952 std::optional<PrimType>
T = classify(
E->
getType());
956 LabelTy LabelTrue = this->getLabel();
957 LabelTy LabelEnd = this->getLabel();
959 if (!this->visitBool(LHS))
961 if (!this->jumpTrue(LabelTrue))
964 if (!this->visitBool(RHS))
966 if (!this->jump(LabelEnd))
969 this->emitLabel(LabelTrue);
970 this->emitConstBool(
true,
E);
971 this->fallthrough(LabelEnd);
972 this->emitLabel(LabelEnd);
975 assert(Op == BO_LAnd);
978 LabelTy LabelFalse = this->getLabel();
979 LabelTy LabelEnd = this->getLabel();
981 if (!this->visitBool(LHS))
983 if (!this->jumpFalse(LabelFalse))
986 if (!this->visitBool(RHS))
988 if (!this->jump(LabelEnd))
991 this->emitLabel(LabelFalse);
992 this->emitConstBool(
false,
E);
993 this->fallthrough(LabelEnd);
994 this->emitLabel(LabelEnd);
998 return this->emitPopBool(
E);
1007template <
class Emitter>
1010 if (!Initializing) {
1011 unsigned LocalIndex = allocateTemporary(
E);
1012 if (!this->emitGetPtrLocal(LocalIndex,
E))
1018 const Expr *LHS =
E->getLHS();
1019 const Expr *RHS =
E->getRHS();
1022 unsigned ResultOffset = ~0u;
1024 ResultOffset = this->allocateLocalPrimitive(
E,
PT_Ptr,
true,
false);
1027 if (!this->DiscardResult) {
1028 if (!this->emitDupPtr(
E))
1030 if (!this->emitSetLocal(
PT_Ptr, ResultOffset,
E))
1035 LHSType = AT->getValueType();
1038 RHSType = AT->getValueType();
1047 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1052 if (!this->visit(LHS))
1054 if (!this->visit(RHS))
1056 return this->emitMulc(ElemT,
E);
1059 if (Op == BO_Div && RHSIsComplex) {
1061 PrimType ElemT = classifyPrim(ElemQT);
1066 if (!LHSIsComplex) {
1068 LHSOffset = allocateTemporary(RHS);
1070 if (!this->emitGetPtrLocal(LHSOffset,
E))
1073 if (!this->visit(LHS))
1076 if (!this->emitInitElem(ElemT, 0,
E))
1079 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1081 if (!this->emitInitElem(ElemT, 1,
E))
1084 if (!this->visit(LHS))
1088 if (!this->visit(RHS))
1090 return this->emitDivc(ElemT,
E);
1095 LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
1096 if (!this->visit(LHS))
1098 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1101 PrimType LHST = classifyPrim(LHSType);
1102 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
1103 if (!this->visit(LHS))
1105 if (!this->emitSetLocal(LHST, LHSOffset,
E))
1112 RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
1113 if (!this->visit(RHS))
1115 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1118 PrimType RHST = classifyPrim(RHSType);
1119 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
1120 if (!this->visit(RHS))
1122 if (!this->emitSetLocal(RHST, RHSOffset,
E))
1129 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1130 unsigned ElemIndex,
unsigned Offset,
1131 const Expr *
E) ->
bool {
1133 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
1135 return this->emitArrayElemPop(classifyComplexElementType(
E->
getType()),
1138 if (ElemIndex == 0 || !LoadZero)
1139 return this->emitGetLocal(classifyPrim(
E->
getType()), Offset,
E);
1140 return this->visitZeroInitializer(classifyPrim(
E->
getType()),
E->
getType(),
1145 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1147 if (!this->DiscardResult) {
1148 if (!this->emitGetLocal(
PT_Ptr, ResultOffset,
E))
1155 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1158 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1161 if (!this->emitAddf(getRoundingMode(
E),
E))
1164 if (!this->emitAdd(ResultElemT,
E))
1169 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1172 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1175 if (!this->emitSubf(getRoundingMode(
E),
E))
1178 if (!this->emitSub(ResultElemT,
E))
1183 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1186 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1190 if (!this->emitMulf(getRoundingMode(
E),
E))
1193 if (!this->emitMul(ResultElemT,
E))
1198 assert(!RHSIsComplex);
1199 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1202 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1206 if (!this->emitDivf(getRoundingMode(
E),
E))
1209 if (!this->emitDiv(ResultElemT,
E))
1218 if (!this->DiscardResult) {
1220 if (!this->emitInitElemPop(ResultElemT, ElemIndex,
E))
1223 if (!this->emitPop(ResultElemT,
E))
1230template <
class Emitter>
1235 if (std::optional<PrimType>
T = classify(QT))
1236 return this->visitZeroInitializer(*
T, QT,
E);
1250 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1251 CXXRD && CXXRD->getNumVBases() > 0) {
1256 const Record *R = getRecord(QT);
1260 assert(Initializing);
1261 return this->visitZeroRecordInitializer(R,
E);
1270 const auto *CAT = cast<ConstantArrayType>(AT);
1271 size_t NumElems = CAT->getZExtSize();
1272 PrimType ElemT = classifyPrim(CAT->getElementType());
1274 for (
size_t I = 0; I != NumElems; ++I) {
1275 if (!this->visitZeroInitializer(ElemT, CAT->getElementType(),
E))
1277 if (!this->emitInitElem(ElemT, I,
E))
1285 assert(Initializing);
1286 QualType ElemQT = ComplexTy->getElementType();
1287 PrimType ElemT = classifyPrim(ElemQT);
1288 for (
unsigned I = 0; I < 2; ++I) {
1289 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1291 if (!this->emitInitElem(ElemT, I,
E))
1298 unsigned NumVecElements = VecT->getNumElements();
1299 QualType ElemQT = VecT->getElementType();
1300 PrimType ElemT = classifyPrim(ElemQT);
1302 for (
unsigned I = 0; I < NumVecElements; ++I) {
1303 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1305 if (!this->emitInitElem(ElemT, I,
E))
1314template <
class Emitter>
1316 const Expr *LHS =
E->getLHS();
1317 const Expr *RHS =
E->getRHS();
1318 const Expr *Index =
E->getIdx();
1321 return this->discard(LHS) && this->discard(RHS);
1326 for (
const Expr *SubExpr : {LHS, RHS}) {
1327 if (!this->visit(SubExpr))
1334 PrimType IndexT = classifyPrim(Index->getType());
1337 if (!this->emitFlip(
PT_Ptr, IndexT,
E))
1341 return this->emitArrayElemPtrPop(IndexT,
E);
1344template <
class Emitter>
1346 const Expr *ArrayFiller,
const Expr *
E) {
1349 QT = AT->getValueType();
1352 if (Inits.size() == 0)
1354 return this->emitInvalid(
E);
1358 if (DiscardResult) {
1360 if (!this->discard(
Init))
1367 if (std::optional<PrimType>
T = classify(QT)) {
1368 assert(!DiscardResult);
1369 if (Inits.size() == 0)
1370 return this->visitZeroInitializer(*
T, QT,
E);
1371 assert(Inits.size() == 1);
1372 return this->delegate(Inits[0]);
1376 const Record *R = getRecord(QT);
1378 if (Inits.size() == 1 &&
E->
getType() == Inits[0]->getType())
1379 return this->delegate(Inits[0]);
1381 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
1384 if (!this->visit(
Init))
1387 if (FieldToInit->isBitField())
1388 return this->emitInitBitField(
T, FieldToInit,
E);
1389 return this->emitInitField(
T, FieldToInit->Offset,
E);
1392 auto initCompositeField = [=](
const Record::Field *FieldToInit,
1398 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
1400 if (!this->visitInitializer(
Init))
1402 return this->emitPopPtr(
E);
1406 if (Inits.size() == 0) {
1407 if (!this->visitZeroRecordInitializer(R,
E))
1412 if (
const auto *ILE = dyn_cast<InitListExpr>(
E))
1413 FToInit = ILE->getInitializedFieldInUnion();
1415 FToInit = cast<CXXParenListInitExpr>(
E)->getInitializedFieldInUnion();
1417 const Record::Field *FieldToInit = R->
getField(FToInit);
1418 if (std::optional<PrimType>
T = classify(
Init)) {
1419 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1422 if (!initCompositeField(FieldToInit,
Init))
1426 return this->emitFinishInit(
E);
1430 unsigned InitIndex = 0;
1433 while (InitIndex < R->getNumFields() &&
1437 if (std::optional<PrimType>
T = classify(
Init)) {
1438 const Record::Field *FieldToInit = R->
getField(InitIndex);
1439 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1444 if (
const Record::Base *B = R->
getBase(
Init->getType())) {
1445 if (!this->emitGetPtrBase(B->Offset,
Init))
1448 if (!this->visitInitializer(
Init))
1451 if (!this->emitFinishInitPop(
E))
1456 const Record::Field *FieldToInit = R->
getField(InitIndex);
1457 if (!initCompositeField(FieldToInit,
Init))
1463 return this->emitFinishInit(
E);
1467 if (Inits.size() == 1 && QT == Inits[0]->getType())
1468 return this->delegate(Inits[0]);
1470 unsigned ElementIndex = 0;
1472 if (
const auto *EmbedS =
1473 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1476 auto Eval = [&](
const Expr *
Init,
unsigned ElemIndex) {
1478 if (!this->visit(
Init))
1480 if (InitT != TargetT) {
1481 if (!this->emitCast(InitT, TargetT,
E))
1484 return this->emitInitElem(TargetT, ElemIndex,
Init);
1486 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
1489 if (!this->visitArrayElemInit(ElementIndex,
Init))
1499 Ctx.getASTContext().getAsConstantArrayType(QT);
1502 for (; ElementIndex != NumElems; ++ElementIndex) {
1503 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller))
1508 return this->emitFinishInit(
E);
1512 unsigned NumInits = Inits.size();
1515 return this->delegate(Inits[0]);
1517 QualType ElemQT = ComplexTy->getElementType();
1518 PrimType ElemT = classifyPrim(ElemQT);
1519 if (NumInits == 0) {
1521 for (
unsigned I = 0; I < 2; ++I) {
1522 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1524 if (!this->emitInitElem(ElemT, I,
E))
1527 }
else if (NumInits == 2) {
1528 unsigned InitIndex = 0;
1530 if (!this->visit(
Init))
1533 if (!this->emitInitElem(ElemT, InitIndex,
E))
1542 unsigned NumVecElements = VecT->getNumElements();
1543 assert(NumVecElements >= Inits.size());
1545 QualType ElemQT = VecT->getElementType();
1546 PrimType ElemT = classifyPrim(ElemQT);
1549 unsigned InitIndex = 0;
1551 if (!this->visit(
Init))
1556 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
1557 if (!this->emitCopyArray(ElemT, 0, InitIndex,
1558 InitVecT->getNumElements(),
E))
1560 InitIndex += InitVecT->getNumElements();
1562 if (!this->emitInitElem(ElemT, InitIndex,
E))
1568 assert(InitIndex <= NumVecElements);
1571 for (; InitIndex != NumVecElements; ++InitIndex) {
1572 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1574 if (!this->emitInitElem(ElemT, InitIndex,
E))
1585template <
class Emitter>
1588 if (std::optional<PrimType>
T = classify(
Init->getType())) {
1590 if (!this->visit(
Init))
1592 return this->emitInitElem(*
T, ElemIndex,
Init);
1598 if (!this->emitConstUint32(ElemIndex,
Init))
1600 if (!this->emitArrayElemPtrUint32(
Init))
1602 if (!this->visitInitializer(
Init))
1604 return this->emitFinishInitPop(
Init);
1607template <
class Emitter>
1609 return this->visitInitList(
E->inits(),
E->getArrayFiller(),
E);
1612template <
class Emitter>
1615 return this->visitInitList(
E->getInitExprs(),
E->getArrayFiller(),
E);
1618template <
class Emitter>
1621 return this->delegate(
E->getReplacement());
1624template <
class Emitter>
1626 std::optional<PrimType>
T = classify(
E->
getType());
1627 if (
T &&
E->hasAPValueResult()) {
1634 if (this->visitAPValue(
E->getAPValueResult(), *
T,
E))
1637 return this->delegate(
E->getSubExpr());
1640template <
class Emitter>
1642 auto It =
E->begin();
1643 return this->visit(*It);
1648 bool AlignOfReturnsPreferred =
1649 ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
1657 if (
T.getQualifiers().hasUnaligned())
1663 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
1669template <
class Emitter>
1673 const ASTContext &ASTCtx = Ctx.getASTContext();
1675 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
1676 QualType ArgType =
E->getTypeOfArgument();
1690 if (Kind == UETT_SizeOf)
1699 return this->emitConst(Size.getQuantity(),
E);
1702 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
1705 if (
E->isArgumentType()) {
1706 QualType ArgType =
E->getTypeOfArgument();
1719 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
1722 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
1732 return this->emitConst(Size.getQuantity(),
E);
1735 if (Kind == UETT_VectorElements) {
1736 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>())
1737 return this->emitConst(VT->getNumElements(),
E);
1738 assert(
E->getTypeOfArgument()->isSizelessVectorType());
1739 return this->emitSizelessVectorElementSize(
E);
1742 if (Kind == UETT_VecStep) {
1743 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>()) {
1744 unsigned N = VT->getNumElements();
1751 return this->emitConst(N,
E);
1753 return this->emitConst(1,
E);
1759template <
class Emitter>
1766 return this->discard(
Base);
1770 const auto maybeLoadValue = [&]() ->
bool {
1773 if (std::optional<PrimType>
T = classify(
E))
1774 return this->emitLoadPop(*
T,
E);
1778 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
1782 if (
auto GlobalIndex =
P.getGlobal(VD))
1783 return this->emitGetPtrGlobal(*GlobalIndex,
E) && maybeLoadValue();
1787 if (!isa<FieldDecl>(
Member))
1788 return this->discard(
Base) && this->visitDeclRef(
Member,
E);
1791 if (!this->delegate(
Base))
1794 if (!this->visit(
Base))
1799 const auto *FD = cast<FieldDecl>(
Member);
1801 const Record *R = getRecord(RD);
1804 const Record::Field *F = R->
getField(FD);
1806 if (F->Decl->getType()->isReferenceType())
1807 return this->emitGetFieldPop(
PT_Ptr, F->Offset,
E) && maybeLoadValue();
1808 return this->emitGetPtrFieldPop(F->Offset,
E) && maybeLoadValue();
1811template <
class Emitter>
1817 return this->emitConst(*ArrayIndex,
E);
1820template <
class Emitter>
1822 assert(Initializing);
1823 assert(!DiscardResult);
1827 if (!this->discard(
E->getCommonExpr()))
1832 const Expr *SubExpr =
E->getSubExpr();
1833 size_t Size =
E->getArraySize().getZExtValue();
1838 for (
size_t I = 0; I != Size; ++I) {
1842 if (!this->visitArrayElemInit(I, SubExpr))
1850template <
class Emitter>
1852 const Expr *SourceExpr =
E->getSourceExpr();
1857 return this->visitInitializer(SourceExpr);
1860 if (
auto It = OpaqueExprs.find(
E); It != OpaqueExprs.end())
1861 return this->emitGetLocal(SubExprT, It->second,
E);
1863 if (!this->visit(SourceExpr))
1869 unsigned LocalIndex = allocateLocalPrimitive(
E, SubExprT,
true);
1870 if (!this->emitSetLocal(SubExprT, LocalIndex,
E))
1875 if (!DiscardResult) {
1876 if (!this->emitGetLocal(SubExprT, LocalIndex,
E))
1881 OpaqueExprs.insert({
E, LocalIndex});
1886template <
class Emitter>
1890 const Expr *TrueExpr =
E->getTrueExpr();
1891 const Expr *FalseExpr =
E->getFalseExpr();
1893 LabelTy LabelEnd = this->getLabel();
1894 LabelTy LabelFalse = this->getLabel();
1899 if (!this->jumpFalse(LabelFalse))
1904 if (!this->delegate(TrueExpr))
1906 if (!S.destroyLocals())
1910 if (!this->jump(LabelEnd))
1913 this->emitLabel(LabelFalse);
1917 if (!this->delegate(FalseExpr))
1919 if (!S.destroyLocals())
1923 this->fallthrough(LabelEnd);
1924 this->emitLabel(LabelEnd);
1929template <
class Emitter>
1934 if (!Initializing) {
1935 unsigned StringIndex =
P.createGlobalString(
E);
1936 return this->emitGetPtrGlobal(StringIndex,
E);
1941 Ctx.getASTContext().getAsConstantArrayType(
E->
getType());
1942 assert(CAT &&
"a string literal that's not a constant array?");
1947 unsigned N = std::min(ArraySize,
E->getLength());
1948 size_t CharWidth =
E->getCharByteWidth();
1950 for (
unsigned I = 0; I != N; ++I) {
1951 uint32_t CodeUnit =
E->getCodeUnit(I);
1953 if (CharWidth == 1) {
1954 this->emitConstSint8(CodeUnit,
E);
1955 this->emitInitElemSint8(I,
E);
1956 }
else if (CharWidth == 2) {
1957 this->emitConstUint16(CodeUnit,
E);
1958 this->emitInitElemUint16(I,
E);
1959 }
else if (CharWidth == 4) {
1960 this->emitConstUint32(CodeUnit,
E);
1961 this->emitInitElemUint32(I,
E);
1963 llvm_unreachable(
"unsupported character width");
1968 for (
unsigned I = N; I != ArraySize; ++I) {
1969 if (CharWidth == 1) {
1970 this->emitConstSint8(0,
E);
1971 this->emitInitElemSint8(I,
E);
1972 }
else if (CharWidth == 2) {
1973 this->emitConstUint16(0,
E);
1974 this->emitInitElemUint16(I,
E);
1975 }
else if (CharWidth == 4) {
1976 this->emitConstUint32(0,
E);
1977 this->emitInitElemUint32(I,
E);
1979 llvm_unreachable(
"unsupported character width");
1986template <
class Emitter>
1988 return this->delegate(
E->getString());
1991template <
class Emitter>
1993 auto &A = Ctx.getASTContext();
1995 A.getObjCEncodingForType(
E->getEncodedType(), Str);
1999 return this->delegate(SL);
2002template <
class Emitter>
2008 assert(!Initializing);
2010 auto &A = Ctx.getASTContext();
2011 std::string ResultStr =
E->ComputeName(A);
2014 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
2015 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
2016 ArraySizeModifier::Normal, 0);
2020 false, ArrayTy,
E->getLocation());
2022 unsigned StringIndex =
P.createGlobalString(SL);
2023 return this->emitGetPtrGlobal(StringIndex,
E);
2026template <
class Emitter>
2030 return this->emitConst(
E->getValue(),
E);
2033template <
class Emitter>
2037 const Expr *LHS =
E->getLHS();
2038 const Expr *RHS =
E->getRHS();
2040 QualType LHSComputationType =
E->getComputationLHSType();
2041 QualType ResultType =
E->getComputationResultType();
2042 std::optional<PrimType>
LT = classify(LHSComputationType);
2043 std::optional<PrimType> RT = classify(ResultType);
2050 PrimType LHST = classifyPrim(LHSType);
2058 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2059 if (!this->emitSetLocal(*RT, TempOffset,
E))
2065 if (!this->emitLoad(LHST,
E))
2069 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
2070 LHSComputationType,
E))
2074 if (!this->emitGetLocal(*RT, TempOffset,
E))
2077 llvm::RoundingMode RM = getRoundingMode(
E);
2078 switch (
E->getOpcode()) {
2080 if (!this->emitAddf(RM,
E))
2084 if (!this->emitSubf(RM,
E))
2088 if (!this->emitMulf(RM,
E))
2092 if (!this->emitDivf(RM,
E))
2099 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->
getType(),
E))
2103 return this->emitStorePop(LHST,
E);
2104 return this->emitStore(LHST,
E);
2107template <
class Emitter>
2111 const Expr *LHS =
E->getLHS();
2112 const Expr *RHS =
E->getRHS();
2113 std::optional<PrimType>
LT = classify(LHS->
getType());
2114 std::optional<PrimType> RT = classify(RHS->
getType());
2116 if (Op != BO_AddAssign && Op != BO_SubAssign)
2125 if (!this->emitLoad(*
LT, LHS))
2131 if (Op == BO_AddAssign) {
2132 if (!this->emitAddOffset(*RT,
E))
2135 if (!this->emitSubOffset(*RT,
E))
2140 return this->emitStorePopPtr(
E);
2141 return this->emitStorePtr(
E);
2144template <
class Emitter>
2148 const Expr *LHS =
E->getLHS();
2149 const Expr *RHS =
E->getRHS();
2150 std::optional<PrimType> LHSComputationT =
2151 classify(
E->getComputationLHSType());
2152 std::optional<PrimType>
LT = classify(LHS->
getType());
2153 std::optional<PrimType> RT = classify(RHS->
getType());
2154 std::optional<PrimType> ResultT = classify(
E->
getType());
2156 if (!Ctx.getLangOpts().CPlusPlus14)
2157 return this->visit(RHS) && this->visit(LHS) && this->emitError(
E);
2159 if (!
LT || !RT || !ResultT || !LHSComputationT)
2166 return VisitFloatCompoundAssignOperator(
E);
2169 return VisitPointerCompoundAssignOperator(
E);
2182 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2184 if (!this->emitSetLocal(*RT, TempOffset,
E))
2191 if (!this->emitLoad(*
LT,
E))
2193 if (
LT != LHSComputationT) {
2194 if (!this->emitCast(*
LT, *LHSComputationT,
E))
2199 if (!this->emitGetLocal(*RT, TempOffset,
E))
2203 switch (
E->getOpcode()) {
2205 if (!this->emitAdd(*LHSComputationT,
E))
2209 if (!this->emitSub(*LHSComputationT,
E))
2213 if (!this->emitMul(*LHSComputationT,
E))
2217 if (!this->emitDiv(*LHSComputationT,
E))
2221 if (!this->emitRem(*LHSComputationT,
E))
2225 if (!this->emitShl(*LHSComputationT, *RT,
E))
2229 if (!this->emitShr(*LHSComputationT, *RT,
E))
2233 if (!this->emitBitAnd(*LHSComputationT,
E))
2237 if (!this->emitBitXor(*LHSComputationT,
E))
2241 if (!this->emitBitOr(*LHSComputationT,
E))
2245 llvm_unreachable(
"Unimplemented compound assign operator");
2249 if (ResultT != LHSComputationT) {
2250 if (!this->emitCast(*LHSComputationT, *ResultT,
E))
2255 if (DiscardResult) {
2257 return this->emitStoreBitFieldPop(*ResultT,
E);
2258 return this->emitStorePop(*ResultT,
E);
2261 return this->emitStoreBitField(*ResultT,
E);
2262 return this->emitStore(*ResultT,
E);
2265template <
class Emitter>
2268 const Expr *SubExpr =
E->getSubExpr();
2273template <
class Emitter>
2276 const Expr *SubExpr =
E->getSubExpr();
2280 return this->delegate(SubExpr);
2285 return this->discard(SubExpr);
2289 std::optional<PrimType> SubExprT = classify(SubExpr);
2292 std::optional<unsigned> GlobalIndex =
P.createGlobal(
E);
2297 E->getLifetimeExtendedTemporaryDecl();
2302 if (!this->visit(SubExpr))
2305 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl,
E))
2308 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex,
E))
2311 return this->emitGetPtrGlobal(*GlobalIndex,
E);
2315 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2317 if (!this->visitInitializer(SubExpr))
2320 return this->emitInitGlobalTempComp(TempDecl,
E);
2326 unsigned LocalIndex = allocateLocalPrimitive(
2327 SubExpr, *SubExprT,
true,
true);
2328 if (!this->visit(SubExpr))
2330 if (!this->emitSetLocal(*SubExprT, LocalIndex,
E))
2332 return this->emitGetPtrLocal(LocalIndex,
E);
2335 if (std::optional<unsigned> LocalIndex =
2336 allocateLocal(Inner,
E->getExtendingDecl())) {
2338 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2340 return this->visitInitializer(SubExpr);
2346template <
class Emitter>
2349 return this->delegate(
E->getSubExpr());
2352template <
class Emitter>
2356 return this->discard(
Init);
2360 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2363 std::optional<PrimType>
T = classify(
E->
getType());
2364 if (
E->isFileScope()) {
2367 return this->delegate(
Init);
2369 if (std::optional<unsigned> GlobalIndex =
P.createGlobal(
E)) {
2370 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2374 if (!this->visit(
Init))
2376 return this->emitInitGlobal(*
T, *GlobalIndex,
E);
2379 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2388 return this->delegate(
Init);
2390 unsigned LocalIndex;
2393 LocalIndex = this->allocateLocalPrimitive(
Init, *
T,
false,
false);
2394 else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(
Init))
2395 LocalIndex = *MaybeIndex;
2399 if (!this->emitGetPtrLocal(LocalIndex,
E))
2403 if (!this->visit(
Init)) {
2406 return this->emitInit(*
T,
E);
2408 if (!this->visitInitializer(
Init) || !this->emitFinishInit(
E))
2417template <
class Emitter>
2422 return this->emitConstBool(
E->getValue(),
E);
2423 return this->emitConst(
E->getValue(),
E);
2426template <
class Emitter>
2430 return this->emitConst(
E->getValue(),
E);
2433template <
class Emitter>
2438 assert(Initializing);
2439 const Record *R =
P.getOrCreateRecord(
E->getLambdaClass());
2441 auto *CaptureInitIt =
E->capture_init_begin();
2444 for (
const Record::Field &F : R->
fields()) {
2451 if (std::optional<PrimType>
T = classify(
Init)) {
2452 if (!this->visit(
Init))
2455 if (!this->emitInitField(*
T, F.Offset,
E))
2458 if (!this->emitGetPtrField(F.Offset,
E))
2461 if (!this->visitInitializer(
Init))
2464 if (!this->emitPopPtr(
E))
2472template <
class Emitter>
2477 return this->delegate(
E->getFunctionName());
2480template <
class Emitter>
2482 if (
E->getSubExpr() && !this->discard(
E->getSubExpr()))
2485 return this->emitInvalid(
E);
2488template <
class Emitter>
2491 const Expr *SubExpr =
E->getSubExpr();
2493 bool TypesMatch = classify(
E) == classify(SubExpr);
2494 if (!this->emitInvalidCast(CastKind::Reinterpret, !TypesMatch,
E))
2497 return this->delegate(SubExpr);
2500template <
class Emitter>
2506 return this->emitConstBool(
E->getValue(),
E);
2509template <
class Emitter>
2512 assert(!classify(
T));
2522 return this->visitInitializer(
E->getArg(0));
2526 if (DiscardResult) {
2529 assert(!Initializing);
2530 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2535 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2540 if (
E->requiresZeroInitialization()) {
2543 if (!this->visitZeroRecordInitializer(R,
E))
2556 assert(
Func->hasThisPointer());
2557 assert(!
Func->hasRVO());
2561 if (!this->emitDupPtr(
E))
2565 for (
const auto *Arg :
E->arguments()) {
2566 if (!this->visit(Arg))
2570 if (
Func->isVariadic()) {
2571 uint32_t VarArgSize = 0;
2572 unsigned NumParams =
Func->getNumWrittenParams();
2573 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I) {
2577 if (!this->emitCallVar(
Func, VarArgSize,
E))
2580 if (!this->emitCall(
Func, 0,
E))
2585 return this->emitPopPtr(
E);
2586 return this->emitFinishInit(
E);
2591 Ctx.getASTContext().getAsConstantArrayType(
E->
getType());
2602 for (
size_t I = 0; I != NumElems; ++I) {
2603 if (!this->emitConstUint64(I,
E))
2605 if (!this->emitArrayElemPtrUint64(
E))
2609 for (
const auto *Arg :
E->arguments()) {
2610 if (!this->visit(Arg))
2614 if (!this->emitCall(
Func, 0,
E))
2623template <
class Emitter>
2629 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
2633 assert(Val.
isInt());
2635 return this->emitConst(I,
E);
2642 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
2643 return this->visit(LValueExpr);
2652 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
2654 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(UGCD);
2658 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2662 const APValue &
V = UGCD->getValue();
2663 for (
unsigned I = 0, N = R->
getNumFields(); I != N; ++I) {
2664 const Record::Field *F = R->
getField(I);
2665 const APValue &FieldValue =
V.getStructField(I);
2667 PrimType FieldT = classifyPrim(F->Decl->getType());
2669 if (!this->visitAPValue(FieldValue, FieldT,
E))
2671 if (!this->emitInitField(FieldT, F->Offset,
E))
2679template <
class Emitter>
2681 unsigned N =
E->getNumComponents();
2685 for (
unsigned I = 0; I != N; ++I) {
2688 const Expr *ArrayIndexExpr =
E->getIndexExpr(
Node.getArrayExprIndex());
2691 if (DiscardResult) {
2692 if (!this->discard(ArrayIndexExpr))
2697 if (!this->visit(ArrayIndexExpr))
2711 return this->emitOffsetOf(
T,
E,
E);
2714template <
class Emitter>
2722 if (std::optional<PrimType>
T = classify(Ty))
2723 return this->visitZeroInitializer(*
T, Ty,
E);
2726 if (!Initializing) {
2727 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2730 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2735 QualType ElemQT = CT->getElementType();
2736 PrimType ElemT = classifyPrim(ElemQT);
2738 for (
unsigned I = 0; I != 2; ++I) {
2739 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
2741 if (!this->emitInitElem(ElemT, I,
E))
2749 if (!Initializing) {
2750 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2753 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2758 QualType ElemQT = VT->getElementType();
2759 PrimType ElemT = classifyPrim(ElemQT);
2761 for (
unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
2762 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
2764 if (!this->emitInitElem(ElemT, I,
E))
2773template <
class Emitter>
2775 return this->emitConst(
E->getPackLength(),
E);
2778template <
class Emitter>
2781 return this->delegate(
E->getResultExpr());
2784template <
class Emitter>
2786 return this->delegate(
E->getChosenSubExpr());
2789template <
class Emitter>
2794 return this->emitConst(
E->getValue(),
E);
2797template <
class Emitter>
2802 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
2803 const Function *F = this->getFunction(Ctor);
2820 if (!this->emitGetParam(PT, Offset,
E))
2825 return this->emitCall(F, 0,
E);
2828template <
class Emitter>
2832 QualType ElementType =
E->getAllocatedType();
2833 std::optional<PrimType> ElemT = classify(ElementType);
2834 unsigned PlacementArgs =
E->getNumPlacementArgs();
2835 bool IsNoThrow =
false;
2838 if (PlacementArgs != 0) {
2850 return this->emitInvalid(
E);
2852 if (!this->discard(
E->getPlacementArg(0)))
2866 Desc =
P.createDescriptor(
2869 false,
false,
false,
Init);
2873 std::optional<const Expr *> ArraySizeExpr =
E->getArraySize();
2877 const Expr *Stripped = *ArraySizeExpr;
2878 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
2879 Stripped = ICE->getSubExpr())
2880 if (ICE->getCastKind() != CK_NoOp &&
2881 ICE->getCastKind() != CK_IntegralCast)
2886 if (!this->visit(Stripped))
2891 if (!this->emitAllocN(SizeT, *ElemT,
E, IsNoThrow,
E))
2895 if (!this->emitAllocCN(SizeT, Desc, IsNoThrow,
E))
2899 if (
Init && !this->visitInitializer(
Init))
2904 if (!this->emitAlloc(Desc,
E))
2909 if (!this->visit(
Init))
2912 if (!this->emitInit(*ElemT,
E))
2916 if (!this->visitInitializer(
Init))
2923 return this->emitPopPtr(
E);
2928template <
class Emitter>
2930 const Expr *Arg =
E->getArgument();
2933 if (!this->visit(Arg))
2936 return this->emitFree(
E->isArrayForm(),
E);
2939template <
class Emitter>
2947 return this->emitGetFnPtr(
Func,
E);
2950template <
class Emitter>
2952 assert(Ctx.getLangOpts().CPlusPlus);
2953 return this->emitConstBool(
E->getValue(),
E);
2956template <
class Emitter>
2960 assert(!Initializing);
2968 if (std::optional<unsigned> I =
P.getOrCreateDummy(GuidDecl))
2969 return this->emitGetPtrGlobal(*I,
E);
2973 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(GuidDecl);
2976 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2979 assert(this->getRecord(
E->
getType()));
2985 assert(
V.isStruct());
2986 assert(
V.getStructNumBases() == 0);
2987 if (!this->visitAPValueInitializer(
V,
E))
2990 return this->emitFinishInit(
E);
2993template <
class Emitter>
2998 return this->emitConstBool(
E->isSatisfied(),
E);
3001template <
class Emitter>
3007 return this->emitConstBool(
E->isSatisfied(),
E);
3010template <
class Emitter>
3013 return this->delegate(
E->getSemanticForm());
3016template <
class Emitter>
3019 for (
const Expr *SemE :
E->semantics()) {
3020 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
3021 if (SemE ==
E->getResultExpr())
3024 if (OVE->isUnique())
3027 if (!this->discard(OVE))
3029 }
else if (SemE ==
E->getResultExpr()) {
3030 if (!this->delegate(SemE))
3033 if (!this->discard(SemE))
3040template <
class Emitter>
3042 return this->delegate(
E->getSelectedExpr());
3045template <
class Emitter>
3047 return this->emitError(
E);
3050template <
class Emitter>
3054 unsigned Offset = allocateLocalPrimitive(
3055 E->getLabel(),
PT_Ptr,
true,
false);
3057 return this->emitGetLocal(
PT_Ptr, Offset,
E);
3060template <
class Emitter>
3062 assert(Initializing);
3064 QualType ElemType = VT->getElementType();
3065 PrimType ElemT = classifyPrim(ElemType);
3066 const Expr *Src =
E->getSrcExpr();
3070 unsigned SrcOffset = this->allocateLocalPrimitive(Src,
PT_Ptr,
true,
false);
3071 if (!this->visit(Src))
3073 if (!this->emitSetLocal(
PT_Ptr, SrcOffset,
E))
3076 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
3077 if (!this->emitGetLocal(
PT_Ptr, SrcOffset,
E))
3079 if (!this->emitArrayElemPop(SrcElemT, I,
E))
3081 if (SrcElemT != ElemT) {
3082 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType,
E))
3085 if (!this->emitInitElem(ElemT, I,
E))
3092template <
class Emitter>
3094 assert(Initializing);
3095 assert(
E->getNumSubExprs() > 2);
3097 const Expr *Vecs[] = {
E->getExpr(0),
E->getExpr(1)};
3101 unsigned NumOutputElems =
E->getNumSubExprs() - 2;
3102 assert(NumOutputElems > 0);
3105 unsigned VectorOffsets[2];
3106 for (
unsigned I = 0; I != 2; ++I) {
3107 VectorOffsets[I] = this->allocateLocalPrimitive(
3108 Vecs[I],
PT_Ptr,
true,
false);
3109 if (!this->visit(Vecs[I]))
3111 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I],
E))
3114 for (
unsigned I = 0; I != NumOutputElems; ++I) {
3115 APSInt ShuffleIndex =
E->getShuffleMaskIdx(Ctx.getASTContext(), I);
3116 if (ShuffleIndex == -1)
3117 return this->emitInvalid(
E);
3119 assert(ShuffleIndex < (NumInputElems * 2));
3120 if (!this->emitGetLocal(
PT_Ptr,
3121 VectorOffsets[ShuffleIndex >= NumInputElems],
E))
3123 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
3124 if (!this->emitArrayElemPop(ElemT, InputVectorIndex,
E))
3127 if (!this->emitInitElem(ElemT, I,
E))
3134template <
class Emitter>
3139 Base->getType()->isVectorType() ||
3143 E->getEncodedElementAccess(Indices);
3145 if (Indices.size() == 1) {
3146 if (!this->visit(
Base))
3150 if (!this->emitConstUint32(Indices[0],
E))
3152 return this->emitArrayElemPtrPop(
PT_Uint32,
E);
3155 return this->emitArrayElemPop(classifyPrim(
E->
getType()), Indices[0],
E);
3159 unsigned BaseOffset = allocateLocalPrimitive(
Base,
PT_Ptr,
true,
3161 if (!this->visit(
Base))
3163 if (!this->emitSetLocal(
PT_Ptr, BaseOffset,
E))
3167 if (!Initializing) {
3168 std::optional<unsigned> ResultIndex;
3169 ResultIndex = allocateLocal(
E);
3172 if (!this->emitGetPtrLocal(*ResultIndex,
E))
3180 uint32_t DstIndex = 0;
3181 for (uint32_t I : Indices) {
3182 if (!this->emitGetLocal(
PT_Ptr, BaseOffset,
E))
3184 if (!this->emitArrayElemPop(ElemT, I,
E))
3186 if (!this->emitInitElem(ElemT, DstIndex,
E))
3192 assert(!DiscardResult);
3196template <
class Emitter>
3198 const Expr *SubExpr =
E->getSubExpr();
3199 if (!
E->isExpressibleAsConstantInitializer())
3200 return this->discard(SubExpr) && this->emitInvalid(
E);
3202 return this->delegate(SubExpr);
3205template <
class Emitter>
3208 const Expr *SubExpr =
E->getSubExpr();
3210 Ctx.getASTContext().getAsConstantArrayType(SubExpr->
getType());
3212 assert(Initializing);
3215 if (!this->visit(SubExpr))
3227 assert(SecondFieldT ==
PT_Ptr);
3233 if (!this->emitArrayElemPtrPop(
PT_Uint64,
E))
3238template <
class Emitter>
3247 if (!this->visitStmt(S))
3252 assert(S == Result);
3253 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
3254 return this->delegate(ResultExpr);
3255 return this->emitUnsupported(
E);
3264 return this->Visit(
E);
3271 return this->Visit(
E);
3279 return this->discard(
E);
3284 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3288 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3290 return this->visitInitializer(
E);
3297 return this->Visit(
E);
3300template <
class Emitter>
3305 return this->emitError(
E);
3307 if (!this->checkLiteralType(
E))
3312 return this->Visit(
E);
3316 std::optional<PrimType>
T = classify(
E->
getType());
3320 if (!this->visit(
E))
3322 return this->emitComplexBoolCast(
E);
3327 if (!this->visit(
E))
3335 if (!this->emitNull(*
T,
nullptr,
E))
3337 return this->emitNE(*
T,
E);
3342 return this->emitCastFloatingIntegralBool(
E);
3348template <
class Emitter>
3353 return this->emitZeroBool(
E);
3355 return this->emitZeroSint8(
E);
3357 return this->emitZeroUint8(
E);
3359 return this->emitZeroSint16(
E);
3361 return this->emitZeroUint16(
E);
3363 return this->emitZeroSint32(
E);
3365 return this->emitZeroUint32(
E);
3367 return this->emitZeroSint64(
E);
3369 return this->emitZeroUint64(
E);
3371 return this->emitZeroIntAP(Ctx.getBitWidth(QT),
E);
3373 return this->emitZeroIntAPS(Ctx.getBitWidth(QT),
E);
3375 return this->emitNullPtr(
nullptr,
E);
3377 return this->emitNullFnPtr(
nullptr,
E);
3379 return this->emitNullMemberPtr(
nullptr,
E);
3381 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)),
E);
3384 llvm_unreachable(
"unknown primitive type");
3387template <
class Emitter>
3393 for (
const Record::Field &Field : R->
fields()) {
3394 if (
Field.Decl->isUnnamedBitField())
3398 if (
D->isPrimitive()) {
3401 if (!this->visitZeroInitializer(
T, QT,
E))
3403 if (!this->emitInitField(
T,
Field.Offset,
E))
3410 if (!this->emitGetPtrField(
Field.Offset,
E))
3413 if (
D->isPrimitiveArray()) {
3416 for (uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
3417 if (!this->visitZeroInitializer(
T, ET,
E))
3419 if (!this->emitInitElem(
T, I,
E))
3422 }
else if (
D->isCompositeArray()) {
3423 const Record *ElemRecord =
D->ElemDesc->ElemRecord;
3424 assert(
D->ElemDesc->ElemRecord);
3425 for (uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
3426 if (!this->emitConstUint32(I,
E))
3430 if (!this->visitZeroRecordInitializer(ElemRecord,
E))
3432 if (!this->emitPopPtr(
E))
3435 }
else if (
D->isRecord()) {
3436 if (!this->visitZeroRecordInitializer(
D->ElemRecord,
E))
3442 if (!this->emitFinishInitPop(
E))
3449 for (
const Record::Base &B : R->
bases()) {
3450 if (!this->emitGetPtrBase(B.Offset,
E))
3452 if (!this->visitZeroRecordInitializer(B.R,
E))
3454 if (!this->emitFinishInitPop(
E))
3463template <
class Emitter>
3464template <
typename T>
3468 return this->emitConstSint8(
Value,
E);
3470 return this->emitConstUint8(
Value,
E);
3472 return this->emitConstSint16(
Value,
E);
3474 return this->emitConstUint16(
Value,
E);
3476 return this->emitConstSint32(
Value,
E);
3478 return this->emitConstUint32(
Value,
E);
3480 return this->emitConstSint64(
Value,
E);
3482 return this->emitConstUint64(
Value,
E);
3484 return this->emitConstBool(
Value,
E);
3491 llvm_unreachable(
"Invalid integral type");
3494 llvm_unreachable(
"unknown primitive type");
3497template <
class Emitter>
3498template <
typename T>
3503template <
class Emitter>
3507 return this->emitConstIntAPS(
Value,
E);
3509 return this->emitConstIntAP(
Value,
E);
3511 if (
Value.isSigned())
3512 return this->emitConst(
Value.getSExtValue(), Ty,
E);
3513 return this->emitConst(
Value.getZExtValue(), Ty,
E);
3516template <
class Emitter>
3521template <
class Emitter>
3526 if (
const auto *VD =
3527 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
3528 assert(!
P.getGlobal(VD));
3529 assert(!Locals.contains(VD));
3537 Src.is<
const Expr *>());
3539 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
3540 Locals.insert({VD, Local});
3541 VarScope->add(Local, IsExtended);
3542 return Local.Offset;
3545template <
class Emitter>
3546std::optional<unsigned>
3549 if ([[maybe_unused]]
const auto *VD =
3550 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
3551 assert(!
P.getGlobal(VD));
3552 assert(!Locals.contains(VD));
3558 bool IsTemporary =
false;
3559 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
3563 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
3564 Init = VarD->getInit();
3566 if (
auto *
E = Src.dyn_cast<
const Expr *>()) {
3573 IsTemporary,
false,
Init);
3575 return std::nullopt;
3579 Locals.insert({Key, Local});
3581 VarScope->addExtended(Local, ExtendingDecl);
3583 VarScope->add(Local,
false);
3584 return Local.Offset;
3587template <
class Emitter>
3594 true,
false,
nullptr);
3601 while (S->getParent())
3603 assert(S && !S->getParent());
3605 return Local.Offset;
3608template <
class Emitter>
3610 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
3616 if (
const auto *RecordTy = getRecordTy(Ty))
3617 return getRecord(RecordTy->getDecl());
3621template <
class Emitter>
3623 return P.getOrCreateRecord(RD);
3626template <
class Emitter>
3628 return Ctx.getOrCreateFunction(FD);
3641 if (std::optional<PrimType>
T = classify(
E)) {
3650 if (std::optional<unsigned> LocalOffset = this->allocateLocal(
E)) {
3651 if (!this->emitGetPtrLocal(*LocalOffset,
E))
3654 if (!visitInitializer(
E))
3657 if (!this->emitFinishInit(
E))
3669template <
class Emitter>
3672 auto R = this->visitVarDecl(VD,
true);
3681 if (
auto GlobalIndex =
P.getGlobal(VD)) {
3682 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
3686 GD.
InitState = GlobalInitState::InitializerFailed;
3697template <
class Emitter>
3699 bool ConstantContext) {
3700 std::optional<PrimType> VarT = classify(VD->
getType());
3704 if (!ConstantContext) {
3712 if (!this->visitVarDecl(VD,
true))
3716 auto GlobalIndex =
P.getGlobal(VD);
3717 assert(GlobalIndex);
3719 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
3722 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
3726 auto Local = Locals.find(VD);
3727 assert(Local != Locals.end());
3729 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
3732 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
3738 if (!this->emitRet(VarT.value_or(
PT_Ptr), VD)) {
3742 auto GlobalIndex =
P.getGlobal(VD);
3743 assert(GlobalIndex);
3744 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
3748 GD.
InitState = GlobalInitState::InitializerFailed;
3757template <
class Emitter>
3766 if (!this->isActive())
3770 std::optional<PrimType> VarT = classify(VD->
getType());
3772 if (
Init &&
Init->isValueDependent())
3776 auto checkDecl = [&]() ->
bool {
3778 return !NeedsOp || this->emitCheckDecl(VD, VD);
3781 auto initGlobal = [&](
unsigned GlobalIndex) ->
bool {
3786 if (!this->visit(
Init))
3787 return checkDecl() &&
false;
3789 return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
3795 if (!this->emitGetPtrGlobal(GlobalIndex,
Init))
3798 if (!visitInitializer(
Init))
3801 if (!this->emitFinishInit(
Init))
3804 return this->emitPopPtr(
Init);
3808 if (std::optional<unsigned> GlobalIndex =
P.getGlobal(VD)) {
3809 if (
P.getPtrGlobal(*GlobalIndex).isInitialized())
3814 return Init && checkDecl() && initGlobal(*GlobalIndex);
3817 std::optional<unsigned> GlobalIndex =
P.createGlobal(VD,
Init);
3822 return !
Init || (checkDecl() && initGlobal(*GlobalIndex));
3827 unsigned Offset = this->allocateLocalPrimitive(
3834 if (!this->visit(
Init))
3836 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
3838 if (!this->visit(
Init))
3840 return this->emitSetLocal(*VarT, Offset, VD);
3844 if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
3848 if (!this->emitGetPtrLocal(*Offset,
Init))
3851 if (!visitInitializer(
Init))
3854 if (!this->emitFinishInit(
Init))
3857 return this->emitPopPtr(
Init);
3867template <
class Emitter>
3870 assert(!DiscardResult);
3872 return this->emitConst(Val.
getInt(), ValType,
E);
3874 return this->emitConstFloat(Val.
getFloat(),
E);
3878 return this->emitNull(ValType,
nullptr,
E);
3880 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
3881 return this->visit(BaseExpr);
3882 else if (
const auto *VD =
Base.dyn_cast<
const ValueDecl *>()) {
3883 return this->visitDeclRef(VD,
E);
3887 return this->emitGetMemberPtr(MemberDecl,
E);
3888 return this->emitNullMemberPtr(
nullptr,
E);
3894template <
class Emitter>
3903 const Record::Field *RF = R->
getField(I);
3906 PrimType T = classifyPrim(RF->Decl->getType());
3907 if (!this->visitAPValue(F,
T,
E))
3909 if (!this->emitInitField(
T, RF->Offset,
E))
3912 assert(RF->Desc->isPrimitiveArray());
3913 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
3914 PrimType ElemT = classifyPrim(ArrType->getElementType());
3917 if (!this->emitGetPtrField(RF->Offset,
E))
3920 for (
unsigned A = 0, AN = F.
getArraySize(); A != AN; ++A) {
3923 if (!this->emitInitElem(ElemT, A,
E))
3927 if (!this->emitPopPtr(
E))
3930 if (!this->emitGetPtrField(RF->Offset,
E))
3932 if (!this->visitAPValueInitializer(F,
E))
3934 if (!this->emitPopPtr(
E))
3937 assert(
false &&
"I don't think this should be possible");
3946 const Record::Field *RF = R->
getField(UnionField);
3947 PrimType T = classifyPrim(RF->Decl->getType());
3948 if (!this->visitAPValue(F,
T,
E))
3950 return this->emitInitField(
T, RF->Offset,
E);
3957template <
class Emitter>
3965 unsigned Builtin =
E->getBuiltinCallee();
3966 if (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
3967 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
3968 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
3969 Builtin == Builtin::BI__builtin_function_start) {
3970 if (std::optional<unsigned> GlobalOffset =
P.createGlobal(
E)) {
3971 if (!this->emitGetPtrGlobal(*GlobalOffset,
E))
3975 return this->emitDecayPtr(
PT_Ptr, PT,
E);
3982 std::optional<PrimType> ReturnT = classify(
E);
3985 if (!Initializing && !ReturnT && !ReturnType->
isVoidType()) {
3986 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3989 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3993 if (!
Func->isUnevaluatedBuiltin()) {
3995 for (
const auto *Arg :
E->arguments()) {
3996 if (!this->visit(Arg))
4001 if (!this->emitCallBI(
Func,
E,
E))
4004 if (DiscardResult && !ReturnType->
isVoidType()) {
4006 return this->emitPop(*ReturnT,
E);
4012template <
class Emitter>
4014 if (
E->getBuiltinCallee())
4015 return VisitBuiltinCallExpr(
E);
4017 QualType ReturnType =
E->getCallReturnType(Ctx.getASTContext());
4018 std::optional<PrimType>
T = classify(ReturnType);
4023 if (DiscardResult) {
4027 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4028 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4034 if (!Initializing) {
4035 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4036 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4040 if (!this->emitDupPtr(
E))
4048 bool IsAssignmentOperatorCall =
false;
4049 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
4050 OCE && OCE->isAssignmentOp()) {
4054 assert(Args.size() == 2);
4055 IsAssignmentOperatorCall =
true;
4056 std::reverse(Args.begin(), Args.end());
4061 if (isa<CXXOperatorCallExpr>(
E)) {
4062 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
4063 MD && MD->isStatic()) {
4064 if (!this->discard(
E->getArg(0)))
4067 Args.erase(Args.begin());
4071 std::optional<unsigned> CalleeOffset;
4073 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(
E)) {
4074 if (!FuncDecl && classifyPrim(
E->getCallee()) ==
PT_MemberPtr) {
4078 const Expr *Callee =
E->getCallee();
4080 this->allocateLocalPrimitive(Callee,
PT_MemberPtr,
true,
false);
4081 if (!this->visit(Callee))
4087 if (!this->emitGetMemberPtrBase(
E))
4089 }
else if (!this->visit(MC->getImplicitObjectArgument())) {
4092 }
else if (!FuncDecl) {
4093 const Expr *Callee =
E->getCallee();
4094 CalleeOffset = this->allocateLocalPrimitive(Callee,
PT_FnPtr,
true,
false);
4095 if (!this->visit(Callee))
4097 if (!this->emitSetLocal(
PT_FnPtr, *CalleeOffset,
E))
4103 unsigned ArgIndex = 0;
4104 for (
const auto *Arg : Args) {
4105 if (!this->visit(Arg))
4109 if (FuncDecl && NonNullArgs[ArgIndex]) {
4112 if (!this->emitCheckNonNullArg(ArgT, Arg))
4120 if (IsAssignmentOperatorCall) {
4121 assert(Args.size() == 2);
4124 if (!this->emitFlip(Arg2T, Arg1T,
E))
4132 assert(HasRVO ==
Func->hasRVO());
4134 bool HasQualifier =
false;
4135 if (
const auto *ME = dyn_cast<MemberExpr>(
E->getCallee()))
4136 HasQualifier = ME->hasQualifier();
4138 bool IsVirtual =
false;
4139 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
4140 IsVirtual = MD->isVirtual();
4145 if (IsVirtual && !HasQualifier) {
4146 uint32_t VarArgSize = 0;
4147 unsigned NumParams =
4148 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4149 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4152 if (!this->emitCallVirt(
Func, VarArgSize,
E))
4154 }
else if (
Func->isVariadic()) {
4155 uint32_t VarArgSize = 0;
4156 unsigned NumParams =
4157 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4158 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4160 if (!this->emitCallVar(
Func, VarArgSize,
E))
4163 if (!this->emitCall(
Func, 0,
E))
4172 uint32_t ArgSize = 0;
4173 for (
unsigned I = 0, N =
E->getNumArgs(); I != N; ++I)
4178 if (isa<CXXMemberCallExpr>(
E) && CalleeOffset) {
4181 if (!this->emitGetMemberPtrDecl(
E))
4184 if (!this->emitGetLocal(
PT_FnPtr, *CalleeOffset,
E))
4187 if (!this->emitCallPtr(ArgSize,
E,
E))
4192 if (DiscardResult && !ReturnType->
isVoidType() &&
T)
4193 return this->emitPop(*
T,
E);
4198template <
class Emitter>
4202 return this->delegate(
E->getExpr());
4205template <
class Emitter>
4209 const Expr *SubExpr =
E->getExpr();
4210 if (std::optional<PrimType>
T = classify(
E->getExpr()))
4211 return this->visit(SubExpr);
4213 assert(Initializing);
4214 return this->visitInitializer(SubExpr);
4217template <
class Emitter>
4222 return this->emitConstBool(
E->getValue(),
E);
4225template <
class Emitter>
4231 return this->emitNullPtr(
nullptr,
E);
4234template <
class Emitter>
4242 return this->emitZero(
T,
E);
4245template <
class Emitter>
4250 if (this->LambdaThisCapture.Offset > 0) {
4251 if (this->LambdaThisCapture.IsPtr)
4252 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset,
E);
4253 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset,
E);
4260 if (!InitStackActive || !
E->isImplicit())
4261 return this->emitThis(
E);
4263 if (InitStackActive && !InitStack.empty()) {
4264 unsigned StartIndex = 0;
4265 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
4271 for (
unsigned I = StartIndex, N = InitStack.size(); I != N; ++I) {
4272 if (!InitStack[I].
template emit<Emitter>(
this,
E))
4277 return this->emitThis(
E);
4281 switch (S->getStmtClass()) {
4282 case Stmt::CompoundStmtClass:
4283 return visitCompoundStmt(cast<CompoundStmt>(S));
4284 case Stmt::DeclStmtClass:
4285 return visitDeclStmt(cast<DeclStmt>(S));
4286 case Stmt::ReturnStmtClass:
4287 return visitReturnStmt(cast<ReturnStmt>(S));
4288 case Stmt::IfStmtClass:
4289 return visitIfStmt(cast<IfStmt>(S));
4290 case Stmt::WhileStmtClass:
4291 return visitWhileStmt(cast<WhileStmt>(S));
4292 case Stmt::DoStmtClass:
4293 return visitDoStmt(cast<DoStmt>(S));
4294 case Stmt::ForStmtClass:
4295 return visitForStmt(cast<ForStmt>(S));
4296 case Stmt::CXXForRangeStmtClass:
4297 return visitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
4298 case Stmt::BreakStmtClass:
4299 return visitBreakStmt(cast<BreakStmt>(S));
4300 case Stmt::ContinueStmtClass:
4301 return visitContinueStmt(cast<ContinueStmt>(S));
4302 case Stmt::SwitchStmtClass:
4303 return visitSwitchStmt(cast<SwitchStmt>(S));
4304 case Stmt::CaseStmtClass:
4305 return visitCaseStmt(cast<CaseStmt>(S));
4306 case Stmt::DefaultStmtClass:
4307 return visitDefaultStmt(cast<DefaultStmt>(S));
4308 case Stmt::AttributedStmtClass:
4309 return visitAttributedStmt(cast<AttributedStmt>(S));
4310 case Stmt::CXXTryStmtClass:
4311 return visitCXXTryStmt(cast<CXXTryStmt>(S));
4312 case Stmt::NullStmtClass:
4315 case Stmt::GCCAsmStmtClass:
4316 case Stmt::MSAsmStmtClass:
4317 case Stmt::GotoStmtClass:
4318 return this->emitInvalid(S);
4319 case Stmt::LabelStmtClass:
4320 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
4322 if (
const auto *
E = dyn_cast<Expr>(S))
4323 return this->discard(
E);
4329template <
class Emitter>
4332 for (
const auto *InnerStmt : S->body())
4333 if (!visitStmt(InnerStmt))
4335 return Scope.destroyLocals();
4338template <
class Emitter>
4340 for (
const auto *
D : DS->
decls()) {
4345 const auto *VD = dyn_cast<VarDecl>(
D);
4348 if (!this->visitVarDecl(VD))
4355template <
class Emitter>
4357 if (this->InStmtExpr)
4358 return this->emitUnsupported(RS);
4364 if (!this->visit(RE))
4366 this->emitCleanup();
4367 return this->emitRet(*ReturnType, RS);
4368 }
else if (RE->getType()->isVoidType()) {
4369 if (!this->visit(RE))
4373 if (!this->emitRVOPtr(RE))
4375 if (!this->visitInitializer(RE))
4377 if (!this->emitPopPtr(RE))
4380 this->emitCleanup();
4381 return this->emitRetVoid(RS);
4386 this->emitCleanup();
4387 return this->emitRetVoid(RS);
4391 if (
auto *CondInit = IS->
getInit())
4392 if (!visitStmt(CondInit))
4396 if (!visitDeclStmt(CondDecl))
4401 if (!this->emitIsConstantContext(IS))
4404 if (!this->emitIsConstantContext(IS))
4406 if (!this->emitInv(IS))
4409 if (!this->visitBool(IS->
getCond()))
4414 LabelTy LabelElse = this->getLabel();
4415 LabelTy LabelEnd = this->getLabel();
4416 if (!this->jumpFalse(LabelElse))
4418 if (!visitStmt(IS->
getThen()))
4420 if (!this->jump(LabelEnd))
4422 this->emitLabel(LabelElse);
4423 if (!visitStmt(Else))
4425 this->emitLabel(LabelEnd);
4427 LabelTy LabelEnd = this->getLabel();
4428 if (!this->jumpFalse(LabelEnd))
4430 if (!visitStmt(IS->
getThen()))
4432 this->emitLabel(LabelEnd);
4438template <
class Emitter>
4440 const Expr *Cond = S->getCond();
4441 const Stmt *Body = S->getBody();
4443 LabelTy CondLabel = this->getLabel();
4444 LabelTy EndLabel = this->getLabel();
4447 this->fallthrough(CondLabel);
4448 this->emitLabel(CondLabel);
4450 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
4451 if (!visitDeclStmt(CondDecl))
4454 if (!this->visitBool(Cond))
4456 if (!this->jumpFalse(EndLabel))
4459 if (!this->visitStmt(Body))
4462 if (!this->jump(CondLabel))
4464 this->fallthrough(EndLabel);
4465 this->emitLabel(EndLabel);
4471 const Expr *Cond = S->getCond();
4472 const Stmt *Body = S->getBody();
4474 LabelTy StartLabel = this->getLabel();
4475 LabelTy EndLabel = this->getLabel();
4476 LabelTy CondLabel = this->getLabel();
4479 this->fallthrough(StartLabel);
4480 this->emitLabel(StartLabel);
4482 if (!this->visitStmt(Body))
4484 this->fallthrough(CondLabel);
4485 this->emitLabel(CondLabel);
4486 if (!this->visitBool(Cond))
4489 if (!this->jumpTrue(StartLabel))
4492 this->fallthrough(EndLabel);
4493 this->emitLabel(EndLabel);
4497template <
class Emitter>
4501 const Expr *Cond = S->getCond();
4502 const Expr *
Inc = S->getInc();
4503 const Stmt *Body = S->getBody();
4505 LabelTy EndLabel = this->getLabel();
4506 LabelTy CondLabel = this->getLabel();
4507 LabelTy IncLabel = this->getLabel();
4510 if (
Init && !this->visitStmt(
Init))
4513 this->fallthrough(CondLabel);
4514 this->emitLabel(CondLabel);
4516 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
4517 if (!visitDeclStmt(CondDecl))
4521 if (!this->visitBool(Cond))
4523 if (!this->jumpFalse(EndLabel))
4528 if (Body && !this->visitStmt(Body))
4531 this->fallthrough(IncLabel);
4532 this->emitLabel(IncLabel);
4533 if (
Inc && !this->discard(
Inc))
4537 if (!this->jump(CondLabel))
4539 this->fallthrough(EndLabel);
4540 this->emitLabel(EndLabel);
4544template <
class Emitter>
4547 const Expr *Cond = S->getCond();
4548 const Expr *
Inc = S->getInc();
4549 const Stmt *Body = S->getBody();
4550 const Stmt *BeginStmt = S->getBeginStmt();
4551 const Stmt *RangeStmt = S->getRangeStmt();
4552 const Stmt *EndStmt = S->getEndStmt();
4553 const VarDecl *LoopVar = S->getLoopVariable();
4555 LabelTy EndLabel = this->getLabel();
4556 LabelTy CondLabel = this->getLabel();
4557 LabelTy IncLabel = this->getLabel();
4561 if (
Init && !this->visitStmt(
Init))
4563 if (!this->visitStmt(RangeStmt))
4565 if (!this->visitStmt(BeginStmt))
4567 if (!this->visitStmt(EndStmt))
4571 this->fallthrough(CondLabel);
4572 this->emitLabel(CondLabel);
4573 if (!this->visitBool(Cond))
4575 if (!this->jumpFalse(EndLabel))
4578 if (!this->visitVarDecl(LoopVar))
4583 if (!this->visitStmt(Body))
4586 this->fallthrough(IncLabel);
4587 this->emitLabel(IncLabel);
4588 if (!this->discard(
Inc))
4592 if (!this->jump(CondLabel))
4595 this->fallthrough(EndLabel);
4596 this->emitLabel(EndLabel);
4600template <
class Emitter>
4605 this->emitCleanup();
4606 return this->jump(*BreakLabel);
4609template <
class Emitter>
4614 this->emitCleanup();
4615 return this->jump(*ContinueLabel);
4618template <
class Emitter>
4620 const Expr *Cond = S->getCond();
4623 LabelTy EndLabel = this->getLabel();
4625 unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT,
true,
false);
4627 if (
const auto *CondInit = S->getInit())
4628 if (!visitStmt(CondInit))
4631 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
4632 if (!visitDeclStmt(CondDecl))
4636 if (!this->visit(Cond))
4638 if (!this->emitSetLocal(CondT, CondVar, S))
4643 for (
const SwitchCase *SC = S->getSwitchCaseList(); SC;
4644 SC = SC->getNextSwitchCase()) {
4645 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
4647 if (CS->caseStmtIsGNURange())
4649 CaseLabels[SC] = this->getLabel();
4655 if (!this->emitGetLocal(CondT, CondVar, CS))
4657 if (!this->visit(
Value))
4661 if (!this->emitEQ(ValueT, S))
4663 if (!this->jumpTrue(CaseLabels[CS]))
4666 assert(!DefaultLabel);
4667 DefaultLabel = this->getLabel();
4674 if (!this->jump(*DefaultLabel))
4677 if (!this->jump(EndLabel))
4682 if (!this->visitStmt(S->getBody()))
4684 this->emitLabel(EndLabel);
4688template <
class Emitter>
4690 this->emitLabel(CaseLabels[S]);
4691 return this->visitStmt(S->getSubStmt());
4694template <
class Emitter>
4696 this->emitLabel(*DefaultLabel);
4697 return this->visitStmt(S->getSubStmt());
4700template <
class Emitter>
4702 if (this->Ctx.getLangOpts().CXXAssumptions &&
4703 !this->Ctx.getLangOpts().MSVCCompat) {
4704 for (
const Attr *A : S->getAttrs()) {
4705 auto *AA = dyn_cast<CXXAssumeAttr>(A);
4709 assert(isa<NullStmt>(S->getSubStmt()));
4711 const Expr *Assumption = AA->getAssumption();
4719 if (!this->visitBool(Assumption))
4722 if (!this->emitAssume(Assumption))
4728 return this->visitStmt(S->getSubStmt());
4731template <
class Emitter>
4734 return this->visitStmt(S->getTryBlock());
4737template <
class Emitter>
4741 assert(cast<CompoundStmt>(MD->
getBody())->body_empty());
4746 const Function *
Func = this->getFunction(LambdaCallOp);
4749 assert(
Func->hasThisPointer());
4752 if (
Func->hasRVO()) {
4753 if (!this->emitRVOPtr(MD))
4761 if (!this->emitNullPtr(
nullptr, MD))
4766 auto It = this->Params.find(PVD);
4767 assert(It != this->Params.end());
4771 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
4772 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
4776 if (!this->emitCall(
Func, 0, LambdaCallOp))
4779 this->emitCleanup();
4781 return this->emitRet(*ReturnType, MD);
4784 return this->emitRetVoid(MD);
4787template <
class Emitter>
4789 if (Ctx.getLangOpts().CPlusPlus23)
4798template <
class Emitter>
4800 assert(!ReturnType);
4802 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
4803 const Expr *InitExpr) ->
bool {
4805 if (InitExpr->getType().isNull())
4808 if (std::optional<PrimType>
T = this->classify(InitExpr)) {
4809 if (!this->visit(InitExpr))
4812 if (F->isBitField())
4813 return this->emitInitThisBitField(*
T, F, FieldOffset, InitExpr);
4814 return this->emitInitThisField(*
T, FieldOffset, InitExpr);
4819 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
4822 if (!this->visitInitializer(InitExpr))
4825 return this->emitFinishInitPop(InitExpr);
4829 const Record *R = this->getRecord(RD);
4835 assert(cast<CompoundStmt>(Ctor->
getBody())->body_empty());
4836 if (!this->emitThis(Ctor))
4845 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
4846 this->emitRetVoid(Ctor);
4850 for (
const auto *
Init : Ctor->
inits()) {
4854 const Expr *InitExpr =
Init->getInit();
4858 if (!emitFieldInitializer(F, F->Offset, InitExpr))
4861 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
4864 if (
Init->isBaseVirtual()) {
4866 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
4872 const Record::Base *B = R->
getBase(BaseDecl);
4874 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
4878 if (!this->visitInitializer(InitExpr))
4880 if (!this->emitFinishInitPop(InitExpr))
4883 assert(IFD->getChainingSize() >= 2);
4885 unsigned NestedFieldOffset = 0;
4886 const Record::Field *NestedField =
nullptr;
4887 for (
const NamedDecl *ND : IFD->chain()) {
4888 const auto *FD = cast<FieldDecl>(ND);
4889 const Record *FieldRecord = this->
P.getOrCreateRecord(FD->getParent());
4890 assert(FieldRecord);
4892 NestedField = FieldRecord->
getField(FD);
4893 assert(NestedField);
4895 NestedFieldOffset += NestedField->Offset;
4897 assert(NestedField);
4899 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
4902 assert(
Init->isDelegatingInitializer());
4903 if (!this->emitThis(InitExpr))
4905 if (!this->visitInitializer(
Init->getInit()))
4907 if (!this->emitPopPtr(InitExpr))
4911 if (!
Scope.destroyLocals())
4915 if (
const auto *Body = Ctor->
getBody())
4916 if (!visitStmt(Body))
4922template <
class Emitter>
4925 const Record *R = this->getRecord(RD);
4930 if (!this->visitStmt(Dtor->
getBody()))
4934 if (!this->emitThis(Dtor))
4940 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
4942 if (!
D->isPrimitive() && !
D->isPrimitiveArray()) {
4945 if (!this->emitDestruction(
D))
4953 for (
const Record::Base &
Base : llvm::reverse(R->
bases())) {
4956 if (!this->emitRecordDestruction(
Base.R))
4963 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
4966template <
class Emitter>
4971 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
4972 return this->compileConstructor(Ctor);
4973 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
4974 return this->compileDestructor(Dtor);
4977 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F);
4979 return this->emitLambdaStaticInvokerBody(MD);
4982 if (
const auto *Body = F->
getBody())
4983 if (!visitStmt(Body))
4992template <
class Emitter>
4994 const Expr *SubExpr =
E->getSubExpr();
4996 return this->VisitComplexUnaryOperator(
E);
4997 std::optional<PrimType>
T = classify(SubExpr->
getType());
4999 switch (
E->getOpcode()) {
5001 if (!Ctx.getLangOpts().CPlusPlus14)
5002 return this->emitInvalid(
E);
5004 return this->emitError(
E);
5006 if (!this->visit(SubExpr))
5010 if (!this->emitIncPtr(
E))
5013 return DiscardResult ? this->emitPopPtr(
E) :
true;
5017 return DiscardResult ? this->emitIncfPop(getRoundingMode(
E),
E)
5018 : this->emitIncf(getRoundingMode(
E),
E);
5021 return DiscardResult ? this->emitIncPop(*
T,
E) : this->emitInc(*
T,
E);
5024 if (!Ctx.getLangOpts().CPlusPlus14)
5025 return this->emitInvalid(
E);
5027 return this->emitError(
E);
5029 if (!this->visit(SubExpr))
5033 if (!this->emitDecPtr(
E))
5036 return DiscardResult ? this->emitPopPtr(
E) :
true;
5040 return DiscardResult ? this->emitDecfPop(getRoundingMode(
E),
E)
5041 : this->emitDecf(getRoundingMode(
E),
E);
5044 return DiscardResult ? this->emitDecPop(*
T,
E) : this->emitDec(*
T,
E);
5047 if (!Ctx.getLangOpts().CPlusPlus14)
5048 return this->emitInvalid(
E);
5050 return this->emitError(
E);
5052 if (!this->visit(SubExpr))
5056 if (!this->emitLoadPtr(
E))
5058 if (!this->emitConstUint8(1,
E))
5060 if (!this->emitAddOffsetUint8(
E))
5062 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5066 if (DiscardResult) {
5068 return this->emitIncfPop(getRoundingMode(
E),
E);
5069 return this->emitIncPop(*
T,
E);
5073 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5074 if (!this->emitLoadFloat(
E))
5076 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5078 if (!this->emitAddf(getRoundingMode(
E),
E))
5080 if (!this->emitStoreFloat(
E))
5084 if (!this->emitLoad(*
T,
E))
5086 if (!this->emitConst(1,
E))
5088 if (!this->emitAdd(*
T,
E))
5090 if (!this->emitStore(*
T,
E))
5096 if (!Ctx.getLangOpts().CPlusPlus14)
5097 return this->emitInvalid(
E);
5099 return this->emitError(
E);
5101 if (!this->visit(SubExpr))
5105 if (!this->emitLoadPtr(
E))
5107 if (!this->emitConstUint8(1,
E))
5109 if (!this->emitSubOffsetUint8(
E))
5111 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5115 if (DiscardResult) {
5117 return this->emitDecfPop(getRoundingMode(
E),
E);
5118 return this->emitDecPop(*
T,
E);
5122 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5123 if (!this->emitLoadFloat(
E))
5125 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5127 if (!this->emitSubf(getRoundingMode(
E),
E))
5129 if (!this->emitStoreFloat(
E))
5133 if (!this->emitLoad(*
T,
E))
5135 if (!this->emitConst(1,
E))
5137 if (!this->emitSub(*
T,
E))
5139 if (!this->emitStore(*
T,
E))
5146 return this->emitError(
E);
5149 return this->discard(SubExpr);
5151 if (!this->visitBool(SubExpr))
5154 if (!this->emitInv(
E))
5158 return this->emitCast(
PT_Bool, ET,
E);
5162 return this->emitError(
E);
5164 if (!this->visit(SubExpr))
5166 return DiscardResult ? this->emitPop(*
T,
E) : this->emitNeg(*
T,
E);
5169 return this->emitError(
E);
5171 if (!this->visit(SubExpr))
5173 return DiscardResult ? this->emitPop(*
T,
E) :
true;
5178 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(),
E);
5181 return this->delegate(SubExpr);
5184 return this->discard(SubExpr);
5185 return this->visit(SubExpr);
5188 return this->emitError(
E);
5190 if (!this->visit(SubExpr))
5192 return DiscardResult ? this->emitPop(*
T,
E) : this->emitComp(*
T,
E);
5195 return this->delegate(SubExpr);
5198 if (!this->discard(SubExpr))
5200 return this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
5203 return this->delegate(SubExpr);
5205 assert(
false &&
"Unhandled opcode");
5211template <
class Emitter>
5213 const Expr *SubExpr =
E->getSubExpr();
5217 return this->discard(SubExpr);
5219 std::optional<PrimType> ResT = classify(
E);
5220 auto prepareResult = [=]() ->
bool {
5221 if (!ResT && !Initializing) {
5222 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5225 return this->emitGetPtrLocal(*LocalIndex,
E);
5232 unsigned SubExprOffset = ~0u;
5233 auto createTemp = [=, &SubExprOffset]() ->
bool {
5234 SubExprOffset = this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
5235 if (!this->visit(SubExpr))
5237 return this->emitSetLocal(
PT_Ptr, SubExprOffset,
E);
5241 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
5242 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
5244 return this->emitArrayElemPop(ElemT, Index,
E);
5247 switch (
E->getOpcode()) {
5249 if (!prepareResult())
5253 for (
unsigned I = 0; I != 2; ++I) {
5254 if (!getElem(SubExprOffset, I))
5256 if (!this->emitNeg(ElemT,
E))
5258 if (!this->emitInitElem(ElemT, I,
E))
5266 return this->delegate(SubExpr);
5269 if (!this->visit(SubExpr))
5271 if (!this->emitComplexBoolCast(SubExpr))
5273 if (!this->emitInv(
E))
5276 return this->emitCast(
PT_Bool, ET,
E);
5280 return this->emitComplexReal(SubExpr);
5283 if (!this->visit(SubExpr))
5287 if (!this->emitConstUint8(1,
E))
5289 return this->emitArrayElemPtrPopUint8(
E);
5294 return this->emitArrayElemPop(classifyPrim(
E->
getType()), 1,
E);
5297 if (!this->visit(SubExpr))
5300 if (!this->emitArrayElem(ElemT, 1,
E))
5302 if (!this->emitNeg(ElemT,
E))
5304 if (!this->emitInitElem(ElemT, 1,
E))
5306 return DiscardResult ? this->emitPopPtr(
E) :
true;
5309 return this->delegate(SubExpr);
5312 return this->emitInvalid(
E);
5318template <
class Emitter>
5323 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(
D)) {
5324 return this->emitConst(ECD->getInitVal(),
E);
5325 }
else if (
const auto *BD = dyn_cast<BindingDecl>(
D)) {
5326 return this->visit(BD->getBinding());
5327 }
else if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(
D)) {
5328 const Function *F = getFunction(FuncDecl);
5329 return F && this->emitGetFnPtr(F,
E);
5330 }
else if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(
D)) {
5331 if (std::optional<unsigned> Index =
P.getOrCreateGlobal(
D)) {
5332 if (!this->emitGetPtrGlobal(*Index,
E))
5334 if (std::optional<PrimType>
T = classify(
E->
getType())) {
5335 if (!this->visitAPValue(TPOD->getValue(), *
T,
E))
5337 return this->emitInitGlobal(*
T, *Index,
E);
5339 return this->visitAPValueInitializer(TPOD->getValue(),
E);
5348 bool IsReference =
D->getType()->isReferenceType();
5351 if (
auto It = Locals.find(
D); It != Locals.end()) {
5352 const unsigned Offset = It->second.Offset;
5354 return this->emitGetLocal(
PT_Ptr, Offset,
E);
5355 return this->emitGetPtrLocal(Offset,
E);
5356 }
else if (
auto GlobalIndex =
P.getGlobal(
D)) {
5358 if (!Ctx.getLangOpts().CPlusPlus11)
5359 return this->emitGetGlobal(classifyPrim(
E), *GlobalIndex,
E);
5360 return this->emitGetGlobalUnchecked(classifyPrim(
E), *GlobalIndex,
E);
5363 return this->emitGetPtrGlobal(*GlobalIndex,
E);
5364 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(
D)) {
5365 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
5366 if (IsReference || !It->second.IsPtr)
5367 return this->emitGetParam(classifyPrim(
E), It->second.Offset,
E);
5369 return this->emitGetPtrParam(It->second.Offset,
E);
5374 auto revisit = [&](
const VarDecl *VD) ->
bool {
5375 auto VarState = this->visitDecl(VD);
5377 if (VarState.notCreated())
5382 return this->visitDeclRef(
D,
E);
5386 if (
auto It = this->LambdaCaptures.find(
D);
5387 It != this->LambdaCaptures.end()) {
5388 auto [Offset, IsPtr] = It->second;
5391 return this->emitGetThisFieldPtr(Offset,
E);
5392 return this->emitGetPtrThisField(Offset,
E);
5393 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E);
5394 DRE && DRE->refersToEnclosingVariableOrCapture()) {
5395 if (
const auto *VD = dyn_cast<VarDecl>(
D); VD && VD->isInitCapture())
5399 if (
D != InitializingDecl) {
5402 if (Ctx.getLangOpts().CPlusPlus) {
5403 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
5404 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
5405 if (
T.isConstant(Ctx.getASTContext()))
5408 return RT->getPointeeType().isConstQualified();
5413 if (isa<DecompositionDecl>(VD))
5417 if ((VD->hasGlobalStorage() || VD->isLocalVarDecl() ||
5418 VD->isStaticDataMember()) &&
5419 typeShouldBeVisited(VD->getType()))
5423 if (
const auto *VD = dyn_cast<VarDecl>(
D);
5424 VD && VD->getAnyInitializer() &&
5425 VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak())
5430 if (std::optional<unsigned> I =
P.getOrCreateDummy(
D)) {
5431 if (!this->emitGetPtrGlobal(*I,
E))
5438 return this->emitDecayPtr(
PT_Ptr, PT,
E);
5444 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E))
5445 return this->emitInvalidDeclRef(DRE,
E);
5449template <
class Emitter>
5451 const auto *
D =
E->getDecl();
5452 return this->visitDeclRef(
D,
E);
5457 C->emitDestruction();
5460template <
class Emitter>
5464 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
5466 return Ty->getAsCXXRecordDecl();
5468 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
5469 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
5471 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
5475template <
class Emitter>
5482 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
5483 return this->emitCastFP(ToSem, getRoundingMode(
E),
E);
5487 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
E);
5489 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
E);
5493 return this->emitCastFloatingIntegral(ToT,
E);
5498 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT),
E);
5500 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT),
E);
5504 return FromT != ToT ? this->emitCast(FromT, ToT,
E) :
true;
5508 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
5509 return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(
E),
5518template <
class Emitter>
5523 return this->discard(SubExpr);
5525 if (!this->visit(SubExpr))
5528 if (!this->emitConstUint8(0, SubExpr))
5530 return this->emitArrayElemPtrPopUint8(SubExpr);
5534 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
5538template <
class Emitter>
5540 assert(!DiscardResult);
5544 if (!this->emitArrayElem(ElemT, 0,
E))
5547 if (!this->emitCastFloatingIntegral(
PT_Bool,
E))
5550 if (!this->emitCast(ElemT,
PT_Bool,
E))
5555 LabelTy LabelTrue = this->getLabel();
5556 if (!this->jumpTrue(LabelTrue))
5559 if (!this->emitArrayElemPop(ElemT, 1,
E))
5562 if (!this->emitCastFloatingIntegral(
PT_Bool,
E))
5565 if (!this->emitCast(ElemT,
PT_Bool,
E))
5569 LabelTy EndLabel = this->getLabel();
5570 this->jump(EndLabel);
5572 this->emitLabel(LabelTrue);
5573 if (!this->emitPopPtr(
E))
5575 if (!this->emitConstBool(
true,
E))
5578 this->fallthrough(EndLabel);
5579 this->emitLabel(EndLabel);
5584template <
class Emitter>
5587 assert(
E->isComparisonOp());
5588 assert(!Initializing);
5589 assert(!DiscardResult);
5595 LHSIsComplex =
true;
5596 ElemT = classifyComplexElementType(LHS->
getType());
5597 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true,
5599 if (!this->visit(LHS))
5601 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
5604 LHSIsComplex =
false;
5606 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
5607 if (!this->visit(LHS))
5609 if (!this->emitSetLocal(LHST, LHSOffset,
E))
5616 RHSIsComplex =
true;
5617 ElemT = classifyComplexElementType(RHS->
getType());
5618 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true,
5620 if (!this->visit(RHS))
5622 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
5625 RHSIsComplex =
false;
5627 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
5628 if (!this->visit(RHS))
5630 if (!this->emitSetLocal(RHST, RHSOffset,
E))
5634 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
5635 bool IsComplex) ->
bool {
5637 if (!this->emitGetLocal(
PT_Ptr, LocalOffset,
E))
5639 return this->emitArrayElemPop(ElemT, Index,
E);
5641 return this->emitGetLocal(ElemT, LocalOffset,
E);
5644 for (
unsigned I = 0; I != 2; ++I) {
5646 if (!getElem(LHSOffset, I, LHSIsComplex))
5648 if (!getElem(RHSOffset, I, RHSIsComplex))
5651 if (!this->emitEQ(ElemT,
E))
5654 if (!this->emitCastBoolUint8(
E))
5659 if (!this->emitAddUint8(
E))
5661 if (!this->emitConstUint8(2,
E))
5664 if (
E->getOpcode() == BO_EQ) {
5665 if (!this->emitEQUint8(
E))
5667 }
else if (
E->getOpcode() == BO_NE) {
5668 if (!this->emitNEUint8(
E))
5675 return this->emitCast(
PT_Bool, ResT,
E);
5682template <
class Emitter>
5690 const Function *DtorFunc = getFunction(Dtor);
5697 return this->emitCall(DtorFunc, 0,
SourceInfo{});
5702template <
class Emitter>
5726 for (ssize_t I = Desc->
getNumElems() - 1; I >= 0; --I) {
5729 if (!this->emitArrayElemPtrUint64(
SourceInfo{}))
5731 if (!this->emitDestruction(ElemDesc))
5740 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()