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 unsigned LocalIndex = allocateTemporary(CE);
566 if (!this->emitGetPtrLocal(LocalIndex, CE))
571 if (!this->visitArrayElemInit(0, SubExpr))
575 if (!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
577 return this->emitInitElem(
T, 1, SubExpr);
580 case CK_IntegralComplexCast:
581 case CK_FloatingComplexCast:
582 case CK_IntegralComplexToFloatingComplex:
583 case CK_FloatingComplexToIntegralComplex: {
587 return this->discard(SubExpr);
590 std::optional<unsigned> LocalIndex = allocateLocal(CE);
593 if (!this->emitGetPtrLocal(*LocalIndex, CE))
600 unsigned SubExprOffset = allocateLocalPrimitive(
601 SubExpr,
PT_Ptr,
true,
false);
602 if (!this->visit(SubExpr))
604 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, CE))
610 PrimType DestElemT = classifyPrim(DestElemType);
612 for (
unsigned I = 0; I != 2; ++I) {
613 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, CE))
615 if (!this->emitArrayElemPop(SourceElemT, I, CE))
619 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
623 if (!this->emitInitElem(DestElemT, I, CE))
629 case CK_VectorSplat: {
630 assert(!classify(CE->
getType()));
631 assert(classify(SubExpr->
getType()));
635 return this->discard(SubExpr);
638 std::optional<unsigned> LocalIndex = allocateLocal(CE);
641 if (!this->emitGetPtrLocal(*LocalIndex, CE))
647 unsigned ElemOffset = allocateLocalPrimitive(
648 SubExpr, ElemT,
true,
false);
651 if (!this->visit(SubExpr))
653 if (classifyPrim(SubExpr) ==
PT_Ptr && !this->emitLoadPop(ElemT, CE))
656 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
659 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
660 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
662 if (!this->emitInitElem(ElemT, I, CE))
669 case CK_HLSLVectorTruncation: {
671 if (std::optional<PrimType> ResultT = classify(CE)) {
672 assert(!DiscardResult);
674 if (!this->visit(SubExpr))
676 return this->emitArrayElemPop(*ResultT, 0, CE);
682 unsigned LocalIndex = allocateTemporary(CE);
683 if (!this->emitGetPtrLocal(LocalIndex, CE))
688 if (!this->visit(SubExpr))
690 return this->emitCopyArray(classifyVectorElementType(CE->
getType()), 0, 0,
694 case CK_IntegralToFixedPoint: {
695 if (!this->visit(SubExpr))
700 return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->
getType()),
703 case CK_FloatingToFixedPoint: {
704 if (!this->visit(SubExpr))
709 return this->emitCastFloatingFixedPoint(Sem, CE);
711 case CK_FixedPointToFloating: {
712 if (!this->visit(SubExpr))
714 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
715 return this->emitCastFixedPointFloating(TargetSemantics, CE);
717 case CK_FixedPointToIntegral: {
718 if (!this->visit(SubExpr))
720 return this->emitCastFixedPointIntegral(classifyPrim(CE->
getType()), CE);
722 case CK_FixedPointCast: {
723 if (!this->visit(SubExpr))
727 return this->emitCastFixedPoint(Sem, CE);
731 return discard(SubExpr);
734 return this->emitInvalid(CE);
736 llvm_unreachable(
"Unhandled clang::CastKind enum");
739template <
class Emitter>
744 return this->emitConst(
LE->getValue(),
LE);
747template <
class Emitter>
752 return this->emitConstFloat(
E->getValue(),
E);
755template <
class Emitter>
762 unsigned LocalIndex = allocateTemporary(
E);
763 if (!this->emitGetPtrLocal(LocalIndex,
E))
767 const Expr *SubExpr =
E->getSubExpr();
770 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
772 if (!this->emitInitElem(SubExprT, 0, SubExpr))
774 return this->visitArrayElemInit(1, SubExpr);
777template <
class Emitter>
790template <
class Emitter>
792 return this->delegate(
E->getSubExpr());
795template <
class Emitter>
799 return this->VisitLogicalBinOp(BO);
807 if (!this->discard(LHS))
810 return this->discard(RHS);
812 return this->delegate(RHS);
816 return this->VisitComplexBinOp(BO);
818 return this->VisitVectorBinOp(BO);
822 return this->emitComplexComparison(LHS, RHS, BO);
824 return this->VisitFixedPointBinOp(BO);
827 if (!this->visit(LHS))
830 if (!this->visit(RHS))
833 if (!this->emitToMemberPtr(BO))
839 if (!this->emitCastMemberPtrPtr(BO))
841 return DiscardResult ? this->emitPopPtr(BO) :
true;
845 std::optional<PrimType>
LT = classify(LHS);
846 std::optional<PrimType> RT = classify(RHS);
847 std::optional<PrimType>
T = classify(BO->
getType());
861 std::optional<unsigned> ResultIndex = this->allocateLocal(BO);
862 if (!this->emitGetPtrLocal(*ResultIndex, BO))
866 if (!visit(LHS) || !visit(RHS))
869 return this->emitCMP3(*
LT, CmpInfo, BO);
872 if (!
LT || !RT || !
T)
878 return this->VisitPointerArithBinOp(BO);
883 if (!visit(RHS) || !visit(LHS))
885 if (!this->emitFlip(*
LT, *RT, BO))
888 if (!visit(LHS) || !visit(RHS))
894 auto MaybeCastToBool = [
this,
T, BO](
bool Result) {
898 return this->emitPop(*
T, BO);
900 return this->emitCast(
PT_Bool, *
T, BO);
904 auto Discard = [
this,
T, BO](
bool Result) {
907 return DiscardResult ? this->emitPop(*
T, BO) :
true;
912 return MaybeCastToBool(this->emitEQ(*
LT, BO));
914 return MaybeCastToBool(this->emitNE(*
LT, BO));
916 return MaybeCastToBool(this->emitLT(*
LT, BO));
918 return MaybeCastToBool(this->emitLE(*
LT, BO));
920 return MaybeCastToBool(this->emitGT(*
LT, BO));
922 return MaybeCastToBool(this->emitGE(*
LT, BO));
925 return Discard(this->emitSubf(getFPOptions(BO), BO));
926 return Discard(this->emitSub(*
T, BO));
929 return Discard(this->emitAddf(getFPOptions(BO), BO));
930 return Discard(this->emitAdd(*
T, BO));
933 return Discard(this->emitMulf(getFPOptions(BO), BO));
934 return Discard(this->emitMul(*
T, BO));
936 return Discard(this->emitRem(*
T, BO));
939 return Discard(this->emitDivf(getFPOptions(BO), BO));
940 return Discard(this->emitDiv(*
T, BO));
944 : this->emitStorePop(*
T, BO);
946 if (!this->emitStoreBitField(*
T, BO))
949 if (!this->emitStore(*
T, BO))
955 return this->emitLoadPop(*
T, BO);
958 return Discard(this->emitBitAnd(*
T, BO));
960 return Discard(this->emitBitOr(*
T, BO));
962 return Discard(this->emitShl(*
LT, *RT, BO));
964 return Discard(this->emitShr(*
LT, *RT, BO));
966 return Discard(this->emitBitXor(*
T, BO));
969 llvm_unreachable(
"Already handled earlier");
974 llvm_unreachable(
"Unhandled binary op");
979template <
class Emitter>
982 const Expr *LHS =
E->getLHS();
983 const Expr *RHS =
E->getRHS();
985 if ((Op != BO_Add && Op != BO_Sub) ||
989 std::optional<PrimType>
LT = classify(LHS);
990 std::optional<PrimType> RT = classify(RHS);
1000 return this->emitDecayPtr(
T,
PT_Ptr,
E);
1009 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *
LT))
1013 if (!this->emitSubPtr(IntT,
E))
1015 return DiscardResult ? this->emitPop(IntT,
E) :
true;
1020 if (!visitAsPointer(RHS, *RT))
1022 if (!this->visit(LHS))
1026 if (!visitAsPointer(LHS, *
LT))
1028 if (!this->visit(RHS))
1038 if (!this->emitAddOffset(OffsetType,
E))
1041 if (classifyPrim(
E) !=
PT_Ptr)
1042 return this->emitDecayPtr(
PT_Ptr, classifyPrim(
E),
E);
1044 }
else if (Op == BO_Sub) {
1045 if (!this->emitSubOffset(OffsetType,
E))
1048 if (classifyPrim(
E) !=
PT_Ptr)
1049 return this->emitDecayPtr(
PT_Ptr, classifyPrim(
E),
E);
1056template <
class Emitter>
1058 assert(
E->isLogicalOp());
1060 const Expr *LHS =
E->getLHS();
1061 const Expr *RHS =
E->getRHS();
1062 std::optional<PrimType>
T = classify(
E->
getType());
1066 LabelTy LabelTrue = this->getLabel();
1067 LabelTy LabelEnd = this->getLabel();
1069 if (!this->visitBool(LHS))
1071 if (!this->jumpTrue(LabelTrue))
1074 if (!this->visitBool(RHS))
1076 if (!this->jump(LabelEnd))
1079 this->emitLabel(LabelTrue);
1080 this->emitConstBool(
true,
E);
1081 this->fallthrough(LabelEnd);
1082 this->emitLabel(LabelEnd);
1085 assert(Op == BO_LAnd);
1088 LabelTy LabelFalse = this->getLabel();
1089 LabelTy LabelEnd = this->getLabel();
1091 if (!this->visitBool(LHS))
1093 if (!this->jumpFalse(LabelFalse))
1096 if (!this->visitBool(RHS))
1098 if (!this->jump(LabelEnd))
1101 this->emitLabel(LabelFalse);
1102 this->emitConstBool(
false,
E);
1103 this->fallthrough(LabelEnd);
1104 this->emitLabel(LabelEnd);
1108 return this->emitPopBool(
E);
1117template <
class Emitter>
1121 unsigned LocalIndex = allocateTemporary(
E);
1122 if (!this->emitGetPtrLocal(LocalIndex,
E))
1128 const Expr *LHS =
E->getLHS();
1129 const Expr *RHS =
E->getRHS();
1132 unsigned ResultOffset = ~0u;
1134 ResultOffset = this->allocateLocalPrimitive(
E,
PT_Ptr,
true,
false);
1137 if (!this->DiscardResult) {
1138 if (!this->emitDupPtr(
E))
1140 if (!this->emitSetLocal(
PT_Ptr, ResultOffset,
E))
1145 LHSType = AT->getValueType();
1148 RHSType = AT->getValueType();
1157 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1162 if (!this->visit(LHS))
1164 if (!this->visit(RHS))
1166 return this->emitMulc(ElemT,
E);
1169 if (Op == BO_Div && RHSIsComplex) {
1171 PrimType ElemT = classifyPrim(ElemQT);
1176 if (!LHSIsComplex) {
1178 LHSOffset = allocateTemporary(RHS);
1180 if (!this->emitGetPtrLocal(LHSOffset,
E))
1183 if (!this->visit(LHS))
1186 if (!this->emitInitElem(ElemT, 0,
E))
1189 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1191 if (!this->emitInitElem(ElemT, 1,
E))
1194 if (!this->visit(LHS))
1198 if (!this->visit(RHS))
1200 return this->emitDivc(ElemT,
E);
1205 LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
1206 if (!this->visit(LHS))
1208 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1211 PrimType LHST = classifyPrim(LHSType);
1212 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
1213 if (!this->visit(LHS))
1215 if (!this->emitSetLocal(LHST, LHSOffset,
E))
1222 RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
1223 if (!this->visit(RHS))
1225 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1228 PrimType RHST = classifyPrim(RHSType);
1229 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
1230 if (!this->visit(RHS))
1232 if (!this->emitSetLocal(RHST, RHSOffset,
E))
1239 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1240 unsigned ElemIndex,
unsigned Offset,
1241 const Expr *
E) ->
bool {
1243 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
1245 return this->emitArrayElemPop(classifyComplexElementType(
E->
getType()),
1248 if (ElemIndex == 0 || !LoadZero)
1249 return this->emitGetLocal(classifyPrim(
E->
getType()), Offset,
E);
1250 return this->visitZeroInitializer(classifyPrim(
E->
getType()),
E->
getType(),
1255 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1257 if (!this->DiscardResult) {
1258 if (!this->emitGetLocal(
PT_Ptr, ResultOffset,
E))
1265 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1268 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1271 if (!this->emitAddf(getFPOptions(
E),
E))
1274 if (!this->emitAdd(ResultElemT,
E))
1279 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1282 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1285 if (!this->emitSubf(getFPOptions(
E),
E))
1288 if (!this->emitSub(ResultElemT,
E))
1293 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1296 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1300 if (!this->emitMulf(getFPOptions(
E),
E))
1303 if (!this->emitMul(ResultElemT,
E))
1308 assert(!RHSIsComplex);
1309 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1312 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1316 if (!this->emitDivf(getFPOptions(
E),
E))
1319 if (!this->emitDiv(ResultElemT,
E))
1328 if (!this->DiscardResult) {
1330 if (!this->emitInitElemPop(ResultElemT, ElemIndex,
E))
1333 if (!this->emitPop(ResultElemT,
E))
1340template <
class Emitter>
1342 assert(!
E->isCommaOp() &&
1343 "Comma op should be handled in VisitBinaryOperator");
1350 unsigned LocalIndex = allocateTemporary(
E);
1351 if (!this->emitGetPtrLocal(LocalIndex,
E))
1355 const Expr *LHS =
E->getLHS();
1356 const Expr *RHS =
E->getRHS();
1358 auto Op =
E->isCompoundAssignmentOp()
1367 unsigned LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
1368 if (!this->visit(LHS))
1370 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1374 unsigned RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
1375 if (!this->visit(RHS))
1377 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1380 if (
E->isCompoundAssignmentOp() && !this->emitGetLocal(
PT_Ptr, LHSOffset,
E))
1385 bool NeedIntPromot = ElemT ==
PT_Bool && (
E->isBitwiseOp() ||
E->isShiftOp());
1388 PrimType PromotT = classifyPrim(PromotTy);
1389 PrimType OpT = NeedIntPromot ? PromotT : ElemT;
1391 auto getElem = [=](
unsigned Offset,
PrimType ElemT,
unsigned Index) {
1392 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
1394 if (!this->emitArrayElemPop(ElemT, Index,
E))
1396 if (
E->isLogicalOp()) {
1397 if (!this->emitPrimCast(ElemT,
PT_Bool, Ctx.getASTContext().
BoolTy,
E))
1399 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(),
E))
1401 }
else if (NeedIntPromot) {
1402 if (!this->emitPrimCast(ElemT, PromotT, PromotTy,
E))
1408#define EMIT_ARITH_OP(OP) \
1410 if (ElemT == PT_Float) { \
1411 if (!this->emit##OP##f(getFPOptions(E), E)) \
1414 if (!this->emit##OP(ElemT, E)) \
1420 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
1421 if (!getElem(LHSOffset, ElemT, I))
1423 if (!getElem(RHSOffset, RHSElemT, I))
1435 if (!this->emitRem(ElemT,
E))
1439 if (!this->emitBitAnd(OpT,
E))
1443 if (!this->emitBitOr(OpT,
E))
1447 if (!this->emitBitXor(OpT,
E))
1451 if (!this->emitShl(OpT, RHSElemT,
E))
1455 if (!this->emitShr(OpT, RHSElemT,
E))
1459 if (!this->emitEQ(ElemT,
E))
1463 if (!this->emitNE(ElemT,
E))
1467 if (!this->emitLE(ElemT,
E))
1471 if (!this->emitLT(ElemT,
E))
1475 if (!this->emitGE(ElemT,
E))
1479 if (!this->emitGT(ElemT,
E))
1484 if (!this->emitBitAnd(ResultElemT,
E))
1489 if (!this->emitBitOr(ResultElemT,
E))
1493 return this->emitInvalid(
E);
1501 if (
E->isComparisonOp()) {
1502 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(),
E))
1504 if (!this->emitNeg(ResultElemT,
E))
1510 if (NeedIntPromot &&
1511 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(),
E))
1515 if (!this->emitInitElem(ResultElemT, I,
E))
1519 if (DiscardResult &&
E->isCompoundAssignmentOp() && !this->emitPopPtr(
E))
1524template <
class Emitter>
1526 const Expr *LHS =
E->getLHS();
1527 const Expr *RHS =
E->getRHS();
1528 const ASTContext &ASTCtx = Ctx.getASTContext();
1534 auto LHSSemaInt = LHSSema.toOpaqueInt();
1536 auto RHSSemaInt = RHSSema.toOpaqueInt();
1538 if (!this->visit(LHS))
1541 if (!this->emitCastIntegralFixedPoint(classifyPrim(LHS->
getType()),
1546 if (!this->visit(RHS))
1549 if (!this->emitCastIntegralFixedPoint(classifyPrim(RHS->
getType()),
1555 auto ConvertResult = [&](
bool R) ->
bool {
1559 auto CommonSema = LHSSema.getCommonSemantics(RHSSema).toOpaqueInt();
1560 if (ResultSema != CommonSema)
1561 return this->emitCastFixedPoint(ResultSema,
E);
1565 auto MaybeCastToBool = [&](
bool Result) {
1570 return this->emitPop(
T,
E);
1576 switch (
E->getOpcode()) {
1578 return MaybeCastToBool(this->emitEQFixedPoint(
E));
1580 return MaybeCastToBool(this->emitNEFixedPoint(
E));
1582 return MaybeCastToBool(this->emitLTFixedPoint(
E));
1584 return MaybeCastToBool(this->emitLEFixedPoint(
E));
1586 return MaybeCastToBool(this->emitGTFixedPoint(
E));
1588 return MaybeCastToBool(this->emitGEFixedPoint(
E));
1590 return ConvertResult(this->emitAddFixedPoint(
E));
1592 return ConvertResult(this->emitSubFixedPoint(
E));
1594 return ConvertResult(this->emitMulFixedPoint(
E));
1596 return ConvertResult(this->emitDivFixedPoint(
E));
1598 return ConvertResult(this->emitShiftFixedPoint(
true,
E));
1600 return ConvertResult(this->emitShiftFixedPoint(
false,
E));
1603 return this->emitInvalid(
E);
1606 llvm_unreachable(
"unhandled binop opcode");
1609template <
class Emitter>
1611 const Expr *SubExpr =
E->getSubExpr();
1614 switch (
E->getOpcode()) {
1616 return this->delegate(SubExpr);
1618 if (!this->visit(SubExpr))
1620 return this->emitNegFixedPoint(
E);
1625 llvm_unreachable(
"Unhandled unary opcode");
1628template <
class Emitter>
1633 if (std::optional<PrimType>
T = classify(QT))
1634 return this->visitZeroInitializer(*
T, QT,
E);
1642 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1643 CXXRD && CXXRD->getNumVBases() > 0) {
1648 const Record *R = getRecord(QT);
1653 return this->visitZeroRecordInitializer(R,
E);
1660 return this->visitZeroArrayInitializer(QT,
E);
1664 QualType ElemQT = ComplexTy->getElementType();
1665 PrimType ElemT = classifyPrim(ElemQT);
1666 for (
unsigned I = 0; I < 2; ++I) {
1667 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1669 if (!this->emitInitElem(ElemT, I,
E))
1676 unsigned NumVecElements = VecT->getNumElements();
1677 QualType ElemQT = VecT->getElementType();
1678 PrimType ElemT = classifyPrim(ElemQT);
1680 for (
unsigned I = 0; I < NumVecElements; ++I) {
1681 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1683 if (!this->emitInitElem(ElemT, I,
E))
1692template <
class Emitter>
1694 const Expr *LHS =
E->getLHS();
1695 const Expr *RHS =
E->getRHS();
1696 const Expr *Index =
E->getIdx();
1699 return this->discard(LHS) && this->discard(RHS);
1704 for (
const Expr *SubExpr : {LHS, RHS}) {
1705 if (!this->visit(SubExpr))
1712 PrimType IndexT = classifyPrim(Index->getType());
1715 if (!this->emitFlip(
PT_Ptr, IndexT,
E))
1719 return this->emitArrayElemPtrPop(IndexT,
E);
1722template <
class Emitter>
1724 const Expr *ArrayFiller,
const Expr *
E) {
1729 QT = AT->getValueType();
1732 if (Inits.size() == 0)
1734 return this->emitInvalid(
E);
1738 if (DiscardResult) {
1740 if (!this->discard(
Init))
1747 if (std::optional<PrimType>
T = classify(QT)) {
1748 assert(!DiscardResult);
1749 if (Inits.size() == 0)
1750 return this->visitZeroInitializer(*
T, QT,
E);
1751 assert(Inits.size() == 1);
1752 return this->delegate(Inits[0]);
1756 const Record *R = getRecord(QT);
1758 if (Inits.size() == 1 &&
E->
getType() == Inits[0]->getType())
1759 return this->delegate(Inits[0]);
1761 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
1765 if (!this->visit(
Init))
1768 if (FieldToInit->isBitField())
1769 return this->emitInitBitField(
T, FieldToInit,
E);
1770 return this->emitInitField(
T, FieldToInit->Offset,
E);
1773 auto initCompositeField = [=](
const Record::Field *FieldToInit,
1780 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
1782 if (!this->visitInitializer(
Init))
1784 return this->emitPopPtr(
E);
1788 if (Inits.size() == 0) {
1789 if (!this->visitZeroRecordInitializer(R,
E))
1794 if (
const auto *ILE = dyn_cast<InitListExpr>(
E))
1795 FToInit = ILE->getInitializedFieldInUnion();
1797 FToInit = cast<CXXParenListInitExpr>(
E)->getInitializedFieldInUnion();
1799 const Record::Field *FieldToInit = R->
getField(FToInit);
1800 if (std::optional<PrimType>
T = classify(
Init)) {
1801 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1804 if (!initCompositeField(FieldToInit,
Init))
1808 return this->emitFinishInit(
E);
1812 unsigned InitIndex = 0;
1815 while (InitIndex < R->getNumFields() &&
1819 if (std::optional<PrimType>
T = classify(
Init)) {
1820 const Record::Field *FieldToInit = R->
getField(InitIndex);
1821 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1826 if (
const Record::Base *B = R->
getBase(
Init->getType())) {
1827 if (!this->emitGetPtrBase(B->Offset,
Init))
1830 if (!this->visitInitializer(
Init))
1833 if (!this->emitFinishInitPop(
E))
1838 const Record::Field *FieldToInit = R->
getField(InitIndex);
1839 if (!initCompositeField(FieldToInit,
Init))
1845 return this->emitFinishInit(
E);
1849 if (Inits.size() == 1 && QT == Inits[0]->getType())
1850 return this->delegate(Inits[0]);
1852 unsigned ElementIndex = 0;
1854 if (
const auto *EmbedS =
1855 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1858 auto Eval = [&](
const Expr *
Init,
unsigned ElemIndex) {
1860 if (!this->visit(
Init))
1862 if (InitT != TargetT) {
1863 if (!this->emitCast(InitT, TargetT,
E))
1866 return this->emitInitElem(TargetT, ElemIndex,
Init);
1868 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
1871 if (!this->visitArrayElemInit(ElementIndex,
Init))
1884 for (; ElementIndex != NumElems; ++ElementIndex) {
1885 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller))
1890 return this->emitFinishInit(
E);
1894 unsigned NumInits = Inits.size();
1897 return this->delegate(Inits[0]);
1899 QualType ElemQT = ComplexTy->getElementType();
1900 PrimType ElemT = classifyPrim(ElemQT);
1901 if (NumInits == 0) {
1903 for (
unsigned I = 0; I < 2; ++I) {
1904 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1906 if (!this->emitInitElem(ElemT, I,
E))
1909 }
else if (NumInits == 2) {
1910 unsigned InitIndex = 0;
1912 if (!this->visit(
Init))
1915 if (!this->emitInitElem(ElemT, InitIndex,
E))
1924 unsigned NumVecElements = VecT->getNumElements();
1925 assert(NumVecElements >= Inits.size());
1927 QualType ElemQT = VecT->getElementType();
1928 PrimType ElemT = classifyPrim(ElemQT);
1931 unsigned InitIndex = 0;
1933 if (!this->visit(
Init))
1938 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
1939 if (!this->emitCopyArray(ElemT, 0, InitIndex,
1940 InitVecT->getNumElements(),
E))
1942 InitIndex += InitVecT->getNumElements();
1944 if (!this->emitInitElem(ElemT, InitIndex,
E))
1950 assert(InitIndex <= NumVecElements);
1953 for (; InitIndex != NumVecElements; ++InitIndex) {
1954 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1956 if (!this->emitInitElem(ElemT, InitIndex,
E))
1967template <
class Emitter>
1970 if (std::optional<PrimType>
T = classify(
Init->getType())) {
1972 if (!this->visit(
Init))
1974 return this->emitInitElem(*
T, ElemIndex,
Init);
1980 if (!this->emitConstUint32(ElemIndex,
Init))
1982 if (!this->emitArrayElemPtrUint32(
Init))
1984 if (!this->visitInitializer(
Init))
1986 return this->emitFinishInitPop(
Init);
1989template <
class Emitter>
1991 return this->visitInitList(
E->inits(),
E->getArrayFiller(),
E);
1994template <
class Emitter>
1997 return this->visitInitList(
E->getInitExprs(),
E->getArrayFiller(),
E);
2000template <
class Emitter>
2003 return this->delegate(
E->getReplacement());
2006template <
class Emitter>
2008 std::optional<PrimType>
T = classify(
E->
getType());
2009 if (
T &&
E->hasAPValueResult()) {
2016 if (this->visitAPValue(
E->getAPValueResult(), *
T,
E))
2019 return this->delegate(
E->getSubExpr());
2022template <
class Emitter>
2024 auto It =
E->begin();
2025 return this->visit(*It);
2030 bool AlignOfReturnsPreferred =
2031 ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
2039 if (
T.getQualifiers().hasUnaligned())
2045 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2051template <
class Emitter>
2055 const ASTContext &ASTCtx = Ctx.getASTContext();
2057 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2058 QualType ArgType =
E->getTypeOfArgument();
2070 return this->emitInvalid(
E);
2072 if (Kind == UETT_SizeOf)
2081 return this->emitConst(Size.getQuantity(),
E);
2084 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2087 if (
E->isArgumentType()) {
2088 QualType ArgType =
E->getTypeOfArgument();
2101 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2104 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
2114 return this->emitConst(Size.getQuantity(),
E);
2117 if (Kind == UETT_VectorElements) {
2118 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>())
2119 return this->emitConst(VT->getNumElements(),
E);
2120 assert(
E->getTypeOfArgument()->isSizelessVectorType());
2121 return this->emitSizelessVectorElementSize(
E);
2124 if (Kind == UETT_VecStep) {
2125 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>()) {
2126 unsigned N = VT->getNumElements();
2133 return this->emitConst(N,
E);
2135 return this->emitConst(1,
E);
2138 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2139 assert(
E->isArgumentType());
2145 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2146 if (
E->getArgumentType()->isDependentType())
2147 return this->emitInvalid(
E);
2149 return this->emitConst(
2150 const_cast<ASTContext &
>(ASTCtx).getPointerAuthTypeDiscriminator(
2151 E->getArgumentType()),
2158template <
class Emitter>
2165 return this->discard(
Base);
2169 const auto maybeLoadValue = [&]() ->
bool {
2172 if (std::optional<PrimType>
T = classify(
E))
2173 return this->emitLoadPop(*
T,
E);
2177 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
2181 if (
auto GlobalIndex =
P.getGlobal(VD))
2182 return this->emitGetPtrGlobal(*GlobalIndex,
E) && maybeLoadValue();
2186 if (!isa<FieldDecl>(
Member)) {
2187 if (!this->discard(
Base) && !this->emitSideEffect(
E))
2190 return this->visitDeclRef(
Member,
E);
2194 if (!this->delegate(
Base))
2197 if (!this->visit(
Base))
2202 const auto *FD = cast<FieldDecl>(
Member);
2204 const Record *R = getRecord(RD);
2207 const Record::Field *F = R->
getField(FD);
2209 if (F->Decl->getType()->isReferenceType())
2210 return this->emitGetFieldPop(
PT_Ptr, F->Offset,
E) && maybeLoadValue();
2211 return this->emitGetPtrFieldPop(F->Offset,
E) && maybeLoadValue();
2214template <
class Emitter>
2220 return this->emitConst(*ArrayIndex,
E);
2223template <
class Emitter>
2226 assert(!DiscardResult);
2230 if (!this->discard(
E->getCommonExpr()))
2235 const Expr *SubExpr =
E->getSubExpr();
2236 size_t Size =
E->getArraySize().getZExtValue();
2241 for (
size_t I = 0; I != Size; ++I) {
2245 if (!this->visitArrayElemInit(I, SubExpr))
2253template <
class Emitter>
2255 const Expr *SourceExpr =
E->getSourceExpr();
2260 return this->visitInitializer(SourceExpr);
2263 if (
auto It = OpaqueExprs.find(
E); It != OpaqueExprs.end())
2264 return this->emitGetLocal(SubExprT, It->second,
E);
2266 if (!this->visit(SourceExpr))
2272 unsigned LocalIndex = allocateLocalPrimitive(
E, SubExprT,
true);
2273 if (!this->emitSetLocal(SubExprT, LocalIndex,
E))
2278 if (!DiscardResult) {
2279 if (!this->emitGetLocal(SubExprT, LocalIndex,
E))
2284 OpaqueExprs.insert({
E, LocalIndex});
2289template <
class Emitter>
2293 const Expr *TrueExpr =
E->getTrueExpr();
2294 const Expr *FalseExpr =
E->getFalseExpr();
2296 LabelTy LabelEnd = this->getLabel();
2297 LabelTy LabelFalse = this->getLabel();
2302 if (!this->jumpFalse(LabelFalse))
2307 if (!this->delegate(TrueExpr))
2309 if (!S.destroyLocals())
2313 if (!this->jump(LabelEnd))
2316 this->emitLabel(LabelFalse);
2320 if (!this->delegate(FalseExpr))
2322 if (!S.destroyLocals())
2326 this->fallthrough(LabelEnd);
2327 this->emitLabel(LabelEnd);
2332template <
class Emitter>
2338 unsigned StringIndex =
P.createGlobalString(
E);
2339 return this->emitGetPtrGlobal(StringIndex,
E);
2345 assert(CAT &&
"a string literal that's not a constant array?");
2350 unsigned N = std::min(ArraySize,
E->getLength());
2351 size_t CharWidth =
E->getCharByteWidth();
2353 for (
unsigned I = 0; I != N; ++I) {
2354 uint32_t CodeUnit =
E->getCodeUnit(I);
2356 if (CharWidth == 1) {
2357 this->emitConstSint8(CodeUnit,
E);
2358 this->emitInitElemSint8(I,
E);
2359 }
else if (CharWidth == 2) {
2360 this->emitConstUint16(CodeUnit,
E);
2361 this->emitInitElemUint16(I,
E);
2362 }
else if (CharWidth == 4) {
2363 this->emitConstUint32(CodeUnit,
E);
2364 this->emitInitElemUint32(I,
E);
2366 llvm_unreachable(
"unsupported character width");
2371 for (
unsigned I = N; I != ArraySize; ++I) {
2372 if (CharWidth == 1) {
2373 this->emitConstSint8(0,
E);
2374 this->emitInitElemSint8(I,
E);
2375 }
else if (CharWidth == 2) {
2376 this->emitConstUint16(0,
E);
2377 this->emitInitElemUint16(I,
E);
2378 }
else if (CharWidth == 4) {
2379 this->emitConstUint32(0,
E);
2380 this->emitInitElemUint32(I,
E);
2382 llvm_unreachable(
"unsupported character width");
2389template <
class Emitter>
2393 return this->emitDummyPtr(
E,
E);
2396template <
class Emitter>
2398 auto &A = Ctx.getASTContext();
2404 return this->delegate(SL);
2407template <
class Emitter>
2415 auto &A = Ctx.getASTContext();
2416 std::string ResultStr =
E->ComputeName(A);
2419 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
2420 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
2421 ArraySizeModifier::Normal, 0);
2425 false, ArrayTy,
E->getLocation());
2427 unsigned StringIndex =
P.createGlobalString(SL);
2428 return this->emitGetPtrGlobal(StringIndex,
E);
2431template <
class Emitter>
2435 return this->emitConst(
E->getValue(),
E);
2438template <
class Emitter>
2442 const Expr *LHS =
E->getLHS();
2443 const Expr *RHS =
E->getRHS();
2445 QualType LHSComputationType =
E->getComputationLHSType();
2446 QualType ResultType =
E->getComputationResultType();
2447 std::optional<PrimType>
LT = classify(LHSComputationType);
2448 std::optional<PrimType> RT = classify(ResultType);
2455 PrimType LHST = classifyPrim(LHSType);
2463 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2464 if (!this->emitSetLocal(*RT, TempOffset,
E))
2470 if (!this->emitLoad(LHST,
E))
2474 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
2475 LHSComputationType,
E))
2479 if (!this->emitGetLocal(*RT, TempOffset,
E))
2482 switch (
E->getOpcode()) {
2484 if (!this->emitAddf(getFPOptions(
E),
E))
2488 if (!this->emitSubf(getFPOptions(
E),
E))
2492 if (!this->emitMulf(getFPOptions(
E),
E))
2496 if (!this->emitDivf(getFPOptions(
E),
E))
2503 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->
getType(),
E))
2507 return this->emitStorePop(LHST,
E);
2508 return this->emitStore(LHST,
E);
2511template <
class Emitter>
2515 const Expr *LHS =
E->getLHS();
2516 const Expr *RHS =
E->getRHS();
2517 std::optional<PrimType>
LT = classify(LHS->
getType());
2518 std::optional<PrimType> RT = classify(RHS->
getType());
2520 if (Op != BO_AddAssign && Op != BO_SubAssign)
2529 if (!this->emitLoad(*
LT, LHS))
2535 if (Op == BO_AddAssign) {
2536 if (!this->emitAddOffset(*RT,
E))
2539 if (!this->emitSubOffset(*RT,
E))
2544 return this->emitStorePopPtr(
E);
2545 return this->emitStorePtr(
E);
2548template <
class Emitter>
2552 return VisitVectorBinOp(
E);
2554 const Expr *LHS =
E->getLHS();
2555 const Expr *RHS =
E->getRHS();
2556 std::optional<PrimType> LHSComputationT =
2557 classify(
E->getComputationLHSType());
2558 std::optional<PrimType>
LT = classify(LHS->
getType());
2559 std::optional<PrimType> RT = classify(RHS->
getType());
2560 std::optional<PrimType> ResultT = classify(
E->
getType());
2563 return this->visit(RHS) && this->visit(LHS) && this->emitError(
E);
2565 if (!
LT || !RT || !ResultT || !LHSComputationT)
2572 return VisitFloatCompoundAssignOperator(
E);
2575 return VisitPointerCompoundAssignOperator(
E);
2588 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2590 if (!this->emitSetLocal(*RT, TempOffset,
E))
2597 if (!this->emitLoad(*
LT,
E))
2599 if (
LT != LHSComputationT) {
2600 if (!this->emitCast(*
LT, *LHSComputationT,
E))
2605 if (!this->emitGetLocal(*RT, TempOffset,
E))
2609 switch (
E->getOpcode()) {
2611 if (!this->emitAdd(*LHSComputationT,
E))
2615 if (!this->emitSub(*LHSComputationT,
E))
2619 if (!this->emitMul(*LHSComputationT,
E))
2623 if (!this->emitDiv(*LHSComputationT,
E))
2627 if (!this->emitRem(*LHSComputationT,
E))
2631 if (!this->emitShl(*LHSComputationT, *RT,
E))
2635 if (!this->emitShr(*LHSComputationT, *RT,
E))
2639 if (!this->emitBitAnd(*LHSComputationT,
E))
2643 if (!this->emitBitXor(*LHSComputationT,
E))
2647 if (!this->emitBitOr(*LHSComputationT,
E))
2651 llvm_unreachable(
"Unimplemented compound assign operator");
2655 if (ResultT != LHSComputationT) {
2656 if (!this->emitCast(*LHSComputationT, *ResultT,
E))
2661 if (DiscardResult) {
2663 return this->emitStoreBitFieldPop(*ResultT,
E);
2664 return this->emitStorePop(*ResultT,
E);
2667 return this->emitStoreBitField(*ResultT,
E);
2668 return this->emitStore(*ResultT,
E);
2671template <
class Emitter>
2674 const Expr *SubExpr =
E->getSubExpr();
2679template <
class Emitter>
2682 const Expr *SubExpr =
E->getSubExpr();
2686 return this->delegate(SubExpr);
2691 return this->discard(SubExpr);
2695 std::optional<PrimType> SubExprT = classify(SubExpr);
2698 std::optional<unsigned> GlobalIndex =
P.createGlobal(
E);
2703 E->getLifetimeExtendedTemporaryDecl();
2708 if (!this->visit(SubExpr))
2711 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl,
E))
2714 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex,
E))
2717 return this->emitGetPtrGlobal(*GlobalIndex,
E);
2720 if (!this->checkLiteralType(SubExpr))
2723 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2725 if (!this->visitInitializer(SubExpr))
2728 return this->emitInitGlobalTempComp(TempDecl,
E);
2734 unsigned LocalIndex = allocateLocalPrimitive(
E, *SubExprT,
true,
2736 if (!this->visit(SubExpr))
2738 if (!this->emitSetLocal(*SubExprT, LocalIndex,
E))
2740 return this->emitGetPtrLocal(LocalIndex,
E);
2743 if (!this->checkLiteralType(SubExpr))
2747 if (std::optional<unsigned> LocalIndex =
2748 allocateLocal(
E, Inner->getType(),
E->getExtendingDecl())) {
2750 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2752 return this->visitInitializer(SubExpr) && this->emitFinishInit(
E);
2758template <
class Emitter>
2761 return this->delegate(
E->getSubExpr());
2764template <
class Emitter>
2768 return this->discard(
Init);
2772 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2775 std::optional<PrimType>
T = classify(
E->
getType());
2776 if (
E->isFileScope()) {
2779 return this->delegate(
Init);
2781 if (std::optional<unsigned> GlobalIndex =
P.createGlobal(
E)) {
2782 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2786 if (!this->visit(
Init))
2788 return this->emitInitGlobal(*
T, *GlobalIndex,
E);
2791 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2800 return this->delegate(
Init);
2802 unsigned LocalIndex;
2805 LocalIndex = this->allocateLocalPrimitive(
Init, *
T,
false,
false);
2806 else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(
Init))
2807 LocalIndex = *MaybeIndex;
2811 if (!this->emitGetPtrLocal(LocalIndex,
E))
2815 if (!this->visit(
Init)) {
2818 return this->emitInit(*
T,
E);
2820 if (!this->visitInitializer(
Init) || !this->emitFinishInit(
E))
2829template <
class Emitter>
2834 return this->emitConstBool(
E->getValue(),
E);
2835 return this->emitConst(
E->getValue(),
E);
2838template <
class Emitter>
2842 return this->emitConst(
E->getValue(),
E);
2845template <
class Emitter>
2851 const Record *R =
P.getOrCreateRecord(
E->getLambdaClass());
2853 auto *CaptureInitIt =
E->capture_init_begin();
2856 for (
const Record::Field &F : R->
fields()) {
2863 if (std::optional<PrimType>
T = classify(
Init)) {
2864 if (!this->visit(
Init))
2867 if (!this->emitInitField(*
T, F.Offset,
E))
2870 if (!this->emitGetPtrField(F.Offset,
E))
2873 if (!this->visitInitializer(
Init))
2876 if (!this->emitPopPtr(
E))
2884template <
class Emitter>
2890 unsigned StringIndex =
P.createGlobalString(
E->getFunctionName(),
E);
2891 return this->emitGetPtrGlobal(StringIndex,
E);
2894 return this->delegate(
E->getFunctionName());
2897template <
class Emitter>
2899 if (
E->getSubExpr() && !this->discard(
E->getSubExpr()))
2902 return this->emitInvalid(
E);
2905template <
class Emitter>
2908 const Expr *SubExpr =
E->getSubExpr();
2910 std::optional<PrimType> FromT = classify(SubExpr);
2911 std::optional<PrimType> ToT = classify(
E);
2914 return this->emitInvalidCast(CastKind::Reinterpret,
true,
E);
2918 std::optional<PrimType> PointeeFromT;
2922 PointeeFromT = classify(SubExpr->
getType());
2924 std::optional<PrimType> PointeeToT;
2928 PointeeToT = classify(
E->
getType());
2931 if (PointeeToT && PointeeFromT) {
2936 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal,
E))
2939 if (
E->getCastKind() == CK_LValueBitCast)
2940 return this->delegate(SubExpr);
2941 return this->VisitCastExpr(
E);
2945 bool Fatal = (ToT != FromT);
2946 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal,
E))
2949 return this->VisitCastExpr(
E);
2952template <
class Emitter>
2958 return this->emitConstBool(
E->getValue(),
E);
2961template <
class Emitter>
2964 assert(!classify(
T));
2974 return this->visitInitializer(
E->getArg(0));
2978 if (DiscardResult) {
2982 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2987 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2992 if (
E->requiresZeroInitialization()) {
2995 if (!this->visitZeroRecordInitializer(R,
E))
3008 assert(
Func->hasThisPointer());
3009 assert(!
Func->hasRVO());
3013 if (!this->emitDupPtr(
E))
3017 for (
const auto *Arg :
E->arguments()) {
3018 if (!this->visit(Arg))
3022 if (
Func->isVariadic()) {
3023 uint32_t VarArgSize = 0;
3024 unsigned NumParams =
Func->getNumWrittenParams();
3025 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I) {
3029 if (!this->emitCallVar(
Func, VarArgSize,
E))
3032 if (!this->emitCall(
Func, 0,
E)) {
3037 (void)this->emitPopPtr(
E);
3043 return this->emitPopPtr(
E);
3044 return this->emitFinishInit(
E);
3060 for (
size_t I = 0; I != NumElems; ++I) {
3061 if (!this->emitConstUint64(I,
E))
3063 if (!this->emitArrayElemPtrUint64(
E))
3067 for (
const auto *Arg :
E->arguments()) {
3068 if (!this->visit(Arg))
3072 if (!this->emitCall(
Func, 0,
E))
3081template <
class Emitter>
3087 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
3091 assert(Val.
isInt());
3093 return this->emitConst(I,
E);
3100 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
3101 return this->visit(LValueExpr);
3110 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
3112 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(UGCD);
3116 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
3120 const APValue &
V = UGCD->getValue();
3121 for (
unsigned I = 0, N = R->
getNumFields(); I != N; ++I) {
3122 const Record::Field *F = R->
getField(I);
3123 const APValue &FieldValue =
V.getStructField(I);
3125 PrimType FieldT = classifyPrim(F->Decl->getType());
3127 if (!this->visitAPValue(FieldValue, FieldT,
E))
3129 if (!this->emitInitField(FieldT, F->Offset,
E))
3137template <
class Emitter>
3139 unsigned N =
E->getNumComponents();
3143 for (
unsigned I = 0; I != N; ++I) {
3146 const Expr *ArrayIndexExpr =
E->getIndexExpr(
Node.getArrayExprIndex());
3149 if (DiscardResult) {
3150 if (!this->discard(ArrayIndexExpr))
3155 if (!this->visit(ArrayIndexExpr))
3169 return this->emitOffsetOf(
T,
E,
E);
3172template <
class Emitter>
3180 if (std::optional<PrimType>
T = classify(Ty))
3181 return this->visitZeroInitializer(*
T, Ty,
E);
3185 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3188 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3193 QualType ElemQT = CT->getElementType();
3194 PrimType ElemT = classifyPrim(ElemQT);
3196 for (
unsigned I = 0; I != 2; ++I) {
3197 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
3199 if (!this->emitInitElem(ElemT, I,
E))
3208 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3211 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3216 QualType ElemQT = VT->getElementType();
3217 PrimType ElemT = classifyPrim(ElemQT);
3219 for (
unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
3220 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
3222 if (!this->emitInitElem(ElemT, I,
E))
3231template <
class Emitter>
3233 return this->emitConst(
E->getPackLength(),
E);
3236template <
class Emitter>
3239 return this->delegate(
E->getResultExpr());
3242template <
class Emitter>
3244 return this->delegate(
E->getChosenSubExpr());
3247template <
class Emitter>
3252 return this->emitConst(
E->getValue(),
E);
3255template <
class Emitter>
3260 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
3261 const Function *F = this->getFunction(Ctor);
3278 if (!this->emitGetParam(PT, Offset,
E))
3283 return this->emitCall(F, 0,
E);
3286template <
class Emitter>
3290 QualType ElementType =
E->getAllocatedType();
3291 std::optional<PrimType> ElemT = classify(ElementType);
3292 unsigned PlacementArgs =
E->getNumPlacementArgs();
3294 const Expr *PlacementDest =
nullptr;
3295 bool IsNoThrow =
false;
3297 if (PlacementArgs != 0) {
3306 if (PlacementArgs == 1) {
3307 const Expr *Arg1 =
E->getPlacementArg(0);
3309 if (!this->discard(Arg1))
3314 if (!this->emitInvalidNewDeleteExpr(
E,
E))
3319 if (OperatorNew->isReservedGlobalPlacementOperator())
3320 PlacementDest = Arg1;
3324 return this->emitInvalid(
E);
3326 }
else if (!OperatorNew->isReplaceableGlobalAllocationFunction())
3327 return this->emitInvalidNewDeleteExpr(
E,
E);
3330 if (!PlacementDest) {
3339 Desc =
P.createDescriptor(
3342 false,
false,
false,
Init);
3347 std::optional<const Expr *> ArraySizeExpr =
E->getArraySize();
3351 const Expr *Stripped = *ArraySizeExpr;
3352 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
3353 Stripped = ICE->getSubExpr())
3354 if (ICE->getCastKind() != CK_NoOp &&
3355 ICE->getCastKind() != CK_IntegralCast)
3360 if (PlacementDest) {
3361 if (!this->visit(PlacementDest))
3363 if (!this->visit(Stripped))
3365 if (!this->emitCheckNewTypeMismatchArray(SizeT,
E,
E))
3368 if (!this->visit(Stripped))
3373 if (!this->emitAllocN(SizeT, *ElemT,
E, IsNoThrow,
E))
3377 if (!this->emitAllocCN(SizeT, Desc, IsNoThrow,
E))
3382 if (
Init && !this->visitInitializer(
Init))
3386 if (PlacementDest) {
3387 if (!this->visit(PlacementDest))
3389 if (!this->emitCheckNewTypeMismatch(
E,
E))
3393 if (!this->emitAlloc(Desc,
E))
3399 if (!this->visit(
Init))
3402 if (!this->emitInit(*ElemT,
E))
3406 if (!this->visitInitializer(
Init))
3413 return this->emitPopPtr(
E);
3418template <
class Emitter>
3420 const Expr *Arg =
E->getArgument();
3422 const FunctionDecl *OperatorDelete =
E->getOperatorDelete();
3424 if (!OperatorDelete->isReplaceableGlobalAllocationFunction())
3425 return this->emitInvalidNewDeleteExpr(
E,
E);
3428 if (!this->visit(Arg))
3431 return this->emitFree(
E->isArrayForm(),
E->isGlobalDelete(),
E);
3434template <
class Emitter>
3445 return this->emitGetFnPtr(
Func,
E);
3448template <
class Emitter>
3452 if (!
E->isPotentiallyEvaluated()) {
3456 if (
E->isTypeOperand())
3457 return this->emitGetTypeid(
3458 E->getTypeOperand(Ctx.getASTContext()).getTypePtr(), TypeInfoType,
E);
3464 assert(
E->getExprOperand());
3465 assert(
E->getExprOperand()->
isLValue());
3467 if (!Ctx.
getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(
E))
3470 if (!this->visit(
E->getExprOperand()))
3473 if (!this->emitGetTypeidPtr(TypeInfoType,
E))
3476 return this->emitPopPtr(
E);
3480template <
class Emitter>
3483 return this->emitConstBool(
E->getValue(),
E);
3486template <
class Emitter>
3498 return this->emitDummyPtr(GuidDecl,
E);
3500 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(GuidDecl);
3503 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
3506 assert(this->getRecord(
E->
getType()));
3512 assert(
V.isStruct());
3513 assert(
V.getStructNumBases() == 0);
3514 if (!this->visitAPValueInitializer(
V,
E))
3517 return this->emitFinishInit(
E);
3520template <
class Emitter>
3525 return this->emitConstBool(
E->isSatisfied(),
E);
3528template <
class Emitter>
3534 return this->emitConstBool(
E->isSatisfied(),
E);
3537template <
class Emitter>
3540 return this->delegate(
E->getSemanticForm());
3543template <
class Emitter>
3546 for (
const Expr *SemE :
E->semantics()) {
3547 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
3548 if (SemE ==
E->getResultExpr())
3551 if (OVE->isUnique())
3554 if (!this->discard(OVE))
3556 }
else if (SemE ==
E->getResultExpr()) {
3557 if (!this->delegate(SemE))
3560 if (!this->discard(SemE))
3567template <
class Emitter>
3569 return this->delegate(
E->getSelectedExpr());
3572template <
class Emitter>
3574 return this->emitError(
E);
3577template <
class Emitter>
3581 unsigned Offset = allocateLocalPrimitive(
3582 E->getLabel(),
PT_Ptr,
true,
false);
3584 return this->emitGetLocal(
PT_Ptr, Offset,
E);
3587template <
class Emitter>
3591 QualType ElemType = VT->getElementType();
3592 PrimType ElemT = classifyPrim(ElemType);
3593 const Expr *Src =
E->getSrcExpr();
3595 PrimType SrcElemT = classifyVectorElementType(SrcType);
3597 unsigned SrcOffset = this->allocateLocalPrimitive(Src,
PT_Ptr,
true,
false);
3598 if (!this->visit(Src))
3600 if (!this->emitSetLocal(
PT_Ptr, SrcOffset,
E))
3603 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
3604 if (!this->emitGetLocal(
PT_Ptr, SrcOffset,
E))
3606 if (!this->emitArrayElemPop(SrcElemT, I,
E))
3610 if (SrcElemT != ElemT) {
3611 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType,
E))
3613 }
else if (ElemType->isFloatingType() && SrcType != ElemType) {
3614 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
3618 if (!this->emitInitElem(ElemT, I,
E))
3625template <
class Emitter>
3628 assert(
E->getNumSubExprs() > 2);
3630 const Expr *Vecs[] = {
E->getExpr(0),
E->getExpr(1)};
3634 unsigned NumOutputElems =
E->getNumSubExprs() - 2;
3635 assert(NumOutputElems > 0);
3638 unsigned VectorOffsets[2];
3639 for (
unsigned I = 0; I != 2; ++I) {
3640 VectorOffsets[I] = this->allocateLocalPrimitive(
3641 Vecs[I],
PT_Ptr,
true,
false);
3642 if (!this->visit(Vecs[I]))
3644 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I],
E))
3647 for (
unsigned I = 0; I != NumOutputElems; ++I) {
3648 APSInt ShuffleIndex =
E->getShuffleMaskIdx(Ctx.getASTContext(), I);
3649 assert(ShuffleIndex >= -1);
3650 if (ShuffleIndex == -1)
3651 return this->emitInvalidShuffleVectorIndex(I,
E);
3653 assert(ShuffleIndex < (NumInputElems * 2));
3654 if (!this->emitGetLocal(
PT_Ptr,
3655 VectorOffsets[ShuffleIndex >= NumInputElems],
E))
3657 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
3658 if (!this->emitArrayElemPop(ElemT, InputVectorIndex,
E))
3661 if (!this->emitInitElem(ElemT, I,
E))
3668template <
class Emitter>
3673 Base->getType()->isVectorType() ||
3677 E->getEncodedElementAccess(Indices);
3679 if (Indices.size() == 1) {
3680 if (!this->visit(
Base))
3684 if (!this->emitConstUint32(Indices[0],
E))
3686 return this->emitArrayElemPtrPop(
PT_Uint32,
E);
3689 return this->emitArrayElemPop(classifyPrim(
E->
getType()), Indices[0],
E);
3693 unsigned BaseOffset = allocateLocalPrimitive(
Base,
PT_Ptr,
true,
3695 if (!this->visit(
Base))
3697 if (!this->emitSetLocal(
PT_Ptr, BaseOffset,
E))
3702 std::optional<unsigned> ResultIndex;
3703 ResultIndex = allocateLocal(
E);
3706 if (!this->emitGetPtrLocal(*ResultIndex,
E))
3714 uint32_t DstIndex = 0;
3715 for (uint32_t I : Indices) {
3716 if (!this->emitGetLocal(
PT_Ptr, BaseOffset,
E))
3718 if (!this->emitArrayElemPop(ElemT, I,
E))
3720 if (!this->emitInitElem(ElemT, DstIndex,
E))
3726 assert(!DiscardResult);
3730template <
class Emitter>
3732 const Expr *SubExpr =
E->getSubExpr();
3733 if (!
E->isExpressibleAsConstantInitializer())
3734 return this->discard(SubExpr) && this->emitInvalid(
E);
3739 assert(classifyPrim(
E) ==
PT_Ptr);
3740 return this->emitDummyPtr(
E,
E);
3743template <
class Emitter>
3746 const Expr *SubExpr =
E->getSubExpr();
3753 if (!this->visit(SubExpr))
3755 if (!this->emitConstUint8(0,
E))
3757 if (!this->emitArrayElemPtrPopUint8(
E))
3769 assert(SecondFieldT ==
PT_Ptr);
3773 if (!this->emitExpandPtr(
E))
3777 if (!this->emitArrayElemPtrPop(
PT_Uint64,
E))
3782template <
class Emitter>
3791 if (!this->visitStmt(S))
3796 assert(S == Result);
3797 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
3798 return this->delegate(ResultExpr);
3799 return this->emitUnsupported(
E);
3808 return this->Visit(
E);
3815 return this->Visit(
E);
3823 return this->discard(
E);
3828 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3832 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3835 return this->visitInitializer(
E);
3842 return this->Visit(
E);
3845template <
class Emitter>
3851 return this->Visit(
E);
3855 std::optional<PrimType>
T = classify(
E->
getType());
3859 if (!this->visit(
E))
3861 return this->emitComplexBoolCast(
E);
3866 if (!this->visit(
E))
3874 if (!this->emitNull(*
T, 0,
nullptr,
E))
3876 return this->emitNE(*
T,
E);
3881 return this->emitCastFloatingIntegralBool(getFPOptions(
E),
E);
3887template <
class Emitter>
3892 return this->emitZeroBool(
E);
3894 return this->emitZeroSint8(
E);
3896 return this->emitZeroUint8(
E);
3898 return this->emitZeroSint16(
E);
3900 return this->emitZeroUint16(
E);
3902 return this->emitZeroSint32(
E);
3904 return this->emitZeroUint32(
E);
3906 return this->emitZeroSint64(
E);
3908 return this->emitZeroUint64(
E);
3910 return this->emitZeroIntAP(Ctx.getBitWidth(QT),
E);
3912 return this->emitZeroIntAPS(Ctx.getBitWidth(QT),
E);
3917 return this->emitNullFnPtr(0,
nullptr,
E);
3919 return this->emitNullMemberPtr(0,
nullptr,
E);
3921 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)),
E);
3926 llvm_unreachable(
"Implement");
3928 llvm_unreachable(
"unknown primitive type");
3931template <
class Emitter>
3937 for (
const Record::Field &Field : R->
fields()) {
3938 if (
Field.Decl->isUnnamedBitField())
3942 if (
D->isPrimitive()) {
3945 if (!this->visitZeroInitializer(
T, QT,
E))
3947 if (!this->emitInitField(
T,
Field.Offset,
E))
3954 if (!this->emitGetPtrField(
Field.Offset,
E))
3957 if (
D->isPrimitiveArray()) {
3960 for (uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
3961 if (!this->visitZeroInitializer(
T, ET,
E))
3963 if (!this->emitInitElem(
T, I,
E))
3966 }
else if (
D->isCompositeArray()) {
3968 if (!this->visitZeroArrayInitializer(
D->getType(),
E))
3970 }
else if (
D->isRecord()) {
3971 if (!this->visitZeroRecordInitializer(
D->ElemRecord,
E))
3977 if (!this->emitFinishInitPop(
E))
3986 for (
const Record::Base &B : R->
bases()) {
3987 if (!this->emitGetPtrBase(B.Offset,
E))
3989 if (!this->visitZeroRecordInitializer(B.R,
E))
3991 if (!this->emitFinishInitPop(
E))
4000template <
class Emitter>
4005 size_t NumElems = cast<ConstantArrayType>(AT)->getZExtSize();
4007 if (std::optional<PrimType> ElemT = classify(ElemType)) {
4008 for (
size_t I = 0; I != NumElems; ++I) {
4009 if (!this->visitZeroInitializer(*ElemT, ElemType,
E))
4011 if (!this->emitInitElem(*ElemT, I,
E))
4016 const Record *R = getRecord(ElemType);
4018 for (
size_t I = 0; I != NumElems; ++I) {
4019 if (!this->emitConstUint32(I,
E))
4023 if (!this->visitZeroRecordInitializer(R,
E))
4025 if (!this->emitPopPtr(
E))
4030 for (
size_t I = 0; I != NumElems; ++I) {
4031 if (!this->emitConstUint32(I,
E))
4035 if (!this->visitZeroArrayInitializer(ElemType,
E))
4037 if (!this->emitPopPtr(
E))
4046template <
class Emitter>
4047template <
typename T>
4051 return this->emitConstSint8(
Value,
E);
4053 return this->emitConstUint8(
Value,
E);
4055 return this->emitConstSint16(
Value,
E);
4057 return this->emitConstUint16(
Value,
E);
4059 return this->emitConstSint32(
Value,
E);
4061 return this->emitConstUint32(
Value,
E);
4063 return this->emitConstSint64(
Value,
E);
4065 return this->emitConstUint64(
Value,
E);
4067 return this->emitConstBool(
Value,
E);
4075 llvm_unreachable(
"Invalid integral type");
4078 llvm_unreachable(
"unknown primitive type");
4081template <
class Emitter>
4082template <
typename T>
4087template <
class Emitter>
4091 return this->emitConstIntAPS(
Value,
E);
4093 return this->emitConstIntAP(
Value,
E);
4095 if (
Value.isSigned())
4096 return this->emitConst(
Value.getSExtValue(), Ty,
E);
4097 return this->emitConst(
Value.getZExtValue(), Ty,
E);
4100template <
class Emitter>
4105template <
class Emitter>
4110 if (
const auto *VD =
4111 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4112 assert(!
P.getGlobal(VD));
4113 assert(!Locals.contains(VD));
4121 isa<const Expr *>(Src));
4123 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
4124 Locals.insert({VD, Local});
4125 VarScope->add(Local, IsExtended);
4126 return Local.Offset;
4129template <
class Emitter>
4130std::optional<unsigned>
4134 if ([[maybe_unused]]
const auto *VD =
4135 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4136 assert(!
P.getGlobal(VD));
4137 assert(!Locals.contains(VD));
4142 bool IsTemporary =
false;
4143 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4147 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
4148 Init = VarD->getInit();
4150 if (
auto *
E = Src.dyn_cast<
const Expr *>()) {
4158 IsTemporary,
false,
Init);
4160 return std::nullopt;
4164 Locals.insert({Key, Local});
4166 VarScope->addExtended(Local, ExtendingDecl);
4168 VarScope->add(Local,
false);
4169 return Local.Offset;
4172template <
class Emitter>
4179 true,
false,
nullptr);
4186 while (S->getParent())
4188 assert(S && !S->getParent());
4190 return Local.Offset;
4193template <
class Emitter>
4195 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
4201 if (
const auto *RecordTy = getRecordTy(Ty))
4202 return getRecord(RecordTy->getDecl());
4206template <
class Emitter>
4208 return P.getOrCreateRecord(RD);
4211template <
class Emitter>
4213 return Ctx.getOrCreateFunction(FD);
4216template <
class Emitter>
4221 if (!DestroyToplevelScope) {
4222 if (!this->emitCheckAllocations(
E))
4226 auto maybeDestroyLocals = [&]() ->
bool {
4227 if (DestroyToplevelScope)
4228 return RootScope.
destroyLocals() && this->emitCheckAllocations(
E);
4229 return this->emitCheckAllocations(
E);
4236 return this->emitRetVoid(
E) && maybeDestroyLocals();
4240 if (std::optional<PrimType>
T = classify(
E)) {
4244 return this->emitRet(*
T,
E) && maybeDestroyLocals();
4250 if (std::optional<unsigned> LocalOffset = this->allocateLocal(
E)) {
4252 if (!this->emitGetPtrLocal(*LocalOffset,
E))
4255 if (!visitInitializer(
E))
4258 if (!this->emitFinishInit(
E))
4263 return this->emitRetValue(
E) && maybeDestroyLocals();
4266 return maybeDestroyLocals() && this->emitCheckAllocations(
E) &&
false;
4269template <
class Emitter>
4272 auto R = this->visitVarDecl(VD,
true);
4281 if (
auto GlobalIndex =
P.getGlobal(VD)) {
4282 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
4286 GD.
InitState = GlobalInitState::InitializerFailed;
4297template <
class Emitter>
4299 bool ConstantContext) {
4300 std::optional<PrimType> VarT = classify(VD->
getType());
4304 if (!ConstantContext) {
4309 this->emitCheckAllocations(VD);
4313 if (!this->visitVarDecl(VD,
true))
4317 auto GlobalIndex =
P.getGlobal(VD);
4318 assert(GlobalIndex);
4320 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
4323 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
4327 auto Local = Locals.find(VD);
4328 assert(Local != Locals.end());
4330 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
4333 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
4339 if (!this->emitRet(VarT.value_or(
PT_Ptr), VD)) {
4343 auto GlobalIndex =
P.getGlobal(VD);
4344 assert(GlobalIndex);
4345 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
4349 GD.
InitState = GlobalInitState::InitializerFailed;
4355 return VDScope.
destroyLocals() && this->emitCheckAllocations(VD);
4358template <
class Emitter>
4367 if (!this->isActive())
4371 std::optional<PrimType> VarT = classify(VD->
getType());
4373 if (
Init &&
Init->isValueDependent())
4377 auto checkDecl = [&]() ->
bool {
4379 return !NeedsOp || this->emitCheckDecl(VD, VD);
4382 auto initGlobal = [&](
unsigned GlobalIndex) ->
bool {
4386 if (!this->visit(
Init))
4387 return checkDecl() &&
false;
4389 return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
4395 if (!this->emitGetPtrGlobal(GlobalIndex,
Init))
4398 if (!visitInitializer(
Init))
4401 if (!this->emitFinishInit(
Init))
4404 return this->emitPopPtr(
Init);
4410 if (std::optional<unsigned> GlobalIndex =
P.getGlobal(VD)) {
4411 if (
P.getPtrGlobal(*GlobalIndex).isInitialized())
4416 return Init && checkDecl() && initGlobal(*GlobalIndex);
4419 std::optional<unsigned> GlobalIndex =
P.createGlobal(VD,
Init);
4424 return !
Init || (checkDecl() && initGlobal(*GlobalIndex));
4429 unsigned Offset = this->allocateLocalPrimitive(
4436 if (!this->visit(
Init))
4438 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
4440 if (!this->visit(
Init))
4442 return this->emitSetLocal(*VarT, Offset, VD);
4446 if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
4450 if (!this->emitGetPtrLocal(*Offset,
Init))
4453 if (!visitInitializer(
Init))
4456 if (!this->emitFinishInit(
Init))
4459 return this->emitPopPtr(
Init);
4469template <
class Emitter>
4472 assert(!DiscardResult);
4474 return this->emitConst(Val.
getInt(), ValType,
E);
4476 return this->emitConstFloat(Val.
getFloat(),
E);
4480 return this->emitNull(ValType, 0,
nullptr,
E);
4482 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
4483 return this->visit(BaseExpr);
4484 else if (
const auto *VD =
Base.dyn_cast<
const ValueDecl *>()) {
4485 return this->visitDeclRef(VD,
E);
4489 return this->emitGetMemberPtr(MemberDecl,
E);
4490 return this->emitNullMemberPtr(0,
nullptr,
E);
4496template <
class Emitter>
4505 const Record::Field *RF = R->
getField(I);
4508 PrimType T = classifyPrim(RF->Decl->getType());
4509 if (!this->visitAPValue(F,
T,
E))
4511 if (!this->emitInitField(
T, RF->Offset,
E))
4514 assert(RF->Desc->isPrimitiveArray());
4515 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
4516 PrimType ElemT = classifyPrim(ArrType->getElementType());
4519 if (!this->emitGetPtrField(RF->Offset,
E))
4522 for (
unsigned A = 0, AN = F.
getArraySize(); A != AN; ++A) {
4525 if (!this->emitInitElem(ElemT, A,
E))
4529 if (!this->emitPopPtr(
E))
4532 if (!this->emitGetPtrField(RF->Offset,
E))
4534 if (!this->visitAPValueInitializer(F,
E))
4536 if (!this->emitPopPtr(
E))
4539 assert(
false &&
"I don't think this should be possible");
4548 const Record::Field *RF = R->
getField(UnionField);
4549 PrimType T = classifyPrim(RF->Decl->getType());
4550 if (!this->visitAPValue(F,
T,
E))
4552 return this->emitInitField(
T, RF->Offset,
E);
4559template <
class Emitter>
4561 unsigned BuiltinID) {
4568 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
4569 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
4570 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
4571 BuiltinID == Builtin::BI__builtin_function_start) {
4574 return this->emitDummyPtr(
E,
E);
4578 std::optional<PrimType> ReturnT = classify(
E);
4582 std::optional<unsigned> LocalIndex = allocateLocal(
E);
4585 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4589 if (!
Func->isUnevaluatedBuiltin()) {
4591 for (
const auto *Arg :
E->arguments()) {
4592 if (!this->visit(Arg))
4597 if (!this->emitCallBI(
Func,
E, BuiltinID,
E))
4600 if (DiscardResult && !ReturnType->
isVoidType()) {
4602 return this->emitPop(*ReturnT,
E);
4608template <
class Emitter>
4610 if (
unsigned BuiltinID =
E->getBuiltinCallee())
4611 return VisitBuiltinCallExpr(
E, BuiltinID);
4618 return VisitBuiltinCallExpr(
E, Builtin::BI__builtin_operator_new);
4621 return VisitBuiltinCallExpr(
E, Builtin::BI__builtin_operator_delete);
4625 if (
const auto *DD = dyn_cast_if_present<CXXDestructorDecl>(FuncDecl);
4626 DD && DD->isTrivial())
4629 QualType ReturnType =
E->getCallReturnType(Ctx.getASTContext());
4630 std::optional<PrimType>
T = classify(ReturnType);
4634 if (DiscardResult) {
4638 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4639 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4646 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4647 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4651 if (!this->emitDupPtr(
E))
4659 bool IsAssignmentOperatorCall =
false;
4660 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
4661 OCE && OCE->isAssignmentOp()) {
4665 assert(Args.size() == 2);
4666 IsAssignmentOperatorCall =
true;
4667 std::reverse(Args.begin(), Args.end());
4672 if (isa<CXXOperatorCallExpr>(
E)) {
4673 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
4674 MD && MD->isStatic()) {
4675 if (!this->discard(
E->getArg(0)))
4678 Args.erase(Args.begin());
4682 std::optional<unsigned> CalleeOffset;
4684 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(
E)) {
4685 if (!FuncDecl && classifyPrim(
E->getCallee()) ==
PT_MemberPtr) {
4689 const Expr *Callee =
E->getCallee();
4691 this->allocateLocalPrimitive(Callee,
PT_MemberPtr,
true,
false);
4692 if (!this->visit(Callee))
4698 if (!this->emitGetMemberPtrBase(
E))
4700 }
else if (!this->visit(MC->getImplicitObjectArgument())) {
4703 }
else if (!FuncDecl) {
4704 const Expr *Callee =
E->getCallee();
4705 CalleeOffset = this->allocateLocalPrimitive(Callee,
PT_FnPtr,
true,
false);
4706 if (!this->visit(Callee))
4708 if (!this->emitSetLocal(
PT_FnPtr, *CalleeOffset,
E))
4714 unsigned ArgIndex = 0;
4715 for (
const auto *Arg : Args) {
4716 if (!this->visit(Arg))
4720 if (FuncDecl && NonNullArgs[ArgIndex]) {
4723 if (!this->emitCheckNonNullArg(ArgT, Arg))
4731 if (IsAssignmentOperatorCall) {
4732 assert(Args.size() == 2);
4735 if (!this->emitFlip(Arg2T, Arg1T,
E))
4743 assert(HasRVO ==
Func->hasRVO());
4745 bool HasQualifier =
false;
4746 if (
const auto *ME = dyn_cast<MemberExpr>(
E->getCallee()))
4747 HasQualifier = ME->hasQualifier();
4749 bool IsVirtual =
false;
4750 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
4751 IsVirtual = MD->isVirtual();
4756 if (IsVirtual && !HasQualifier) {
4757 uint32_t VarArgSize = 0;
4758 unsigned NumParams =
4759 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4760 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4763 if (!this->emitCallVirt(
Func, VarArgSize,
E))
4765 }
else if (
Func->isVariadic()) {
4766 uint32_t VarArgSize = 0;
4767 unsigned NumParams =
4768 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4769 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4771 if (!this->emitCallVar(
Func, VarArgSize,
E))
4774 if (!this->emitCall(
Func, 0,
E))
4783 uint32_t ArgSize = 0;
4784 for (
unsigned I = 0, N =
E->getNumArgs(); I != N; ++I)
4789 if (isa<CXXMemberCallExpr>(
E) && CalleeOffset) {
4792 if (!this->emitGetMemberPtrDecl(
E))
4795 if (!this->emitGetLocal(
PT_FnPtr, *CalleeOffset,
E))
4798 if (!this->emitCallPtr(ArgSize,
E,
E))
4803 if (DiscardResult && !ReturnType->
isVoidType() &&
T)
4804 return this->emitPop(*
T,
E);
4809template <
class Emitter>
4813 return this->delegate(
E->getExpr());
4816template <
class Emitter>
4820 return this->delegate(
E->getExpr());
4823template <
class Emitter>
4828 return this->emitConstBool(
E->getValue(),
E);
4831template <
class Emitter>
4838 return this->emitNullPtr(Val,
nullptr,
E);
4841template <
class Emitter>
4849 return this->emitZero(
T,
E);
4852template <
class Emitter>
4857 if (this->LambdaThisCapture.Offset > 0) {
4858 if (this->LambdaThisCapture.IsPtr)
4859 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset,
E);
4860 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset,
E);
4867 if (!InitStackActive)
4868 return this->emitThis(
E);
4870 if (!InitStack.empty()) {
4884 unsigned StartIndex = 0;
4885 unsigned EndIndex = 0;
4887 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
4890 EndIndex = StartIndex;
4897 for (; StartIndex > 0; --StartIndex) {
4907 for (
unsigned I = StartIndex; I != EndIndex; ++I) {
4910 if (!InitStack[I].
template emit<Emitter>(
this,
E))
4915 return this->emitThis(
E);
4919 switch (S->getStmtClass()) {
4920 case Stmt::CompoundStmtClass:
4921 return visitCompoundStmt(cast<CompoundStmt>(S));
4922 case Stmt::DeclStmtClass:
4923 return visitDeclStmt(cast<DeclStmt>(S));
4924 case Stmt::ReturnStmtClass:
4925 return visitReturnStmt(cast<ReturnStmt>(S));
4926 case Stmt::IfStmtClass:
4927 return visitIfStmt(cast<IfStmt>(S));
4928 case Stmt::WhileStmtClass:
4929 return visitWhileStmt(cast<WhileStmt>(S));
4930 case Stmt::DoStmtClass:
4931 return visitDoStmt(cast<DoStmt>(S));
4932 case Stmt::ForStmtClass:
4933 return visitForStmt(cast<ForStmt>(S));
4934 case Stmt::CXXForRangeStmtClass:
4935 return visitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
4936 case Stmt::BreakStmtClass:
4937 return visitBreakStmt(cast<BreakStmt>(S));
4938 case Stmt::ContinueStmtClass:
4939 return visitContinueStmt(cast<ContinueStmt>(S));
4940 case Stmt::SwitchStmtClass:
4941 return visitSwitchStmt(cast<SwitchStmt>(S));
4942 case Stmt::CaseStmtClass:
4943 return visitCaseStmt(cast<CaseStmt>(S));
4944 case Stmt::DefaultStmtClass:
4945 return visitDefaultStmt(cast<DefaultStmt>(S));
4946 case Stmt::AttributedStmtClass:
4947 return visitAttributedStmt(cast<AttributedStmt>(S));
4948 case Stmt::CXXTryStmtClass:
4949 return visitCXXTryStmt(cast<CXXTryStmt>(S));
4950 case Stmt::NullStmtClass:
4953 case Stmt::GCCAsmStmtClass:
4954 case Stmt::MSAsmStmtClass:
4955 case Stmt::GotoStmtClass:
4956 return this->emitInvalid(S);
4957 case Stmt::LabelStmtClass:
4958 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
4960 if (
const auto *
E = dyn_cast<Expr>(S))
4961 return this->discard(
E);
4967template <
class Emitter>
4970 for (
const auto *InnerStmt : S->body())
4971 if (!visitStmt(InnerStmt))
4973 return Scope.destroyLocals();
4976template <
class Emitter>
4978 for (
const auto *
D : DS->
decls()) {
4983 const auto *VD = dyn_cast<VarDecl>(
D);
4986 if (!this->visitVarDecl(VD))
4990 if (
const auto *DD = dyn_cast<DecompositionDecl>(VD)) {
4991 for (
auto *BD : DD->bindings())
4992 if (
auto *KD = BD->getHoldingVar()) {
4993 if (!this->visitVarDecl(KD))
5002template <
class Emitter>
5004 if (this->InStmtExpr)
5005 return this->emitUnsupported(RS);
5011 if (!this->visit(RE))
5013 this->emitCleanup();
5014 return this->emitRet(*ReturnType, RS);
5015 }
else if (RE->getType()->isVoidType()) {
5016 if (!this->visit(RE))
5021 if (!this->emitRVOPtr(RE))
5023 if (!this->visitInitializer(RE))
5025 if (!this->emitPopPtr(RE))
5028 this->emitCleanup();
5029 return this->emitRetVoid(RS);
5034 this->emitCleanup();
5035 return this->emitRetVoid(RS);
5039 if (
auto *CondInit = IS->
getInit())
5040 if (!visitStmt(CondInit))
5044 if (!visitDeclStmt(CondDecl))
5049 if (!this->emitIsConstantContext(IS))
5052 if (!this->emitIsConstantContext(IS))
5054 if (!this->emitInv(IS))
5057 if (!this->visitBool(IS->
getCond()))
5062 LabelTy LabelElse = this->getLabel();
5063 LabelTy LabelEnd = this->getLabel();
5064 if (!this->jumpFalse(LabelElse))
5068 if (!visitStmt(IS->
getThen()))
5073 if (!this->jump(LabelEnd))
5075 this->emitLabel(LabelElse);
5078 if (!visitStmt(Else))
5083 this->emitLabel(LabelEnd);
5085 LabelTy LabelEnd = this->getLabel();
5086 if (!this->jumpFalse(LabelEnd))
5090 if (!visitStmt(IS->
getThen()))
5095 this->emitLabel(LabelEnd);
5101template <
class Emitter>
5103 const Expr *Cond = S->getCond();
5104 const Stmt *Body = S->getBody();
5106 LabelTy CondLabel = this->getLabel();
5107 LabelTy EndLabel = this->getLabel();
5110 this->fallthrough(CondLabel);
5111 this->emitLabel(CondLabel);
5115 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5116 if (!visitDeclStmt(CondDecl))
5119 if (!this->visitBool(Cond))
5121 if (!this->jumpFalse(EndLabel))
5124 if (!this->visitStmt(Body))
5130 if (!this->jump(CondLabel))
5132 this->fallthrough(EndLabel);
5133 this->emitLabel(EndLabel);
5139 const Expr *Cond = S->getCond();
5140 const Stmt *Body = S->getBody();
5142 LabelTy StartLabel = this->getLabel();
5143 LabelTy EndLabel = this->getLabel();
5144 LabelTy CondLabel = this->getLabel();
5147 this->fallthrough(StartLabel);
5148 this->emitLabel(StartLabel);
5152 if (!this->visitStmt(Body))
5154 this->fallthrough(CondLabel);
5155 this->emitLabel(CondLabel);
5156 if (!this->visitBool(Cond))
5162 if (!this->jumpTrue(StartLabel))
5165 this->fallthrough(EndLabel);
5166 this->emitLabel(EndLabel);
5170template <
class Emitter>
5174 const Expr *Cond = S->getCond();
5175 const Expr *
Inc = S->getInc();
5176 const Stmt *Body = S->getBody();
5178 LabelTy EndLabel = this->getLabel();
5179 LabelTy CondLabel = this->getLabel();
5180 LabelTy IncLabel = this->getLabel();
5183 if (
Init && !this->visitStmt(
Init))
5186 this->fallthrough(CondLabel);
5187 this->emitLabel(CondLabel);
5191 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5192 if (!visitDeclStmt(CondDecl))
5196 if (!this->visitBool(Cond))
5198 if (!this->jumpFalse(EndLabel))
5202 if (Body && !this->visitStmt(Body))
5205 this->fallthrough(IncLabel);
5206 this->emitLabel(IncLabel);
5207 if (
Inc && !this->discard(
Inc))
5213 if (!this->jump(CondLabel))
5216 this->fallthrough(EndLabel);
5217 this->emitLabel(EndLabel);
5221template <
class Emitter>
5224 const Expr *Cond = S->getCond();
5225 const Expr *
Inc = S->getInc();
5226 const Stmt *Body = S->getBody();
5227 const Stmt *BeginStmt = S->getBeginStmt();
5228 const Stmt *RangeStmt = S->getRangeStmt();
5229 const Stmt *EndStmt = S->getEndStmt();
5230 const VarDecl *LoopVar = S->getLoopVariable();
5232 LabelTy EndLabel = this->getLabel();
5233 LabelTy CondLabel = this->getLabel();
5234 LabelTy IncLabel = this->getLabel();
5238 if (
Init && !this->visitStmt(
Init))
5240 if (!this->visitStmt(RangeStmt))
5242 if (!this->visitStmt(BeginStmt))
5244 if (!this->visitStmt(EndStmt))
5248 this->fallthrough(CondLabel);
5249 this->emitLabel(CondLabel);
5250 if (!this->visitBool(Cond))
5252 if (!this->jumpFalse(EndLabel))
5255 if (!this->visitVarDecl(LoopVar))
5260 if (!this->visitStmt(Body))
5263 this->fallthrough(IncLabel);
5264 this->emitLabel(IncLabel);
5265 if (!this->discard(
Inc))
5269 if (!this->jump(CondLabel))
5272 this->fallthrough(EndLabel);
5273 this->emitLabel(EndLabel);
5277template <
class Emitter>
5284 C->emitDestruction();
5285 return this->jump(*BreakLabel);
5288template <
class Emitter>
5294 C &&
C->getParent() != ContinueVarScope;
C =
C->getParent())
5295 C->emitDestruction();
5296 return this->jump(*ContinueLabel);
5299template <
class Emitter>
5301 const Expr *Cond = S->getCond();
5305 LabelTy EndLabel = this->getLabel();
5307 unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT,
true,
false);
5309 if (
const auto *CondInit = S->getInit())
5310 if (!visitStmt(CondInit))
5313 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5314 if (!visitDeclStmt(CondDecl))
5318 if (!this->visit(Cond))
5320 if (!this->emitSetLocal(CondT, CondVar, S))
5325 for (
const SwitchCase *SC = S->getSwitchCaseList(); SC;
5326 SC = SC->getNextSwitchCase()) {
5327 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
5329 if (CS->caseStmtIsGNURange())
5331 CaseLabels[SC] = this->getLabel();
5337 if (!this->emitGetLocal(CondT, CondVar, CS))
5339 if (!this->visit(
Value))
5343 if (!this->emitEQ(ValueT, S))
5345 if (!this->jumpTrue(CaseLabels[CS]))
5348 assert(!DefaultLabel);
5349 DefaultLabel = this->getLabel();
5356 if (!this->jump(*DefaultLabel))
5359 if (!this->jump(EndLabel))
5364 if (!this->visitStmt(S->getBody()))
5366 this->emitLabel(EndLabel);
5371template <
class Emitter>
5373 this->emitLabel(CaseLabels[S]);
5374 return this->visitStmt(S->getSubStmt());
5377template <
class Emitter>
5379 this->emitLabel(*DefaultLabel);
5380 return this->visitStmt(S->getSubStmt());
5383template <
class Emitter>
5386 !this->Ctx.getLangOpts().MSVCCompat) {
5387 for (
const Attr *A : S->getAttrs()) {
5388 auto *AA = dyn_cast<CXXAssumeAttr>(A);
5392 assert(isa<NullStmt>(S->getSubStmt()));
5394 const Expr *Assumption = AA->getAssumption();
5402 if (!this->visitBool(Assumption))
5405 if (!this->emitAssume(Assumption))
5411 return this->visitStmt(S->getSubStmt());
5414template <
class Emitter>
5417 return this->visitStmt(S->getTryBlock());
5420template <
class Emitter>
5424 assert(cast<CompoundStmt>(MD->
getBody())->body_empty());
5429 const Function *
Func = this->getFunction(LambdaCallOp);
5432 assert(
Func->hasThisPointer());
5435 if (
Func->hasRVO()) {
5436 if (!this->emitRVOPtr(MD))
5444 if (!this->emitNullPtr(0,
nullptr, MD))
5449 auto It = this->Params.find(PVD);
5450 assert(It != this->Params.end());
5454 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
5455 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
5459 if (!this->emitCall(
Func, 0, LambdaCallOp))
5462 this->emitCleanup();
5464 return this->emitRet(*ReturnType, MD);
5467 return this->emitRetVoid(MD);
5470template <
class Emitter>
5481template <
class Emitter>
5483 assert(!ReturnType);
5485 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
5486 const Expr *InitExpr) ->
bool {
5488 if (InitExpr->getType().isNull())
5491 if (std::optional<PrimType>
T = this->classify(InitExpr)) {
5492 if (!this->visit(InitExpr))
5495 if (F->isBitField())
5496 return this->emitInitThisBitField(*
T, F, FieldOffset, InitExpr);
5497 return this->emitInitThisField(*
T, FieldOffset, InitExpr);
5502 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
5505 if (!this->visitInitializer(InitExpr))
5508 return this->emitFinishInitPop(InitExpr);
5512 const Record *R = this->getRecord(RD);
5518 assert(cast<CompoundStmt>(Ctor->
getBody())->body_empty());
5519 if (!this->emitThis(Ctor))
5528 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
5529 this->emitRetVoid(Ctor);
5533 for (
const auto *
Init : Ctor->
inits()) {
5537 const Expr *InitExpr =
Init->getInit();
5541 if (!emitFieldInitializer(F, F->Offset, InitExpr))
5544 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
5547 if (
Init->isBaseVirtual()) {
5549 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
5555 const Record::Base *B = R->
getBase(BaseDecl);
5557 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
5561 if (!this->visitInitializer(InitExpr))
5563 if (!this->emitFinishInitPop(InitExpr))
5566 assert(IFD->getChainingSize() >= 2);
5568 unsigned NestedFieldOffset = 0;
5569 const Record::Field *NestedField =
nullptr;
5570 for (
const NamedDecl *ND : IFD->chain()) {
5571 const auto *FD = cast<FieldDecl>(ND);
5572 const Record *FieldRecord = this->
P.getOrCreateRecord(FD->getParent());
5573 assert(FieldRecord);
5575 NestedField = FieldRecord->
getField(FD);
5576 assert(NestedField);
5578 NestedFieldOffset += NestedField->Offset;
5580 assert(NestedField);
5582 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
5585 assert(
Init->isDelegatingInitializer());
5586 if (!this->emitThis(InitExpr))
5588 if (!this->visitInitializer(
Init->getInit()))
5590 if (!this->emitPopPtr(InitExpr))
5594 if (!
Scope.destroyLocals())
5598 if (
const auto *Body = Ctor->
getBody())
5599 if (!visitStmt(Body))
5605template <
class Emitter>
5608 const Record *R = this->getRecord(RD);
5613 if (!this->visitStmt(Dtor->
getBody()))
5617 if (!this->emitThis(Dtor))
5623 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
5625 if (!
D->isPrimitive() && !
D->isPrimitiveArray()) {
5636 for (
const Record::Base &
Base : llvm::reverse(R->
bases())) {
5637 if (
Base.R->isAnonymousUnion())
5642 if (!this->emitRecordDestruction(
Base.R, {}))
5649 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
5652template <
class Emitter>
5657 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
5658 return this->compileConstructor(Ctor);
5659 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
5660 return this->compileDestructor(Dtor);
5663 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F);
5665 return this->emitLambdaStaticInvokerBody(MD);
5668 if (
const auto *Body = F->
getBody())
5669 if (!visitStmt(Body))
5678template <
class Emitter>
5680 const Expr *SubExpr =
E->getSubExpr();
5682 return this->VisitComplexUnaryOperator(
E);
5684 return this->VisitVectorUnaryOperator(
E);
5686 return this->VisitFixedPointUnaryOperator(
E);
5687 std::optional<PrimType>
T = classify(SubExpr->
getType());
5689 switch (
E->getOpcode()) {
5692 return this->emitInvalid(
E);
5694 return this->emitError(
E);
5696 if (!this->visit(SubExpr))
5700 if (!this->emitIncPtr(
E))
5703 return DiscardResult ? this->emitPopPtr(
E) :
true;
5707 return DiscardResult ? this->emitIncfPop(getFPOptions(
E),
E)
5708 : this->emitIncf(getFPOptions(
E),
E);
5711 return DiscardResult ? this->emitIncPop(*
T,
E) : this->emitInc(*
T,
E);
5715 return this->emitInvalid(
E);
5717 return this->emitError(
E);
5719 if (!this->visit(SubExpr))
5723 if (!this->emitDecPtr(
E))
5726 return DiscardResult ? this->emitPopPtr(
E) :
true;
5730 return DiscardResult ? this->emitDecfPop(getFPOptions(
E),
E)
5731 : this->emitDecf(getFPOptions(
E),
E);
5734 return DiscardResult ? this->emitDecPop(*
T,
E) : this->emitDec(*
T,
E);
5738 return this->emitInvalid(
E);
5740 return this->emitError(
E);
5742 if (!this->visit(SubExpr))
5746 if (!this->emitLoadPtr(
E))
5748 if (!this->emitConstUint8(1,
E))
5750 if (!this->emitAddOffsetUint8(
E))
5752 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5756 if (DiscardResult) {
5758 return this->emitIncfPop(getFPOptions(
E),
E);
5759 return this->emitIncPop(*
T,
E);
5763 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5764 if (!this->emitLoadFloat(
E))
5766 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5768 if (!this->emitAddf(getFPOptions(
E),
E))
5770 if (!this->emitStoreFloat(
E))
5774 if (!this->emitLoad(*
T,
E))
5776 if (!this->emitConst(1,
E))
5778 if (!this->emitAdd(*
T,
E))
5780 if (!this->emitStore(*
T,
E))
5787 return this->emitInvalid(
E);
5789 return this->emitError(
E);
5791 if (!this->visit(SubExpr))
5795 if (!this->emitLoadPtr(
E))
5797 if (!this->emitConstUint8(1,
E))
5799 if (!this->emitSubOffsetUint8(
E))
5801 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5805 if (DiscardResult) {
5807 return this->emitDecfPop(getFPOptions(
E),
E);
5808 return this->emitDecPop(*
T,
E);
5812 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5813 if (!this->emitLoadFloat(
E))
5815 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5817 if (!this->emitSubf(getFPOptions(
E),
E))
5819 if (!this->emitStoreFloat(
E))
5823 if (!this->emitLoad(*
T,
E))
5825 if (!this->emitConst(1,
E))
5827 if (!this->emitSub(*
T,
E))
5829 if (!this->emitStore(*
T,
E))
5836 return this->emitError(
E);
5839 return this->discard(SubExpr);
5841 if (!this->visitBool(SubExpr))
5844 if (!this->emitInv(
E))
5848 return this->emitCast(
PT_Bool, ET,
E);
5852 return this->emitError(
E);
5854 if (!this->visit(SubExpr))
5856 return DiscardResult ? this->emitPop(*
T,
E) : this->emitNeg(*
T,
E);
5859 return this->emitError(
E);
5861 if (!this->visit(SubExpr))
5863 return DiscardResult ? this->emitPop(*
T,
E) :
true;
5868 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(),
E);
5871 return this->delegate(SubExpr);
5873 if (DiscardResult) {
5875 return this->discard(SubExpr);
5878 if (!this->visit(SubExpr))
5880 if (classifyPrim(SubExpr) ==
PT_Ptr)
5881 return this->emitNarrowPtr(
E);
5886 return this->emitError(
E);
5888 if (!this->visit(SubExpr))
5890 return DiscardResult ? this->emitPop(*
T,
E) : this->emitComp(*
T,
E);
5893 return this->delegate(SubExpr);
5896 if (!this->discard(SubExpr))
5898 return this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
5901 return this->delegate(SubExpr);
5903 assert(
false &&
"Unhandled opcode");
5909template <
class Emitter>
5911 const Expr *SubExpr =
E->getSubExpr();
5915 return this->discard(SubExpr);
5917 std::optional<PrimType> ResT = classify(
E);
5918 auto prepareResult = [=]() ->
bool {
5920 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5923 return this->emitGetPtrLocal(*LocalIndex,
E);
5930 unsigned SubExprOffset = ~0u;
5931 auto createTemp = [=, &SubExprOffset]() ->
bool {
5932 SubExprOffset = this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
5933 if (!this->visit(SubExpr))
5935 return this->emitSetLocal(
PT_Ptr, SubExprOffset,
E);
5939 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
5940 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
5942 return this->emitArrayElemPop(ElemT, Index,
E);
5945 switch (
E->getOpcode()) {
5947 if (!prepareResult())
5951 for (
unsigned I = 0; I != 2; ++I) {
5952 if (!getElem(SubExprOffset, I))
5954 if (!this->emitNeg(ElemT,
E))
5956 if (!this->emitInitElem(ElemT, I,
E))
5964 return this->delegate(SubExpr);
5967 if (!this->visit(SubExpr))
5969 if (!this->emitComplexBoolCast(SubExpr))
5971 if (!this->emitInv(
E))
5974 return this->emitCast(
PT_Bool, ET,
E);
5978 return this->emitComplexReal(SubExpr);
5981 if (!this->visit(SubExpr))
5985 if (!this->emitConstUint8(1,
E))
5987 return this->emitArrayElemPtrPopUint8(
E);
5992 return this->emitArrayElemPop(classifyPrim(
E->
getType()), 1,
E);
5995 if (!this->visit(SubExpr))
5998 if (!this->emitArrayElem(ElemT, 1,
E))
6000 if (!this->emitNeg(ElemT,
E))
6002 if (!this->emitInitElem(ElemT, 1,
E))
6004 return DiscardResult ? this->emitPopPtr(
E) :
true;
6007 return this->delegate(SubExpr);
6010 return this->emitInvalid(
E);
6016template <
class Emitter>
6018 const Expr *SubExpr =
E->getSubExpr();
6022 return this->discard(SubExpr);
6024 auto UnaryOp =
E->getOpcode();
6025 if (UnaryOp == UO_Extension)
6026 return this->delegate(SubExpr);
6028 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
6029 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
6030 return this->emitInvalid(
E);
6033 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
6034 return this->delegate(SubExpr);
6037 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
6040 if (!this->emitGetPtrLocal(*LocalIndex,
E))
6045 unsigned SubExprOffset =
6046 this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
6047 if (!this->visit(SubExpr))
6049 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset,
E))
6054 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
6055 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
6057 return this->emitArrayElemPop(ElemT, Index,
E);
6062 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6063 if (!getElem(SubExprOffset, I))
6065 if (!this->emitNeg(ElemT,
E))
6067 if (!this->emitInitElem(ElemT, I,
E))
6082 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6083 if (!getElem(SubExprOffset, I))
6086 if (!this->emitPrimCast(ElemT,
PT_Bool, Ctx.getASTContext().
BoolTy,
E))
6088 if (!this->emitInv(
E))
6090 if (!this->emitPrimCast(
PT_Bool, ElemT, VecTy->getElementType(),
E))
6092 if (!this->emitNeg(ElemT,
E))
6094 if (ElemT != ResultVecElemT &&
6095 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy,
E))
6097 if (!this->emitInitElem(ResultVecElemT, I,
E))
6103 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6104 if (!getElem(SubExprOffset, I))
6107 if (!this->emitInv(
E))
6110 if (!this->emitComp(ElemT,
E))
6113 if (!this->emitInitElem(ElemT, I,
E))
6118 llvm_unreachable(
"Unsupported unary operators should be handled up front");
6123template <
class Emitter>
6128 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(
D)) {
6129 return this->emitConst(ECD->getInitVal(),
E);
6130 }
else if (
const auto *BD = dyn_cast<BindingDecl>(
D)) {
6131 return this->visit(BD->getBinding());
6132 }
else if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(
D)) {
6133 const Function *F = getFunction(FuncDecl);
6134 return F && this->emitGetFnPtr(F,
E);
6135 }
else if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(
D)) {
6136 if (std::optional<unsigned> Index =
P.getOrCreateGlobal(
D)) {
6137 if (!this->emitGetPtrGlobal(*Index,
E))
6139 if (std::optional<PrimType>
T = classify(
E->
getType())) {
6140 if (!this->visitAPValue(TPOD->getValue(), *
T,
E))
6142 return this->emitInitGlobal(*
T, *Index,
E);
6144 return this->visitAPValueInitializer(TPOD->getValue(),
E);
6153 bool IsReference =
D->getType()->isReferenceType();
6156 if (
auto It = Locals.find(
D); It != Locals.end()) {
6157 const unsigned Offset = It->second.Offset;
6159 return this->emitGetLocal(
PT_Ptr, Offset,
E);
6160 return this->emitGetPtrLocal(Offset,
E);
6161 }
else if (
auto GlobalIndex =
P.getGlobal(
D)) {
6164 return this->emitGetGlobal(classifyPrim(
E), *GlobalIndex,
E);
6165 return this->emitGetGlobalUnchecked(classifyPrim(
E), *GlobalIndex,
E);
6168 return this->emitGetPtrGlobal(*GlobalIndex,
E);
6169 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(
D)) {
6170 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
6171 if (IsReference || !It->second.IsPtr)
6172 return this->emitGetParam(classifyPrim(
E), It->second.Offset,
E);
6174 return this->emitGetPtrParam(It->second.Offset,
E);
6177 if (
D->getType()->isReferenceType())
6182 auto revisit = [&](
const VarDecl *VD) ->
bool {
6183 auto VarState = this->visitDecl(VD);
6185 if (VarState.notCreated())
6190 return this->visitDeclRef(
D,
E);
6194 if (
auto It = this->LambdaCaptures.find(
D);
6195 It != this->LambdaCaptures.end()) {
6196 auto [Offset, IsPtr] = It->second;
6199 return this->emitGetThisFieldPtr(Offset,
E);
6200 return this->emitGetPtrThisField(Offset,
E);
6201 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E);
6202 DRE && DRE->refersToEnclosingVariableOrCapture()) {
6203 if (
const auto *VD = dyn_cast<VarDecl>(
D); VD && VD->isInitCapture())
6208 if (
D == InitializingDecl)
6209 return this->emitDummyPtr(
D,
E);
6215 if (
const auto *VD = dyn_cast<VarDecl>(
D);
6216 VD && VD->getAnyInitializer() &&
6217 VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak())
6219 return this->emitDummyPtr(
D,
E);
6223 const auto *VD = dyn_cast<VarDecl>(
D);
6225 return this->emitDummyPtr(
D,
E);
6227 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
6228 if (
T.isConstant(Ctx.getASTContext()))
6234 if (isa<DecompositionDecl>(VD))
6237 if ((VD->hasGlobalStorage() || VD->isStaticDataMember()) &&
6238 typeShouldBeVisited(VD->getType())) {
6239 if (
const Expr *
Init = VD->getAnyInitializer();
6240 Init && !
Init->isValueDependent()) {
6246 (void)
Init->EvaluateAsInitializer(
V, Ctx.getASTContext(), VD, Notes,
6248 return this->visitDeclRef(
D,
E);
6257 if (VD->isLocalVarDecl() && typeShouldBeVisited(VD->getType()) &&
6258 VD->getInit() && !VD->getInit()->isValueDependent()) {
6260 if (VD->evaluateValue())
6263 if (!
D->getType()->isReferenceType())
6264 return this->emitDummyPtr(
D,
E);
6266 return this->emitInvalidDeclRef(cast<DeclRefExpr>(
E),
6270 return this->emitDummyPtr(
D,
E);
6273template <
class Emitter>
6275 const auto *
D =
E->getDecl();
6276 return this->visitDeclRef(
D,
E);
6281 C->emitDestruction();
6284template <
class Emitter>
6288 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
6290 return Ty->getAsCXXRecordDecl();
6292 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
6293 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
6295 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
6299template <
class Emitter>
6306 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6311 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
6312 getFPOptions(
E),
E);
6314 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
6315 getFPOptions(
E),
E);
6319 return this->emitCastFloatingIntegral(ToT, getFPOptions(
E),
E);
6324 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT),
E);
6326 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT),
E);
6330 return FromT != ToT ? this->emitCast(FromT, ToT,
E) :
true;
6334 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6335 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(
E),
E);
6343template <
class Emitter>
6348 return this->discard(SubExpr);
6350 if (!this->visit(SubExpr))
6353 if (!this->emitConstUint8(0, SubExpr))
6355 return this->emitArrayElemPtrPopUint8(SubExpr);
6359 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
6363template <
class Emitter>
6365 assert(!DiscardResult);
6369 if (!this->emitArrayElem(ElemT, 0,
E))
6372 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(
E),
E))
6375 if (!this->emitCast(ElemT,
PT_Bool,
E))
6380 LabelTy LabelTrue = this->getLabel();
6381 if (!this->jumpTrue(LabelTrue))
6384 if (!this->emitArrayElemPop(ElemT, 1,
E))
6387 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(
E),
E))
6390 if (!this->emitCast(ElemT,
PT_Bool,
E))
6394 LabelTy EndLabel = this->getLabel();
6395 this->jump(EndLabel);
6397 this->emitLabel(LabelTrue);
6398 if (!this->emitPopPtr(
E))
6400 if (!this->emitConstBool(
true,
E))
6403 this->fallthrough(EndLabel);
6404 this->emitLabel(EndLabel);
6409template <
class Emitter>
6412 assert(
E->isComparisonOp());
6414 assert(!DiscardResult);
6420 LHSIsComplex =
true;
6421 ElemT = classifyComplexElementType(LHS->
getType());
6422 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true,
6424 if (!this->visit(LHS))
6426 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
6429 LHSIsComplex =
false;
6431 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
6432 if (!this->visit(LHS))
6434 if (!this->emitSetLocal(LHST, LHSOffset,
E))
6441 RHSIsComplex =
true;
6442 ElemT = classifyComplexElementType(RHS->
getType());
6443 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true,
6445 if (!this->visit(RHS))
6447 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
6450 RHSIsComplex =
false;
6452 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
6453 if (!this->visit(RHS))
6455 if (!this->emitSetLocal(RHST, RHSOffset,
E))
6459 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
6460 bool IsComplex) ->
bool {
6462 if (!this->emitGetLocal(
PT_Ptr, LocalOffset,
E))
6464 return this->emitArrayElemPop(ElemT, Index,
E);
6466 return this->emitGetLocal(ElemT, LocalOffset,
E);
6469 for (
unsigned I = 0; I != 2; ++I) {
6471 if (!getElem(LHSOffset, I, LHSIsComplex))
6473 if (!getElem(RHSOffset, I, RHSIsComplex))
6476 if (!this->emitEQ(ElemT,
E))
6479 if (!this->emitCastBoolUint8(
E))
6484 if (!this->emitAddUint8(
E))
6486 if (!this->emitConstUint8(2,
E))
6489 if (
E->getOpcode() == BO_EQ) {
6490 if (!this->emitEQUint8(
E))
6492 }
else if (
E->getOpcode() == BO_NE) {
6493 if (!this->emitNEUint8(
E))
6500 return this->emitCast(
PT_Bool, ResT,
E);
6507template <
class Emitter>
6516 const Function *DtorFunc = getFunction(Dtor);
6521 if (!this->emitDupPtr(
Loc))
6523 return this->emitCall(DtorFunc, 0,
Loc);
6528template <
class Emitter>
6553 for (ssize_t I = Desc->
getNumElems() - 1; I >= 0; --I) {
6554 if (!this->emitConstUint64(I,
Loc))
6556 if (!this->emitArrayElemPtrUint64(
Loc))
6558 if (!this->emitDestruction(ElemDesc,
Loc))
6560 if (!this->emitPopPtr(
Loc))
6575template <
class Emitter>
6577 assert(!DiscardResult &&
"Should've been checked before");
6579 unsigned DummyID =
P.getOrCreateDummy(
D);
6581 if (!this->emitGetPtrGlobal(DummyID,
E))
6589 return this->emitDecayPtr(
PT_Ptr, PT,
E);
6602template <
class Emitter>
6604 const Expr *SubExpr =
E->getSubExpr();
6607 std::optional<PrimType> ToT = classify(ToType);
6613 std::optional<unsigned> LocalIndex = allocateLocal(
E);
6616 if (!this->emitGetPtrLocal(*LocalIndex,
E))
6626 if (!this->visit(SubExpr))
6628 }
else if (std::optional<PrimType> FromT = classify(SubExpr)) {
6629 unsigned TempOffset = allocateLocalPrimitive(
6630 SubExpr, *FromT,
true,
false);
6631 if (!this->visit(SubExpr))
6633 if (!this->emitSetLocal(*FromT, TempOffset,
E))
6635 if (!this->emitGetPtrLocal(TempOffset,
E))
6642 if (!this->emitBitCast(
E))
6644 return DiscardResult ? this->emitPopPtr(
E) :
true;
6648 const llvm::fltSemantics *TargetSemantics =
nullptr;
6650 TargetSemantics = &Ctx.getFloatSemantics(ToType);
6656 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
6658 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->
isStdByteType(),
6659 ResultBitWidth, TargetSemantics,
E))
6663 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.
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 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.
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),...
Represents a C++ using-enum-declaration.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
const Expr * getInit() const
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
Scope for storage declared in a compound statement.
A memory block, either on the stack or in the heap.
void invokeDtor()
Invokes the Destructor.
std::byte * rawData()
Returns a pointer to the raw data, including metadata.
Compilation context for expressions.
OptLabelTy BreakLabel
Point to break to.
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E)
bool VisitCXXDeleteExpr(const CXXDeleteExpr *E)
bool VisitOffsetOfExpr(const OffsetOfExpr *E)
bool visitContinueStmt(const ContinueStmt *S)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E)
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
bool visitDeclAndReturn(const VarDecl *VD, bool ConstantContext) override
Toplevel visitDeclAndReturn().
bool 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)
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)
unsigned allocateTemporary(const Expr *E)
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool visitSwitchStmt(const SwitchStmt *S)
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E)
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsExtended=false)
Creates a local primitive value.
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool visitWhileStmt(const WhileStmt *S)
bool visitIfStmt(const IfStmt *IS)
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
bool VisitFloatingLiteral(const FloatingLiteral *E)
bool 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()