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),
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);
90 if (!Ctx->emitConstUint32(
Offset,
E))
92 return Ctx->emitArrayElemPtrPopUint32(
E);
94 llvm_unreachable(
"Unhandled InitLink kind");
118 OldContinueLabel(
Ctx->ContinueLabel),
119 OldBreakVarScope(
Ctx->BreakVarScope),
120 OldContinueVarScope(
Ctx->ContinueVarScope) {
128 this->
Ctx->BreakLabel = OldBreakLabel;
129 this->
Ctx->ContinueLabel = OldContinueLabel;
130 this->
Ctx->ContinueVarScope = OldContinueVarScope;
131 this->
Ctx->BreakVarScope = OldBreakVarScope;
151 OldDefaultLabel(this->
Ctx->DefaultLabel),
152 OldCaseLabels(
std::move(this->
Ctx->CaseLabels)),
153 OldLabelVarScope(
Ctx->BreakVarScope) {
156 this->Ctx->
CaseLabels = std::move(CaseLabels);
161 this->
Ctx->BreakLabel = OldBreakLabel;
162 this->
Ctx->DefaultLabel = OldDefaultLabel;
163 this->
Ctx->CaseLabels = std::move(OldCaseLabels);
164 this->
Ctx->BreakVarScope = OldLabelVarScope;
190template <
class Emitter>
195 case CK_LValueToRValue: {
197 return this->discard(SubExpr);
199 std::optional<PrimType> SubExprT = classify(SubExpr->
getType());
202 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
205 if (!this->emitGetPtrLocal(*LocalIndex, CE))
209 if (!this->visit(SubExpr))
213 return this->emitLoadPop(*SubExprT, CE);
218 return this->emitMemcpy(CE);
221 case CK_DerivedToBaseMemberPointer: {
230 if (!this->delegate(SubExpr))
233 return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
236 case CK_BaseToDerivedMemberPointer: {
242 unsigned DerivedOffset = collectBaseOffset(
QualType(FromMP->getClass(), 0),
245 if (!this->delegate(SubExpr))
247 return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
250 case CK_UncheckedDerivedToBase:
251 case CK_DerivedToBase: {
252 if (!this->delegate(SubExpr))
256 if (
const auto *PT = dyn_cast<PointerType>(Ty))
257 return PT->getPointeeType()->getAsCXXRecordDecl();
258 return Ty->getAsCXXRecordDecl();
265 if (B->isVirtual()) {
266 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))
268 CurType = B->getType();
270 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
271 if (!this->emitGetPtrBasePop(DerivedOffset, CE))
273 CurType = B->getType();
280 case CK_BaseToDerived: {
281 if (!this->delegate(SubExpr))
284 unsigned DerivedOffset =
287 return this->emitGetPtrDerivedPop(DerivedOffset, CE);
290 case CK_FloatingCast: {
296 return this->discard(SubExpr);
297 if (!this->visit(SubExpr))
299 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
303 case CK_IntegralToFloating: {
305 return this->discard(SubExpr);
306 std::optional<PrimType> FromT = classify(SubExpr->
getType());
310 if (!this->visit(SubExpr))
313 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
314 return this->emitCastIntegralFloating(*FromT, TargetSemantics,
315 getFPOptions(CE), CE);
318 case CK_FloatingToBoolean:
319 case CK_FloatingToIntegral: {
321 return this->discard(SubExpr);
323 std::optional<PrimType> ToT = classify(CE->
getType());
328 if (!this->visit(SubExpr))
332 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->
getType()),
333 getFPOptions(CE), CE);
335 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->
getType()),
336 getFPOptions(CE), CE);
338 return this->emitCastFloatingIntegral(*ToT, getFPOptions(CE), CE);
341 case CK_NullToPointer:
342 case CK_NullToMemberPointer: {
343 if (!this->discard(SubExpr))
350 if (!PointeeType.
isNull()) {
351 if (std::optional<PrimType>
T = classify(PointeeType))
352 Desc =
P.createDescriptor(SubExpr, *
T);
354 Desc =
P.createDescriptor(SubExpr, PointeeType.
getTypePtr(),
355 std::nullopt,
true,
false,
359 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(CE->
getType());
360 return this->emitNull(classifyPrim(CE->
getType()), Val, Desc, CE);
363 case CK_PointerToIntegral: {
365 return this->discard(SubExpr);
367 if (!this->visit(SubExpr))
373 if (!this->emitDecayPtr(FromT,
PT_Ptr, CE))
379 return this->emitCastPointerIntegralAP(Ctx.getBitWidth(CE->
getType()),
382 return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(CE->
getType()),
384 return this->emitCastPointerIntegral(
T, CE);
387 case CK_ArrayToPointerDecay: {
388 if (!this->visit(SubExpr))
390 if (!this->emitArrayDecay(CE))
393 return this->emitPopPtr(CE);
397 case CK_IntegralToPointer: {
400 if (!this->visit(SubExpr))
406 return this->emitPop(
T, CE);
411 Desc =
P.createDescriptor(SubExpr, *
T);
419 if (!this->emitGetIntPtr(
T, Desc, CE))
422 PrimType DestPtrT = classifyPrim(PtrType);
427 return this->emitDecayPtr(
PT_Ptr, DestPtrT, CE);
430 case CK_AtomicToNonAtomic:
431 case CK_ConstructorConversion:
432 case CK_FunctionToPointerDecay:
433 case CK_NonAtomicToAtomic:
435 case CK_UserDefinedConversion:
436 case CK_AddressSpaceConversion:
437 case CK_CPointerToObjCPointerCast:
438 return this->delegate(SubExpr);
443 if (!this->discard(SubExpr))
445 return this->emitInvalidCast(CastKind::Reinterpret,
true, CE);
449 return this->discard(SubExpr);
452 std::optional<PrimType> FromT = classify(SubExprTy);
455 return this->emitBuiltinBitCast(CE);
457 std::optional<PrimType> ToT = classify(CE->
getType());
465 return this->delegate(SubExpr);
467 if (!this->visit(SubExpr))
474 if (!this->visit(SubExpr))
476 return this->emitDecayPtr(*FromT, *ToT, CE);
479 case CK_LValueToRValueBitCast:
480 return this->emitBuiltinBitCast(CE);
482 case CK_IntegralToBoolean:
483 case CK_FixedPointToBoolean:
484 case CK_BooleanToSignedIntegral:
485 case CK_IntegralCast: {
487 return this->discard(SubExpr);
488 std::optional<PrimType> FromT = classify(SubExpr->
getType());
489 std::optional<PrimType> ToT = classify(CE->
getType());
494 if (!this->visit(SubExpr))
502 if (!this->emitCheckEnumValue(*FromT, ET->getDecl(), CE))
507 auto maybeNegate = [&]() ->
bool {
508 if (CE->
getCastKind() == CK_BooleanToSignedIntegral)
509 return this->emitNeg(*ToT, CE);
514 return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->
getType()), CE) &&
517 return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->
getType()), CE) &&
522 if (!this->emitCast(*FromT, *ToT, CE))
525 return maybeNegate();
528 case CK_PointerToBoolean:
529 case CK_MemberPointerToBoolean: {
532 if (!this->visit(SubExpr))
534 return this->emitIsNonNull(PtrT, CE);
537 case CK_IntegralComplexToBoolean:
538 case CK_FloatingComplexToBoolean: {
540 return this->discard(SubExpr);
541 if (!this->visit(SubExpr))
543 return this->emitComplexBoolCast(SubExpr);
546 case CK_IntegralComplexToReal:
547 case CK_FloatingComplexToReal:
548 return this->emitComplexReal(SubExpr);
550 case CK_IntegralRealToComplex:
551 case CK_FloatingRealToComplex: {
555 unsigned LocalIndex = allocateTemporary(CE);
556 if (!this->emitGetPtrLocal(LocalIndex, CE))
561 if (!this->visitArrayElemInit(0, SubExpr))
565 if (!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
567 return this->emitInitElem(
T, 1, SubExpr);
570 case CK_IntegralComplexCast:
571 case CK_FloatingComplexCast:
572 case CK_IntegralComplexToFloatingComplex:
573 case CK_FloatingComplexToIntegralComplex: {
577 return this->discard(SubExpr);
580 std::optional<unsigned> LocalIndex = allocateLocal(CE);
583 if (!this->emitGetPtrLocal(*LocalIndex, CE))
590 unsigned SubExprOffset = allocateLocalPrimitive(
591 SubExpr,
PT_Ptr,
true,
false);
592 if (!this->visit(SubExpr))
594 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, CE))
600 PrimType DestElemT = classifyPrim(DestElemType);
602 for (
unsigned I = 0; I != 2; ++I) {
603 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, CE))
605 if (!this->emitArrayElemPop(SourceElemT, I, CE))
609 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
613 if (!this->emitInitElem(DestElemT, I, CE))
619 case CK_VectorSplat: {
620 assert(!classify(CE->
getType()));
621 assert(classify(SubExpr->
getType()));
625 return this->discard(SubExpr);
628 std::optional<unsigned> LocalIndex = allocateLocal(CE);
631 if (!this->emitGetPtrLocal(*LocalIndex, CE))
637 unsigned ElemOffset = allocateLocalPrimitive(
638 SubExpr, ElemT,
true,
false);
641 if (!this->visit(SubExpr))
643 if (classifyPrim(SubExpr) ==
PT_Ptr && !this->emitLoadPop(ElemT, CE))
646 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
649 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
650 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
652 if (!this->emitInitElem(ElemT, I, CE))
659 case CK_HLSLVectorTruncation: {
661 if (std::optional<PrimType> ResultT = classify(CE)) {
662 assert(!DiscardResult);
664 if (!this->visit(SubExpr))
666 return this->emitArrayElemPop(*ResultT, 0, CE);
672 unsigned LocalIndex = allocateTemporary(CE);
673 if (!this->emitGetPtrLocal(LocalIndex, CE))
678 if (!this->visit(SubExpr))
680 return this->emitCopyArray(classifyVectorElementType(CE->
getType()), 0, 0,
684 case CK_IntegralToFixedPoint: {
685 if (!this->visit(SubExpr))
688 auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->
getType());
690 std::memcpy(&I, &Sem,
sizeof(Sem));
691 return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->
getType()), I,
694 case CK_FloatingToFixedPoint: {
695 if (!this->visit(SubExpr))
698 auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->
getType());
700 std::memcpy(&I, &Sem,
sizeof(Sem));
701 return this->emitCastFloatingFixedPoint(I, CE);
703 case CK_FixedPointToFloating: {
704 if (!this->visit(SubExpr))
706 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
707 return this->emitCastFixedPointFloating(TargetSemantics, CE);
709 case CK_FixedPointToIntegral: {
710 if (!this->visit(SubExpr))
712 return this->emitCastFixedPointIntegral(classifyPrim(CE->
getType()), CE);
714 case CK_FixedPointCast: {
715 if (!this->visit(SubExpr))
717 auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->
getType());
719 std::memcpy(&I, &Sem,
sizeof(Sem));
720 return this->emitCastFixedPoint(I, CE);
724 return discard(SubExpr);
727 return this->emitInvalid(CE);
729 llvm_unreachable(
"Unhandled clang::CastKind enum");
732template <
class Emitter>
737 return this->emitConst(
LE->getValue(),
LE);
740template <
class Emitter>
745 return this->emitConstFloat(
E->getValue(),
E);
748template <
class Emitter>
755 unsigned LocalIndex = allocateTemporary(
E);
756 if (!this->emitGetPtrLocal(LocalIndex,
E))
760 const Expr *SubExpr =
E->getSubExpr();
763 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
765 if (!this->emitInitElem(SubExprT, 0, SubExpr))
767 return this->visitArrayElemInit(1, SubExpr);
770template <
class Emitter>
778 auto Sem = Ctx.getASTContext().getFixedPointSemantics(
E->
getType());
783template <
class Emitter>
785 return this->delegate(
E->getSubExpr());
788template <
class Emitter>
792 return this->VisitLogicalBinOp(BO);
800 if (!this->discard(LHS))
803 return this->discard(RHS);
805 return this->delegate(RHS);
809 return this->VisitComplexBinOp(BO);
811 return this->VisitVectorBinOp(BO);
815 return this->emitComplexComparison(LHS, RHS, BO);
817 return this->VisitFixedPointBinOp(BO);
820 if (!this->visit(LHS))
823 if (!this->visit(RHS))
826 if (!this->emitToMemberPtr(BO))
832 if (!this->emitCastMemberPtrPtr(BO))
834 return DiscardResult ? this->emitPopPtr(BO) :
true;
838 std::optional<PrimType>
LT = classify(LHS);
839 std::optional<PrimType> RT = classify(RHS);
840 std::optional<PrimType>
T = classify(BO->
getType());
849 Ctx.getASTContext().CompCategories.lookupInfoForType(BO->
getType());
854 std::optional<unsigned> ResultIndex = this->allocateLocal(BO);
855 if (!this->emitGetPtrLocal(*ResultIndex, BO))
859 if (!visit(LHS) || !visit(RHS))
862 return this->emitCMP3(*
LT, CmpInfo, BO);
865 if (!
LT || !RT || !
T)
871 return this->VisitPointerArithBinOp(BO);
876 if (!visit(RHS) || !visit(LHS))
878 if (!this->emitFlip(*
LT, *RT, BO))
881 if (!visit(LHS) || !visit(RHS))
887 auto MaybeCastToBool = [
this,
T, BO](
bool Result) {
891 return this->emitPop(*
T, BO);
893 return this->emitCast(
PT_Bool, *
T, BO);
897 auto Discard = [
this,
T, BO](
bool Result) {
900 return DiscardResult ? this->emitPop(*
T, BO) :
true;
905 return MaybeCastToBool(this->emitEQ(*
LT, BO));
907 return MaybeCastToBool(this->emitNE(*
LT, BO));
909 return MaybeCastToBool(this->emitLT(*
LT, BO));
911 return MaybeCastToBool(this->emitLE(*
LT, BO));
913 return MaybeCastToBool(this->emitGT(*
LT, BO));
915 return MaybeCastToBool(this->emitGE(*
LT, BO));
918 return Discard(this->emitSubf(getFPOptions(BO), BO));
919 return Discard(this->emitSub(*
T, BO));
922 return Discard(this->emitAddf(getFPOptions(BO), BO));
923 return Discard(this->emitAdd(*
T, BO));
926 return Discard(this->emitMulf(getFPOptions(BO), BO));
927 return Discard(this->emitMul(*
T, BO));
929 return Discard(this->emitRem(*
T, BO));
932 return Discard(this->emitDivf(getFPOptions(BO), BO));
933 return Discard(this->emitDiv(*
T, BO));
937 : this->emitStorePop(*
T, BO);
939 if (!this->emitStoreBitField(*
T, BO))
942 if (!this->emitStore(*
T, BO))
948 return this->emitLoadPop(*
T, BO);
951 return Discard(this->emitBitAnd(*
T, BO));
953 return Discard(this->emitBitOr(*
T, BO));
955 return Discard(this->emitShl(*
LT, *RT, BO));
957 return Discard(this->emitShr(*
LT, *RT, BO));
959 return Discard(this->emitBitXor(*
T, BO));
962 llvm_unreachable(
"Already handled earlier");
967 llvm_unreachable(
"Unhandled binary op");
972template <
class Emitter>
975 const Expr *LHS =
E->getLHS();
976 const Expr *RHS =
E->getRHS();
978 if ((Op != BO_Add && Op != BO_Sub) ||
982 std::optional<PrimType>
LT = classify(LHS);
983 std::optional<PrimType> RT = classify(RHS);
993 return this->emitDecayPtr(
T,
PT_Ptr,
E);
1002 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *
LT))
1006 if (!this->emitSubPtr(IntT,
E))
1008 return DiscardResult ? this->emitPop(IntT,
E) :
true;
1013 if (!visitAsPointer(RHS, *RT))
1015 if (!this->visit(LHS))
1019 if (!visitAsPointer(LHS, *
LT))
1021 if (!this->visit(RHS))
1031 if (!this->emitAddOffset(OffsetType,
E))
1034 if (classifyPrim(
E) !=
PT_Ptr)
1035 return this->emitDecayPtr(
PT_Ptr, classifyPrim(
E),
E);
1037 }
else if (Op == BO_Sub) {
1038 if (!this->emitSubOffset(OffsetType,
E))
1041 if (classifyPrim(
E) !=
PT_Ptr)
1042 return this->emitDecayPtr(
PT_Ptr, classifyPrim(
E),
E);
1049template <
class Emitter>
1051 assert(
E->isLogicalOp());
1053 const Expr *LHS =
E->getLHS();
1054 const Expr *RHS =
E->getRHS();
1055 std::optional<PrimType>
T = classify(
E->
getType());
1059 LabelTy LabelTrue = this->getLabel();
1060 LabelTy LabelEnd = this->getLabel();
1062 if (!this->visitBool(LHS))
1064 if (!this->jumpTrue(LabelTrue))
1067 if (!this->visitBool(RHS))
1069 if (!this->jump(LabelEnd))
1072 this->emitLabel(LabelTrue);
1073 this->emitConstBool(
true,
E);
1074 this->fallthrough(LabelEnd);
1075 this->emitLabel(LabelEnd);
1078 assert(Op == BO_LAnd);
1081 LabelTy LabelFalse = this->getLabel();
1082 LabelTy LabelEnd = this->getLabel();
1084 if (!this->visitBool(LHS))
1086 if (!this->jumpFalse(LabelFalse))
1089 if (!this->visitBool(RHS))
1091 if (!this->jump(LabelEnd))
1094 this->emitLabel(LabelFalse);
1095 this->emitConstBool(
false,
E);
1096 this->fallthrough(LabelEnd);
1097 this->emitLabel(LabelEnd);
1101 return this->emitPopBool(
E);
1110template <
class Emitter>
1114 unsigned LocalIndex = allocateTemporary(
E);
1115 if (!this->emitGetPtrLocal(LocalIndex,
E))
1121 const Expr *LHS =
E->getLHS();
1122 const Expr *RHS =
E->getRHS();
1125 unsigned ResultOffset = ~0u;
1127 ResultOffset = this->allocateLocalPrimitive(
E,
PT_Ptr,
true,
false);
1130 if (!this->DiscardResult) {
1131 if (!this->emitDupPtr(
E))
1133 if (!this->emitSetLocal(
PT_Ptr, ResultOffset,
E))
1138 LHSType = AT->getValueType();
1141 RHSType = AT->getValueType();
1150 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1155 if (!this->visit(LHS))
1157 if (!this->visit(RHS))
1159 return this->emitMulc(ElemT,
E);
1162 if (Op == BO_Div && RHSIsComplex) {
1164 PrimType ElemT = classifyPrim(ElemQT);
1169 if (!LHSIsComplex) {
1171 LHSOffset = allocateTemporary(RHS);
1173 if (!this->emitGetPtrLocal(LHSOffset,
E))
1176 if (!this->visit(LHS))
1179 if (!this->emitInitElem(ElemT, 0,
E))
1182 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1184 if (!this->emitInitElem(ElemT, 1,
E))
1187 if (!this->visit(LHS))
1191 if (!this->visit(RHS))
1193 return this->emitDivc(ElemT,
E);
1198 LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
1199 if (!this->visit(LHS))
1201 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1204 PrimType LHST = classifyPrim(LHSType);
1205 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
1206 if (!this->visit(LHS))
1208 if (!this->emitSetLocal(LHST, LHSOffset,
E))
1215 RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
1216 if (!this->visit(RHS))
1218 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1221 PrimType RHST = classifyPrim(RHSType);
1222 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
1223 if (!this->visit(RHS))
1225 if (!this->emitSetLocal(RHST, RHSOffset,
E))
1232 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1233 unsigned ElemIndex,
unsigned Offset,
1234 const Expr *
E) ->
bool {
1236 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
1238 return this->emitArrayElemPop(classifyComplexElementType(
E->
getType()),
1241 if (ElemIndex == 0 || !LoadZero)
1242 return this->emitGetLocal(classifyPrim(
E->
getType()), Offset,
E);
1243 return this->visitZeroInitializer(classifyPrim(
E->
getType()),
E->
getType(),
1248 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1250 if (!this->DiscardResult) {
1251 if (!this->emitGetLocal(
PT_Ptr, ResultOffset,
E))
1258 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1261 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1264 if (!this->emitAddf(getFPOptions(
E),
E))
1267 if (!this->emitAdd(ResultElemT,
E))
1272 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1275 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1278 if (!this->emitSubf(getFPOptions(
E),
E))
1281 if (!this->emitSub(ResultElemT,
E))
1286 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1289 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1293 if (!this->emitMulf(getFPOptions(
E),
E))
1296 if (!this->emitMul(ResultElemT,
E))
1301 assert(!RHSIsComplex);
1302 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1305 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1309 if (!this->emitDivf(getFPOptions(
E),
E))
1312 if (!this->emitDiv(ResultElemT,
E))
1321 if (!this->DiscardResult) {
1323 if (!this->emitInitElemPop(ResultElemT, ElemIndex,
E))
1326 if (!this->emitPop(ResultElemT,
E))
1333template <
class Emitter>
1335 assert(!
E->isCommaOp() &&
1336 "Comma op should be handled in VisitBinaryOperator");
1343 unsigned LocalIndex = allocateTemporary(
E);
1344 if (!this->emitGetPtrLocal(LocalIndex,
E))
1348 const Expr *LHS =
E->getLHS();
1349 const Expr *RHS =
E->getRHS();
1351 auto Op =
E->isCompoundAssignmentOp()
1360 unsigned LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
1361 if (!this->visit(LHS))
1363 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1367 unsigned RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
1368 if (!this->visit(RHS))
1370 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1373 if (
E->isCompoundAssignmentOp() && !this->emitGetLocal(
PT_Ptr, LHSOffset,
E))
1378 bool NeedIntPromot = ElemT ==
PT_Bool && (
E->isBitwiseOp() ||
E->isShiftOp());
1380 Ctx.getASTContext().getPromotedIntegerType(Ctx.getASTContext().BoolTy);
1381 PrimType PromotT = classifyPrim(PromotTy);
1382 PrimType OpT = NeedIntPromot ? PromotT : ElemT;
1384 auto getElem = [=](
unsigned Offset,
PrimType ElemT,
unsigned Index) {
1385 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
1387 if (!this->emitArrayElemPop(ElemT, Index,
E))
1389 if (
E->isLogicalOp()) {
1390 if (!this->emitPrimCast(ElemT,
PT_Bool, Ctx.getASTContext().BoolTy,
E))
1392 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(),
E))
1394 }
else if (NeedIntPromot) {
1395 if (!this->emitPrimCast(ElemT, PromotT, PromotTy,
E))
1401#define EMIT_ARITH_OP(OP) \
1403 if (ElemT == PT_Float) { \
1404 if (!this->emit##OP##f(getFPOptions(E), E)) \
1407 if (!this->emit##OP(ElemT, E)) \
1413 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
1414 if (!getElem(LHSOffset, ElemT, I))
1416 if (!getElem(RHSOffset, RHSElemT, I))
1428 if (!this->emitRem(ElemT,
E))
1432 if (!this->emitBitAnd(OpT,
E))
1436 if (!this->emitBitOr(OpT,
E))
1440 if (!this->emitBitXor(OpT,
E))
1444 if (!this->emitShl(OpT, RHSElemT,
E))
1448 if (!this->emitShr(OpT, RHSElemT,
E))
1452 if (!this->emitEQ(ElemT,
E))
1456 if (!this->emitNE(ElemT,
E))
1460 if (!this->emitLE(ElemT,
E))
1464 if (!this->emitLT(ElemT,
E))
1468 if (!this->emitGE(ElemT,
E))
1472 if (!this->emitGT(ElemT,
E))
1477 if (!this->emitBitAnd(ResultElemT,
E))
1482 if (!this->emitBitOr(ResultElemT,
E))
1486 return this->emitInvalid(
E);
1494 if (
E->isComparisonOp()) {
1495 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(),
E))
1497 if (!this->emitNeg(ResultElemT,
E))
1503 if (NeedIntPromot &&
1504 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(),
E))
1508 if (!this->emitInitElem(ResultElemT, I,
E))
1512 if (DiscardResult &&
E->isCompoundAssignmentOp() && !this->emitPopPtr(
E))
1517template <
class Emitter>
1519 const Expr *LHS =
E->getLHS();
1520 const Expr *RHS =
E->getRHS();
1525 auto LHSSema = Ctx.getASTContext().getFixedPointSemantics(LHS->
getType());
1526 auto RHSSema = Ctx.getASTContext().getFixedPointSemantics(RHS->
getType());
1528 if (!this->visit(LHS))
1532 std::memcpy(&I, &LHSSema,
sizeof(llvm::FixedPointSemantics));
1533 if (!this->emitCastIntegralFixedPoint(classifyPrim(LHS->
getType()), I,
E))
1537 if (!this->visit(RHS))
1541 std::memcpy(&I, &RHSSema,
sizeof(llvm::FixedPointSemantics));
1542 if (!this->emitCastIntegralFixedPoint(classifyPrim(RHS->
getType()), I,
E))
1547 auto ConvertResult = [&](
bool R) ->
bool {
1550 auto ResultSema = Ctx.getASTContext().getFixedPointSemantics(
E->
getType());
1551 auto CommonSema = LHSSema.getCommonSemantics(RHSSema);
1552 if (ResultSema != CommonSema) {
1554 std::memcpy(&I, &ResultSema,
sizeof(ResultSema));
1555 return this->emitCastFixedPoint(I,
E);
1560 auto MaybeCastToBool = [&](
bool Result) {
1565 return this->emitPop(
T,
E);
1571 switch (
E->getOpcode()) {
1573 return MaybeCastToBool(this->emitEQFixedPoint(
E));
1575 return MaybeCastToBool(this->emitNEFixedPoint(
E));
1577 return MaybeCastToBool(this->emitLTFixedPoint(
E));
1579 return MaybeCastToBool(this->emitLEFixedPoint(
E));
1581 return MaybeCastToBool(this->emitGTFixedPoint(
E));
1583 return MaybeCastToBool(this->emitGEFixedPoint(
E));
1585 return ConvertResult(this->emitAddFixedPoint(
E));
1587 return ConvertResult(this->emitSubFixedPoint(
E));
1589 return ConvertResult(this->emitMulFixedPoint(
E));
1591 return ConvertResult(this->emitDivFixedPoint(
E));
1593 return ConvertResult(this->emitShiftFixedPoint(
true,
E));
1595 return ConvertResult(this->emitShiftFixedPoint(
false,
E));
1598 return this->emitInvalid(
E);
1601 llvm_unreachable(
"unhandled binop opcode");
1604template <
class Emitter>
1606 const Expr *SubExpr =
E->getSubExpr();
1609 switch (
E->getOpcode()) {
1611 return this->delegate(SubExpr);
1613 if (!this->visit(SubExpr))
1615 return this->emitNegFixedPoint(
E);
1620 llvm_unreachable(
"Unhandled unary opcode");
1623template <
class Emitter>
1628 if (std::optional<PrimType>
T = classify(QT))
1629 return this->visitZeroInitializer(*
T, QT,
E);
1637 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1638 CXXRD && CXXRD->getNumVBases() > 0) {
1643 const Record *R = getRecord(QT);
1648 return this->visitZeroRecordInitializer(R,
E);
1655 return this->visitZeroArrayInitializer(QT,
E);
1659 QualType ElemQT = ComplexTy->getElementType();
1660 PrimType ElemT = classifyPrim(ElemQT);
1661 for (
unsigned I = 0; I < 2; ++I) {
1662 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1664 if (!this->emitInitElem(ElemT, I,
E))
1671 unsigned NumVecElements = VecT->getNumElements();
1672 QualType ElemQT = VecT->getElementType();
1673 PrimType ElemT = classifyPrim(ElemQT);
1675 for (
unsigned I = 0; I < NumVecElements; ++I) {
1676 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1678 if (!this->emitInitElem(ElemT, I,
E))
1687template <
class Emitter>
1689 const Expr *LHS =
E->getLHS();
1690 const Expr *RHS =
E->getRHS();
1691 const Expr *Index =
E->getIdx();
1694 return this->discard(LHS) && this->discard(RHS);
1699 for (
const Expr *SubExpr : {LHS, RHS}) {
1700 if (!this->visit(SubExpr))
1707 PrimType IndexT = classifyPrim(Index->getType());
1710 if (!this->emitFlip(
PT_Ptr, IndexT,
E))
1714 return this->emitArrayElemPtrPop(IndexT,
E);
1717template <
class Emitter>
1719 const Expr *ArrayFiller,
const Expr *
E) {
1722 QT = AT->getValueType();
1725 if (Inits.size() == 0)
1727 return this->emitInvalid(
E);
1731 if (DiscardResult) {
1733 if (!this->discard(
Init))
1740 if (std::optional<PrimType>
T = classify(QT)) {
1741 assert(!DiscardResult);
1742 if (Inits.size() == 0)
1743 return this->visitZeroInitializer(*
T, QT,
E);
1744 assert(Inits.size() == 1);
1745 return this->delegate(Inits[0]);
1749 const Record *R = getRecord(QT);
1751 if (Inits.size() == 1 &&
E->
getType() == Inits[0]->getType())
1752 return this->delegate(Inits[0]);
1754 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
1757 if (!this->visit(
Init))
1760 if (FieldToInit->isBitField())
1761 return this->emitInitBitField(
T, FieldToInit,
E);
1762 return this->emitInitField(
T, FieldToInit->Offset,
E);
1765 auto initCompositeField = [=](
const Record::Field *FieldToInit,
1771 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
1773 if (!this->visitInitializer(
Init))
1775 return this->emitPopPtr(
E);
1779 if (Inits.size() == 0) {
1780 if (!this->visitZeroRecordInitializer(R,
E))
1785 if (
const auto *ILE = dyn_cast<InitListExpr>(
E))
1786 FToInit = ILE->getInitializedFieldInUnion();
1788 FToInit = cast<CXXParenListInitExpr>(
E)->getInitializedFieldInUnion();
1790 const Record::Field *FieldToInit = R->
getField(FToInit);
1791 if (std::optional<PrimType>
T = classify(
Init)) {
1792 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1795 if (!initCompositeField(FieldToInit,
Init))
1799 return this->emitFinishInit(
E);
1803 unsigned InitIndex = 0;
1806 while (InitIndex < R->getNumFields() &&
1810 if (std::optional<PrimType>
T = classify(
Init)) {
1811 const Record::Field *FieldToInit = R->
getField(InitIndex);
1812 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1817 if (
const Record::Base *B = R->
getBase(
Init->getType())) {
1818 if (!this->emitGetPtrBase(B->Offset,
Init))
1821 if (!this->visitInitializer(
Init))
1824 if (!this->emitFinishInitPop(
E))
1829 const Record::Field *FieldToInit = R->
getField(InitIndex);
1830 if (!initCompositeField(FieldToInit,
Init))
1836 return this->emitFinishInit(
E);
1840 if (Inits.size() == 1 && QT == Inits[0]->getType())
1841 return this->delegate(Inits[0]);
1843 unsigned ElementIndex = 0;
1845 if (
const auto *EmbedS =
1846 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1849 auto Eval = [&](
const Expr *
Init,
unsigned ElemIndex) {
1851 if (!this->visit(
Init))
1853 if (InitT != TargetT) {
1854 if (!this->emitCast(InitT, TargetT,
E))
1857 return this->emitInitElem(TargetT, ElemIndex,
Init);
1859 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
1862 if (!this->visitArrayElemInit(ElementIndex,
Init))
1872 Ctx.getASTContext().getAsConstantArrayType(QT);
1875 for (; ElementIndex != NumElems; ++ElementIndex) {
1876 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller))
1881 return this->emitFinishInit(
E);
1885 unsigned NumInits = Inits.size();
1888 return this->delegate(Inits[0]);
1890 QualType ElemQT = ComplexTy->getElementType();
1891 PrimType ElemT = classifyPrim(ElemQT);
1892 if (NumInits == 0) {
1894 for (
unsigned I = 0; I < 2; ++I) {
1895 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1897 if (!this->emitInitElem(ElemT, I,
E))
1900 }
else if (NumInits == 2) {
1901 unsigned InitIndex = 0;
1903 if (!this->visit(
Init))
1906 if (!this->emitInitElem(ElemT, InitIndex,
E))
1915 unsigned NumVecElements = VecT->getNumElements();
1916 assert(NumVecElements >= Inits.size());
1918 QualType ElemQT = VecT->getElementType();
1919 PrimType ElemT = classifyPrim(ElemQT);
1922 unsigned InitIndex = 0;
1924 if (!this->visit(
Init))
1929 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
1930 if (!this->emitCopyArray(ElemT, 0, InitIndex,
1931 InitVecT->getNumElements(),
E))
1933 InitIndex += InitVecT->getNumElements();
1935 if (!this->emitInitElem(ElemT, InitIndex,
E))
1941 assert(InitIndex <= NumVecElements);
1944 for (; InitIndex != NumVecElements; ++InitIndex) {
1945 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1947 if (!this->emitInitElem(ElemT, InitIndex,
E))
1958template <
class Emitter>
1961 if (std::optional<PrimType>
T = classify(
Init->getType())) {
1963 if (!this->visit(
Init))
1965 return this->emitInitElem(*
T, ElemIndex,
Init);
1971 if (!this->emitConstUint32(ElemIndex,
Init))
1973 if (!this->emitArrayElemPtrUint32(
Init))
1975 if (!this->visitInitializer(
Init))
1977 return this->emitFinishInitPop(
Init);
1980template <
class Emitter>
1982 return this->visitInitList(
E->inits(),
E->getArrayFiller(),
E);
1985template <
class Emitter>
1988 return this->visitInitList(
E->getInitExprs(),
E->getArrayFiller(),
E);
1991template <
class Emitter>
1994 return this->delegate(
E->getReplacement());
1997template <
class Emitter>
1999 std::optional<PrimType>
T = classify(
E->
getType());
2000 if (
T &&
E->hasAPValueResult()) {
2007 if (this->visitAPValue(
E->getAPValueResult(), *
T,
E))
2010 return this->delegate(
E->getSubExpr());
2013template <
class Emitter>
2015 auto It =
E->begin();
2016 return this->visit(*It);
2021 bool AlignOfReturnsPreferred =
2022 ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
2030 if (
T.getQualifiers().hasUnaligned())
2036 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2042template <
class Emitter>
2046 const ASTContext &ASTCtx = Ctx.getASTContext();
2048 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2049 QualType ArgType =
E->getTypeOfArgument();
2063 if (Kind == UETT_SizeOf)
2072 return this->emitConst(Size.getQuantity(),
E);
2075 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2078 if (
E->isArgumentType()) {
2079 QualType ArgType =
E->getTypeOfArgument();
2092 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2095 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
2105 return this->emitConst(Size.getQuantity(),
E);
2108 if (Kind == UETT_VectorElements) {
2109 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>())
2110 return this->emitConst(VT->getNumElements(),
E);
2111 assert(
E->getTypeOfArgument()->isSizelessVectorType());
2112 return this->emitSizelessVectorElementSize(
E);
2115 if (Kind == UETT_VecStep) {
2116 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>()) {
2117 unsigned N = VT->getNumElements();
2124 return this->emitConst(N,
E);
2126 return this->emitConst(1,
E);
2129 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2130 assert(
E->isArgumentType());
2139template <
class Emitter>
2146 return this->discard(
Base);
2150 const auto maybeLoadValue = [&]() ->
bool {
2153 if (std::optional<PrimType>
T = classify(
E))
2154 return this->emitLoadPop(*
T,
E);
2158 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
2162 if (
auto GlobalIndex =
P.getGlobal(VD))
2163 return this->emitGetPtrGlobal(*GlobalIndex,
E) && maybeLoadValue();
2167 if (!isa<FieldDecl>(
Member)) {
2168 if (!this->discard(
Base) && !this->emitSideEffect(
E))
2171 return this->visitDeclRef(
Member,
E);
2175 if (!this->delegate(
Base))
2178 if (!this->visit(
Base))
2183 const auto *FD = cast<FieldDecl>(
Member);
2185 const Record *R = getRecord(RD);
2188 const Record::Field *F = R->
getField(FD);
2190 if (F->Decl->getType()->isReferenceType())
2191 return this->emitGetFieldPop(
PT_Ptr, F->Offset,
E) && maybeLoadValue();
2192 return this->emitGetPtrFieldPop(F->Offset,
E) && maybeLoadValue();
2195template <
class Emitter>
2201 return this->emitConst(*ArrayIndex,
E);
2204template <
class Emitter>
2207 assert(!DiscardResult);
2211 if (!this->discard(
E->getCommonExpr()))
2216 const Expr *SubExpr =
E->getSubExpr();
2217 size_t Size =
E->getArraySize().getZExtValue();
2222 for (
size_t I = 0; I != Size; ++I) {
2226 if (!this->visitArrayElemInit(I, SubExpr))
2234template <
class Emitter>
2236 const Expr *SourceExpr =
E->getSourceExpr();
2241 return this->visitInitializer(SourceExpr);
2244 if (
auto It = OpaqueExprs.find(
E); It != OpaqueExprs.end())
2245 return this->emitGetLocal(SubExprT, It->second,
E);
2247 if (!this->visit(SourceExpr))
2253 unsigned LocalIndex = allocateLocalPrimitive(
E, SubExprT,
true);
2254 if (!this->emitSetLocal(SubExprT, LocalIndex,
E))
2259 if (!DiscardResult) {
2260 if (!this->emitGetLocal(SubExprT, LocalIndex,
E))
2265 OpaqueExprs.insert({
E, LocalIndex});
2270template <
class Emitter>
2274 const Expr *TrueExpr =
E->getTrueExpr();
2275 const Expr *FalseExpr =
E->getFalseExpr();
2277 LabelTy LabelEnd = this->getLabel();
2278 LabelTy LabelFalse = this->getLabel();
2283 if (!this->jumpFalse(LabelFalse))
2288 if (!this->delegate(TrueExpr))
2290 if (!S.destroyLocals())
2294 if (!this->jump(LabelEnd))
2297 this->emitLabel(LabelFalse);
2301 if (!this->delegate(FalseExpr))
2303 if (!S.destroyLocals())
2307 this->fallthrough(LabelEnd);
2308 this->emitLabel(LabelEnd);
2313template <
class Emitter>
2319 unsigned StringIndex =
P.createGlobalString(
E);
2320 return this->emitGetPtrGlobal(StringIndex,
E);
2325 Ctx.getASTContext().getAsConstantArrayType(
E->
getType());
2326 assert(CAT &&
"a string literal that's not a constant array?");
2331 unsigned N = std::min(ArraySize,
E->getLength());
2332 size_t CharWidth =
E->getCharByteWidth();
2334 for (
unsigned I = 0; I != N; ++I) {
2335 uint32_t CodeUnit =
E->getCodeUnit(I);
2337 if (CharWidth == 1) {
2338 this->emitConstSint8(CodeUnit,
E);
2339 this->emitInitElemSint8(I,
E);
2340 }
else if (CharWidth == 2) {
2341 this->emitConstUint16(CodeUnit,
E);
2342 this->emitInitElemUint16(I,
E);
2343 }
else if (CharWidth == 4) {
2344 this->emitConstUint32(CodeUnit,
E);
2345 this->emitInitElemUint32(I,
E);
2347 llvm_unreachable(
"unsupported character width");
2352 for (
unsigned I = N; I != ArraySize; ++I) {
2353 if (CharWidth == 1) {
2354 this->emitConstSint8(0,
E);
2355 this->emitInitElemSint8(I,
E);
2356 }
else if (CharWidth == 2) {
2357 this->emitConstUint16(0,
E);
2358 this->emitInitElemUint16(I,
E);
2359 }
else if (CharWidth == 4) {
2360 this->emitConstUint32(0,
E);
2361 this->emitInitElemUint32(I,
E);
2363 llvm_unreachable(
"unsupported character width");
2370template <
class Emitter>
2374 return this->emitDummyPtr(
E,
E);
2377template <
class Emitter>
2379 auto &A = Ctx.getASTContext();
2381 A.getObjCEncodingForType(
E->getEncodedType(), Str);
2385 return this->delegate(SL);
2388template <
class Emitter>
2396 auto &A = Ctx.getASTContext();
2397 std::string ResultStr =
E->ComputeName(A);
2400 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
2401 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
2402 ArraySizeModifier::Normal, 0);
2406 false, ArrayTy,
E->getLocation());
2408 unsigned StringIndex =
P.createGlobalString(SL);
2409 return this->emitGetPtrGlobal(StringIndex,
E);
2412template <
class Emitter>
2416 return this->emitConst(
E->getValue(),
E);
2419template <
class Emitter>
2423 const Expr *LHS =
E->getLHS();
2424 const Expr *RHS =
E->getRHS();
2426 QualType LHSComputationType =
E->getComputationLHSType();
2427 QualType ResultType =
E->getComputationResultType();
2428 std::optional<PrimType>
LT = classify(LHSComputationType);
2429 std::optional<PrimType> RT = classify(ResultType);
2436 PrimType LHST = classifyPrim(LHSType);
2444 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2445 if (!this->emitSetLocal(*RT, TempOffset,
E))
2451 if (!this->emitLoad(LHST,
E))
2455 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
2456 LHSComputationType,
E))
2460 if (!this->emitGetLocal(*RT, TempOffset,
E))
2463 switch (
E->getOpcode()) {
2465 if (!this->emitAddf(getFPOptions(
E),
E))
2469 if (!this->emitSubf(getFPOptions(
E),
E))
2473 if (!this->emitMulf(getFPOptions(
E),
E))
2477 if (!this->emitDivf(getFPOptions(
E),
E))
2484 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->
getType(),
E))
2488 return this->emitStorePop(LHST,
E);
2489 return this->emitStore(LHST,
E);
2492template <
class Emitter>
2496 const Expr *LHS =
E->getLHS();
2497 const Expr *RHS =
E->getRHS();
2498 std::optional<PrimType>
LT = classify(LHS->
getType());
2499 std::optional<PrimType> RT = classify(RHS->
getType());
2501 if (Op != BO_AddAssign && Op != BO_SubAssign)
2510 if (!this->emitLoad(*
LT, LHS))
2516 if (Op == BO_AddAssign) {
2517 if (!this->emitAddOffset(*RT,
E))
2520 if (!this->emitSubOffset(*RT,
E))
2525 return this->emitStorePopPtr(
E);
2526 return this->emitStorePtr(
E);
2529template <
class Emitter>
2533 return VisitVectorBinOp(
E);
2535 const Expr *LHS =
E->getLHS();
2536 const Expr *RHS =
E->getRHS();
2537 std::optional<PrimType> LHSComputationT =
2538 classify(
E->getComputationLHSType());
2539 std::optional<PrimType>
LT = classify(LHS->
getType());
2540 std::optional<PrimType> RT = classify(RHS->
getType());
2541 std::optional<PrimType> ResultT = classify(
E->
getType());
2543 if (!Ctx.getLangOpts().CPlusPlus14)
2544 return this->visit(RHS) && this->visit(LHS) && this->emitError(
E);
2546 if (!
LT || !RT || !ResultT || !LHSComputationT)
2553 return VisitFloatCompoundAssignOperator(
E);
2556 return VisitPointerCompoundAssignOperator(
E);
2569 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2571 if (!this->emitSetLocal(*RT, TempOffset,
E))
2578 if (!this->emitLoad(*
LT,
E))
2580 if (
LT != LHSComputationT) {
2581 if (!this->emitCast(*
LT, *LHSComputationT,
E))
2586 if (!this->emitGetLocal(*RT, TempOffset,
E))
2590 switch (
E->getOpcode()) {
2592 if (!this->emitAdd(*LHSComputationT,
E))
2596 if (!this->emitSub(*LHSComputationT,
E))
2600 if (!this->emitMul(*LHSComputationT,
E))
2604 if (!this->emitDiv(*LHSComputationT,
E))
2608 if (!this->emitRem(*LHSComputationT,
E))
2612 if (!this->emitShl(*LHSComputationT, *RT,
E))
2616 if (!this->emitShr(*LHSComputationT, *RT,
E))
2620 if (!this->emitBitAnd(*LHSComputationT,
E))
2624 if (!this->emitBitXor(*LHSComputationT,
E))
2628 if (!this->emitBitOr(*LHSComputationT,
E))
2632 llvm_unreachable(
"Unimplemented compound assign operator");
2636 if (ResultT != LHSComputationT) {
2637 if (!this->emitCast(*LHSComputationT, *ResultT,
E))
2642 if (DiscardResult) {
2644 return this->emitStoreBitFieldPop(*ResultT,
E);
2645 return this->emitStorePop(*ResultT,
E);
2648 return this->emitStoreBitField(*ResultT,
E);
2649 return this->emitStore(*ResultT,
E);
2652template <
class Emitter>
2655 const Expr *SubExpr =
E->getSubExpr();
2660template <
class Emitter>
2663 const Expr *SubExpr =
E->getSubExpr();
2667 return this->delegate(SubExpr);
2672 return this->discard(SubExpr);
2676 std::optional<PrimType> SubExprT = classify(SubExpr);
2679 std::optional<unsigned> GlobalIndex =
P.createGlobal(
E);
2684 E->getLifetimeExtendedTemporaryDecl();
2689 if (!this->visit(SubExpr))
2692 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl,
E))
2695 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex,
E))
2698 return this->emitGetPtrGlobal(*GlobalIndex,
E);
2701 if (!this->checkLiteralType(SubExpr))
2704 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2706 if (!this->visitInitializer(SubExpr))
2709 return this->emitInitGlobalTempComp(TempDecl,
E);
2715 unsigned LocalIndex = allocateLocalPrimitive(
E, *SubExprT,
true,
2717 if (!this->visit(SubExpr))
2719 if (!this->emitSetLocal(*SubExprT, LocalIndex,
E))
2721 return this->emitGetPtrLocal(LocalIndex,
E);
2724 if (!this->checkLiteralType(SubExpr))
2728 if (std::optional<unsigned> LocalIndex =
2729 allocateLocal(
E, Inner->getType(),
E->getExtendingDecl())) {
2731 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2733 return this->visitInitializer(SubExpr) && this->emitFinishInit(
E);
2739template <
class Emitter>
2742 return this->delegate(
E->getSubExpr());
2745template <
class Emitter>
2749 return this->discard(
Init);
2753 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2756 std::optional<PrimType>
T = classify(
E->
getType());
2757 if (
E->isFileScope()) {
2760 return this->delegate(
Init);
2762 if (std::optional<unsigned> GlobalIndex =
P.createGlobal(
E)) {
2763 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2767 if (!this->visit(
Init))
2769 return this->emitInitGlobal(*
T, *GlobalIndex,
E);
2772 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2781 return this->delegate(
Init);
2783 unsigned LocalIndex;
2786 LocalIndex = this->allocateLocalPrimitive(
Init, *
T,
false,
false);
2787 else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(
Init))
2788 LocalIndex = *MaybeIndex;
2792 if (!this->emitGetPtrLocal(LocalIndex,
E))
2796 if (!this->visit(
Init)) {
2799 return this->emitInit(*
T,
E);
2801 if (!this->visitInitializer(
Init) || !this->emitFinishInit(
E))
2810template <
class Emitter>
2815 return this->emitConstBool(
E->getValue(),
E);
2816 return this->emitConst(
E->getValue(),
E);
2819template <
class Emitter>
2823 return this->emitConst(
E->getValue(),
E);
2826template <
class Emitter>
2832 const Record *R =
P.getOrCreateRecord(
E->getLambdaClass());
2834 auto *CaptureInitIt =
E->capture_init_begin();
2837 for (
const Record::Field &F : R->
fields()) {
2844 if (std::optional<PrimType>
T = classify(
Init)) {
2845 if (!this->visit(
Init))
2848 if (!this->emitInitField(*
T, F.Offset,
E))
2851 if (!this->emitGetPtrField(F.Offset,
E))
2854 if (!this->visitInitializer(
Init))
2857 if (!this->emitPopPtr(
E))
2865template <
class Emitter>
2871 unsigned StringIndex =
P.createGlobalString(
E->getFunctionName(),
E);
2872 return this->emitGetPtrGlobal(StringIndex,
E);
2875 return this->delegate(
E->getFunctionName());
2878template <
class Emitter>
2880 if (
E->getSubExpr() && !this->discard(
E->getSubExpr()))
2883 return this->emitInvalid(
E);
2886template <
class Emitter>
2889 const Expr *SubExpr =
E->getSubExpr();
2891 std::optional<PrimType> FromT = classify(SubExpr);
2892 std::optional<PrimType> ToT = classify(
E);
2895 return this->emitInvalidCast(CastKind::Reinterpret,
true,
E);
2899 std::optional<PrimType> PointeeFromT;
2903 PointeeFromT = classify(SubExpr->
getType());
2905 std::optional<PrimType> PointeeToT;
2909 PointeeToT = classify(
E->
getType());
2912 if (PointeeToT && PointeeFromT) {
2917 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal,
E))
2920 if (
E->getCastKind() == CK_LValueBitCast)
2921 return this->delegate(SubExpr);
2922 return this->VisitCastExpr(
E);
2926 bool Fatal = (ToT != FromT);
2927 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal,
E))
2930 return this->VisitCastExpr(
E);
2933template <
class Emitter>
2939 return this->emitConstBool(
E->getValue(),
E);
2942template <
class Emitter>
2945 assert(!classify(
T));
2955 return this->visitInitializer(
E->getArg(0));
2959 if (DiscardResult) {
2963 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2968 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2973 if (
E->requiresZeroInitialization()) {
2976 if (!this->visitZeroRecordInitializer(R,
E))
2989 assert(
Func->hasThisPointer());
2990 assert(!
Func->hasRVO());
2994 if (!this->emitDupPtr(
E))
2998 for (
const auto *Arg :
E->arguments()) {
2999 if (!this->visit(Arg))
3003 if (
Func->isVariadic()) {
3004 uint32_t VarArgSize = 0;
3005 unsigned NumParams =
Func->getNumWrittenParams();
3006 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I) {
3010 if (!this->emitCallVar(
Func, VarArgSize,
E))
3013 if (!this->emitCall(
Func, 0,
E)) {
3018 (void)this->emitPopPtr(
E);
3024 return this->emitPopPtr(
E);
3025 return this->emitFinishInit(
E);
3030 Ctx.getASTContext().getAsConstantArrayType(
E->
getType());
3041 for (
size_t I = 0; I != NumElems; ++I) {
3042 if (!this->emitConstUint64(I,
E))
3044 if (!this->emitArrayElemPtrUint64(
E))
3048 for (
const auto *Arg :
E->arguments()) {
3049 if (!this->visit(Arg))
3053 if (!this->emitCall(
Func, 0,
E))
3062template <
class Emitter>
3068 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
3072 assert(Val.
isInt());
3074 return this->emitConst(I,
E);
3081 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
3082 return this->visit(LValueExpr);
3091 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
3093 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(UGCD);
3097 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
3101 const APValue &
V = UGCD->getValue();
3102 for (
unsigned I = 0, N = R->
getNumFields(); I != N; ++I) {
3103 const Record::Field *F = R->
getField(I);
3104 const APValue &FieldValue =
V.getStructField(I);
3106 PrimType FieldT = classifyPrim(F->Decl->getType());
3108 if (!this->visitAPValue(FieldValue, FieldT,
E))
3110 if (!this->emitInitField(FieldT, F->Offset,
E))
3118template <
class Emitter>
3120 unsigned N =
E->getNumComponents();
3124 for (
unsigned I = 0; I != N; ++I) {
3127 const Expr *ArrayIndexExpr =
E->getIndexExpr(
Node.getArrayExprIndex());
3130 if (DiscardResult) {
3131 if (!this->discard(ArrayIndexExpr))
3136 if (!this->visit(ArrayIndexExpr))
3150 return this->emitOffsetOf(
T,
E,
E);
3153template <
class Emitter>
3161 if (std::optional<PrimType>
T = classify(Ty))
3162 return this->visitZeroInitializer(*
T, Ty,
E);
3166 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3169 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3174 QualType ElemQT = CT->getElementType();
3175 PrimType ElemT = classifyPrim(ElemQT);
3177 for (
unsigned I = 0; I != 2; ++I) {
3178 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
3180 if (!this->emitInitElem(ElemT, I,
E))
3189 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3192 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3197 QualType ElemQT = VT->getElementType();
3198 PrimType ElemT = classifyPrim(ElemQT);
3200 for (
unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
3201 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
3203 if (!this->emitInitElem(ElemT, I,
E))
3212template <
class Emitter>
3214 return this->emitConst(
E->getPackLength(),
E);
3217template <
class Emitter>
3220 return this->delegate(
E->getResultExpr());
3223template <
class Emitter>
3225 return this->delegate(
E->getChosenSubExpr());
3228template <
class Emitter>
3233 return this->emitConst(
E->getValue(),
E);
3236template <
class Emitter>
3241 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
3242 const Function *F = this->getFunction(Ctor);
3259 if (!this->emitGetParam(PT, Offset,
E))
3264 return this->emitCall(F, 0,
E);
3267template <
class Emitter>
3271 QualType ElementType =
E->getAllocatedType();
3272 std::optional<PrimType> ElemT = classify(ElementType);
3273 unsigned PlacementArgs =
E->getNumPlacementArgs();
3275 const Expr *PlacementDest =
nullptr;
3276 bool IsNoThrow =
false;
3278 if (PlacementArgs != 0) {
3287 if (PlacementArgs == 1) {
3288 const Expr *Arg1 =
E->getPlacementArg(0);
3290 if (!this->discard(Arg1))
3295 if (!this->emitInvalidNewDeleteExpr(
E,
E))
3300 if (OperatorNew->isReservedGlobalPlacementOperator())
3301 PlacementDest = Arg1;
3305 return this->emitInvalid(
E);
3307 }
else if (!OperatorNew->isReplaceableGlobalAllocationFunction())
3308 return this->emitInvalidNewDeleteExpr(
E,
E);
3311 if (!PlacementDest) {
3320 Desc =
P.createDescriptor(
3323 false,
false,
false,
Init);
3328 std::optional<const Expr *> ArraySizeExpr =
E->getArraySize();
3332 const Expr *Stripped = *ArraySizeExpr;
3333 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
3334 Stripped = ICE->getSubExpr())
3335 if (ICE->getCastKind() != CK_NoOp &&
3336 ICE->getCastKind() != CK_IntegralCast)
3341 if (PlacementDest) {
3342 if (!this->visit(PlacementDest))
3344 if (!this->visit(Stripped))
3346 if (!this->emitCheckNewTypeMismatchArray(SizeT,
E,
E))
3349 if (!this->visit(Stripped))
3354 if (!this->emitAllocN(SizeT, *ElemT,
E, IsNoThrow,
E))
3358 if (!this->emitAllocCN(SizeT, Desc, IsNoThrow,
E))
3363 if (
Init && !this->visitInitializer(
Init))
3367 if (PlacementDest) {
3368 if (!this->visit(PlacementDest))
3370 if (!this->emitCheckNewTypeMismatch(
E,
E))
3374 if (!this->emitAlloc(Desc,
E))
3380 if (!this->visit(
Init))
3383 if (!this->emitInit(*ElemT,
E))
3387 if (!this->visitInitializer(
Init))
3394 return this->emitPopPtr(
E);
3399template <
class Emitter>
3401 const Expr *Arg =
E->getArgument();
3403 const FunctionDecl *OperatorDelete =
E->getOperatorDelete();
3405 if (!OperatorDelete->isReplaceableGlobalAllocationFunction())
3406 return this->emitInvalidNewDeleteExpr(
E,
E);
3409 if (!this->visit(Arg))
3412 return this->emitFree(
E->isArrayForm(),
E->isGlobalDelete(),
E);
3415template <
class Emitter>
3426 return this->emitGetFnPtr(
Func,
E);
3429template <
class Emitter>
3431 assert(Ctx.getLangOpts().CPlusPlus);
3432 return this->emitConstBool(
E->getValue(),
E);
3435template <
class Emitter>
3447 return this->emitDummyPtr(GuidDecl,
E);
3449 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(GuidDecl);
3452 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
3455 assert(this->getRecord(
E->
getType()));
3461 assert(
V.isStruct());
3462 assert(
V.getStructNumBases() == 0);
3463 if (!this->visitAPValueInitializer(
V,
E))
3466 return this->emitFinishInit(
E);
3469template <
class Emitter>
3474 return this->emitConstBool(
E->isSatisfied(),
E);
3477template <
class Emitter>
3483 return this->emitConstBool(
E->isSatisfied(),
E);
3486template <
class Emitter>
3489 return this->delegate(
E->getSemanticForm());
3492template <
class Emitter>
3495 for (
const Expr *SemE :
E->semantics()) {
3496 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
3497 if (SemE ==
E->getResultExpr())
3500 if (OVE->isUnique())
3503 if (!this->discard(OVE))
3505 }
else if (SemE ==
E->getResultExpr()) {
3506 if (!this->delegate(SemE))
3509 if (!this->discard(SemE))
3516template <
class Emitter>
3518 return this->delegate(
E->getSelectedExpr());
3521template <
class Emitter>
3523 return this->emitError(
E);
3526template <
class Emitter>
3530 unsigned Offset = allocateLocalPrimitive(
3531 E->getLabel(),
PT_Ptr,
true,
false);
3533 return this->emitGetLocal(
PT_Ptr, Offset,
E);
3536template <
class Emitter>
3540 QualType ElemType = VT->getElementType();
3541 PrimType ElemT = classifyPrim(ElemType);
3542 const Expr *Src =
E->getSrcExpr();
3544 PrimType SrcElemT = classifyVectorElementType(SrcType);
3546 unsigned SrcOffset = this->allocateLocalPrimitive(Src,
PT_Ptr,
true,
false);
3547 if (!this->visit(Src))
3549 if (!this->emitSetLocal(
PT_Ptr, SrcOffset,
E))
3552 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
3553 if (!this->emitGetLocal(
PT_Ptr, SrcOffset,
E))
3555 if (!this->emitArrayElemPop(SrcElemT, I,
E))
3559 if (SrcElemT != ElemT) {
3560 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType,
E))
3562 }
else if (ElemType->isFloatingType() && SrcType != ElemType) {
3563 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
3567 if (!this->emitInitElem(ElemT, I,
E))
3574template <
class Emitter>
3577 assert(
E->getNumSubExprs() > 2);
3579 const Expr *Vecs[] = {
E->getExpr(0),
E->getExpr(1)};
3583 unsigned NumOutputElems =
E->getNumSubExprs() - 2;
3584 assert(NumOutputElems > 0);
3587 unsigned VectorOffsets[2];
3588 for (
unsigned I = 0; I != 2; ++I) {
3589 VectorOffsets[I] = this->allocateLocalPrimitive(
3590 Vecs[I],
PT_Ptr,
true,
false);
3591 if (!this->visit(Vecs[I]))
3593 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I],
E))
3596 for (
unsigned I = 0; I != NumOutputElems; ++I) {
3597 APSInt ShuffleIndex =
E->getShuffleMaskIdx(Ctx.getASTContext(), I);
3598 assert(ShuffleIndex >= -1);
3599 if (ShuffleIndex == -1)
3600 return this->emitInvalidShuffleVectorIndex(I,
E);
3602 assert(ShuffleIndex < (NumInputElems * 2));
3603 if (!this->emitGetLocal(
PT_Ptr,
3604 VectorOffsets[ShuffleIndex >= NumInputElems],
E))
3606 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
3607 if (!this->emitArrayElemPop(ElemT, InputVectorIndex,
E))
3610 if (!this->emitInitElem(ElemT, I,
E))
3617template <
class Emitter>
3622 Base->getType()->isVectorType() ||
3626 E->getEncodedElementAccess(Indices);
3628 if (Indices.size() == 1) {
3629 if (!this->visit(
Base))
3633 if (!this->emitConstUint32(Indices[0],
E))
3635 return this->emitArrayElemPtrPop(
PT_Uint32,
E);
3638 return this->emitArrayElemPop(classifyPrim(
E->
getType()), Indices[0],
E);
3642 unsigned BaseOffset = allocateLocalPrimitive(
Base,
PT_Ptr,
true,
3644 if (!this->visit(
Base))
3646 if (!this->emitSetLocal(
PT_Ptr, BaseOffset,
E))
3651 std::optional<unsigned> ResultIndex;
3652 ResultIndex = allocateLocal(
E);
3655 if (!this->emitGetPtrLocal(*ResultIndex,
E))
3663 uint32_t DstIndex = 0;
3664 for (uint32_t I : Indices) {
3665 if (!this->emitGetLocal(
PT_Ptr, BaseOffset,
E))
3667 if (!this->emitArrayElemPop(ElemT, I,
E))
3669 if (!this->emitInitElem(ElemT, DstIndex,
E))
3675 assert(!DiscardResult);
3679template <
class Emitter>
3681 const Expr *SubExpr =
E->getSubExpr();
3682 if (!
E->isExpressibleAsConstantInitializer())
3683 return this->discard(SubExpr) && this->emitInvalid(
E);
3688 assert(classifyPrim(
E) ==
PT_Ptr);
3689 return this->emitDummyPtr(
E,
E);
3692template <
class Emitter>
3695 const Expr *SubExpr =
E->getSubExpr();
3697 Ctx.getASTContext().getAsConstantArrayType(SubExpr->
getType());
3702 if (!this->visit(SubExpr))
3704 if (!this->emitConstUint8(0,
E))
3706 if (!this->emitArrayElemPtrPopUint8(
E))
3718 assert(SecondFieldT ==
PT_Ptr);
3722 if (!this->emitExpandPtr(
E))
3726 if (!this->emitArrayElemPtrPop(
PT_Uint64,
E))
3731template <
class Emitter>
3740 if (!this->visitStmt(S))
3745 assert(S == Result);
3746 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
3747 return this->delegate(ResultExpr);
3748 return this->emitUnsupported(
E);
3757 return this->Visit(
E);
3764 return this->Visit(
E);
3772 return this->discard(
E);
3777 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3781 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3783 return this->visitInitializer(
E);
3790 return this->Visit(
E);
3793template <
class Emitter>
3799 return this->Visit(
E);
3803 std::optional<PrimType>
T = classify(
E->
getType());
3807 if (!this->visit(
E))
3809 return this->emitComplexBoolCast(
E);
3814 if (!this->visit(
E))
3822 if (!this->emitNull(*
T, 0,
nullptr,
E))
3824 return this->emitNE(*
T,
E);
3829 return this->emitCastFloatingIntegralBool(getFPOptions(
E),
E);
3835template <
class Emitter>
3840 return this->emitZeroBool(
E);
3842 return this->emitZeroSint8(
E);
3844 return this->emitZeroUint8(
E);
3846 return this->emitZeroSint16(
E);
3848 return this->emitZeroUint16(
E);
3850 return this->emitZeroSint32(
E);
3852 return this->emitZeroUint32(
E);
3854 return this->emitZeroSint64(
E);
3856 return this->emitZeroUint64(
E);
3858 return this->emitZeroIntAP(Ctx.getBitWidth(QT),
E);
3860 return this->emitZeroIntAPS(Ctx.getBitWidth(QT),
E);
3862 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
3865 return this->emitNullFnPtr(0,
nullptr,
E);
3867 return this->emitNullMemberPtr(0,
nullptr,
E);
3869 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)),
E);
3871 auto Sem = Ctx.getASTContext().getFixedPointSemantics(
E->
getType());
3874 llvm_unreachable(
"Implement");
3876 llvm_unreachable(
"unknown primitive type");
3879template <
class Emitter>
3885 for (
const Record::Field &Field : R->
fields()) {
3886 if (
Field.Decl->isUnnamedBitField())
3890 if (
D->isPrimitive()) {
3893 if (!this->visitZeroInitializer(
T, QT,
E))
3895 if (!this->emitInitField(
T,
Field.Offset,
E))
3902 if (!this->emitGetPtrField(
Field.Offset,
E))
3905 if (
D->isPrimitiveArray()) {
3908 for (uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
3909 if (!this->visitZeroInitializer(
T, ET,
E))
3911 if (!this->emitInitElem(
T, I,
E))
3914 }
else if (
D->isCompositeArray()) {
3916 if (!this->visitZeroArrayInitializer(
D->getType(),
E))
3918 }
else if (
D->isRecord()) {
3919 if (!this->visitZeroRecordInitializer(
D->ElemRecord,
E))
3925 if (!this->emitFinishInitPop(
E))
3934 for (
const Record::Base &B : R->
bases()) {
3935 if (!this->emitGetPtrBase(B.Offset,
E))
3937 if (!this->visitZeroRecordInitializer(B.R,
E))
3939 if (!this->emitFinishInitPop(
E))
3948template <
class Emitter>
3953 size_t NumElems = cast<ConstantArrayType>(AT)->getZExtSize();
3955 if (std::optional<PrimType> ElemT = classify(ElemType)) {
3956 for (
size_t I = 0; I != NumElems; ++I) {
3957 if (!this->visitZeroInitializer(*ElemT, ElemType,
E))
3959 if (!this->emitInitElem(*ElemT, I,
E))
3964 const Record *R = getRecord(ElemType);
3966 for (
size_t I = 0; I != NumElems; ++I) {
3967 if (!this->emitConstUint32(I,
E))
3971 if (!this->visitZeroRecordInitializer(R,
E))
3973 if (!this->emitPopPtr(
E))
3978 for (
size_t I = 0; I != NumElems; ++I) {
3979 if (!this->emitConstUint32(I,
E))
3983 if (!this->visitZeroArrayInitializer(ElemType,
E))
3985 if (!this->emitPopPtr(
E))
3994template <
class Emitter>
3995template <
typename T>
3999 return this->emitConstSint8(
Value,
E);
4001 return this->emitConstUint8(
Value,
E);
4003 return this->emitConstSint16(
Value,
E);
4005 return this->emitConstUint16(
Value,
E);
4007 return this->emitConstSint32(
Value,
E);
4009 return this->emitConstUint32(
Value,
E);
4011 return this->emitConstSint64(
Value,
E);
4013 return this->emitConstUint64(
Value,
E);
4015 return this->emitConstBool(
Value,
E);
4023 llvm_unreachable(
"Invalid integral type");
4026 llvm_unreachable(
"unknown primitive type");
4029template <
class Emitter>
4030template <
typename T>
4035template <
class Emitter>
4039 return this->emitConstIntAPS(
Value,
E);
4041 return this->emitConstIntAP(
Value,
E);
4043 if (
Value.isSigned())
4044 return this->emitConst(
Value.getSExtValue(), Ty,
E);
4045 return this->emitConst(
Value.getZExtValue(), Ty,
E);
4048template <
class Emitter>
4053template <
class Emitter>
4058 if (
const auto *VD =
4059 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4060 assert(!
P.getGlobal(VD));
4061 assert(!Locals.contains(VD));
4069 isa<const Expr *>(Src));
4071 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
4072 Locals.insert({VD, Local});
4073 VarScope->add(Local, IsExtended);
4074 return Local.Offset;
4077template <
class Emitter>
4078std::optional<unsigned>
4082 if ([[maybe_unused]]
const auto *VD =
4083 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4084 assert(!
P.getGlobal(VD));
4085 assert(!Locals.contains(VD));
4090 bool IsTemporary =
false;
4091 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4095 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
4096 Init = VarD->getInit();
4098 if (
auto *
E = Src.dyn_cast<
const Expr *>()) {
4106 IsTemporary,
false,
Init);
4108 return std::nullopt;
4112 Locals.insert({Key, Local});
4114 VarScope->addExtended(Local, ExtendingDecl);
4116 VarScope->add(Local,
false);
4117 return Local.Offset;
4120template <
class Emitter>
4127 true,
false,
nullptr);
4134 while (S->getParent())
4136 assert(S && !S->getParent());
4138 return Local.Offset;
4141template <
class Emitter>
4143 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
4149 if (
const auto *RecordTy = getRecordTy(Ty))
4150 return getRecord(RecordTy->getDecl());
4154template <
class Emitter>
4156 return P.getOrCreateRecord(RD);
4159template <
class Emitter>
4161 return Ctx.getOrCreateFunction(FD);
4164template <
class Emitter>
4169 if (!DestroyToplevelScope) {
4170 if (!this->emitCheckAllocations(
E))
4174 auto maybeDestroyLocals = [&]() ->
bool {
4175 if (DestroyToplevelScope)
4176 return RootScope.
destroyLocals() && this->emitCheckAllocations(
E);
4177 return this->emitCheckAllocations(
E);
4184 return this->emitRetVoid(
E) && maybeDestroyLocals();
4188 if (std::optional<PrimType>
T = classify(
E)) {
4192 return this->emitRet(*
T,
E) && maybeDestroyLocals();
4198 if (std::optional<unsigned> LocalOffset = this->allocateLocal(
E)) {
4199 if (!this->emitGetPtrLocal(*LocalOffset,
E))
4202 if (!visitInitializer(
E))
4205 if (!this->emitFinishInit(
E))
4210 return this->emitRetValue(
E) && maybeDestroyLocals();
4213 return maybeDestroyLocals() && this->emitCheckAllocations(
E) &&
false;
4216template <
class Emitter>
4219 auto R = this->visitVarDecl(VD,
true);
4228 if (
auto GlobalIndex =
P.getGlobal(VD)) {
4229 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
4233 GD.
InitState = GlobalInitState::InitializerFailed;
4244template <
class Emitter>
4246 bool ConstantContext) {
4247 std::optional<PrimType> VarT = classify(VD->
getType());
4251 if (!ConstantContext) {
4256 this->emitCheckAllocations(VD);
4260 if (!this->visitVarDecl(VD,
true))
4264 auto GlobalIndex =
P.getGlobal(VD);
4265 assert(GlobalIndex);
4267 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
4270 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
4274 auto Local = Locals.find(VD);
4275 assert(Local != Locals.end());
4277 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
4280 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
4286 if (!this->emitRet(VarT.value_or(
PT_Ptr), VD)) {
4290 auto GlobalIndex =
P.getGlobal(VD);
4291 assert(GlobalIndex);
4292 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
4296 GD.
InitState = GlobalInitState::InitializerFailed;
4302 return VDScope.
destroyLocals() && this->emitCheckAllocations(VD);
4305template <
class Emitter>
4314 if (!this->isActive())
4318 std::optional<PrimType> VarT = classify(VD->
getType());
4320 if (
Init &&
Init->isValueDependent())
4324 auto checkDecl = [&]() ->
bool {
4326 return !NeedsOp || this->emitCheckDecl(VD, VD);
4329 auto initGlobal = [&](
unsigned GlobalIndex) ->
bool {
4333 if (!this->visit(
Init))
4334 return checkDecl() &&
false;
4336 return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
4342 if (!this->emitGetPtrGlobal(GlobalIndex,
Init))
4345 if (!visitInitializer(
Init))
4348 if (!this->emitFinishInit(
Init))
4351 return this->emitPopPtr(
Init);
4357 if (std::optional<unsigned> GlobalIndex =
P.getGlobal(VD)) {
4358 if (
P.getPtrGlobal(*GlobalIndex).isInitialized())
4363 return Init && checkDecl() && initGlobal(*GlobalIndex);
4366 std::optional<unsigned> GlobalIndex =
P.createGlobal(VD,
Init);
4371 return !
Init || (checkDecl() && initGlobal(*GlobalIndex));
4376 unsigned Offset = this->allocateLocalPrimitive(
4383 if (!this->visit(
Init))
4385 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
4387 if (!this->visit(
Init))
4389 return this->emitSetLocal(*VarT, Offset, VD);
4393 if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
4397 if (!this->emitGetPtrLocal(*Offset,
Init))
4400 if (!visitInitializer(
Init))
4403 if (!this->emitFinishInit(
Init))
4406 return this->emitPopPtr(
Init);
4416template <
class Emitter>
4419 assert(!DiscardResult);
4421 return this->emitConst(Val.
getInt(), ValType,
E);
4423 return this->emitConstFloat(Val.
getFloat(),
E);
4427 return this->emitNull(ValType, 0,
nullptr,
E);
4429 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
4430 return this->visit(BaseExpr);
4431 else if (
const auto *VD =
Base.dyn_cast<
const ValueDecl *>()) {
4432 return this->visitDeclRef(VD,
E);
4436 return this->emitGetMemberPtr(MemberDecl,
E);
4437 return this->emitNullMemberPtr(0,
nullptr,
E);
4443template <
class Emitter>
4452 const Record::Field *RF = R->
getField(I);
4455 PrimType T = classifyPrim(RF->Decl->getType());
4456 if (!this->visitAPValue(F,
T,
E))
4458 if (!this->emitInitField(
T, RF->Offset,
E))
4461 assert(RF->Desc->isPrimitiveArray());
4462 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
4463 PrimType ElemT = classifyPrim(ArrType->getElementType());
4466 if (!this->emitGetPtrField(RF->Offset,
E))
4469 for (
unsigned A = 0, AN = F.
getArraySize(); A != AN; ++A) {
4472 if (!this->emitInitElem(ElemT, A,
E))
4476 if (!this->emitPopPtr(
E))
4479 if (!this->emitGetPtrField(RF->Offset,
E))
4481 if (!this->visitAPValueInitializer(F,
E))
4483 if (!this->emitPopPtr(
E))
4486 assert(
false &&
"I don't think this should be possible");
4495 const Record::Field *RF = R->
getField(UnionField);
4496 PrimType T = classifyPrim(RF->Decl->getType());
4497 if (!this->visitAPValue(F,
T,
E))
4499 return this->emitInitField(
T, RF->Offset,
E);
4506template <
class Emitter>
4508 unsigned BuiltinID) {
4515 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
4516 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
4517 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
4518 BuiltinID == Builtin::BI__builtin_function_start) {
4521 return this->emitDummyPtr(
E,
E);
4525 std::optional<PrimType> ReturnT = classify(
E);
4529 std::optional<unsigned> LocalIndex = allocateLocal(
E);
4532 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4536 if (!
Func->isUnevaluatedBuiltin()) {
4538 for (
const auto *Arg :
E->arguments()) {
4539 if (!this->visit(Arg))
4544 if (!this->emitCallBI(
Func,
E, BuiltinID,
E))
4547 if (DiscardResult && !ReturnType->
isVoidType()) {
4549 return this->emitPop(*ReturnT,
E);
4555template <
class Emitter>
4557 if (
unsigned BuiltinID =
E->getBuiltinCallee())
4558 return VisitBuiltinCallExpr(
E, BuiltinID);
4565 return VisitBuiltinCallExpr(
E, Builtin::BI__builtin_operator_new);
4568 return VisitBuiltinCallExpr(
E, Builtin::BI__builtin_operator_delete);
4572 if (
const auto *DD = dyn_cast_if_present<CXXDestructorDecl>(FuncDecl);
4573 DD && DD->isTrivial())
4576 QualType ReturnType =
E->getCallReturnType(Ctx.getASTContext());
4577 std::optional<PrimType>
T = classify(ReturnType);
4581 if (DiscardResult) {
4585 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4586 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4593 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4594 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4598 if (!this->emitDupPtr(
E))
4606 bool IsAssignmentOperatorCall =
false;
4607 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
4608 OCE && OCE->isAssignmentOp()) {
4612 assert(Args.size() == 2);
4613 IsAssignmentOperatorCall =
true;
4614 std::reverse(Args.begin(), Args.end());
4619 if (isa<CXXOperatorCallExpr>(
E)) {
4620 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
4621 MD && MD->isStatic()) {
4622 if (!this->discard(
E->getArg(0)))
4625 Args.erase(Args.begin());
4629 std::optional<unsigned> CalleeOffset;
4631 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(
E)) {
4632 if (!FuncDecl && classifyPrim(
E->getCallee()) ==
PT_MemberPtr) {
4636 const Expr *Callee =
E->getCallee();
4638 this->allocateLocalPrimitive(Callee,
PT_MemberPtr,
true,
false);
4639 if (!this->visit(Callee))
4645 if (!this->emitGetMemberPtrBase(
E))
4647 }
else if (!this->visit(MC->getImplicitObjectArgument())) {
4650 }
else if (!FuncDecl) {
4651 const Expr *Callee =
E->getCallee();
4652 CalleeOffset = this->allocateLocalPrimitive(Callee,
PT_FnPtr,
true,
false);
4653 if (!this->visit(Callee))
4655 if (!this->emitSetLocal(
PT_FnPtr, *CalleeOffset,
E))
4661 unsigned ArgIndex = 0;
4662 for (
const auto *Arg : Args) {
4663 if (!this->visit(Arg))
4667 if (FuncDecl && NonNullArgs[ArgIndex]) {
4670 if (!this->emitCheckNonNullArg(ArgT, Arg))
4678 if (IsAssignmentOperatorCall) {
4679 assert(Args.size() == 2);
4682 if (!this->emitFlip(Arg2T, Arg1T,
E))
4690 assert(HasRVO ==
Func->hasRVO());
4692 bool HasQualifier =
false;
4693 if (
const auto *ME = dyn_cast<MemberExpr>(
E->getCallee()))
4694 HasQualifier = ME->hasQualifier();
4696 bool IsVirtual =
false;
4697 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
4698 IsVirtual = MD->isVirtual();
4703 if (IsVirtual && !HasQualifier) {
4704 uint32_t VarArgSize = 0;
4705 unsigned NumParams =
4706 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4707 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4710 if (!this->emitCallVirt(
Func, VarArgSize,
E))
4712 }
else if (
Func->isVariadic()) {
4713 uint32_t VarArgSize = 0;
4714 unsigned NumParams =
4715 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4716 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4718 if (!this->emitCallVar(
Func, VarArgSize,
E))
4721 if (!this->emitCall(
Func, 0,
E))
4730 uint32_t ArgSize = 0;
4731 for (
unsigned I = 0, N =
E->getNumArgs(); I != N; ++I)
4736 if (isa<CXXMemberCallExpr>(
E) && CalleeOffset) {
4739 if (!this->emitGetMemberPtrDecl(
E))
4742 if (!this->emitGetLocal(
PT_FnPtr, *CalleeOffset,
E))
4745 if (!this->emitCallPtr(ArgSize,
E,
E))
4750 if (DiscardResult && !ReturnType->
isVoidType() &&
T)
4751 return this->emitPop(*
T,
E);
4756template <
class Emitter>
4760 return this->delegate(
E->getExpr());
4763template <
class Emitter>
4767 const Expr *SubExpr =
E->getExpr();
4768 if (std::optional<PrimType>
T = classify(
E->getExpr()))
4769 return this->visit(SubExpr);
4772 return this->visitInitializer(SubExpr);
4775template <
class Emitter>
4780 return this->emitConstBool(
E->getValue(),
E);
4783template <
class Emitter>
4789 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(
E->
getType());
4790 return this->emitNullPtr(Val,
nullptr,
E);
4793template <
class Emitter>
4801 return this->emitZero(
T,
E);
4804template <
class Emitter>
4809 if (this->LambdaThisCapture.Offset > 0) {
4810 if (this->LambdaThisCapture.IsPtr)
4811 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset,
E);
4812 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset,
E);
4819 if (!InitStackActive || !
E->isImplicit())
4820 return this->emitThis(
E);
4822 if (InitStackActive && !InitStack.empty()) {
4823 unsigned StartIndex = 0;
4824 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
4830 for (
unsigned I = StartIndex, N = InitStack.size(); I != N; ++I) {
4831 if (!InitStack[I].
template emit<Emitter>(
this,
E))
4836 return this->emitThis(
E);
4840 switch (S->getStmtClass()) {
4841 case Stmt::CompoundStmtClass:
4842 return visitCompoundStmt(cast<CompoundStmt>(S));
4843 case Stmt::DeclStmtClass:
4844 return visitDeclStmt(cast<DeclStmt>(S));
4845 case Stmt::ReturnStmtClass:
4846 return visitReturnStmt(cast<ReturnStmt>(S));
4847 case Stmt::IfStmtClass:
4848 return visitIfStmt(cast<IfStmt>(S));
4849 case Stmt::WhileStmtClass:
4850 return visitWhileStmt(cast<WhileStmt>(S));
4851 case Stmt::DoStmtClass:
4852 return visitDoStmt(cast<DoStmt>(S));
4853 case Stmt::ForStmtClass:
4854 return visitForStmt(cast<ForStmt>(S));
4855 case Stmt::CXXForRangeStmtClass:
4856 return visitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
4857 case Stmt::BreakStmtClass:
4858 return visitBreakStmt(cast<BreakStmt>(S));
4859 case Stmt::ContinueStmtClass:
4860 return visitContinueStmt(cast<ContinueStmt>(S));
4861 case Stmt::SwitchStmtClass:
4862 return visitSwitchStmt(cast<SwitchStmt>(S));
4863 case Stmt::CaseStmtClass:
4864 return visitCaseStmt(cast<CaseStmt>(S));
4865 case Stmt::DefaultStmtClass:
4866 return visitDefaultStmt(cast<DefaultStmt>(S));
4867 case Stmt::AttributedStmtClass:
4868 return visitAttributedStmt(cast<AttributedStmt>(S));
4869 case Stmt::CXXTryStmtClass:
4870 return visitCXXTryStmt(cast<CXXTryStmt>(S));
4871 case Stmt::NullStmtClass:
4874 case Stmt::GCCAsmStmtClass:
4875 case Stmt::MSAsmStmtClass:
4876 case Stmt::GotoStmtClass:
4877 return this->emitInvalid(S);
4878 case Stmt::LabelStmtClass:
4879 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
4881 if (
const auto *
E = dyn_cast<Expr>(S))
4882 return this->discard(
E);
4888template <
class Emitter>
4891 for (
const auto *InnerStmt : S->body())
4892 if (!visitStmt(InnerStmt))
4894 return Scope.destroyLocals();
4897template <
class Emitter>
4899 for (
const auto *
D : DS->
decls()) {
4904 const auto *VD = dyn_cast<VarDecl>(
D);
4907 if (!this->visitVarDecl(VD))
4914template <
class Emitter>
4916 if (this->InStmtExpr)
4917 return this->emitUnsupported(RS);
4923 if (!this->visit(RE))
4925 this->emitCleanup();
4926 return this->emitRet(*ReturnType, RS);
4927 }
else if (RE->getType()->isVoidType()) {
4928 if (!this->visit(RE))
4932 if (!this->emitRVOPtr(RE))
4934 if (!this->visitInitializer(RE))
4936 if (!this->emitPopPtr(RE))
4939 this->emitCleanup();
4940 return this->emitRetVoid(RS);
4945 this->emitCleanup();
4946 return this->emitRetVoid(RS);
4950 if (
auto *CondInit = IS->
getInit())
4951 if (!visitStmt(CondInit))
4955 if (!visitDeclStmt(CondDecl))
4960 if (!this->emitIsConstantContext(IS))
4963 if (!this->emitIsConstantContext(IS))
4965 if (!this->emitInv(IS))
4968 if (!this->visitBool(IS->
getCond()))
4973 LabelTy LabelElse = this->getLabel();
4974 LabelTy LabelEnd = this->getLabel();
4975 if (!this->jumpFalse(LabelElse))
4979 if (!visitStmt(IS->
getThen()))
4984 if (!this->jump(LabelEnd))
4986 this->emitLabel(LabelElse);
4989 if (!visitStmt(Else))
4994 this->emitLabel(LabelEnd);
4996 LabelTy LabelEnd = this->getLabel();
4997 if (!this->jumpFalse(LabelEnd))
5001 if (!visitStmt(IS->
getThen()))
5006 this->emitLabel(LabelEnd);
5012template <
class Emitter>
5014 const Expr *Cond = S->getCond();
5015 const Stmt *Body = S->getBody();
5017 LabelTy CondLabel = this->getLabel();
5018 LabelTy EndLabel = this->getLabel();
5021 this->fallthrough(CondLabel);
5022 this->emitLabel(CondLabel);
5026 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5027 if (!visitDeclStmt(CondDecl))
5030 if (!this->visitBool(Cond))
5032 if (!this->jumpFalse(EndLabel))
5035 if (!this->visitStmt(Body))
5041 if (!this->jump(CondLabel))
5043 this->fallthrough(EndLabel);
5044 this->emitLabel(EndLabel);
5050 const Expr *Cond = S->getCond();
5051 const Stmt *Body = S->getBody();
5053 LabelTy StartLabel = this->getLabel();
5054 LabelTy EndLabel = this->getLabel();
5055 LabelTy CondLabel = this->getLabel();
5058 this->fallthrough(StartLabel);
5059 this->emitLabel(StartLabel);
5063 if (!this->visitStmt(Body))
5065 this->fallthrough(CondLabel);
5066 this->emitLabel(CondLabel);
5067 if (!this->visitBool(Cond))
5073 if (!this->jumpTrue(StartLabel))
5076 this->fallthrough(EndLabel);
5077 this->emitLabel(EndLabel);
5081template <
class Emitter>
5085 const Expr *Cond = S->getCond();
5086 const Expr *
Inc = S->getInc();
5087 const Stmt *Body = S->getBody();
5089 LabelTy EndLabel = this->getLabel();
5090 LabelTy CondLabel = this->getLabel();
5091 LabelTy IncLabel = this->getLabel();
5094 if (
Init && !this->visitStmt(
Init))
5097 this->fallthrough(CondLabel);
5098 this->emitLabel(CondLabel);
5102 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5103 if (!visitDeclStmt(CondDecl))
5107 if (!this->visitBool(Cond))
5109 if (!this->jumpFalse(EndLabel))
5113 if (Body && !this->visitStmt(Body))
5116 this->fallthrough(IncLabel);
5117 this->emitLabel(IncLabel);
5118 if (
Inc && !this->discard(
Inc))
5124 if (!this->jump(CondLabel))
5127 this->fallthrough(EndLabel);
5128 this->emitLabel(EndLabel);
5132template <
class Emitter>
5135 const Expr *Cond = S->getCond();
5136 const Expr *
Inc = S->getInc();
5137 const Stmt *Body = S->getBody();
5138 const Stmt *BeginStmt = S->getBeginStmt();
5139 const Stmt *RangeStmt = S->getRangeStmt();
5140 const Stmt *EndStmt = S->getEndStmt();
5141 const VarDecl *LoopVar = S->getLoopVariable();
5143 LabelTy EndLabel = this->getLabel();
5144 LabelTy CondLabel = this->getLabel();
5145 LabelTy IncLabel = this->getLabel();
5149 if (
Init && !this->visitStmt(
Init))
5151 if (!this->visitStmt(RangeStmt))
5153 if (!this->visitStmt(BeginStmt))
5155 if (!this->visitStmt(EndStmt))
5159 this->fallthrough(CondLabel);
5160 this->emitLabel(CondLabel);
5161 if (!this->visitBool(Cond))
5163 if (!this->jumpFalse(EndLabel))
5166 if (!this->visitVarDecl(LoopVar))
5171 if (!this->visitStmt(Body))
5174 this->fallthrough(IncLabel);
5175 this->emitLabel(IncLabel);
5176 if (!this->discard(
Inc))
5180 if (!this->jump(CondLabel))
5183 this->fallthrough(EndLabel);
5184 this->emitLabel(EndLabel);
5188template <
class Emitter>
5195 C->emitDestruction();
5196 return this->jump(*BreakLabel);
5199template <
class Emitter>
5205 C &&
C->getParent() != ContinueVarScope;
C =
C->getParent())
5206 C->emitDestruction();
5207 return this->jump(*ContinueLabel);
5210template <
class Emitter>
5212 const Expr *Cond = S->getCond();
5216 LabelTy EndLabel = this->getLabel();
5218 unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT,
true,
false);
5220 if (
const auto *CondInit = S->getInit())
5221 if (!visitStmt(CondInit))
5224 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5225 if (!visitDeclStmt(CondDecl))
5229 if (!this->visit(Cond))
5231 if (!this->emitSetLocal(CondT, CondVar, S))
5236 for (
const SwitchCase *SC = S->getSwitchCaseList(); SC;
5237 SC = SC->getNextSwitchCase()) {
5238 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
5240 if (CS->caseStmtIsGNURange())
5242 CaseLabels[SC] = this->getLabel();
5248 if (!this->emitGetLocal(CondT, CondVar, CS))
5250 if (!this->visit(
Value))
5254 if (!this->emitEQ(ValueT, S))
5256 if (!this->jumpTrue(CaseLabels[CS]))
5259 assert(!DefaultLabel);
5260 DefaultLabel = this->getLabel();
5267 if (!this->jump(*DefaultLabel))
5270 if (!this->jump(EndLabel))
5275 if (!this->visitStmt(S->getBody()))
5277 this->emitLabel(EndLabel);
5282template <
class Emitter>
5284 this->emitLabel(CaseLabels[S]);
5285 return this->visitStmt(S->getSubStmt());
5288template <
class Emitter>
5290 this->emitLabel(*DefaultLabel);
5291 return this->visitStmt(S->getSubStmt());
5294template <
class Emitter>
5296 if (this->Ctx.getLangOpts().CXXAssumptions &&
5297 !this->Ctx.getLangOpts().MSVCCompat) {
5298 for (
const Attr *A : S->getAttrs()) {
5299 auto *AA = dyn_cast<CXXAssumeAttr>(A);
5303 assert(isa<NullStmt>(S->getSubStmt()));
5305 const Expr *Assumption = AA->getAssumption();
5313 if (!this->visitBool(Assumption))
5316 if (!this->emitAssume(Assumption))
5322 return this->visitStmt(S->getSubStmt());
5325template <
class Emitter>
5328 return this->visitStmt(S->getTryBlock());
5331template <
class Emitter>
5335 assert(cast<CompoundStmt>(MD->
getBody())->body_empty());
5340 const Function *
Func = this->getFunction(LambdaCallOp);
5343 assert(
Func->hasThisPointer());
5346 if (
Func->hasRVO()) {
5347 if (!this->emitRVOPtr(MD))
5355 if (!this->emitNullPtr(0,
nullptr, MD))
5360 auto It = this->Params.find(PVD);
5361 assert(It != this->Params.end());
5365 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
5366 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
5370 if (!this->emitCall(
Func, 0, LambdaCallOp))
5373 this->emitCleanup();
5375 return this->emitRet(*ReturnType, MD);
5378 return this->emitRetVoid(MD);
5381template <
class Emitter>
5383 if (Ctx.getLangOpts().CPlusPlus23)
5392template <
class Emitter>
5394 assert(!ReturnType);
5396 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
5397 const Expr *InitExpr) ->
bool {
5399 if (InitExpr->getType().isNull())
5402 if (std::optional<PrimType>
T = this->classify(InitExpr)) {
5403 if (!this->visit(InitExpr))
5406 if (F->isBitField())
5407 return this->emitInitThisBitField(*
T, F, FieldOffset, InitExpr);
5408 return this->emitInitThisField(*
T, FieldOffset, InitExpr);
5413 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
5416 if (!this->visitInitializer(InitExpr))
5419 return this->emitFinishInitPop(InitExpr);
5423 const Record *R = this->getRecord(RD);
5429 assert(cast<CompoundStmt>(Ctor->
getBody())->body_empty());
5430 if (!this->emitThis(Ctor))
5439 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
5440 this->emitRetVoid(Ctor);
5444 for (
const auto *
Init : Ctor->
inits()) {
5448 const Expr *InitExpr =
Init->getInit();
5452 if (!emitFieldInitializer(F, F->Offset, InitExpr))
5455 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
5458 if (
Init->isBaseVirtual()) {
5460 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
5466 const Record::Base *B = R->
getBase(BaseDecl);
5468 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
5472 if (!this->visitInitializer(InitExpr))
5474 if (!this->emitFinishInitPop(InitExpr))
5477 assert(IFD->getChainingSize() >= 2);
5479 unsigned NestedFieldOffset = 0;
5480 const Record::Field *NestedField =
nullptr;
5481 for (
const NamedDecl *ND : IFD->chain()) {
5482 const auto *FD = cast<FieldDecl>(ND);
5483 const Record *FieldRecord = this->
P.getOrCreateRecord(FD->getParent());
5484 assert(FieldRecord);
5486 NestedField = FieldRecord->
getField(FD);
5487 assert(NestedField);
5489 NestedFieldOffset += NestedField->Offset;
5491 assert(NestedField);
5493 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
5496 assert(
Init->isDelegatingInitializer());
5497 if (!this->emitThis(InitExpr))
5499 if (!this->visitInitializer(
Init->getInit()))
5501 if (!this->emitPopPtr(InitExpr))
5505 if (!
Scope.destroyLocals())
5509 if (
const auto *Body = Ctor->
getBody())
5510 if (!visitStmt(Body))
5516template <
class Emitter>
5519 const Record *R = this->getRecord(RD);
5524 if (!this->visitStmt(Dtor->
getBody()))
5528 if (!this->emitThis(Dtor))
5534 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
5536 if (!
D->isPrimitive() && !
D->isPrimitiveArray()) {
5547 for (
const Record::Base &
Base : llvm::reverse(R->
bases())) {
5548 if (
Base.R->isAnonymousUnion())
5553 if (!this->emitRecordDestruction(
Base.R, {}))
5560 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
5563template <
class Emitter>
5568 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
5569 return this->compileConstructor(Ctor);
5570 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
5571 return this->compileDestructor(Dtor);
5574 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F);
5576 return this->emitLambdaStaticInvokerBody(MD);
5579 if (
const auto *Body = F->
getBody())
5580 if (!visitStmt(Body))
5589template <
class Emitter>
5591 const Expr *SubExpr =
E->getSubExpr();
5593 return this->VisitComplexUnaryOperator(
E);
5595 return this->VisitVectorUnaryOperator(
E);
5597 return this->VisitFixedPointUnaryOperator(
E);
5598 std::optional<PrimType>
T = classify(SubExpr->
getType());
5600 switch (
E->getOpcode()) {
5602 if (!Ctx.getLangOpts().CPlusPlus14)
5603 return this->emitInvalid(
E);
5605 return this->emitError(
E);
5607 if (!this->visit(SubExpr))
5611 if (!this->emitIncPtr(
E))
5614 return DiscardResult ? this->emitPopPtr(
E) :
true;
5618 return DiscardResult ? this->emitIncfPop(getFPOptions(
E),
E)
5619 : this->emitIncf(getFPOptions(
E),
E);
5622 return DiscardResult ? this->emitIncPop(*
T,
E) : this->emitInc(*
T,
E);
5625 if (!Ctx.getLangOpts().CPlusPlus14)
5626 return this->emitInvalid(
E);
5628 return this->emitError(
E);
5630 if (!this->visit(SubExpr))
5634 if (!this->emitDecPtr(
E))
5637 return DiscardResult ? this->emitPopPtr(
E) :
true;
5641 return DiscardResult ? this->emitDecfPop(getFPOptions(
E),
E)
5642 : this->emitDecf(getFPOptions(
E),
E);
5645 return DiscardResult ? this->emitDecPop(*
T,
E) : this->emitDec(*
T,
E);
5648 if (!Ctx.getLangOpts().CPlusPlus14)
5649 return this->emitInvalid(
E);
5651 return this->emitError(
E);
5653 if (!this->visit(SubExpr))
5657 if (!this->emitLoadPtr(
E))
5659 if (!this->emitConstUint8(1,
E))
5661 if (!this->emitAddOffsetUint8(
E))
5663 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5667 if (DiscardResult) {
5669 return this->emitIncfPop(getFPOptions(
E),
E);
5670 return this->emitIncPop(*
T,
E);
5674 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5675 if (!this->emitLoadFloat(
E))
5677 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5679 if (!this->emitAddf(getFPOptions(
E),
E))
5681 if (!this->emitStoreFloat(
E))
5685 if (!this->emitLoad(*
T,
E))
5687 if (!this->emitConst(1,
E))
5689 if (!this->emitAdd(*
T,
E))
5691 if (!this->emitStore(*
T,
E))
5697 if (!Ctx.getLangOpts().CPlusPlus14)
5698 return this->emitInvalid(
E);
5700 return this->emitError(
E);
5702 if (!this->visit(SubExpr))
5706 if (!this->emitLoadPtr(
E))
5708 if (!this->emitConstUint8(1,
E))
5710 if (!this->emitSubOffsetUint8(
E))
5712 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5716 if (DiscardResult) {
5718 return this->emitDecfPop(getFPOptions(
E),
E);
5719 return this->emitDecPop(*
T,
E);
5723 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5724 if (!this->emitLoadFloat(
E))
5726 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5728 if (!this->emitSubf(getFPOptions(
E),
E))
5730 if (!this->emitStoreFloat(
E))
5734 if (!this->emitLoad(*
T,
E))
5736 if (!this->emitConst(1,
E))
5738 if (!this->emitSub(*
T,
E))
5740 if (!this->emitStore(*
T,
E))
5747 return this->emitError(
E);
5750 return this->discard(SubExpr);
5752 if (!this->visitBool(SubExpr))
5755 if (!this->emitInv(
E))
5759 return this->emitCast(
PT_Bool, ET,
E);
5763 return this->emitError(
E);
5765 if (!this->visit(SubExpr))
5767 return DiscardResult ? this->emitPop(*
T,
E) : this->emitNeg(*
T,
E);
5770 return this->emitError(
E);
5772 if (!this->visit(SubExpr))
5774 return DiscardResult ? this->emitPop(*
T,
E) :
true;
5779 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(),
E);
5782 return this->delegate(SubExpr);
5784 if (DiscardResult) {
5786 return this->discard(SubExpr);
5789 if (!this->visit(SubExpr))
5791 if (classifyPrim(SubExpr) ==
PT_Ptr)
5792 return this->emitNarrowPtr(
E);
5797 return this->emitError(
E);
5799 if (!this->visit(SubExpr))
5801 return DiscardResult ? this->emitPop(*
T,
E) : this->emitComp(*
T,
E);
5804 return this->delegate(SubExpr);
5807 if (!this->discard(SubExpr))
5809 return this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
5812 return this->delegate(SubExpr);
5814 assert(
false &&
"Unhandled opcode");
5820template <
class Emitter>
5822 const Expr *SubExpr =
E->getSubExpr();
5826 return this->discard(SubExpr);
5828 std::optional<PrimType> ResT = classify(
E);
5829 auto prepareResult = [=]() ->
bool {
5831 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5834 return this->emitGetPtrLocal(*LocalIndex,
E);
5841 unsigned SubExprOffset = ~0u;
5842 auto createTemp = [=, &SubExprOffset]() ->
bool {
5843 SubExprOffset = this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
5844 if (!this->visit(SubExpr))
5846 return this->emitSetLocal(
PT_Ptr, SubExprOffset,
E);
5850 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
5851 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
5853 return this->emitArrayElemPop(ElemT, Index,
E);
5856 switch (
E->getOpcode()) {
5858 if (!prepareResult())
5862 for (
unsigned I = 0; I != 2; ++I) {
5863 if (!getElem(SubExprOffset, I))
5865 if (!this->emitNeg(ElemT,
E))
5867 if (!this->emitInitElem(ElemT, I,
E))
5875 return this->delegate(SubExpr);
5878 if (!this->visit(SubExpr))
5880 if (!this->emitComplexBoolCast(SubExpr))
5882 if (!this->emitInv(
E))
5885 return this->emitCast(
PT_Bool, ET,
E);
5889 return this->emitComplexReal(SubExpr);
5892 if (!this->visit(SubExpr))
5896 if (!this->emitConstUint8(1,
E))
5898 return this->emitArrayElemPtrPopUint8(
E);
5903 return this->emitArrayElemPop(classifyPrim(
E->
getType()), 1,
E);
5906 if (!this->visit(SubExpr))
5909 if (!this->emitArrayElem(ElemT, 1,
E))
5911 if (!this->emitNeg(ElemT,
E))
5913 if (!this->emitInitElem(ElemT, 1,
E))
5915 return DiscardResult ? this->emitPopPtr(
E) :
true;
5918 return this->delegate(SubExpr);
5921 return this->emitInvalid(
E);
5927template <
class Emitter>
5929 const Expr *SubExpr =
E->getSubExpr();
5933 return this->discard(SubExpr);
5935 auto UnaryOp =
E->getOpcode();
5936 if (UnaryOp == UO_Extension)
5937 return this->delegate(SubExpr);
5939 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
5940 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
5941 return this->emitInvalid(
E);
5944 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
5945 return this->delegate(SubExpr);
5948 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5951 if (!this->emitGetPtrLocal(*LocalIndex,
E))
5956 unsigned SubExprOffset =
5957 this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
5958 if (!this->visit(SubExpr))
5960 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset,
E))
5965 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
5966 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
5968 return this->emitArrayElemPop(ElemT, Index,
E);
5973 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
5974 if (!getElem(SubExprOffset, I))
5976 if (!this->emitNeg(ElemT,
E))
5978 if (!this->emitInitElem(ElemT, I,
E))
5993 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
5994 if (!getElem(SubExprOffset, I))
5997 if (!this->emitPrimCast(ElemT,
PT_Bool, Ctx.getASTContext().BoolTy,
E))
5999 if (!this->emitInv(
E))
6001 if (!this->emitPrimCast(
PT_Bool, ElemT, VecTy->getElementType(),
E))
6003 if (!this->emitNeg(ElemT,
E))
6005 if (ElemT != ResultVecElemT &&
6006 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy,
E))
6008 if (!this->emitInitElem(ResultVecElemT, I,
E))
6014 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6015 if (!getElem(SubExprOffset, I))
6018 if (!this->emitInv(
E))
6021 if (!this->emitComp(ElemT,
E))
6024 if (!this->emitInitElem(ElemT, I,
E))
6029 llvm_unreachable(
"Unsupported unary operators should be handled up front");
6034template <
class Emitter>
6039 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(
D)) {
6040 return this->emitConst(ECD->getInitVal(),
E);
6041 }
else if (
const auto *BD = dyn_cast<BindingDecl>(
D)) {
6042 return this->visit(BD->getBinding());
6043 }
else if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(
D)) {
6044 const Function *F = getFunction(FuncDecl);
6045 return F && this->emitGetFnPtr(F,
E);
6046 }
else if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(
D)) {
6047 if (std::optional<unsigned> Index =
P.getOrCreateGlobal(
D)) {
6048 if (!this->emitGetPtrGlobal(*Index,
E))
6050 if (std::optional<PrimType>
T = classify(
E->
getType())) {
6051 if (!this->visitAPValue(TPOD->getValue(), *
T,
E))
6053 return this->emitInitGlobal(*
T, *Index,
E);
6055 return this->visitAPValueInitializer(TPOD->getValue(),
E);
6064 bool IsReference =
D->getType()->isReferenceType();
6067 if (
auto It = Locals.find(
D); It != Locals.end()) {
6068 const unsigned Offset = It->second.Offset;
6070 return this->emitGetLocal(
PT_Ptr, Offset,
E);
6071 return this->emitGetPtrLocal(Offset,
E);
6072 }
else if (
auto GlobalIndex =
P.getGlobal(
D)) {
6074 if (!Ctx.getLangOpts().CPlusPlus11)
6075 return this->emitGetGlobal(classifyPrim(
E), *GlobalIndex,
E);
6076 return this->emitGetGlobalUnchecked(classifyPrim(
E), *GlobalIndex,
E);
6079 return this->emitGetPtrGlobal(*GlobalIndex,
E);
6080 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(
D)) {
6081 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
6082 if (IsReference || !It->second.IsPtr)
6083 return this->emitGetParam(classifyPrim(
E), It->second.Offset,
E);
6085 return this->emitGetPtrParam(It->second.Offset,
E);
6088 if (
D->getType()->isReferenceType())
6093 auto revisit = [&](
const VarDecl *VD) ->
bool {
6094 auto VarState = this->visitDecl(VD);
6096 if (VarState.notCreated())
6101 return this->visitDeclRef(
D,
E);
6105 if (
auto It = this->LambdaCaptures.find(
D);
6106 It != this->LambdaCaptures.end()) {
6107 auto [Offset, IsPtr] = It->second;
6110 return this->emitGetThisFieldPtr(Offset,
E);
6111 return this->emitGetPtrThisField(Offset,
E);
6112 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E);
6113 DRE && DRE->refersToEnclosingVariableOrCapture()) {
6114 if (
const auto *VD = dyn_cast<VarDecl>(
D); VD && VD->isInitCapture())
6118 if (
D != InitializingDecl) {
6121 if (Ctx.getLangOpts().CPlusPlus) {
6122 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
6123 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
6124 if (
T.isConstant(Ctx.getASTContext()))
6130 if (isa<DecompositionDecl>(VD))
6133 if ((VD->hasGlobalStorage() || VD->isStaticDataMember()) &&
6134 typeShouldBeVisited(VD->getType()))
6141 if (VD->isLocalVarDecl() && typeShouldBeVisited(VD->getType()) &&
6142 VD->getInit() && !VD->getInit()->isValueDependent()) {
6144 if (VD->evaluateValue())
6147 if (!
D->getType()->isReferenceType())
6148 return this->emitDummyPtr(
D,
E);
6150 return this->emitInvalidDeclRef(cast<DeclRefExpr>(
E),
6155 if (
const auto *VD = dyn_cast<VarDecl>(
D);
6156 VD && VD->getAnyInitializer() &&
6157 VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak())
6162 return this->emitDummyPtr(
D,
E);
6165template <
class Emitter>
6167 const auto *
D =
E->getDecl();
6168 return this->visitDeclRef(
D,
E);
6173 C->emitDestruction();
6176template <
class Emitter>
6180 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
6182 return Ty->getAsCXXRecordDecl();
6184 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
6185 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
6187 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
6191template <
class Emitter>
6198 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6203 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
6204 getFPOptions(
E),
E);
6206 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
6207 getFPOptions(
E),
E);
6211 return this->emitCastFloatingIntegral(ToT, getFPOptions(
E),
E);
6216 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT),
E);
6218 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT),
E);
6222 return FromT != ToT ? this->emitCast(FromT, ToT,
E) :
true;
6226 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6227 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(
E),
E);
6235template <
class Emitter>
6240 return this->discard(SubExpr);
6242 if (!this->visit(SubExpr))
6245 if (!this->emitConstUint8(0, SubExpr))
6247 return this->emitArrayElemPtrPopUint8(SubExpr);
6251 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
6255template <
class Emitter>
6257 assert(!DiscardResult);
6261 if (!this->emitArrayElem(ElemT, 0,
E))
6264 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(
E),
E))
6267 if (!this->emitCast(ElemT,
PT_Bool,
E))
6272 LabelTy LabelTrue = this->getLabel();
6273 if (!this->jumpTrue(LabelTrue))
6276 if (!this->emitArrayElemPop(ElemT, 1,
E))
6279 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(
E),
E))
6282 if (!this->emitCast(ElemT,
PT_Bool,
E))
6286 LabelTy EndLabel = this->getLabel();
6287 this->jump(EndLabel);
6289 this->emitLabel(LabelTrue);
6290 if (!this->emitPopPtr(
E))
6292 if (!this->emitConstBool(
true,
E))
6295 this->fallthrough(EndLabel);
6296 this->emitLabel(EndLabel);
6301template <
class Emitter>
6304 assert(
E->isComparisonOp());
6306 assert(!DiscardResult);
6312 LHSIsComplex =
true;
6313 ElemT = classifyComplexElementType(LHS->
getType());
6314 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true,
6316 if (!this->visit(LHS))
6318 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
6321 LHSIsComplex =
false;
6323 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
6324 if (!this->visit(LHS))
6326 if (!this->emitSetLocal(LHST, LHSOffset,
E))
6333 RHSIsComplex =
true;
6334 ElemT = classifyComplexElementType(RHS->
getType());
6335 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true,
6337 if (!this->visit(RHS))
6339 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
6342 RHSIsComplex =
false;
6344 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
6345 if (!this->visit(RHS))
6347 if (!this->emitSetLocal(RHST, RHSOffset,
E))
6351 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
6352 bool IsComplex) ->
bool {
6354 if (!this->emitGetLocal(
PT_Ptr, LocalOffset,
E))
6356 return this->emitArrayElemPop(ElemT, Index,
E);
6358 return this->emitGetLocal(ElemT, LocalOffset,
E);
6361 for (
unsigned I = 0; I != 2; ++I) {
6363 if (!getElem(LHSOffset, I, LHSIsComplex))
6365 if (!getElem(RHSOffset, I, RHSIsComplex))
6368 if (!this->emitEQ(ElemT,
E))
6371 if (!this->emitCastBoolUint8(
E))
6376 if (!this->emitAddUint8(
E))
6378 if (!this->emitConstUint8(2,
E))
6381 if (
E->getOpcode() == BO_EQ) {
6382 if (!this->emitEQUint8(
E))
6384 }
else if (
E->getOpcode() == BO_NE) {
6385 if (!this->emitNEUint8(
E))
6392 return this->emitCast(
PT_Bool, ResT,
E);
6399template <
class Emitter>
6408 const Function *DtorFunc = getFunction(Dtor);
6413 if (!this->emitDupPtr(
Loc))
6415 return this->emitCall(DtorFunc, 0,
Loc);
6420template <
class Emitter>
6445 for (ssize_t I = Desc->
getNumElems() - 1; I >= 0; --I) {
6446 if (!this->emitConstUint64(I,
Loc))
6448 if (!this->emitArrayElemPtrUint64(
Loc))
6450 if (!this->emitDestruction(ElemDesc,
Loc))
6452 if (!this->emitPopPtr(
Loc))
6467template <
class Emitter>
6469 assert(!DiscardResult &&
"Should've been checked before");
6471 unsigned DummyID =
P.getOrCreateDummy(
D);
6473 if (!this->emitGetPtrGlobal(DummyID,
E))
6481 return this->emitDecayPtr(
PT_Ptr, PT,
E);
6494template <
class Emitter>
6496 const Expr *SubExpr =
E->getSubExpr();
6499 std::optional<PrimType> ToT = classify(ToType);
6505 std::optional<unsigned> LocalIndex = allocateLocal(
E);
6508 if (!this->emitGetPtrLocal(*LocalIndex,
E))
6518 if (!this->visit(SubExpr))
6520 }
else if (std::optional<PrimType> FromT = classify(SubExpr)) {
6521 unsigned TempOffset = allocateLocalPrimitive(
6522 SubExpr, *FromT,
true,
false);
6523 if (!this->visit(SubExpr))
6525 if (!this->emitSetLocal(*FromT, TempOffset,
E))
6527 if (!this->emitGetPtrLocal(TempOffset,
E))
6534 if (!this->emitBitCast(
E))
6536 return DiscardResult ? this->emitPopPtr(
E) :
true;
6540 const llvm::fltSemantics *TargetSemantics =
nullptr;
6542 TargetSemantics = &Ctx.getFloatSemantics(ToType);
6548 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
6550 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->
isStdByteType(),
6551 ResultBitWidth, TargetSemantics,
E))
6555 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 ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
const LangOptions & getLangOpts() const
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.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
AddrLabelExpr - The GNU address of label extension, representing &&label.
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Represents a loop initializing the elements of an array.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
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 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.
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 Initializing
Flag inidicating if we're initializing an already created variable.
bool visitReturnStmt(const ReturnStmt *RS)
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitChooseExpr(const ChooseExpr *E)
bool visitFunc(const FunctionDecl *F) override
bool visitCXXForRangeStmt(const CXXForRangeStmt *S)
bool visitCaseStmt(const CaseStmt *S)
bool VisitComplexBinOp(const BinaryOperator *E)
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
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 DiscardResult
Flag indicating if return value is to be discarded.
bool VisitEmbedExpr(const EmbedExpr *E)
bool VisitConvertVectorExpr(const ConvertVectorExpr *E)
bool VisitCXXThisExpr(const CXXThisExpr *E)
bool VisitConstantExpr(const ConstantExpr *E)
unsigned allocateTemporary(const Expr *E)
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool visitSwitchStmt(const SwitchStmt *S)
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E)
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsExtended=false)
Creates a local primitive value.
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool visitWhileStmt(const WhileStmt *S)
bool visitIfStmt(const IfStmt *IS)
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
bool VisitFloatingLiteral(const FloatingLiteral *E)
bool 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 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()