33 OldInitializingDecl(
Ctx->InitializingDecl) {
34 Ctx->InitializingDecl = VD;
43 this->
Ctx->InitializingDecl = OldInitializingDecl;
44 this->
Ctx->InitStack.pop_back();
58 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
60 Ctx->DiscardResult = NewDiscardResult;
61 Ctx->Initializing = NewInitializing;
65 Ctx->DiscardResult = OldDiscardResult;
66 Ctx->Initializing = OldInitializing;
73 bool OldDiscardResult;
77template <
class Emitter>
81 return Ctx->emitThis(
E);
84 return Ctx->emitGetPtrFieldPop(
Offset,
E);
86 return Ctx->emitGetPtrLocal(
Offset,
E);
88 return Ctx->visitDeclRef(
D,
E);
90 if (!Ctx->emitConstUint32(
Offset,
E))
92 return Ctx->emitArrayElemPtrPopUint32(
E);
94 return Ctx->emitRVOPtr(
E);
98 llvm_unreachable(
"Unhandled InitLink kind");
122 OldContinueLabel(
Ctx->ContinueLabel),
123 OldBreakVarScope(
Ctx->BreakVarScope),
124 OldContinueVarScope(
Ctx->ContinueVarScope) {
132 this->
Ctx->BreakLabel = OldBreakLabel;
133 this->
Ctx->ContinueLabel = OldContinueLabel;
134 this->
Ctx->ContinueVarScope = OldContinueVarScope;
135 this->
Ctx->BreakVarScope = OldBreakVarScope;
155 OldDefaultLabel(this->
Ctx->DefaultLabel),
156 OldCaseLabels(
std::move(this->
Ctx->CaseLabels)),
157 OldLabelVarScope(
Ctx->BreakVarScope) {
160 this->Ctx->
CaseLabels = std::move(CaseLabels);
165 this->
Ctx->BreakLabel = OldBreakLabel;
166 this->
Ctx->DefaultLabel = OldDefaultLabel;
167 this->
Ctx->CaseLabels = std::move(OldCaseLabels);
168 this->
Ctx->BreakVarScope = OldLabelVarScope;
181 Ctx->InStmtExpr =
true;
194template <
class Emitter>
199 case CK_LValueToRValue: {
201 return this->discard(SubExpr);
203 std::optional<PrimType> SubExprT = classify(SubExpr->
getType());
206 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
209 if (!this->emitGetPtrLocal(*LocalIndex, CE))
213 if (!this->visit(SubExpr))
217 return this->emitLoadPop(*SubExprT, CE);
222 return this->emitMemcpy(CE);
225 case CK_DerivedToBaseMemberPointer: {
234 if (!this->delegate(SubExpr))
237 return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
240 case CK_BaseToDerivedMemberPointer: {
246 unsigned DerivedOffset = collectBaseOffset(
QualType(FromMP->getClass(), 0),
249 if (!this->delegate(SubExpr))
251 return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
254 case CK_UncheckedDerivedToBase:
255 case CK_DerivedToBase: {
257 return this->discard(SubExpr);
259 if (!this->delegate(SubExpr))
263 if (
const auto *PT = dyn_cast<PointerType>(Ty))
264 return PT->getPointeeType()->getAsCXXRecordDecl();
265 return Ty->getAsCXXRecordDecl();
272 if (B->isVirtual()) {
273 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))
275 CurType = B->getType();
277 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
278 if (!this->emitGetPtrBasePop(DerivedOffset, CE))
280 CurType = B->getType();
287 case CK_BaseToDerived: {
289 return this->discard(SubExpr);
291 if (!this->delegate(SubExpr))
294 unsigned DerivedOffset =
297 return this->emitGetPtrDerivedPop(DerivedOffset, CE);
300 case CK_FloatingCast: {
306 return this->discard(SubExpr);
307 if (!this->visit(SubExpr))
309 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
313 case CK_IntegralToFloating: {
315 return this->discard(SubExpr);
316 std::optional<PrimType> FromT = classify(SubExpr->
getType());
320 if (!this->visit(SubExpr))
323 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
324 return this->emitCastIntegralFloating(*FromT, TargetSemantics,
325 getFPOptions(CE), CE);
328 case CK_FloatingToBoolean:
329 case CK_FloatingToIntegral: {
331 return this->discard(SubExpr);
333 std::optional<PrimType> ToT = classify(CE->
getType());
338 if (!this->visit(SubExpr))
342 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->
getType()),
343 getFPOptions(CE), CE);
345 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->
getType()),
346 getFPOptions(CE), CE);
348 return this->emitCastFloatingIntegral(*ToT, getFPOptions(CE), CE);
351 case CK_NullToPointer:
352 case CK_NullToMemberPointer: {
353 if (!this->discard(SubExpr))
360 if (!PointeeType.
isNull()) {
361 if (std::optional<PrimType>
T = classify(PointeeType))
362 Desc =
P.createDescriptor(SubExpr, *
T);
364 Desc =
P.createDescriptor(SubExpr, PointeeType.
getTypePtr(),
365 std::nullopt,
true,
false,
370 return this->emitNull(classifyPrim(CE->
getType()), Val, Desc, CE);
373 case CK_PointerToIntegral: {
375 return this->discard(SubExpr);
377 if (!this->visit(SubExpr))
383 if (!this->emitDecayPtr(FromT,
PT_Ptr, CE))
389 return this->emitCastPointerIntegralAP(Ctx.getBitWidth(CE->
getType()),
392 return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(CE->
getType()),
394 return this->emitCastPointerIntegral(
T, CE);
397 case CK_ArrayToPointerDecay: {
398 if (!this->visit(SubExpr))
400 if (!this->emitArrayDecay(CE))
403 return this->emitPopPtr(CE);
407 case CK_IntegralToPointer: {
410 if (!this->visit(SubExpr))
416 return this->emitPop(
T, CE);
421 Desc =
P.createDescriptor(SubExpr, *
T);
429 if (!this->emitGetIntPtr(
T, Desc, CE))
432 PrimType DestPtrT = classifyPrim(PtrType);
437 return this->emitDecayPtr(
PT_Ptr, DestPtrT, CE);
440 case CK_AtomicToNonAtomic:
441 case CK_ConstructorConversion:
442 case CK_FunctionToPointerDecay:
443 case CK_NonAtomicToAtomic:
445 case CK_UserDefinedConversion:
446 case CK_AddressSpaceConversion:
447 case CK_CPointerToObjCPointerCast:
448 return this->delegate(SubExpr);
453 if (!this->discard(SubExpr))
455 return this->emitInvalidCast(CastKind::Reinterpret,
true, CE);
459 return this->discard(SubExpr);
462 std::optional<PrimType> FromT = classify(SubExprTy);
465 return this->emitBuiltinBitCast(CE);
467 std::optional<PrimType> ToT = classify(CE->
getType());
475 return this->delegate(SubExpr);
477 if (!this->visit(SubExpr))
484 if (!this->visit(SubExpr))
486 return this->emitDecayPtr(*FromT, *ToT, CE);
489 case CK_LValueToRValueBitCast:
490 return this->emitBuiltinBitCast(CE);
492 case CK_IntegralToBoolean:
493 case CK_FixedPointToBoolean:
494 case CK_BooleanToSignedIntegral:
495 case CK_IntegralCast: {
497 return this->discard(SubExpr);
498 std::optional<PrimType> FromT = classify(SubExpr->
getType());
499 std::optional<PrimType> ToT = classify(CE->
getType());
504 if (!this->visit(SubExpr))
512 if (!this->emitCheckEnumValue(*FromT, ET->getDecl(), CE))
517 auto maybeNegate = [&]() ->
bool {
518 if (CE->
getCastKind() == CK_BooleanToSignedIntegral)
519 return this->emitNeg(*ToT, CE);
524 return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->
getType()), CE) &&
527 return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->
getType()), CE) &&
532 if (!this->emitCast(*FromT, *ToT, CE))
535 return maybeNegate();
538 case CK_PointerToBoolean:
539 case CK_MemberPointerToBoolean: {
542 if (!this->visit(SubExpr))
544 return this->emitIsNonNull(PtrT, CE);
547 case CK_IntegralComplexToBoolean:
548 case CK_FloatingComplexToBoolean: {
550 return this->discard(SubExpr);
551 if (!this->visit(SubExpr))
553 return this->emitComplexBoolCast(SubExpr);
556 case CK_IntegralComplexToReal:
557 case CK_FloatingComplexToReal:
558 return this->emitComplexReal(SubExpr);
560 case CK_IntegralRealToComplex:
561 case CK_FloatingRealToComplex: {
565 std::optional<unsigned> LocalIndex = allocateTemporary(CE);
568 if (!this->emitGetPtrLocal(*LocalIndex, CE))
573 if (!this->visitArrayElemInit(0, SubExpr))
577 if (!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
579 return this->emitInitElem(
T, 1, SubExpr);
582 case CK_IntegralComplexCast:
583 case CK_FloatingComplexCast:
584 case CK_IntegralComplexToFloatingComplex:
585 case CK_FloatingComplexToIntegralComplex: {
589 return this->discard(SubExpr);
592 std::optional<unsigned> LocalIndex = allocateLocal(CE);
595 if (!this->emitGetPtrLocal(*LocalIndex, CE))
602 unsigned SubExprOffset = allocateLocalPrimitive(
603 SubExpr,
PT_Ptr,
true,
false);
604 if (!this->visit(SubExpr))
606 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, CE))
612 PrimType DestElemT = classifyPrim(DestElemType);
614 for (
unsigned I = 0; I != 2; ++I) {
615 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, CE))
617 if (!this->emitArrayElemPop(SourceElemT, I, CE))
621 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
625 if (!this->emitInitElem(DestElemT, I, CE))
631 case CK_VectorSplat: {
632 assert(!classify(CE->
getType()));
633 assert(classify(SubExpr->
getType()));
637 return this->discard(SubExpr);
640 std::optional<unsigned> LocalIndex = allocateLocal(CE);
643 if (!this->emitGetPtrLocal(*LocalIndex, CE))
649 unsigned ElemOffset = allocateLocalPrimitive(
650 SubExpr, ElemT,
true,
false);
653 if (!this->visit(SubExpr))
655 if (classifyPrim(SubExpr) ==
PT_Ptr && !this->emitLoadPop(ElemT, CE))
658 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
661 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
662 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
664 if (!this->emitInitElem(ElemT, I, CE))
671 case CK_HLSLVectorTruncation: {
673 if (std::optional<PrimType> ResultT = classify(CE)) {
674 assert(!DiscardResult);
676 if (!this->visit(SubExpr))
678 return this->emitArrayElemPop(*ResultT, 0, CE);
684 std::optional<unsigned> LocalIndex = allocateTemporary(CE);
687 if (!this->emitGetPtrLocal(*LocalIndex, CE))
692 if (!this->visit(SubExpr))
694 return this->emitCopyArray(classifyVectorElementType(CE->
getType()), 0, 0,
698 case CK_IntegralToFixedPoint: {
699 if (!this->visit(SubExpr))
704 return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->
getType()),
707 case CK_FloatingToFixedPoint: {
708 if (!this->visit(SubExpr))
713 return this->emitCastFloatingFixedPoint(Sem, CE);
715 case CK_FixedPointToFloating: {
716 if (!this->visit(SubExpr))
718 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
719 return this->emitCastFixedPointFloating(TargetSemantics, CE);
721 case CK_FixedPointToIntegral: {
722 if (!this->visit(SubExpr))
724 return this->emitCastFixedPointIntegral(classifyPrim(CE->
getType()), CE);
726 case CK_FixedPointCast: {
727 if (!this->visit(SubExpr))
731 return this->emitCastFixedPoint(Sem, CE);
735 return discard(SubExpr);
738 return this->emitInvalid(CE);
740 llvm_unreachable(
"Unhandled clang::CastKind enum");
743template <
class Emitter>
748 return this->emitConst(
LE->getValue(),
LE);
751template <
class Emitter>
756 return this->emitConstFloat(
E->getValue(),
E);
759template <
class Emitter>
766 std::optional<unsigned> LocalIndex = allocateTemporary(
E);
769 if (!this->emitGetPtrLocal(*LocalIndex,
E))
773 const Expr *SubExpr =
E->getSubExpr();
776 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
778 if (!this->emitInitElem(SubExprT, 0, SubExpr))
780 return this->visitArrayElemInit(1, SubExpr);
783template <
class Emitter>
796template <
class Emitter>
798 return this->delegate(
E->getSubExpr());
801template <
class Emitter>
805 return this->VisitLogicalBinOp(BO);
813 if (!this->discard(LHS))
816 return this->discard(RHS);
818 return this->delegate(RHS);
822 return this->VisitComplexBinOp(BO);
824 return this->VisitVectorBinOp(BO);
828 return this->emitComplexComparison(LHS, RHS, BO);
830 return this->VisitFixedPointBinOp(BO);
833 if (!this->visit(LHS))
836 if (!this->visit(RHS))
839 if (!this->emitToMemberPtr(BO))
845 if (!this->emitCastMemberPtrPtr(BO))
847 return DiscardResult ? this->emitPopPtr(BO) :
true;
851 std::optional<PrimType>
LT = classify(LHS);
852 std::optional<PrimType> RT = classify(RHS);
853 std::optional<PrimType>
T = classify(BO->
getType());
867 std::optional<unsigned> ResultIndex = this->allocateLocal(BO);
868 if (!this->emitGetPtrLocal(*ResultIndex, BO))
872 if (!visit(LHS) || !visit(RHS))
875 return this->emitCMP3(*
LT, CmpInfo, BO);
878 if (!
LT || !RT || !
T)
884 return this->VisitPointerArithBinOp(BO);
889 if (!visit(RHS) || !visit(LHS))
891 if (!this->emitFlip(*
LT, *RT, BO))
894 if (!visit(LHS) || !visit(RHS))
900 auto MaybeCastToBool = [
this,
T, BO](
bool Result) {
904 return this->emitPop(*
T, BO);
906 return this->emitCast(
PT_Bool, *
T, BO);
910 auto Discard = [
this,
T, BO](
bool Result) {
913 return DiscardResult ? this->emitPop(*
T, BO) :
true;
918 return MaybeCastToBool(this->emitEQ(*
LT, BO));
920 return MaybeCastToBool(this->emitNE(*
LT, BO));
922 return MaybeCastToBool(this->emitLT(*
LT, BO));
924 return MaybeCastToBool(this->emitLE(*
LT, BO));
926 return MaybeCastToBool(this->emitGT(*
LT, BO));
928 return MaybeCastToBool(this->emitGE(*
LT, BO));
931 return Discard(this->emitSubf(getFPOptions(BO), BO));
932 return Discard(this->emitSub(*
T, BO));
935 return Discard(this->emitAddf(getFPOptions(BO), BO));
936 return Discard(this->emitAdd(*
T, BO));
939 return Discard(this->emitMulf(getFPOptions(BO), BO));
940 return Discard(this->emitMul(*
T, BO));
942 return Discard(this->emitRem(*
T, BO));
945 return Discard(this->emitDivf(getFPOptions(BO), BO));
946 return Discard(this->emitDiv(*
T, BO));
950 : this->emitStorePop(*
T, BO);
952 if (!this->emitStoreBitField(*
T, BO))
955 if (!this->emitStore(*
T, BO))
961 return this->emitLoadPop(*
T, BO);
964 return Discard(this->emitBitAnd(*
T, BO));
966 return Discard(this->emitBitOr(*
T, BO));
968 return Discard(this->emitShl(*
LT, *RT, BO));
970 return Discard(this->emitShr(*
LT, *RT, BO));
972 return Discard(this->emitBitXor(*
T, BO));
975 llvm_unreachable(
"Already handled earlier");
980 llvm_unreachable(
"Unhandled binary op");
985template <
class Emitter>
988 const Expr *LHS =
E->getLHS();
989 const Expr *RHS =
E->getRHS();
991 if ((Op != BO_Add && Op != BO_Sub) ||
995 std::optional<PrimType>
LT = classify(LHS);
996 std::optional<PrimType> RT = classify(RHS);
1003 if (!this->visit(
E))
1006 return this->emitDecayPtr(
T,
PT_Ptr,
E);
1015 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *
LT))
1019 if (!this->emitSubPtr(IntT,
E))
1021 return DiscardResult ? this->emitPop(IntT,
E) :
true;
1026 if (!visitAsPointer(RHS, *RT))
1028 if (!this->visit(LHS))
1032 if (!visitAsPointer(LHS, *
LT))
1034 if (!this->visit(RHS))
1044 if (!this->emitAddOffset(OffsetType,
E))
1047 if (classifyPrim(
E) !=
PT_Ptr)
1048 return this->emitDecayPtr(
PT_Ptr, classifyPrim(
E),
E);
1050 }
else if (Op == BO_Sub) {
1051 if (!this->emitSubOffset(OffsetType,
E))
1054 if (classifyPrim(
E) !=
PT_Ptr)
1055 return this->emitDecayPtr(
PT_Ptr, classifyPrim(
E),
E);
1062template <
class Emitter>
1064 assert(
E->isLogicalOp());
1066 const Expr *LHS =
E->getLHS();
1067 const Expr *RHS =
E->getRHS();
1068 std::optional<PrimType>
T = classify(
E->
getType());
1072 LabelTy LabelTrue = this->getLabel();
1073 LabelTy LabelEnd = this->getLabel();
1075 if (!this->visitBool(LHS))
1077 if (!this->jumpTrue(LabelTrue))
1080 if (!this->visitBool(RHS))
1082 if (!this->jump(LabelEnd))
1085 this->emitLabel(LabelTrue);
1086 this->emitConstBool(
true,
E);
1087 this->fallthrough(LabelEnd);
1088 this->emitLabel(LabelEnd);
1091 assert(Op == BO_LAnd);
1094 LabelTy LabelFalse = this->getLabel();
1095 LabelTy LabelEnd = this->getLabel();
1097 if (!this->visitBool(LHS))
1099 if (!this->jumpFalse(LabelFalse))
1102 if (!this->visitBool(RHS))
1104 if (!this->jump(LabelEnd))
1107 this->emitLabel(LabelFalse);
1108 this->emitConstBool(
false,
E);
1109 this->fallthrough(LabelEnd);
1110 this->emitLabel(LabelEnd);
1114 return this->emitPopBool(
E);
1123template <
class Emitter>
1127 std::optional<unsigned> LocalIndex = allocateTemporary(
E);
1130 if (!this->emitGetPtrLocal(*LocalIndex,
E))
1136 const Expr *LHS =
E->getLHS();
1137 const Expr *RHS =
E->getRHS();
1140 unsigned ResultOffset = ~0u;
1142 ResultOffset = this->allocateLocalPrimitive(
E,
PT_Ptr,
true,
false);
1145 if (!this->DiscardResult) {
1146 if (!this->emitDupPtr(
E))
1148 if (!this->emitSetLocal(
PT_Ptr, ResultOffset,
E))
1153 LHSType = AT->getValueType();
1156 RHSType = AT->getValueType();
1165 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1170 if (!this->visit(LHS))
1172 if (!this->visit(RHS))
1174 return this->emitMulc(ElemT,
E);
1177 if (Op == BO_Div && RHSIsComplex) {
1179 PrimType ElemT = classifyPrim(ElemQT);
1184 if (!LHSIsComplex) {
1186 std::optional<unsigned> LocalIndex = allocateTemporary(RHS);
1189 LHSOffset = *LocalIndex;
1191 if (!this->emitGetPtrLocal(LHSOffset,
E))
1194 if (!this->visit(LHS))
1197 if (!this->emitInitElem(ElemT, 0,
E))
1200 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1202 if (!this->emitInitElem(ElemT, 1,
E))
1205 if (!this->visit(LHS))
1209 if (!this->visit(RHS))
1211 return this->emitDivc(ElemT,
E);
1216 LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
1217 if (!this->visit(LHS))
1219 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1222 PrimType LHST = classifyPrim(LHSType);
1223 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
1224 if (!this->visit(LHS))
1226 if (!this->emitSetLocal(LHST, LHSOffset,
E))
1233 RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
1234 if (!this->visit(RHS))
1236 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1239 PrimType RHST = classifyPrim(RHSType);
1240 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
1241 if (!this->visit(RHS))
1243 if (!this->emitSetLocal(RHST, RHSOffset,
E))
1250 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1251 unsigned ElemIndex,
unsigned Offset,
1252 const Expr *
E) ->
bool {
1254 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
1256 return this->emitArrayElemPop(classifyComplexElementType(
E->
getType()),
1259 if (ElemIndex == 0 || !LoadZero)
1260 return this->emitGetLocal(classifyPrim(
E->
getType()), Offset,
E);
1261 return this->visitZeroInitializer(classifyPrim(
E->
getType()),
E->
getType(),
1266 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1268 if (!this->DiscardResult) {
1269 if (!this->emitGetLocal(
PT_Ptr, ResultOffset,
E))
1276 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1279 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1282 if (!this->emitAddf(getFPOptions(
E),
E))
1285 if (!this->emitAdd(ResultElemT,
E))
1290 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1293 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1296 if (!this->emitSubf(getFPOptions(
E),
E))
1299 if (!this->emitSub(ResultElemT,
E))
1304 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1307 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1311 if (!this->emitMulf(getFPOptions(
E),
E))
1314 if (!this->emitMul(ResultElemT,
E))
1319 assert(!RHSIsComplex);
1320 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1323 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1327 if (!this->emitDivf(getFPOptions(
E),
E))
1330 if (!this->emitDiv(ResultElemT,
E))
1339 if (!this->DiscardResult) {
1341 if (!this->emitInitElemPop(ResultElemT, ElemIndex,
E))
1344 if (!this->emitPop(ResultElemT,
E))
1351template <
class Emitter>
1353 assert(!
E->isCommaOp() &&
1354 "Comma op should be handled in VisitBinaryOperator");
1361 std::optional<unsigned> LocalIndex = allocateTemporary(
E);
1364 if (!this->emitGetPtrLocal(*LocalIndex,
E))
1368 const Expr *LHS =
E->getLHS();
1369 const Expr *RHS =
E->getRHS();
1371 auto Op =
E->isCompoundAssignmentOp()
1380 unsigned LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
1381 if (!this->visit(LHS))
1383 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1387 unsigned RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
1388 if (!this->visit(RHS))
1390 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1393 if (
E->isCompoundAssignmentOp() && !this->emitGetLocal(
PT_Ptr, LHSOffset,
E))
1398 bool NeedIntPromot = ElemT ==
PT_Bool && (
E->isBitwiseOp() ||
E->isShiftOp());
1401 PrimType PromotT = classifyPrim(PromotTy);
1402 PrimType OpT = NeedIntPromot ? PromotT : ElemT;
1404 auto getElem = [=](
unsigned Offset,
PrimType ElemT,
unsigned Index) {
1405 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
1407 if (!this->emitArrayElemPop(ElemT, Index,
E))
1409 if (
E->isLogicalOp()) {
1410 if (!this->emitPrimCast(ElemT,
PT_Bool, Ctx.getASTContext().
BoolTy,
E))
1412 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(),
E))
1414 }
else if (NeedIntPromot) {
1415 if (!this->emitPrimCast(ElemT, PromotT, PromotTy,
E))
1421#define EMIT_ARITH_OP(OP) \
1423 if (ElemT == PT_Float) { \
1424 if (!this->emit##OP##f(getFPOptions(E), E)) \
1427 if (!this->emit##OP(ElemT, E)) \
1433 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
1434 if (!getElem(LHSOffset, ElemT, I))
1436 if (!getElem(RHSOffset, RHSElemT, I))
1448 if (!this->emitRem(ElemT,
E))
1452 if (!this->emitBitAnd(OpT,
E))
1456 if (!this->emitBitOr(OpT,
E))
1460 if (!this->emitBitXor(OpT,
E))
1464 if (!this->emitShl(OpT, RHSElemT,
E))
1468 if (!this->emitShr(OpT, RHSElemT,
E))
1472 if (!this->emitEQ(ElemT,
E))
1476 if (!this->emitNE(ElemT,
E))
1480 if (!this->emitLE(ElemT,
E))
1484 if (!this->emitLT(ElemT,
E))
1488 if (!this->emitGE(ElemT,
E))
1492 if (!this->emitGT(ElemT,
E))
1497 if (!this->emitBitAnd(ResultElemT,
E))
1502 if (!this->emitBitOr(ResultElemT,
E))
1506 return this->emitInvalid(
E);
1514 if (
E->isComparisonOp()) {
1515 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(),
E))
1517 if (!this->emitNeg(ResultElemT,
E))
1523 if (NeedIntPromot &&
1524 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(),
E))
1528 if (!this->emitInitElem(ResultElemT, I,
E))
1532 if (DiscardResult &&
E->isCompoundAssignmentOp() && !this->emitPopPtr(
E))
1537template <
class Emitter>
1539 const Expr *LHS =
E->getLHS();
1540 const Expr *RHS =
E->getRHS();
1541 const ASTContext &ASTCtx = Ctx.getASTContext();
1547 auto LHSSemaInt = LHSSema.toOpaqueInt();
1549 auto RHSSemaInt = RHSSema.toOpaqueInt();
1551 if (!this->visit(LHS))
1554 if (!this->emitCastIntegralFixedPoint(classifyPrim(LHS->
getType()),
1559 if (!this->visit(RHS))
1562 if (!this->emitCastIntegralFixedPoint(classifyPrim(RHS->
getType()),
1568 auto ConvertResult = [&](
bool R) ->
bool {
1572 auto CommonSema = LHSSema.getCommonSemantics(RHSSema).toOpaqueInt();
1573 if (ResultSema != CommonSema)
1574 return this->emitCastFixedPoint(ResultSema,
E);
1578 auto MaybeCastToBool = [&](
bool Result) {
1583 return this->emitPop(
T,
E);
1589 switch (
E->getOpcode()) {
1591 return MaybeCastToBool(this->emitEQFixedPoint(
E));
1593 return MaybeCastToBool(this->emitNEFixedPoint(
E));
1595 return MaybeCastToBool(this->emitLTFixedPoint(
E));
1597 return MaybeCastToBool(this->emitLEFixedPoint(
E));
1599 return MaybeCastToBool(this->emitGTFixedPoint(
E));
1601 return MaybeCastToBool(this->emitGEFixedPoint(
E));
1603 return ConvertResult(this->emitAddFixedPoint(
E));
1605 return ConvertResult(this->emitSubFixedPoint(
E));
1607 return ConvertResult(this->emitMulFixedPoint(
E));
1609 return ConvertResult(this->emitDivFixedPoint(
E));
1611 return ConvertResult(this->emitShiftFixedPoint(
true,
E));
1613 return ConvertResult(this->emitShiftFixedPoint(
false,
E));
1616 return this->emitInvalid(
E);
1619 llvm_unreachable(
"unhandled binop opcode");
1622template <
class Emitter>
1624 const Expr *SubExpr =
E->getSubExpr();
1627 switch (
E->getOpcode()) {
1629 return this->delegate(SubExpr);
1631 if (!this->visit(SubExpr))
1633 return this->emitNegFixedPoint(
E);
1638 llvm_unreachable(
"Unhandled unary opcode");
1641template <
class Emitter>
1646 if (std::optional<PrimType>
T = classify(QT))
1647 return this->visitZeroInitializer(*
T, QT,
E);
1655 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1656 CXXRD && CXXRD->getNumVBases() > 0) {
1661 const Record *R = getRecord(QT);
1666 return this->visitZeroRecordInitializer(R,
E);
1673 return this->visitZeroArrayInitializer(QT,
E);
1677 QualType ElemQT = ComplexTy->getElementType();
1678 PrimType ElemT = classifyPrim(ElemQT);
1679 for (
unsigned I = 0; I < 2; ++I) {
1680 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1682 if (!this->emitInitElem(ElemT, I,
E))
1689 unsigned NumVecElements = VecT->getNumElements();
1690 QualType ElemQT = VecT->getElementType();
1691 PrimType ElemT = classifyPrim(ElemQT);
1693 for (
unsigned I = 0; I < NumVecElements; ++I) {
1694 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1696 if (!this->emitInitElem(ElemT, I,
E))
1705template <
class Emitter>
1707 const Expr *LHS =
E->getLHS();
1708 const Expr *RHS =
E->getRHS();
1709 const Expr *Index =
E->getIdx();
1712 return this->discard(LHS) && this->discard(RHS);
1717 for (
const Expr *SubExpr : {LHS, RHS}) {
1718 if (!this->visit(SubExpr))
1725 PrimType IndexT = classifyPrim(Index->getType());
1728 if (!this->emitFlip(
PT_Ptr, IndexT,
E))
1732 return this->emitArrayElemPtrPop(IndexT,
E);
1735template <
class Emitter>
1737 const Expr *ArrayFiller,
const Expr *
E) {
1742 QT = AT->getValueType();
1745 if (Inits.size() == 0)
1747 return this->emitInvalid(
E);
1751 if (DiscardResult) {
1753 if (!this->discard(
Init))
1760 if (std::optional<PrimType>
T = classify(QT)) {
1761 assert(!DiscardResult);
1762 if (Inits.size() == 0)
1763 return this->visitZeroInitializer(*
T, QT,
E);
1764 assert(Inits.size() == 1);
1765 return this->delegate(Inits[0]);
1769 const Record *R = getRecord(QT);
1771 if (Inits.size() == 1 &&
E->
getType() == Inits[0]->getType())
1772 return this->delegate(Inits[0]);
1774 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
1778 if (!this->visit(
Init))
1781 if (FieldToInit->isBitField())
1782 return this->emitInitBitField(
T, FieldToInit,
E);
1783 return this->emitInitField(
T, FieldToInit->Offset,
E);
1786 auto initCompositeField = [=](
const Record::Field *FieldToInit,
1793 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
1795 if (!this->visitInitializer(
Init))
1797 return this->emitPopPtr(
E);
1801 if (Inits.size() == 0) {
1802 if (!this->visitZeroRecordInitializer(R,
E))
1807 if (
const auto *ILE = dyn_cast<InitListExpr>(
E))
1808 FToInit = ILE->getInitializedFieldInUnion();
1810 FToInit = cast<CXXParenListInitExpr>(
E)->getInitializedFieldInUnion();
1812 const Record::Field *FieldToInit = R->
getField(FToInit);
1813 if (std::optional<PrimType>
T = classify(
Init)) {
1814 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1817 if (!initCompositeField(FieldToInit,
Init))
1821 return this->emitFinishInit(
E);
1825 unsigned InitIndex = 0;
1828 while (InitIndex < R->getNumFields() &&
1832 if (std::optional<PrimType>
T = classify(
Init)) {
1833 const Record::Field *FieldToInit = R->
getField(InitIndex);
1834 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1839 if (
const Record::Base *B = R->
getBase(
Init->getType())) {
1840 if (!this->emitGetPtrBase(B->Offset,
Init))
1843 if (!this->visitInitializer(
Init))
1846 if (!this->emitFinishInitPop(
E))
1851 const Record::Field *FieldToInit = R->
getField(InitIndex);
1852 if (!initCompositeField(FieldToInit,
Init))
1858 return this->emitFinishInit(
E);
1862 if (Inits.size() == 1 && QT == Inits[0]->getType())
1863 return this->delegate(Inits[0]);
1865 unsigned ElementIndex = 0;
1867 if (
const auto *EmbedS =
1868 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1871 auto Eval = [&](
const Expr *
Init,
unsigned ElemIndex) {
1873 if (!this->visit(
Init))
1875 if (InitT != TargetT) {
1876 if (!this->emitCast(InitT, TargetT,
E))
1879 return this->emitInitElem(TargetT, ElemIndex,
Init);
1881 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
1884 if (!this->visitArrayElemInit(ElementIndex,
Init))
1897 for (; ElementIndex != NumElems; ++ElementIndex) {
1898 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller))
1903 return this->emitFinishInit(
E);
1907 unsigned NumInits = Inits.size();
1910 return this->delegate(Inits[0]);
1912 QualType ElemQT = ComplexTy->getElementType();
1913 PrimType ElemT = classifyPrim(ElemQT);
1914 if (NumInits == 0) {
1916 for (
unsigned I = 0; I < 2; ++I) {
1917 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1919 if (!this->emitInitElem(ElemT, I,
E))
1922 }
else if (NumInits == 2) {
1923 unsigned InitIndex = 0;
1925 if (!this->visit(
Init))
1928 if (!this->emitInitElem(ElemT, InitIndex,
E))
1937 unsigned NumVecElements = VecT->getNumElements();
1938 assert(NumVecElements >= Inits.size());
1940 QualType ElemQT = VecT->getElementType();
1941 PrimType ElemT = classifyPrim(ElemQT);
1944 unsigned InitIndex = 0;
1946 if (!this->visit(
Init))
1951 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
1952 if (!this->emitCopyArray(ElemT, 0, InitIndex,
1953 InitVecT->getNumElements(),
E))
1955 InitIndex += InitVecT->getNumElements();
1957 if (!this->emitInitElem(ElemT, InitIndex,
E))
1963 assert(InitIndex <= NumVecElements);
1966 for (; InitIndex != NumVecElements; ++InitIndex) {
1967 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1969 if (!this->emitInitElem(ElemT, InitIndex,
E))
1980template <
class Emitter>
1983 if (std::optional<PrimType>
T = classify(
Init->getType())) {
1985 if (!this->visit(
Init))
1987 return this->emitInitElem(*
T, ElemIndex,
Init);
1993 if (!this->emitConstUint32(ElemIndex,
Init))
1995 if (!this->emitArrayElemPtrUint32(
Init))
1997 if (!this->visitInitializer(
Init))
1999 return this->emitFinishInitPop(
Init);
2002template <
class Emitter>
2004 return this->visitInitList(
E->inits(),
E->getArrayFiller(),
E);
2007template <
class Emitter>
2010 return this->visitInitList(
E->getInitExprs(),
E->getArrayFiller(),
E);
2013template <
class Emitter>
2016 return this->delegate(
E->getReplacement());
2019template <
class Emitter>
2021 std::optional<PrimType>
T = classify(
E->
getType());
2022 if (
T &&
E->hasAPValueResult()) {
2029 if (this->visitAPValue(
E->getAPValueResult(), *
T,
E))
2032 return this->delegate(
E->getSubExpr());
2035template <
class Emitter>
2037 auto It =
E->begin();
2038 return this->visit(*It);
2043 bool AlignOfReturnsPreferred =
2044 ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
2052 if (
T.getQualifiers().hasUnaligned())
2058 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2064template <
class Emitter>
2068 const ASTContext &ASTCtx = Ctx.getASTContext();
2070 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2071 QualType ArgType =
E->getTypeOfArgument();
2083 return this->emitInvalid(
E);
2085 if (Kind == UETT_SizeOf)
2094 return this->emitConst(Size.getQuantity(),
E);
2097 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2100 if (
E->isArgumentType()) {
2101 QualType ArgType =
E->getTypeOfArgument();
2114 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2117 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
2127 return this->emitConst(Size.getQuantity(),
E);
2130 if (Kind == UETT_VectorElements) {
2131 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>())
2132 return this->emitConst(VT->getNumElements(),
E);
2133 assert(
E->getTypeOfArgument()->isSizelessVectorType());
2134 return this->emitSizelessVectorElementSize(
E);
2137 if (Kind == UETT_VecStep) {
2138 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>()) {
2139 unsigned N = VT->getNumElements();
2146 return this->emitConst(N,
E);
2148 return this->emitConst(1,
E);
2151 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2152 assert(
E->isArgumentType());
2158 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2159 if (
E->getArgumentType()->isDependentType())
2160 return this->emitInvalid(
E);
2162 return this->emitConst(
2163 const_cast<ASTContext &
>(ASTCtx).getPointerAuthTypeDiscriminator(
2164 E->getArgumentType()),
2171template <
class Emitter>
2178 return this->discard(
Base);
2182 const auto maybeLoadValue = [&]() ->
bool {
2185 if (std::optional<PrimType>
T = classify(
E))
2186 return this->emitLoadPop(*
T,
E);
2190 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
2194 if (
auto GlobalIndex =
P.getGlobal(VD))
2195 return this->emitGetPtrGlobal(*GlobalIndex,
E) && maybeLoadValue();
2199 if (!isa<FieldDecl>(
Member)) {
2200 if (!this->discard(
Base) && !this->emitSideEffect(
E))
2203 return this->visitDeclRef(
Member,
E);
2207 if (!this->delegate(
Base))
2210 if (!this->visit(
Base))
2215 const auto *FD = cast<FieldDecl>(
Member);
2217 const Record *R = getRecord(RD);
2220 const Record::Field *F = R->
getField(FD);
2222 if (F->Decl->getType()->isReferenceType())
2223 return this->emitGetFieldPop(
PT_Ptr, F->Offset,
E) && maybeLoadValue();
2224 return this->emitGetPtrFieldPop(F->Offset,
E) && maybeLoadValue();
2227template <
class Emitter>
2233 return this->emitConst(*ArrayIndex,
E);
2236template <
class Emitter>
2239 assert(!DiscardResult);
2243 if (!this->discard(
E->getCommonExpr()))
2248 const Expr *SubExpr =
E->getSubExpr();
2249 size_t Size =
E->getArraySize().getZExtValue();
2254 for (
size_t I = 0; I != Size; ++I) {
2258 if (!this->visitArrayElemInit(I, SubExpr))
2266template <
class Emitter>
2268 const Expr *SourceExpr =
E->getSourceExpr();
2273 return this->visitInitializer(SourceExpr);
2276 if (
auto It = OpaqueExprs.find(
E); It != OpaqueExprs.end())
2277 return this->emitGetLocal(SubExprT, It->second,
E);
2279 if (!this->visit(SourceExpr))
2285 unsigned LocalIndex = allocateLocalPrimitive(
E, SubExprT,
true);
2286 if (!this->emitSetLocal(SubExprT, LocalIndex,
E))
2291 if (!DiscardResult) {
2292 if (!this->emitGetLocal(SubExprT, LocalIndex,
E))
2297 OpaqueExprs.insert({
E, LocalIndex});
2302template <
class Emitter>
2306 const Expr *TrueExpr =
E->getTrueExpr();
2307 const Expr *FalseExpr =
E->getFalseExpr();
2309 LabelTy LabelEnd = this->getLabel();
2310 LabelTy LabelFalse = this->getLabel();
2315 if (!this->jumpFalse(LabelFalse))
2320 if (!this->delegate(TrueExpr))
2322 if (!S.destroyLocals())
2326 if (!this->jump(LabelEnd))
2329 this->emitLabel(LabelFalse);
2333 if (!this->delegate(FalseExpr))
2335 if (!S.destroyLocals())
2339 this->fallthrough(LabelEnd);
2340 this->emitLabel(LabelEnd);
2345template <
class Emitter>
2351 unsigned StringIndex =
P.createGlobalString(
E);
2352 return this->emitGetPtrGlobal(StringIndex,
E);
2358 assert(CAT &&
"a string literal that's not a constant array?");
2363 unsigned N = std::min(ArraySize,
E->getLength());
2364 size_t CharWidth =
E->getCharByteWidth();
2366 for (
unsigned I = 0; I != N; ++I) {
2367 uint32_t CodeUnit =
E->getCodeUnit(I);
2369 if (CharWidth == 1) {
2370 this->emitConstSint8(CodeUnit,
E);
2371 this->emitInitElemSint8(I,
E);
2372 }
else if (CharWidth == 2) {
2373 this->emitConstUint16(CodeUnit,
E);
2374 this->emitInitElemUint16(I,
E);
2375 }
else if (CharWidth == 4) {
2376 this->emitConstUint32(CodeUnit,
E);
2377 this->emitInitElemUint32(I,
E);
2379 llvm_unreachable(
"unsupported character width");
2384 for (
unsigned I = N; I != ArraySize; ++I) {
2385 if (CharWidth == 1) {
2386 this->emitConstSint8(0,
E);
2387 this->emitInitElemSint8(I,
E);
2388 }
else if (CharWidth == 2) {
2389 this->emitConstUint16(0,
E);
2390 this->emitInitElemUint16(I,
E);
2391 }
else if (CharWidth == 4) {
2392 this->emitConstUint32(0,
E);
2393 this->emitInitElemUint32(I,
E);
2395 llvm_unreachable(
"unsupported character width");
2402template <
class Emitter>
2406 return this->emitDummyPtr(
E,
E);
2409template <
class Emitter>
2411 auto &A = Ctx.getASTContext();
2417 return this->delegate(SL);
2420template <
class Emitter>
2428 auto &A = Ctx.getASTContext();
2429 std::string ResultStr =
E->ComputeName(A);
2432 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
2433 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
2434 ArraySizeModifier::Normal, 0);
2438 false, ArrayTy,
E->getLocation());
2440 unsigned StringIndex =
P.createGlobalString(SL);
2441 return this->emitGetPtrGlobal(StringIndex,
E);
2444template <
class Emitter>
2448 return this->emitConst(
E->getValue(),
E);
2451template <
class Emitter>
2455 const Expr *LHS =
E->getLHS();
2456 const Expr *RHS =
E->getRHS();
2458 QualType LHSComputationType =
E->getComputationLHSType();
2459 QualType ResultType =
E->getComputationResultType();
2460 std::optional<PrimType>
LT = classify(LHSComputationType);
2461 std::optional<PrimType> RT = classify(ResultType);
2468 PrimType LHST = classifyPrim(LHSType);
2476 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2477 if (!this->emitSetLocal(*RT, TempOffset,
E))
2483 if (!this->emitLoad(LHST,
E))
2487 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
2488 LHSComputationType,
E))
2492 if (!this->emitGetLocal(*RT, TempOffset,
E))
2495 switch (
E->getOpcode()) {
2497 if (!this->emitAddf(getFPOptions(
E),
E))
2501 if (!this->emitSubf(getFPOptions(
E),
E))
2505 if (!this->emitMulf(getFPOptions(
E),
E))
2509 if (!this->emitDivf(getFPOptions(
E),
E))
2516 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->
getType(),
E))
2520 return this->emitStorePop(LHST,
E);
2521 return this->emitStore(LHST,
E);
2524template <
class Emitter>
2528 const Expr *LHS =
E->getLHS();
2529 const Expr *RHS =
E->getRHS();
2530 std::optional<PrimType>
LT = classify(LHS->
getType());
2531 std::optional<PrimType> RT = classify(RHS->
getType());
2533 if (Op != BO_AddAssign && Op != BO_SubAssign)
2542 if (!this->emitLoad(*
LT, LHS))
2548 if (Op == BO_AddAssign) {
2549 if (!this->emitAddOffset(*RT,
E))
2552 if (!this->emitSubOffset(*RT,
E))
2557 return this->emitStorePopPtr(
E);
2558 return this->emitStorePtr(
E);
2561template <
class Emitter>
2565 return VisitVectorBinOp(
E);
2567 const Expr *LHS =
E->getLHS();
2568 const Expr *RHS =
E->getRHS();
2569 std::optional<PrimType> LHSComputationT =
2570 classify(
E->getComputationLHSType());
2571 std::optional<PrimType>
LT = classify(LHS->
getType());
2572 std::optional<PrimType> RT = classify(RHS->
getType());
2573 std::optional<PrimType> ResultT = classify(
E->
getType());
2576 return this->visit(RHS) && this->visit(LHS) && this->emitError(
E);
2578 if (!
LT || !RT || !ResultT || !LHSComputationT)
2585 return VisitFloatCompoundAssignOperator(
E);
2588 return VisitPointerCompoundAssignOperator(
E);
2601 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2603 if (!this->emitSetLocal(*RT, TempOffset,
E))
2610 if (!this->emitLoad(*
LT,
E))
2612 if (
LT != LHSComputationT) {
2613 if (!this->emitCast(*
LT, *LHSComputationT,
E))
2618 if (!this->emitGetLocal(*RT, TempOffset,
E))
2622 switch (
E->getOpcode()) {
2624 if (!this->emitAdd(*LHSComputationT,
E))
2628 if (!this->emitSub(*LHSComputationT,
E))
2632 if (!this->emitMul(*LHSComputationT,
E))
2636 if (!this->emitDiv(*LHSComputationT,
E))
2640 if (!this->emitRem(*LHSComputationT,
E))
2644 if (!this->emitShl(*LHSComputationT, *RT,
E))
2648 if (!this->emitShr(*LHSComputationT, *RT,
E))
2652 if (!this->emitBitAnd(*LHSComputationT,
E))
2656 if (!this->emitBitXor(*LHSComputationT,
E))
2660 if (!this->emitBitOr(*LHSComputationT,
E))
2664 llvm_unreachable(
"Unimplemented compound assign operator");
2668 if (ResultT != LHSComputationT) {
2669 if (!this->emitCast(*LHSComputationT, *ResultT,
E))
2674 if (DiscardResult) {
2676 return this->emitStoreBitFieldPop(*ResultT,
E);
2677 return this->emitStorePop(*ResultT,
E);
2680 return this->emitStoreBitField(*ResultT,
E);
2681 return this->emitStore(*ResultT,
E);
2684template <
class Emitter>
2687 const Expr *SubExpr =
E->getSubExpr();
2692template <
class Emitter>
2695 const Expr *SubExpr =
E->getSubExpr();
2699 return this->delegate(SubExpr);
2704 return this->discard(SubExpr);
2708 std::optional<PrimType> SubExprT = classify(SubExpr);
2711 std::optional<unsigned> GlobalIndex =
P.createGlobal(
E);
2716 E->getLifetimeExtendedTemporaryDecl();
2721 if (!this->visit(SubExpr))
2724 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl,
E))
2727 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex,
E))
2730 return this->emitGetPtrGlobal(*GlobalIndex,
E);
2733 if (!this->checkLiteralType(SubExpr))
2736 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2738 if (!this->visitInitializer(SubExpr))
2741 return this->emitInitGlobalTempComp(TempDecl,
E);
2747 unsigned LocalIndex = allocateLocalPrimitive(
E, *SubExprT,
true,
2749 if (!this->visit(SubExpr))
2751 if (!this->emitSetLocal(*SubExprT, LocalIndex,
E))
2753 return this->emitGetPtrLocal(LocalIndex,
E);
2756 if (!this->checkLiteralType(SubExpr))
2760 if (std::optional<unsigned> LocalIndex =
2761 allocateLocal(
E, Inner->getType(),
E->getExtendingDecl())) {
2763 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2765 return this->visitInitializer(SubExpr) && this->emitFinishInit(
E);
2771template <
class Emitter>
2774 return this->delegate(
E->getSubExpr());
2777template <
class Emitter>
2781 return this->discard(
Init);
2785 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2788 std::optional<PrimType>
T = classify(
E->
getType());
2789 if (
E->isFileScope()) {
2792 return this->delegate(
Init);
2794 if (std::optional<unsigned> GlobalIndex =
P.createGlobal(
E)) {
2795 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2799 if (!this->visit(
Init))
2801 return this->emitInitGlobal(*
T, *GlobalIndex,
E);
2804 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2813 return this->delegate(
Init);
2815 unsigned LocalIndex;
2818 LocalIndex = this->allocateLocalPrimitive(
Init, *
T,
false,
false);
2819 else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(
Init))
2820 LocalIndex = *MaybeIndex;
2824 if (!this->emitGetPtrLocal(LocalIndex,
E))
2828 if (!this->visit(
Init)) {
2831 return this->emitInit(*
T,
E);
2833 if (!this->visitInitializer(
Init) || !this->emitFinishInit(
E))
2842template <
class Emitter>
2847 return this->emitConstBool(
E->getValue(),
E);
2848 return this->emitConst(
E->getValue(),
E);
2851template <
class Emitter>
2855 return this->emitConst(
E->getValue(),
E);
2858template <
class Emitter>
2864 const Record *R =
P.getOrCreateRecord(
E->getLambdaClass());
2866 auto *CaptureInitIt =
E->capture_init_begin();
2869 for (
const Record::Field &F : R->
fields()) {
2876 if (std::optional<PrimType>
T = classify(
Init)) {
2877 if (!this->visit(
Init))
2880 if (!this->emitInitField(*
T, F.Offset,
E))
2883 if (!this->emitGetPtrField(F.Offset,
E))
2886 if (!this->visitInitializer(
Init))
2889 if (!this->emitPopPtr(
E))
2897template <
class Emitter>
2903 unsigned StringIndex =
P.createGlobalString(
E->getFunctionName(),
E);
2904 return this->emitGetPtrGlobal(StringIndex,
E);
2907 return this->delegate(
E->getFunctionName());
2910template <
class Emitter>
2912 if (
E->getSubExpr() && !this->discard(
E->getSubExpr()))
2915 return this->emitInvalid(
E);
2918template <
class Emitter>
2921 const Expr *SubExpr =
E->getSubExpr();
2923 std::optional<PrimType> FromT = classify(SubExpr);
2924 std::optional<PrimType> ToT = classify(
E);
2927 return this->emitInvalidCast(CastKind::Reinterpret,
true,
E);
2931 std::optional<PrimType> PointeeFromT;
2935 PointeeFromT = classify(SubExpr->
getType());
2937 std::optional<PrimType> PointeeToT;
2941 PointeeToT = classify(
E->
getType());
2944 if (PointeeToT && PointeeFromT) {
2949 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal,
E))
2952 if (
E->getCastKind() == CK_LValueBitCast)
2953 return this->delegate(SubExpr);
2954 return this->VisitCastExpr(
E);
2958 bool Fatal = (ToT != FromT);
2959 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal,
E))
2962 return this->VisitCastExpr(
E);
2965template <
class Emitter>
2971 return this->emitConstBool(
E->getValue(),
E);
2974template <
class Emitter>
2977 assert(!classify(
T));
2987 return this->visitInitializer(
E->getArg(0));
2991 if (DiscardResult) {
2995 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3000 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3005 if (
E->requiresZeroInitialization()) {
3008 if (!this->visitZeroRecordInitializer(R,
E))
3021 assert(
Func->hasThisPointer());
3022 assert(!
Func->hasRVO());
3026 if (!this->emitDupPtr(
E))
3030 for (
const auto *Arg :
E->arguments()) {
3031 if (!this->visit(Arg))
3035 if (
Func->isVariadic()) {
3036 uint32_t VarArgSize = 0;
3037 unsigned NumParams =
Func->getNumWrittenParams();
3038 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I) {
3042 if (!this->emitCallVar(
Func, VarArgSize,
E))
3045 if (!this->emitCall(
Func, 0,
E)) {
3050 (void)this->emitPopPtr(
E);
3056 return this->emitPopPtr(
E);
3057 return this->emitFinishInit(
E);
3073 for (
size_t I = 0; I != NumElems; ++I) {
3074 if (!this->emitConstUint64(I,
E))
3076 if (!this->emitArrayElemPtrUint64(
E))
3080 for (
const auto *Arg :
E->arguments()) {
3081 if (!this->visit(Arg))
3085 if (!this->emitCall(
Func, 0,
E))
3094template <
class Emitter>
3100 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
3104 assert(Val.
isInt());
3106 return this->emitConst(I,
E);
3113 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
3114 return this->visit(LValueExpr);
3123 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
3125 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(UGCD);
3129 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
3133 const APValue &
V = UGCD->getValue();
3134 for (
unsigned I = 0, N = R->
getNumFields(); I != N; ++I) {
3135 const Record::Field *F = R->
getField(I);
3136 const APValue &FieldValue =
V.getStructField(I);
3138 PrimType FieldT = classifyPrim(F->Decl->getType());
3140 if (!this->visitAPValue(FieldValue, FieldT,
E))
3142 if (!this->emitInitField(FieldT, F->Offset,
E))
3150template <
class Emitter>
3152 unsigned N =
E->getNumComponents();
3156 for (
unsigned I = 0; I != N; ++I) {
3159 const Expr *ArrayIndexExpr =
E->getIndexExpr(
Node.getArrayExprIndex());
3162 if (DiscardResult) {
3163 if (!this->discard(ArrayIndexExpr))
3168 if (!this->visit(ArrayIndexExpr))
3182 return this->emitOffsetOf(
T,
E,
E);
3185template <
class Emitter>
3193 if (std::optional<PrimType>
T = classify(Ty))
3194 return this->visitZeroInitializer(*
T, Ty,
E);
3198 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3201 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3206 QualType ElemQT = CT->getElementType();
3207 PrimType ElemT = classifyPrim(ElemQT);
3209 for (
unsigned I = 0; I != 2; ++I) {
3210 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
3212 if (!this->emitInitElem(ElemT, I,
E))
3221 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3224 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3229 QualType ElemQT = VT->getElementType();
3230 PrimType ElemT = classifyPrim(ElemQT);
3232 for (
unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
3233 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
3235 if (!this->emitInitElem(ElemT, I,
E))
3244template <
class Emitter>
3246 return this->emitConst(
E->getPackLength(),
E);
3249template <
class Emitter>
3252 return this->delegate(
E->getResultExpr());
3255template <
class Emitter>
3257 return this->delegate(
E->getChosenSubExpr());
3260template <
class Emitter>
3265 return this->emitConst(
E->getValue(),
E);
3268template <
class Emitter>
3273 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
3274 const Function *F = this->getFunction(Ctor);
3291 if (!this->emitGetParam(PT, Offset,
E))
3296 return this->emitCall(F, 0,
E);
3299template <
class Emitter>
3303 QualType ElementType =
E->getAllocatedType();
3304 std::optional<PrimType> ElemT = classify(ElementType);
3305 unsigned PlacementArgs =
E->getNumPlacementArgs();
3307 const Expr *PlacementDest =
nullptr;
3308 bool IsNoThrow =
false;
3310 if (PlacementArgs != 0) {
3319 if (PlacementArgs == 1) {
3320 const Expr *Arg1 =
E->getPlacementArg(0);
3322 if (!this->discard(Arg1))
3327 if (!this->emitInvalidNewDeleteExpr(
E,
E))
3332 if (OperatorNew->isReservedGlobalPlacementOperator())
3333 PlacementDest = Arg1;
3337 return this->emitInvalid(
E);
3339 }
else if (!OperatorNew->isReplaceableGlobalAllocationFunction())
3340 return this->emitInvalidNewDeleteExpr(
E,
E);
3343 if (!PlacementDest) {
3352 Desc =
P.createDescriptor(
3355 false,
false,
false,
Init);
3360 std::optional<const Expr *> ArraySizeExpr =
E->getArraySize();
3364 const Expr *Stripped = *ArraySizeExpr;
3365 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
3366 Stripped = ICE->getSubExpr())
3367 if (ICE->getCastKind() != CK_NoOp &&
3368 ICE->getCastKind() != CK_IntegralCast)
3373 if (PlacementDest) {
3374 if (!this->visit(PlacementDest))
3376 if (!this->visit(Stripped))
3378 if (!this->emitCheckNewTypeMismatchArray(SizeT,
E,
E))
3381 if (!this->visit(Stripped))
3386 if (!this->emitAllocN(SizeT, *ElemT,
E, IsNoThrow,
E))
3390 if (!this->emitAllocCN(SizeT, Desc, IsNoThrow,
E))
3395 if (
Init && !this->visitInitializer(
Init))
3399 if (PlacementDest) {
3400 if (!this->visit(PlacementDest))
3402 if (!this->emitCheckNewTypeMismatch(
E,
E))
3406 if (!this->emitAlloc(Desc,
E))
3412 if (!this->visit(
Init))
3415 if (!this->emitInit(*ElemT,
E))
3419 if (!this->visitInitializer(
Init))
3426 return this->emitPopPtr(
E);
3431template <
class Emitter>
3433 const Expr *Arg =
E->getArgument();
3435 const FunctionDecl *OperatorDelete =
E->getOperatorDelete();
3437 if (!OperatorDelete->isReplaceableGlobalAllocationFunction())
3438 return this->emitInvalidNewDeleteExpr(
E,
E);
3441 if (!this->visit(Arg))
3444 return this->emitFree(
E->isArrayForm(),
E->isGlobalDelete(),
E);
3447template <
class Emitter>
3458 return this->emitGetFnPtr(
Func,
E);
3461template <
class Emitter>
3465 if (!
E->isPotentiallyEvaluated()) {
3469 if (
E->isTypeOperand())
3470 return this->emitGetTypeid(
3471 E->getTypeOperand(Ctx.getASTContext()).getTypePtr(), TypeInfoType,
E);
3477 assert(
E->getExprOperand());
3478 assert(
E->getExprOperand()->
isLValue());
3480 if (!Ctx.
getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(
E))
3483 if (!this->visit(
E->getExprOperand()))
3486 if (!this->emitGetTypeidPtr(TypeInfoType,
E))
3489 return this->emitPopPtr(
E);
3493template <
class Emitter>
3496 return this->emitConstBool(
E->getValue(),
E);
3499template <
class Emitter>
3511 return this->emitDummyPtr(GuidDecl,
E);
3513 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(GuidDecl);
3516 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
3519 assert(this->getRecord(
E->
getType()));
3525 assert(
V.isStruct());
3526 assert(
V.getStructNumBases() == 0);
3527 if (!this->visitAPValueInitializer(
V,
E))
3530 return this->emitFinishInit(
E);
3533template <
class Emitter>
3538 return this->emitConstBool(
E->isSatisfied(),
E);
3541template <
class Emitter>
3547 return this->emitConstBool(
E->isSatisfied(),
E);
3550template <
class Emitter>
3553 return this->delegate(
E->getSemanticForm());
3556template <
class Emitter>
3559 for (
const Expr *SemE :
E->semantics()) {
3560 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
3561 if (SemE ==
E->getResultExpr())
3564 if (OVE->isUnique())
3567 if (!this->discard(OVE))
3569 }
else if (SemE ==
E->getResultExpr()) {
3570 if (!this->delegate(SemE))
3573 if (!this->discard(SemE))
3580template <
class Emitter>
3582 return this->delegate(
E->getSelectedExpr());
3585template <
class Emitter>
3587 return this->emitError(
E);
3590template <
class Emitter>
3594 unsigned Offset = allocateLocalPrimitive(
3595 E->getLabel(),
PT_Ptr,
true,
false);
3597 return this->emitGetLocal(
PT_Ptr, Offset,
E);
3600template <
class Emitter>
3604 QualType ElemType = VT->getElementType();
3605 PrimType ElemT = classifyPrim(ElemType);
3606 const Expr *Src =
E->getSrcExpr();
3608 PrimType SrcElemT = classifyVectorElementType(SrcType);
3610 unsigned SrcOffset = this->allocateLocalPrimitive(Src,
PT_Ptr,
true,
false);
3611 if (!this->visit(Src))
3613 if (!this->emitSetLocal(
PT_Ptr, SrcOffset,
E))
3616 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
3617 if (!this->emitGetLocal(
PT_Ptr, SrcOffset,
E))
3619 if (!this->emitArrayElemPop(SrcElemT, I,
E))
3623 if (SrcElemT != ElemT) {
3624 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType,
E))
3626 }
else if (ElemType->isFloatingType() && SrcType != ElemType) {
3627 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
3631 if (!this->emitInitElem(ElemT, I,
E))
3638template <
class Emitter>
3641 assert(
E->getNumSubExprs() > 2);
3643 const Expr *Vecs[] = {
E->getExpr(0),
E->getExpr(1)};
3647 unsigned NumOutputElems =
E->getNumSubExprs() - 2;
3648 assert(NumOutputElems > 0);
3651 unsigned VectorOffsets[2];
3652 for (
unsigned I = 0; I != 2; ++I) {
3653 VectorOffsets[I] = this->allocateLocalPrimitive(
3654 Vecs[I],
PT_Ptr,
true,
false);
3655 if (!this->visit(Vecs[I]))
3657 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I],
E))
3660 for (
unsigned I = 0; I != NumOutputElems; ++I) {
3661 APSInt ShuffleIndex =
E->getShuffleMaskIdx(Ctx.getASTContext(), I);
3662 assert(ShuffleIndex >= -1);
3663 if (ShuffleIndex == -1)
3664 return this->emitInvalidShuffleVectorIndex(I,
E);
3666 assert(ShuffleIndex < (NumInputElems * 2));
3667 if (!this->emitGetLocal(
PT_Ptr,
3668 VectorOffsets[ShuffleIndex >= NumInputElems],
E))
3670 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
3671 if (!this->emitArrayElemPop(ElemT, InputVectorIndex,
E))
3674 if (!this->emitInitElem(ElemT, I,
E))
3681template <
class Emitter>
3686 Base->getType()->isVectorType() ||
3690 E->getEncodedElementAccess(Indices);
3692 if (Indices.size() == 1) {
3693 if (!this->visit(
Base))
3697 if (!this->emitConstUint32(Indices[0],
E))
3699 return this->emitArrayElemPtrPop(
PT_Uint32,
E);
3702 return this->emitArrayElemPop(classifyPrim(
E->
getType()), Indices[0],
E);
3706 unsigned BaseOffset = allocateLocalPrimitive(
Base,
PT_Ptr,
true,
3708 if (!this->visit(
Base))
3710 if (!this->emitSetLocal(
PT_Ptr, BaseOffset,
E))
3715 std::optional<unsigned> ResultIndex;
3716 ResultIndex = allocateLocal(
E);
3719 if (!this->emitGetPtrLocal(*ResultIndex,
E))
3727 uint32_t DstIndex = 0;
3728 for (uint32_t I : Indices) {
3729 if (!this->emitGetLocal(
PT_Ptr, BaseOffset,
E))
3731 if (!this->emitArrayElemPop(ElemT, I,
E))
3733 if (!this->emitInitElem(ElemT, DstIndex,
E))
3739 assert(!DiscardResult);
3743template <
class Emitter>
3745 const Expr *SubExpr =
E->getSubExpr();
3746 if (!
E->isExpressibleAsConstantInitializer())
3747 return this->discard(SubExpr) && this->emitInvalid(
E);
3752 assert(classifyPrim(
E) ==
PT_Ptr);
3753 return this->emitDummyPtr(
E,
E);
3756template <
class Emitter>
3759 const Expr *SubExpr =
E->getSubExpr();
3766 if (!this->visit(SubExpr))
3768 if (!this->emitConstUint8(0,
E))
3770 if (!this->emitArrayElemPtrPopUint8(
E))
3782 assert(SecondFieldT ==
PT_Ptr);
3786 if (!this->emitExpandPtr(
E))
3790 if (!this->emitArrayElemPtrPop(
PT_Uint64,
E))
3795template <
class Emitter>
3804 if (!this->visitStmt(S))
3809 assert(S == Result);
3810 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
3811 return this->delegate(ResultExpr);
3812 return this->emitUnsupported(
E);
3821 return this->Visit(
E);
3828 return this->Visit(
E);
3836 return this->discard(
E);
3841 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3845 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3848 return this->visitInitializer(
E);
3855 return this->Visit(
E);
3858template <
class Emitter>
3864 return this->Visit(
E);
3868 std::optional<PrimType>
T = classify(
E->
getType());
3872 if (!this->visit(
E))
3874 return this->emitComplexBoolCast(
E);
3879 if (!this->visit(
E))
3887 if (!this->emitNull(*
T, 0,
nullptr,
E))
3889 return this->emitNE(*
T,
E);
3894 return this->emitCastFloatingIntegralBool(getFPOptions(
E),
E);
3900template <
class Emitter>
3905 return this->emitZeroBool(
E);
3907 return this->emitZeroSint8(
E);
3909 return this->emitZeroUint8(
E);
3911 return this->emitZeroSint16(
E);
3913 return this->emitZeroUint16(
E);
3915 return this->emitZeroSint32(
E);
3917 return this->emitZeroUint32(
E);
3919 return this->emitZeroSint64(
E);
3921 return this->emitZeroUint64(
E);
3923 return this->emitZeroIntAP(Ctx.getBitWidth(QT),
E);
3925 return this->emitZeroIntAPS(Ctx.getBitWidth(QT),
E);
3930 return this->emitNullFnPtr(0,
nullptr,
E);
3932 return this->emitNullMemberPtr(0,
nullptr,
E);
3934 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)),
E);
3939 llvm_unreachable(
"Implement");
3941 llvm_unreachable(
"unknown primitive type");
3944template <
class Emitter>
3950 for (
const Record::Field &Field : R->
fields()) {
3951 if (
Field.Decl->isUnnamedBitField())
3955 if (
D->isPrimitive()) {
3958 if (!this->visitZeroInitializer(
T, QT,
E))
3960 if (!this->emitInitField(
T,
Field.Offset,
E))
3967 if (!this->emitGetPtrField(
Field.Offset,
E))
3970 if (
D->isPrimitiveArray()) {
3973 for (uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
3974 if (!this->visitZeroInitializer(
T, ET,
E))
3976 if (!this->emitInitElem(
T, I,
E))
3979 }
else if (
D->isCompositeArray()) {
3981 if (!this->visitZeroArrayInitializer(
D->getType(),
E))
3983 }
else if (
D->isRecord()) {
3984 if (!this->visitZeroRecordInitializer(
D->ElemRecord,
E))
3990 if (!this->emitFinishInitPop(
E))
3999 for (
const Record::Base &B : R->
bases()) {
4000 if (!this->emitGetPtrBase(B.Offset,
E))
4002 if (!this->visitZeroRecordInitializer(B.R,
E))
4004 if (!this->emitFinishInitPop(
E))
4013template <
class Emitter>
4018 size_t NumElems = cast<ConstantArrayType>(AT)->getZExtSize();
4020 if (std::optional<PrimType> ElemT = classify(ElemType)) {
4021 for (
size_t I = 0; I != NumElems; ++I) {
4022 if (!this->visitZeroInitializer(*ElemT, ElemType,
E))
4024 if (!this->emitInitElem(*ElemT, I,
E))
4029 const Record *R = getRecord(ElemType);
4031 for (
size_t I = 0; I != NumElems; ++I) {
4032 if (!this->emitConstUint32(I,
E))
4036 if (!this->visitZeroRecordInitializer(R,
E))
4038 if (!this->emitPopPtr(
E))
4043 for (
size_t I = 0; I != NumElems; ++I) {
4044 if (!this->emitConstUint32(I,
E))
4048 if (!this->visitZeroArrayInitializer(ElemType,
E))
4050 if (!this->emitPopPtr(
E))
4059template <
class Emitter>
4060template <
typename T>
4064 return this->emitConstSint8(
Value,
E);
4066 return this->emitConstUint8(
Value,
E);
4068 return this->emitConstSint16(
Value,
E);
4070 return this->emitConstUint16(
Value,
E);
4072 return this->emitConstSint32(
Value,
E);
4074 return this->emitConstUint32(
Value,
E);
4076 return this->emitConstSint64(
Value,
E);
4078 return this->emitConstUint64(
Value,
E);
4080 return this->emitConstBool(
Value,
E);
4088 llvm_unreachable(
"Invalid integral type");
4091 llvm_unreachable(
"unknown primitive type");
4094template <
class Emitter>
4095template <
typename T>
4100template <
class Emitter>
4104 return this->emitConstIntAPS(
Value,
E);
4106 return this->emitConstIntAP(
Value,
E);
4108 if (
Value.isSigned())
4109 return this->emitConst(
Value.getSExtValue(), Ty,
E);
4110 return this->emitConst(
Value.getZExtValue(), Ty,
E);
4113template <
class Emitter>
4118template <
class Emitter>
4123 if (
const auto *VD =
4124 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4125 assert(!
P.getGlobal(VD));
4126 assert(!Locals.contains(VD));
4134 isa<const Expr *>(Src));
4136 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
4137 Locals.insert({VD, Local});
4138 VarScope->add(Local, IsExtended);
4139 return Local.Offset;
4142template <
class Emitter>
4143std::optional<unsigned>
4147 if ([[maybe_unused]]
const auto *VD =
4148 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4149 assert(!
P.getGlobal(VD));
4150 assert(!Locals.contains(VD));
4155 bool IsTemporary =
false;
4156 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4160 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
4161 Init = VarD->getInit();
4163 if (
auto *
E = Src.dyn_cast<
const Expr *>()) {
4171 IsTemporary,
false,
Init);
4173 return std::nullopt;
4177 Locals.insert({Key, Local});
4179 VarScope->addExtended(Local, ExtendingDecl);
4181 VarScope->add(Local,
false);
4182 return Local.Offset;
4185template <
class Emitter>
4192 true,
false,
nullptr);
4195 return std::nullopt;
4201 while (S->getParent())
4203 assert(S && !S->getParent());
4205 return Local.Offset;
4208template <
class Emitter>
4210 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
4216 if (
const auto *RecordTy = getRecordTy(Ty))
4217 return getRecord(RecordTy->getDecl());
4221template <
class Emitter>
4223 return P.getOrCreateRecord(RD);
4226template <
class Emitter>
4228 return Ctx.getOrCreateFunction(FD);
4231template <
class Emitter>
4236 if (!DestroyToplevelScope) {
4237 if (!this->emitCheckAllocations(
E))
4241 auto maybeDestroyLocals = [&]() ->
bool {
4242 if (DestroyToplevelScope)
4243 return RootScope.
destroyLocals() && this->emitCheckAllocations(
E);
4244 return this->emitCheckAllocations(
E);
4251 return this->emitRetVoid(
E) && maybeDestroyLocals();
4255 if (std::optional<PrimType>
T = classify(
E)) {
4259 return this->emitRet(*
T,
E) && maybeDestroyLocals();
4265 if (std::optional<unsigned> LocalOffset = this->allocateLocal(
E)) {
4267 if (!this->emitGetPtrLocal(*LocalOffset,
E))
4270 if (!visitInitializer(
E))
4273 if (!this->emitFinishInit(
E))
4278 return this->emitRetValue(
E) && maybeDestroyLocals();
4281 return maybeDestroyLocals() && this->emitCheckAllocations(
E) &&
false;
4284template <
class Emitter>
4287 auto R = this->visitVarDecl(VD,
true);
4296 if (
auto GlobalIndex =
P.getGlobal(VD)) {
4297 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
4301 GD.
InitState = GlobalInitState::InitializerFailed;
4312template <
class Emitter>
4314 bool ConstantContext) {
4315 std::optional<PrimType> VarT = classify(VD->
getType());
4319 if (!ConstantContext) {
4324 this->emitCheckAllocations(VD);
4328 if (!this->visitVarDecl(VD,
true))
4332 auto GlobalIndex =
P.getGlobal(VD);
4333 assert(GlobalIndex);
4335 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
4338 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
4342 auto Local = Locals.find(VD);
4343 assert(Local != Locals.end());
4345 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
4348 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
4354 if (!this->emitRet(VarT.value_or(
PT_Ptr), VD)) {
4358 auto GlobalIndex =
P.getGlobal(VD);
4359 assert(GlobalIndex);
4360 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
4364 GD.
InitState = GlobalInitState::InitializerFailed;
4370 return VDScope.
destroyLocals() && this->emitCheckAllocations(VD);
4373template <
class Emitter>
4382 if (!this->isActive())
4386 std::optional<PrimType> VarT = classify(VD->
getType());
4388 if (
Init &&
Init->isValueDependent())
4392 auto checkDecl = [&]() ->
bool {
4394 return !NeedsOp || this->emitCheckDecl(VD, VD);
4397 auto initGlobal = [&](
unsigned GlobalIndex) ->
bool {
4401 if (!this->visit(
Init))
4402 return checkDecl() &&
false;
4404 return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
4410 if (!this->emitGetPtrGlobal(GlobalIndex,
Init))
4413 if (!visitInitializer(
Init))
4416 if (!this->emitFinishInit(
Init))
4419 return this->emitPopPtr(
Init);
4425 if (std::optional<unsigned> GlobalIndex =
P.getGlobal(VD)) {
4426 if (
P.getPtrGlobal(*GlobalIndex).isInitialized())
4431 return Init && checkDecl() && initGlobal(*GlobalIndex);
4434 std::optional<unsigned> GlobalIndex =
P.createGlobal(VD,
Init);
4439 return !
Init || (checkDecl() && initGlobal(*GlobalIndex));
4444 unsigned Offset = this->allocateLocalPrimitive(
4451 if (!this->visit(
Init))
4453 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
4455 if (!this->visit(
Init))
4457 return this->emitSetLocal(*VarT, Offset, VD);
4461 if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
4465 if (!this->emitGetPtrLocal(*Offset,
Init))
4468 if (!visitInitializer(
Init))
4471 if (!this->emitFinishInit(
Init))
4474 return this->emitPopPtr(
Init);
4484template <
class Emitter>
4487 assert(!DiscardResult);
4489 return this->emitConst(Val.
getInt(), ValType,
E);
4491 return this->emitConstFloat(Val.
getFloat(),
E);
4495 return this->emitNull(ValType, 0,
nullptr,
E);
4497 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
4498 return this->visit(BaseExpr);
4499 else if (
const auto *VD =
Base.dyn_cast<
const ValueDecl *>()) {
4500 return this->visitDeclRef(VD,
E);
4504 return this->emitGetMemberPtr(MemberDecl,
E);
4505 return this->emitNullMemberPtr(0,
nullptr,
E);
4511template <
class Emitter>
4520 const Record::Field *RF = R->
getField(I);
4523 PrimType T = classifyPrim(RF->Decl->getType());
4524 if (!this->visitAPValue(F,
T,
E))
4526 if (!this->emitInitField(
T, RF->Offset,
E))
4529 assert(RF->Desc->isPrimitiveArray());
4530 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
4531 PrimType ElemT = classifyPrim(ArrType->getElementType());
4534 if (!this->emitGetPtrField(RF->Offset,
E))
4537 for (
unsigned A = 0, AN = F.
getArraySize(); A != AN; ++A) {
4540 if (!this->emitInitElem(ElemT, A,
E))
4544 if (!this->emitPopPtr(
E))
4547 if (!this->emitGetPtrField(RF->Offset,
E))
4549 if (!this->visitAPValueInitializer(F,
E))
4551 if (!this->emitPopPtr(
E))
4554 assert(
false &&
"I don't think this should be possible");
4563 const Record::Field *RF = R->
getField(UnionField);
4564 PrimType T = classifyPrim(RF->Decl->getType());
4565 if (!this->visitAPValue(F,
T,
E))
4567 return this->emitInitField(
T, RF->Offset,
E);
4574template <
class Emitter>
4576 unsigned BuiltinID) {
4583 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
4584 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
4585 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
4586 BuiltinID == Builtin::BI__builtin_function_start) {
4589 return this->emitDummyPtr(
E,
E);
4593 std::optional<PrimType> ReturnT = classify(
E);
4597 std::optional<unsigned> LocalIndex = allocateLocal(
E);
4600 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4604 if (!
Func->isUnevaluatedBuiltin()) {
4606 for (
const auto *Arg :
E->arguments()) {
4607 if (!this->visit(Arg))
4612 if (!this->emitCallBI(
Func,
E, BuiltinID,
E))
4615 if (DiscardResult && !ReturnType->
isVoidType()) {
4617 return this->emitPop(*ReturnT,
E);
4623template <
class Emitter>
4625 if (
unsigned BuiltinID =
E->getBuiltinCallee())
4626 return VisitBuiltinCallExpr(
E, BuiltinID);
4633 return VisitBuiltinCallExpr(
E, Builtin::BI__builtin_operator_new);
4636 return VisitBuiltinCallExpr(
E, Builtin::BI__builtin_operator_delete);
4640 if (
const auto *DD = dyn_cast_if_present<CXXDestructorDecl>(FuncDecl);
4641 DD && DD->isTrivial())
4644 QualType ReturnType =
E->getCallReturnType(Ctx.getASTContext());
4645 std::optional<PrimType>
T = classify(ReturnType);
4649 if (DiscardResult) {
4653 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4654 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4661 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4662 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4666 if (!this->emitDupPtr(
E))
4674 bool IsAssignmentOperatorCall =
false;
4675 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
4676 OCE && OCE->isAssignmentOp()) {
4680 assert(Args.size() == 2);
4681 IsAssignmentOperatorCall =
true;
4682 std::reverse(Args.begin(), Args.end());
4687 if (isa<CXXOperatorCallExpr>(
E)) {
4688 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
4689 MD && MD->isStatic()) {
4690 if (!this->discard(
E->getArg(0)))
4693 Args.erase(Args.begin());
4697 std::optional<unsigned> CalleeOffset;
4699 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(
E)) {
4700 if (!FuncDecl && classifyPrim(
E->getCallee()) ==
PT_MemberPtr) {
4704 const Expr *Callee =
E->getCallee();
4706 this->allocateLocalPrimitive(Callee,
PT_MemberPtr,
true,
false);
4707 if (!this->visit(Callee))
4713 if (!this->emitGetMemberPtrBase(
E))
4715 }
else if (!this->visit(MC->getImplicitObjectArgument())) {
4718 }
else if (!FuncDecl) {
4719 const Expr *Callee =
E->getCallee();
4720 CalleeOffset = this->allocateLocalPrimitive(Callee,
PT_FnPtr,
true,
false);
4721 if (!this->visit(Callee))
4723 if (!this->emitSetLocal(
PT_FnPtr, *CalleeOffset,
E))
4729 unsigned ArgIndex = 0;
4730 for (
const auto *Arg : Args) {
4731 if (!this->visit(Arg))
4735 if (FuncDecl && NonNullArgs[ArgIndex]) {
4738 if (!this->emitCheckNonNullArg(ArgT, Arg))
4746 if (IsAssignmentOperatorCall) {
4747 assert(Args.size() == 2);
4750 if (!this->emitFlip(Arg2T, Arg1T,
E))
4758 assert(HasRVO ==
Func->hasRVO());
4760 bool HasQualifier =
false;
4761 if (
const auto *ME = dyn_cast<MemberExpr>(
E->getCallee()))
4762 HasQualifier = ME->hasQualifier();
4764 bool IsVirtual =
false;
4765 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
4766 IsVirtual = MD->isVirtual();
4771 if (IsVirtual && !HasQualifier) {
4772 uint32_t VarArgSize = 0;
4773 unsigned NumParams =
4774 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4775 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4778 if (!this->emitCallVirt(
Func, VarArgSize,
E))
4780 }
else if (
Func->isVariadic()) {
4781 uint32_t VarArgSize = 0;
4782 unsigned NumParams =
4783 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4784 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4786 if (!this->emitCallVar(
Func, VarArgSize,
E))
4789 if (!this->emitCall(
Func, 0,
E))
4798 uint32_t ArgSize = 0;
4799 for (
unsigned I = 0, N =
E->getNumArgs(); I != N; ++I)
4804 if (isa<CXXMemberCallExpr>(
E) && CalleeOffset) {
4807 if (!this->emitGetMemberPtrDecl(
E))
4810 if (!this->emitGetLocal(
PT_FnPtr, *CalleeOffset,
E))
4813 if (!this->emitCallPtr(ArgSize,
E,
E))
4818 if (DiscardResult && !ReturnType->
isVoidType() &&
T)
4819 return this->emitPop(*
T,
E);
4824template <
class Emitter>
4828 return this->delegate(
E->getExpr());
4831template <
class Emitter>
4835 return this->delegate(
E->getExpr());
4838template <
class Emitter>
4843 return this->emitConstBool(
E->getValue(),
E);
4846template <
class Emitter>
4853 return this->emitNullPtr(Val,
nullptr,
E);
4856template <
class Emitter>
4864 return this->emitZero(
T,
E);
4867template <
class Emitter>
4872 if (this->LambdaThisCapture.Offset > 0) {
4873 if (this->LambdaThisCapture.IsPtr)
4874 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset,
E);
4875 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset,
E);
4882 if (!InitStackActive)
4883 return this->emitThis(
E);
4885 if (!InitStack.empty()) {
4899 unsigned StartIndex = 0;
4900 unsigned EndIndex = 0;
4902 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
4905 EndIndex = StartIndex;
4912 for (; StartIndex > 0; --StartIndex) {
4922 for (
unsigned I = StartIndex; I != EndIndex; ++I) {
4925 if (!InitStack[I].
template emit<Emitter>(
this,
E))
4930 return this->emitThis(
E);
4934 switch (S->getStmtClass()) {
4935 case Stmt::CompoundStmtClass:
4936 return visitCompoundStmt(cast<CompoundStmt>(S));
4937 case Stmt::DeclStmtClass:
4938 return visitDeclStmt(cast<DeclStmt>(S));
4939 case Stmt::ReturnStmtClass:
4940 return visitReturnStmt(cast<ReturnStmt>(S));
4941 case Stmt::IfStmtClass:
4942 return visitIfStmt(cast<IfStmt>(S));
4943 case Stmt::WhileStmtClass:
4944 return visitWhileStmt(cast<WhileStmt>(S));
4945 case Stmt::DoStmtClass:
4946 return visitDoStmt(cast<DoStmt>(S));
4947 case Stmt::ForStmtClass:
4948 return visitForStmt(cast<ForStmt>(S));
4949 case Stmt::CXXForRangeStmtClass:
4950 return visitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
4951 case Stmt::BreakStmtClass:
4952 return visitBreakStmt(cast<BreakStmt>(S));
4953 case Stmt::ContinueStmtClass:
4954 return visitContinueStmt(cast<ContinueStmt>(S));
4955 case Stmt::SwitchStmtClass:
4956 return visitSwitchStmt(cast<SwitchStmt>(S));
4957 case Stmt::CaseStmtClass:
4958 return visitCaseStmt(cast<CaseStmt>(S));
4959 case Stmt::DefaultStmtClass:
4960 return visitDefaultStmt(cast<DefaultStmt>(S));
4961 case Stmt::AttributedStmtClass:
4962 return visitAttributedStmt(cast<AttributedStmt>(S));
4963 case Stmt::CXXTryStmtClass:
4964 return visitCXXTryStmt(cast<CXXTryStmt>(S));
4965 case Stmt::NullStmtClass:
4968 case Stmt::GCCAsmStmtClass:
4969 case Stmt::MSAsmStmtClass:
4970 case Stmt::GotoStmtClass:
4971 return this->emitInvalid(S);
4972 case Stmt::LabelStmtClass:
4973 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
4975 if (
const auto *
E = dyn_cast<Expr>(S))
4976 return this->discard(
E);
4982template <
class Emitter>
4985 for (
const auto *InnerStmt : S->body())
4986 if (!visitStmt(InnerStmt))
4988 return Scope.destroyLocals();
4991template <
class Emitter>
4993 for (
const auto *
D : DS->
decls()) {
4998 const auto *VD = dyn_cast<VarDecl>(
D);
5001 if (!this->visitVarDecl(VD))
5005 if (
const auto *DD = dyn_cast<DecompositionDecl>(VD)) {
5006 for (
auto *BD : DD->bindings())
5007 if (
auto *KD = BD->getHoldingVar()) {
5008 if (!this->visitVarDecl(KD))
5017template <
class Emitter>
5019 if (this->InStmtExpr)
5020 return this->emitUnsupported(RS);
5026 if (!this->visit(RE))
5028 this->emitCleanup();
5029 return this->emitRet(*ReturnType, RS);
5030 }
else if (RE->getType()->isVoidType()) {
5031 if (!this->visit(RE))
5036 if (!this->emitRVOPtr(RE))
5038 if (!this->visitInitializer(RE))
5040 if (!this->emitPopPtr(RE))
5043 this->emitCleanup();
5044 return this->emitRetVoid(RS);
5049 this->emitCleanup();
5050 return this->emitRetVoid(RS);
5054 if (
auto *CondInit = IS->
getInit())
5055 if (!visitStmt(CondInit))
5059 if (!visitDeclStmt(CondDecl))
5064 if (!this->emitIsConstantContext(IS))
5067 if (!this->emitIsConstantContext(IS))
5069 if (!this->emitInv(IS))
5072 if (!this->visitBool(IS->
getCond()))
5077 LabelTy LabelElse = this->getLabel();
5078 LabelTy LabelEnd = this->getLabel();
5079 if (!this->jumpFalse(LabelElse))
5083 if (!visitStmt(IS->
getThen()))
5088 if (!this->jump(LabelEnd))
5090 this->emitLabel(LabelElse);
5093 if (!visitStmt(Else))
5098 this->emitLabel(LabelEnd);
5100 LabelTy LabelEnd = this->getLabel();
5101 if (!this->jumpFalse(LabelEnd))
5105 if (!visitStmt(IS->
getThen()))
5110 this->emitLabel(LabelEnd);
5116template <
class Emitter>
5118 const Expr *Cond = S->getCond();
5119 const Stmt *Body = S->getBody();
5121 LabelTy CondLabel = this->getLabel();
5122 LabelTy EndLabel = this->getLabel();
5125 this->fallthrough(CondLabel);
5126 this->emitLabel(CondLabel);
5130 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5131 if (!visitDeclStmt(CondDecl))
5134 if (!this->visitBool(Cond))
5136 if (!this->jumpFalse(EndLabel))
5139 if (!this->visitStmt(Body))
5145 if (!this->jump(CondLabel))
5147 this->fallthrough(EndLabel);
5148 this->emitLabel(EndLabel);
5154 const Expr *Cond = S->getCond();
5155 const Stmt *Body = S->getBody();
5157 LabelTy StartLabel = this->getLabel();
5158 LabelTy EndLabel = this->getLabel();
5159 LabelTy CondLabel = this->getLabel();
5162 this->fallthrough(StartLabel);
5163 this->emitLabel(StartLabel);
5167 if (!this->visitStmt(Body))
5169 this->fallthrough(CondLabel);
5170 this->emitLabel(CondLabel);
5171 if (!this->visitBool(Cond))
5177 if (!this->jumpTrue(StartLabel))
5180 this->fallthrough(EndLabel);
5181 this->emitLabel(EndLabel);
5185template <
class Emitter>
5189 const Expr *Cond = S->getCond();
5190 const Expr *
Inc = S->getInc();
5191 const Stmt *Body = S->getBody();
5193 LabelTy EndLabel = this->getLabel();
5194 LabelTy CondLabel = this->getLabel();
5195 LabelTy IncLabel = this->getLabel();
5198 if (
Init && !this->visitStmt(
Init))
5201 this->fallthrough(CondLabel);
5202 this->emitLabel(CondLabel);
5206 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5207 if (!visitDeclStmt(CondDecl))
5211 if (!this->visitBool(Cond))
5213 if (!this->jumpFalse(EndLabel))
5217 if (Body && !this->visitStmt(Body))
5220 this->fallthrough(IncLabel);
5221 this->emitLabel(IncLabel);
5222 if (
Inc && !this->discard(
Inc))
5228 if (!this->jump(CondLabel))
5231 this->fallthrough(EndLabel);
5232 this->emitLabel(EndLabel);
5236template <
class Emitter>
5239 const Expr *Cond = S->getCond();
5240 const Expr *
Inc = S->getInc();
5241 const Stmt *Body = S->getBody();
5242 const Stmt *BeginStmt = S->getBeginStmt();
5243 const Stmt *RangeStmt = S->getRangeStmt();
5244 const Stmt *EndStmt = S->getEndStmt();
5245 const VarDecl *LoopVar = S->getLoopVariable();
5247 LabelTy EndLabel = this->getLabel();
5248 LabelTy CondLabel = this->getLabel();
5249 LabelTy IncLabel = this->getLabel();
5253 if (
Init && !this->visitStmt(
Init))
5255 if (!this->visitStmt(RangeStmt))
5257 if (!this->visitStmt(BeginStmt))
5259 if (!this->visitStmt(EndStmt))
5263 this->fallthrough(CondLabel);
5264 this->emitLabel(CondLabel);
5265 if (!this->visitBool(Cond))
5267 if (!this->jumpFalse(EndLabel))
5270 if (!this->visitVarDecl(LoopVar))
5275 if (!this->visitStmt(Body))
5278 this->fallthrough(IncLabel);
5279 this->emitLabel(IncLabel);
5280 if (!this->discard(
Inc))
5284 if (!this->jump(CondLabel))
5287 this->fallthrough(EndLabel);
5288 this->emitLabel(EndLabel);
5292template <
class Emitter>
5299 C->emitDestruction();
5300 return this->jump(*BreakLabel);
5303template <
class Emitter>
5309 C &&
C->getParent() != ContinueVarScope;
C =
C->getParent())
5310 C->emitDestruction();
5311 return this->jump(*ContinueLabel);
5314template <
class Emitter>
5316 const Expr *Cond = S->getCond();
5320 LabelTy EndLabel = this->getLabel();
5322 unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT,
true,
false);
5324 if (
const auto *CondInit = S->getInit())
5325 if (!visitStmt(CondInit))
5328 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5329 if (!visitDeclStmt(CondDecl))
5333 if (!this->visit(Cond))
5335 if (!this->emitSetLocal(CondT, CondVar, S))
5340 for (
const SwitchCase *SC = S->getSwitchCaseList(); SC;
5341 SC = SC->getNextSwitchCase()) {
5342 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
5344 if (CS->caseStmtIsGNURange())
5346 CaseLabels[SC] = this->getLabel();
5352 if (!this->emitGetLocal(CondT, CondVar, CS))
5354 if (!this->visit(
Value))
5358 if (!this->emitEQ(ValueT, S))
5360 if (!this->jumpTrue(CaseLabels[CS]))
5363 assert(!DefaultLabel);
5364 DefaultLabel = this->getLabel();
5371 if (!this->jump(*DefaultLabel))
5374 if (!this->jump(EndLabel))
5379 if (!this->visitStmt(S->getBody()))
5381 this->emitLabel(EndLabel);
5386template <
class Emitter>
5388 this->emitLabel(CaseLabels[S]);
5389 return this->visitStmt(S->getSubStmt());
5392template <
class Emitter>
5394 this->emitLabel(*DefaultLabel);
5395 return this->visitStmt(S->getSubStmt());
5398template <
class Emitter>
5401 !this->Ctx.getLangOpts().MSVCCompat) {
5402 for (
const Attr *A : S->getAttrs()) {
5403 auto *AA = dyn_cast<CXXAssumeAttr>(A);
5407 assert(isa<NullStmt>(S->getSubStmt()));
5409 const Expr *Assumption = AA->getAssumption();
5417 if (!this->visitBool(Assumption))
5420 if (!this->emitAssume(Assumption))
5426 return this->visitStmt(S->getSubStmt());
5429template <
class Emitter>
5432 return this->visitStmt(S->getTryBlock());
5435template <
class Emitter>
5439 assert(cast<CompoundStmt>(MD->
getBody())->body_empty());
5444 const Function *
Func = this->getFunction(LambdaCallOp);
5447 assert(
Func->hasThisPointer());
5450 if (
Func->hasRVO()) {
5451 if (!this->emitRVOPtr(MD))
5459 if (!this->emitNullPtr(0,
nullptr, MD))
5464 auto It = this->Params.find(PVD);
5465 assert(It != this->Params.end());
5469 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
5470 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
5474 if (!this->emitCall(
Func, 0, LambdaCallOp))
5477 this->emitCleanup();
5479 return this->emitRet(*ReturnType, MD);
5482 return this->emitRetVoid(MD);
5485template <
class Emitter>
5496template <
class Emitter>
5498 assert(!ReturnType);
5500 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
5501 const Expr *InitExpr) ->
bool {
5503 if (InitExpr->getType().isNull())
5506 if (std::optional<PrimType>
T = this->classify(InitExpr)) {
5507 if (!this->visit(InitExpr))
5510 if (F->isBitField())
5511 return this->emitInitThisBitField(*
T, F, FieldOffset, InitExpr);
5512 return this->emitInitThisField(*
T, FieldOffset, InitExpr);
5517 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
5520 if (!this->visitInitializer(InitExpr))
5523 return this->emitFinishInitPop(InitExpr);
5527 const Record *R = this->getRecord(RD);
5533 assert(cast<CompoundStmt>(Ctor->
getBody())->body_empty());
5534 if (!this->emitThis(Ctor))
5543 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
5544 this->emitRetVoid(Ctor);
5548 for (
const auto *
Init : Ctor->
inits()) {
5552 const Expr *InitExpr =
Init->getInit();
5556 if (!emitFieldInitializer(F, F->Offset, InitExpr))
5559 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
5562 if (
Init->isBaseVirtual()) {
5564 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
5570 const Record::Base *B = R->
getBase(BaseDecl);
5572 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
5576 if (!this->visitInitializer(InitExpr))
5578 if (!this->emitFinishInitPop(InitExpr))
5581 assert(IFD->getChainingSize() >= 2);
5583 unsigned NestedFieldOffset = 0;
5584 const Record::Field *NestedField =
nullptr;
5585 for (
const NamedDecl *ND : IFD->chain()) {
5586 const auto *FD = cast<FieldDecl>(ND);
5587 const Record *FieldRecord = this->
P.getOrCreateRecord(FD->getParent());
5588 assert(FieldRecord);
5590 NestedField = FieldRecord->
getField(FD);
5591 assert(NestedField);
5593 NestedFieldOffset += NestedField->Offset;
5595 assert(NestedField);
5597 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
5600 assert(
Init->isDelegatingInitializer());
5601 if (!this->emitThis(InitExpr))
5603 if (!this->visitInitializer(
Init->getInit()))
5605 if (!this->emitPopPtr(InitExpr))
5609 if (!
Scope.destroyLocals())
5613 if (
const auto *Body = Ctor->
getBody())
5614 if (!visitStmt(Body))
5620template <
class Emitter>
5623 const Record *R = this->getRecord(RD);
5628 if (!this->visitStmt(Dtor->
getBody()))
5632 if (!this->emitThis(Dtor))
5638 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
5640 if (!
D->isPrimitive() && !
D->isPrimitiveArray()) {
5651 for (
const Record::Base &
Base : llvm::reverse(R->
bases())) {
5652 if (
Base.R->isAnonymousUnion())
5657 if (!this->emitRecordDestruction(
Base.R, {}))
5664 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
5667template <
class Emitter>
5670 if (!this->emitThis(MD))
5679 return this->emitMemcpy(MD) && this->emitRet(
PT_Ptr, MD);
5682template <
class Emitter>
5687 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
5688 return this->compileConstructor(Ctor);
5689 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
5690 return this->compileDestructor(Dtor);
5693 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
5698 return this->compileUnionAssignmentOperator(MD);
5701 return this->emitLambdaStaticInvokerBody(MD);
5705 if (
const auto *Body = F->
getBody())
5706 if (!visitStmt(Body))
5715template <
class Emitter>
5717 const Expr *SubExpr =
E->getSubExpr();
5719 return this->VisitComplexUnaryOperator(
E);
5721 return this->VisitVectorUnaryOperator(
E);
5723 return this->VisitFixedPointUnaryOperator(
E);
5724 std::optional<PrimType>
T = classify(SubExpr->
getType());
5726 switch (
E->getOpcode()) {
5729 return this->emitInvalid(
E);
5731 return this->emitError(
E);
5733 if (!this->visit(SubExpr))
5737 if (!this->emitIncPtr(
E))
5740 return DiscardResult ? this->emitPopPtr(
E) :
true;
5744 return DiscardResult ? this->emitIncfPop(getFPOptions(
E),
E)
5745 : this->emitIncf(getFPOptions(
E),
E);
5748 return DiscardResult ? this->emitIncPop(*
T,
E) : this->emitInc(*
T,
E);
5752 return this->emitInvalid(
E);
5754 return this->emitError(
E);
5756 if (!this->visit(SubExpr))
5760 if (!this->emitDecPtr(
E))
5763 return DiscardResult ? this->emitPopPtr(
E) :
true;
5767 return DiscardResult ? this->emitDecfPop(getFPOptions(
E),
E)
5768 : this->emitDecf(getFPOptions(
E),
E);
5771 return DiscardResult ? this->emitDecPop(*
T,
E) : this->emitDec(*
T,
E);
5775 return this->emitInvalid(
E);
5777 return this->emitError(
E);
5779 if (!this->visit(SubExpr))
5783 if (!this->emitLoadPtr(
E))
5785 if (!this->emitConstUint8(1,
E))
5787 if (!this->emitAddOffsetUint8(
E))
5789 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5793 if (DiscardResult) {
5795 return this->emitIncfPop(getFPOptions(
E),
E);
5796 return this->emitIncPop(*
T,
E);
5800 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5801 if (!this->emitLoadFloat(
E))
5803 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5805 if (!this->emitAddf(getFPOptions(
E),
E))
5807 if (!this->emitStoreFloat(
E))
5811 if (!this->emitLoad(*
T,
E))
5813 if (!this->emitConst(1,
E))
5815 if (!this->emitAdd(*
T,
E))
5817 if (!this->emitStore(*
T,
E))
5824 return this->emitInvalid(
E);
5826 return this->emitError(
E);
5828 if (!this->visit(SubExpr))
5832 if (!this->emitLoadPtr(
E))
5834 if (!this->emitConstUint8(1,
E))
5836 if (!this->emitSubOffsetUint8(
E))
5838 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5842 if (DiscardResult) {
5844 return this->emitDecfPop(getFPOptions(
E),
E);
5845 return this->emitDecPop(*
T,
E);
5849 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5850 if (!this->emitLoadFloat(
E))
5852 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5854 if (!this->emitSubf(getFPOptions(
E),
E))
5856 if (!this->emitStoreFloat(
E))
5860 if (!this->emitLoad(*
T,
E))
5862 if (!this->emitConst(1,
E))
5864 if (!this->emitSub(*
T,
E))
5866 if (!this->emitStore(*
T,
E))
5873 return this->emitError(
E);
5876 return this->discard(SubExpr);
5878 if (!this->visitBool(SubExpr))
5881 if (!this->emitInv(
E))
5885 return this->emitCast(
PT_Bool, ET,
E);
5889 return this->emitError(
E);
5891 if (!this->visit(SubExpr))
5893 return DiscardResult ? this->emitPop(*
T,
E) : this->emitNeg(*
T,
E);
5896 return this->emitError(
E);
5898 if (!this->visit(SubExpr))
5900 return DiscardResult ? this->emitPop(*
T,
E) :
true;
5905 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(),
E);
5908 return this->delegate(SubExpr);
5910 if (DiscardResult) {
5912 return this->discard(SubExpr);
5915 if (!this->visit(SubExpr))
5917 if (classifyPrim(SubExpr) ==
PT_Ptr)
5918 return this->emitNarrowPtr(
E);
5923 return this->emitError(
E);
5925 if (!this->visit(SubExpr))
5927 return DiscardResult ? this->emitPop(*
T,
E) : this->emitComp(*
T,
E);
5930 return this->delegate(SubExpr);
5933 if (!this->discard(SubExpr))
5935 return this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
5938 return this->delegate(SubExpr);
5940 assert(
false &&
"Unhandled opcode");
5946template <
class Emitter>
5948 const Expr *SubExpr =
E->getSubExpr();
5952 return this->discard(SubExpr);
5954 std::optional<PrimType> ResT = classify(
E);
5955 auto prepareResult = [=]() ->
bool {
5957 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5960 return this->emitGetPtrLocal(*LocalIndex,
E);
5967 unsigned SubExprOffset = ~0u;
5968 auto createTemp = [=, &SubExprOffset]() ->
bool {
5969 SubExprOffset = this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
5970 if (!this->visit(SubExpr))
5972 return this->emitSetLocal(
PT_Ptr, SubExprOffset,
E);
5976 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
5977 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
5979 return this->emitArrayElemPop(ElemT, Index,
E);
5982 switch (
E->getOpcode()) {
5984 if (!prepareResult())
5988 for (
unsigned I = 0; I != 2; ++I) {
5989 if (!getElem(SubExprOffset, I))
5991 if (!this->emitNeg(ElemT,
E))
5993 if (!this->emitInitElem(ElemT, I,
E))
6001 return this->delegate(SubExpr);
6004 if (!this->visit(SubExpr))
6006 if (!this->emitComplexBoolCast(SubExpr))
6008 if (!this->emitInv(
E))
6011 return this->emitCast(
PT_Bool, ET,
E);
6015 return this->emitComplexReal(SubExpr);
6018 if (!this->visit(SubExpr))
6022 if (!this->emitConstUint8(1,
E))
6024 return this->emitArrayElemPtrPopUint8(
E);
6029 return this->emitArrayElemPop(classifyPrim(
E->
getType()), 1,
E);
6032 if (!this->visit(SubExpr))
6035 if (!this->emitArrayElem(ElemT, 1,
E))
6037 if (!this->emitNeg(ElemT,
E))
6039 if (!this->emitInitElem(ElemT, 1,
E))
6041 return DiscardResult ? this->emitPopPtr(
E) :
true;
6044 return this->delegate(SubExpr);
6047 return this->emitInvalid(
E);
6053template <
class Emitter>
6055 const Expr *SubExpr =
E->getSubExpr();
6059 return this->discard(SubExpr);
6061 auto UnaryOp =
E->getOpcode();
6062 if (UnaryOp == UO_Extension)
6063 return this->delegate(SubExpr);
6065 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
6066 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
6067 return this->emitInvalid(
E);
6070 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
6071 return this->delegate(SubExpr);
6074 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
6077 if (!this->emitGetPtrLocal(*LocalIndex,
E))
6082 unsigned SubExprOffset =
6083 this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
6084 if (!this->visit(SubExpr))
6086 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset,
E))
6091 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
6092 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
6094 return this->emitArrayElemPop(ElemT, Index,
E);
6099 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6100 if (!getElem(SubExprOffset, I))
6102 if (!this->emitNeg(ElemT,
E))
6104 if (!this->emitInitElem(ElemT, I,
E))
6119 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6120 if (!getElem(SubExprOffset, I))
6123 if (!this->emitPrimCast(ElemT,
PT_Bool, Ctx.getASTContext().
BoolTy,
E))
6125 if (!this->emitInv(
E))
6127 if (!this->emitPrimCast(
PT_Bool, ElemT, VecTy->getElementType(),
E))
6129 if (!this->emitNeg(ElemT,
E))
6131 if (ElemT != ResultVecElemT &&
6132 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy,
E))
6134 if (!this->emitInitElem(ResultVecElemT, I,
E))
6140 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6141 if (!getElem(SubExprOffset, I))
6144 if (!this->emitInv(
E))
6147 if (!this->emitComp(ElemT,
E))
6150 if (!this->emitInitElem(ElemT, I,
E))
6155 llvm_unreachable(
"Unsupported unary operators should be handled up front");
6160template <
class Emitter>
6165 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(
D)) {
6166 return this->emitConst(ECD->getInitVal(),
E);
6167 }
else if (
const auto *BD = dyn_cast<BindingDecl>(
D)) {
6168 return this->visit(BD->getBinding());
6169 }
else if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(
D)) {
6170 const Function *F = getFunction(FuncDecl);
6171 return F && this->emitGetFnPtr(F,
E);
6172 }
else if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(
D)) {
6173 if (std::optional<unsigned> Index =
P.getOrCreateGlobal(
D)) {
6174 if (!this->emitGetPtrGlobal(*Index,
E))
6176 if (std::optional<PrimType>
T = classify(
E->
getType())) {
6177 if (!this->visitAPValue(TPOD->getValue(), *
T,
E))
6179 return this->emitInitGlobal(*
T, *Index,
E);
6181 return this->visitAPValueInitializer(TPOD->getValue(),
E);
6190 bool IsReference =
D->getType()->isReferenceType();
6193 if (
auto It = Locals.find(
D); It != Locals.end()) {
6194 const unsigned Offset = It->second.Offset;
6196 return this->emitGetLocal(
PT_Ptr, Offset,
E);
6197 return this->emitGetPtrLocal(Offset,
E);
6198 }
else if (
auto GlobalIndex =
P.getGlobal(
D)) {
6201 return this->emitGetGlobal(classifyPrim(
E), *GlobalIndex,
E);
6202 return this->emitGetGlobalUnchecked(classifyPrim(
E), *GlobalIndex,
E);
6205 return this->emitGetPtrGlobal(*GlobalIndex,
E);
6206 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(
D)) {
6207 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
6208 if (IsReference || !It->second.IsPtr)
6209 return this->emitGetParam(classifyPrim(
E), It->second.Offset,
E);
6211 return this->emitGetPtrParam(It->second.Offset,
E);
6214 if (
D->getType()->isReferenceType())
6215 return this->emitDummyPtr(
D,
E);
6219 auto revisit = [&](
const VarDecl *VD) ->
bool {
6220 auto VarState = this->visitDecl(VD);
6222 if (VarState.notCreated())
6227 return this->visitDeclRef(
D,
E);
6231 if (
auto It = this->LambdaCaptures.find(
D);
6232 It != this->LambdaCaptures.end()) {
6233 auto [Offset, IsPtr] = It->second;
6236 return this->emitGetThisFieldPtr(Offset,
E);
6237 return this->emitGetPtrThisField(Offset,
E);
6238 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E);
6239 DRE && DRE->refersToEnclosingVariableOrCapture()) {
6240 if (
const auto *VD = dyn_cast<VarDecl>(
D); VD && VD->isInitCapture())
6245 if (
D == InitializingDecl)
6246 return this->emitDummyPtr(
D,
E);
6252 if (
const auto *VD = dyn_cast<VarDecl>(
D);
6253 VD && VD->getAnyInitializer() &&
6254 VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak())
6256 return this->emitDummyPtr(
D,
E);
6260 const auto *VD = dyn_cast<VarDecl>(
D);
6262 return this->emitDummyPtr(
D,
E);
6264 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
6265 if (
T.isConstant(Ctx.getASTContext()))
6271 if (isa<DecompositionDecl>(VD))
6274 if ((VD->hasGlobalStorage() || VD->isStaticDataMember()) &&
6275 typeShouldBeVisited(VD->getType())) {
6276 if (
const Expr *
Init = VD->getAnyInitializer();
6277 Init && !
Init->isValueDependent()) {
6283 (void)
Init->EvaluateAsInitializer(
V, Ctx.getASTContext(), VD, Notes,
6285 return this->visitDeclRef(
D,
E);
6294 if (VD->isLocalVarDecl() && typeShouldBeVisited(VD->getType()) &&
6295 VD->getInit() && !VD->getInit()->isValueDependent()) {
6297 if (VD->evaluateValue())
6300 if (!
D->getType()->isReferenceType())
6301 return this->emitDummyPtr(
D,
E);
6303 return this->emitInvalidDeclRef(cast<DeclRefExpr>(
E),
6307 return this->emitDummyPtr(
D,
E);
6310template <
class Emitter>
6312 const auto *
D =
E->getDecl();
6313 return this->visitDeclRef(
D,
E);
6318 C->emitDestruction();
6321template <
class Emitter>
6325 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
6327 return Ty->getAsCXXRecordDecl();
6329 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
6330 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
6332 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
6336template <
class Emitter>
6343 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6348 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
6349 getFPOptions(
E),
E);
6351 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
6352 getFPOptions(
E),
E);
6356 return this->emitCastFloatingIntegral(ToT, getFPOptions(
E),
E);
6361 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT),
E);
6363 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT),
E);
6367 return FromT != ToT ? this->emitCast(FromT, ToT,
E) :
true;
6371 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6372 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(
E),
E);
6380template <
class Emitter>
6385 return this->discard(SubExpr);
6387 if (!this->visit(SubExpr))
6390 if (!this->emitConstUint8(0, SubExpr))
6392 return this->emitArrayElemPtrPopUint8(SubExpr);
6396 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
6400template <
class Emitter>
6402 assert(!DiscardResult);
6406 if (!this->emitArrayElem(ElemT, 0,
E))
6409 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(
E),
E))
6412 if (!this->emitCast(ElemT,
PT_Bool,
E))
6417 LabelTy LabelTrue = this->getLabel();
6418 if (!this->jumpTrue(LabelTrue))
6421 if (!this->emitArrayElemPop(ElemT, 1,
E))
6424 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(
E),
E))
6427 if (!this->emitCast(ElemT,
PT_Bool,
E))
6431 LabelTy EndLabel = this->getLabel();
6432 this->jump(EndLabel);
6434 this->emitLabel(LabelTrue);
6435 if (!this->emitPopPtr(
E))
6437 if (!this->emitConstBool(
true,
E))
6440 this->fallthrough(EndLabel);
6441 this->emitLabel(EndLabel);
6446template <
class Emitter>
6449 assert(
E->isComparisonOp());
6451 assert(!DiscardResult);
6457 LHSIsComplex =
true;
6458 ElemT = classifyComplexElementType(LHS->
getType());
6459 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true,
6461 if (!this->visit(LHS))
6463 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
6466 LHSIsComplex =
false;
6468 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
6469 if (!this->visit(LHS))
6471 if (!this->emitSetLocal(LHST, LHSOffset,
E))
6478 RHSIsComplex =
true;
6479 ElemT = classifyComplexElementType(RHS->
getType());
6480 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true,
6482 if (!this->visit(RHS))
6484 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
6487 RHSIsComplex =
false;
6489 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
6490 if (!this->visit(RHS))
6492 if (!this->emitSetLocal(RHST, RHSOffset,
E))
6496 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
6497 bool IsComplex) ->
bool {
6499 if (!this->emitGetLocal(
PT_Ptr, LocalOffset,
E))
6501 return this->emitArrayElemPop(ElemT, Index,
E);
6503 return this->emitGetLocal(ElemT, LocalOffset,
E);
6506 for (
unsigned I = 0; I != 2; ++I) {
6508 if (!getElem(LHSOffset, I, LHSIsComplex))
6510 if (!getElem(RHSOffset, I, RHSIsComplex))
6513 if (!this->emitEQ(ElemT,
E))
6516 if (!this->emitCastBoolUint8(
E))
6521 if (!this->emitAddUint8(
E))
6523 if (!this->emitConstUint8(2,
E))
6526 if (
E->getOpcode() == BO_EQ) {
6527 if (!this->emitEQUint8(
E))
6529 }
else if (
E->getOpcode() == BO_NE) {
6530 if (!this->emitNEUint8(
E))
6537 return this->emitCast(
PT_Bool, ResT,
E);
6544template <
class Emitter>
6553 const Function *DtorFunc = getFunction(Dtor);
6558 if (!this->emitDupPtr(
Loc))
6560 return this->emitCall(DtorFunc, 0,
Loc);
6565template <
class Emitter>
6590 for (ssize_t I = Desc->
getNumElems() - 1; I >= 0; --I) {
6591 if (!this->emitConstUint64(I,
Loc))
6593 if (!this->emitArrayElemPtrUint64(
Loc))
6595 if (!this->emitDestruction(ElemDesc,
Loc))
6597 if (!this->emitPopPtr(
Loc))
6612template <
class Emitter>
6614 assert(!DiscardResult &&
"Should've been checked before");
6616 unsigned DummyID =
P.getOrCreateDummy(
D);
6618 if (!this->emitGetPtrGlobal(DummyID,
E))
6626 return this->emitDecayPtr(
PT_Ptr, PT,
E);
6639template <
class Emitter>
6641 const Expr *SubExpr =
E->getSubExpr();
6644 std::optional<PrimType> ToT = classify(ToType);
6650 std::optional<unsigned> LocalIndex = allocateLocal(
E);
6653 if (!this->emitGetPtrLocal(*LocalIndex,
E))
6663 if (!this->visit(SubExpr))
6665 }
else if (std::optional<PrimType> FromT = classify(SubExpr)) {
6666 unsigned TempOffset = allocateLocalPrimitive(
6667 SubExpr, *FromT,
true,
false);
6668 if (!this->visit(SubExpr))
6670 if (!this->emitSetLocal(*FromT, TempOffset,
E))
6672 if (!this->emitGetPtrLocal(TempOffset,
E))
6679 if (!this->emitBitCast(
E))
6681 return DiscardResult ? this->emitPopPtr(
E) :
true;
6685 const llvm::fltSemantics *TargetSemantics =
nullptr;
6687 TargetSemantics = &Ctx.getFloatSemantics(ToType);
6693 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
6695 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->
isStdByteType(),
6696 ResultBitWidth, TargetSemantics,
E))
6700 return this->emitPop(*ToT,
E);
ASTImporterLookupTable & LT
#define EMIT_ARITH_OP(OP)
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 ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
const LangOptions & getLangOpts() const
ComparisonCategories CompCategories
Types and expressions required to build C++2a three-way comparisons using operator<=>,...
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
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.
QualType getElementType() const
Attr - This represents one attribute.
Represents an attribute applied to a statement.
Represents a C++ declaration that introduces decls from somewhere else.
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 Opcode getOpForCompoundAssignment(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
BreakStmt - This represents a break.
Represents a base class of a C++ class.
Represents binding an expression to a temporary.
A boolean literal, per ([C++ lex.bool] Boolean literals).
Represents a call to a C++ constructor.
Represents a C++ constructor within a class.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Represents a delete expression for memory deallocation and destructor calls, e.g.
Represents a C++ destructor within a class.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Represents a call to an inherited base class constructor from an inheriting constructor.
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a list-initialization with parenthesis.
Represents a C++ struct/union/class.
capture_const_iterator captures_end() const
capture_const_iterator captures_begin() const
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
A rewritten comparison expression that was originally written using operator syntax.
An expression "T()" which creates an rvalue of a non-class type T.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Represents the this expression in C++.
A C++ throw-expression (C++ [except.throw]).
CXXTryStmt - A C++ try block, including all handlers.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
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.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
const ComparisonCategoryInfo * lookupInfoForType(QualType Ty) const
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
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
DoStmt - This represents a 'do/while' stmt.
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.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
An expression trait intrinsic.
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Represents a member of a struct/union/class.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isReplaceableGlobalAllocationFunction(std::optional< unsigned > *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
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.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a C++ namespace alias.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
ObjCEncodeExpr, used for @encode in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Helper class for OffsetOfExpr.
@ Array
An index into an array.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
[C99 6.4.2.2] - A predefined identifier such as func.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
QualType withConst() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getCanonicalType() const
bool isConstQualified() const
Determine whether this type is const-qualified.
Represents a struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Base for LValueReferenceType and RValueReferenceType.
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Represents an expression that computes the length of a parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Represents a C++11 static_assert declaration.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Stmt - This represents one statement.
StringLiteral - This represents a string literal expression, e.g.
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumConcatenated)
This is the "fully general" constructor that allows representation of strings formed from multiple co...
Represents a reference to a non-type template parameter that has been substituted with a template arg...
SwitchStmt - This represents a 'switch' stmt.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBooleanType() const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
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 isSpecificBuiltinType(unsigned K) const
Test for a particular builtin 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 isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool isMemberPointerType() const
bool isAtomicType() const
bool isStdByteType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isPointerOrReferenceType() const
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),...
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 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 VisitFixedPointBinOp(const BinaryOperator *E)
bool VisitCastExpr(const CastExpr *E)
bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E)
bool VisitFixedPointUnaryOperator(const UnaryOperator *E)
bool VisitComplexUnaryOperator(const UnaryOperator *E)
llvm::DenseMap< const SwitchCase *, LabelTy > CaseMap
bool visitDeclStmt(const DeclStmt *DS)
bool VisitBlockExpr(const BlockExpr *E)
bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E)
Visit an APValue.
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
bool VisitLogicalBinOp(const BinaryOperator *E)
bool visitCompoundStmt(const CompoundStmt *S)
bool visitDeclRef(const ValueDecl *D, const Expr *E)
Visit the given decl as if we have a reference to it.
bool visitBreakStmt(const BreakStmt *S)
bool visitExpr(const Expr *E, bool DestroyToplevelScope) override
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)
std::optional< unsigned > allocateLocal(DeclTy &&Decl, QualType Ty=QualType(), const ValueDecl *ExtendingDecl=nullptr)
Allocates a space storing a local given its type.
bool VisitFixedPointLiteral(const FixedPointLiteral *E)
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
VariableScope< Emitter > * VarScope
Current scope.
VariableScope< Emitter > * ContinueVarScope
Scope to cleanup until when we see a continue statement.
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)
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 VisitVectorUnaryOperator(const UnaryOperator *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 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)
bool VisitCXXTypeidExpr(const CXXTypeidExpr *E)
bool VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinID)
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 VisitVectorBinOp(const BinaryOperator *E)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
std::optional< unsigned > allocateTemporary(const Expr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
VariableScope< Emitter > * BreakVarScope
Scope to cleanup until when we see a break statement.
std::optional< LabelTy > OptLabelTy
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 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)
Wrapper around fixed point types.
static FixedPoint zero(llvm::FixedPointSemantics Sem)
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
bool isAnonymousUnion() const
Checks if the record is an anonymous union.
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.
static llvm::RoundingMode getRoundingMode(FPOptions FPO)
bool Div(InterpState &S, CodePtr OpPC)
1) Pops the RHS from the stack.
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.
bool Mul(InterpState &S, CodePtr OpPC)
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 InitList()
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()