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->visit(SubExpr))
220 return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
223 case CK_BaseToDerivedMemberPointer: {
229 unsigned DerivedOffset = collectBaseOffset(
QualType(FromMP->getClass(), 0),
232 if (!this->visit(SubExpr))
234 return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
237 case CK_UncheckedDerivedToBase:
238 case CK_DerivedToBase: {
239 if (!this->visit(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->visit(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: {
335 if (!PointeeType.
isNull()) {
336 if (std::optional<PrimType>
T = classify(PointeeType))
337 Desc =
P.createDescriptor(SubExpr, *
T);
339 Desc =
P.createDescriptor(SubExpr, PointeeType.
getTypePtr(),
340 std::nullopt,
true,
false,
343 return this->emitNull(classifyPrim(CE->
getType()), Desc, CE);
346 case CK_PointerToIntegral: {
348 return this->discard(SubExpr);
350 if (!this->visit(SubExpr))
356 if (!this->emitDecayPtr(FromT,
PT_Ptr, CE))
362 return this->emitCastPointerIntegralAP(Ctx.getBitWidth(CE->
getType()),
365 return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(CE->
getType()),
367 return this->emitCastPointerIntegral(
T, CE);
370 case CK_ArrayToPointerDecay: {
371 if (!this->visit(SubExpr))
373 if (!this->emitArrayDecay(CE))
376 return this->emitPopPtr(CE);
380 case CK_IntegralToPointer: {
383 if (!this->visit(SubExpr))
389 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 std::optional<unsigned> LocalIndex = allocateLocal(CE);
539 if (!this->emitGetPtrLocal(*LocalIndex, CE))
544 if (!this->visitArrayElemInit(0, SubExpr))
548 if (!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
550 return this->emitInitElem(
T, 1, SubExpr);
553 case CK_IntegralComplexCast:
554 case CK_FloatingComplexCast:
555 case CK_IntegralComplexToFloatingComplex:
556 case CK_FloatingComplexToIntegralComplex: {
560 return this->discard(SubExpr);
563 std::optional<unsigned> LocalIndex = allocateLocal(CE);
566 if (!this->emitGetPtrLocal(*LocalIndex, CE))
573 unsigned SubExprOffset = allocateLocalPrimitive(
574 SubExpr,
PT_Ptr,
true,
false);
575 if (!this->visit(SubExpr))
577 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, CE))
583 PrimType DestElemT = classifyPrim(DestElemType);
585 for (
unsigned I = 0; I != 2; ++I) {
586 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, CE))
588 if (!this->emitArrayElemPop(SourceElemT, I, CE))
592 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
596 if (!this->emitInitElem(DestElemT, I, CE))
602 case CK_VectorSplat: {
603 assert(!classify(CE->
getType()));
604 assert(classify(SubExpr->
getType()));
608 return this->discard(SubExpr);
611 std::optional<unsigned> LocalIndex = allocateLocal(CE);
614 if (!this->emitGetPtrLocal(*LocalIndex, CE))
620 unsigned ElemOffset = allocateLocalPrimitive(
621 SubExpr, ElemT,
true,
false);
624 if (!this->visit(SubExpr))
626 if (classifyPrim(SubExpr) ==
PT_Ptr && !this->emitLoadPop(ElemT, CE))
629 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
632 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
633 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
635 if (!this->emitInitElem(ElemT, I, CE))
643 return discard(SubExpr);
646 return this->emitInvalid(CE);
648 llvm_unreachable(
"Unhandled clang::CastKind enum");
651template <
class Emitter>
656 return this->emitConst(
LE->getValue(),
LE);
659template <
class Emitter>
664 return this->emitConstFloat(
E->getValue(),
E);
667template <
class Emitter>
674 std::optional<unsigned> LocalIndex = allocateLocal(
E);
677 if (!this->emitGetPtrLocal(*LocalIndex,
E))
681 const Expr *SubExpr =
E->getSubExpr();
684 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
686 if (!this->emitInitElem(SubExprT, 0, SubExpr))
688 return this->visitArrayElemInit(1, SubExpr);
691template <
class Emitter>
693 return this->delegate(
E->getSubExpr());
696template <
class Emitter>
700 return this->VisitLogicalBinOp(BO);
708 if (!this->discard(LHS))
711 return this->discard(RHS);
713 return this->delegate(RHS);
717 return this->VisitComplexBinOp(BO);
721 return this->emitComplexComparison(LHS, RHS, BO);
724 if (!this->visit(LHS))
727 if (!this->visit(RHS))
730 if (!this->emitToMemberPtr(BO))
736 if (!this->emitCastMemberPtrPtr(BO))
738 return DiscardResult ? this->emitPopPtr(BO) :
true;
742 std::optional<PrimType>
LT = classify(LHS);
743 std::optional<PrimType> RT = classify(RHS);
744 std::optional<PrimType>
T = classify(BO->
getType());
753 Ctx.getASTContext().CompCategories.lookupInfoForType(BO->
getType());
758 std::optional<unsigned> ResultIndex = this->allocateLocal(BO);
759 if (!this->emitGetPtrLocal(*ResultIndex, BO))
763 if (!visit(LHS) || !visit(RHS))
766 return this->emitCMP3(*
LT, CmpInfo, BO);
769 if (!
LT || !RT || !
T)
775 return this->VisitPointerArithBinOp(BO);
780 if (!visit(RHS) || !visit(LHS))
782 if (!this->emitFlip(*
LT, *RT, BO))
785 if (!visit(LHS) || !visit(RHS))
791 auto MaybeCastToBool = [
this,
T, BO](
bool Result) {
795 return this->emitPop(*
T, BO);
797 return this->emitCast(
PT_Bool, *
T, BO);
801 auto Discard = [
this,
T, BO](
bool Result) {
804 return DiscardResult ? this->emitPop(*
T, BO) :
true;
809 return MaybeCastToBool(this->emitEQ(*
LT, BO));
811 return MaybeCastToBool(this->emitNE(*
LT, BO));
813 return MaybeCastToBool(this->emitLT(*
LT, BO));
815 return MaybeCastToBool(this->emitLE(*
LT, BO));
817 return MaybeCastToBool(this->emitGT(*
LT, BO));
819 return MaybeCastToBool(this->emitGE(*
LT, BO));
822 return Discard(this->emitSubf(getRoundingMode(BO), BO));
823 return Discard(this->emitSub(*
T, BO));
826 return Discard(this->emitAddf(getRoundingMode(BO), BO));
827 return Discard(this->emitAdd(*
T, BO));
830 return Discard(this->emitMulf(getRoundingMode(BO), BO));
831 return Discard(this->emitMul(*
T, BO));
833 return Discard(this->emitRem(*
T, BO));
836 return Discard(this->emitDivf(getRoundingMode(BO), BO));
837 return Discard(this->emitDiv(*
T, BO));
841 : this->emitStorePop(*
T, BO);
843 if (!this->emitStoreBitField(*
T, BO))
846 if (!this->emitStore(*
T, BO))
852 return this->emitLoadPop(*
T, BO);
855 return Discard(this->emitBitAnd(*
T, BO));
857 return Discard(this->emitBitOr(*
T, BO));
859 return Discard(this->emitShl(*
LT, *RT, BO));
861 return Discard(this->emitShr(*
LT, *RT, BO));
863 return Discard(this->emitBitXor(*
T, BO));
866 llvm_unreachable(
"Already handled earlier");
871 llvm_unreachable(
"Unhandled binary op");
876template <
class Emitter>
879 const Expr *LHS =
E->getLHS();
880 const Expr *RHS =
E->getRHS();
882 if ((Op != BO_Add && Op != BO_Sub) ||
886 std::optional<PrimType>
LT = classify(LHS);
887 std::optional<PrimType> RT = classify(RHS);
897 if (!visit(RHS) || !visit(LHS))
900 return this->emitSubPtr(classifyPrim(
E->
getType()),
E);
905 if (!visit(RHS) || !visit(LHS))
909 if (!visit(LHS) || !visit(RHS))
917 return this->emitAddOffset(OffsetType,
E);
918 else if (Op == BO_Sub)
919 return this->emitSubOffset(OffsetType,
E);
924template <
class Emitter>
926 assert(
E->isLogicalOp());
928 const Expr *LHS =
E->getLHS();
929 const Expr *RHS =
E->getRHS();
930 std::optional<PrimType>
T = classify(
E->
getType());
934 LabelTy LabelTrue = this->getLabel();
935 LabelTy LabelEnd = this->getLabel();
937 if (!this->visitBool(LHS))
939 if (!this->jumpTrue(LabelTrue))
942 if (!this->visitBool(RHS))
944 if (!this->jump(LabelEnd))
947 this->emitLabel(LabelTrue);
948 this->emitConstBool(
true,
E);
949 this->fallthrough(LabelEnd);
950 this->emitLabel(LabelEnd);
953 assert(Op == BO_LAnd);
956 LabelTy LabelFalse = this->getLabel();
957 LabelTy LabelEnd = this->getLabel();
959 if (!this->visitBool(LHS))
961 if (!this->jumpFalse(LabelFalse))
964 if (!this->visitBool(RHS))
966 if (!this->jump(LabelEnd))
969 this->emitLabel(LabelFalse);
970 this->emitConstBool(
false,
E);
971 this->fallthrough(LabelEnd);
972 this->emitLabel(LabelEnd);
976 return this->emitPopBool(
E);
985template <
class Emitter>
989 std::optional<unsigned> LocalIndex = allocateLocal(
E);
992 if (!this->emitGetPtrLocal(*LocalIndex,
E))
998 const Expr *LHS =
E->getLHS();
999 const Expr *RHS =
E->getRHS();
1002 unsigned ResultOffset = ~0u;
1004 ResultOffset = this->allocateLocalPrimitive(
E,
PT_Ptr,
true,
false);
1007 if (!this->DiscardResult) {
1008 if (!this->emitDupPtr(
E))
1010 if (!this->emitSetLocal(
PT_Ptr, ResultOffset,
E))
1015 LHSType = AT->getValueType();
1018 RHSType = AT->getValueType();
1027 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1032 if (!this->visit(LHS))
1034 if (!this->visit(RHS))
1036 return this->emitMulc(ElemT,
E);
1039 if (Op == BO_Div && RHSIsComplex) {
1041 PrimType ElemT = classifyPrim(ElemQT);
1046 if (!LHSIsComplex) {
1048 if (
auto LHSO = allocateLocal(RHS))
1053 if (!this->emitGetPtrLocal(LHSOffset,
E))
1056 if (!this->visit(LHS))
1059 if (!this->emitInitElem(ElemT, 0,
E))
1062 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1064 if (!this->emitInitElem(ElemT, 1,
E))
1067 if (!this->visit(LHS))
1071 if (!this->visit(RHS))
1073 return this->emitDivc(ElemT,
E);
1078 LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
1079 if (!this->visit(LHS))
1081 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1084 PrimType LHST = classifyPrim(LHSType);
1085 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
1086 if (!this->visit(LHS))
1088 if (!this->emitSetLocal(LHST, LHSOffset,
E))
1095 RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
1096 if (!this->visit(RHS))
1098 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1101 PrimType RHST = classifyPrim(RHSType);
1102 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
1103 if (!this->visit(RHS))
1105 if (!this->emitSetLocal(RHST, RHSOffset,
E))
1112 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1113 unsigned ElemIndex,
unsigned Offset,
1114 const Expr *
E) ->
bool {
1116 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
1118 return this->emitArrayElemPop(classifyComplexElementType(
E->
getType()),
1121 if (ElemIndex == 0 || !LoadZero)
1122 return this->emitGetLocal(classifyPrim(
E->
getType()), Offset,
E);
1123 return this->visitZeroInitializer(classifyPrim(
E->
getType()),
E->
getType(),
1128 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1130 if (!this->DiscardResult) {
1131 if (!this->emitGetLocal(
PT_Ptr, ResultOffset,
E))
1138 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1141 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1144 if (!this->emitAddf(getRoundingMode(
E),
E))
1147 if (!this->emitAdd(ResultElemT,
E))
1152 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1155 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1158 if (!this->emitSubf(getRoundingMode(
E),
E))
1161 if (!this->emitSub(ResultElemT,
E))
1166 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1169 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1173 if (!this->emitMulf(getRoundingMode(
E),
E))
1176 if (!this->emitMul(ResultElemT,
E))
1181 assert(!RHSIsComplex);
1182 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1185 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1189 if (!this->emitDivf(getRoundingMode(
E),
E))
1192 if (!this->emitDiv(ResultElemT,
E))
1201 if (!this->DiscardResult) {
1203 if (!this->emitInitElemPop(ResultElemT, ElemIndex,
E))
1206 if (!this->emitPop(ResultElemT,
E))
1213template <
class Emitter>
1218 if (std::optional<PrimType>
T = classify(QT))
1219 return this->visitZeroInitializer(*
T, QT,
E);
1233 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1234 CXXRD && CXXRD->getNumVBases() > 0) {
1239 const Record *R = getRecord(QT);
1243 assert(Initializing);
1244 return this->visitZeroRecordInitializer(R,
E);
1253 const auto *CAT = cast<ConstantArrayType>(AT);
1254 size_t NumElems = CAT->getZExtSize();
1255 PrimType ElemT = classifyPrim(CAT->getElementType());
1257 for (
size_t I = 0; I != NumElems; ++I) {
1258 if (!this->visitZeroInitializer(ElemT, CAT->getElementType(),
E))
1260 if (!this->emitInitElem(ElemT, I,
E))
1268 assert(Initializing);
1269 QualType ElemQT = ComplexTy->getElementType();
1270 PrimType ElemT = classifyPrim(ElemQT);
1271 for (
unsigned I = 0; I < 2; ++I) {
1272 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1274 if (!this->emitInitElem(ElemT, I,
E))
1281 unsigned NumVecElements = VecT->getNumElements();
1282 QualType ElemQT = VecT->getElementType();
1283 PrimType ElemT = classifyPrim(ElemQT);
1285 for (
unsigned I = 0; I < NumVecElements; ++I) {
1286 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1288 if (!this->emitInitElem(ElemT, I,
E))
1297template <
class Emitter>
1299 const Expr *LHS =
E->getLHS();
1300 const Expr *RHS =
E->getRHS();
1301 const Expr *Index =
E->getIdx();
1304 return this->discard(LHS) && this->discard(RHS);
1309 for (
const Expr *SubExpr : {LHS, RHS}) {
1310 if (!this->visit(SubExpr))
1317 PrimType IndexT = classifyPrim(Index->getType());
1320 if (!this->emitFlip(
PT_Ptr, IndexT,
E))
1324 return this->emitArrayElemPtrPop(IndexT,
E);
1327template <
class Emitter>
1329 const Expr *ArrayFiller,
const Expr *
E) {
1334 QT = AT->getValueType();
1337 return this->emitInvalid(
E);
1340 if (DiscardResult) {
1342 if (!this->discard(
Init))
1349 if (std::optional<PrimType>
T = classify(QT)) {
1350 assert(!DiscardResult);
1351 if (Inits.size() == 0)
1352 return this->visitZeroInitializer(*
T, QT,
E);
1353 assert(Inits.size() == 1);
1354 return this->delegate(Inits[0]);
1358 const Record *R = getRecord(QT);
1360 if (Inits.size() == 1 &&
E->
getType() == Inits[0]->getType())
1361 return this->delegate(Inits[0]);
1363 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
1366 if (!this->visit(
Init))
1369 if (FieldToInit->isBitField())
1370 return this->emitInitBitField(
T, FieldToInit,
E);
1371 return this->emitInitField(
T, FieldToInit->Offset,
E);
1374 auto initCompositeField = [=](
const Record::Field *FieldToInit,
1380 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
1382 if (!this->visitInitializer(
Init))
1384 return this->emitPopPtr(
E);
1388 if (Inits.size() == 0) {
1389 if (!this->visitZeroRecordInitializer(R,
E))
1394 if (
const auto *ILE = dyn_cast<InitListExpr>(
E))
1395 FToInit = ILE->getInitializedFieldInUnion();
1397 FToInit = cast<CXXParenListInitExpr>(
E)->getInitializedFieldInUnion();
1399 const Record::Field *FieldToInit = R->
getField(FToInit);
1400 if (std::optional<PrimType>
T = classify(
Init)) {
1401 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1404 if (!initCompositeField(FieldToInit,
Init))
1408 return this->emitFinishInit(
E);
1412 unsigned InitIndex = 0;
1415 while (InitIndex < R->getNumFields() &&
1419 if (std::optional<PrimType>
T = classify(
Init)) {
1420 const Record::Field *FieldToInit = R->
getField(InitIndex);
1421 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1426 if (
const Record::Base *B = R->
getBase(
Init->getType())) {
1427 if (!this->emitGetPtrBase(B->Offset,
Init))
1430 if (!this->visitInitializer(
Init))
1433 if (!this->emitFinishInitPop(
E))
1438 const Record::Field *FieldToInit = R->
getField(InitIndex);
1439 if (!initCompositeField(FieldToInit,
Init))
1445 return this->emitFinishInit(
E);
1449 if (Inits.size() == 1 && QT == Inits[0]->getType())
1450 return this->delegate(Inits[0]);
1452 unsigned ElementIndex = 0;
1454 if (
const auto *EmbedS =
1455 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1458 auto Eval = [&](
const Expr *
Init,
unsigned ElemIndex) {
1460 if (!this->visit(
Init))
1462 if (InitT != TargetT) {
1463 if (!this->emitCast(InitT, TargetT,
E))
1466 return this->emitInitElem(TargetT, ElemIndex,
Init);
1468 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
1471 if (!this->visitArrayElemInit(ElementIndex,
Init))
1481 Ctx.getASTContext().getAsConstantArrayType(QT);
1484 for (; ElementIndex != NumElems; ++ElementIndex) {
1485 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller))
1490 return this->emitFinishInit(
E);
1494 unsigned NumInits = Inits.size();
1497 return this->delegate(Inits[0]);
1499 QualType ElemQT = ComplexTy->getElementType();
1500 PrimType ElemT = classifyPrim(ElemQT);
1501 if (NumInits == 0) {
1503 for (
unsigned I = 0; I < 2; ++I) {
1504 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1506 if (!this->emitInitElem(ElemT, I,
E))
1509 }
else if (NumInits == 2) {
1510 unsigned InitIndex = 0;
1512 if (!this->visit(
Init))
1515 if (!this->emitInitElem(ElemT, InitIndex,
E))
1524 unsigned NumVecElements = VecT->getNumElements();
1525 assert(NumVecElements >= Inits.size());
1527 QualType ElemQT = VecT->getElementType();
1528 PrimType ElemT = classifyPrim(ElemQT);
1531 unsigned InitIndex = 0;
1533 if (!this->visit(
Init))
1538 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
1539 if (!this->emitCopyArray(ElemT, 0, InitIndex,
1540 InitVecT->getNumElements(),
E))
1542 InitIndex += InitVecT->getNumElements();
1544 if (!this->emitInitElem(ElemT, InitIndex,
E))
1550 assert(InitIndex <= NumVecElements);
1553 for (; InitIndex != NumVecElements; ++InitIndex) {
1554 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1556 if (!this->emitInitElem(ElemT, InitIndex,
E))
1567template <
class Emitter>
1570 if (std::optional<PrimType>
T = classify(
Init->getType())) {
1572 if (!this->visit(
Init))
1574 return this->emitInitElem(*
T, ElemIndex,
Init);
1580 if (!this->emitConstUint32(ElemIndex,
Init))
1582 if (!this->emitArrayElemPtrUint32(
Init))
1584 if (!this->visitInitializer(
Init))
1586 return this->emitFinishInitPop(
Init);
1589template <
class Emitter>
1591 return this->visitInitList(
E->inits(),
E->getArrayFiller(),
E);
1594template <
class Emitter>
1597 return this->visitInitList(
E->getInitExprs(),
E->getArrayFiller(),
E);
1600template <
class Emitter>
1603 return this->delegate(
E->getReplacement());
1606template <
class Emitter>
1608 std::optional<PrimType>
T = classify(
E->
getType());
1609 if (
T &&
E->hasAPValueResult()) {
1616 if (this->visitAPValue(
E->getAPValueResult(), *
T,
E))
1619 return this->delegate(
E->getSubExpr());
1622template <
class Emitter>
1624 auto It =
E->begin();
1625 return this->visit(*It);
1630 bool AlignOfReturnsPreferred =
1631 ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
1639 if (
T.getQualifiers().hasUnaligned())
1645 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
1651template <
class Emitter>
1655 const ASTContext &ASTCtx = Ctx.getASTContext();
1657 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
1658 QualType ArgType =
E->getTypeOfArgument();
1672 if (Kind == UETT_SizeOf)
1681 return this->emitConst(Size.getQuantity(),
E);
1684 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
1687 if (
E->isArgumentType()) {
1688 QualType ArgType =
E->getTypeOfArgument();
1701 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
1704 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
1714 return this->emitConst(Size.getQuantity(),
E);
1717 if (Kind == UETT_VectorElements) {
1718 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>())
1719 return this->emitConst(VT->getNumElements(),
E);
1720 assert(
E->getTypeOfArgument()->isSizelessVectorType());
1721 return this->emitSizelessVectorElementSize(
E);
1724 if (Kind == UETT_VecStep) {
1725 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>()) {
1726 unsigned N = VT->getNumElements();
1733 return this->emitConst(N,
E);
1735 return this->emitConst(1,
E);
1741template <
class Emitter>
1748 return this->discard(
Base);
1752 const auto maybeLoadValue = [&]() ->
bool {
1755 if (std::optional<PrimType>
T = classify(
E))
1756 return this->emitLoadPop(*
T,
E);
1760 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
1764 if (
auto GlobalIndex =
P.getGlobal(VD))
1765 return this->emitGetPtrGlobal(*GlobalIndex,
E) && maybeLoadValue();
1769 if (!isa<FieldDecl>(
Member))
1770 return this->discard(
Base) && this->visitDeclRef(
Member,
E);
1773 if (!this->delegate(
Base))
1776 if (!this->visit(
Base))
1781 const auto *FD = cast<FieldDecl>(
Member);
1783 const Record *R = getRecord(RD);
1786 const Record::Field *F = R->
getField(FD);
1788 if (F->Decl->getType()->isReferenceType())
1789 return this->emitGetFieldPop(
PT_Ptr, F->Offset,
E) && maybeLoadValue();
1790 return this->emitGetPtrFieldPop(F->Offset,
E) && maybeLoadValue();
1793template <
class Emitter>
1799 return this->emitConst(*ArrayIndex,
E);
1802template <
class Emitter>
1804 assert(Initializing);
1805 assert(!DiscardResult);
1809 if (!this->discard(
E->getCommonExpr()))
1814 const Expr *SubExpr =
E->getSubExpr();
1815 size_t Size =
E->getArraySize().getZExtValue();
1820 for (
size_t I = 0; I != Size; ++I) {
1824 if (!this->visitArrayElemInit(I, SubExpr))
1832template <
class Emitter>
1834 const Expr *SourceExpr =
E->getSourceExpr();
1839 return this->visitInitializer(SourceExpr);
1842 if (
auto It = OpaqueExprs.find(
E); It != OpaqueExprs.end())
1843 return this->emitGetLocal(SubExprT, It->second,
E);
1845 if (!this->visit(SourceExpr))
1851 unsigned LocalIndex = allocateLocalPrimitive(
E, SubExprT,
true);
1852 if (!this->emitSetLocal(SubExprT, LocalIndex,
E))
1857 if (!DiscardResult) {
1858 if (!this->emitGetLocal(SubExprT, LocalIndex,
E))
1863 OpaqueExprs.insert({
E, LocalIndex});
1868template <
class Emitter>
1872 const Expr *TrueExpr =
E->getTrueExpr();
1873 const Expr *FalseExpr =
E->getFalseExpr();
1875 LabelTy LabelEnd = this->getLabel();
1876 LabelTy LabelFalse = this->getLabel();
1881 if (!this->jumpFalse(LabelFalse))
1884 if (!this->delegate(TrueExpr))
1886 if (!this->jump(LabelEnd))
1889 this->emitLabel(LabelFalse);
1891 if (!this->delegate(FalseExpr))
1894 this->fallthrough(LabelEnd);
1895 this->emitLabel(LabelEnd);
1900template <
class Emitter>
1905 if (!Initializing) {
1906 unsigned StringIndex =
P.createGlobalString(
E);
1907 return this->emitGetPtrGlobal(StringIndex,
E);
1912 Ctx.getASTContext().getAsConstantArrayType(
E->
getType());
1913 assert(CAT &&
"a string literal that's not a constant array?");
1918 unsigned N = std::min(ArraySize,
E->getLength());
1919 size_t CharWidth =
E->getCharByteWidth();
1921 for (
unsigned I = 0; I != N; ++I) {
1922 uint32_t CodeUnit =
E->getCodeUnit(I);
1924 if (CharWidth == 1) {
1925 this->emitConstSint8(CodeUnit,
E);
1926 this->emitInitElemSint8(I,
E);
1927 }
else if (CharWidth == 2) {
1928 this->emitConstUint16(CodeUnit,
E);
1929 this->emitInitElemUint16(I,
E);
1930 }
else if (CharWidth == 4) {
1931 this->emitConstUint32(CodeUnit,
E);
1932 this->emitInitElemUint32(I,
E);
1934 llvm_unreachable(
"unsupported character width");
1939 for (
unsigned I = N; I != ArraySize; ++I) {
1940 if (CharWidth == 1) {
1941 this->emitConstSint8(0,
E);
1942 this->emitInitElemSint8(I,
E);
1943 }
else if (CharWidth == 2) {
1944 this->emitConstUint16(0,
E);
1945 this->emitInitElemUint16(I,
E);
1946 }
else if (CharWidth == 4) {
1947 this->emitConstUint32(0,
E);
1948 this->emitInitElemUint32(I,
E);
1950 llvm_unreachable(
"unsupported character width");
1957template <
class Emitter>
1959 return this->delegate(
E->getString());
1962template <
class Emitter>
1964 auto &A = Ctx.getASTContext();
1966 A.getObjCEncodingForType(
E->getEncodedType(), Str);
1970 return this->delegate(SL);
1973template <
class Emitter>
1979 assert(!Initializing);
1981 auto &A = Ctx.getASTContext();
1982 std::string ResultStr =
E->ComputeName(A);
1985 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
1986 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
1987 ArraySizeModifier::Normal, 0);
1991 false, ArrayTy,
E->getLocation());
1993 unsigned StringIndex =
P.createGlobalString(SL);
1994 return this->emitGetPtrGlobal(StringIndex,
E);
1997template <
class Emitter>
2001 return this->emitConst(
E->getValue(),
E);
2004template <
class Emitter>
2008 const Expr *LHS =
E->getLHS();
2009 const Expr *RHS =
E->getRHS();
2011 QualType LHSComputationType =
E->getComputationLHSType();
2012 QualType ResultType =
E->getComputationResultType();
2013 std::optional<PrimType>
LT = classify(LHSComputationType);
2014 std::optional<PrimType> RT = classify(ResultType);
2021 PrimType LHST = classifyPrim(LHSType);
2029 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2030 if (!this->emitSetLocal(*RT, TempOffset,
E))
2036 if (!this->emitLoad(LHST,
E))
2040 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
2041 LHSComputationType,
E))
2045 if (!this->emitGetLocal(*RT, TempOffset,
E))
2048 llvm::RoundingMode RM = getRoundingMode(
E);
2049 switch (
E->getOpcode()) {
2051 if (!this->emitAddf(RM,
E))
2055 if (!this->emitSubf(RM,
E))
2059 if (!this->emitMulf(RM,
E))
2063 if (!this->emitDivf(RM,
E))
2070 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->
getType(),
E))
2074 return this->emitStorePop(LHST,
E);
2075 return this->emitStore(LHST,
E);
2078template <
class Emitter>
2082 const Expr *LHS =
E->getLHS();
2083 const Expr *RHS =
E->getRHS();
2084 std::optional<PrimType>
LT = classify(LHS->
getType());
2085 std::optional<PrimType> RT = classify(RHS->
getType());
2087 if (Op != BO_AddAssign && Op != BO_SubAssign)
2096 if (!this->emitLoad(*
LT, LHS))
2102 if (Op == BO_AddAssign) {
2103 if (!this->emitAddOffset(*RT,
E))
2106 if (!this->emitSubOffset(*RT,
E))
2111 return this->emitStorePopPtr(
E);
2112 return this->emitStorePtr(
E);
2115template <
class Emitter>
2119 const Expr *LHS =
E->getLHS();
2120 const Expr *RHS =
E->getRHS();
2121 std::optional<PrimType> LHSComputationT =
2122 classify(
E->getComputationLHSType());
2123 std::optional<PrimType>
LT = classify(LHS->
getType());
2124 std::optional<PrimType> RT = classify(RHS->
getType());
2125 std::optional<PrimType> ResultT = classify(
E->
getType());
2127 if (!Ctx.getLangOpts().CPlusPlus14)
2128 return this->visit(RHS) && this->visit(LHS) && this->emitError(
E);
2130 if (!
LT || !RT || !ResultT || !LHSComputationT)
2137 return VisitFloatCompoundAssignOperator(
E);
2140 return VisitPointerCompoundAssignOperator(
E);
2153 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2155 if (!this->emitSetLocal(*RT, TempOffset,
E))
2162 if (!this->emitLoad(*
LT,
E))
2164 if (
LT != LHSComputationT) {
2165 if (!this->emitCast(*
LT, *LHSComputationT,
E))
2170 if (!this->emitGetLocal(*RT, TempOffset,
E))
2174 switch (
E->getOpcode()) {
2176 if (!this->emitAdd(*LHSComputationT,
E))
2180 if (!this->emitSub(*LHSComputationT,
E))
2184 if (!this->emitMul(*LHSComputationT,
E))
2188 if (!this->emitDiv(*LHSComputationT,
E))
2192 if (!this->emitRem(*LHSComputationT,
E))
2196 if (!this->emitShl(*LHSComputationT, *RT,
E))
2200 if (!this->emitShr(*LHSComputationT, *RT,
E))
2204 if (!this->emitBitAnd(*LHSComputationT,
E))
2208 if (!this->emitBitXor(*LHSComputationT,
E))
2212 if (!this->emitBitOr(*LHSComputationT,
E))
2216 llvm_unreachable(
"Unimplemented compound assign operator");
2220 if (ResultT != LHSComputationT) {
2221 if (!this->emitCast(*LHSComputationT, *ResultT,
E))
2226 if (DiscardResult) {
2228 return this->emitStoreBitFieldPop(*ResultT,
E);
2229 return this->emitStorePop(*ResultT,
E);
2232 return this->emitStoreBitField(*ResultT,
E);
2233 return this->emitStore(*ResultT,
E);
2236template <
class Emitter>
2239 const Expr *SubExpr =
E->getSubExpr();
2241 assert(
E->getNumObjects() == 0 &&
"TODO: Implement cleanups");
2246template <
class Emitter>
2249 const Expr *SubExpr =
E->getSubExpr();
2253 return this->delegate(SubExpr);
2258 return this->discard(SubExpr);
2262 std::optional<PrimType> SubExprT = classify(SubExpr);
2265 std::optional<unsigned> GlobalIndex =
P.createGlobal(
E);
2270 E->getLifetimeExtendedTemporaryDecl();
2275 if (!this->visit(SubExpr))
2278 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl,
E))
2281 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex,
E))
2284 return this->emitGetPtrGlobal(*GlobalIndex,
E);
2288 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2290 if (!this->visitInitializer(SubExpr))
2293 return this->emitInitGlobalTempComp(TempDecl,
E);
2299 unsigned LocalIndex = allocateLocalPrimitive(
2300 SubExpr, *SubExprT,
true,
true);
2301 if (!this->visit(SubExpr))
2303 if (!this->emitSetLocal(*SubExprT, LocalIndex,
E))
2305 return this->emitGetPtrLocal(LocalIndex,
E);
2308 if (std::optional<unsigned> LocalIndex =
2309 allocateLocal(Inner,
E->getExtendingDecl())) {
2311 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2313 return this->visitInitializer(SubExpr);
2319template <
class Emitter>
2322 return this->delegate(
E->getSubExpr());
2325template <
class Emitter>
2330 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2333 std::optional<PrimType>
T = classify(
E->
getType());
2334 if (
E->isFileScope()) {
2337 return this->delegate(
Init);
2339 if (std::optional<unsigned> GlobalIndex =
P.createGlobal(
E)) {
2340 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2344 if (!this->visit(
Init))
2346 return this->emitInitGlobal(*
T, *GlobalIndex,
E);
2349 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2358 return this->delegate(
Init);
2360 unsigned LocalIndex;
2363 LocalIndex = this->allocateLocalPrimitive(
Init, *
T,
false,
false);
2364 else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(
Init))
2365 LocalIndex = *MaybeIndex;
2369 if (!this->emitGetPtrLocal(LocalIndex,
E))
2373 if (!this->visit(
Init)) {
2376 return this->emitInit(*
T,
E);
2378 if (!this->visitInitializer(
Init) || !this->emitFinishInit(
E))
2383 return this->emitPopPtr(
E);
2390template <
class Emitter>
2395 return this->emitConstBool(
E->getValue(),
E);
2396 return this->emitConst(
E->getValue(),
E);
2399template <
class Emitter>
2403 return this->emitConst(
E->getValue(),
E);
2406template <
class Emitter>
2411 assert(Initializing);
2412 const Record *R =
P.getOrCreateRecord(
E->getLambdaClass());
2414 auto *CaptureInitIt =
E->capture_init_begin();
2417 for (
const Record::Field &F : R->
fields()) {
2424 if (std::optional<PrimType>
T = classify(
Init)) {
2425 if (!this->visit(
Init))
2428 if (!this->emitInitField(*
T, F.Offset,
E))
2431 if (!this->emitGetPtrField(F.Offset,
E))
2434 if (!this->visitInitializer(
Init))
2437 if (!this->emitPopPtr(
E))
2445template <
class Emitter>
2450 return this->delegate(
E->getFunctionName());
2453template <
class Emitter>
2455 if (
E->getSubExpr() && !this->discard(
E->getSubExpr()))
2458 return this->emitInvalid(
E);
2461template <
class Emitter>
2464 const Expr *SubExpr =
E->getSubExpr();
2466 bool TypesMatch = classify(
E) == classify(SubExpr);
2467 if (!this->emitInvalidCast(CastKind::Reinterpret, !TypesMatch,
E))
2470 return this->delegate(SubExpr);
2473template <
class Emitter>
2479 return this->emitConstBool(
E->getValue(),
E);
2482template <
class Emitter>
2485 assert(!classify(
T));
2495 return this->visitInitializer(
E->getArg(0));
2499 if (DiscardResult) {
2502 assert(!Initializing);
2503 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2508 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2513 if (
E->requiresZeroInitialization()) {
2516 if (!this->visitZeroRecordInitializer(R,
E))
2529 assert(
Func->hasThisPointer());
2530 assert(!
Func->hasRVO());
2534 if (!this->emitDupPtr(
E))
2538 for (
const auto *Arg :
E->arguments()) {
2539 if (!this->visit(Arg))
2543 if (
Func->isVariadic()) {
2544 uint32_t VarArgSize = 0;
2545 unsigned NumParams =
Func->getNumWrittenParams();
2546 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I) {
2550 if (!this->emitCallVar(
Func, VarArgSize,
E))
2553 if (!this->emitCall(
Func, 0,
E))
2558 return this->emitPopPtr(
E);
2564 Ctx.getASTContext().getAsConstantArrayType(
E->
getType());
2575 for (
size_t I = 0; I != NumElems; ++I) {
2576 if (!this->emitConstUint64(I,
E))
2578 if (!this->emitArrayElemPtrUint64(
E))
2582 for (
const auto *Arg :
E->arguments()) {
2583 if (!this->visit(Arg))
2587 if (!this->emitCall(
Func, 0,
E))
2596template <
class Emitter>
2602 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
2606 assert(Val.
isInt());
2608 return this->emitConst(I,
E);
2615 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
2616 return this->visit(LValueExpr);
2625 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
2627 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(UGCD);
2631 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2635 const APValue &
V = UGCD->getValue();
2636 for (
unsigned I = 0, N = R->
getNumFields(); I != N; ++I) {
2637 const Record::Field *F = R->
getField(I);
2638 const APValue &FieldValue =
V.getStructField(I);
2640 PrimType FieldT = classifyPrim(F->Decl->getType());
2642 if (!this->visitAPValue(FieldValue, FieldT,
E))
2644 if (!this->emitInitField(FieldT, F->Offset,
E))
2652template <
class Emitter>
2654 unsigned N =
E->getNumComponents();
2658 for (
unsigned I = 0; I != N; ++I) {
2661 const Expr *ArrayIndexExpr =
E->getIndexExpr(
Node.getArrayExprIndex());
2664 if (DiscardResult) {
2665 if (!this->discard(ArrayIndexExpr))
2670 if (!this->visit(ArrayIndexExpr))
2684 return this->emitOffsetOf(
T,
E,
E);
2687template <
class Emitter>
2695 if (std::optional<PrimType>
T = classify(Ty))
2696 return this->visitZeroInitializer(*
T, Ty,
E);
2699 if (!Initializing) {
2700 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2703 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2708 QualType ElemQT = CT->getElementType();
2709 PrimType ElemT = classifyPrim(ElemQT);
2711 for (
unsigned I = 0; I != 2; ++I) {
2712 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
2714 if (!this->emitInitElem(ElemT, I,
E))
2722 if (!Initializing) {
2723 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2726 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2731 QualType ElemQT = VT->getElementType();
2732 PrimType ElemT = classifyPrim(ElemQT);
2734 for (
unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
2735 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
2737 if (!this->emitInitElem(ElemT, I,
E))
2746template <
class Emitter>
2748 return this->emitConst(
E->getPackLength(),
E);
2751template <
class Emitter>
2754 return this->delegate(
E->getResultExpr());
2757template <
class Emitter>
2759 return this->delegate(
E->getChosenSubExpr());
2762template <
class Emitter>
2767 return this->emitConst(
E->getValue(),
E);
2770template <
class Emitter>
2775 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
2776 const Function *F = this->getFunction(Ctor);
2793 if (!this->emitGetParam(PT, Offset,
E))
2798 return this->emitCall(F, 0,
E);
2801template <
class Emitter>
2805 QualType ElementType =
E->getAllocatedType();
2806 std::optional<PrimType> ElemT = classify(ElementType);
2807 unsigned PlacementArgs =
E->getNumPlacementArgs();
2808 bool IsNoThrow =
false;
2811 if (PlacementArgs != 0) {
2823 return this->emitInvalid(
E);
2825 if (!this->discard(
E->getPlacementArg(0)))
2839 Desc =
P.createDescriptor(
2842 false,
false,
false,
Init);
2846 std::optional<const Expr *> ArraySizeExpr =
E->getArraySize();
2850 const Expr *Stripped = *ArraySizeExpr;
2851 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
2852 Stripped = ICE->getSubExpr())
2853 if (ICE->getCastKind() != CK_NoOp &&
2854 ICE->getCastKind() != CK_IntegralCast)
2859 if (!this->visit(Stripped))
2864 if (!this->emitAllocN(SizeT, *ElemT,
E, IsNoThrow,
E))
2868 if (!this->emitAllocCN(SizeT, Desc, IsNoThrow,
E))
2872 if (
Init && !this->visitInitializer(
Init))
2877 if (!this->emitAlloc(Desc,
E))
2882 if (!this->visit(
Init))
2885 if (!this->emitInit(*ElemT,
E))
2889 if (!this->visitInitializer(
Init))
2896 return this->emitPopPtr(
E);
2901template <
class Emitter>
2903 const Expr *Arg =
E->getArgument();
2906 if (!this->visit(Arg))
2909 return this->emitFree(
E->isArrayForm(),
E);
2912template <
class Emitter>
2914 assert(Ctx.getLangOpts().CPlusPlus);
2915 return this->emitConstBool(
E->getValue(),
E);
2918template <
class Emitter>
2922 assert(!Initializing);
2930 if (std::optional<unsigned> I =
P.getOrCreateDummy(GuidDecl))
2931 return this->emitGetPtrGlobal(*I,
E);
2935 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(GuidDecl);
2938 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2941 assert(this->getRecord(
E->
getType()));
2947 assert(
V.isStruct());
2948 assert(
V.getStructNumBases() == 0);
2949 if (!this->visitAPValueInitializer(
V,
E))
2952 return this->emitFinishInit(
E);
2955template <
class Emitter>
2960 return this->emitConstBool(
E->isSatisfied(),
E);
2963template <
class Emitter>
2969 return this->emitConstBool(
E->isSatisfied(),
E);
2972template <
class Emitter>
2975 return this->delegate(
E->getSemanticForm());
2978template <
class Emitter>
2981 for (
const Expr *SemE :
E->semantics()) {
2982 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
2983 if (SemE ==
E->getResultExpr())
2986 if (OVE->isUnique())
2989 if (!this->discard(OVE))
2991 }
else if (SemE ==
E->getResultExpr()) {
2992 if (!this->delegate(SemE))
2995 if (!this->discard(SemE))
3002template <
class Emitter>
3004 return this->delegate(
E->getSelectedExpr());
3007template <
class Emitter>
3009 return this->emitError(
E);
3012template <
class Emitter>
3016 unsigned Offset = allocateLocalPrimitive(
3017 E->getLabel(),
PT_Ptr,
true,
false);
3019 return this->emitGetLocal(
PT_Ptr, Offset,
E);
3022template <
class Emitter>
3024 assert(Initializing);
3026 QualType ElemType = VT->getElementType();
3027 PrimType ElemT = classifyPrim(ElemType);
3028 const Expr *Src =
E->getSrcExpr();
3032 unsigned SrcOffset = this->allocateLocalPrimitive(Src,
PT_Ptr,
true,
false);
3033 if (!this->visit(Src))
3035 if (!this->emitSetLocal(
PT_Ptr, SrcOffset,
E))
3038 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
3039 if (!this->emitGetLocal(
PT_Ptr, SrcOffset,
E))
3041 if (!this->emitArrayElemPop(SrcElemT, I,
E))
3043 if (SrcElemT != ElemT) {
3044 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType,
E))
3047 if (!this->emitInitElem(ElemT, I,
E))
3054template <
class Emitter>
3056 assert(Initializing);
3057 assert(
E->getNumSubExprs() > 2);
3059 const Expr *Vecs[] = {
E->getExpr(0),
E->getExpr(1)};
3063 unsigned NumOutputElems =
E->getNumSubExprs() - 2;
3064 assert(NumOutputElems > 0);
3067 unsigned VectorOffsets[2];
3068 for (
unsigned I = 0; I != 2; ++I) {
3069 VectorOffsets[I] = this->allocateLocalPrimitive(
3070 Vecs[I],
PT_Ptr,
true,
false);
3071 if (!this->visit(Vecs[I]))
3073 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I],
E))
3076 for (
unsigned I = 0; I != NumOutputElems; ++I) {
3077 APSInt ShuffleIndex =
E->getShuffleMaskIdx(Ctx.getASTContext(), I);
3078 if (ShuffleIndex == -1)
3079 return this->emitInvalid(
E);
3081 assert(ShuffleIndex < (NumInputElems * 2));
3082 if (!this->emitGetLocal(
PT_Ptr,
3083 VectorOffsets[ShuffleIndex >= NumInputElems],
E))
3085 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
3086 if (!this->emitArrayElemPop(ElemT, InputVectorIndex,
E))
3089 if (!this->emitInitElem(ElemT, I,
E))
3096template <
class Emitter>
3101 Base->getType()->isVectorType() ||
3105 E->getEncodedElementAccess(Indices);
3107 if (Indices.size() == 1) {
3108 if (!this->visit(
Base))
3112 if (!this->emitConstUint32(Indices[0],
E))
3114 return this->emitArrayElemPtrPop(
PT_Uint32,
E);
3117 return this->emitArrayElemPop(classifyPrim(
E->
getType()), Indices[0],
E);
3121 unsigned BaseOffset = allocateLocalPrimitive(
Base,
PT_Ptr,
true,
3123 if (!this->visit(
Base))
3125 if (!this->emitSetLocal(
PT_Ptr, BaseOffset,
E))
3129 if (!Initializing) {
3130 std::optional<unsigned> ResultIndex;
3131 ResultIndex = allocateLocal(
E);
3134 if (!this->emitGetPtrLocal(*ResultIndex,
E))
3142 uint32_t DstIndex = 0;
3143 for (uint32_t I : Indices) {
3144 if (!this->emitGetLocal(
PT_Ptr, BaseOffset,
E))
3146 if (!this->emitArrayElemPop(ElemT, I,
E))
3148 if (!this->emitInitElem(ElemT, DstIndex,
E))
3154 assert(!DiscardResult);
3158template <
class Emitter>
3160 const Expr *SubExpr =
E->getSubExpr();
3161 if (!
E->isExpressibleAsConstantInitializer())
3162 return this->discard(SubExpr) && this->emitInvalid(
E);
3164 return this->delegate(SubExpr);
3167template <
class Emitter>
3170 const Expr *SubExpr =
E->getSubExpr();
3172 Ctx.getASTContext().getAsConstantArrayType(SubExpr->
getType());
3174 assert(Initializing);
3177 if (!this->visit(SubExpr))
3189 assert(SecondFieldT ==
PT_Ptr);
3195 if (!this->emitArrayElemPtrPop(
PT_Uint64,
E))
3200template <
class Emitter>
3209 if (!this->visitStmt(S))
3214 assert(S == Result);
3215 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
3216 return this->delegate(ResultExpr);
3217 return this->emitUnsupported(
E);
3226 return this->Visit(
E);
3231 return this->emitError(
E);
3236 return this->Visit(
E);
3244 return this->discard(
E);
3249 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3253 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3255 return this->visitInitializer(
E);
3262 return this->Visit(
E);
3265template <
class Emitter>
3270 return this->emitError(
E);
3272 if (!this->checkLiteralType(
E))
3277 return this->Visit(
E);
3281 std::optional<PrimType>
T = classify(
E->
getType());
3285 if (!this->visit(
E))
3287 return this->emitComplexBoolCast(
E);
3292 if (!this->visit(
E))
3300 if (!this->emitNull(*
T,
nullptr,
E))
3302 return this->emitNE(*
T,
E);
3307 return this->emitCastFloatingIntegralBool(
E);
3313template <
class Emitter>
3318 return this->emitZeroBool(
E);
3320 return this->emitZeroSint8(
E);
3322 return this->emitZeroUint8(
E);
3324 return this->emitZeroSint16(
E);
3326 return this->emitZeroUint16(
E);
3328 return this->emitZeroSint32(
E);
3330 return this->emitZeroUint32(
E);
3332 return this->emitZeroSint64(
E);
3334 return this->emitZeroUint64(
E);
3336 return this->emitZeroIntAP(Ctx.getBitWidth(QT),
E);
3338 return this->emitZeroIntAPS(Ctx.getBitWidth(QT),
E);
3340 return this->emitNullPtr(
nullptr,
E);
3342 return this->emitNullFnPtr(
nullptr,
E);
3344 return this->emitNullMemberPtr(
nullptr,
E);
3346 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)),
E);
3349 llvm_unreachable(
"unknown primitive type");
3352template <
class Emitter>
3358 for (
const Record::Field &Field : R->
fields()) {
3359 if (
Field.Decl->isUnnamedBitField())
3363 if (
D->isPrimitive()) {
3366 if (!this->visitZeroInitializer(
T, QT,
E))
3368 if (!this->emitInitField(
T,
Field.Offset,
E))
3375 if (!this->emitGetPtrField(
Field.Offset,
E))
3378 if (
D->isPrimitiveArray()) {
3381 for (uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
3382 if (!this->visitZeroInitializer(
T, ET,
E))
3384 if (!this->emitInitElem(
T, I,
E))
3387 }
else if (
D->isCompositeArray()) {
3388 const Record *ElemRecord =
D->ElemDesc->ElemRecord;
3389 assert(
D->ElemDesc->ElemRecord);
3390 for (uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
3391 if (!this->emitConstUint32(I,
E))
3395 if (!this->visitZeroRecordInitializer(ElemRecord,
E))
3397 if (!this->emitPopPtr(
E))
3400 }
else if (
D->isRecord()) {
3401 if (!this->visitZeroRecordInitializer(
D->ElemRecord,
E))
3407 if (!this->emitFinishInitPop(
E))
3414 for (
const Record::Base &B : R->
bases()) {
3415 if (!this->emitGetPtrBase(B.Offset,
E))
3417 if (!this->visitZeroRecordInitializer(B.R,
E))
3419 if (!this->emitFinishInitPop(
E))
3428template <
class Emitter>
3429template <
typename T>
3433 return this->emitConstSint8(
Value,
E);
3435 return this->emitConstUint8(
Value,
E);
3437 return this->emitConstSint16(
Value,
E);
3439 return this->emitConstUint16(
Value,
E);
3441 return this->emitConstSint32(
Value,
E);
3443 return this->emitConstUint32(
Value,
E);
3445 return this->emitConstSint64(
Value,
E);
3447 return this->emitConstUint64(
Value,
E);
3449 return this->emitConstBool(
Value,
E);
3456 llvm_unreachable(
"Invalid integral type");
3459 llvm_unreachable(
"unknown primitive type");
3462template <
class Emitter>
3463template <
typename T>
3468template <
class Emitter>
3472 return this->emitConstIntAPS(
Value,
E);
3474 return this->emitConstIntAP(
Value,
E);
3476 if (
Value.isSigned())
3477 return this->emitConst(
Value.getSExtValue(), Ty,
E);
3478 return this->emitConst(
Value.getZExtValue(), Ty,
E);
3481template <
class Emitter>
3486template <
class Emitter>
3491 if (
const auto *VD =
3492 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
3493 assert(!
P.getGlobal(VD));
3494 assert(!Locals.contains(VD));
3502 Src.is<
const Expr *>());
3504 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
3505 Locals.insert({VD, Local});
3506 VarScope->add(Local, IsExtended);
3507 return Local.Offset;
3510template <
class Emitter>
3511std::optional<unsigned>
3514 if ([[maybe_unused]]
const auto *VD =
3515 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
3516 assert(!
P.getGlobal(VD));
3517 assert(!Locals.contains(VD));
3523 bool IsTemporary =
false;
3524 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
3528 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
3529 Init = VarD->getInit();
3531 if (
auto *
E = Src.dyn_cast<
const Expr *>()) {
3538 IsTemporary,
false,
Init);
3540 return std::nullopt;
3544 Locals.insert({Key, Local});
3546 VarScope->addExtended(Local, ExtendingDecl);
3548 VarScope->add(Local,
false);
3549 return Local.Offset;
3552template <
class Emitter>
3554 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
3560 if (
const auto *RecordTy = getRecordTy(Ty))
3561 return getRecord(RecordTy->getDecl());
3565template <
class Emitter>
3567 return P.getOrCreateRecord(RD);
3570template <
class Emitter>
3572 return Ctx.getOrCreateFunction(FD);
3585 if (std::optional<PrimType>
T = classify(
E)) {
3594 if (std::optional<unsigned> LocalOffset = this->allocateLocal(
E)) {
3595 if (!this->emitGetPtrLocal(*LocalOffset,
E))
3598 if (!visitInitializer(
E))
3601 if (!this->emitFinishInit(
E))
3613template <
class Emitter>
3616 auto R = this->visitVarDecl(VD,
true);
3625 if (
auto GlobalIndex =
P.getGlobal(VD)) {
3626 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
3630 GD.
InitState = GlobalInitState::InitializerFailed;
3641template <
class Emitter>
3643 bool ConstantContext) {
3644 std::optional<PrimType> VarT = classify(VD->
getType());
3648 if (!ConstantContext) {
3656 if (!this->visitVarDecl(VD,
true))
3660 auto GlobalIndex =
P.getGlobal(VD);
3661 assert(GlobalIndex);
3663 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
3666 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
3670 auto Local = Locals.find(VD);
3671 assert(Local != Locals.end());
3673 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
3676 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
3682 if (!this->emitRet(VarT.value_or(
PT_Ptr), VD)) {
3686 auto GlobalIndex =
P.getGlobal(VD);
3687 assert(GlobalIndex);
3688 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
3692 GD.
InitState = GlobalInitState::InitializerFailed;
3701template <
class Emitter>
3709 if (!this->isActive())
3713 std::optional<PrimType> VarT = classify(VD->
getType());
3715 if (
Init &&
Init->isValueDependent())
3719 auto checkDecl = [&]() ->
bool {
3721 return !NeedsOp || this->emitCheckDecl(VD, VD);
3724 auto initGlobal = [&](
unsigned GlobalIndex) ->
bool {
3729 if (!this->visit(
Init))
3730 return checkDecl() &&
false;
3732 return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
3738 if (!this->emitGetPtrGlobal(GlobalIndex,
Init))
3741 if (!visitInitializer(
Init))
3744 if (!this->emitFinishInit(
Init))
3747 return this->emitPopPtr(
Init);
3751 if (std::optional<unsigned> GlobalIndex =
P.getGlobal(VD)) {
3752 if (
P.getPtrGlobal(*GlobalIndex).isInitialized())
3757 return Init && checkDecl() && initGlobal(*GlobalIndex);
3760 std::optional<unsigned> GlobalIndex =
P.createGlobal(VD,
Init);
3765 return !
Init || (checkDecl() && initGlobal(*GlobalIndex));
3770 unsigned Offset = this->allocateLocalPrimitive(
3777 if (!this->visit(
Init))
3779 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
3781 if (!this->visit(
Init))
3783 return this->emitSetLocal(*VarT, Offset, VD);
3787 if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
3791 if (!this->emitGetPtrLocal(*Offset,
Init))
3794 if (!visitInitializer(
Init))
3797 if (!this->emitFinishInit(
Init))
3800 return this->emitPopPtr(
Init);
3810template <
class Emitter>
3813 assert(!DiscardResult);
3815 return this->emitConst(Val.
getInt(), ValType,
E);
3817 return this->emitConstFloat(Val.
getFloat(),
E);
3821 return this->emitNull(ValType,
nullptr,
E);
3823 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
3824 return this->visit(BaseExpr);
3825 else if (
const auto *VD =
Base.dyn_cast<
const ValueDecl *>()) {
3826 return this->visitDeclRef(VD,
E);
3830 return this->emitGetMemberPtr(MemberDecl,
E);
3831 return this->emitNullMemberPtr(
nullptr,
E);
3837template <
class Emitter>
3846 const Record::Field *RF = R->
getField(I);
3849 PrimType T = classifyPrim(RF->Decl->getType());
3850 if (!this->visitAPValue(F,
T,
E))
3852 if (!this->emitInitField(
T, RF->Offset,
E))
3855 assert(RF->Desc->isPrimitiveArray());
3856 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
3857 PrimType ElemT = classifyPrim(ArrType->getElementType());
3860 if (!this->emitGetPtrField(RF->Offset,
E))
3863 for (
unsigned A = 0, AN = F.
getArraySize(); A != AN; ++A) {
3866 if (!this->emitInitElem(ElemT, A,
E))
3870 if (!this->emitPopPtr(
E))
3873 if (!this->emitGetPtrField(RF->Offset,
E))
3875 if (!this->visitAPValueInitializer(F,
E))
3877 if (!this->emitPopPtr(
E))
3880 assert(
false &&
"I don't think this should be possible");
3889 const Record::Field *RF = R->
getField(UnionField);
3890 PrimType T = classifyPrim(RF->Decl->getType());
3891 if (!this->visitAPValue(F,
T,
E))
3893 return this->emitInitField(
T, RF->Offset,
E);
3900template <
class Emitter>
3908 unsigned Builtin =
E->getBuiltinCallee();
3909 if (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
3910 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
3911 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
3912 Builtin == Builtin::BI__builtin_function_start) {
3913 if (std::optional<unsigned> GlobalOffset =
P.createGlobal(
E)) {
3914 if (!this->emitGetPtrGlobal(*GlobalOffset,
E))
3918 return this->emitDecayPtr(
PT_Ptr, PT,
E);
3925 std::optional<PrimType> ReturnT = classify(
E);
3928 if (!Initializing && !ReturnT && !ReturnType->
isVoidType()) {
3929 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3932 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3936 if (!
Func->isUnevaluatedBuiltin()) {
3938 for (
const auto *Arg :
E->arguments()) {
3939 if (!this->visit(Arg))
3944 if (!this->emitCallBI(
Func,
E,
E))
3947 if (DiscardResult && !ReturnType->
isVoidType()) {
3949 return this->emitPop(*ReturnT,
E);
3955template <
class Emitter>
3957 if (
E->getBuiltinCallee())
3958 return VisitBuiltinCallExpr(
E);
3960 QualType ReturnType =
E->getCallReturnType(Ctx.getASTContext());
3961 std::optional<PrimType>
T = classify(ReturnType);
3966 if (DiscardResult) {
3970 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
3971 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3977 if (!Initializing) {
3978 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
3979 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3983 if (!this->emitDupPtr(
E))
3991 bool IsAssignmentOperatorCall =
false;
3992 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
3993 OCE && OCE->isAssignmentOp()) {
3997 assert(Args.size() == 2);
3998 IsAssignmentOperatorCall =
true;
3999 std::reverse(Args.begin(), Args.end());
4004 if (isa<CXXOperatorCallExpr>(
E)) {
4005 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
4006 MD && MD->isStatic()) {
4007 if (!this->discard(
E->getArg(0)))
4010 Args.erase(Args.begin());
4014 std::optional<unsigned> CalleeOffset;
4016 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(
E)) {
4017 if (!FuncDecl && classifyPrim(
E->getCallee()) ==
PT_MemberPtr) {
4021 const Expr *Callee =
E->getCallee();
4023 this->allocateLocalPrimitive(Callee,
PT_MemberPtr,
true,
false);
4024 if (!this->visit(Callee))
4030 if (!this->emitGetMemberPtrBase(
E))
4032 }
else if (!this->visit(MC->getImplicitObjectArgument())) {
4035 }
else if (!FuncDecl) {
4036 const Expr *Callee =
E->getCallee();
4037 CalleeOffset = this->allocateLocalPrimitive(Callee,
PT_FnPtr,
true,
false);
4038 if (!this->visit(Callee))
4040 if (!this->emitSetLocal(
PT_FnPtr, *CalleeOffset,
E))
4046 unsigned ArgIndex = 0;
4047 for (
const auto *Arg : Args) {
4048 if (!this->visit(Arg))
4052 if (FuncDecl && NonNullArgs[ArgIndex]) {
4055 if (!this->emitCheckNonNullArg(ArgT, Arg))
4063 if (IsAssignmentOperatorCall) {
4064 assert(Args.size() == 2);
4067 if (!this->emitFlip(Arg2T, Arg1T,
E))
4075 assert(HasRVO ==
Func->hasRVO());
4077 bool HasQualifier =
false;
4078 if (
const auto *ME = dyn_cast<MemberExpr>(
E->getCallee()))
4079 HasQualifier = ME->hasQualifier();
4081 bool IsVirtual =
false;
4082 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
4083 IsVirtual = MD->isVirtual();
4088 if (IsVirtual && !HasQualifier) {
4089 uint32_t VarArgSize = 0;
4090 unsigned NumParams =
4091 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4092 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4095 if (!this->emitCallVirt(
Func, VarArgSize,
E))
4097 }
else if (
Func->isVariadic()) {
4098 uint32_t VarArgSize = 0;
4099 unsigned NumParams =
4100 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4101 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4103 if (!this->emitCallVar(
Func, VarArgSize,
E))
4106 if (!this->emitCall(
Func, 0,
E))
4115 uint32_t ArgSize = 0;
4116 for (
unsigned I = 0, N =
E->getNumArgs(); I != N; ++I)
4121 if (isa<CXXMemberCallExpr>(
E) && CalleeOffset) {
4124 if (!this->emitGetMemberPtrDecl(
E))
4127 if (!this->emitGetLocal(
PT_FnPtr, *CalleeOffset,
E))
4130 if (!this->emitCallPtr(ArgSize,
E,
E))
4135 if (DiscardResult && !ReturnType->
isVoidType() &&
T)
4136 return this->emitPop(*
T,
E);
4141template <
class Emitter>
4145 return this->delegate(
E->getExpr());
4148template <
class Emitter>
4152 const Expr *SubExpr =
E->getExpr();
4153 if (std::optional<PrimType>
T = classify(
E->getExpr()))
4154 return this->visit(SubExpr);
4156 assert(Initializing);
4157 return this->visitInitializer(SubExpr);
4160template <
class Emitter>
4165 return this->emitConstBool(
E->getValue(),
E);
4168template <
class Emitter>
4174 return this->emitNullPtr(
nullptr,
E);
4177template <
class Emitter>
4185 return this->emitZero(
T,
E);
4188template <
class Emitter>
4193 if (this->LambdaThisCapture.Offset > 0) {
4194 if (this->LambdaThisCapture.IsPtr)
4195 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset,
E);
4196 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset,
E);
4203 if (!InitStackActive || !
E->isImplicit())
4204 return this->emitThis(
E);
4206 if (InitStackActive && !InitStack.empty()) {
4207 unsigned StartIndex = 0;
4208 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
4214 for (
unsigned I = StartIndex, N = InitStack.size(); I != N; ++I) {
4215 if (!InitStack[I].
template emit<Emitter>(
this,
E))
4220 return this->emitThis(
E);
4224 switch (S->getStmtClass()) {
4225 case Stmt::CompoundStmtClass:
4226 return visitCompoundStmt(cast<CompoundStmt>(S));
4227 case Stmt::DeclStmtClass:
4228 return visitDeclStmt(cast<DeclStmt>(S));
4229 case Stmt::ReturnStmtClass:
4230 return visitReturnStmt(cast<ReturnStmt>(S));
4231 case Stmt::IfStmtClass:
4232 return visitIfStmt(cast<IfStmt>(S));
4233 case Stmt::WhileStmtClass:
4234 return visitWhileStmt(cast<WhileStmt>(S));
4235 case Stmt::DoStmtClass:
4236 return visitDoStmt(cast<DoStmt>(S));
4237 case Stmt::ForStmtClass:
4238 return visitForStmt(cast<ForStmt>(S));
4239 case Stmt::CXXForRangeStmtClass:
4240 return visitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
4241 case Stmt::BreakStmtClass:
4242 return visitBreakStmt(cast<BreakStmt>(S));
4243 case Stmt::ContinueStmtClass:
4244 return visitContinueStmt(cast<ContinueStmt>(S));
4245 case Stmt::SwitchStmtClass:
4246 return visitSwitchStmt(cast<SwitchStmt>(S));
4247 case Stmt::CaseStmtClass:
4248 return visitCaseStmt(cast<CaseStmt>(S));
4249 case Stmt::DefaultStmtClass:
4250 return visitDefaultStmt(cast<DefaultStmt>(S));
4251 case Stmt::AttributedStmtClass:
4252 return visitAttributedStmt(cast<AttributedStmt>(S));
4253 case Stmt::CXXTryStmtClass:
4254 return visitCXXTryStmt(cast<CXXTryStmt>(S));
4255 case Stmt::NullStmtClass:
4258 case Stmt::GCCAsmStmtClass:
4259 case Stmt::MSAsmStmtClass:
4260 case Stmt::GotoStmtClass:
4261 return this->emitInvalid(S);
4262 case Stmt::LabelStmtClass:
4263 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
4265 if (
const auto *
E = dyn_cast<Expr>(S))
4266 return this->discard(
E);
4272template <
class Emitter>
4275 for (
const auto *InnerStmt : S->body())
4276 if (!visitStmt(InnerStmt))
4278 return Scope.destroyLocals();
4281template <
class Emitter>
4283 for (
const auto *
D : DS->
decls()) {
4288 const auto *VD = dyn_cast<VarDecl>(
D);
4291 if (!this->visitVarDecl(VD))
4298template <
class Emitter>
4300 if (this->InStmtExpr)
4301 return this->emitUnsupported(RS);
4307 if (!this->visit(RE))
4309 this->emitCleanup();
4310 return this->emitRet(*ReturnType, RS);
4311 }
else if (RE->getType()->isVoidType()) {
4312 if (!this->visit(RE))
4316 if (!this->emitRVOPtr(RE))
4318 if (!this->visitInitializer(RE))
4320 if (!this->emitPopPtr(RE))
4323 this->emitCleanup();
4324 return this->emitRetVoid(RS);
4329 this->emitCleanup();
4330 return this->emitRetVoid(RS);
4335 return visitStmt(IS->
getThen());
4339 if (
auto *CondInit = IS->
getInit())
4340 if (!visitStmt(CondInit))
4344 if (!visitDeclStmt(CondDecl))
4347 if (!this->visitBool(IS->
getCond()))
4351 LabelTy LabelElse = this->getLabel();
4352 LabelTy LabelEnd = this->getLabel();
4353 if (!this->jumpFalse(LabelElse))
4355 if (!visitStmt(IS->
getThen()))
4357 if (!this->jump(LabelEnd))
4359 this->emitLabel(LabelElse);
4360 if (!visitStmt(Else))
4362 this->emitLabel(LabelEnd);
4364 LabelTy LabelEnd = this->getLabel();
4365 if (!this->jumpFalse(LabelEnd))
4367 if (!visitStmt(IS->
getThen()))
4369 this->emitLabel(LabelEnd);
4375template <
class Emitter>
4377 const Expr *Cond = S->getCond();
4378 const Stmt *Body = S->getBody();
4380 LabelTy CondLabel = this->getLabel();
4381 LabelTy EndLabel = this->getLabel();
4384 this->fallthrough(CondLabel);
4385 this->emitLabel(CondLabel);
4387 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
4388 if (!visitDeclStmt(CondDecl))
4391 if (!this->visitBool(Cond))
4393 if (!this->jumpFalse(EndLabel))
4396 if (!this->visitStmt(Body))
4399 if (!this->jump(CondLabel))
4401 this->fallthrough(EndLabel);
4402 this->emitLabel(EndLabel);
4408 const Expr *Cond = S->getCond();
4409 const Stmt *Body = S->getBody();
4411 LabelTy StartLabel = this->getLabel();
4412 LabelTy EndLabel = this->getLabel();
4413 LabelTy CondLabel = this->getLabel();
4416 this->fallthrough(StartLabel);
4417 this->emitLabel(StartLabel);
4419 if (!this->visitStmt(Body))
4421 this->fallthrough(CondLabel);
4422 this->emitLabel(CondLabel);
4423 if (!this->visitBool(Cond))
4426 if (!this->jumpTrue(StartLabel))
4429 this->fallthrough(EndLabel);
4430 this->emitLabel(EndLabel);
4434template <
class Emitter>
4438 const Expr *Cond = S->getCond();
4439 const Expr *
Inc = S->getInc();
4440 const Stmt *Body = S->getBody();
4442 LabelTy EndLabel = this->getLabel();
4443 LabelTy CondLabel = this->getLabel();
4444 LabelTy IncLabel = this->getLabel();
4447 if (
Init && !this->visitStmt(
Init))
4450 this->fallthrough(CondLabel);
4451 this->emitLabel(CondLabel);
4453 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
4454 if (!visitDeclStmt(CondDecl))
4458 if (!this->visitBool(Cond))
4460 if (!this->jumpFalse(EndLabel))
4465 if (Body && !this->visitStmt(Body))
4468 this->fallthrough(IncLabel);
4469 this->emitLabel(IncLabel);
4470 if (
Inc && !this->discard(
Inc))
4474 if (!this->jump(CondLabel))
4476 this->fallthrough(EndLabel);
4477 this->emitLabel(EndLabel);
4481template <
class Emitter>
4484 const Expr *Cond = S->getCond();
4485 const Expr *
Inc = S->getInc();
4486 const Stmt *Body = S->getBody();
4487 const Stmt *BeginStmt = S->getBeginStmt();
4488 const Stmt *RangeStmt = S->getRangeStmt();
4489 const Stmt *EndStmt = S->getEndStmt();
4490 const VarDecl *LoopVar = S->getLoopVariable();
4492 LabelTy EndLabel = this->getLabel();
4493 LabelTy CondLabel = this->getLabel();
4494 LabelTy IncLabel = this->getLabel();
4498 if (
Init && !this->visitStmt(
Init))
4500 if (!this->visitStmt(RangeStmt))
4502 if (!this->visitStmt(BeginStmt))
4504 if (!this->visitStmt(EndStmt))
4508 this->fallthrough(CondLabel);
4509 this->emitLabel(CondLabel);
4510 if (!this->visitBool(Cond))
4512 if (!this->jumpFalse(EndLabel))
4515 if (!this->visitVarDecl(LoopVar))
4520 if (!this->visitStmt(Body))
4523 this->fallthrough(IncLabel);
4524 this->emitLabel(IncLabel);
4525 if (!this->discard(
Inc))
4529 if (!this->jump(CondLabel))
4532 this->fallthrough(EndLabel);
4533 this->emitLabel(EndLabel);
4537template <
class Emitter>
4542 this->emitCleanup();
4543 return this->jump(*BreakLabel);
4546template <
class Emitter>
4551 this->emitCleanup();
4552 return this->jump(*ContinueLabel);
4555template <
class Emitter>
4557 const Expr *Cond = S->getCond();
4560 LabelTy EndLabel = this->getLabel();
4562 unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT,
true,
false);
4564 if (
const auto *CondInit = S->getInit())
4565 if (!visitStmt(CondInit))
4568 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
4569 if (!visitDeclStmt(CondDecl))
4573 if (!this->visit(Cond))
4575 if (!this->emitSetLocal(CondT, CondVar, S))
4580 for (
const SwitchCase *SC = S->getSwitchCaseList(); SC;
4581 SC = SC->getNextSwitchCase()) {
4582 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
4584 if (CS->caseStmtIsGNURange())
4586 CaseLabels[SC] = this->getLabel();
4592 if (!this->emitGetLocal(CondT, CondVar, CS))
4594 if (!this->visit(
Value))
4598 if (!this->emitEQ(ValueT, S))
4600 if (!this->jumpTrue(CaseLabels[CS]))
4603 assert(!DefaultLabel);
4604 DefaultLabel = this->getLabel();
4611 if (!this->jump(*DefaultLabel))
4614 if (!this->jump(EndLabel))
4619 if (!this->visitStmt(S->getBody()))
4621 this->emitLabel(EndLabel);
4625template <
class Emitter>
4627 this->emitLabel(CaseLabels[S]);
4628 return this->visitStmt(S->getSubStmt());
4631template <
class Emitter>
4633 this->emitLabel(*DefaultLabel);
4634 return this->visitStmt(S->getSubStmt());
4637template <
class Emitter>
4639 if (this->Ctx.getLangOpts().CXXAssumptions &&
4640 !this->Ctx.getLangOpts().MSVCCompat) {
4641 for (
const Attr *A : S->getAttrs()) {
4642 auto *AA = dyn_cast<CXXAssumeAttr>(A);
4646 assert(isa<NullStmt>(S->getSubStmt()));
4648 const Expr *Assumption = AA->getAssumption();
4656 if (!this->visitBool(Assumption))
4659 if (!this->emitAssume(Assumption))
4665 return this->visitStmt(S->getSubStmt());
4668template <
class Emitter>
4671 return this->visitStmt(S->getTryBlock());
4674template <
class Emitter>
4678 assert(cast<CompoundStmt>(MD->
getBody())->body_empty());
4683 const Function *
Func = this->getFunction(LambdaCallOp);
4686 assert(
Func->hasThisPointer());
4689 if (
Func->hasRVO()) {
4690 if (!this->emitRVOPtr(MD))
4698 if (!this->emitNullPtr(
nullptr, MD))
4703 auto It = this->Params.find(PVD);
4704 assert(It != this->Params.end());
4708 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
4709 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
4713 if (!this->emitCall(
Func, 0, LambdaCallOp))
4716 this->emitCleanup();
4718 return this->emitRet(*ReturnType, MD);
4721 return this->emitRetVoid(MD);
4724template <
class Emitter>
4726 if (Ctx.getLangOpts().CPlusPlus23)
4735template <
class Emitter>
4740 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
4741 const Expr *InitExpr) ->
bool {
4743 if (InitExpr->getType().isNull())
4746 if (std::optional<PrimType>
T = this->classify(InitExpr)) {
4747 if (!this->visit(InitExpr))
4750 if (F->isBitField())
4751 return this->emitInitThisBitField(*
T, F, FieldOffset, InitExpr);
4752 return this->emitInitThisField(*
T, FieldOffset, InitExpr);
4757 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
4760 if (!this->visitInitializer(InitExpr))
4763 return this->emitFinishInitPop(InitExpr);
4767 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F);
4769 return this->emitLambdaStaticInvokerBody(MD);
4772 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F)) {
4774 const Record *R = this->getRecord(RD);
4778 if (R->
isUnion() && Ctor->isCopyOrMoveConstructor()) {
4780 assert(cast<CompoundStmt>(Ctor->getBody())->body_empty());
4781 if (!this->emitThis(Ctor))
4784 auto PVD = Ctor->getParamDecl(0);
4790 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
4791 this->emitRetVoid(Ctor);
4795 for (
const auto *
Init : Ctor->inits()) {
4799 const Expr *InitExpr =
Init->getInit();
4803 if (!emitFieldInitializer(F, F->Offset, InitExpr))
4806 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
4809 if (
Init->isBaseVirtual()) {
4811 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
4817 const Record::Base *B = R->
getBase(BaseDecl);
4819 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
4823 if (!this->visitInitializer(InitExpr))
4825 if (!this->emitFinishInitPop(InitExpr))
4828 assert(IFD->getChainingSize() >= 2);
4830 unsigned NestedFieldOffset = 0;
4831 const Record::Field *NestedField =
nullptr;
4832 for (
const NamedDecl *ND : IFD->chain()) {
4833 const auto *FD = cast<FieldDecl>(ND);
4834 const Record *FieldRecord =
4835 this->
P.getOrCreateRecord(FD->getParent());
4836 assert(FieldRecord);
4838 NestedField = FieldRecord->
getField(FD);
4839 assert(NestedField);
4841 NestedFieldOffset += NestedField->Offset;
4843 assert(NestedField);
4845 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
4848 assert(
Init->isDelegatingInitializer());
4849 if (!this->emitThis(InitExpr))
4851 if (!this->visitInitializer(
Init->getInit()))
4853 if (!this->emitPopPtr(InitExpr))
4857 if (!
Scope.destroyLocals())
4862 if (
const auto *Body = F->
getBody())
4863 if (!visitStmt(Body))
4872template <
class Emitter>
4874 const Expr *SubExpr =
E->getSubExpr();
4876 return this->VisitComplexUnaryOperator(
E);
4877 std::optional<PrimType>
T = classify(SubExpr->
getType());
4879 switch (
E->getOpcode()) {
4881 if (!Ctx.getLangOpts().CPlusPlus14)
4882 return this->emitInvalid(
E);
4884 return this->emitError(
E);
4886 if (!this->visit(SubExpr))
4890 if (!this->emitIncPtr(
E))
4893 return DiscardResult ? this->emitPopPtr(
E) :
true;
4897 return DiscardResult ? this->emitIncfPop(getRoundingMode(
E),
E)
4898 : this->emitIncf(getRoundingMode(
E),
E);
4901 return DiscardResult ? this->emitIncPop(*
T,
E) : this->emitInc(*
T,
E);
4904 if (!Ctx.getLangOpts().CPlusPlus14)
4905 return this->emitInvalid(
E);
4907 return this->emitError(
E);
4909 if (!this->visit(SubExpr))
4913 if (!this->emitDecPtr(
E))
4916 return DiscardResult ? this->emitPopPtr(
E) :
true;
4920 return DiscardResult ? this->emitDecfPop(getRoundingMode(
E),
E)
4921 : this->emitDecf(getRoundingMode(
E),
E);
4924 return DiscardResult ? this->emitDecPop(*
T,
E) : this->emitDec(*
T,
E);
4927 if (!Ctx.getLangOpts().CPlusPlus14)
4928 return this->emitInvalid(
E);
4930 return this->emitError(
E);
4932 if (!this->visit(SubExpr))
4936 if (!this->emitLoadPtr(
E))
4938 if (!this->emitConstUint8(1,
E))
4940 if (!this->emitAddOffsetUint8(
E))
4942 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
4946 if (DiscardResult) {
4948 return this->emitIncfPop(getRoundingMode(
E),
E);
4949 return this->emitIncPop(*
T,
E);
4953 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
4954 if (!this->emitLoadFloat(
E))
4956 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
4958 if (!this->emitAddf(getRoundingMode(
E),
E))
4960 if (!this->emitStoreFloat(
E))
4964 if (!this->emitLoad(*
T,
E))
4966 if (!this->emitConst(1,
E))
4968 if (!this->emitAdd(*
T,
E))
4970 if (!this->emitStore(*
T,
E))
4976 if (!Ctx.getLangOpts().CPlusPlus14)
4977 return this->emitInvalid(
E);
4979 return this->emitError(
E);
4981 if (!this->visit(SubExpr))
4985 if (!this->emitLoadPtr(
E))
4987 if (!this->emitConstUint8(1,
E))
4989 if (!this->emitSubOffsetUint8(
E))
4991 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
4995 if (DiscardResult) {
4997 return this->emitDecfPop(getRoundingMode(
E),
E);
4998 return this->emitDecPop(*
T,
E);
5002 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5003 if (!this->emitLoadFloat(
E))
5005 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5007 if (!this->emitSubf(getRoundingMode(
E),
E))
5009 if (!this->emitStoreFloat(
E))
5013 if (!this->emitLoad(*
T,
E))
5015 if (!this->emitConst(1,
E))
5017 if (!this->emitSub(*
T,
E))
5019 if (!this->emitStore(*
T,
E))
5026 return this->emitError(
E);
5029 return this->discard(SubExpr);
5031 if (!this->visitBool(SubExpr))
5034 if (!this->emitInvBool(
E))
5038 return this->emitCast(
PT_Bool, ET,
E);
5042 return this->emitError(
E);
5044 if (!this->visit(SubExpr))
5046 return DiscardResult ? this->emitPop(*
T,
E) : this->emitNeg(*
T,
E);
5049 return this->emitError(
E);
5051 if (!this->visit(SubExpr))
5053 return DiscardResult ? this->emitPop(*
T,
E) :
true;
5058 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(),
E);
5061 return this->delegate(SubExpr);
5064 return this->discard(SubExpr);
5065 return this->visit(SubExpr);
5068 return this->emitError(
E);
5070 if (!this->visit(SubExpr))
5072 return DiscardResult ? this->emitPop(*
T,
E) : this->emitComp(*
T,
E);
5075 return this->delegate(SubExpr);
5078 if (!this->discard(SubExpr))
5080 return this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
5083 return this->delegate(SubExpr);
5085 assert(
false &&
"Unhandled opcode");
5091template <
class Emitter>
5093 const Expr *SubExpr =
E->getSubExpr();
5097 return this->discard(SubExpr);
5099 std::optional<PrimType> ResT = classify(
E);
5100 auto prepareResult = [=]() ->
bool {
5101 if (!ResT && !Initializing) {
5102 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5105 return this->emitGetPtrLocal(*LocalIndex,
E);
5112 unsigned SubExprOffset = ~0u;
5113 auto createTemp = [=, &SubExprOffset]() ->
bool {
5114 SubExprOffset = this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
5115 if (!this->visit(SubExpr))
5117 return this->emitSetLocal(
PT_Ptr, SubExprOffset,
E);
5121 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
5122 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
5124 return this->emitArrayElemPop(ElemT, Index,
E);
5127 switch (
E->getOpcode()) {
5129 if (!prepareResult())
5133 for (
unsigned I = 0; I != 2; ++I) {
5134 if (!getElem(SubExprOffset, I))
5136 if (!this->emitNeg(ElemT,
E))
5138 if (!this->emitInitElem(ElemT, I,
E))
5146 return this->delegate(SubExpr);
5149 if (!this->visit(SubExpr))
5151 if (!this->emitComplexBoolCast(SubExpr))
5153 if (!this->emitInvBool(
E))
5156 return this->emitCast(
PT_Bool, ET,
E);
5160 return this->emitComplexReal(SubExpr);
5163 if (!this->visit(SubExpr))
5167 if (!this->emitConstUint8(1,
E))
5169 return this->emitArrayElemPtrPopUint8(
E);
5174 return this->emitArrayElemPop(classifyPrim(
E->
getType()), 1,
E);
5177 if (!this->visit(SubExpr))
5180 if (!this->emitArrayElem(ElemT, 1,
E))
5182 if (!this->emitNeg(ElemT,
E))
5184 if (!this->emitInitElem(ElemT, 1,
E))
5186 return DiscardResult ? this->emitPopPtr(
E) :
true;
5189 return this->delegate(SubExpr);
5192 return this->emitInvalid(
E);
5198template <
class Emitter>
5203 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(
D)) {
5204 return this->emitConst(ECD->getInitVal(),
E);
5205 }
else if (
const auto *BD = dyn_cast<BindingDecl>(
D)) {
5206 return this->visit(BD->getBinding());
5207 }
else if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(
D)) {
5208 const Function *F = getFunction(FuncDecl);
5209 return F && this->emitGetFnPtr(F,
E);
5210 }
else if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(
D)) {
5211 if (std::optional<unsigned> Index =
P.getOrCreateGlobal(
D)) {
5212 if (!this->emitGetPtrGlobal(*Index,
E))
5214 if (std::optional<PrimType>
T = classify(
E->
getType())) {
5215 if (!this->visitAPValue(TPOD->getValue(), *
T,
E))
5217 return this->emitInitGlobal(*
T, *Index,
E);
5219 return this->visitAPValueInitializer(TPOD->getValue(),
E);
5228 bool IsReference =
D->getType()->isReferenceType();
5231 if (
auto It = Locals.find(
D); It != Locals.end()) {
5232 const unsigned Offset = It->second.Offset;
5234 return this->emitGetLocal(
PT_Ptr, Offset,
E);
5235 return this->emitGetPtrLocal(Offset,
E);
5236 }
else if (
auto GlobalIndex =
P.getGlobal(
D)) {
5238 if (!Ctx.getLangOpts().CPlusPlus11)
5239 return this->emitGetGlobal(classifyPrim(
E), *GlobalIndex,
E);
5240 return this->emitGetGlobalUnchecked(classifyPrim(
E), *GlobalIndex,
E);
5243 return this->emitGetPtrGlobal(*GlobalIndex,
E);
5244 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(
D)) {
5245 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
5246 if (IsReference || !It->second.IsPtr)
5247 return this->emitGetParam(classifyPrim(
E), It->second.Offset,
E);
5249 return this->emitGetPtrParam(It->second.Offset,
E);
5254 auto revisit = [&](
const VarDecl *VD) ->
bool {
5255 auto VarState = this->visitDecl(VD);
5257 if (VarState.notCreated())
5262 return this->visitDeclRef(
D,
E);
5266 if (
auto It = this->LambdaCaptures.find(
D);
5267 It != this->LambdaCaptures.end()) {
5268 auto [Offset, IsPtr] = It->second;
5271 return this->emitGetThisFieldPtr(Offset,
E);
5272 return this->emitGetPtrThisField(Offset,
E);
5273 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E);
5274 DRE && DRE->refersToEnclosingVariableOrCapture()) {
5275 if (
const auto *VD = dyn_cast<VarDecl>(
D); VD && VD->isInitCapture())
5279 if (
D != InitializingDecl) {
5282 if (Ctx.getLangOpts().CPlusPlus) {
5283 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
5284 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
5285 if (
T.isConstant(Ctx.getASTContext()))
5288 return RT->getPointeeType().isConstQualified();
5293 if (isa<DecompositionDecl>(VD))
5297 if ((VD->hasGlobalStorage() || VD->isLocalVarDecl() ||
5298 VD->isStaticDataMember()) &&
5299 typeShouldBeVisited(VD->getType()))
5303 if (
const auto *VD = dyn_cast<VarDecl>(
D);
5304 VD && VD->getAnyInitializer() &&
5305 VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak())
5310 if (std::optional<unsigned> I =
P.getOrCreateDummy(
D)) {
5311 if (!this->emitGetPtrGlobal(*I,
E))
5318 return this->emitDecayPtr(
PT_Ptr, PT,
E);
5324 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E))
5325 return this->emitInvalidDeclRef(DRE,
E);
5329template <
class Emitter>
5331 const auto *
D =
E->getDecl();
5332 return this->visitDeclRef(
D,
E);
5337 C->emitDestruction();
5340template <
class Emitter>
5344 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
5346 return Ty->getAsCXXRecordDecl();
5348 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
5349 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
5351 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
5355template <
class Emitter>
5362 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
5363 return this->emitCastFP(ToSem, getRoundingMode(
E),
E);
5367 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
E);
5369 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
E);
5373 return this->emitCastFloatingIntegral(ToT,
E);
5378 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT),
E);
5380 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT),
E);
5384 return FromT != ToT ? this->emitCast(FromT, ToT,
E) :
true;
5388 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
5389 return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(
E),
5398template <
class Emitter>
5403 return this->discard(SubExpr);
5405 if (!this->visit(SubExpr))
5408 if (!this->emitConstUint8(0, SubExpr))
5410 return this->emitArrayElemPtrPopUint8(SubExpr);
5414 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
5418template <
class Emitter>
5420 assert(!DiscardResult);
5424 if (!this->emitArrayElem(ElemT, 0,
E))
5427 if (!this->emitCastFloatingIntegral(
PT_Bool,
E))
5430 if (!this->emitCast(ElemT,
PT_Bool,
E))
5435 LabelTy LabelTrue = this->getLabel();
5436 if (!this->jumpTrue(LabelTrue))
5439 if (!this->emitArrayElemPop(ElemT, 1,
E))
5442 if (!this->emitCastFloatingIntegral(
PT_Bool,
E))
5445 if (!this->emitCast(ElemT,
PT_Bool,
E))
5449 LabelTy EndLabel = this->getLabel();
5450 this->jump(EndLabel);
5452 this->emitLabel(LabelTrue);
5453 if (!this->emitPopPtr(
E))
5455 if (!this->emitConstBool(
true,
E))
5458 this->fallthrough(EndLabel);
5459 this->emitLabel(EndLabel);
5464template <
class Emitter>
5467 assert(
E->isComparisonOp());
5468 assert(!Initializing);
5469 assert(!DiscardResult);
5475 LHSIsComplex =
true;
5476 ElemT = classifyComplexElementType(LHS->
getType());
5477 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true,
5479 if (!this->visit(LHS))
5481 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
5484 LHSIsComplex =
false;
5486 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
5487 if (!this->visit(LHS))
5489 if (!this->emitSetLocal(LHST, LHSOffset,
E))
5496 RHSIsComplex =
true;
5497 ElemT = classifyComplexElementType(RHS->
getType());
5498 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true,
5500 if (!this->visit(RHS))
5502 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
5505 RHSIsComplex =
false;
5507 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
5508 if (!this->visit(RHS))
5510 if (!this->emitSetLocal(RHST, RHSOffset,
E))
5514 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
5515 bool IsComplex) ->
bool {
5517 if (!this->emitGetLocal(
PT_Ptr, LocalOffset,
E))
5519 return this->emitArrayElemPop(ElemT, Index,
E);
5521 return this->emitGetLocal(ElemT, LocalOffset,
E);
5524 for (
unsigned I = 0; I != 2; ++I) {
5526 if (!getElem(LHSOffset, I, LHSIsComplex))
5528 if (!getElem(RHSOffset, I, RHSIsComplex))
5531 if (!this->emitEQ(ElemT,
E))
5534 if (!this->emitCastBoolUint8(
E))
5539 if (!this->emitAddUint8(
E))
5541 if (!this->emitConstUint8(2,
E))
5544 if (
E->getOpcode() == BO_EQ) {
5545 if (!this->emitEQUint8(
E))
5547 }
else if (
E->getOpcode() == BO_NE) {
5548 if (!this->emitNEUint8(
E))
5555 return this->emitCast(
PT_Bool, ResT,
E);
5562template <
class Emitter>
5567 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
5569 if (!
D->isPrimitive() && !
D->isPrimitiveArray()) {
5572 if (!this->emitDestruction(
D))
5583 const Function *DtorFunc = getFunction(Dtor);
5590 if (!this->emitCall(DtorFunc, 0,
SourceInfo{}))
5594 for (
const Record::Base &
Base : llvm::reverse(R->
bases())) {
5597 if (!this->emitRecordDestruction(
Base.R))
5609template <
class Emitter>
5633 for (ssize_t I = Desc->
getNumElems() - 1; I >= 0; --I) {
5636 if (!this->emitArrayElemPtrUint64(
SourceInfo{}))
5638 if (!this->emitDestruction(ElemDesc))
5647 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.
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 a value-initialized rvalue of type T, which is a non-class type.
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.
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;.
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 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)
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()