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 return Ctx->emitRVOPtr(
E);
98 llvm_unreachable(
"Unhandled InitLink kind");
122 OldContinueLabel(
Ctx->ContinueLabel),
123 OldBreakVarScope(
Ctx->BreakVarScope),
124 OldContinueVarScope(
Ctx->ContinueVarScope) {
132 this->
Ctx->BreakLabel = OldBreakLabel;
133 this->
Ctx->ContinueLabel = OldContinueLabel;
134 this->
Ctx->ContinueVarScope = OldContinueVarScope;
135 this->
Ctx->BreakVarScope = OldBreakVarScope;
155 OldDefaultLabel(this->
Ctx->DefaultLabel),
156 OldCaseLabels(
std::move(this->
Ctx->CaseLabels)),
157 OldLabelVarScope(
Ctx->BreakVarScope) {
160 this->Ctx->
CaseLabels = std::move(CaseLabels);
165 this->
Ctx->BreakLabel = OldBreakLabel;
166 this->
Ctx->DefaultLabel = OldDefaultLabel;
167 this->
Ctx->CaseLabels = std::move(OldCaseLabels);
168 this->
Ctx->BreakVarScope = OldLabelVarScope;
194template <
class Emitter>
199 case CK_LValueToRValue: {
201 return this->discard(SubExpr);
203 std::optional<PrimType> SubExprT = classify(SubExpr->
getType());
206 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
209 if (!this->emitGetPtrLocal(*LocalIndex, CE))
213 if (!this->visit(SubExpr))
217 return this->emitLoadPop(*SubExprT, CE);
222 return this->emitMemcpy(CE);
225 case CK_DerivedToBaseMemberPointer: {
234 if (!this->delegate(SubExpr))
237 return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
240 case CK_BaseToDerivedMemberPointer: {
246 unsigned DerivedOffset = collectBaseOffset(
QualType(FromMP->getClass(), 0),
249 if (!this->delegate(SubExpr))
251 return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
254 case CK_UncheckedDerivedToBase:
255 case CK_DerivedToBase: {
256 if (!this->delegate(SubExpr))
260 if (
const auto *PT = dyn_cast<PointerType>(Ty))
261 return PT->getPointeeType()->getAsCXXRecordDecl();
262 return Ty->getAsCXXRecordDecl();
269 if (B->isVirtual()) {
270 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))
272 CurType = B->getType();
274 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
275 if (!this->emitGetPtrBasePop(DerivedOffset, CE))
277 CurType = B->getType();
284 case CK_BaseToDerived: {
285 if (!this->delegate(SubExpr))
288 unsigned DerivedOffset =
291 return this->emitGetPtrDerivedPop(DerivedOffset, CE);
294 case CK_FloatingCast: {
300 return this->discard(SubExpr);
301 if (!this->visit(SubExpr))
303 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
307 case CK_IntegralToFloating: {
309 return this->discard(SubExpr);
310 std::optional<PrimType> FromT = classify(SubExpr->
getType());
314 if (!this->visit(SubExpr))
317 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
318 return this->emitCastIntegralFloating(*FromT, TargetSemantics,
319 getFPOptions(CE), CE);
322 case CK_FloatingToBoolean:
323 case CK_FloatingToIntegral: {
325 return this->discard(SubExpr);
327 std::optional<PrimType> ToT = classify(CE->
getType());
332 if (!this->visit(SubExpr))
336 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->
getType()),
337 getFPOptions(CE), CE);
339 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->
getType()),
340 getFPOptions(CE), CE);
342 return this->emitCastFloatingIntegral(*ToT, getFPOptions(CE), CE);
345 case CK_NullToPointer:
346 case CK_NullToMemberPointer: {
347 if (!this->discard(SubExpr))
354 if (!PointeeType.
isNull()) {
355 if (std::optional<PrimType>
T = classify(PointeeType))
356 Desc =
P.createDescriptor(SubExpr, *
T);
358 Desc =
P.createDescriptor(SubExpr, PointeeType.
getTypePtr(),
359 std::nullopt,
true,
false,
363 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(CE->
getType());
364 return this->emitNull(classifyPrim(CE->
getType()), Val, Desc, CE);
367 case CK_PointerToIntegral: {
369 return this->discard(SubExpr);
371 if (!this->visit(SubExpr))
377 if (!this->emitDecayPtr(FromT,
PT_Ptr, CE))
383 return this->emitCastPointerIntegralAP(Ctx.getBitWidth(CE->
getType()),
386 return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(CE->
getType()),
388 return this->emitCastPointerIntegral(
T, CE);
391 case CK_ArrayToPointerDecay: {
392 if (!this->visit(SubExpr))
394 if (!this->emitArrayDecay(CE))
397 return this->emitPopPtr(CE);
401 case CK_IntegralToPointer: {
404 if (!this->visit(SubExpr))
410 return this->emitPop(
T, CE);
415 Desc =
P.createDescriptor(SubExpr, *
T);
423 if (!this->emitGetIntPtr(
T, Desc, CE))
426 PrimType DestPtrT = classifyPrim(PtrType);
431 return this->emitDecayPtr(
PT_Ptr, DestPtrT, CE);
434 case CK_AtomicToNonAtomic:
435 case CK_ConstructorConversion:
436 case CK_FunctionToPointerDecay:
437 case CK_NonAtomicToAtomic:
439 case CK_UserDefinedConversion:
440 case CK_AddressSpaceConversion:
441 case CK_CPointerToObjCPointerCast:
442 return this->delegate(SubExpr);
447 if (!this->discard(SubExpr))
449 return this->emitInvalidCast(CastKind::Reinterpret,
true, CE);
453 return this->discard(SubExpr);
456 std::optional<PrimType> FromT = classify(SubExprTy);
459 return this->emitBuiltinBitCast(CE);
461 std::optional<PrimType> ToT = classify(CE->
getType());
469 return this->delegate(SubExpr);
471 if (!this->visit(SubExpr))
478 if (!this->visit(SubExpr))
480 return this->emitDecayPtr(*FromT, *ToT, CE);
483 case CK_LValueToRValueBitCast:
484 return this->emitBuiltinBitCast(CE);
486 case CK_IntegralToBoolean:
487 case CK_FixedPointToBoolean:
488 case CK_BooleanToSignedIntegral:
489 case CK_IntegralCast: {
491 return this->discard(SubExpr);
492 std::optional<PrimType> FromT = classify(SubExpr->
getType());
493 std::optional<PrimType> ToT = classify(CE->
getType());
498 if (!this->visit(SubExpr))
506 if (!this->emitCheckEnumValue(*FromT, ET->getDecl(), CE))
511 auto maybeNegate = [&]() ->
bool {
512 if (CE->
getCastKind() == CK_BooleanToSignedIntegral)
513 return this->emitNeg(*ToT, CE);
518 return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->
getType()), CE) &&
521 return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->
getType()), CE) &&
526 if (!this->emitCast(*FromT, *ToT, CE))
529 return maybeNegate();
532 case CK_PointerToBoolean:
533 case CK_MemberPointerToBoolean: {
536 if (!this->visit(SubExpr))
538 return this->emitIsNonNull(PtrT, CE);
541 case CK_IntegralComplexToBoolean:
542 case CK_FloatingComplexToBoolean: {
544 return this->discard(SubExpr);
545 if (!this->visit(SubExpr))
547 return this->emitComplexBoolCast(SubExpr);
550 case CK_IntegralComplexToReal:
551 case CK_FloatingComplexToReal:
552 return this->emitComplexReal(SubExpr);
554 case CK_IntegralRealToComplex:
555 case CK_FloatingRealToComplex: {
559 unsigned LocalIndex = allocateTemporary(CE);
560 if (!this->emitGetPtrLocal(LocalIndex, CE))
565 if (!this->visitArrayElemInit(0, SubExpr))
569 if (!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
571 return this->emitInitElem(
T, 1, SubExpr);
574 case CK_IntegralComplexCast:
575 case CK_FloatingComplexCast:
576 case CK_IntegralComplexToFloatingComplex:
577 case CK_FloatingComplexToIntegralComplex: {
581 return this->discard(SubExpr);
584 std::optional<unsigned> LocalIndex = allocateLocal(CE);
587 if (!this->emitGetPtrLocal(*LocalIndex, CE))
594 unsigned SubExprOffset = allocateLocalPrimitive(
595 SubExpr,
PT_Ptr,
true,
false);
596 if (!this->visit(SubExpr))
598 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, CE))
604 PrimType DestElemT = classifyPrim(DestElemType);
606 for (
unsigned I = 0; I != 2; ++I) {
607 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, CE))
609 if (!this->emitArrayElemPop(SourceElemT, I, CE))
613 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
617 if (!this->emitInitElem(DestElemT, I, CE))
623 case CK_VectorSplat: {
624 assert(!classify(CE->
getType()));
625 assert(classify(SubExpr->
getType()));
629 return this->discard(SubExpr);
632 std::optional<unsigned> LocalIndex = allocateLocal(CE);
635 if (!this->emitGetPtrLocal(*LocalIndex, CE))
641 unsigned ElemOffset = allocateLocalPrimitive(
642 SubExpr, ElemT,
true,
false);
645 if (!this->visit(SubExpr))
647 if (classifyPrim(SubExpr) ==
PT_Ptr && !this->emitLoadPop(ElemT, CE))
650 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
653 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
654 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
656 if (!this->emitInitElem(ElemT, I, CE))
663 case CK_HLSLVectorTruncation: {
665 if (std::optional<PrimType> ResultT = classify(CE)) {
666 assert(!DiscardResult);
668 if (!this->visit(SubExpr))
670 return this->emitArrayElemPop(*ResultT, 0, CE);
676 unsigned LocalIndex = allocateTemporary(CE);
677 if (!this->emitGetPtrLocal(LocalIndex, CE))
682 if (!this->visit(SubExpr))
684 return this->emitCopyArray(classifyVectorElementType(CE->
getType()), 0, 0,
688 case CK_IntegralToFixedPoint: {
689 if (!this->visit(SubExpr))
692 auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->
getType());
694 std::memcpy(&I, &Sem,
sizeof(Sem));
695 return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->
getType()), I,
698 case CK_FloatingToFixedPoint: {
699 if (!this->visit(SubExpr))
702 auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->
getType());
704 std::memcpy(&I, &Sem,
sizeof(Sem));
705 return this->emitCastFloatingFixedPoint(I, CE);
707 case CK_FixedPointToFloating: {
708 if (!this->visit(SubExpr))
710 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
711 return this->emitCastFixedPointFloating(TargetSemantics, CE);
713 case CK_FixedPointToIntegral: {
714 if (!this->visit(SubExpr))
716 return this->emitCastFixedPointIntegral(classifyPrim(CE->
getType()), CE);
718 case CK_FixedPointCast: {
719 if (!this->visit(SubExpr))
721 auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->
getType());
723 std::memcpy(&I, &Sem,
sizeof(Sem));
724 return this->emitCastFixedPoint(I, CE);
728 return discard(SubExpr);
731 return this->emitInvalid(CE);
733 llvm_unreachable(
"Unhandled clang::CastKind enum");
736template <
class Emitter>
741 return this->emitConst(
LE->getValue(),
LE);
744template <
class Emitter>
749 return this->emitConstFloat(
E->getValue(),
E);
752template <
class Emitter>
759 unsigned LocalIndex = allocateTemporary(
E);
760 if (!this->emitGetPtrLocal(LocalIndex,
E))
764 const Expr *SubExpr =
E->getSubExpr();
767 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
769 if (!this->emitInitElem(SubExprT, 0, SubExpr))
771 return this->visitArrayElemInit(1, SubExpr);
774template <
class Emitter>
782 auto Sem = Ctx.getASTContext().getFixedPointSemantics(
E->
getType());
787template <
class Emitter>
789 return this->delegate(
E->getSubExpr());
792template <
class Emitter>
796 return this->VisitLogicalBinOp(BO);
804 if (!this->discard(LHS))
807 return this->discard(RHS);
809 return this->delegate(RHS);
813 return this->VisitComplexBinOp(BO);
815 return this->VisitVectorBinOp(BO);
819 return this->emitComplexComparison(LHS, RHS, BO);
821 return this->VisitFixedPointBinOp(BO);
824 if (!this->visit(LHS))
827 if (!this->visit(RHS))
830 if (!this->emitToMemberPtr(BO))
836 if (!this->emitCastMemberPtrPtr(BO))
838 return DiscardResult ? this->emitPopPtr(BO) :
true;
842 std::optional<PrimType>
LT = classify(LHS);
843 std::optional<PrimType> RT = classify(RHS);
844 std::optional<PrimType>
T = classify(BO->
getType());
853 Ctx.getASTContext().CompCategories.lookupInfoForType(BO->
getType());
858 std::optional<unsigned> ResultIndex = this->allocateLocal(BO);
859 if (!this->emitGetPtrLocal(*ResultIndex, BO))
863 if (!visit(LHS) || !visit(RHS))
866 return this->emitCMP3(*
LT, CmpInfo, BO);
869 if (!
LT || !RT || !
T)
875 return this->VisitPointerArithBinOp(BO);
880 if (!visit(RHS) || !visit(LHS))
882 if (!this->emitFlip(*
LT, *RT, BO))
885 if (!visit(LHS) || !visit(RHS))
891 auto MaybeCastToBool = [
this,
T, BO](
bool Result) {
895 return this->emitPop(*
T, BO);
897 return this->emitCast(
PT_Bool, *
T, BO);
901 auto Discard = [
this,
T, BO](
bool Result) {
904 return DiscardResult ? this->emitPop(*
T, BO) :
true;
909 return MaybeCastToBool(this->emitEQ(*
LT, BO));
911 return MaybeCastToBool(this->emitNE(*
LT, BO));
913 return MaybeCastToBool(this->emitLT(*
LT, BO));
915 return MaybeCastToBool(this->emitLE(*
LT, BO));
917 return MaybeCastToBool(this->emitGT(*
LT, BO));
919 return MaybeCastToBool(this->emitGE(*
LT, BO));
922 return Discard(this->emitSubf(getFPOptions(BO), BO));
923 return Discard(this->emitSub(*
T, BO));
926 return Discard(this->emitAddf(getFPOptions(BO), BO));
927 return Discard(this->emitAdd(*
T, BO));
930 return Discard(this->emitMulf(getFPOptions(BO), BO));
931 return Discard(this->emitMul(*
T, BO));
933 return Discard(this->emitRem(*
T, BO));
936 return Discard(this->emitDivf(getFPOptions(BO), BO));
937 return Discard(this->emitDiv(*
T, BO));
941 : this->emitStorePop(*
T, BO);
943 if (!this->emitStoreBitField(*
T, BO))
946 if (!this->emitStore(*
T, BO))
952 return this->emitLoadPop(*
T, BO);
955 return Discard(this->emitBitAnd(*
T, BO));
957 return Discard(this->emitBitOr(*
T, BO));
959 return Discard(this->emitShl(*
LT, *RT, BO));
961 return Discard(this->emitShr(*
LT, *RT, BO));
963 return Discard(this->emitBitXor(*
T, BO));
966 llvm_unreachable(
"Already handled earlier");
971 llvm_unreachable(
"Unhandled binary op");
976template <
class Emitter>
979 const Expr *LHS =
E->getLHS();
980 const Expr *RHS =
E->getRHS();
982 if ((Op != BO_Add && Op != BO_Sub) ||
986 std::optional<PrimType>
LT = classify(LHS);
987 std::optional<PrimType> RT = classify(RHS);
997 return this->emitDecayPtr(
T,
PT_Ptr,
E);
1006 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *
LT))
1010 if (!this->emitSubPtr(IntT,
E))
1012 return DiscardResult ? this->emitPop(IntT,
E) :
true;
1017 if (!visitAsPointer(RHS, *RT))
1019 if (!this->visit(LHS))
1023 if (!visitAsPointer(LHS, *
LT))
1025 if (!this->visit(RHS))
1035 if (!this->emitAddOffset(OffsetType,
E))
1038 if (classifyPrim(
E) !=
PT_Ptr)
1039 return this->emitDecayPtr(
PT_Ptr, classifyPrim(
E),
E);
1041 }
else if (Op == BO_Sub) {
1042 if (!this->emitSubOffset(OffsetType,
E))
1045 if (classifyPrim(
E) !=
PT_Ptr)
1046 return this->emitDecayPtr(
PT_Ptr, classifyPrim(
E),
E);
1053template <
class Emitter>
1055 assert(
E->isLogicalOp());
1057 const Expr *LHS =
E->getLHS();
1058 const Expr *RHS =
E->getRHS();
1059 std::optional<PrimType>
T = classify(
E->
getType());
1063 LabelTy LabelTrue = this->getLabel();
1064 LabelTy LabelEnd = this->getLabel();
1066 if (!this->visitBool(LHS))
1068 if (!this->jumpTrue(LabelTrue))
1071 if (!this->visitBool(RHS))
1073 if (!this->jump(LabelEnd))
1076 this->emitLabel(LabelTrue);
1077 this->emitConstBool(
true,
E);
1078 this->fallthrough(LabelEnd);
1079 this->emitLabel(LabelEnd);
1082 assert(Op == BO_LAnd);
1085 LabelTy LabelFalse = this->getLabel();
1086 LabelTy LabelEnd = this->getLabel();
1088 if (!this->visitBool(LHS))
1090 if (!this->jumpFalse(LabelFalse))
1093 if (!this->visitBool(RHS))
1095 if (!this->jump(LabelEnd))
1098 this->emitLabel(LabelFalse);
1099 this->emitConstBool(
false,
E);
1100 this->fallthrough(LabelEnd);
1101 this->emitLabel(LabelEnd);
1105 return this->emitPopBool(
E);
1114template <
class Emitter>
1118 unsigned LocalIndex = allocateTemporary(
E);
1119 if (!this->emitGetPtrLocal(LocalIndex,
E))
1125 const Expr *LHS =
E->getLHS();
1126 const Expr *RHS =
E->getRHS();
1129 unsigned ResultOffset = ~0u;
1131 ResultOffset = this->allocateLocalPrimitive(
E,
PT_Ptr,
true,
false);
1134 if (!this->DiscardResult) {
1135 if (!this->emitDupPtr(
E))
1137 if (!this->emitSetLocal(
PT_Ptr, ResultOffset,
E))
1142 LHSType = AT->getValueType();
1145 RHSType = AT->getValueType();
1154 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1159 if (!this->visit(LHS))
1161 if (!this->visit(RHS))
1163 return this->emitMulc(ElemT,
E);
1166 if (Op == BO_Div && RHSIsComplex) {
1168 PrimType ElemT = classifyPrim(ElemQT);
1173 if (!LHSIsComplex) {
1175 LHSOffset = allocateTemporary(RHS);
1177 if (!this->emitGetPtrLocal(LHSOffset,
E))
1180 if (!this->visit(LHS))
1183 if (!this->emitInitElem(ElemT, 0,
E))
1186 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1188 if (!this->emitInitElem(ElemT, 1,
E))
1191 if (!this->visit(LHS))
1195 if (!this->visit(RHS))
1197 return this->emitDivc(ElemT,
E);
1202 LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
1203 if (!this->visit(LHS))
1205 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1208 PrimType LHST = classifyPrim(LHSType);
1209 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
1210 if (!this->visit(LHS))
1212 if (!this->emitSetLocal(LHST, LHSOffset,
E))
1219 RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
1220 if (!this->visit(RHS))
1222 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1225 PrimType RHST = classifyPrim(RHSType);
1226 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
1227 if (!this->visit(RHS))
1229 if (!this->emitSetLocal(RHST, RHSOffset,
E))
1236 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1237 unsigned ElemIndex,
unsigned Offset,
1238 const Expr *
E) ->
bool {
1240 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
1242 return this->emitArrayElemPop(classifyComplexElementType(
E->
getType()),
1245 if (ElemIndex == 0 || !LoadZero)
1246 return this->emitGetLocal(classifyPrim(
E->
getType()), Offset,
E);
1247 return this->visitZeroInitializer(classifyPrim(
E->
getType()),
E->
getType(),
1252 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1254 if (!this->DiscardResult) {
1255 if (!this->emitGetLocal(
PT_Ptr, ResultOffset,
E))
1262 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1265 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1268 if (!this->emitAddf(getFPOptions(
E),
E))
1271 if (!this->emitAdd(ResultElemT,
E))
1276 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1279 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1282 if (!this->emitSubf(getFPOptions(
E),
E))
1285 if (!this->emitSub(ResultElemT,
E))
1290 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1293 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1297 if (!this->emitMulf(getFPOptions(
E),
E))
1300 if (!this->emitMul(ResultElemT,
E))
1305 assert(!RHSIsComplex);
1306 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1309 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1313 if (!this->emitDivf(getFPOptions(
E),
E))
1316 if (!this->emitDiv(ResultElemT,
E))
1325 if (!this->DiscardResult) {
1327 if (!this->emitInitElemPop(ResultElemT, ElemIndex,
E))
1330 if (!this->emitPop(ResultElemT,
E))
1337template <
class Emitter>
1339 assert(!
E->isCommaOp() &&
1340 "Comma op should be handled in VisitBinaryOperator");
1347 unsigned LocalIndex = allocateTemporary(
E);
1348 if (!this->emitGetPtrLocal(LocalIndex,
E))
1352 const Expr *LHS =
E->getLHS();
1353 const Expr *RHS =
E->getRHS();
1355 auto Op =
E->isCompoundAssignmentOp()
1364 unsigned LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
1365 if (!this->visit(LHS))
1367 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1371 unsigned RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
1372 if (!this->visit(RHS))
1374 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1377 if (
E->isCompoundAssignmentOp() && !this->emitGetLocal(
PT_Ptr, LHSOffset,
E))
1382 bool NeedIntPromot = ElemT ==
PT_Bool && (
E->isBitwiseOp() ||
E->isShiftOp());
1384 Ctx.getASTContext().getPromotedIntegerType(Ctx.getASTContext().BoolTy);
1385 PrimType PromotT = classifyPrim(PromotTy);
1386 PrimType OpT = NeedIntPromot ? PromotT : ElemT;
1388 auto getElem = [=](
unsigned Offset,
PrimType ElemT,
unsigned Index) {
1389 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
1391 if (!this->emitArrayElemPop(ElemT, Index,
E))
1393 if (
E->isLogicalOp()) {
1394 if (!this->emitPrimCast(ElemT,
PT_Bool, Ctx.getASTContext().BoolTy,
E))
1396 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(),
E))
1398 }
else if (NeedIntPromot) {
1399 if (!this->emitPrimCast(ElemT, PromotT, PromotTy,
E))
1405#define EMIT_ARITH_OP(OP) \
1407 if (ElemT == PT_Float) { \
1408 if (!this->emit##OP##f(getFPOptions(E), E)) \
1411 if (!this->emit##OP(ElemT, E)) \
1417 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
1418 if (!getElem(LHSOffset, ElemT, I))
1420 if (!getElem(RHSOffset, RHSElemT, I))
1432 if (!this->emitRem(ElemT,
E))
1436 if (!this->emitBitAnd(OpT,
E))
1440 if (!this->emitBitOr(OpT,
E))
1444 if (!this->emitBitXor(OpT,
E))
1448 if (!this->emitShl(OpT, RHSElemT,
E))
1452 if (!this->emitShr(OpT, RHSElemT,
E))
1456 if (!this->emitEQ(ElemT,
E))
1460 if (!this->emitNE(ElemT,
E))
1464 if (!this->emitLE(ElemT,
E))
1468 if (!this->emitLT(ElemT,
E))
1472 if (!this->emitGE(ElemT,
E))
1476 if (!this->emitGT(ElemT,
E))
1481 if (!this->emitBitAnd(ResultElemT,
E))
1486 if (!this->emitBitOr(ResultElemT,
E))
1490 return this->emitInvalid(
E);
1498 if (
E->isComparisonOp()) {
1499 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(),
E))
1501 if (!this->emitNeg(ResultElemT,
E))
1507 if (NeedIntPromot &&
1508 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(),
E))
1512 if (!this->emitInitElem(ResultElemT, I,
E))
1516 if (DiscardResult &&
E->isCompoundAssignmentOp() && !this->emitPopPtr(
E))
1521template <
class Emitter>
1523 const Expr *LHS =
E->getLHS();
1524 const Expr *RHS =
E->getRHS();
1529 auto LHSSema = Ctx.getASTContext().getFixedPointSemantics(LHS->
getType());
1530 auto RHSSema = Ctx.getASTContext().getFixedPointSemantics(RHS->
getType());
1532 if (!this->visit(LHS))
1536 std::memcpy(&I, &LHSSema,
sizeof(llvm::FixedPointSemantics));
1537 if (!this->emitCastIntegralFixedPoint(classifyPrim(LHS->
getType()), I,
E))
1541 if (!this->visit(RHS))
1545 std::memcpy(&I, &RHSSema,
sizeof(llvm::FixedPointSemantics));
1546 if (!this->emitCastIntegralFixedPoint(classifyPrim(RHS->
getType()), I,
E))
1551 auto ConvertResult = [&](
bool R) ->
bool {
1554 auto ResultSema = Ctx.getASTContext().getFixedPointSemantics(
E->
getType());
1555 auto CommonSema = LHSSema.getCommonSemantics(RHSSema);
1556 if (ResultSema != CommonSema) {
1558 std::memcpy(&I, &ResultSema,
sizeof(ResultSema));
1559 return this->emitCastFixedPoint(I,
E);
1564 auto MaybeCastToBool = [&](
bool Result) {
1569 return this->emitPop(
T,
E);
1575 switch (
E->getOpcode()) {
1577 return MaybeCastToBool(this->emitEQFixedPoint(
E));
1579 return MaybeCastToBool(this->emitNEFixedPoint(
E));
1581 return MaybeCastToBool(this->emitLTFixedPoint(
E));
1583 return MaybeCastToBool(this->emitLEFixedPoint(
E));
1585 return MaybeCastToBool(this->emitGTFixedPoint(
E));
1587 return MaybeCastToBool(this->emitGEFixedPoint(
E));
1589 return ConvertResult(this->emitAddFixedPoint(
E));
1591 return ConvertResult(this->emitSubFixedPoint(
E));
1593 return ConvertResult(this->emitMulFixedPoint(
E));
1595 return ConvertResult(this->emitDivFixedPoint(
E));
1597 return ConvertResult(this->emitShiftFixedPoint(
true,
E));
1599 return ConvertResult(this->emitShiftFixedPoint(
false,
E));
1602 return this->emitInvalid(
E);
1605 llvm_unreachable(
"unhandled binop opcode");
1608template <
class Emitter>
1610 const Expr *SubExpr =
E->getSubExpr();
1613 switch (
E->getOpcode()) {
1615 return this->delegate(SubExpr);
1617 if (!this->visit(SubExpr))
1619 return this->emitNegFixedPoint(
E);
1624 llvm_unreachable(
"Unhandled unary opcode");
1627template <
class Emitter>
1632 if (std::optional<PrimType>
T = classify(QT))
1633 return this->visitZeroInitializer(*
T, QT,
E);
1641 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1642 CXXRD && CXXRD->getNumVBases() > 0) {
1647 const Record *R = getRecord(QT);
1652 return this->visitZeroRecordInitializer(R,
E);
1659 return this->visitZeroArrayInitializer(QT,
E);
1663 QualType ElemQT = ComplexTy->getElementType();
1664 PrimType ElemT = classifyPrim(ElemQT);
1665 for (
unsigned I = 0; I < 2; ++I) {
1666 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1668 if (!this->emitInitElem(ElemT, I,
E))
1675 unsigned NumVecElements = VecT->getNumElements();
1676 QualType ElemQT = VecT->getElementType();
1677 PrimType ElemT = classifyPrim(ElemQT);
1679 for (
unsigned I = 0; I < NumVecElements; ++I) {
1680 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1682 if (!this->emitInitElem(ElemT, I,
E))
1691template <
class Emitter>
1693 const Expr *LHS =
E->getLHS();
1694 const Expr *RHS =
E->getRHS();
1695 const Expr *Index =
E->getIdx();
1698 return this->discard(LHS) && this->discard(RHS);
1703 for (
const Expr *SubExpr : {LHS, RHS}) {
1704 if (!this->visit(SubExpr))
1711 PrimType IndexT = classifyPrim(Index->getType());
1714 if (!this->emitFlip(
PT_Ptr, IndexT,
E))
1718 return this->emitArrayElemPtrPop(IndexT,
E);
1721template <
class Emitter>
1723 const Expr *ArrayFiller,
const Expr *
E) {
1728 QT = AT->getValueType();
1731 if (Inits.size() == 0)
1733 return this->emitInvalid(
E);
1737 if (DiscardResult) {
1739 if (!this->discard(
Init))
1746 if (std::optional<PrimType>
T = classify(QT)) {
1747 assert(!DiscardResult);
1748 if (Inits.size() == 0)
1749 return this->visitZeroInitializer(*
T, QT,
E);
1750 assert(Inits.size() == 1);
1751 return this->delegate(Inits[0]);
1755 const Record *R = getRecord(QT);
1757 if (Inits.size() == 1 &&
E->
getType() == Inits[0]->getType())
1758 return this->delegate(Inits[0]);
1760 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
1764 if (!this->visit(
Init))
1767 if (FieldToInit->isBitField())
1768 return this->emitInitBitField(
T, FieldToInit,
E);
1769 return this->emitInitField(
T, FieldToInit->Offset,
E);
1772 auto initCompositeField = [=](
const Record::Field *FieldToInit,
1779 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
1781 if (!this->visitInitializer(
Init))
1783 return this->emitPopPtr(
E);
1787 if (Inits.size() == 0) {
1788 if (!this->visitZeroRecordInitializer(R,
E))
1793 if (
const auto *ILE = dyn_cast<InitListExpr>(
E))
1794 FToInit = ILE->getInitializedFieldInUnion();
1796 FToInit = cast<CXXParenListInitExpr>(
E)->getInitializedFieldInUnion();
1798 const Record::Field *FieldToInit = R->
getField(FToInit);
1799 if (std::optional<PrimType>
T = classify(
Init)) {
1800 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1803 if (!initCompositeField(FieldToInit,
Init))
1807 return this->emitFinishInit(
E);
1811 unsigned InitIndex = 0;
1814 while (InitIndex < R->getNumFields() &&
1818 if (std::optional<PrimType>
T = classify(
Init)) {
1819 const Record::Field *FieldToInit = R->
getField(InitIndex);
1820 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1825 if (
const Record::Base *B = R->
getBase(
Init->getType())) {
1826 if (!this->emitGetPtrBase(B->Offset,
Init))
1829 if (!this->visitInitializer(
Init))
1832 if (!this->emitFinishInitPop(
E))
1837 const Record::Field *FieldToInit = R->
getField(InitIndex);
1838 if (!initCompositeField(FieldToInit,
Init))
1844 return this->emitFinishInit(
E);
1848 if (Inits.size() == 1 && QT == Inits[0]->getType())
1849 return this->delegate(Inits[0]);
1851 unsigned ElementIndex = 0;
1853 if (
const auto *EmbedS =
1854 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1857 auto Eval = [&](
const Expr *
Init,
unsigned ElemIndex) {
1859 if (!this->visit(
Init))
1861 if (InitT != TargetT) {
1862 if (!this->emitCast(InitT, TargetT,
E))
1865 return this->emitInitElem(TargetT, ElemIndex,
Init);
1867 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
1870 if (!this->visitArrayElemInit(ElementIndex,
Init))
1880 Ctx.getASTContext().getAsConstantArrayType(QT);
1883 for (; ElementIndex != NumElems; ++ElementIndex) {
1884 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller))
1889 return this->emitFinishInit(
E);
1893 unsigned NumInits = Inits.size();
1896 return this->delegate(Inits[0]);
1898 QualType ElemQT = ComplexTy->getElementType();
1899 PrimType ElemT = classifyPrim(ElemQT);
1900 if (NumInits == 0) {
1902 for (
unsigned I = 0; I < 2; ++I) {
1903 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1905 if (!this->emitInitElem(ElemT, I,
E))
1908 }
else if (NumInits == 2) {
1909 unsigned InitIndex = 0;
1911 if (!this->visit(
Init))
1914 if (!this->emitInitElem(ElemT, InitIndex,
E))
1923 unsigned NumVecElements = VecT->getNumElements();
1924 assert(NumVecElements >= Inits.size());
1926 QualType ElemQT = VecT->getElementType();
1927 PrimType ElemT = classifyPrim(ElemQT);
1930 unsigned InitIndex = 0;
1932 if (!this->visit(
Init))
1937 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
1938 if (!this->emitCopyArray(ElemT, 0, InitIndex,
1939 InitVecT->getNumElements(),
E))
1941 InitIndex += InitVecT->getNumElements();
1943 if (!this->emitInitElem(ElemT, InitIndex,
E))
1949 assert(InitIndex <= NumVecElements);
1952 for (; InitIndex != NumVecElements; ++InitIndex) {
1953 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1955 if (!this->emitInitElem(ElemT, InitIndex,
E))
1966template <
class Emitter>
1969 if (std::optional<PrimType>
T = classify(
Init->getType())) {
1971 if (!this->visit(
Init))
1973 return this->emitInitElem(*
T, ElemIndex,
Init);
1979 if (!this->emitConstUint32(ElemIndex,
Init))
1981 if (!this->emitArrayElemPtrUint32(
Init))
1983 if (!this->visitInitializer(
Init))
1985 return this->emitFinishInitPop(
Init);
1988template <
class Emitter>
1990 return this->visitInitList(
E->inits(),
E->getArrayFiller(),
E);
1993template <
class Emitter>
1996 return this->visitInitList(
E->getInitExprs(),
E->getArrayFiller(),
E);
1999template <
class Emitter>
2002 return this->delegate(
E->getReplacement());
2005template <
class Emitter>
2007 std::optional<PrimType>
T = classify(
E->
getType());
2008 if (
T &&
E->hasAPValueResult()) {
2015 if (this->visitAPValue(
E->getAPValueResult(), *
T,
E))
2018 return this->delegate(
E->getSubExpr());
2021template <
class Emitter>
2023 auto It =
E->begin();
2024 return this->visit(*It);
2029 bool AlignOfReturnsPreferred =
2030 ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
2038 if (
T.getQualifiers().hasUnaligned())
2044 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2050template <
class Emitter>
2054 const ASTContext &ASTCtx = Ctx.getASTContext();
2056 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2057 QualType ArgType =
E->getTypeOfArgument();
2071 if (Kind == UETT_SizeOf)
2080 return this->emitConst(Size.getQuantity(),
E);
2083 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2086 if (
E->isArgumentType()) {
2087 QualType ArgType =
E->getTypeOfArgument();
2100 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2103 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
2113 return this->emitConst(Size.getQuantity(),
E);
2116 if (Kind == UETT_VectorElements) {
2117 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>())
2118 return this->emitConst(VT->getNumElements(),
E);
2119 assert(
E->getTypeOfArgument()->isSizelessVectorType());
2120 return this->emitSizelessVectorElementSize(
E);
2123 if (Kind == UETT_VecStep) {
2124 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>()) {
2125 unsigned N = VT->getNumElements();
2132 return this->emitConst(N,
E);
2134 return this->emitConst(1,
E);
2137 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2138 assert(
E->isArgumentType());
2144 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2145 if (
E->getArgumentType()->isDependentType())
2146 return this->emitInvalid(
E);
2148 return this->emitConst(
2149 const_cast<ASTContext &
>(ASTCtx).getPointerAuthTypeDiscriminator(
2150 E->getArgumentType()),
2157template <
class Emitter>
2164 return this->discard(
Base);
2168 const auto maybeLoadValue = [&]() ->
bool {
2171 if (std::optional<PrimType>
T = classify(
E))
2172 return this->emitLoadPop(*
T,
E);
2176 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
2180 if (
auto GlobalIndex =
P.getGlobal(VD))
2181 return this->emitGetPtrGlobal(*GlobalIndex,
E) && maybeLoadValue();
2185 if (!isa<FieldDecl>(
Member)) {
2186 if (!this->discard(
Base) && !this->emitSideEffect(
E))
2189 return this->visitDeclRef(
Member,
E);
2193 if (!this->delegate(
Base))
2196 if (!this->visit(
Base))
2201 const auto *FD = cast<FieldDecl>(
Member);
2203 const Record *R = getRecord(RD);
2206 const Record::Field *F = R->
getField(FD);
2208 if (F->Decl->getType()->isReferenceType())
2209 return this->emitGetFieldPop(
PT_Ptr, F->Offset,
E) && maybeLoadValue();
2210 return this->emitGetPtrFieldPop(F->Offset,
E) && maybeLoadValue();
2213template <
class Emitter>
2219 return this->emitConst(*ArrayIndex,
E);
2222template <
class Emitter>
2225 assert(!DiscardResult);
2229 if (!this->discard(
E->getCommonExpr()))
2234 const Expr *SubExpr =
E->getSubExpr();
2235 size_t Size =
E->getArraySize().getZExtValue();
2240 for (
size_t I = 0; I != Size; ++I) {
2244 if (!this->visitArrayElemInit(I, SubExpr))
2252template <
class Emitter>
2254 const Expr *SourceExpr =
E->getSourceExpr();
2259 return this->visitInitializer(SourceExpr);
2262 if (
auto It = OpaqueExprs.find(
E); It != OpaqueExprs.end())
2263 return this->emitGetLocal(SubExprT, It->second,
E);
2265 if (!this->visit(SourceExpr))
2271 unsigned LocalIndex = allocateLocalPrimitive(
E, SubExprT,
true);
2272 if (!this->emitSetLocal(SubExprT, LocalIndex,
E))
2277 if (!DiscardResult) {
2278 if (!this->emitGetLocal(SubExprT, LocalIndex,
E))
2283 OpaqueExprs.insert({
E, LocalIndex});
2288template <
class Emitter>
2292 const Expr *TrueExpr =
E->getTrueExpr();
2293 const Expr *FalseExpr =
E->getFalseExpr();
2295 LabelTy LabelEnd = this->getLabel();
2296 LabelTy LabelFalse = this->getLabel();
2301 if (!this->jumpFalse(LabelFalse))
2306 if (!this->delegate(TrueExpr))
2308 if (!S.destroyLocals())
2312 if (!this->jump(LabelEnd))
2315 this->emitLabel(LabelFalse);
2319 if (!this->delegate(FalseExpr))
2321 if (!S.destroyLocals())
2325 this->fallthrough(LabelEnd);
2326 this->emitLabel(LabelEnd);
2331template <
class Emitter>
2337 unsigned StringIndex =
P.createGlobalString(
E);
2338 return this->emitGetPtrGlobal(StringIndex,
E);
2343 Ctx.getASTContext().getAsConstantArrayType(
E->
getType());
2344 assert(CAT &&
"a string literal that's not a constant array?");
2349 unsigned N = std::min(ArraySize,
E->getLength());
2350 size_t CharWidth =
E->getCharByteWidth();
2352 for (
unsigned I = 0; I != N; ++I) {
2353 uint32_t CodeUnit =
E->getCodeUnit(I);
2355 if (CharWidth == 1) {
2356 this->emitConstSint8(CodeUnit,
E);
2357 this->emitInitElemSint8(I,
E);
2358 }
else if (CharWidth == 2) {
2359 this->emitConstUint16(CodeUnit,
E);
2360 this->emitInitElemUint16(I,
E);
2361 }
else if (CharWidth == 4) {
2362 this->emitConstUint32(CodeUnit,
E);
2363 this->emitInitElemUint32(I,
E);
2365 llvm_unreachable(
"unsupported character width");
2370 for (
unsigned I = N; I != ArraySize; ++I) {
2371 if (CharWidth == 1) {
2372 this->emitConstSint8(0,
E);
2373 this->emitInitElemSint8(I,
E);
2374 }
else if (CharWidth == 2) {
2375 this->emitConstUint16(0,
E);
2376 this->emitInitElemUint16(I,
E);
2377 }
else if (CharWidth == 4) {
2378 this->emitConstUint32(0,
E);
2379 this->emitInitElemUint32(I,
E);
2381 llvm_unreachable(
"unsupported character width");
2388template <
class Emitter>
2392 return this->emitDummyPtr(
E,
E);
2395template <
class Emitter>
2397 auto &A = Ctx.getASTContext();
2399 A.getObjCEncodingForType(
E->getEncodedType(), Str);
2403 return this->delegate(SL);
2406template <
class Emitter>
2414 auto &A = Ctx.getASTContext();
2415 std::string ResultStr =
E->ComputeName(A);
2418 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
2419 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
2420 ArraySizeModifier::Normal, 0);
2424 false, ArrayTy,
E->getLocation());
2426 unsigned StringIndex =
P.createGlobalString(SL);
2427 return this->emitGetPtrGlobal(StringIndex,
E);
2430template <
class Emitter>
2434 return this->emitConst(
E->getValue(),
E);
2437template <
class Emitter>
2441 const Expr *LHS =
E->getLHS();
2442 const Expr *RHS =
E->getRHS();
2444 QualType LHSComputationType =
E->getComputationLHSType();
2445 QualType ResultType =
E->getComputationResultType();
2446 std::optional<PrimType>
LT = classify(LHSComputationType);
2447 std::optional<PrimType> RT = classify(ResultType);
2454 PrimType LHST = classifyPrim(LHSType);
2462 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2463 if (!this->emitSetLocal(*RT, TempOffset,
E))
2469 if (!this->emitLoad(LHST,
E))
2473 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
2474 LHSComputationType,
E))
2478 if (!this->emitGetLocal(*RT, TempOffset,
E))
2481 switch (
E->getOpcode()) {
2483 if (!this->emitAddf(getFPOptions(
E),
E))
2487 if (!this->emitSubf(getFPOptions(
E),
E))
2491 if (!this->emitMulf(getFPOptions(
E),
E))
2495 if (!this->emitDivf(getFPOptions(
E),
E))
2502 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->
getType(),
E))
2506 return this->emitStorePop(LHST,
E);
2507 return this->emitStore(LHST,
E);
2510template <
class Emitter>
2514 const Expr *LHS =
E->getLHS();
2515 const Expr *RHS =
E->getRHS();
2516 std::optional<PrimType>
LT = classify(LHS->
getType());
2517 std::optional<PrimType> RT = classify(RHS->
getType());
2519 if (Op != BO_AddAssign && Op != BO_SubAssign)
2528 if (!this->emitLoad(*
LT, LHS))
2534 if (Op == BO_AddAssign) {
2535 if (!this->emitAddOffset(*RT,
E))
2538 if (!this->emitSubOffset(*RT,
E))
2543 return this->emitStorePopPtr(
E);
2544 return this->emitStorePtr(
E);
2547template <
class Emitter>
2551 return VisitVectorBinOp(
E);
2553 const Expr *LHS =
E->getLHS();
2554 const Expr *RHS =
E->getRHS();
2555 std::optional<PrimType> LHSComputationT =
2556 classify(
E->getComputationLHSType());
2557 std::optional<PrimType>
LT = classify(LHS->
getType());
2558 std::optional<PrimType> RT = classify(RHS->
getType());
2559 std::optional<PrimType> ResultT = classify(
E->
getType());
2561 if (!Ctx.getLangOpts().CPlusPlus14)
2562 return this->visit(RHS) && this->visit(LHS) && this->emitError(
E);
2564 if (!
LT || !RT || !ResultT || !LHSComputationT)
2571 return VisitFloatCompoundAssignOperator(
E);
2574 return VisitPointerCompoundAssignOperator(
E);
2587 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2589 if (!this->emitSetLocal(*RT, TempOffset,
E))
2596 if (!this->emitLoad(*
LT,
E))
2598 if (
LT != LHSComputationT) {
2599 if (!this->emitCast(*
LT, *LHSComputationT,
E))
2604 if (!this->emitGetLocal(*RT, TempOffset,
E))
2608 switch (
E->getOpcode()) {
2610 if (!this->emitAdd(*LHSComputationT,
E))
2614 if (!this->emitSub(*LHSComputationT,
E))
2618 if (!this->emitMul(*LHSComputationT,
E))
2622 if (!this->emitDiv(*LHSComputationT,
E))
2626 if (!this->emitRem(*LHSComputationT,
E))
2630 if (!this->emitShl(*LHSComputationT, *RT,
E))
2634 if (!this->emitShr(*LHSComputationT, *RT,
E))
2638 if (!this->emitBitAnd(*LHSComputationT,
E))
2642 if (!this->emitBitXor(*LHSComputationT,
E))
2646 if (!this->emitBitOr(*LHSComputationT,
E))
2650 llvm_unreachable(
"Unimplemented compound assign operator");
2654 if (ResultT != LHSComputationT) {
2655 if (!this->emitCast(*LHSComputationT, *ResultT,
E))
2660 if (DiscardResult) {
2662 return this->emitStoreBitFieldPop(*ResultT,
E);
2663 return this->emitStorePop(*ResultT,
E);
2666 return this->emitStoreBitField(*ResultT,
E);
2667 return this->emitStore(*ResultT,
E);
2670template <
class Emitter>
2673 const Expr *SubExpr =
E->getSubExpr();
2678template <
class Emitter>
2681 const Expr *SubExpr =
E->getSubExpr();
2685 return this->delegate(SubExpr);
2690 return this->discard(SubExpr);
2694 std::optional<PrimType> SubExprT = classify(SubExpr);
2697 std::optional<unsigned> GlobalIndex =
P.createGlobal(
E);
2702 E->getLifetimeExtendedTemporaryDecl();
2707 if (!this->visit(SubExpr))
2710 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl,
E))
2713 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex,
E))
2716 return this->emitGetPtrGlobal(*GlobalIndex,
E);
2719 if (!this->checkLiteralType(SubExpr))
2722 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2724 if (!this->visitInitializer(SubExpr))
2727 return this->emitInitGlobalTempComp(TempDecl,
E);
2733 unsigned LocalIndex = allocateLocalPrimitive(
E, *SubExprT,
true,
2735 if (!this->visit(SubExpr))
2737 if (!this->emitSetLocal(*SubExprT, LocalIndex,
E))
2739 return this->emitGetPtrLocal(LocalIndex,
E);
2742 if (!this->checkLiteralType(SubExpr))
2746 if (std::optional<unsigned> LocalIndex =
2747 allocateLocal(
E, Inner->getType(),
E->getExtendingDecl())) {
2749 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2751 return this->visitInitializer(SubExpr) && this->emitFinishInit(
E);
2757template <
class Emitter>
2760 return this->delegate(
E->getSubExpr());
2763template <
class Emitter>
2767 return this->discard(
Init);
2771 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2774 std::optional<PrimType>
T = classify(
E->
getType());
2775 if (
E->isFileScope()) {
2778 return this->delegate(
Init);
2780 if (std::optional<unsigned> GlobalIndex =
P.createGlobal(
E)) {
2781 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2785 if (!this->visit(
Init))
2787 return this->emitInitGlobal(*
T, *GlobalIndex,
E);
2790 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2799 return this->delegate(
Init);
2801 unsigned LocalIndex;
2804 LocalIndex = this->allocateLocalPrimitive(
Init, *
T,
false,
false);
2805 else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(
Init))
2806 LocalIndex = *MaybeIndex;
2810 if (!this->emitGetPtrLocal(LocalIndex,
E))
2814 if (!this->visit(
Init)) {
2817 return this->emitInit(*
T,
E);
2819 if (!this->visitInitializer(
Init) || !this->emitFinishInit(
E))
2828template <
class Emitter>
2833 return this->emitConstBool(
E->getValue(),
E);
2834 return this->emitConst(
E->getValue(),
E);
2837template <
class Emitter>
2841 return this->emitConst(
E->getValue(),
E);
2844template <
class Emitter>
2850 const Record *R =
P.getOrCreateRecord(
E->getLambdaClass());
2852 auto *CaptureInitIt =
E->capture_init_begin();
2855 for (
const Record::Field &F : R->
fields()) {
2862 if (std::optional<PrimType>
T = classify(
Init)) {
2863 if (!this->visit(
Init))
2866 if (!this->emitInitField(*
T, F.Offset,
E))
2869 if (!this->emitGetPtrField(F.Offset,
E))
2872 if (!this->visitInitializer(
Init))
2875 if (!this->emitPopPtr(
E))
2883template <
class Emitter>
2889 unsigned StringIndex =
P.createGlobalString(
E->getFunctionName(),
E);
2890 return this->emitGetPtrGlobal(StringIndex,
E);
2893 return this->delegate(
E->getFunctionName());
2896template <
class Emitter>
2898 if (
E->getSubExpr() && !this->discard(
E->getSubExpr()))
2901 return this->emitInvalid(
E);
2904template <
class Emitter>
2907 const Expr *SubExpr =
E->getSubExpr();
2909 std::optional<PrimType> FromT = classify(SubExpr);
2910 std::optional<PrimType> ToT = classify(
E);
2913 return this->emitInvalidCast(CastKind::Reinterpret,
true,
E);
2917 std::optional<PrimType> PointeeFromT;
2921 PointeeFromT = classify(SubExpr->
getType());
2923 std::optional<PrimType> PointeeToT;
2927 PointeeToT = classify(
E->
getType());
2930 if (PointeeToT && PointeeFromT) {
2935 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal,
E))
2938 if (
E->getCastKind() == CK_LValueBitCast)
2939 return this->delegate(SubExpr);
2940 return this->VisitCastExpr(
E);
2944 bool Fatal = (ToT != FromT);
2945 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal,
E))
2948 return this->VisitCastExpr(
E);
2951template <
class Emitter>
2957 return this->emitConstBool(
E->getValue(),
E);
2960template <
class Emitter>
2963 assert(!classify(
T));
2973 return this->visitInitializer(
E->getArg(0));
2977 if (DiscardResult) {
2981 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2986 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2991 if (
E->requiresZeroInitialization()) {
2994 if (!this->visitZeroRecordInitializer(R,
E))
3007 assert(
Func->hasThisPointer());
3008 assert(!
Func->hasRVO());
3012 if (!this->emitDupPtr(
E))
3016 for (
const auto *Arg :
E->arguments()) {
3017 if (!this->visit(Arg))
3021 if (
Func->isVariadic()) {
3022 uint32_t VarArgSize = 0;
3023 unsigned NumParams =
Func->getNumWrittenParams();
3024 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I) {
3028 if (!this->emitCallVar(
Func, VarArgSize,
E))
3031 if (!this->emitCall(
Func, 0,
E)) {
3036 (void)this->emitPopPtr(
E);
3042 return this->emitPopPtr(
E);
3043 return this->emitFinishInit(
E);
3048 Ctx.getASTContext().getAsConstantArrayType(
E->
getType());
3059 for (
size_t I = 0; I != NumElems; ++I) {
3060 if (!this->emitConstUint64(I,
E))
3062 if (!this->emitArrayElemPtrUint64(
E))
3066 for (
const auto *Arg :
E->arguments()) {
3067 if (!this->visit(Arg))
3071 if (!this->emitCall(
Func, 0,
E))
3080template <
class Emitter>
3086 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
3090 assert(Val.
isInt());
3092 return this->emitConst(I,
E);
3099 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
3100 return this->visit(LValueExpr);
3109 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
3111 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(UGCD);
3115 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
3119 const APValue &
V = UGCD->getValue();
3120 for (
unsigned I = 0, N = R->
getNumFields(); I != N; ++I) {
3121 const Record::Field *F = R->
getField(I);
3122 const APValue &FieldValue =
V.getStructField(I);
3124 PrimType FieldT = classifyPrim(F->Decl->getType());
3126 if (!this->visitAPValue(FieldValue, FieldT,
E))
3128 if (!this->emitInitField(FieldT, F->Offset,
E))
3136template <
class Emitter>
3138 unsigned N =
E->getNumComponents();
3142 for (
unsigned I = 0; I != N; ++I) {
3145 const Expr *ArrayIndexExpr =
E->getIndexExpr(
Node.getArrayExprIndex());
3148 if (DiscardResult) {
3149 if (!this->discard(ArrayIndexExpr))
3154 if (!this->visit(ArrayIndexExpr))
3168 return this->emitOffsetOf(
T,
E,
E);
3171template <
class Emitter>
3179 if (std::optional<PrimType>
T = classify(Ty))
3180 return this->visitZeroInitializer(*
T, Ty,
E);
3184 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3187 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3192 QualType ElemQT = CT->getElementType();
3193 PrimType ElemT = classifyPrim(ElemQT);
3195 for (
unsigned I = 0; I != 2; ++I) {
3196 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
3198 if (!this->emitInitElem(ElemT, I,
E))
3207 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3210 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3215 QualType ElemQT = VT->getElementType();
3216 PrimType ElemT = classifyPrim(ElemQT);
3218 for (
unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
3219 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
3221 if (!this->emitInitElem(ElemT, I,
E))
3230template <
class Emitter>
3232 return this->emitConst(
E->getPackLength(),
E);
3235template <
class Emitter>
3238 return this->delegate(
E->getResultExpr());
3241template <
class Emitter>
3243 return this->delegate(
E->getChosenSubExpr());
3246template <
class Emitter>
3251 return this->emitConst(
E->getValue(),
E);
3254template <
class Emitter>
3259 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
3260 const Function *F = this->getFunction(Ctor);
3277 if (!this->emitGetParam(PT, Offset,
E))
3282 return this->emitCall(F, 0,
E);
3285template <
class Emitter>
3289 QualType ElementType =
E->getAllocatedType();
3290 std::optional<PrimType> ElemT = classify(ElementType);
3291 unsigned PlacementArgs =
E->getNumPlacementArgs();
3293 const Expr *PlacementDest =
nullptr;
3294 bool IsNoThrow =
false;
3296 if (PlacementArgs != 0) {
3305 if (PlacementArgs == 1) {
3306 const Expr *Arg1 =
E->getPlacementArg(0);
3308 if (!this->discard(Arg1))
3313 if (!this->emitInvalidNewDeleteExpr(
E,
E))
3318 if (OperatorNew->isReservedGlobalPlacementOperator())
3319 PlacementDest = Arg1;
3323 return this->emitInvalid(
E);
3325 }
else if (!OperatorNew->isReplaceableGlobalAllocationFunction())
3326 return this->emitInvalidNewDeleteExpr(
E,
E);
3329 if (!PlacementDest) {
3338 Desc =
P.createDescriptor(
3341 false,
false,
false,
Init);
3346 std::optional<const Expr *> ArraySizeExpr =
E->getArraySize();
3350 const Expr *Stripped = *ArraySizeExpr;
3351 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
3352 Stripped = ICE->getSubExpr())
3353 if (ICE->getCastKind() != CK_NoOp &&
3354 ICE->getCastKind() != CK_IntegralCast)
3359 if (PlacementDest) {
3360 if (!this->visit(PlacementDest))
3362 if (!this->visit(Stripped))
3364 if (!this->emitCheckNewTypeMismatchArray(SizeT,
E,
E))
3367 if (!this->visit(Stripped))
3372 if (!this->emitAllocN(SizeT, *ElemT,
E, IsNoThrow,
E))
3376 if (!this->emitAllocCN(SizeT, Desc, IsNoThrow,
E))
3381 if (
Init && !this->visitInitializer(
Init))
3385 if (PlacementDest) {
3386 if (!this->visit(PlacementDest))
3388 if (!this->emitCheckNewTypeMismatch(
E,
E))
3392 if (!this->emitAlloc(Desc,
E))
3398 if (!this->visit(
Init))
3401 if (!this->emitInit(*ElemT,
E))
3405 if (!this->visitInitializer(
Init))
3412 return this->emitPopPtr(
E);
3417template <
class Emitter>
3419 const Expr *Arg =
E->getArgument();
3421 const FunctionDecl *OperatorDelete =
E->getOperatorDelete();
3423 if (!OperatorDelete->isReplaceableGlobalAllocationFunction())
3424 return this->emitInvalidNewDeleteExpr(
E,
E);
3427 if (!this->visit(Arg))
3430 return this->emitFree(
E->isArrayForm(),
E->isGlobalDelete(),
E);
3433template <
class Emitter>
3444 return this->emitGetFnPtr(
Func,
E);
3447template <
class Emitter>
3451 if (!
E->isPotentiallyEvaluated()) {
3455 if (
E->isTypeOperand())
3456 return this->emitGetTypeid(
3457 E->getTypeOperand(Ctx.getASTContext()).getTypePtr(), TypeInfoType,
E);
3463 assert(
E->getExprOperand());
3464 assert(
E->getExprOperand()->
isLValue());
3466 if (!Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(
E))
3469 if (!this->visit(
E->getExprOperand()))
3472 if (!this->emitGetTypeidPtr(TypeInfoType,
E))
3475 return this->emitPopPtr(
E);
3479template <
class Emitter>
3481 assert(Ctx.getLangOpts().CPlusPlus);
3482 return this->emitConstBool(
E->getValue(),
E);
3485template <
class Emitter>
3497 return this->emitDummyPtr(GuidDecl,
E);
3499 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(GuidDecl);
3502 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
3505 assert(this->getRecord(
E->
getType()));
3511 assert(
V.isStruct());
3512 assert(
V.getStructNumBases() == 0);
3513 if (!this->visitAPValueInitializer(
V,
E))
3516 return this->emitFinishInit(
E);
3519template <
class Emitter>
3524 return this->emitConstBool(
E->isSatisfied(),
E);
3527template <
class Emitter>
3533 return this->emitConstBool(
E->isSatisfied(),
E);
3536template <
class Emitter>
3539 return this->delegate(
E->getSemanticForm());
3542template <
class Emitter>
3545 for (
const Expr *SemE :
E->semantics()) {
3546 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
3547 if (SemE ==
E->getResultExpr())
3550 if (OVE->isUnique())
3553 if (!this->discard(OVE))
3555 }
else if (SemE ==
E->getResultExpr()) {
3556 if (!this->delegate(SemE))
3559 if (!this->discard(SemE))
3566template <
class Emitter>
3568 return this->delegate(
E->getSelectedExpr());
3571template <
class Emitter>
3573 return this->emitError(
E);
3576template <
class Emitter>
3580 unsigned Offset = allocateLocalPrimitive(
3581 E->getLabel(),
PT_Ptr,
true,
false);
3583 return this->emitGetLocal(
PT_Ptr, Offset,
E);
3586template <
class Emitter>
3590 QualType ElemType = VT->getElementType();
3591 PrimType ElemT = classifyPrim(ElemType);
3592 const Expr *Src =
E->getSrcExpr();
3594 PrimType SrcElemT = classifyVectorElementType(SrcType);
3596 unsigned SrcOffset = this->allocateLocalPrimitive(Src,
PT_Ptr,
true,
false);
3597 if (!this->visit(Src))
3599 if (!this->emitSetLocal(
PT_Ptr, SrcOffset,
E))
3602 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
3603 if (!this->emitGetLocal(
PT_Ptr, SrcOffset,
E))
3605 if (!this->emitArrayElemPop(SrcElemT, I,
E))
3609 if (SrcElemT != ElemT) {
3610 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType,
E))
3612 }
else if (ElemType->isFloatingType() && SrcType != ElemType) {
3613 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
3617 if (!this->emitInitElem(ElemT, I,
E))
3624template <
class Emitter>
3627 assert(
E->getNumSubExprs() > 2);
3629 const Expr *Vecs[] = {
E->getExpr(0),
E->getExpr(1)};
3633 unsigned NumOutputElems =
E->getNumSubExprs() - 2;
3634 assert(NumOutputElems > 0);
3637 unsigned VectorOffsets[2];
3638 for (
unsigned I = 0; I != 2; ++I) {
3639 VectorOffsets[I] = this->allocateLocalPrimitive(
3640 Vecs[I],
PT_Ptr,
true,
false);
3641 if (!this->visit(Vecs[I]))
3643 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I],
E))
3646 for (
unsigned I = 0; I != NumOutputElems; ++I) {
3647 APSInt ShuffleIndex =
E->getShuffleMaskIdx(Ctx.getASTContext(), I);
3648 assert(ShuffleIndex >= -1);
3649 if (ShuffleIndex == -1)
3650 return this->emitInvalidShuffleVectorIndex(I,
E);
3652 assert(ShuffleIndex < (NumInputElems * 2));
3653 if (!this->emitGetLocal(
PT_Ptr,
3654 VectorOffsets[ShuffleIndex >= NumInputElems],
E))
3656 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
3657 if (!this->emitArrayElemPop(ElemT, InputVectorIndex,
E))
3660 if (!this->emitInitElem(ElemT, I,
E))
3667template <
class Emitter>
3672 Base->getType()->isVectorType() ||
3676 E->getEncodedElementAccess(Indices);
3678 if (Indices.size() == 1) {
3679 if (!this->visit(
Base))
3683 if (!this->emitConstUint32(Indices[0],
E))
3685 return this->emitArrayElemPtrPop(
PT_Uint32,
E);
3688 return this->emitArrayElemPop(classifyPrim(
E->
getType()), Indices[0],
E);
3692 unsigned BaseOffset = allocateLocalPrimitive(
Base,
PT_Ptr,
true,
3694 if (!this->visit(
Base))
3696 if (!this->emitSetLocal(
PT_Ptr, BaseOffset,
E))
3701 std::optional<unsigned> ResultIndex;
3702 ResultIndex = allocateLocal(
E);
3705 if (!this->emitGetPtrLocal(*ResultIndex,
E))
3713 uint32_t DstIndex = 0;
3714 for (uint32_t I : Indices) {
3715 if (!this->emitGetLocal(
PT_Ptr, BaseOffset,
E))
3717 if (!this->emitArrayElemPop(ElemT, I,
E))
3719 if (!this->emitInitElem(ElemT, DstIndex,
E))
3725 assert(!DiscardResult);
3729template <
class Emitter>
3731 const Expr *SubExpr =
E->getSubExpr();
3732 if (!
E->isExpressibleAsConstantInitializer())
3733 return this->discard(SubExpr) && this->emitInvalid(
E);
3738 assert(classifyPrim(
E) ==
PT_Ptr);
3739 return this->emitDummyPtr(
E,
E);
3742template <
class Emitter>
3745 const Expr *SubExpr =
E->getSubExpr();
3747 Ctx.getASTContext().getAsConstantArrayType(SubExpr->
getType());
3752 if (!this->visit(SubExpr))
3754 if (!this->emitConstUint8(0,
E))
3756 if (!this->emitArrayElemPtrPopUint8(
E))
3768 assert(SecondFieldT ==
PT_Ptr);
3772 if (!this->emitExpandPtr(
E))
3776 if (!this->emitArrayElemPtrPop(
PT_Uint64,
E))
3781template <
class Emitter>
3790 if (!this->visitStmt(S))
3795 assert(S == Result);
3796 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
3797 return this->delegate(ResultExpr);
3798 return this->emitUnsupported(
E);
3807 return this->Visit(
E);
3814 return this->Visit(
E);
3822 return this->discard(
E);
3827 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3831 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3834 return this->visitInitializer(
E);
3841 return this->Visit(
E);
3844template <
class Emitter>
3850 return this->Visit(
E);
3854 std::optional<PrimType>
T = classify(
E->
getType());
3858 if (!this->visit(
E))
3860 return this->emitComplexBoolCast(
E);
3865 if (!this->visit(
E))
3873 if (!this->emitNull(*
T, 0,
nullptr,
E))
3875 return this->emitNE(*
T,
E);
3880 return this->emitCastFloatingIntegralBool(getFPOptions(
E),
E);
3886template <
class Emitter>
3891 return this->emitZeroBool(
E);
3893 return this->emitZeroSint8(
E);
3895 return this->emitZeroUint8(
E);
3897 return this->emitZeroSint16(
E);
3899 return this->emitZeroUint16(
E);
3901 return this->emitZeroSint32(
E);
3903 return this->emitZeroUint32(
E);
3905 return this->emitZeroSint64(
E);
3907 return this->emitZeroUint64(
E);
3909 return this->emitZeroIntAP(Ctx.getBitWidth(QT),
E);
3911 return this->emitZeroIntAPS(Ctx.getBitWidth(QT),
E);
3913 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
3916 return this->emitNullFnPtr(0,
nullptr,
E);
3918 return this->emitNullMemberPtr(0,
nullptr,
E);
3920 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)),
E);
3922 auto Sem = Ctx.getASTContext().getFixedPointSemantics(
E->
getType());
3925 llvm_unreachable(
"Implement");
3927 llvm_unreachable(
"unknown primitive type");
3930template <
class Emitter>
3936 for (
const Record::Field &Field : R->
fields()) {
3937 if (
Field.Decl->isUnnamedBitField())
3941 if (
D->isPrimitive()) {
3944 if (!this->visitZeroInitializer(
T, QT,
E))
3946 if (!this->emitInitField(
T,
Field.Offset,
E))
3953 if (!this->emitGetPtrField(
Field.Offset,
E))
3956 if (
D->isPrimitiveArray()) {
3959 for (uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
3960 if (!this->visitZeroInitializer(
T, ET,
E))
3962 if (!this->emitInitElem(
T, I,
E))
3965 }
else if (
D->isCompositeArray()) {
3967 if (!this->visitZeroArrayInitializer(
D->getType(),
E))
3969 }
else if (
D->isRecord()) {
3970 if (!this->visitZeroRecordInitializer(
D->ElemRecord,
E))
3976 if (!this->emitFinishInitPop(
E))
3985 for (
const Record::Base &B : R->
bases()) {
3986 if (!this->emitGetPtrBase(B.Offset,
E))
3988 if (!this->visitZeroRecordInitializer(B.R,
E))
3990 if (!this->emitFinishInitPop(
E))
3999template <
class Emitter>
4004 size_t NumElems = cast<ConstantArrayType>(AT)->getZExtSize();
4006 if (std::optional<PrimType> ElemT = classify(ElemType)) {
4007 for (
size_t I = 0; I != NumElems; ++I) {
4008 if (!this->visitZeroInitializer(*ElemT, ElemType,
E))
4010 if (!this->emitInitElem(*ElemT, I,
E))
4015 const Record *R = getRecord(ElemType);
4017 for (
size_t I = 0; I != NumElems; ++I) {
4018 if (!this->emitConstUint32(I,
E))
4022 if (!this->visitZeroRecordInitializer(R,
E))
4024 if (!this->emitPopPtr(
E))
4029 for (
size_t I = 0; I != NumElems; ++I) {
4030 if (!this->emitConstUint32(I,
E))
4034 if (!this->visitZeroArrayInitializer(ElemType,
E))
4036 if (!this->emitPopPtr(
E))
4045template <
class Emitter>
4046template <
typename T>
4050 return this->emitConstSint8(
Value,
E);
4052 return this->emitConstUint8(
Value,
E);
4054 return this->emitConstSint16(
Value,
E);
4056 return this->emitConstUint16(
Value,
E);
4058 return this->emitConstSint32(
Value,
E);
4060 return this->emitConstUint32(
Value,
E);
4062 return this->emitConstSint64(
Value,
E);
4064 return this->emitConstUint64(
Value,
E);
4066 return this->emitConstBool(
Value,
E);
4074 llvm_unreachable(
"Invalid integral type");
4077 llvm_unreachable(
"unknown primitive type");
4080template <
class Emitter>
4081template <
typename T>
4086template <
class Emitter>
4090 return this->emitConstIntAPS(
Value,
E);
4092 return this->emitConstIntAP(
Value,
E);
4094 if (
Value.isSigned())
4095 return this->emitConst(
Value.getSExtValue(), Ty,
E);
4096 return this->emitConst(
Value.getZExtValue(), Ty,
E);
4099template <
class Emitter>
4104template <
class Emitter>
4109 if (
const auto *VD =
4110 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4111 assert(!
P.getGlobal(VD));
4112 assert(!Locals.contains(VD));
4120 isa<const Expr *>(Src));
4122 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
4123 Locals.insert({VD, Local});
4124 VarScope->add(Local, IsExtended);
4125 return Local.Offset;
4128template <
class Emitter>
4129std::optional<unsigned>
4133 if ([[maybe_unused]]
const auto *VD =
4134 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4135 assert(!
P.getGlobal(VD));
4136 assert(!Locals.contains(VD));
4141 bool IsTemporary =
false;
4142 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4146 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
4147 Init = VarD->getInit();
4149 if (
auto *
E = Src.dyn_cast<
const Expr *>()) {
4157 IsTemporary,
false,
Init);
4159 return std::nullopt;
4163 Locals.insert({Key, Local});
4165 VarScope->addExtended(Local, ExtendingDecl);
4167 VarScope->add(Local,
false);
4168 return Local.Offset;
4171template <
class Emitter>
4178 true,
false,
nullptr);
4185 while (S->getParent())
4187 assert(S && !S->getParent());
4189 return Local.Offset;
4192template <
class Emitter>
4194 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
4200 if (
const auto *RecordTy = getRecordTy(Ty))
4201 return getRecord(RecordTy->getDecl());
4205template <
class Emitter>
4207 return P.getOrCreateRecord(RD);
4210template <
class Emitter>
4212 return Ctx.getOrCreateFunction(FD);
4215template <
class Emitter>
4220 if (!DestroyToplevelScope) {
4221 if (!this->emitCheckAllocations(
E))
4225 auto maybeDestroyLocals = [&]() ->
bool {
4226 if (DestroyToplevelScope)
4227 return RootScope.
destroyLocals() && this->emitCheckAllocations(
E);
4228 return this->emitCheckAllocations(
E);
4235 return this->emitRetVoid(
E) && maybeDestroyLocals();
4239 if (std::optional<PrimType>
T = classify(
E)) {
4243 return this->emitRet(*
T,
E) && maybeDestroyLocals();
4249 if (std::optional<unsigned> LocalOffset = this->allocateLocal(
E)) {
4250 if (!this->emitGetPtrLocal(*LocalOffset,
E))
4253 if (!visitInitializer(
E))
4256 if (!this->emitFinishInit(
E))
4261 return this->emitRetValue(
E) && maybeDestroyLocals();
4264 return maybeDestroyLocals() && this->emitCheckAllocations(
E) &&
false;
4267template <
class Emitter>
4270 auto R = this->visitVarDecl(VD,
true);
4279 if (
auto GlobalIndex =
P.getGlobal(VD)) {
4280 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
4284 GD.
InitState = GlobalInitState::InitializerFailed;
4295template <
class Emitter>
4297 bool ConstantContext) {
4298 std::optional<PrimType> VarT = classify(VD->
getType());
4302 if (!ConstantContext) {
4307 this->emitCheckAllocations(VD);
4311 if (!this->visitVarDecl(VD,
true))
4315 auto GlobalIndex =
P.getGlobal(VD);
4316 assert(GlobalIndex);
4318 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
4321 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
4325 auto Local = Locals.find(VD);
4326 assert(Local != Locals.end());
4328 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
4331 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
4337 if (!this->emitRet(VarT.value_or(
PT_Ptr), VD)) {
4341 auto GlobalIndex =
P.getGlobal(VD);
4342 assert(GlobalIndex);
4343 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
4347 GD.
InitState = GlobalInitState::InitializerFailed;
4353 return VDScope.
destroyLocals() && this->emitCheckAllocations(VD);
4356template <
class Emitter>
4365 if (!this->isActive())
4369 std::optional<PrimType> VarT = classify(VD->
getType());
4371 if (
Init &&
Init->isValueDependent())
4375 auto checkDecl = [&]() ->
bool {
4377 return !NeedsOp || this->emitCheckDecl(VD, VD);
4380 auto initGlobal = [&](
unsigned GlobalIndex) ->
bool {
4384 if (!this->visit(
Init))
4385 return checkDecl() &&
false;
4387 return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
4393 if (!this->emitGetPtrGlobal(GlobalIndex,
Init))
4396 if (!visitInitializer(
Init))
4399 if (!this->emitFinishInit(
Init))
4402 return this->emitPopPtr(
Init);
4408 if (std::optional<unsigned> GlobalIndex =
P.getGlobal(VD)) {
4409 if (
P.getPtrGlobal(*GlobalIndex).isInitialized())
4414 return Init && checkDecl() && initGlobal(*GlobalIndex);
4417 std::optional<unsigned> GlobalIndex =
P.createGlobal(VD,
Init);
4422 return !
Init || (checkDecl() && initGlobal(*GlobalIndex));
4427 unsigned Offset = this->allocateLocalPrimitive(
4434 if (!this->visit(
Init))
4436 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
4438 if (!this->visit(
Init))
4440 return this->emitSetLocal(*VarT, Offset, VD);
4444 if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
4448 if (!this->emitGetPtrLocal(*Offset,
Init))
4451 if (!visitInitializer(
Init))
4454 if (!this->emitFinishInit(
Init))
4457 return this->emitPopPtr(
Init);
4467template <
class Emitter>
4470 assert(!DiscardResult);
4472 return this->emitConst(Val.
getInt(), ValType,
E);
4474 return this->emitConstFloat(Val.
getFloat(),
E);
4478 return this->emitNull(ValType, 0,
nullptr,
E);
4480 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
4481 return this->visit(BaseExpr);
4482 else if (
const auto *VD =
Base.dyn_cast<
const ValueDecl *>()) {
4483 return this->visitDeclRef(VD,
E);
4487 return this->emitGetMemberPtr(MemberDecl,
E);
4488 return this->emitNullMemberPtr(0,
nullptr,
E);
4494template <
class Emitter>
4503 const Record::Field *RF = R->
getField(I);
4506 PrimType T = classifyPrim(RF->Decl->getType());
4507 if (!this->visitAPValue(F,
T,
E))
4509 if (!this->emitInitField(
T, RF->Offset,
E))
4512 assert(RF->Desc->isPrimitiveArray());
4513 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
4514 PrimType ElemT = classifyPrim(ArrType->getElementType());
4517 if (!this->emitGetPtrField(RF->Offset,
E))
4520 for (
unsigned A = 0, AN = F.
getArraySize(); A != AN; ++A) {
4523 if (!this->emitInitElem(ElemT, A,
E))
4527 if (!this->emitPopPtr(
E))
4530 if (!this->emitGetPtrField(RF->Offset,
E))
4532 if (!this->visitAPValueInitializer(F,
E))
4534 if (!this->emitPopPtr(
E))
4537 assert(
false &&
"I don't think this should be possible");
4546 const Record::Field *RF = R->
getField(UnionField);
4547 PrimType T = classifyPrim(RF->Decl->getType());
4548 if (!this->visitAPValue(F,
T,
E))
4550 return this->emitInitField(
T, RF->Offset,
E);
4557template <
class Emitter>
4559 unsigned BuiltinID) {
4566 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
4567 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
4568 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
4569 BuiltinID == Builtin::BI__builtin_function_start) {
4572 return this->emitDummyPtr(
E,
E);
4576 std::optional<PrimType> ReturnT = classify(
E);
4580 std::optional<unsigned> LocalIndex = allocateLocal(
E);
4583 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4587 if (!
Func->isUnevaluatedBuiltin()) {
4589 for (
const auto *Arg :
E->arguments()) {
4590 if (!this->visit(Arg))
4595 if (!this->emitCallBI(
Func,
E, BuiltinID,
E))
4598 if (DiscardResult && !ReturnType->
isVoidType()) {
4600 return this->emitPop(*ReturnT,
E);
4606template <
class Emitter>
4608 if (
unsigned BuiltinID =
E->getBuiltinCallee())
4609 return VisitBuiltinCallExpr(
E, BuiltinID);
4616 return VisitBuiltinCallExpr(
E, Builtin::BI__builtin_operator_new);
4619 return VisitBuiltinCallExpr(
E, Builtin::BI__builtin_operator_delete);
4623 if (
const auto *DD = dyn_cast_if_present<CXXDestructorDecl>(FuncDecl);
4624 DD && DD->isTrivial())
4627 QualType ReturnType =
E->getCallReturnType(Ctx.getASTContext());
4628 std::optional<PrimType>
T = classify(ReturnType);
4632 if (DiscardResult) {
4636 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4637 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4644 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4645 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4649 if (!this->emitDupPtr(
E))
4657 bool IsAssignmentOperatorCall =
false;
4658 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
4659 OCE && OCE->isAssignmentOp()) {
4663 assert(Args.size() == 2);
4664 IsAssignmentOperatorCall =
true;
4665 std::reverse(Args.begin(), Args.end());
4670 if (isa<CXXOperatorCallExpr>(
E)) {
4671 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
4672 MD && MD->isStatic()) {
4673 if (!this->discard(
E->getArg(0)))
4676 Args.erase(Args.begin());
4680 std::optional<unsigned> CalleeOffset;
4682 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(
E)) {
4683 if (!FuncDecl && classifyPrim(
E->getCallee()) ==
PT_MemberPtr) {
4687 const Expr *Callee =
E->getCallee();
4689 this->allocateLocalPrimitive(Callee,
PT_MemberPtr,
true,
false);
4690 if (!this->visit(Callee))
4696 if (!this->emitGetMemberPtrBase(
E))
4698 }
else if (!this->visit(MC->getImplicitObjectArgument())) {
4701 }
else if (!FuncDecl) {
4702 const Expr *Callee =
E->getCallee();
4703 CalleeOffset = this->allocateLocalPrimitive(Callee,
PT_FnPtr,
true,
false);
4704 if (!this->visit(Callee))
4706 if (!this->emitSetLocal(
PT_FnPtr, *CalleeOffset,
E))
4712 unsigned ArgIndex = 0;
4713 for (
const auto *Arg : Args) {
4714 if (!this->visit(Arg))
4718 if (FuncDecl && NonNullArgs[ArgIndex]) {
4721 if (!this->emitCheckNonNullArg(ArgT, Arg))
4729 if (IsAssignmentOperatorCall) {
4730 assert(Args.size() == 2);
4733 if (!this->emitFlip(Arg2T, Arg1T,
E))
4741 assert(HasRVO ==
Func->hasRVO());
4743 bool HasQualifier =
false;
4744 if (
const auto *ME = dyn_cast<MemberExpr>(
E->getCallee()))
4745 HasQualifier = ME->hasQualifier();
4747 bool IsVirtual =
false;
4748 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
4749 IsVirtual = MD->isVirtual();
4754 if (IsVirtual && !HasQualifier) {
4755 uint32_t VarArgSize = 0;
4756 unsigned NumParams =
4757 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4758 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4761 if (!this->emitCallVirt(
Func, VarArgSize,
E))
4763 }
else if (
Func->isVariadic()) {
4764 uint32_t VarArgSize = 0;
4765 unsigned NumParams =
4766 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4767 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4769 if (!this->emitCallVar(
Func, VarArgSize,
E))
4772 if (!this->emitCall(
Func, 0,
E))
4781 uint32_t ArgSize = 0;
4782 for (
unsigned I = 0, N =
E->getNumArgs(); I != N; ++I)
4787 if (isa<CXXMemberCallExpr>(
E) && CalleeOffset) {
4790 if (!this->emitGetMemberPtrDecl(
E))
4793 if (!this->emitGetLocal(
PT_FnPtr, *CalleeOffset,
E))
4796 if (!this->emitCallPtr(ArgSize,
E,
E))
4801 if (DiscardResult && !ReturnType->
isVoidType() &&
T)
4802 return this->emitPop(*
T,
E);
4807template <
class Emitter>
4811 return this->delegate(
E->getExpr());
4814template <
class Emitter>
4818 return this->delegate(
E->getExpr());
4821template <
class Emitter>
4826 return this->emitConstBool(
E->getValue(),
E);
4829template <
class Emitter>
4835 uint64_t Val = Ctx.getASTContext().getTargetNullPointerValue(
E->
getType());
4836 return this->emitNullPtr(Val,
nullptr,
E);
4839template <
class Emitter>
4847 return this->emitZero(
T,
E);
4850template <
class Emitter>
4855 if (this->LambdaThisCapture.Offset > 0) {
4856 if (this->LambdaThisCapture.IsPtr)
4857 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset,
E);
4858 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset,
E);
4865 if (!InitStackActive)
4866 return this->emitThis(
E);
4868 if (!InitStack.empty()) {
4882 unsigned StartIndex = 0;
4883 unsigned EndIndex = 0;
4885 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
4888 EndIndex = StartIndex;
4895 for (; StartIndex > 0; --StartIndex) {
4905 for (
unsigned I = StartIndex; I != EndIndex; ++I) {
4908 if (!InitStack[I].
template emit<Emitter>(
this,
E))
4913 return this->emitThis(
E);
4917 switch (S->getStmtClass()) {
4918 case Stmt::CompoundStmtClass:
4919 return visitCompoundStmt(cast<CompoundStmt>(S));
4920 case Stmt::DeclStmtClass:
4921 return visitDeclStmt(cast<DeclStmt>(S));
4922 case Stmt::ReturnStmtClass:
4923 return visitReturnStmt(cast<ReturnStmt>(S));
4924 case Stmt::IfStmtClass:
4925 return visitIfStmt(cast<IfStmt>(S));
4926 case Stmt::WhileStmtClass:
4927 return visitWhileStmt(cast<WhileStmt>(S));
4928 case Stmt::DoStmtClass:
4929 return visitDoStmt(cast<DoStmt>(S));
4930 case Stmt::ForStmtClass:
4931 return visitForStmt(cast<ForStmt>(S));
4932 case Stmt::CXXForRangeStmtClass:
4933 return visitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
4934 case Stmt::BreakStmtClass:
4935 return visitBreakStmt(cast<BreakStmt>(S));
4936 case Stmt::ContinueStmtClass:
4937 return visitContinueStmt(cast<ContinueStmt>(S));
4938 case Stmt::SwitchStmtClass:
4939 return visitSwitchStmt(cast<SwitchStmt>(S));
4940 case Stmt::CaseStmtClass:
4941 return visitCaseStmt(cast<CaseStmt>(S));
4942 case Stmt::DefaultStmtClass:
4943 return visitDefaultStmt(cast<DefaultStmt>(S));
4944 case Stmt::AttributedStmtClass:
4945 return visitAttributedStmt(cast<AttributedStmt>(S));
4946 case Stmt::CXXTryStmtClass:
4947 return visitCXXTryStmt(cast<CXXTryStmt>(S));
4948 case Stmt::NullStmtClass:
4951 case Stmt::GCCAsmStmtClass:
4952 case Stmt::MSAsmStmtClass:
4953 case Stmt::GotoStmtClass:
4954 return this->emitInvalid(S);
4955 case Stmt::LabelStmtClass:
4956 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
4958 if (
const auto *
E = dyn_cast<Expr>(S))
4959 return this->discard(
E);
4965template <
class Emitter>
4968 for (
const auto *InnerStmt : S->body())
4969 if (!visitStmt(InnerStmt))
4971 return Scope.destroyLocals();
4974template <
class Emitter>
4976 for (
const auto *
D : DS->
decls()) {
4981 const auto *VD = dyn_cast<VarDecl>(
D);
4984 if (!this->visitVarDecl(VD))
4991template <
class Emitter>
4993 if (this->InStmtExpr)
4994 return this->emitUnsupported(RS);
5000 if (!this->visit(RE))
5002 this->emitCleanup();
5003 return this->emitRet(*ReturnType, RS);
5004 }
else if (RE->getType()->isVoidType()) {
5005 if (!this->visit(RE))
5010 if (!this->emitRVOPtr(RE))
5012 if (!this->visitInitializer(RE))
5014 if (!this->emitPopPtr(RE))
5017 this->emitCleanup();
5018 return this->emitRetVoid(RS);
5023 this->emitCleanup();
5024 return this->emitRetVoid(RS);
5028 if (
auto *CondInit = IS->
getInit())
5029 if (!visitStmt(CondInit))
5033 if (!visitDeclStmt(CondDecl))
5038 if (!this->emitIsConstantContext(IS))
5041 if (!this->emitIsConstantContext(IS))
5043 if (!this->emitInv(IS))
5046 if (!this->visitBool(IS->
getCond()))
5051 LabelTy LabelElse = this->getLabel();
5052 LabelTy LabelEnd = this->getLabel();
5053 if (!this->jumpFalse(LabelElse))
5057 if (!visitStmt(IS->
getThen()))
5062 if (!this->jump(LabelEnd))
5064 this->emitLabel(LabelElse);
5067 if (!visitStmt(Else))
5072 this->emitLabel(LabelEnd);
5074 LabelTy LabelEnd = this->getLabel();
5075 if (!this->jumpFalse(LabelEnd))
5079 if (!visitStmt(IS->
getThen()))
5084 this->emitLabel(LabelEnd);
5090template <
class Emitter>
5092 const Expr *Cond = S->getCond();
5093 const Stmt *Body = S->getBody();
5095 LabelTy CondLabel = this->getLabel();
5096 LabelTy EndLabel = this->getLabel();
5099 this->fallthrough(CondLabel);
5100 this->emitLabel(CondLabel);
5104 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5105 if (!visitDeclStmt(CondDecl))
5108 if (!this->visitBool(Cond))
5110 if (!this->jumpFalse(EndLabel))
5113 if (!this->visitStmt(Body))
5119 if (!this->jump(CondLabel))
5121 this->fallthrough(EndLabel);
5122 this->emitLabel(EndLabel);
5128 const Expr *Cond = S->getCond();
5129 const Stmt *Body = S->getBody();
5131 LabelTy StartLabel = this->getLabel();
5132 LabelTy EndLabel = this->getLabel();
5133 LabelTy CondLabel = this->getLabel();
5136 this->fallthrough(StartLabel);
5137 this->emitLabel(StartLabel);
5141 if (!this->visitStmt(Body))
5143 this->fallthrough(CondLabel);
5144 this->emitLabel(CondLabel);
5145 if (!this->visitBool(Cond))
5151 if (!this->jumpTrue(StartLabel))
5154 this->fallthrough(EndLabel);
5155 this->emitLabel(EndLabel);
5159template <
class Emitter>
5163 const Expr *Cond = S->getCond();
5164 const Expr *
Inc = S->getInc();
5165 const Stmt *Body = S->getBody();
5167 LabelTy EndLabel = this->getLabel();
5168 LabelTy CondLabel = this->getLabel();
5169 LabelTy IncLabel = this->getLabel();
5172 if (
Init && !this->visitStmt(
Init))
5175 this->fallthrough(CondLabel);
5176 this->emitLabel(CondLabel);
5180 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5181 if (!visitDeclStmt(CondDecl))
5185 if (!this->visitBool(Cond))
5187 if (!this->jumpFalse(EndLabel))
5191 if (Body && !this->visitStmt(Body))
5194 this->fallthrough(IncLabel);
5195 this->emitLabel(IncLabel);
5196 if (
Inc && !this->discard(
Inc))
5202 if (!this->jump(CondLabel))
5205 this->fallthrough(EndLabel);
5206 this->emitLabel(EndLabel);
5210template <
class Emitter>
5213 const Expr *Cond = S->getCond();
5214 const Expr *
Inc = S->getInc();
5215 const Stmt *Body = S->getBody();
5216 const Stmt *BeginStmt = S->getBeginStmt();
5217 const Stmt *RangeStmt = S->getRangeStmt();
5218 const Stmt *EndStmt = S->getEndStmt();
5219 const VarDecl *LoopVar = S->getLoopVariable();
5221 LabelTy EndLabel = this->getLabel();
5222 LabelTy CondLabel = this->getLabel();
5223 LabelTy IncLabel = this->getLabel();
5227 if (
Init && !this->visitStmt(
Init))
5229 if (!this->visitStmt(RangeStmt))
5231 if (!this->visitStmt(BeginStmt))
5233 if (!this->visitStmt(EndStmt))
5237 this->fallthrough(CondLabel);
5238 this->emitLabel(CondLabel);
5239 if (!this->visitBool(Cond))
5241 if (!this->jumpFalse(EndLabel))
5244 if (!this->visitVarDecl(LoopVar))
5249 if (!this->visitStmt(Body))
5252 this->fallthrough(IncLabel);
5253 this->emitLabel(IncLabel);
5254 if (!this->discard(
Inc))
5258 if (!this->jump(CondLabel))
5261 this->fallthrough(EndLabel);
5262 this->emitLabel(EndLabel);
5266template <
class Emitter>
5273 C->emitDestruction();
5274 return this->jump(*BreakLabel);
5277template <
class Emitter>
5283 C &&
C->getParent() != ContinueVarScope;
C =
C->getParent())
5284 C->emitDestruction();
5285 return this->jump(*ContinueLabel);
5288template <
class Emitter>
5290 const Expr *Cond = S->getCond();
5294 LabelTy EndLabel = this->getLabel();
5296 unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT,
true,
false);
5298 if (
const auto *CondInit = S->getInit())
5299 if (!visitStmt(CondInit))
5302 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5303 if (!visitDeclStmt(CondDecl))
5307 if (!this->visit(Cond))
5309 if (!this->emitSetLocal(CondT, CondVar, S))
5314 for (
const SwitchCase *SC = S->getSwitchCaseList(); SC;
5315 SC = SC->getNextSwitchCase()) {
5316 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
5318 if (CS->caseStmtIsGNURange())
5320 CaseLabels[SC] = this->getLabel();
5326 if (!this->emitGetLocal(CondT, CondVar, CS))
5328 if (!this->visit(
Value))
5332 if (!this->emitEQ(ValueT, S))
5334 if (!this->jumpTrue(CaseLabels[CS]))
5337 assert(!DefaultLabel);
5338 DefaultLabel = this->getLabel();
5345 if (!this->jump(*DefaultLabel))
5348 if (!this->jump(EndLabel))
5353 if (!this->visitStmt(S->getBody()))
5355 this->emitLabel(EndLabel);
5360template <
class Emitter>
5362 this->emitLabel(CaseLabels[S]);
5363 return this->visitStmt(S->getSubStmt());
5366template <
class Emitter>
5368 this->emitLabel(*DefaultLabel);
5369 return this->visitStmt(S->getSubStmt());
5372template <
class Emitter>
5374 if (this->Ctx.getLangOpts().CXXAssumptions &&
5375 !this->Ctx.getLangOpts().MSVCCompat) {
5376 for (
const Attr *A : S->getAttrs()) {
5377 auto *AA = dyn_cast<CXXAssumeAttr>(A);
5381 assert(isa<NullStmt>(S->getSubStmt()));
5383 const Expr *Assumption = AA->getAssumption();
5391 if (!this->visitBool(Assumption))
5394 if (!this->emitAssume(Assumption))
5400 return this->visitStmt(S->getSubStmt());
5403template <
class Emitter>
5406 return this->visitStmt(S->getTryBlock());
5409template <
class Emitter>
5413 assert(cast<CompoundStmt>(MD->
getBody())->body_empty());
5418 const Function *
Func = this->getFunction(LambdaCallOp);
5421 assert(
Func->hasThisPointer());
5424 if (
Func->hasRVO()) {
5425 if (!this->emitRVOPtr(MD))
5433 if (!this->emitNullPtr(0,
nullptr, MD))
5438 auto It = this->Params.find(PVD);
5439 assert(It != this->Params.end());
5443 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
5444 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
5448 if (!this->emitCall(
Func, 0, LambdaCallOp))
5451 this->emitCleanup();
5453 return this->emitRet(*ReturnType, MD);
5456 return this->emitRetVoid(MD);
5459template <
class Emitter>
5461 if (Ctx.getLangOpts().CPlusPlus23)
5470template <
class Emitter>
5472 assert(!ReturnType);
5474 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
5475 const Expr *InitExpr) ->
bool {
5477 if (InitExpr->getType().isNull())
5480 if (std::optional<PrimType>
T = this->classify(InitExpr)) {
5481 if (!this->visit(InitExpr))
5484 if (F->isBitField())
5485 return this->emitInitThisBitField(*
T, F, FieldOffset, InitExpr);
5486 return this->emitInitThisField(*
T, FieldOffset, InitExpr);
5491 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
5494 if (!this->visitInitializer(InitExpr))
5497 return this->emitFinishInitPop(InitExpr);
5501 const Record *R = this->getRecord(RD);
5507 assert(cast<CompoundStmt>(Ctor->
getBody())->body_empty());
5508 if (!this->emitThis(Ctor))
5517 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
5518 this->emitRetVoid(Ctor);
5522 for (
const auto *
Init : Ctor->
inits()) {
5526 const Expr *InitExpr =
Init->getInit();
5530 if (!emitFieldInitializer(F, F->Offset, InitExpr))
5533 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
5536 if (
Init->isBaseVirtual()) {
5538 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
5544 const Record::Base *B = R->
getBase(BaseDecl);
5546 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
5550 if (!this->visitInitializer(InitExpr))
5552 if (!this->emitFinishInitPop(InitExpr))
5555 assert(IFD->getChainingSize() >= 2);
5557 unsigned NestedFieldOffset = 0;
5558 const Record::Field *NestedField =
nullptr;
5559 for (
const NamedDecl *ND : IFD->chain()) {
5560 const auto *FD = cast<FieldDecl>(ND);
5561 const Record *FieldRecord = this->
P.getOrCreateRecord(FD->getParent());
5562 assert(FieldRecord);
5564 NestedField = FieldRecord->
getField(FD);
5565 assert(NestedField);
5567 NestedFieldOffset += NestedField->Offset;
5569 assert(NestedField);
5571 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
5574 assert(
Init->isDelegatingInitializer());
5575 if (!this->emitThis(InitExpr))
5577 if (!this->visitInitializer(
Init->getInit()))
5579 if (!this->emitPopPtr(InitExpr))
5583 if (!
Scope.destroyLocals())
5587 if (
const auto *Body = Ctor->
getBody())
5588 if (!visitStmt(Body))
5594template <
class Emitter>
5597 const Record *R = this->getRecord(RD);
5602 if (!this->visitStmt(Dtor->
getBody()))
5606 if (!this->emitThis(Dtor))
5612 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
5614 if (!
D->isPrimitive() && !
D->isPrimitiveArray()) {
5625 for (
const Record::Base &
Base : llvm::reverse(R->
bases())) {
5626 if (
Base.R->isAnonymousUnion())
5631 if (!this->emitRecordDestruction(
Base.R, {}))
5638 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
5641template <
class Emitter>
5646 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
5647 return this->compileConstructor(Ctor);
5648 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
5649 return this->compileDestructor(Dtor);
5652 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F);
5654 return this->emitLambdaStaticInvokerBody(MD);
5657 if (
const auto *Body = F->
getBody())
5658 if (!visitStmt(Body))
5667template <
class Emitter>
5669 const Expr *SubExpr =
E->getSubExpr();
5671 return this->VisitComplexUnaryOperator(
E);
5673 return this->VisitVectorUnaryOperator(
E);
5675 return this->VisitFixedPointUnaryOperator(
E);
5676 std::optional<PrimType>
T = classify(SubExpr->
getType());
5678 switch (
E->getOpcode()) {
5680 if (!Ctx.getLangOpts().CPlusPlus14)
5681 return this->emitInvalid(
E);
5683 return this->emitError(
E);
5685 if (!this->visit(SubExpr))
5689 if (!this->emitIncPtr(
E))
5692 return DiscardResult ? this->emitPopPtr(
E) :
true;
5696 return DiscardResult ? this->emitIncfPop(getFPOptions(
E),
E)
5697 : this->emitIncf(getFPOptions(
E),
E);
5700 return DiscardResult ? this->emitIncPop(*
T,
E) : this->emitInc(*
T,
E);
5703 if (!Ctx.getLangOpts().CPlusPlus14)
5704 return this->emitInvalid(
E);
5706 return this->emitError(
E);
5708 if (!this->visit(SubExpr))
5712 if (!this->emitDecPtr(
E))
5715 return DiscardResult ? this->emitPopPtr(
E) :
true;
5719 return DiscardResult ? this->emitDecfPop(getFPOptions(
E),
E)
5720 : this->emitDecf(getFPOptions(
E),
E);
5723 return DiscardResult ? this->emitDecPop(*
T,
E) : this->emitDec(*
T,
E);
5726 if (!Ctx.getLangOpts().CPlusPlus14)
5727 return this->emitInvalid(
E);
5729 return this->emitError(
E);
5731 if (!this->visit(SubExpr))
5735 if (!this->emitLoadPtr(
E))
5737 if (!this->emitConstUint8(1,
E))
5739 if (!this->emitAddOffsetUint8(
E))
5741 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5745 if (DiscardResult) {
5747 return this->emitIncfPop(getFPOptions(
E),
E);
5748 return this->emitIncPop(*
T,
E);
5752 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5753 if (!this->emitLoadFloat(
E))
5755 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5757 if (!this->emitAddf(getFPOptions(
E),
E))
5759 if (!this->emitStoreFloat(
E))
5763 if (!this->emitLoad(*
T,
E))
5765 if (!this->emitConst(1,
E))
5767 if (!this->emitAdd(*
T,
E))
5769 if (!this->emitStore(*
T,
E))
5775 if (!Ctx.getLangOpts().CPlusPlus14)
5776 return this->emitInvalid(
E);
5778 return this->emitError(
E);
5780 if (!this->visit(SubExpr))
5784 if (!this->emitLoadPtr(
E))
5786 if (!this->emitConstUint8(1,
E))
5788 if (!this->emitSubOffsetUint8(
E))
5790 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5794 if (DiscardResult) {
5796 return this->emitDecfPop(getFPOptions(
E),
E);
5797 return this->emitDecPop(*
T,
E);
5801 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5802 if (!this->emitLoadFloat(
E))
5804 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5806 if (!this->emitSubf(getFPOptions(
E),
E))
5808 if (!this->emitStoreFloat(
E))
5812 if (!this->emitLoad(*
T,
E))
5814 if (!this->emitConst(1,
E))
5816 if (!this->emitSub(*
T,
E))
5818 if (!this->emitStore(*
T,
E))
5825 return this->emitError(
E);
5828 return this->discard(SubExpr);
5830 if (!this->visitBool(SubExpr))
5833 if (!this->emitInv(
E))
5837 return this->emitCast(
PT_Bool, ET,
E);
5841 return this->emitError(
E);
5843 if (!this->visit(SubExpr))
5845 return DiscardResult ? this->emitPop(*
T,
E) : this->emitNeg(*
T,
E);
5848 return this->emitError(
E);
5850 if (!this->visit(SubExpr))
5852 return DiscardResult ? this->emitPop(*
T,
E) :
true;
5857 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(),
E);
5860 return this->delegate(SubExpr);
5862 if (DiscardResult) {
5864 return this->discard(SubExpr);
5867 if (!this->visit(SubExpr))
5869 if (classifyPrim(SubExpr) ==
PT_Ptr)
5870 return this->emitNarrowPtr(
E);
5875 return this->emitError(
E);
5877 if (!this->visit(SubExpr))
5879 return DiscardResult ? this->emitPop(*
T,
E) : this->emitComp(*
T,
E);
5882 return this->delegate(SubExpr);
5885 if (!this->discard(SubExpr))
5887 return this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
5890 return this->delegate(SubExpr);
5892 assert(
false &&
"Unhandled opcode");
5898template <
class Emitter>
5900 const Expr *SubExpr =
E->getSubExpr();
5904 return this->discard(SubExpr);
5906 std::optional<PrimType> ResT = classify(
E);
5907 auto prepareResult = [=]() ->
bool {
5909 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5912 return this->emitGetPtrLocal(*LocalIndex,
E);
5919 unsigned SubExprOffset = ~0u;
5920 auto createTemp = [=, &SubExprOffset]() ->
bool {
5921 SubExprOffset = this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
5922 if (!this->visit(SubExpr))
5924 return this->emitSetLocal(
PT_Ptr, SubExprOffset,
E);
5928 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
5929 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
5931 return this->emitArrayElemPop(ElemT, Index,
E);
5934 switch (
E->getOpcode()) {
5936 if (!prepareResult())
5940 for (
unsigned I = 0; I != 2; ++I) {
5941 if (!getElem(SubExprOffset, I))
5943 if (!this->emitNeg(ElemT,
E))
5945 if (!this->emitInitElem(ElemT, I,
E))
5953 return this->delegate(SubExpr);
5956 if (!this->visit(SubExpr))
5958 if (!this->emitComplexBoolCast(SubExpr))
5960 if (!this->emitInv(
E))
5963 return this->emitCast(
PT_Bool, ET,
E);
5967 return this->emitComplexReal(SubExpr);
5970 if (!this->visit(SubExpr))
5974 if (!this->emitConstUint8(1,
E))
5976 return this->emitArrayElemPtrPopUint8(
E);
5981 return this->emitArrayElemPop(classifyPrim(
E->
getType()), 1,
E);
5984 if (!this->visit(SubExpr))
5987 if (!this->emitArrayElem(ElemT, 1,
E))
5989 if (!this->emitNeg(ElemT,
E))
5991 if (!this->emitInitElem(ElemT, 1,
E))
5993 return DiscardResult ? this->emitPopPtr(
E) :
true;
5996 return this->delegate(SubExpr);
5999 return this->emitInvalid(
E);
6005template <
class Emitter>
6007 const Expr *SubExpr =
E->getSubExpr();
6011 return this->discard(SubExpr);
6013 auto UnaryOp =
E->getOpcode();
6014 if (UnaryOp == UO_Extension)
6015 return this->delegate(SubExpr);
6017 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
6018 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
6019 return this->emitInvalid(
E);
6022 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
6023 return this->delegate(SubExpr);
6026 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
6029 if (!this->emitGetPtrLocal(*LocalIndex,
E))
6034 unsigned SubExprOffset =
6035 this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
6036 if (!this->visit(SubExpr))
6038 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset,
E))
6043 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
6044 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
6046 return this->emitArrayElemPop(ElemT, Index,
E);
6051 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6052 if (!getElem(SubExprOffset, I))
6054 if (!this->emitNeg(ElemT,
E))
6056 if (!this->emitInitElem(ElemT, I,
E))
6071 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6072 if (!getElem(SubExprOffset, I))
6075 if (!this->emitPrimCast(ElemT,
PT_Bool, Ctx.getASTContext().BoolTy,
E))
6077 if (!this->emitInv(
E))
6079 if (!this->emitPrimCast(
PT_Bool, ElemT, VecTy->getElementType(),
E))
6081 if (!this->emitNeg(ElemT,
E))
6083 if (ElemT != ResultVecElemT &&
6084 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy,
E))
6086 if (!this->emitInitElem(ResultVecElemT, I,
E))
6092 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6093 if (!getElem(SubExprOffset, I))
6096 if (!this->emitInv(
E))
6099 if (!this->emitComp(ElemT,
E))
6102 if (!this->emitInitElem(ElemT, I,
E))
6107 llvm_unreachable(
"Unsupported unary operators should be handled up front");
6112template <
class Emitter>
6117 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(
D)) {
6118 return this->emitConst(ECD->getInitVal(),
E);
6119 }
else if (
const auto *BD = dyn_cast<BindingDecl>(
D)) {
6120 return this->visit(BD->getBinding());
6121 }
else if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(
D)) {
6122 const Function *F = getFunction(FuncDecl);
6123 return F && this->emitGetFnPtr(F,
E);
6124 }
else if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(
D)) {
6125 if (std::optional<unsigned> Index =
P.getOrCreateGlobal(
D)) {
6126 if (!this->emitGetPtrGlobal(*Index,
E))
6128 if (std::optional<PrimType>
T = classify(
E->
getType())) {
6129 if (!this->visitAPValue(TPOD->getValue(), *
T,
E))
6131 return this->emitInitGlobal(*
T, *Index,
E);
6133 return this->visitAPValueInitializer(TPOD->getValue(),
E);
6142 bool IsReference =
D->getType()->isReferenceType();
6145 if (
auto It = Locals.find(
D); It != Locals.end()) {
6146 const unsigned Offset = It->second.Offset;
6148 return this->emitGetLocal(
PT_Ptr, Offset,
E);
6149 return this->emitGetPtrLocal(Offset,
E);
6150 }
else if (
auto GlobalIndex =
P.getGlobal(
D)) {
6152 if (!Ctx.getLangOpts().CPlusPlus11)
6153 return this->emitGetGlobal(classifyPrim(
E), *GlobalIndex,
E);
6154 return this->emitGetGlobalUnchecked(classifyPrim(
E), *GlobalIndex,
E);
6157 return this->emitGetPtrGlobal(*GlobalIndex,
E);
6158 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(
D)) {
6159 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
6160 if (IsReference || !It->second.IsPtr)
6161 return this->emitGetParam(classifyPrim(
E), It->second.Offset,
E);
6163 return this->emitGetPtrParam(It->second.Offset,
E);
6166 if (
D->getType()->isReferenceType())
6171 auto revisit = [&](
const VarDecl *VD) ->
bool {
6172 auto VarState = this->visitDecl(VD);
6174 if (VarState.notCreated())
6179 return this->visitDeclRef(
D,
E);
6183 if (
auto It = this->LambdaCaptures.find(
D);
6184 It != this->LambdaCaptures.end()) {
6185 auto [Offset, IsPtr] = It->second;
6188 return this->emitGetThisFieldPtr(Offset,
E);
6189 return this->emitGetPtrThisField(Offset,
E);
6190 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E);
6191 DRE && DRE->refersToEnclosingVariableOrCapture()) {
6192 if (
const auto *VD = dyn_cast<VarDecl>(
D); VD && VD->isInitCapture())
6196 if (
D != InitializingDecl) {
6199 if (Ctx.getLangOpts().CPlusPlus) {
6200 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
6201 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
6202 if (
T.isConstant(Ctx.getASTContext()))
6208 if (isa<DecompositionDecl>(VD))
6211 if ((VD->hasGlobalStorage() || VD->isStaticDataMember()) &&
6212 typeShouldBeVisited(VD->getType()))
6219 if (VD->isLocalVarDecl() && typeShouldBeVisited(VD->getType()) &&
6220 VD->getInit() && !VD->getInit()->isValueDependent()) {
6222 if (VD->evaluateValue())
6225 if (!
D->getType()->isReferenceType())
6226 return this->emitDummyPtr(
D,
E);
6228 return this->emitInvalidDeclRef(cast<DeclRefExpr>(
E),
6233 if (
const auto *VD = dyn_cast<VarDecl>(
D);
6234 VD && VD->getAnyInitializer() &&
6235 VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak())
6240 return this->emitDummyPtr(
D,
E);
6243template <
class Emitter>
6245 const auto *
D =
E->getDecl();
6246 return this->visitDeclRef(
D,
E);
6251 C->emitDestruction();
6254template <
class Emitter>
6258 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
6260 return Ty->getAsCXXRecordDecl();
6262 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
6263 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
6265 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
6269template <
class Emitter>
6276 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6281 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
6282 getFPOptions(
E),
E);
6284 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
6285 getFPOptions(
E),
E);
6289 return this->emitCastFloatingIntegral(ToT, getFPOptions(
E),
E);
6294 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT),
E);
6296 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT),
E);
6300 return FromT != ToT ? this->emitCast(FromT, ToT,
E) :
true;
6304 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6305 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(
E),
E);
6313template <
class Emitter>
6318 return this->discard(SubExpr);
6320 if (!this->visit(SubExpr))
6323 if (!this->emitConstUint8(0, SubExpr))
6325 return this->emitArrayElemPtrPopUint8(SubExpr);
6329 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
6333template <
class Emitter>
6335 assert(!DiscardResult);
6339 if (!this->emitArrayElem(ElemT, 0,
E))
6342 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(
E),
E))
6345 if (!this->emitCast(ElemT,
PT_Bool,
E))
6350 LabelTy LabelTrue = this->getLabel();
6351 if (!this->jumpTrue(LabelTrue))
6354 if (!this->emitArrayElemPop(ElemT, 1,
E))
6357 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(
E),
E))
6360 if (!this->emitCast(ElemT,
PT_Bool,
E))
6364 LabelTy EndLabel = this->getLabel();
6365 this->jump(EndLabel);
6367 this->emitLabel(LabelTrue);
6368 if (!this->emitPopPtr(
E))
6370 if (!this->emitConstBool(
true,
E))
6373 this->fallthrough(EndLabel);
6374 this->emitLabel(EndLabel);
6379template <
class Emitter>
6382 assert(
E->isComparisonOp());
6384 assert(!DiscardResult);
6390 LHSIsComplex =
true;
6391 ElemT = classifyComplexElementType(LHS->
getType());
6392 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true,
6394 if (!this->visit(LHS))
6396 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
6399 LHSIsComplex =
false;
6401 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
6402 if (!this->visit(LHS))
6404 if (!this->emitSetLocal(LHST, LHSOffset,
E))
6411 RHSIsComplex =
true;
6412 ElemT = classifyComplexElementType(RHS->
getType());
6413 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true,
6415 if (!this->visit(RHS))
6417 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
6420 RHSIsComplex =
false;
6422 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
6423 if (!this->visit(RHS))
6425 if (!this->emitSetLocal(RHST, RHSOffset,
E))
6429 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
6430 bool IsComplex) ->
bool {
6432 if (!this->emitGetLocal(
PT_Ptr, LocalOffset,
E))
6434 return this->emitArrayElemPop(ElemT, Index,
E);
6436 return this->emitGetLocal(ElemT, LocalOffset,
E);
6439 for (
unsigned I = 0; I != 2; ++I) {
6441 if (!getElem(LHSOffset, I, LHSIsComplex))
6443 if (!getElem(RHSOffset, I, RHSIsComplex))
6446 if (!this->emitEQ(ElemT,
E))
6449 if (!this->emitCastBoolUint8(
E))
6454 if (!this->emitAddUint8(
E))
6456 if (!this->emitConstUint8(2,
E))
6459 if (
E->getOpcode() == BO_EQ) {
6460 if (!this->emitEQUint8(
E))
6462 }
else if (
E->getOpcode() == BO_NE) {
6463 if (!this->emitNEUint8(
E))
6470 return this->emitCast(
PT_Bool, ResT,
E);
6477template <
class Emitter>
6486 const Function *DtorFunc = getFunction(Dtor);
6491 if (!this->emitDupPtr(
Loc))
6493 return this->emitCall(DtorFunc, 0,
Loc);
6498template <
class Emitter>
6523 for (ssize_t I = Desc->
getNumElems() - 1; I >= 0; --I) {
6524 if (!this->emitConstUint64(I,
Loc))
6526 if (!this->emitArrayElemPtrUint64(
Loc))
6528 if (!this->emitDestruction(ElemDesc,
Loc))
6530 if (!this->emitPopPtr(
Loc))
6545template <
class Emitter>
6547 assert(!DiscardResult &&
"Should've been checked before");
6549 unsigned DummyID =
P.getOrCreateDummy(
D);
6551 if (!this->emitGetPtrGlobal(DummyID,
E))
6559 return this->emitDecayPtr(
PT_Ptr, PT,
E);
6572template <
class Emitter>
6574 const Expr *SubExpr =
E->getSubExpr();
6577 std::optional<PrimType> ToT = classify(ToType);
6583 std::optional<unsigned> LocalIndex = allocateLocal(
E);
6586 if (!this->emitGetPtrLocal(*LocalIndex,
E))
6596 if (!this->visit(SubExpr))
6598 }
else if (std::optional<PrimType> FromT = classify(SubExpr)) {
6599 unsigned TempOffset = allocateLocalPrimitive(
6600 SubExpr, *FromT,
true,
false);
6601 if (!this->visit(SubExpr))
6603 if (!this->emitSetLocal(*FromT, TempOffset,
E))
6605 if (!this->emitGetPtrLocal(TempOffset,
E))
6612 if (!this->emitBitCast(
E))
6614 return DiscardResult ? this->emitPopPtr(
E) :
true;
6618 const llvm::fltSemantics *TargetSemantics =
nullptr;
6620 TargetSemantics = &Ctx.getFloatSemantics(ToType);
6626 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
6628 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->
isStdByteType(),
6629 ResultBitWidth, TargetSemantics,
E))
6633 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 InitList()
static InitLink Elem(unsigned Index)
bool emit(Compiler< Emitter > *Ctx, const Expr *E) const
static InitLink Field(unsigned Offset)
static InitLink Decl(const ValueDecl *D)
static InitLink Temp(unsigned Offset)
Information about a local's storage.
State encapsulating if a the variable creation has been successful, unsuccessful, or no variable has ...
static VarCreationState NotCreated()