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>
3433 if (!
E->isPotentiallyEvaluated()) {
3437 if (
E->isTypeOperand())
3438 return this->emitGetTypeid(
3439 E->getTypeOperand(Ctx.getASTContext()).getTypePtr(), TypeInfoType,
E);
3445 assert(
E->getExprOperand());
3446 assert(
E->getExprOperand()->
isLValue());
3448 if (!Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(
E))
3451 if (!this->visit(
E->getExprOperand()))
3454 if (!this->emitGetTypeidPtr(TypeInfoType,
E))
3457 return this->emitPopPtr(
E);
3461template <
class Emitter>
3463 assert(Ctx.getLangOpts().CPlusPlus);
3464 return this->emitConstBool(
E->getValue(),
E);
3467template <
class Emitter>
3479 return this->emitDummyPtr(GuidDecl,
E);
3481 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(GuidDecl);
3484 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
3487 assert(this->getRecord(
E->
getType()));
3493 assert(
V.isStruct());
3494 assert(
V.getStructNumBases() == 0);
3495 if (!this->visitAPValueInitializer(
V,
E))
3498 return this->emitFinishInit(
E);
3501template <
class Emitter>
3506 return this->emitConstBool(
E->isSatisfied(),
E);
3509template <
class Emitter>
3515 return this->emitConstBool(
E->isSatisfied(),
E);
3518template <
class Emitter>
3521 return this->delegate(
E->getSemanticForm());
3524template <
class Emitter>
3527 for (
const Expr *SemE :
E->semantics()) {
3528 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
3529 if (SemE ==
E->getResultExpr())
3532 if (OVE->isUnique())
3535 if (!this->discard(OVE))
3537 }
else if (SemE ==
E->getResultExpr()) {
3538 if (!this->delegate(SemE))
3541 if (!this->discard(SemE))
3548template <
class Emitter>
3550 return this->delegate(
E->getSelectedExpr());
3553template <
class Emitter>
3555 return this->emitError(
E);
3558template <
class Emitter>
3562 unsigned Offset = allocateLocalPrimitive(
3563 E->getLabel(),
PT_Ptr,
true,
false);
3565 return this->emitGetLocal(
PT_Ptr, Offset,
E);
3568template <
class Emitter>
3572 QualType ElemType = VT->getElementType();
3573 PrimType ElemT = classifyPrim(ElemType);
3574 const Expr *Src =
E->getSrcExpr();
3576 PrimType SrcElemT = classifyVectorElementType(SrcType);
3578 unsigned SrcOffset = this->allocateLocalPrimitive(Src,
PT_Ptr,
true,
false);
3579 if (!this->visit(Src))
3581 if (!this->emitSetLocal(
PT_Ptr, SrcOffset,
E))
3584 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
3585 if (!this->emitGetLocal(
PT_Ptr, SrcOffset,
E))
3587 if (!this->emitArrayElemPop(SrcElemT, I,
E))
3591 if (SrcElemT != ElemT) {
3592 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType,
E))
3594 }
else if (ElemType->isFloatingType() && SrcType != ElemType) {
3595 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
3599 if (!this->emitInitElem(ElemT, I,
E))
3606template <
class Emitter>
3609 assert(
E->getNumSubExprs() > 2);
3611 const Expr *Vecs[] = {
E->getExpr(0),
E->getExpr(1)};
3615 unsigned NumOutputElems =
E->getNumSubExprs() - 2;
3616 assert(NumOutputElems > 0);
3619 unsigned VectorOffsets[2];
3620 for (
unsigned I = 0; I != 2; ++I) {
3621 VectorOffsets[I] = this->allocateLocalPrimitive(
3622 Vecs[I],
PT_Ptr,
true,
false);
3623 if (!this->visit(Vecs[I]))
3625 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I],
E))
3628 for (
unsigned I = 0; I != NumOutputElems; ++I) {
3629 APSInt ShuffleIndex =
E->getShuffleMaskIdx(Ctx.getASTContext(), I);
3630 assert(ShuffleIndex >= -1);
3631 if (ShuffleIndex == -1)
3632 return this->emitInvalidShuffleVectorIndex(I,
E);
3634 assert(ShuffleIndex < (NumInputElems * 2));
3635 if (!this->emitGetLocal(
PT_Ptr,
3636 VectorOffsets[ShuffleIndex >= NumInputElems],
E))
3638 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
3639 if (!this->emitArrayElemPop(ElemT, InputVectorIndex,
E))
3642 if (!this->emitInitElem(ElemT, I,
E))
3649template <
class Emitter>
3654 Base->getType()->isVectorType() ||
3658 E->getEncodedElementAccess(Indices);
3660 if (Indices.size() == 1) {
3661 if (!this->visit(
Base))
3665 if (!this->emitConstUint32(Indices[0],
E))
3667 return this->emitArrayElemPtrPop(
PT_Uint32,
E);
3670 return this->emitArrayElemPop(classifyPrim(
E->
getType()), Indices[0],
E);
3674 unsigned BaseOffset = allocateLocalPrimitive(
Base,
PT_Ptr,
true,
3676 if (!this->visit(
Base))
3678 if (!this->emitSetLocal(
PT_Ptr, BaseOffset,
E))
3683 std::optional<unsigned> ResultIndex;
3684 ResultIndex = allocateLocal(
E);
3687 if (!this->emitGetPtrLocal(*ResultIndex,
E))
3695 uint32_t DstIndex = 0;
3696 for (uint32_t I : Indices) {
3697 if (!this->emitGetLocal(
PT_Ptr, BaseOffset,
E))
3699 if (!this->emitArrayElemPop(ElemT, I,
E))
3701 if (!this->emitInitElem(ElemT, DstIndex,
E))
3707 assert(!DiscardResult);
3711template <
class Emitter>
3713 const Expr *SubExpr =
E->getSubExpr();
3714 if (!
E->isExpressibleAsConstantInitializer())
3715 return this->discard(SubExpr) && this->emitInvalid(
E);
3720 assert(classifyPrim(
E) ==
PT_Ptr);
3721 return this->emitDummyPtr(
E,
E);
3724template <
class Emitter>
3727 const Expr *SubExpr =
E->getSubExpr();
3729 Ctx.getASTContext().getAsConstantArrayType(SubExpr->
getType());
3734 if (!this->visit(SubExpr))
3736 if (!this->emitConstUint8(0,
E))
3738 if (!this->emitArrayElemPtrPopUint8(
E))
3750 assert(SecondFieldT ==
PT_Ptr);
3754 if (!this->emitExpandPtr(
E))
3758 if (!this->emitArrayElemPtrPop(
PT_Uint64,
E))
3763template <
class Emitter>
3772 if (!this->visitStmt(S))
3777 assert(S == Result);
3778 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
3779 return this->delegate(ResultExpr);
3780 return this->emitUnsupported(
E);
3789 return this->Visit(
E);
3796 return this->Visit(
E);
3804 return this->discard(
E);
3809 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3813 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3815 return this->visitInitializer(
E);
3822 return this->Visit(
E);
3825template <
class Emitter>
3831 return this->Visit(
E);
3835 std::optional<PrimType>
T = classify(
E->
getType());
3839 if (!this->visit(
E))
3841 return this->emitComplexBoolCast(
E);
3846 if (!this->visit(
E))
3854 if (!this->emitNull(*
T, 0,
nullptr,
E))
3856 return this->emitNE(*
T,
E);
3861 return this->emitCastFloatingIntegralBool(getFPOptions(
E),
E);
3867template <
class Emitter>
3872 return this->emitZeroBool(
E);
3874 return this->emitZeroSint8(
E);
3876 return this->emitZeroUint8(
E);
3878 return this->emitZeroSint16(
E);
3880 return this->emitZeroUint16(
E);
3882 return this->emitZeroSint32(
E);
3884 return this->emitZeroUint32(
E);
3886 return this->emitZeroSint64(
E);
3888 return this->emitZeroUint64(
E);
3890 return this->emitZeroIntAP(Ctx.getBitWidth(QT),
E);
3892 return this->emitZeroIntAPS(Ctx.getBitWidth(QT),
E);
3894 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
3897 return this->emitNullFnPtr(0,
nullptr,
E);
3899 return this->emitNullMemberPtr(0,
nullptr,
E);
3901 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)),
E);
3903 auto Sem = Ctx.getASTContext().getFixedPointSemantics(
E->
getType());
3906 llvm_unreachable(
"Implement");
3908 llvm_unreachable(
"unknown primitive type");
3911template <
class Emitter>
3917 for (
const Record::Field &Field : R->
fields()) {
3918 if (
Field.Decl->isUnnamedBitField())
3922 if (
D->isPrimitive()) {
3925 if (!this->visitZeroInitializer(
T, QT,
E))
3927 if (!this->emitInitField(
T,
Field.Offset,
E))
3934 if (!this->emitGetPtrField(
Field.Offset,
E))
3937 if (
D->isPrimitiveArray()) {
3940 for (uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
3941 if (!this->visitZeroInitializer(
T, ET,
E))
3943 if (!this->emitInitElem(
T, I,
E))
3946 }
else if (
D->isCompositeArray()) {
3948 if (!this->visitZeroArrayInitializer(
D->getType(),
E))
3950 }
else if (
D->isRecord()) {
3951 if (!this->visitZeroRecordInitializer(
D->ElemRecord,
E))
3957 if (!this->emitFinishInitPop(
E))
3966 for (
const Record::Base &B : R->
bases()) {
3967 if (!this->emitGetPtrBase(B.Offset,
E))
3969 if (!this->visitZeroRecordInitializer(B.R,
E))
3971 if (!this->emitFinishInitPop(
E))
3980template <
class Emitter>
3985 size_t NumElems = cast<ConstantArrayType>(AT)->getZExtSize();
3987 if (std::optional<PrimType> ElemT = classify(ElemType)) {
3988 for (
size_t I = 0; I != NumElems; ++I) {
3989 if (!this->visitZeroInitializer(*ElemT, ElemType,
E))
3991 if (!this->emitInitElem(*ElemT, I,
E))
3996 const Record *R = getRecord(ElemType);
3998 for (
size_t I = 0; I != NumElems; ++I) {
3999 if (!this->emitConstUint32(I,
E))
4003 if (!this->visitZeroRecordInitializer(R,
E))
4005 if (!this->emitPopPtr(
E))
4010 for (
size_t I = 0; I != NumElems; ++I) {
4011 if (!this->emitConstUint32(I,
E))
4015 if (!this->visitZeroArrayInitializer(ElemType,
E))
4017 if (!this->emitPopPtr(
E))
4026template <
class Emitter>
4027template <
typename T>
4031 return this->emitConstSint8(
Value,
E);
4033 return this->emitConstUint8(
Value,
E);
4035 return this->emitConstSint16(
Value,
E);
4037 return this->emitConstUint16(
Value,
E);
4039 return this->emitConstSint32(
Value,
E);
4041 return this->emitConstUint32(
Value,
E);
4043 return this->emitConstSint64(
Value,
E);
4045 return this->emitConstUint64(
Value,
E);
4047 return this->emitConstBool(
Value,
E);
4055 llvm_unreachable(
"Invalid integral type");
4058 llvm_unreachable(
"unknown primitive type");
4061template <
class Emitter>
4062template <
typename T>
4067template <
class Emitter>
4071 return this->emitConstIntAPS(
Value,
E);
4073 return this->emitConstIntAP(
Value,
E);
4075 if (
Value.isSigned())
4076 return this->emitConst(
Value.getSExtValue(), Ty,
E);
4077 return this->emitConst(
Value.getZExtValue(), Ty,
E);
4080template <
class Emitter>
4085template <
class Emitter>
4090 if (
const auto *VD =
4091 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4092 assert(!
P.getGlobal(VD));
4093 assert(!Locals.contains(VD));
4101 isa<const Expr *>(Src));
4103 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
4104 Locals.insert({VD, Local});
4105 VarScope->add(Local, IsExtended);
4106 return Local.Offset;
4109template <
class Emitter>
4110std::optional<unsigned>
4114 if ([[maybe_unused]]
const auto *VD =
4115 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4116 assert(!
P.getGlobal(VD));
4117 assert(!Locals.contains(VD));
4122 bool IsTemporary =
false;
4123 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4127 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
4128 Init = VarD->getInit();
4130 if (
auto *
E = Src.dyn_cast<
const Expr *>()) {
4138 IsTemporary,
false,
Init);
4140 return std::nullopt;
4144 Locals.insert({Key, Local});
4146 VarScope->addExtended(Local, ExtendingDecl);
4148 VarScope->add(Local,
false);
4149 return Local.Offset;
4152template <
class Emitter>
4159 true,
false,
nullptr);
4166 while (S->getParent())
4168 assert(S && !S->getParent());
4170 return Local.Offset;
4173template <
class Emitter>
4175 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
4181 if (
const auto *RecordTy = getRecordTy(Ty))
4182 return getRecord(RecordTy->getDecl());
4186template <
class Emitter>
4188 return P.getOrCreateRecord(RD);
4191template <
class Emitter>
4193 return Ctx.getOrCreateFunction(FD);
4196template <
class Emitter>
4201 if (!DestroyToplevelScope) {
4202 if (!this->emitCheckAllocations(
E))
4206 auto maybeDestroyLocals = [&]() ->
bool {
4207 if (DestroyToplevelScope)
4208 return RootScope.
destroyLocals() && this->emitCheckAllocations(
E);
4209 return this->emitCheckAllocations(
E);
4216 return this->emitRetVoid(
E) && maybeDestroyLocals();
4220 if (std::optional<PrimType>
T = classify(
E)) {
4224 return this->emitRet(*
T,
E) && maybeDestroyLocals();
4230 if (std::optional<unsigned> LocalOffset = this->allocateLocal(
E)) {
4231 if (!this->emitGetPtrLocal(*LocalOffset,
E))
4234 if (!visitInitializer(
E))
4237 if (!this->emitFinishInit(
E))
4242 return this->emitRetValue(
E) && maybeDestroyLocals();
4245 return maybeDestroyLocals() && this->emitCheckAllocations(
E) &&
false;
4248template <
class Emitter>
4251 auto R = this->visitVarDecl(VD,
true);
4260 if (
auto GlobalIndex =
P.getGlobal(VD)) {
4261 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
4265 GD.
InitState = GlobalInitState::InitializerFailed;
4276template <
class Emitter>
4278 bool ConstantContext) {
4279 std::optional<PrimType> VarT = classify(VD->
getType());
4283 if (!ConstantContext) {
4288 this->emitCheckAllocations(VD);
4292 if (!this->visitVarDecl(VD,
true))
4296 auto GlobalIndex =
P.getGlobal(VD);
4297 assert(GlobalIndex);
4299 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
4302 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
4306 auto Local = Locals.find(VD);
4307 assert(Local != Locals.end());
4309 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
4312 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
4318 if (!this->emitRet(VarT.value_or(
PT_Ptr), VD)) {
4322 auto GlobalIndex =
P.getGlobal(VD);
4323 assert(GlobalIndex);
4324 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
4328 GD.
InitState = GlobalInitState::InitializerFailed;
4334 return VDScope.
destroyLocals() && this->emitCheckAllocations(VD);
4337template <
class Emitter>
4346 if (!this->isActive())
4350 std::optional<PrimType> VarT = classify(VD->
getType());
4352 if (
Init &&
Init->isValueDependent())
4356 auto checkDecl = [&]() ->
bool {
4358 return !NeedsOp || this->emitCheckDecl(VD, VD);
4361 auto initGlobal = [&](
unsigned GlobalIndex) ->
bool {
4365 if (!this->visit(
Init))
4366 return checkDecl() &&
false;
4368 return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
4374 if (!this->emitGetPtrGlobal(GlobalIndex,
Init))
4377 if (!visitInitializer(
Init))
4380 if (!this->emitFinishInit(
Init))
4383 return this->emitPopPtr(
Init);
4389 if (std::optional<unsigned> GlobalIndex =
P.getGlobal(VD)) {
4390 if (
P.getPtrGlobal(*GlobalIndex).isInitialized())
4395 return Init && checkDecl() && initGlobal(*GlobalIndex);
4398 std::optional<unsigned> GlobalIndex =
P.createGlobal(VD,
Init);
4403 return !
Init || (checkDecl() && initGlobal(*GlobalIndex));
4408 unsigned Offset = this->allocateLocalPrimitive(
4415 if (!this->visit(
Init))
4417 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
4419 if (!this->visit(
Init))
4421 return this->emitSetLocal(*VarT, Offset, VD);
4425 if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
4429 if (!this->emitGetPtrLocal(*Offset,
Init))
4432 if (!visitInitializer(
Init))
4435 if (!this->emitFinishInit(
Init))
4438 return this->emitPopPtr(
Init);
4448template <
class Emitter>
4451 assert(!DiscardResult);
4453 return this->emitConst(Val.
getInt(), ValType,
E);
4455 return this->emitConstFloat(Val.
getFloat(),
E);
4459 return this->emitNull(ValType, 0,
nullptr,
E);
4461 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
4462 return this->visit(BaseExpr);
4463 else if (
const auto *VD =
Base.dyn_cast<
const ValueDecl *>()) {
4464 return this->visitDeclRef(VD,
E);
4468 return this->emitGetMemberPtr(MemberDecl,
E);
4469 return this->emitNullMemberPtr(0,
nullptr,
E);
4475template <
class Emitter>
4484 const Record::Field *RF = R->
getField(I);
4487 PrimType T = classifyPrim(RF->Decl->getType());
4488 if (!this->visitAPValue(F,
T,
E))
4490 if (!this->emitInitField(
T, RF->Offset,
E))
4493 assert(RF->Desc->isPrimitiveArray());
4494 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
4495 PrimType ElemT = classifyPrim(ArrType->getElementType());
4498 if (!this->emitGetPtrField(RF->Offset,
E))
4501 for (
unsigned A = 0, AN = F.
getArraySize(); A != AN; ++A) {
4504 if (!this->emitInitElem(ElemT, A,
E))
4508 if (!this->emitPopPtr(
E))
4511 if (!this->emitGetPtrField(RF->Offset,
E))
4513 if (!this->visitAPValueInitializer(F,
E))
4515 if (!this->emitPopPtr(
E))
4518 assert(
false &&
"I don't think this should be possible");
4527 const Record::Field *RF = R->
getField(UnionField);
4528 PrimType T = classifyPrim(RF->Decl->getType());
4529 if (!this->visitAPValue(F,
T,
E))
4531 return this->emitInitField(
T, RF->Offset,
E);
4538template <
class Emitter>
4540 unsigned BuiltinID) {
4547 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
4548 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
4549 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
4550 BuiltinID == Builtin::BI__builtin_function_start) {
4553 return this->emitDummyPtr(
E,
E);
4557 std::optional<PrimType> ReturnT = classify(
E);
4561 std::optional<unsigned> LocalIndex = allocateLocal(
E);
4564 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4568 if (!
Func->isUnevaluatedBuiltin()) {
4570 for (
const auto *Arg :
E->arguments()) {
4571 if (!this->visit(Arg))
4576 if (!this->emitCallBI(
Func,
E, BuiltinID,
E))
4579 if (DiscardResult && !ReturnType->
isVoidType()) {
4581 return this->emitPop(*ReturnT,
E);
4587template <
class Emitter>
4589 if (
unsigned BuiltinID =
E->getBuiltinCallee())
4590 return VisitBuiltinCallExpr(
E, BuiltinID);
4597 return VisitBuiltinCallExpr(
E, Builtin::BI__builtin_operator_new);
4600 return VisitBuiltinCallExpr(
E, Builtin::BI__builtin_operator_delete);
4604 if (
const auto *DD = dyn_cast_if_present<CXXDestructorDecl>(FuncDecl);
4605 DD && DD->isTrivial())
4608 QualType ReturnType =
E->getCallReturnType(Ctx.getASTContext());
4609 std::optional<PrimType>
T = classify(ReturnType);
4613 if (DiscardResult) {
4617 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4618 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4625 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4626 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4630 if (!this->emitDupPtr(
E))
4638 bool IsAssignmentOperatorCall =
false;
4639 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
4640 OCE && OCE->isAssignmentOp()) {
4644 assert(Args.size() == 2);
4645 IsAssignmentOperatorCall =
true;
4646 std::reverse(Args.begin(), Args.end());
4651 if (isa<CXXOperatorCallExpr>(
E)) {
4652 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
4653 MD && MD->isStatic()) {
4654 if (!this->discard(
E->getArg(0)))
4657 Args.erase(Args.begin());
4661 std::optional<unsigned> CalleeOffset;
4663 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(
E)) {
4664 if (!FuncDecl && classifyPrim(
E->getCallee()) ==
PT_MemberPtr) {
4668 const Expr *Callee =
E->getCallee();
4670 this->allocateLocalPrimitive(Callee,
PT_MemberPtr,
true,
false);
4671 if (!this->visit(Callee))
4677 if (!this->emitGetMemberPtrBase(
E))
4679 }
else if (!this->visit(MC->getImplicitObjectArgument())) {
4682 }
else if (!FuncDecl) {
4683 const Expr *Callee =
E->getCallee();
4684 CalleeOffset = this->allocateLocalPrimitive(Callee,
PT_FnPtr,
true,
false);
4685 if (!this->visit(Callee))
4687 if (!this->emitSetLocal(
PT_FnPtr, *CalleeOffset,
E))
4693 unsigned ArgIndex = 0;
4694 for (
const auto *Arg : Args) {
4695 if (!this->visit(Arg))
4699 if (FuncDecl && NonNullArgs[ArgIndex]) {
4702 if (!this->emitCheckNonNullArg(ArgT, Arg))
4710 if (IsAssignmentOperatorCall) {
4711 assert(Args.size() == 2);
4714 if (!this->emitFlip(Arg2T, Arg1T,
E))
4722 assert(HasRVO ==
Func->hasRVO());
4724 bool HasQualifier =
false;
4725 if (
const auto *ME = dyn_cast<MemberExpr>(
E->getCallee()))
4726 HasQualifier = ME->hasQualifier();
4728 bool IsVirtual =
false;
4729 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
4730 IsVirtual = MD->isVirtual();
4735 if (IsVirtual && !HasQualifier) {
4736 uint32_t VarArgSize = 0;
4737 unsigned NumParams =
4738 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4739 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4742 if (!this->emitCallVirt(
Func, VarArgSize,
E))
4744 }
else if (
Func->isVariadic()) {
4745 uint32_t VarArgSize = 0;
4746 unsigned NumParams =
4747 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4748 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4750 if (!this->emitCallVar(
Func, VarArgSize,
E))
4753 if (!this->emitCall(
Func, 0,
E))
4762 uint32_t ArgSize = 0;
4763 for (
unsigned I = 0, N =
E->getNumArgs(); I != N; ++I)
4768 if (isa<CXXMemberCallExpr>(
E) && CalleeOffset) {
4771 if (!this->emitGetMemberPtrDecl(
E))
4774 if (!this->emitGetLocal(
PT_FnPtr, *CalleeOffset,
E))
4777 if (!this->emitCallPtr(ArgSize,
E,
E))
4782 if (DiscardResult && !ReturnType->
isVoidType() &&
T)
4783 return this->emitPop(*
T,
E);
4788template <
class Emitter>
4792 return this->delegate(
E->getExpr());
4795template <
class Emitter>
4799 const Expr *SubExpr =
E->getExpr();
4800 if (std::optional<PrimType>
T = classify(
E->getExpr()))
4801 return this->visit(SubExpr);
4804 return this->visitInitializer(SubExpr);
4807template <
class Emitter>
4812 return this->emitConstBool(
E->getValue(),
E);
4815template <
class Emitter>
4821 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(
E->
getType());
4822 return this->emitNullPtr(Val,
nullptr,
E);
4825template <
class Emitter>
4833 return this->emitZero(
T,
E);
4836template <
class Emitter>
4841 if (this->LambdaThisCapture.Offset > 0) {
4842 if (this->LambdaThisCapture.IsPtr)
4843 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset,
E);
4844 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset,
E);
4851 if (!InitStackActive || !
E->isImplicit())
4852 return this->emitThis(
E);
4854 if (InitStackActive && !InitStack.empty()) {
4855 unsigned StartIndex = 0;
4856 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
4862 for (
unsigned I = StartIndex, N = InitStack.size(); I != N; ++I) {
4863 if (!InitStack[I].
template emit<Emitter>(
this,
E))
4868 return this->emitThis(
E);
4872 switch (S->getStmtClass()) {
4873 case Stmt::CompoundStmtClass:
4874 return visitCompoundStmt(cast<CompoundStmt>(S));
4875 case Stmt::DeclStmtClass:
4876 return visitDeclStmt(cast<DeclStmt>(S));
4877 case Stmt::ReturnStmtClass:
4878 return visitReturnStmt(cast<ReturnStmt>(S));
4879 case Stmt::IfStmtClass:
4880 return visitIfStmt(cast<IfStmt>(S));
4881 case Stmt::WhileStmtClass:
4882 return visitWhileStmt(cast<WhileStmt>(S));
4883 case Stmt::DoStmtClass:
4884 return visitDoStmt(cast<DoStmt>(S));
4885 case Stmt::ForStmtClass:
4886 return visitForStmt(cast<ForStmt>(S));
4887 case Stmt::CXXForRangeStmtClass:
4888 return visitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
4889 case Stmt::BreakStmtClass:
4890 return visitBreakStmt(cast<BreakStmt>(S));
4891 case Stmt::ContinueStmtClass:
4892 return visitContinueStmt(cast<ContinueStmt>(S));
4893 case Stmt::SwitchStmtClass:
4894 return visitSwitchStmt(cast<SwitchStmt>(S));
4895 case Stmt::CaseStmtClass:
4896 return visitCaseStmt(cast<CaseStmt>(S));
4897 case Stmt::DefaultStmtClass:
4898 return visitDefaultStmt(cast<DefaultStmt>(S));
4899 case Stmt::AttributedStmtClass:
4900 return visitAttributedStmt(cast<AttributedStmt>(S));
4901 case Stmt::CXXTryStmtClass:
4902 return visitCXXTryStmt(cast<CXXTryStmt>(S));
4903 case Stmt::NullStmtClass:
4906 case Stmt::GCCAsmStmtClass:
4907 case Stmt::MSAsmStmtClass:
4908 case Stmt::GotoStmtClass:
4909 return this->emitInvalid(S);
4910 case Stmt::LabelStmtClass:
4911 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
4913 if (
const auto *
E = dyn_cast<Expr>(S))
4914 return this->discard(
E);
4920template <
class Emitter>
4923 for (
const auto *InnerStmt : S->body())
4924 if (!visitStmt(InnerStmt))
4926 return Scope.destroyLocals();
4929template <
class Emitter>
4931 for (
const auto *
D : DS->
decls()) {
4936 const auto *VD = dyn_cast<VarDecl>(
D);
4939 if (!this->visitVarDecl(VD))
4946template <
class Emitter>
4948 if (this->InStmtExpr)
4949 return this->emitUnsupported(RS);
4955 if (!this->visit(RE))
4957 this->emitCleanup();
4958 return this->emitRet(*ReturnType, RS);
4959 }
else if (RE->getType()->isVoidType()) {
4960 if (!this->visit(RE))
4964 if (!this->emitRVOPtr(RE))
4966 if (!this->visitInitializer(RE))
4968 if (!this->emitPopPtr(RE))
4971 this->emitCleanup();
4972 return this->emitRetVoid(RS);
4977 this->emitCleanup();
4978 return this->emitRetVoid(RS);
4982 if (
auto *CondInit = IS->
getInit())
4983 if (!visitStmt(CondInit))
4987 if (!visitDeclStmt(CondDecl))
4992 if (!this->emitIsConstantContext(IS))
4995 if (!this->emitIsConstantContext(IS))
4997 if (!this->emitInv(IS))
5000 if (!this->visitBool(IS->
getCond()))
5005 LabelTy LabelElse = this->getLabel();
5006 LabelTy LabelEnd = this->getLabel();
5007 if (!this->jumpFalse(LabelElse))
5011 if (!visitStmt(IS->
getThen()))
5016 if (!this->jump(LabelEnd))
5018 this->emitLabel(LabelElse);
5021 if (!visitStmt(Else))
5026 this->emitLabel(LabelEnd);
5028 LabelTy LabelEnd = this->getLabel();
5029 if (!this->jumpFalse(LabelEnd))
5033 if (!visitStmt(IS->
getThen()))
5038 this->emitLabel(LabelEnd);
5044template <
class Emitter>
5046 const Expr *Cond = S->getCond();
5047 const Stmt *Body = S->getBody();
5049 LabelTy CondLabel = this->getLabel();
5050 LabelTy EndLabel = this->getLabel();
5053 this->fallthrough(CondLabel);
5054 this->emitLabel(CondLabel);
5058 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5059 if (!visitDeclStmt(CondDecl))
5062 if (!this->visitBool(Cond))
5064 if (!this->jumpFalse(EndLabel))
5067 if (!this->visitStmt(Body))
5073 if (!this->jump(CondLabel))
5075 this->fallthrough(EndLabel);
5076 this->emitLabel(EndLabel);
5082 const Expr *Cond = S->getCond();
5083 const Stmt *Body = S->getBody();
5085 LabelTy StartLabel = this->getLabel();
5086 LabelTy EndLabel = this->getLabel();
5087 LabelTy CondLabel = this->getLabel();
5090 this->fallthrough(StartLabel);
5091 this->emitLabel(StartLabel);
5095 if (!this->visitStmt(Body))
5097 this->fallthrough(CondLabel);
5098 this->emitLabel(CondLabel);
5099 if (!this->visitBool(Cond))
5105 if (!this->jumpTrue(StartLabel))
5108 this->fallthrough(EndLabel);
5109 this->emitLabel(EndLabel);
5113template <
class Emitter>
5117 const Expr *Cond = S->getCond();
5118 const Expr *
Inc = S->getInc();
5119 const Stmt *Body = S->getBody();
5121 LabelTy EndLabel = this->getLabel();
5122 LabelTy CondLabel = this->getLabel();
5123 LabelTy IncLabel = this->getLabel();
5126 if (
Init && !this->visitStmt(
Init))
5129 this->fallthrough(CondLabel);
5130 this->emitLabel(CondLabel);
5134 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5135 if (!visitDeclStmt(CondDecl))
5139 if (!this->visitBool(Cond))
5141 if (!this->jumpFalse(EndLabel))
5145 if (Body && !this->visitStmt(Body))
5148 this->fallthrough(IncLabel);
5149 this->emitLabel(IncLabel);
5150 if (
Inc && !this->discard(
Inc))
5156 if (!this->jump(CondLabel))
5159 this->fallthrough(EndLabel);
5160 this->emitLabel(EndLabel);
5164template <
class Emitter>
5167 const Expr *Cond = S->getCond();
5168 const Expr *
Inc = S->getInc();
5169 const Stmt *Body = S->getBody();
5170 const Stmt *BeginStmt = S->getBeginStmt();
5171 const Stmt *RangeStmt = S->getRangeStmt();
5172 const Stmt *EndStmt = S->getEndStmt();
5173 const VarDecl *LoopVar = S->getLoopVariable();
5175 LabelTy EndLabel = this->getLabel();
5176 LabelTy CondLabel = this->getLabel();
5177 LabelTy IncLabel = this->getLabel();
5181 if (
Init && !this->visitStmt(
Init))
5183 if (!this->visitStmt(RangeStmt))
5185 if (!this->visitStmt(BeginStmt))
5187 if (!this->visitStmt(EndStmt))
5191 this->fallthrough(CondLabel);
5192 this->emitLabel(CondLabel);
5193 if (!this->visitBool(Cond))
5195 if (!this->jumpFalse(EndLabel))
5198 if (!this->visitVarDecl(LoopVar))
5203 if (!this->visitStmt(Body))
5206 this->fallthrough(IncLabel);
5207 this->emitLabel(IncLabel);
5208 if (!this->discard(
Inc))
5212 if (!this->jump(CondLabel))
5215 this->fallthrough(EndLabel);
5216 this->emitLabel(EndLabel);
5220template <
class Emitter>
5227 C->emitDestruction();
5228 return this->jump(*BreakLabel);
5231template <
class Emitter>
5237 C &&
C->getParent() != ContinueVarScope;
C =
C->getParent())
5238 C->emitDestruction();
5239 return this->jump(*ContinueLabel);
5242template <
class Emitter>
5244 const Expr *Cond = S->getCond();
5248 LabelTy EndLabel = this->getLabel();
5250 unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT,
true,
false);
5252 if (
const auto *CondInit = S->getInit())
5253 if (!visitStmt(CondInit))
5256 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5257 if (!visitDeclStmt(CondDecl))
5261 if (!this->visit(Cond))
5263 if (!this->emitSetLocal(CondT, CondVar, S))
5268 for (
const SwitchCase *SC = S->getSwitchCaseList(); SC;
5269 SC = SC->getNextSwitchCase()) {
5270 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
5272 if (CS->caseStmtIsGNURange())
5274 CaseLabels[SC] = this->getLabel();
5280 if (!this->emitGetLocal(CondT, CondVar, CS))
5282 if (!this->visit(
Value))
5286 if (!this->emitEQ(ValueT, S))
5288 if (!this->jumpTrue(CaseLabels[CS]))
5291 assert(!DefaultLabel);
5292 DefaultLabel = this->getLabel();
5299 if (!this->jump(*DefaultLabel))
5302 if (!this->jump(EndLabel))
5307 if (!this->visitStmt(S->getBody()))
5309 this->emitLabel(EndLabel);
5314template <
class Emitter>
5316 this->emitLabel(CaseLabels[S]);
5317 return this->visitStmt(S->getSubStmt());
5320template <
class Emitter>
5322 this->emitLabel(*DefaultLabel);
5323 return this->visitStmt(S->getSubStmt());
5326template <
class Emitter>
5328 if (this->Ctx.getLangOpts().CXXAssumptions &&
5329 !this->Ctx.getLangOpts().MSVCCompat) {
5330 for (
const Attr *A : S->getAttrs()) {
5331 auto *AA = dyn_cast<CXXAssumeAttr>(A);
5335 assert(isa<NullStmt>(S->getSubStmt()));
5337 const Expr *Assumption = AA->getAssumption();
5345 if (!this->visitBool(Assumption))
5348 if (!this->emitAssume(Assumption))
5354 return this->visitStmt(S->getSubStmt());
5357template <
class Emitter>
5360 return this->visitStmt(S->getTryBlock());
5363template <
class Emitter>
5367 assert(cast<CompoundStmt>(MD->
getBody())->body_empty());
5372 const Function *
Func = this->getFunction(LambdaCallOp);
5375 assert(
Func->hasThisPointer());
5378 if (
Func->hasRVO()) {
5379 if (!this->emitRVOPtr(MD))
5387 if (!this->emitNullPtr(0,
nullptr, MD))
5392 auto It = this->Params.find(PVD);
5393 assert(It != this->Params.end());
5397 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
5398 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
5402 if (!this->emitCall(
Func, 0, LambdaCallOp))
5405 this->emitCleanup();
5407 return this->emitRet(*ReturnType, MD);
5410 return this->emitRetVoid(MD);
5413template <
class Emitter>
5415 if (Ctx.getLangOpts().CPlusPlus23)
5424template <
class Emitter>
5426 assert(!ReturnType);
5428 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
5429 const Expr *InitExpr) ->
bool {
5431 if (InitExpr->getType().isNull())
5434 if (std::optional<PrimType>
T = this->classify(InitExpr)) {
5435 if (!this->visit(InitExpr))
5438 if (F->isBitField())
5439 return this->emitInitThisBitField(*
T, F, FieldOffset, InitExpr);
5440 return this->emitInitThisField(*
T, FieldOffset, InitExpr);
5445 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
5448 if (!this->visitInitializer(InitExpr))
5451 return this->emitFinishInitPop(InitExpr);
5455 const Record *R = this->getRecord(RD);
5461 assert(cast<CompoundStmt>(Ctor->
getBody())->body_empty());
5462 if (!this->emitThis(Ctor))
5471 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
5472 this->emitRetVoid(Ctor);
5476 for (
const auto *
Init : Ctor->
inits()) {
5480 const Expr *InitExpr =
Init->getInit();
5484 if (!emitFieldInitializer(F, F->Offset, InitExpr))
5487 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
5490 if (
Init->isBaseVirtual()) {
5492 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
5498 const Record::Base *B = R->
getBase(BaseDecl);
5500 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
5504 if (!this->visitInitializer(InitExpr))
5506 if (!this->emitFinishInitPop(InitExpr))
5509 assert(IFD->getChainingSize() >= 2);
5511 unsigned NestedFieldOffset = 0;
5512 const Record::Field *NestedField =
nullptr;
5513 for (
const NamedDecl *ND : IFD->chain()) {
5514 const auto *FD = cast<FieldDecl>(ND);
5515 const Record *FieldRecord = this->
P.getOrCreateRecord(FD->getParent());
5516 assert(FieldRecord);
5518 NestedField = FieldRecord->
getField(FD);
5519 assert(NestedField);
5521 NestedFieldOffset += NestedField->Offset;
5523 assert(NestedField);
5525 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
5528 assert(
Init->isDelegatingInitializer());
5529 if (!this->emitThis(InitExpr))
5531 if (!this->visitInitializer(
Init->getInit()))
5533 if (!this->emitPopPtr(InitExpr))
5537 if (!
Scope.destroyLocals())
5541 if (
const auto *Body = Ctor->
getBody())
5542 if (!visitStmt(Body))
5548template <
class Emitter>
5551 const Record *R = this->getRecord(RD);
5556 if (!this->visitStmt(Dtor->
getBody()))
5560 if (!this->emitThis(Dtor))
5566 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
5568 if (!
D->isPrimitive() && !
D->isPrimitiveArray()) {
5579 for (
const Record::Base &
Base : llvm::reverse(R->
bases())) {
5580 if (
Base.R->isAnonymousUnion())
5585 if (!this->emitRecordDestruction(
Base.R, {}))
5592 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
5595template <
class Emitter>
5600 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
5601 return this->compileConstructor(Ctor);
5602 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
5603 return this->compileDestructor(Dtor);
5606 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F);
5608 return this->emitLambdaStaticInvokerBody(MD);
5611 if (
const auto *Body = F->
getBody())
5612 if (!visitStmt(Body))
5621template <
class Emitter>
5623 const Expr *SubExpr =
E->getSubExpr();
5625 return this->VisitComplexUnaryOperator(
E);
5627 return this->VisitVectorUnaryOperator(
E);
5629 return this->VisitFixedPointUnaryOperator(
E);
5630 std::optional<PrimType>
T = classify(SubExpr->
getType());
5632 switch (
E->getOpcode()) {
5634 if (!Ctx.getLangOpts().CPlusPlus14)
5635 return this->emitInvalid(
E);
5637 return this->emitError(
E);
5639 if (!this->visit(SubExpr))
5643 if (!this->emitIncPtr(
E))
5646 return DiscardResult ? this->emitPopPtr(
E) :
true;
5650 return DiscardResult ? this->emitIncfPop(getFPOptions(
E),
E)
5651 : this->emitIncf(getFPOptions(
E),
E);
5654 return DiscardResult ? this->emitIncPop(*
T,
E) : this->emitInc(*
T,
E);
5657 if (!Ctx.getLangOpts().CPlusPlus14)
5658 return this->emitInvalid(
E);
5660 return this->emitError(
E);
5662 if (!this->visit(SubExpr))
5666 if (!this->emitDecPtr(
E))
5669 return DiscardResult ? this->emitPopPtr(
E) :
true;
5673 return DiscardResult ? this->emitDecfPop(getFPOptions(
E),
E)
5674 : this->emitDecf(getFPOptions(
E),
E);
5677 return DiscardResult ? this->emitDecPop(*
T,
E) : this->emitDec(*
T,
E);
5680 if (!Ctx.getLangOpts().CPlusPlus14)
5681 return this->emitInvalid(
E);
5683 return this->emitError(
E);
5685 if (!this->visit(SubExpr))
5689 if (!this->emitLoadPtr(
E))
5691 if (!this->emitConstUint8(1,
E))
5693 if (!this->emitAddOffsetUint8(
E))
5695 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5699 if (DiscardResult) {
5701 return this->emitIncfPop(getFPOptions(
E),
E);
5702 return this->emitIncPop(*
T,
E);
5706 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5707 if (!this->emitLoadFloat(
E))
5709 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5711 if (!this->emitAddf(getFPOptions(
E),
E))
5713 if (!this->emitStoreFloat(
E))
5717 if (!this->emitLoad(*
T,
E))
5719 if (!this->emitConst(1,
E))
5721 if (!this->emitAdd(*
T,
E))
5723 if (!this->emitStore(*
T,
E))
5729 if (!Ctx.getLangOpts().CPlusPlus14)
5730 return this->emitInvalid(
E);
5732 return this->emitError(
E);
5734 if (!this->visit(SubExpr))
5738 if (!this->emitLoadPtr(
E))
5740 if (!this->emitConstUint8(1,
E))
5742 if (!this->emitSubOffsetUint8(
E))
5744 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5748 if (DiscardResult) {
5750 return this->emitDecfPop(getFPOptions(
E),
E);
5751 return this->emitDecPop(*
T,
E);
5755 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5756 if (!this->emitLoadFloat(
E))
5758 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5760 if (!this->emitSubf(getFPOptions(
E),
E))
5762 if (!this->emitStoreFloat(
E))
5766 if (!this->emitLoad(*
T,
E))
5768 if (!this->emitConst(1,
E))
5770 if (!this->emitSub(*
T,
E))
5772 if (!this->emitStore(*
T,
E))
5779 return this->emitError(
E);
5782 return this->discard(SubExpr);
5784 if (!this->visitBool(SubExpr))
5787 if (!this->emitInv(
E))
5791 return this->emitCast(
PT_Bool, ET,
E);
5795 return this->emitError(
E);
5797 if (!this->visit(SubExpr))
5799 return DiscardResult ? this->emitPop(*
T,
E) : this->emitNeg(*
T,
E);
5802 return this->emitError(
E);
5804 if (!this->visit(SubExpr))
5806 return DiscardResult ? this->emitPop(*
T,
E) :
true;
5811 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(),
E);
5814 return this->delegate(SubExpr);
5816 if (DiscardResult) {
5818 return this->discard(SubExpr);
5821 if (!this->visit(SubExpr))
5823 if (classifyPrim(SubExpr) ==
PT_Ptr)
5824 return this->emitNarrowPtr(
E);
5829 return this->emitError(
E);
5831 if (!this->visit(SubExpr))
5833 return DiscardResult ? this->emitPop(*
T,
E) : this->emitComp(*
T,
E);
5836 return this->delegate(SubExpr);
5839 if (!this->discard(SubExpr))
5841 return this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
5844 return this->delegate(SubExpr);
5846 assert(
false &&
"Unhandled opcode");
5852template <
class Emitter>
5854 const Expr *SubExpr =
E->getSubExpr();
5858 return this->discard(SubExpr);
5860 std::optional<PrimType> ResT = classify(
E);
5861 auto prepareResult = [=]() ->
bool {
5863 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5866 return this->emitGetPtrLocal(*LocalIndex,
E);
5873 unsigned SubExprOffset = ~0u;
5874 auto createTemp = [=, &SubExprOffset]() ->
bool {
5875 SubExprOffset = this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
5876 if (!this->visit(SubExpr))
5878 return this->emitSetLocal(
PT_Ptr, SubExprOffset,
E);
5882 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
5883 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
5885 return this->emitArrayElemPop(ElemT, Index,
E);
5888 switch (
E->getOpcode()) {
5890 if (!prepareResult())
5894 for (
unsigned I = 0; I != 2; ++I) {
5895 if (!getElem(SubExprOffset, I))
5897 if (!this->emitNeg(ElemT,
E))
5899 if (!this->emitInitElem(ElemT, I,
E))
5907 return this->delegate(SubExpr);
5910 if (!this->visit(SubExpr))
5912 if (!this->emitComplexBoolCast(SubExpr))
5914 if (!this->emitInv(
E))
5917 return this->emitCast(
PT_Bool, ET,
E);
5921 return this->emitComplexReal(SubExpr);
5924 if (!this->visit(SubExpr))
5928 if (!this->emitConstUint8(1,
E))
5930 return this->emitArrayElemPtrPopUint8(
E);
5935 return this->emitArrayElemPop(classifyPrim(
E->
getType()), 1,
E);
5938 if (!this->visit(SubExpr))
5941 if (!this->emitArrayElem(ElemT, 1,
E))
5943 if (!this->emitNeg(ElemT,
E))
5945 if (!this->emitInitElem(ElemT, 1,
E))
5947 return DiscardResult ? this->emitPopPtr(
E) :
true;
5950 return this->delegate(SubExpr);
5953 return this->emitInvalid(
E);
5959template <
class Emitter>
5961 const Expr *SubExpr =
E->getSubExpr();
5965 return this->discard(SubExpr);
5967 auto UnaryOp =
E->getOpcode();
5968 if (UnaryOp == UO_Extension)
5969 return this->delegate(SubExpr);
5971 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
5972 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
5973 return this->emitInvalid(
E);
5976 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
5977 return this->delegate(SubExpr);
5980 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5983 if (!this->emitGetPtrLocal(*LocalIndex,
E))
5988 unsigned SubExprOffset =
5989 this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
5990 if (!this->visit(SubExpr))
5992 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset,
E))
5997 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
5998 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
6000 return this->emitArrayElemPop(ElemT, Index,
E);
6005 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6006 if (!getElem(SubExprOffset, I))
6008 if (!this->emitNeg(ElemT,
E))
6010 if (!this->emitInitElem(ElemT, I,
E))
6025 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6026 if (!getElem(SubExprOffset, I))
6029 if (!this->emitPrimCast(ElemT,
PT_Bool, Ctx.getASTContext().BoolTy,
E))
6031 if (!this->emitInv(
E))
6033 if (!this->emitPrimCast(
PT_Bool, ElemT, VecTy->getElementType(),
E))
6035 if (!this->emitNeg(ElemT,
E))
6037 if (ElemT != ResultVecElemT &&
6038 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy,
E))
6040 if (!this->emitInitElem(ResultVecElemT, I,
E))
6046 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6047 if (!getElem(SubExprOffset, I))
6050 if (!this->emitInv(
E))
6053 if (!this->emitComp(ElemT,
E))
6056 if (!this->emitInitElem(ElemT, I,
E))
6061 llvm_unreachable(
"Unsupported unary operators should be handled up front");
6066template <
class Emitter>
6071 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(
D)) {
6072 return this->emitConst(ECD->getInitVal(),
E);
6073 }
else if (
const auto *BD = dyn_cast<BindingDecl>(
D)) {
6074 return this->visit(BD->getBinding());
6075 }
else if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(
D)) {
6076 const Function *F = getFunction(FuncDecl);
6077 return F && this->emitGetFnPtr(F,
E);
6078 }
else if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(
D)) {
6079 if (std::optional<unsigned> Index =
P.getOrCreateGlobal(
D)) {
6080 if (!this->emitGetPtrGlobal(*Index,
E))
6082 if (std::optional<PrimType>
T = classify(
E->
getType())) {
6083 if (!this->visitAPValue(TPOD->getValue(), *
T,
E))
6085 return this->emitInitGlobal(*
T, *Index,
E);
6087 return this->visitAPValueInitializer(TPOD->getValue(),
E);
6096 bool IsReference =
D->getType()->isReferenceType();
6099 if (
auto It = Locals.find(
D); It != Locals.end()) {
6100 const unsigned Offset = It->second.Offset;
6102 return this->emitGetLocal(
PT_Ptr, Offset,
E);
6103 return this->emitGetPtrLocal(Offset,
E);
6104 }
else if (
auto GlobalIndex =
P.getGlobal(
D)) {
6106 if (!Ctx.getLangOpts().CPlusPlus11)
6107 return this->emitGetGlobal(classifyPrim(
E), *GlobalIndex,
E);
6108 return this->emitGetGlobalUnchecked(classifyPrim(
E), *GlobalIndex,
E);
6111 return this->emitGetPtrGlobal(*GlobalIndex,
E);
6112 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(
D)) {
6113 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
6114 if (IsReference || !It->second.IsPtr)
6115 return this->emitGetParam(classifyPrim(
E), It->second.Offset,
E);
6117 return this->emitGetPtrParam(It->second.Offset,
E);
6120 if (
D->getType()->isReferenceType())
6125 auto revisit = [&](
const VarDecl *VD) ->
bool {
6126 auto VarState = this->visitDecl(VD);
6128 if (VarState.notCreated())
6133 return this->visitDeclRef(
D,
E);
6137 if (
auto It = this->LambdaCaptures.find(
D);
6138 It != this->LambdaCaptures.end()) {
6139 auto [Offset, IsPtr] = It->second;
6142 return this->emitGetThisFieldPtr(Offset,
E);
6143 return this->emitGetPtrThisField(Offset,
E);
6144 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E);
6145 DRE && DRE->refersToEnclosingVariableOrCapture()) {
6146 if (
const auto *VD = dyn_cast<VarDecl>(
D); VD && VD->isInitCapture())
6150 if (
D != InitializingDecl) {
6153 if (Ctx.getLangOpts().CPlusPlus) {
6154 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
6155 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
6156 if (
T.isConstant(Ctx.getASTContext()))
6162 if (isa<DecompositionDecl>(VD))
6165 if ((VD->hasGlobalStorage() || VD->isStaticDataMember()) &&
6166 typeShouldBeVisited(VD->getType()))
6173 if (VD->isLocalVarDecl() && typeShouldBeVisited(VD->getType()) &&
6174 VD->getInit() && !VD->getInit()->isValueDependent()) {
6176 if (VD->evaluateValue())
6179 if (!
D->getType()->isReferenceType())
6180 return this->emitDummyPtr(
D,
E);
6182 return this->emitInvalidDeclRef(cast<DeclRefExpr>(
E),
6187 if (
const auto *VD = dyn_cast<VarDecl>(
D);
6188 VD && VD->getAnyInitializer() &&
6189 VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak())
6194 return this->emitDummyPtr(
D,
E);
6197template <
class Emitter>
6199 const auto *
D =
E->getDecl();
6200 return this->visitDeclRef(
D,
E);
6205 C->emitDestruction();
6208template <
class Emitter>
6212 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
6214 return Ty->getAsCXXRecordDecl();
6216 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
6217 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
6219 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
6223template <
class Emitter>
6230 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6235 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
6236 getFPOptions(
E),
E);
6238 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
6239 getFPOptions(
E),
E);
6243 return this->emitCastFloatingIntegral(ToT, getFPOptions(
E),
E);
6248 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT),
E);
6250 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT),
E);
6254 return FromT != ToT ? this->emitCast(FromT, ToT,
E) :
true;
6258 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6259 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(
E),
E);
6267template <
class Emitter>
6272 return this->discard(SubExpr);
6274 if (!this->visit(SubExpr))
6277 if (!this->emitConstUint8(0, SubExpr))
6279 return this->emitArrayElemPtrPopUint8(SubExpr);
6283 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
6287template <
class Emitter>
6289 assert(!DiscardResult);
6293 if (!this->emitArrayElem(ElemT, 0,
E))
6296 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(
E),
E))
6299 if (!this->emitCast(ElemT,
PT_Bool,
E))
6304 LabelTy LabelTrue = this->getLabel();
6305 if (!this->jumpTrue(LabelTrue))
6308 if (!this->emitArrayElemPop(ElemT, 1,
E))
6311 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(
E),
E))
6314 if (!this->emitCast(ElemT,
PT_Bool,
E))
6318 LabelTy EndLabel = this->getLabel();
6319 this->jump(EndLabel);
6321 this->emitLabel(LabelTrue);
6322 if (!this->emitPopPtr(
E))
6324 if (!this->emitConstBool(
true,
E))
6327 this->fallthrough(EndLabel);
6328 this->emitLabel(EndLabel);
6333template <
class Emitter>
6336 assert(
E->isComparisonOp());
6338 assert(!DiscardResult);
6344 LHSIsComplex =
true;
6345 ElemT = classifyComplexElementType(LHS->
getType());
6346 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true,
6348 if (!this->visit(LHS))
6350 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
6353 LHSIsComplex =
false;
6355 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
6356 if (!this->visit(LHS))
6358 if (!this->emitSetLocal(LHST, LHSOffset,
E))
6365 RHSIsComplex =
true;
6366 ElemT = classifyComplexElementType(RHS->
getType());
6367 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true,
6369 if (!this->visit(RHS))
6371 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
6374 RHSIsComplex =
false;
6376 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
6377 if (!this->visit(RHS))
6379 if (!this->emitSetLocal(RHST, RHSOffset,
E))
6383 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
6384 bool IsComplex) ->
bool {
6386 if (!this->emitGetLocal(
PT_Ptr, LocalOffset,
E))
6388 return this->emitArrayElemPop(ElemT, Index,
E);
6390 return this->emitGetLocal(ElemT, LocalOffset,
E);
6393 for (
unsigned I = 0; I != 2; ++I) {
6395 if (!getElem(LHSOffset, I, LHSIsComplex))
6397 if (!getElem(RHSOffset, I, RHSIsComplex))
6400 if (!this->emitEQ(ElemT,
E))
6403 if (!this->emitCastBoolUint8(
E))
6408 if (!this->emitAddUint8(
E))
6410 if (!this->emitConstUint8(2,
E))
6413 if (
E->getOpcode() == BO_EQ) {
6414 if (!this->emitEQUint8(
E))
6416 }
else if (
E->getOpcode() == BO_NE) {
6417 if (!this->emitNEUint8(
E))
6424 return this->emitCast(
PT_Bool, ResT,
E);
6431template <
class Emitter>
6440 const Function *DtorFunc = getFunction(Dtor);
6445 if (!this->emitDupPtr(
Loc))
6447 return this->emitCall(DtorFunc, 0,
Loc);
6452template <
class Emitter>
6477 for (ssize_t I = Desc->
getNumElems() - 1; I >= 0; --I) {
6478 if (!this->emitConstUint64(I,
Loc))
6480 if (!this->emitArrayElemPtrUint64(
Loc))
6482 if (!this->emitDestruction(ElemDesc,
Loc))
6484 if (!this->emitPopPtr(
Loc))
6499template <
class Emitter>
6501 assert(!DiscardResult &&
"Should've been checked before");
6503 unsigned DummyID =
P.getOrCreateDummy(
D);
6505 if (!this->emitGetPtrGlobal(DummyID,
E))
6513 return this->emitDecayPtr(
PT_Ptr, PT,
E);
6526template <
class Emitter>
6528 const Expr *SubExpr =
E->getSubExpr();
6531 std::optional<PrimType> ToT = classify(ToType);
6537 std::optional<unsigned> LocalIndex = allocateLocal(
E);
6540 if (!this->emitGetPtrLocal(*LocalIndex,
E))
6550 if (!this->visit(SubExpr))
6552 }
else if (std::optional<PrimType> FromT = classify(SubExpr)) {
6553 unsigned TempOffset = allocateLocalPrimitive(
6554 SubExpr, *FromT,
true,
false);
6555 if (!this->visit(SubExpr))
6557 if (!this->emitSetLocal(*FromT, TempOffset,
E))
6559 if (!this->emitGetPtrLocal(TempOffset,
E))
6566 if (!this->emitBitCast(
E))
6568 return DiscardResult ? this->emitPopPtr(
E) :
true;
6572 const llvm::fltSemantics *TargetSemantics =
nullptr;
6574 TargetSemantics = &Ctx.getFloatSemantics(ToType);
6580 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
6582 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->
isStdByteType(),
6583 ResultBitWidth, TargetSemantics,
E))
6587 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 C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
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 VisitCXXTypeidExpr(const CXXTypeidExpr *E)
bool VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinID)
OptLabelTy ContinueLabel
Point to continue to.
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
bool visitDoStmt(const DoStmt *S)
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitInitListExpr(const InitListExpr *E)
bool VisitVectorBinOp(const BinaryOperator *E)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
VariableScope< Emitter > * BreakVarScope
Scope to cleanup until when we see a break statement.
std::optional< LabelTy > OptLabelTy
bool 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()