19 using namespace clang;
32 OldInitializingDecl(Ctx->InitializingDecl) {
38 return this->addLocal(Local);
42 this->Ctx->InitializingDecl = OldInitializingDecl;
43 this->Ctx->InitStack.pop_back();
57 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
58 OldInitializing(Ctx->Initializing) {
64 Ctx->DiscardResult = OldDiscardResult;
65 Ctx->Initializing = OldInitializing;
72 bool OldDiscardResult;
76 template <
class Emitter>
80 return Ctx->emitThis(
E);
83 return Ctx->emitGetPtrFieldPop(
Offset,
E);
85 return Ctx->emitGetPtrLocal(
Offset,
E);
89 if (!Ctx->emitConstUint32(
Offset,
E))
91 return Ctx->emitArrayElemPtrPopUint32(
E);
93 llvm_unreachable(
"Unhandled InitLink kind");
117 OldContinueLabel(Ctx->ContinueLabel) {
123 this->Ctx->BreakLabel = OldBreakLabel;
124 this->Ctx->ContinueLabel = OldContinueLabel;
128 OptLabelTy OldBreakLabel;
129 OptLabelTy OldContinueLabel;
142 OldDefaultLabel(this->Ctx->DefaultLabel),
143 OldCaseLabels(
std::move(this->Ctx->CaseLabels)) {
146 this->Ctx->
CaseLabels = std::move(CaseLabels);
150 this->Ctx->BreakLabel = OldBreakLabel;
151 this->Ctx->DefaultLabel = OldDefaultLabel;
152 this->Ctx->CaseLabels = std::move(OldCaseLabels);
156 OptLabelTy OldBreakLabel;
157 OptLabelTy OldDefaultLabel;
158 CaseMap OldCaseLabels;
177 template <
class Emitter>
182 case CK_LValueToRValue: {
184 return this->discard(SubExpr);
186 std::optional<PrimType> SubExprT = classify(SubExpr->
getType());
188 if (!Initializing && !SubExprT) {
189 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
192 if (!this->emitGetPtrLocal(*LocalIndex, CE))
196 if (!this->visit(SubExpr))
200 return this->emitLoadPop(*SubExprT, CE);
205 return this->emitMemcpy(CE);
208 case CK_DerivedToBaseMemberPointer: {
217 if (!this->visit(SubExpr))
220 return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
223 case CK_BaseToDerivedMemberPointer: {
229 unsigned DerivedOffset = collectBaseOffset(
QualType(FromMP->getClass(), 0),
232 if (!this->visit(SubExpr))
234 return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
237 case CK_UncheckedDerivedToBase:
238 case CK_DerivedToBase: {
239 if (!this->visit(SubExpr))
243 if (
const auto *PT = dyn_cast<PointerType>(Ty))
244 return PT->getPointeeType()->getAsCXXRecordDecl();
245 return Ty->getAsCXXRecordDecl();
252 if (B->isVirtual()) {
253 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))
255 CurType = B->getType();
257 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
258 if (!this->emitGetPtrBasePop(DerivedOffset, CE))
260 CurType = B->getType();
267 case CK_BaseToDerived: {
268 if (!this->visit(SubExpr))
271 unsigned DerivedOffset =
274 return this->emitGetPtrDerivedPop(DerivedOffset, CE);
277 case CK_FloatingCast: {
283 return this->discard(SubExpr);
284 if (!this->visit(SubExpr))
286 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
287 return this->emitCastFP(TargetSemantics, getRoundingMode(CE), CE);
290 case CK_IntegralToFloating: {
292 return this->discard(SubExpr);
293 std::optional<PrimType> FromT = classify(SubExpr->
getType());
297 if (!this->visit(SubExpr))
300 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
301 llvm::RoundingMode RM = getRoundingMode(CE);
302 return this->emitCastIntegralFloating(*FromT, TargetSemantics, RM, CE);
305 case CK_FloatingToBoolean:
306 case CK_FloatingToIntegral: {
308 return this->discard(SubExpr);
310 std::optional<PrimType> ToT = classify(CE->
getType());
315 if (!this->visit(SubExpr))
319 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->
getType()),
322 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->
getType()),
325 return this->emitCastFloatingIntegral(*ToT, CE);
328 case CK_NullToPointer:
329 case CK_NullToMemberPointer: {
335 if (!PointeeType.
isNull()) {
336 if (std::optional<PrimType>
T = classify(PointeeType))
337 Desc =
P.createDescriptor(SubExpr, *
T);
339 Desc =
P.createDescriptor(SubExpr, PointeeType.
getTypePtr(),
340 std::nullopt,
true,
false,
343 return this->emitNull(classifyPrim(CE->
getType()), Desc, CE);
346 case CK_PointerToIntegral: {
348 return this->discard(SubExpr);
350 if (!this->visit(SubExpr))
356 if (!this->emitDecayPtr(FromT,
PT_Ptr, CE))
362 return this->emitCastPointerIntegralAP(Ctx.getBitWidth(CE->
getType()),
365 return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(CE->
getType()),
367 return this->emitCastPointerIntegral(
T, CE);
370 case CK_ArrayToPointerDecay: {
371 if (!this->visit(SubExpr))
373 if (!this->emitArrayDecay(CE))
376 return this->emitPopPtr(CE);
380 case CK_IntegralToPointer: {
383 if (!this->visit(SubExpr))
389 return this->emitPop(
T, CE);
396 Desc =
P.createDescriptor(SubExpr, *
T);
404 if (!this->emitGetIntPtr(
T, Desc, CE))
407 PrimType DestPtrT = classifyPrim(PtrType);
412 return this->emitDecayPtr(
PT_Ptr, DestPtrT, CE);
415 case CK_AtomicToNonAtomic:
416 case CK_ConstructorConversion:
417 case CK_FunctionToPointerDecay:
418 case CK_NonAtomicToAtomic:
420 case CK_UserDefinedConversion:
421 case CK_AddressSpaceConversion:
422 return this->delegate(SubExpr);
427 if (!this->discard(SubExpr))
433 return this->discard(SubExpr);
436 std::optional<PrimType> FromT = classify(SubExprTy);
437 std::optional<PrimType> ToT = classify(CE->
getType());
445 return this->delegate(SubExpr);
447 if (!this->visit(SubExpr))
454 if (!this->visit(SubExpr))
456 return this->emitDecayPtr(*FromT, *ToT, CE);
459 case CK_IntegralToBoolean:
460 case CK_BooleanToSignedIntegral:
461 case CK_IntegralCast: {
463 return this->discard(SubExpr);
464 std::optional<PrimType> FromT = classify(SubExpr->
getType());
465 std::optional<PrimType> ToT = classify(CE->
getType());
470 if (!this->visit(SubExpr))
478 if (!this->emitCheckEnumValue(*FromT, ET->getDecl(), CE))
483 auto maybeNegate = [&]() ->
bool {
484 if (CE->
getCastKind() == CK_BooleanToSignedIntegral)
485 return this->emitNeg(*ToT, CE);
490 return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->
getType()), CE) &&
493 return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->
getType()), CE) &&
498 if (!this->emitCast(*FromT, *ToT, CE))
501 return maybeNegate();
504 case CK_PointerToBoolean:
505 case CK_MemberPointerToBoolean: {
509 if (!this->visit(SubExpr))
512 if (!this->emitNull(PtrT,
nullptr, CE))
515 return this->emitNE(PtrT, CE);
518 case CK_IntegralComplexToBoolean:
519 case CK_FloatingComplexToBoolean: {
521 return this->discard(SubExpr);
522 if (!this->visit(SubExpr))
524 return this->emitComplexBoolCast(SubExpr);
527 case CK_IntegralComplexToReal:
528 case CK_FloatingComplexToReal:
529 return this->emitComplexReal(SubExpr);
531 case CK_IntegralRealToComplex:
532 case CK_FloatingRealToComplex: {
536 unsigned LocalIndex = allocateTemporary(CE);
537 if (!this->emitGetPtrLocal(LocalIndex, CE))
542 if (!this->visitArrayElemInit(0, SubExpr))
546 if (!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
548 return this->emitInitElem(
T, 1, SubExpr);
551 case CK_IntegralComplexCast:
552 case CK_FloatingComplexCast:
553 case CK_IntegralComplexToFloatingComplex:
554 case CK_FloatingComplexToIntegralComplex: {
558 return this->discard(SubExpr);
561 std::optional<unsigned> LocalIndex = allocateLocal(CE);
564 if (!this->emitGetPtrLocal(*LocalIndex, CE))
571 unsigned SubExprOffset = allocateLocalPrimitive(
572 SubExpr,
PT_Ptr,
true,
false);
573 if (!this->visit(SubExpr))
575 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, CE))
581 PrimType DestElemT = classifyPrim(DestElemType);
583 for (
unsigned I = 0; I != 2; ++I) {
584 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, CE))
586 if (!this->emitArrayElemPop(SourceElemT, I, CE))
590 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
594 if (!this->emitInitElem(DestElemT, I, CE))
600 case CK_VectorSplat: {
601 assert(!classify(CE->
getType()));
602 assert(classify(SubExpr->
getType()));
606 return this->discard(SubExpr);
609 std::optional<unsigned> LocalIndex = allocateLocal(CE);
612 if (!this->emitGetPtrLocal(*LocalIndex, CE))
618 unsigned ElemOffset = allocateLocalPrimitive(
619 SubExpr, ElemT,
true,
false);
622 if (!this->visit(SubExpr))
624 if (classifyPrim(SubExpr) ==
PT_Ptr && !this->emitLoadPop(ElemT, CE))
627 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
630 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
631 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
633 if (!this->emitInitElem(ElemT, I, CE))
641 return discard(SubExpr);
644 return this->emitInvalid(CE);
646 llvm_unreachable(
"Unhandled clang::CastKind enum");
649 template <
class Emitter>
654 return this->emitConst(
LE->getValue(),
LE);
657 template <
class Emitter>
662 return this->emitConstFloat(
E->getValue(),
E);
665 template <
class Emitter>
672 unsigned LocalIndex = allocateTemporary(
E);
673 if (!this->emitGetPtrLocal(LocalIndex,
E))
677 const Expr *SubExpr =
E->getSubExpr();
680 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
682 if (!this->emitInitElem(SubExprT, 0, SubExpr))
684 return this->visitArrayElemInit(1, SubExpr);
687 template <
class Emitter>
689 return this->delegate(
E->getSubExpr());
692 template <
class Emitter>
696 return this->VisitLogicalBinOp(BO);
704 if (!this->discard(LHS))
707 return this->discard(RHS);
709 return this->delegate(RHS);
713 return this->VisitComplexBinOp(BO);
717 return this->emitComplexComparison(LHS, RHS, BO);
720 if (!this->visit(LHS))
723 if (!this->visit(RHS))
726 if (!this->emitToMemberPtr(BO))
732 if (!this->emitCastMemberPtrPtr(BO))
734 return DiscardResult ? this->emitPopPtr(BO) :
true;
738 std::optional<PrimType>
LT = classify(LHS);
739 std::optional<PrimType> RT = classify(RHS);
740 std::optional<PrimType>
T = classify(BO->
getType());
749 Ctx.getASTContext().CompCategories.lookupInfoForType(BO->
getType());
754 std::optional<unsigned> ResultIndex = this->allocateLocal(BO);
755 if (!this->emitGetPtrLocal(*ResultIndex, BO))
759 if (!visit(LHS) || !visit(RHS))
762 return this->emitCMP3(*
LT, CmpInfo, BO);
765 if (!
LT || !RT || !
T)
771 return this->VisitPointerArithBinOp(BO);
776 if (!visit(RHS) || !visit(LHS))
778 if (!this->emitFlip(*
LT, *RT, BO))
781 if (!visit(LHS) || !visit(RHS))
787 auto MaybeCastToBool = [
this,
T, BO](
bool Result) {
791 return this->emitPop(*
T, BO);
793 return this->emitCast(
PT_Bool, *
T, BO);
797 auto Discard = [
this,
T, BO](
bool Result) {
800 return DiscardResult ? this->emitPop(*
T, BO) :
true;
805 return MaybeCastToBool(this->emitEQ(*
LT, BO));
807 return MaybeCastToBool(this->emitNE(*
LT, BO));
809 return MaybeCastToBool(this->emitLT(*
LT, BO));
811 return MaybeCastToBool(this->emitLE(*
LT, BO));
813 return MaybeCastToBool(this->emitGT(*
LT, BO));
815 return MaybeCastToBool(this->emitGE(*
LT, BO));
818 return Discard(this->emitSubf(getRoundingMode(BO), BO));
819 return Discard(this->emitSub(*
T, BO));
822 return Discard(this->emitAddf(getRoundingMode(BO), BO));
823 return Discard(this->emitAdd(*
T, BO));
826 return Discard(this->emitMulf(getRoundingMode(BO), BO));
827 return Discard(this->emitMul(*
T, BO));
829 return Discard(this->emitRem(*
T, BO));
832 return Discard(this->emitDivf(getRoundingMode(BO), BO));
833 return Discard(this->emitDiv(*
T, BO));
837 : this->emitStorePop(*
T, BO);
839 if (!this->emitStoreBitField(*
T, BO))
842 if (!this->emitStore(*
T, BO))
848 return this->emitLoadPop(*
T, BO);
851 return Discard(this->emitBitAnd(*
T, BO));
853 return Discard(this->emitBitOr(*
T, BO));
855 return Discard(this->emitShl(*
LT, *RT, BO));
857 return Discard(this->emitShr(*
LT, *RT, BO));
859 return Discard(this->emitBitXor(*
T, BO));
862 llvm_unreachable(
"Already handled earlier");
867 llvm_unreachable(
"Unhandled binary op");
872 template <
class Emitter>
875 const Expr *LHS =
E->getLHS();
876 const Expr *RHS =
E->getRHS();
878 if ((Op != BO_Add && Op != BO_Sub) ||
882 std::optional<PrimType>
LT = classify(LHS);
883 std::optional<PrimType> RT = classify(RHS);
893 if (!visit(RHS) || !visit(LHS))
896 return this->emitSubPtr(classifyPrim(
E->
getType()),
E);
901 if (!visit(RHS) || !visit(LHS))
905 if (!visit(LHS) || !visit(RHS))
913 return this->emitAddOffset(OffsetType,
E);
914 else if (Op == BO_Sub)
915 return this->emitSubOffset(OffsetType,
E);
920 template <
class Emitter>
922 assert(
E->isLogicalOp());
924 const Expr *LHS =
E->getLHS();
925 const Expr *RHS =
E->getRHS();
926 std::optional<PrimType>
T = classify(
E->
getType());
930 LabelTy LabelTrue = this->getLabel();
931 LabelTy LabelEnd = this->getLabel();
933 if (!this->visitBool(LHS))
935 if (!this->jumpTrue(LabelTrue))
938 if (!this->visitBool(RHS))
940 if (!this->jump(LabelEnd))
943 this->emitLabel(LabelTrue);
944 this->emitConstBool(
true,
E);
945 this->fallthrough(LabelEnd);
946 this->emitLabel(LabelEnd);
949 assert(Op == BO_LAnd);
952 LabelTy LabelFalse = this->getLabel();
953 LabelTy LabelEnd = this->getLabel();
955 if (!this->visitBool(LHS))
957 if (!this->jumpFalse(LabelFalse))
960 if (!this->visitBool(RHS))
962 if (!this->jump(LabelEnd))
965 this->emitLabel(LabelFalse);
966 this->emitConstBool(
false,
E);
967 this->fallthrough(LabelEnd);
968 this->emitLabel(LabelEnd);
972 return this->emitPopBool(
E);
981 template <
class Emitter>
985 unsigned LocalIndex = allocateTemporary(
E);
986 if (!this->emitGetPtrLocal(LocalIndex,
E))
992 const Expr *LHS =
E->getLHS();
993 const Expr *RHS =
E->getRHS();
996 unsigned ResultOffset = ~0u;
998 ResultOffset = this->allocateLocalPrimitive(
E,
PT_Ptr,
true,
false);
1001 if (!this->DiscardResult) {
1002 if (!this->emitDupPtr(
E))
1004 if (!this->emitSetLocal(
PT_Ptr, ResultOffset,
E))
1009 LHSType = AT->getValueType();
1012 RHSType = AT->getValueType();
1021 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1026 if (!this->visit(LHS))
1028 if (!this->visit(RHS))
1030 return this->emitMulc(ElemT,
E);
1033 if (Op == BO_Div && RHSIsComplex) {
1035 PrimType ElemT = classifyPrim(ElemQT);
1040 if (!LHSIsComplex) {
1042 LHSOffset = allocateTemporary(RHS);
1044 if (!this->emitGetPtrLocal(LHSOffset,
E))
1047 if (!this->visit(LHS))
1050 if (!this->emitInitElem(ElemT, 0,
E))
1053 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1055 if (!this->emitInitElem(ElemT, 1,
E))
1058 if (!this->visit(LHS))
1062 if (!this->visit(RHS))
1064 return this->emitDivc(ElemT,
E);
1069 LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
1070 if (!this->visit(LHS))
1072 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1075 PrimType LHST = classifyPrim(LHSType);
1076 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
1077 if (!this->visit(LHS))
1079 if (!this->emitSetLocal(LHST, LHSOffset,
E))
1086 RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
1087 if (!this->visit(RHS))
1089 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1092 PrimType RHST = classifyPrim(RHSType);
1093 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
1094 if (!this->visit(RHS))
1096 if (!this->emitSetLocal(RHST, RHSOffset,
E))
1103 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1104 unsigned ElemIndex,
unsigned Offset,
1105 const Expr *
E) ->
bool {
1109 return this->emitArrayElemPop(classifyComplexElementType(
E->
getType()),
1112 if (ElemIndex == 0 || !LoadZero)
1114 return this->visitZeroInitializer(classifyPrim(
E->
getType()),
E->
getType(),
1119 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1121 if (!this->DiscardResult) {
1122 if (!this->emitGetLocal(
PT_Ptr, ResultOffset,
E))
1129 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1132 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1135 if (!this->emitAddf(getRoundingMode(
E),
E))
1138 if (!this->emitAdd(ResultElemT,
E))
1143 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1146 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1149 if (!this->emitSubf(getRoundingMode(
E),
E))
1152 if (!this->emitSub(ResultElemT,
E))
1157 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1160 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1164 if (!this->emitMulf(getRoundingMode(
E),
E))
1167 if (!this->emitMul(ResultElemT,
E))
1172 assert(!RHSIsComplex);
1173 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1176 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1180 if (!this->emitDivf(getRoundingMode(
E),
E))
1183 if (!this->emitDiv(ResultElemT,
E))
1192 if (!this->DiscardResult) {
1194 if (!this->emitInitElemPop(ResultElemT, ElemIndex,
E))
1197 if (!this->emitPop(ResultElemT,
E))
1204 template <
class Emitter>
1209 if (std::optional<PrimType>
T = classify(QT))
1210 return this->visitZeroInitializer(*
T, QT,
E);
1224 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1225 CXXRD && CXXRD->getNumVBases() > 0) {
1230 const Record *R = getRecord(QT);
1234 assert(Initializing);
1235 return this->visitZeroRecordInitializer(R,
E);
1244 const auto *CAT = cast<ConstantArrayType>(AT);
1245 size_t NumElems = CAT->getZExtSize();
1246 PrimType ElemT = classifyPrim(CAT->getElementType());
1248 for (
size_t I = 0; I != NumElems; ++I) {
1249 if (!this->visitZeroInitializer(ElemT, CAT->getElementType(),
E))
1251 if (!this->emitInitElem(ElemT, I,
E))
1259 assert(Initializing);
1260 QualType ElemQT = ComplexTy->getElementType();
1261 PrimType ElemT = classifyPrim(ElemQT);
1262 for (
unsigned I = 0; I < 2; ++I) {
1263 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1265 if (!this->emitInitElem(ElemT, I,
E))
1272 unsigned NumVecElements = VecT->getNumElements();
1273 QualType ElemQT = VecT->getElementType();
1274 PrimType ElemT = classifyPrim(ElemQT);
1276 for (
unsigned I = 0; I < NumVecElements; ++I) {
1277 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1279 if (!this->emitInitElem(ElemT, I,
E))
1288 template <
class Emitter>
1290 const Expr *LHS =
E->getLHS();
1291 const Expr *RHS =
E->getRHS();
1292 const Expr *Index =
E->getIdx();
1295 return this->discard(LHS) && this->discard(RHS);
1299 bool Success =
true;
1300 for (
const Expr *SubExpr : {LHS, RHS}) {
1301 if (!this->visit(SubExpr))
1308 PrimType IndexT = classifyPrim(Index->getType());
1311 if (!this->emitFlip(
PT_Ptr, IndexT,
E))
1315 return this->emitArrayElemPtrPop(IndexT,
E);
1318 template <
class Emitter>
1320 const Expr *ArrayFiller,
const Expr *
E) {
1325 QT = AT->getValueType();
1328 return this->emitInvalid(
E);
1331 if (DiscardResult) {
1333 if (!this->discard(
Init))
1340 if (std::optional<PrimType>
T = classify(QT)) {
1341 assert(!DiscardResult);
1342 if (Inits.size() == 0)
1343 return this->visitZeroInitializer(*
T, QT,
E);
1344 assert(Inits.size() == 1);
1345 return this->delegate(Inits[0]);
1349 const Record *R = getRecord(QT);
1351 if (Inits.size() == 1 &&
E->
getType() == Inits[0]->getType())
1352 return this->delegate(Inits[0]);
1354 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
1357 if (!this->visit(
Init))
1360 if (FieldToInit->isBitField())
1361 return this->emitInitBitField(
T, FieldToInit,
E);
1362 return this->emitInitField(
T, FieldToInit->Offset,
E);
1365 auto initCompositeField = [=](
const Record::Field *FieldToInit,
1371 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
1373 if (!this->visitInitializer(
Init))
1375 return this->emitPopPtr(
E);
1379 if (Inits.size() == 0) {
1380 if (!this->visitZeroRecordInitializer(R,
E))
1385 if (
const auto *ILE = dyn_cast<InitListExpr>(
E))
1386 FToInit = ILE->getInitializedFieldInUnion();
1388 FToInit = cast<CXXParenListInitExpr>(
E)->getInitializedFieldInUnion();
1390 const Record::Field *FieldToInit = R->
getField(FToInit);
1391 if (std::optional<PrimType>
T = classify(
Init)) {
1392 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1395 if (!initCompositeField(FieldToInit,
Init))
1399 return this->emitFinishInit(
E);
1403 unsigned InitIndex = 0;
1406 while (InitIndex < R->getNumFields() &&
1410 if (std::optional<PrimType>
T = classify(
Init)) {
1411 const Record::Field *FieldToInit = R->
getField(InitIndex);
1412 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1418 if (!this->emitGetPtrBase(B->Offset,
Init))
1421 if (!this->visitInitializer(
Init))
1424 if (!this->emitFinishInitPop(
E))
1429 const Record::Field *FieldToInit = R->
getField(InitIndex);
1430 if (!initCompositeField(FieldToInit,
Init))
1436 return this->emitFinishInit(
E);
1440 if (Inits.size() == 1 && QT == Inits[0]->getType())
1441 return this->delegate(Inits[0]);
1443 unsigned ElementIndex = 0;
1445 if (
const auto *EmbedS =
1446 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1449 auto Eval = [&](
const Expr *
Init,
unsigned ElemIndex) {
1451 if (!this->visit(
Init))
1453 if (InitT != TargetT) {
1454 if (!this->emitCast(InitT, TargetT,
E))
1457 return this->emitInitElem(TargetT, ElemIndex,
Init);
1459 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
1462 if (!this->visitArrayElemInit(ElementIndex,
Init))
1472 Ctx.getASTContext().getAsConstantArrayType(QT);
1475 for (; ElementIndex != NumElems; ++ElementIndex) {
1476 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller))
1481 return this->emitFinishInit(
E);
1485 unsigned NumInits = Inits.size();
1488 return this->delegate(Inits[0]);
1490 QualType ElemQT = ComplexTy->getElementType();
1491 PrimType ElemT = classifyPrim(ElemQT);
1492 if (NumInits == 0) {
1494 for (
unsigned I = 0; I < 2; ++I) {
1495 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1497 if (!this->emitInitElem(ElemT, I,
E))
1500 }
else if (NumInits == 2) {
1501 unsigned InitIndex = 0;
1503 if (!this->visit(
Init))
1506 if (!this->emitInitElem(ElemT, InitIndex,
E))
1515 unsigned NumVecElements = VecT->getNumElements();
1516 assert(NumVecElements >= Inits.size());
1518 QualType ElemQT = VecT->getElementType();
1519 PrimType ElemT = classifyPrim(ElemQT);
1522 unsigned InitIndex = 0;
1524 if (!this->visit(
Init))
1529 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
1530 if (!this->emitCopyArray(ElemT, 0, InitIndex,
1531 InitVecT->getNumElements(),
E))
1533 InitIndex += InitVecT->getNumElements();
1535 if (!this->emitInitElem(ElemT, InitIndex,
E))
1541 assert(InitIndex <= NumVecElements);
1544 for (; InitIndex != NumVecElements; ++InitIndex) {
1545 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1547 if (!this->emitInitElem(ElemT, InitIndex,
E))
1558 template <
class Emitter>
1561 if (std::optional<PrimType>
T = classify(
Init->getType())) {
1563 if (!this->visit(
Init))
1565 return this->emitInitElem(*
T, ElemIndex,
Init);
1571 if (!this->emitConstUint32(ElemIndex,
Init))
1573 if (!this->emitArrayElemPtrUint32(
Init))
1575 if (!this->visitInitializer(
Init))
1577 return this->emitFinishInitPop(
Init);
1580 template <
class Emitter>
1582 return this->visitInitList(
E->inits(),
E->getArrayFiller(),
E);
1585 template <
class Emitter>
1588 return this->visitInitList(
E->getInitExprs(),
E->getArrayFiller(),
E);
1591 template <
class Emitter>
1594 return this->delegate(
E->getReplacement());
1597 template <
class Emitter>
1599 std::optional<PrimType>
T = classify(
E->
getType());
1600 if (
T &&
E->hasAPValueResult()) {
1607 if (this->visitAPValue(
E->getAPValueResult(), *
T,
E))
1610 return this->delegate(
E->getSubExpr());
1613 template <
class Emitter>
1615 auto It =
E->begin();
1616 return this->visit(*It);
1621 bool AlignOfReturnsPreferred =
1630 if (
T.getQualifiers().hasUnaligned())
1636 if (
Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
1642 template <
class Emitter>
1646 const ASTContext &ASTCtx = Ctx.getASTContext();
1648 if (
Kind == UETT_SizeOf ||
Kind == UETT_DataSizeOf) {
1649 QualType ArgType =
E->getTypeOfArgument();
1663 if (
Kind == UETT_SizeOf)
1672 return this->emitConst(Size.getQuantity(),
E);
1675 if (
Kind == UETT_AlignOf ||
Kind == UETT_PreferredAlignOf) {
1678 if (
E->isArgumentType()) {
1679 QualType ArgType =
E->getTypeOfArgument();
1692 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
1695 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
1705 return this->emitConst(Size.getQuantity(),
E);
1708 if (
Kind == UETT_VectorElements) {
1709 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>())
1710 return this->emitConst(VT->getNumElements(),
E);
1711 assert(
E->getTypeOfArgument()->isSizelessVectorType());
1712 return this->emitSizelessVectorElementSize(
E);
1715 if (
Kind == UETT_VecStep) {
1716 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>()) {
1717 unsigned N = VT->getNumElements();
1724 return this->emitConst(N,
E);
1726 return this->emitConst(1,
E);
1732 template <
class Emitter>
1739 return this->discard(
Base);
1743 const auto maybeLoadValue = [&]() ->
bool {
1746 if (std::optional<PrimType>
T = classify(
E))
1747 return this->emitLoadPop(*
T,
E);
1751 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
1755 if (
auto GlobalIndex =
P.getGlobal(VD))
1756 return this->emitGetPtrGlobal(*GlobalIndex,
E) && maybeLoadValue();
1760 if (!isa<FieldDecl>(
Member))
1761 return this->discard(
Base) && this->visitDeclRef(
Member,
E);
1764 if (!this->delegate(
Base))
1767 if (!this->visit(
Base))
1772 const auto *FD = cast<FieldDecl>(
Member);
1774 const Record *R = getRecord(RD);
1777 const Record::Field *F = R->
getField(FD);
1779 if (F->Decl->getType()->isReferenceType())
1780 return this->emitGetFieldPop(
PT_Ptr, F->Offset,
E) && maybeLoadValue();
1781 return this->emitGetPtrFieldPop(F->Offset,
E) && maybeLoadValue();
1784 template <
class Emitter>
1790 return this->emitConst(*ArrayIndex,
E);
1793 template <
class Emitter>
1795 assert(Initializing);
1796 assert(!DiscardResult);
1800 if (!this->discard(
E->getCommonExpr()))
1805 const Expr *SubExpr =
E->getSubExpr();
1806 size_t Size =
E->getArraySize().getZExtValue();
1811 for (
size_t I = 0; I != Size; ++I) {
1815 if (!this->visitArrayElemInit(I, SubExpr))
1823 template <
class Emitter>
1825 const Expr *SourceExpr =
E->getSourceExpr();
1830 return this->visitInitializer(SourceExpr);
1833 if (
auto It = OpaqueExprs.find(
E); It != OpaqueExprs.end())
1834 return this->emitGetLocal(SubExprT, It->second,
E);
1836 if (!this->visit(SourceExpr))
1842 unsigned LocalIndex = allocateLocalPrimitive(
E, SubExprT,
true);
1843 if (!this->emitSetLocal(SubExprT, LocalIndex,
E))
1848 if (!DiscardResult) {
1849 if (!this->emitGetLocal(SubExprT, LocalIndex,
E))
1854 OpaqueExprs.insert({
E, LocalIndex});
1859 template <
class Emitter>
1863 const Expr *TrueExpr =
E->getTrueExpr();
1864 const Expr *FalseExpr =
E->getFalseExpr();
1866 LabelTy LabelEnd = this->getLabel();
1867 LabelTy LabelFalse = this->getLabel();
1872 if (!this->jumpFalse(LabelFalse))
1877 if (!this->delegate(TrueExpr))
1879 if (!S.destroyLocals())
1883 if (!this->jump(LabelEnd))
1886 this->emitLabel(LabelFalse);
1890 if (!this->delegate(FalseExpr))
1892 if (!S.destroyLocals())
1896 this->fallthrough(LabelEnd);
1897 this->emitLabel(LabelEnd);
1902 template <
class Emitter>
1907 if (!Initializing) {
1908 unsigned StringIndex =
P.createGlobalString(
E);
1909 return this->emitGetPtrGlobal(StringIndex,
E);
1914 Ctx.getASTContext().getAsConstantArrayType(
E->
getType());
1915 assert(CAT &&
"a string literal that's not a constant array?");
1920 unsigned N =
std::min(ArraySize,
E->getLength());
1921 size_t CharWidth =
E->getCharByteWidth();
1923 for (
unsigned I = 0; I != N; ++I) {
1926 if (CharWidth == 1) {
1927 this->emitConstSint8(CodeUnit,
E);
1928 this->emitInitElemSint8(I,
E);
1929 }
else if (CharWidth == 2) {
1930 this->emitConstUint16(CodeUnit,
E);
1931 this->emitInitElemUint16(I,
E);
1932 }
else if (CharWidth == 4) {
1933 this->emitConstUint32(CodeUnit,
E);
1934 this->emitInitElemUint32(I,
E);
1936 llvm_unreachable(
"unsupported character width");
1941 for (
unsigned I = N; I != ArraySize; ++I) {
1942 if (CharWidth == 1) {
1943 this->emitConstSint8(0,
E);
1944 this->emitInitElemSint8(I,
E);
1945 }
else if (CharWidth == 2) {
1946 this->emitConstUint16(0,
E);
1947 this->emitInitElemUint16(I,
E);
1948 }
else if (CharWidth == 4) {
1949 this->emitConstUint32(0,
E);
1950 this->emitInitElemUint32(I,
E);
1952 llvm_unreachable(
"unsupported character width");
1959 template <
class Emitter>
1961 return this->delegate(
E->getString());
1964 template <
class Emitter>
1966 auto &A = Ctx.getASTContext();
1968 A.getObjCEncodingForType(
E->getEncodedType(), Str);
1972 return this->delegate(SL);
1975 template <
class Emitter>
1981 assert(!Initializing);
1983 auto &A = Ctx.getASTContext();
1984 std::string ResultStr =
E->ComputeName(A);
1987 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
1988 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
1993 false, ArrayTy,
E->getLocation());
1995 unsigned StringIndex =
P.createGlobalString(SL);
1996 return this->emitGetPtrGlobal(StringIndex,
E);
1999 template <
class Emitter>
2003 return this->emitConst(
E->getValue(),
E);
2006 template <
class Emitter>
2010 const Expr *LHS =
E->getLHS();
2011 const Expr *RHS =
E->getRHS();
2013 QualType LHSComputationType =
E->getComputationLHSType();
2014 QualType ResultType =
E->getComputationResultType();
2015 std::optional<PrimType>
LT = classify(LHSComputationType);
2016 std::optional<PrimType> RT = classify(ResultType);
2023 PrimType LHST = classifyPrim(LHSType);
2031 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2032 if (!this->emitSetLocal(*RT, TempOffset,
E))
2038 if (!this->emitLoad(LHST,
E))
2042 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
2043 LHSComputationType,
E))
2047 if (!this->emitGetLocal(*RT, TempOffset,
E))
2050 llvm::RoundingMode RM = getRoundingMode(
E);
2051 switch (
E->getOpcode()) {
2053 if (!this->emitAddf(RM,
E))
2057 if (!this->emitSubf(RM,
E))
2061 if (!this->emitMulf(RM,
E))
2065 if (!this->emitDivf(RM,
E))
2072 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->
getType(),
E))
2076 return this->emitStorePop(LHST,
E);
2077 return this->emitStore(LHST,
E);
2080 template <
class Emitter>
2084 const Expr *LHS =
E->getLHS();
2085 const Expr *RHS =
E->getRHS();
2086 std::optional<PrimType>
LT = classify(LHS->
getType());
2087 std::optional<PrimType> RT = classify(RHS->
getType());
2089 if (Op != BO_AddAssign && Op != BO_SubAssign)
2098 if (!this->emitLoad(*
LT, LHS))
2104 if (Op == BO_AddAssign) {
2105 if (!this->emitAddOffset(*RT,
E))
2108 if (!this->emitSubOffset(*RT,
E))
2113 return this->emitStorePopPtr(
E);
2114 return this->emitStorePtr(
E);
2117 template <
class Emitter>
2121 const Expr *LHS =
E->getLHS();
2122 const Expr *RHS =
E->getRHS();
2123 std::optional<PrimType> LHSComputationT =
2124 classify(
E->getComputationLHSType());
2125 std::optional<PrimType>
LT = classify(LHS->
getType());
2126 std::optional<PrimType> RT = classify(RHS->
getType());
2127 std::optional<PrimType> ResultT = classify(
E->
getType());
2129 if (!Ctx.getLangOpts().CPlusPlus14)
2130 return this->visit(RHS) && this->visit(LHS) && this->emitError(
E);
2132 if (!
LT || !RT || !ResultT || !LHSComputationT)
2139 return VisitFloatCompoundAssignOperator(
E);
2142 return VisitPointerCompoundAssignOperator(
E);
2155 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2157 if (!this->emitSetLocal(*RT, TempOffset,
E))
2164 if (!this->emitLoad(*
LT,
E))
2166 if (
LT != LHSComputationT) {
2167 if (!this->emitCast(*
LT, *LHSComputationT,
E))
2172 if (!this->emitGetLocal(*RT, TempOffset,
E))
2176 switch (
E->getOpcode()) {
2178 if (!this->emitAdd(*LHSComputationT,
E))
2182 if (!this->emitSub(*LHSComputationT,
E))
2186 if (!this->emitMul(*LHSComputationT,
E))
2190 if (!this->emitDiv(*LHSComputationT,
E))
2194 if (!this->emitRem(*LHSComputationT,
E))
2198 if (!this->emitShl(*LHSComputationT, *RT,
E))
2202 if (!this->emitShr(*LHSComputationT, *RT,
E))
2206 if (!this->emitBitAnd(*LHSComputationT,
E))
2210 if (!this->emitBitXor(*LHSComputationT,
E))
2214 if (!this->emitBitOr(*LHSComputationT,
E))
2218 llvm_unreachable(
"Unimplemented compound assign operator");
2222 if (ResultT != LHSComputationT) {
2223 if (!this->emitCast(*LHSComputationT, *ResultT,
E))
2228 if (DiscardResult) {
2230 return this->emitStoreBitFieldPop(*ResultT,
E);
2231 return this->emitStorePop(*ResultT,
E);
2234 return this->emitStoreBitField(*ResultT,
E);
2235 return this->emitStore(*ResultT,
E);
2238 template <
class Emitter>
2241 const Expr *SubExpr =
E->getSubExpr();
2243 assert(
E->getNumObjects() == 0 &&
"TODO: Implement cleanups");
2248 template <
class Emitter>
2251 const Expr *SubExpr =
E->getSubExpr();
2255 return this->delegate(SubExpr);
2260 return this->discard(SubExpr);
2264 std::optional<PrimType> SubExprT = classify(SubExpr);
2267 std::optional<unsigned> GlobalIndex =
P.createGlobal(
E);
2272 E->getLifetimeExtendedTemporaryDecl();
2277 if (!this->visit(SubExpr))
2280 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl,
E))
2283 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex,
E))
2286 return this->emitGetPtrGlobal(*GlobalIndex,
E);
2290 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2292 if (!this->visitInitializer(SubExpr))
2295 return this->emitInitGlobalTempComp(TempDecl,
E);
2301 unsigned LocalIndex = allocateLocalPrimitive(
2302 SubExpr, *SubExprT,
true,
true);
2303 if (!this->visit(SubExpr))
2305 if (!this->emitSetLocal(*SubExprT, LocalIndex,
E))
2307 return this->emitGetPtrLocal(LocalIndex,
E);
2310 if (std::optional<unsigned> LocalIndex =
2311 allocateLocal(Inner,
E->getExtendingDecl())) {
2313 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2315 return this->visitInitializer(SubExpr);
2321 template <
class Emitter>
2324 return this->delegate(
E->getSubExpr());
2327 template <
class Emitter>
2332 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2335 std::optional<PrimType>
T = classify(
E->
getType());
2336 if (
E->isFileScope()) {
2339 return this->delegate(
Init);
2341 if (std::optional<unsigned> GlobalIndex =
P.createGlobal(
E)) {
2342 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2346 if (!this->visit(
Init))
2348 return this->emitInitGlobal(*
T, *GlobalIndex,
E);
2351 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
2360 return this->delegate(
Init);
2362 unsigned LocalIndex;
2365 LocalIndex = this->allocateLocalPrimitive(
Init, *
T,
false,
false);
2366 else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(
Init))
2367 LocalIndex = *MaybeIndex;
2371 if (!this->emitGetPtrLocal(LocalIndex,
E))
2375 if (!this->visit(
Init)) {
2378 return this->emitInit(*
T,
E);
2380 if (!this->visitInitializer(
Init) || !this->emitFinishInit(
E))
2385 return this->emitPopPtr(
E);
2392 template <
class Emitter>
2397 return this->emitConstBool(
E->getValue(),
E);
2398 return this->emitConst(
E->getValue(),
E);
2401 template <
class Emitter>
2405 return this->emitConst(
E->getValue(),
E);
2408 template <
class Emitter>
2413 assert(Initializing);
2414 const Record *R =
P.getOrCreateRecord(
E->getLambdaClass());
2416 auto *CaptureInitIt =
E->capture_init_begin();
2419 for (
const Record::Field &F : R->
fields()) {
2426 if (std::optional<PrimType>
T = classify(
Init)) {
2427 if (!this->visit(
Init))
2430 if (!this->emitInitField(*
T, F.Offset,
E))
2433 if (!this->emitGetPtrField(F.Offset,
E))
2436 if (!this->visitInitializer(
Init))
2439 if (!this->emitPopPtr(
E))
2447 template <
class Emitter>
2452 return this->delegate(
E->getFunctionName());
2455 template <
class Emitter>
2457 if (
E->getSubExpr() && !this->discard(
E->getSubExpr()))
2460 return this->emitInvalid(
E);
2463 template <
class Emitter>
2466 const Expr *SubExpr =
E->getSubExpr();
2468 bool TypesMatch = classify(
E) == classify(SubExpr);
2472 return this->delegate(SubExpr);
2475 template <
class Emitter>
2481 return this->emitConstBool(
E->getValue(),
E);
2484 template <
class Emitter>
2487 assert(!classify(
T));
2497 return this->visitInitializer(
E->getArg(0));
2501 if (DiscardResult) {
2504 assert(!Initializing);
2505 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2510 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2515 if (
E->requiresZeroInitialization()) {
2518 if (!this->visitZeroRecordInitializer(R,
E))
2531 assert(
Func->hasThisPointer());
2532 assert(!
Func->hasRVO());
2536 if (!this->emitDupPtr(
E))
2540 for (
const auto *Arg :
E->arguments()) {
2541 if (!this->visit(Arg))
2545 if (
Func->isVariadic()) {
2547 unsigned NumParams =
Func->getNumWrittenParams();
2548 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I) {
2552 if (!this->emitCallVar(
Func, VarArgSize,
E))
2555 if (!this->emitCall(
Func, 0,
E))
2560 return this->emitPopPtr(
E);
2566 Ctx.getASTContext().getAsConstantArrayType(
E->
getType());
2577 for (
size_t I = 0; I != NumElems; ++I) {
2578 if (!this->emitConstUint64(I,
E))
2580 if (!this->emitArrayElemPtrUint64(
E))
2584 for (
const auto *Arg :
E->arguments()) {
2585 if (!this->visit(Arg))
2589 if (!this->emitCall(
Func, 0,
E))
2598 template <
class Emitter>
2604 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
2608 assert(Val.
isInt());
2610 return this->emitConst(I,
E);
2617 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
2618 return this->visit(LValueExpr);
2627 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
2629 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(UGCD);
2633 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2637 const APValue &
V = UGCD->getValue();
2638 for (
unsigned I = 0, N = R->
getNumFields(); I != N; ++I) {
2639 const Record::Field *F = R->
getField(I);
2640 const APValue &FieldValue =
V.getStructField(I);
2642 PrimType FieldT = classifyPrim(F->Decl->getType());
2644 if (!this->visitAPValue(FieldValue, FieldT,
E))
2646 if (!this->emitInitField(FieldT, F->Offset,
E))
2654 template <
class Emitter>
2656 unsigned N =
E->getNumComponents();
2660 for (
unsigned I = 0; I != N; ++I) {
2663 const Expr *ArrayIndexExpr =
E->getIndexExpr(
Node.getArrayExprIndex());
2666 if (DiscardResult) {
2667 if (!this->discard(ArrayIndexExpr))
2672 if (!this->visit(ArrayIndexExpr))
2686 return this->emitOffsetOf(
T,
E,
E);
2689 template <
class Emitter>
2697 if (std::optional<PrimType>
T = classify(Ty))
2698 return this->visitZeroInitializer(*
T, Ty,
E);
2701 if (!Initializing) {
2702 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2705 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2710 QualType ElemQT = CT->getElementType();
2711 PrimType ElemT = classifyPrim(ElemQT);
2713 for (
unsigned I = 0; I != 2; ++I) {
2714 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
2716 if (!this->emitInitElem(ElemT, I,
E))
2724 if (!Initializing) {
2725 std::optional<unsigned> LocalIndex = allocateLocal(
E);
2728 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2733 QualType ElemQT = VT->getElementType();
2734 PrimType ElemT = classifyPrim(ElemQT);
2736 for (
unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
2737 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
2739 if (!this->emitInitElem(ElemT, I,
E))
2748 template <
class Emitter>
2750 return this->emitConst(
E->getPackLength(),
E);
2753 template <
class Emitter>
2756 return this->delegate(
E->getResultExpr());
2759 template <
class Emitter>
2761 return this->delegate(
E->getChosenSubExpr());
2764 template <
class Emitter>
2769 return this->emitConst(
E->getValue(),
E);
2772 template <
class Emitter>
2777 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
2778 const Function *F = this->getFunction(Ctor);
2795 if (!this->emitGetParam(PT,
Offset,
E))
2800 return this->emitCall(F, 0,
E);
2803 template <
class Emitter>
2807 QualType ElementType =
E->getAllocatedType();
2808 std::optional<PrimType> ElemT = classify(ElementType);
2809 unsigned PlacementArgs =
E->getNumPlacementArgs();
2810 bool IsNoThrow =
false;
2813 if (PlacementArgs != 0) {
2825 return this->emitInvalid(
E);
2827 if (!this->discard(
E->getPlacementArg(0)))
2841 Desc =
P.createDescriptor(
2844 false,
false,
false,
Init);
2848 std::optional<const Expr *> ArraySizeExpr =
E->getArraySize();
2852 const Expr *Stripped = *ArraySizeExpr;
2853 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
2854 Stripped = ICE->getSubExpr())
2855 if (ICE->getCastKind() != CK_NoOp &&
2856 ICE->getCastKind() != CK_IntegralCast)
2861 if (!this->visit(Stripped))
2866 if (!this->emitAllocN(SizeT, *ElemT,
E, IsNoThrow,
E))
2870 if (!this->emitAllocCN(SizeT, Desc, IsNoThrow,
E))
2874 if (
Init && !this->visitInitializer(
Init))
2879 if (!this->emitAlloc(Desc,
E))
2884 if (!this->visit(
Init))
2887 if (!this->emitInit(*ElemT,
E))
2891 if (!this->visitInitializer(
Init))
2898 return this->emitPopPtr(
E);
2903 template <
class Emitter>
2905 const Expr *Arg =
E->getArgument();
2908 if (!this->visit(Arg))
2911 return this->emitFree(
E->isArrayForm(),
E);
2914 template <
class Emitter>
2916 assert(Ctx.getLangOpts().CPlusPlus);
2917 return this->emitConstBool(
E->getValue(),
E);
2920 template <
class Emitter>
2924 assert(!Initializing);
2932 if (std::optional<unsigned> I =
P.getOrCreateDummy(GuidDecl))
2933 return this->emitGetPtrGlobal(*I,
E);
2937 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(GuidDecl);
2940 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2943 assert(this->getRecord(
E->
getType()));
2949 assert(
V.isStruct());
2950 assert(
V.getStructNumBases() == 0);
2951 if (!this->visitAPValueInitializer(
V,
E))
2954 return this->emitFinishInit(
E);
2957 template <
class Emitter>
2962 return this->emitConstBool(
E->isSatisfied(),
E);
2965 template <
class Emitter>
2971 return this->emitConstBool(
E->isSatisfied(),
E);
2974 template <
class Emitter>
2977 return this->delegate(
E->getSemanticForm());
2980 template <
class Emitter>
2983 for (
const Expr *SemE :
E->semantics()) {
2984 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
2985 if (SemE ==
E->getResultExpr())
2988 if (OVE->isUnique())
2991 if (!this->discard(OVE))
2993 }
else if (SemE ==
E->getResultExpr()) {
2994 if (!this->delegate(SemE))
2997 if (!this->discard(SemE))
3004 template <
class Emitter>
3006 return this->delegate(
E->getSelectedExpr());
3009 template <
class Emitter>
3011 return this->emitError(
E);
3014 template <
class Emitter>
3018 unsigned Offset = allocateLocalPrimitive(
3019 E->getLabel(),
PT_Ptr,
true,
false);
3024 template <
class Emitter>
3026 assert(Initializing);
3028 QualType ElemType = VT->getElementType();
3029 PrimType ElemT = classifyPrim(ElemType);
3030 const Expr *Src =
E->getSrcExpr();
3034 unsigned SrcOffset = this->allocateLocalPrimitive(Src,
PT_Ptr,
true,
false);
3035 if (!this->visit(Src))
3037 if (!this->emitSetLocal(
PT_Ptr, SrcOffset,
E))
3040 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
3041 if (!this->emitGetLocal(
PT_Ptr, SrcOffset,
E))
3043 if (!this->emitArrayElemPop(SrcElemT, I,
E))
3045 if (SrcElemT != ElemT) {
3046 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType,
E))
3049 if (!this->emitInitElem(ElemT, I,
E))
3056 template <
class Emitter>
3058 assert(Initializing);
3059 assert(
E->getNumSubExprs() > 2);
3061 const Expr *Vecs[] = {
E->getExpr(0),
E->getExpr(1)};
3065 unsigned NumOutputElems =
E->getNumSubExprs() - 2;
3066 assert(NumOutputElems > 0);
3069 unsigned VectorOffsets[2];
3070 for (
unsigned I = 0; I != 2; ++I) {
3071 VectorOffsets[I] = this->allocateLocalPrimitive(
3072 Vecs[I],
PT_Ptr,
true,
false);
3073 if (!this->visit(Vecs[I]))
3075 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I],
E))
3078 for (
unsigned I = 0; I != NumOutputElems; ++I) {
3079 APSInt ShuffleIndex =
E->getShuffleMaskIdx(Ctx.getASTContext(), I);
3080 if (ShuffleIndex == -1)
3081 return this->emitInvalid(
E);
3083 assert(ShuffleIndex < (NumInputElems * 2));
3084 if (!this->emitGetLocal(
PT_Ptr,
3085 VectorOffsets[ShuffleIndex >= NumInputElems],
E))
3087 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
3088 if (!this->emitArrayElemPop(ElemT, InputVectorIndex,
E))
3091 if (!this->emitInitElem(ElemT, I,
E))
3098 template <
class Emitter>
3103 Base->getType()->isVectorType() ||
3107 E->getEncodedElementAccess(Indices);
3109 if (Indices.size() == 1) {
3110 if (!this->visit(
Base))
3114 if (!this->emitConstUint32(Indices[0],
E))
3116 return this->emitArrayElemPtrPop(
PT_Uint32,
E);
3119 return this->emitArrayElemPop(classifyPrim(
E->
getType()), Indices[0],
E);
3123 unsigned BaseOffset = allocateLocalPrimitive(
Base,
PT_Ptr,
true,
3125 if (!this->visit(
Base))
3127 if (!this->emitSetLocal(
PT_Ptr, BaseOffset,
E))
3131 if (!Initializing) {
3132 std::optional<unsigned> ResultIndex;
3133 ResultIndex = allocateLocal(
E);
3136 if (!this->emitGetPtrLocal(*ResultIndex,
E))
3146 if (!this->emitGetLocal(
PT_Ptr, BaseOffset,
E))
3148 if (!this->emitArrayElemPop(ElemT, I,
E))
3150 if (!this->emitInitElem(ElemT, DstIndex,
E))
3156 assert(!DiscardResult);
3160 template <
class Emitter>
3162 const Expr *SubExpr =
E->getSubExpr();
3163 if (!
E->isExpressibleAsConstantInitializer())
3164 return this->discard(SubExpr) && this->emitInvalid(
E);
3166 return this->delegate(SubExpr);
3169 template <
class Emitter>
3172 const Expr *SubExpr =
E->getSubExpr();
3174 Ctx.getASTContext().getAsConstantArrayType(SubExpr->
getType());
3176 assert(Initializing);
3179 if (!this->visit(SubExpr))
3191 assert(SecondFieldT ==
PT_Ptr);
3197 if (!this->emitArrayElemPtrPop(
PT_Uint64,
E))
3202 template <
class Emitter>
3211 if (!this->visitStmt(S))
3216 assert(S == Result);
3217 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
3218 return this->delegate(ResultExpr);
3219 return this->emitUnsupported(
E);
3228 return this->Visit(
E);
3233 return this->emitError(
E);
3238 return this->Visit(
E);
3246 return this->discard(
E);
3251 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3255 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3257 return this->visitInitializer(
E);
3264 return this->Visit(
E);
3267 template <
class Emitter>
3272 return this->emitError(
E);
3274 if (!this->checkLiteralType(
E))
3279 return this->Visit(
E);
3283 std::optional<PrimType>
T = classify(
E->
getType());
3287 if (!this->visit(
E))
3289 return this->emitComplexBoolCast(
E);
3294 if (!this->visit(
E))
3302 if (!this->emitNull(*
T,
nullptr,
E))
3304 return this->emitNE(*
T,
E);
3309 return this->emitCastFloatingIntegralBool(
E);
3315 template <
class Emitter>
3320 return this->emitZeroBool(
E);
3322 return this->emitZeroSint8(
E);
3324 return this->emitZeroUint8(
E);
3326 return this->emitZeroSint16(
E);
3328 return this->emitZeroUint16(
E);
3330 return this->emitZeroSint32(
E);
3332 return this->emitZeroUint32(
E);
3334 return this->emitZeroSint64(
E);
3336 return this->emitZeroUint64(
E);
3338 return this->emitZeroIntAP(Ctx.getBitWidth(QT),
E);
3340 return this->emitZeroIntAPS(Ctx.getBitWidth(QT),
E);
3342 return this->emitNullPtr(
nullptr,
E);
3344 return this->emitNullFnPtr(
nullptr,
E);
3346 return this->emitNullMemberPtr(
nullptr,
E);
3348 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)),
E);
3351 llvm_unreachable(
"unknown primitive type");
3354 template <
class Emitter>
3360 for (
const Record::Field &Field : R->
fields()) {
3361 if (
Field.Decl->isUnnamedBitField())
3365 if (
D->isPrimitive()) {
3368 if (!this->visitZeroInitializer(
T, QT,
E))
3370 if (!this->emitInitField(
T,
Field.Offset,
E))
3377 if (!this->emitGetPtrField(
Field.Offset,
E))
3380 if (
D->isPrimitiveArray()) {
3383 for (
uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
3384 if (!this->visitZeroInitializer(
T, ET,
E))
3386 if (!this->emitInitElem(
T, I,
E))
3389 }
else if (
D->isCompositeArray()) {
3390 const Record *ElemRecord =
D->ElemDesc->ElemRecord;
3391 assert(
D->ElemDesc->ElemRecord);
3392 for (
uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
3393 if (!this->emitConstUint32(I,
E))
3397 if (!this->visitZeroRecordInitializer(ElemRecord,
E))
3399 if (!this->emitPopPtr(
E))
3402 }
else if (
D->isRecord()) {
3403 if (!this->visitZeroRecordInitializer(
D->ElemRecord,
E))
3409 if (!this->emitFinishInitPop(
E))
3417 if (!this->emitGetPtrBase(B.Offset,
E))
3419 if (!this->visitZeroRecordInitializer(B.R,
E))
3421 if (!this->emitFinishInitPop(
E))
3430 template <
class Emitter>
3431 template <
typename T>
3435 return this->emitConstSint8(
Value,
E);
3437 return this->emitConstUint8(
Value,
E);
3439 return this->emitConstSint16(
Value,
E);
3441 return this->emitConstUint16(
Value,
E);
3443 return this->emitConstSint32(
Value,
E);
3445 return this->emitConstUint32(
Value,
E);
3447 return this->emitConstSint64(
Value,
E);
3449 return this->emitConstUint64(
Value,
E);
3451 return this->emitConstBool(
Value,
E);
3458 llvm_unreachable(
"Invalid integral type");
3461 llvm_unreachable(
"unknown primitive type");
3464 template <
class Emitter>
3465 template <
typename T>
3470 template <
class Emitter>
3474 return this->emitConstIntAPS(
Value,
E);
3476 return this->emitConstIntAP(
Value,
E);
3478 if (
Value.isSigned())
3479 return this->emitConst(
Value.getSExtValue(), Ty,
E);
3480 return this->emitConst(
Value.getZExtValue(), Ty,
E);
3483 template <
class Emitter>
3488 template <
class Emitter>
3493 if (
const auto *VD =
3494 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
3495 assert(!
P.getGlobal(VD));
3496 assert(!Locals.contains(VD));
3504 Src.is<
const Expr *>());
3506 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
3507 Locals.insert({VD, Local});
3508 VarScope->add(Local, IsExtended);
3509 return Local.Offset;
3512 template <
class Emitter>
3513 std::optional<unsigned>
3516 if ([[maybe_unused]]
const auto *VD =
3517 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
3518 assert(!
P.getGlobal(VD));
3519 assert(!Locals.contains(VD));
3525 bool IsTemporary =
false;
3526 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
3530 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
3531 Init = VarD->getInit();
3533 if (
auto *
E = Src.dyn_cast<
const Expr *>()) {
3540 IsTemporary,
false,
Init);
3542 return std::nullopt;
3546 Locals.insert({Key, Local});
3548 VarScope->addExtended(Local, ExtendingDecl);
3550 VarScope->add(Local,
false);
3551 return Local.Offset;
3554 template <
class Emitter>
3561 true,
false,
nullptr);
3568 while (S->getParent())
3570 assert(S && !S->getParent());
3572 return Local.Offset;
3575 template <
class Emitter>
3577 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
3583 if (
const auto *RecordTy = getRecordTy(Ty))
3584 return getRecord(RecordTy->getDecl());
3588 template <
class Emitter>
3590 return P.getOrCreateRecord(RD);
3593 template <
class Emitter>
3595 return Ctx.getOrCreateFunction(FD);
3608 if (std::optional<PrimType>
T = classify(
E)) {
3617 if (std::optional<unsigned> LocalOffset = this->allocateLocal(
E)) {
3618 if (!this->emitGetPtrLocal(*LocalOffset,
E))
3621 if (!visitInitializer(
E))
3624 if (!this->emitFinishInit(
E))
3636 template <
class Emitter>
3639 auto R = this->visitVarDecl(VD,
true);
3648 if (
auto GlobalIndex =
P.getGlobal(VD)) {
3649 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
3664 template <
class Emitter>
3666 bool ConstantContext) {
3667 std::optional<PrimType> VarT = classify(VD->
getType());
3671 if (!ConstantContext) {
3679 if (!this->visitVarDecl(VD,
true))
3683 auto GlobalIndex =
P.getGlobal(VD);
3684 assert(GlobalIndex);
3686 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
3689 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
3693 auto Local = Locals.find(VD);
3694 assert(Local != Locals.end());
3696 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
3699 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
3705 if (!this->emitRet(VarT.value_or(
PT_Ptr), VD)) {
3709 auto GlobalIndex =
P.getGlobal(VD);
3710 assert(GlobalIndex);
3711 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
3724 template <
class Emitter>
3733 if (!this->isActive())
3737 std::optional<PrimType> VarT = classify(VD->
getType());
3739 if (
Init &&
Init->isValueDependent())
3743 auto checkDecl = [&]() ->
bool {
3745 return !NeedsOp || this->emitCheckDecl(VD, VD);
3748 auto initGlobal = [&](
unsigned GlobalIndex) ->
bool {
3753 if (!this->visit(
Init))
3754 return checkDecl() &&
false;
3756 return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
3762 if (!this->emitGetPtrGlobal(GlobalIndex,
Init))
3765 if (!visitInitializer(
Init))
3768 if (!this->emitFinishInit(
Init))
3771 return this->emitPopPtr(
Init);
3775 if (std::optional<unsigned> GlobalIndex =
P.getGlobal(VD)) {
3776 if (
P.getPtrGlobal(*GlobalIndex).isInitialized())
3781 return Init && checkDecl() && initGlobal(*GlobalIndex);
3784 std::optional<unsigned> GlobalIndex =
P.createGlobal(VD,
Init);
3789 return !
Init || (checkDecl() && initGlobal(*GlobalIndex));
3794 unsigned Offset = this->allocateLocalPrimitive(
3801 if (!this->visit(
Init))
3803 return this->emitSetLocal(*VarT,
Offset, VD) &&
Scope.destroyLocals();
3805 if (!this->visit(
Init))
3807 return this->emitSetLocal(*VarT,
Offset, VD);
3811 if (std::optional<unsigned>
Offset = this->allocateLocal(VD)) {
3818 if (!visitInitializer(
Init))
3821 if (!this->emitFinishInit(
Init))
3824 return this->emitPopPtr(
Init);
3834 template <
class Emitter>
3837 assert(!DiscardResult);
3839 return this->emitConst(Val.
getInt(), ValType,
E);
3841 return this->emitConstFloat(Val.
getFloat(),
E);
3845 return this->emitNull(ValType,
nullptr,
E);
3847 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
3848 return this->visit(BaseExpr);
3849 else if (
const auto *VD =
Base.dyn_cast<
const ValueDecl *>()) {
3850 return this->visitDeclRef(VD,
E);
3854 return this->emitGetMemberPtr(MemberDecl,
E);
3855 return this->emitNullMemberPtr(
nullptr,
E);
3861 template <
class Emitter>
3870 const Record::Field *RF = R->
getField(I);
3873 PrimType T = classifyPrim(RF->Decl->getType());
3874 if (!this->visitAPValue(F,
T,
E))
3876 if (!this->emitInitField(
T, RF->Offset,
E))
3879 assert(RF->Desc->isPrimitiveArray());
3880 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
3881 PrimType ElemT = classifyPrim(ArrType->getElementType());
3884 if (!this->emitGetPtrField(RF->Offset,
E))
3887 for (
unsigned A = 0, AN = F.
getArraySize(); A != AN; ++A) {
3890 if (!this->emitInitElem(ElemT, A,
E))
3894 if (!this->emitPopPtr(
E))
3897 if (!this->emitGetPtrField(RF->Offset,
E))
3899 if (!this->visitAPValueInitializer(F,
E))
3901 if (!this->emitPopPtr(
E))
3904 assert(
false &&
"I don't think this should be possible");
3913 const Record::Field *RF = R->
getField(UnionField);
3914 PrimType T = classifyPrim(RF->Decl->getType());
3915 if (!this->visitAPValue(F,
T,
E))
3917 return this->emitInitField(
T, RF->Offset,
E);
3924 template <
class Emitter>
3932 unsigned Builtin =
E->getBuiltinCallee();
3933 if (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
3934 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
3935 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
3936 Builtin == Builtin::BI__builtin_function_start) {
3937 if (std::optional<unsigned> GlobalOffset =
P.createGlobal(
E)) {
3938 if (!this->emitGetPtrGlobal(*GlobalOffset,
E))
3942 return this->emitDecayPtr(
PT_Ptr, PT,
E);
3949 std::optional<PrimType> ReturnT = classify(
E);
3952 if (!Initializing && !ReturnT && !ReturnType->
isVoidType()) {
3953 std::optional<unsigned> LocalIndex = allocateLocal(
E);
3956 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3960 if (!
Func->isUnevaluatedBuiltin()) {
3962 for (
const auto *Arg :
E->arguments()) {
3963 if (!this->visit(Arg))
3968 if (!this->emitCallBI(
Func,
E,
E))
3971 if (DiscardResult && !ReturnType->
isVoidType()) {
3973 return this->emitPop(*ReturnT,
E);
3979 template <
class Emitter>
3981 if (
E->getBuiltinCallee())
3982 return VisitBuiltinCallExpr(
E);
3984 QualType ReturnType =
E->getCallReturnType(Ctx.getASTContext());
3985 std::optional<PrimType>
T = classify(ReturnType);
3990 if (DiscardResult) {
3994 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
3995 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4001 if (!Initializing) {
4002 if (std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4003 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4007 if (!this->emitDupPtr(
E))
4015 bool IsAssignmentOperatorCall =
false;
4016 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
4017 OCE && OCE->isAssignmentOp()) {
4021 assert(Args.size() == 2);
4022 IsAssignmentOperatorCall =
true;
4023 std::reverse(Args.begin(), Args.end());
4028 if (isa<CXXOperatorCallExpr>(
E)) {
4029 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
4030 MD && MD->isStatic()) {
4031 if (!this->discard(
E->getArg(0)))
4034 Args.erase(Args.begin());
4038 std::optional<unsigned> CalleeOffset;
4040 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(
E)) {
4041 if (!FuncDecl && classifyPrim(
E->getCallee()) ==
PT_MemberPtr) {
4045 const Expr *Callee =
E->getCallee();
4047 this->allocateLocalPrimitive(Callee,
PT_MemberPtr,
true,
false);
4048 if (!this->visit(Callee))
4054 if (!this->emitGetMemberPtrBase(
E))
4056 }
else if (!this->visit(MC->getImplicitObjectArgument())) {
4059 }
else if (!FuncDecl) {
4060 const Expr *Callee =
E->getCallee();
4061 CalleeOffset = this->allocateLocalPrimitive(Callee,
PT_FnPtr,
true,
false);
4062 if (!this->visit(Callee))
4064 if (!this->emitSetLocal(
PT_FnPtr, *CalleeOffset,
E))
4070 unsigned ArgIndex = 0;
4071 for (
const auto *Arg : Args) {
4072 if (!this->visit(Arg))
4076 if (FuncDecl && NonNullArgs[ArgIndex]) {
4079 if (!this->emitCheckNonNullArg(ArgT, Arg))
4087 if (IsAssignmentOperatorCall) {
4088 assert(Args.size() == 2);
4091 if (!this->emitFlip(Arg2T, Arg1T,
E))
4099 assert(HasRVO ==
Func->hasRVO());
4101 bool HasQualifier =
false;
4102 if (
const auto *ME = dyn_cast<MemberExpr>(
E->getCallee()))
4103 HasQualifier = ME->hasQualifier();
4105 bool IsVirtual =
false;
4106 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
4107 IsVirtual = MD->isVirtual();
4112 if (IsVirtual && !HasQualifier) {
4114 unsigned NumParams =
4115 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4116 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4119 if (!this->emitCallVirt(
Func, VarArgSize,
E))
4121 }
else if (
Func->isVariadic()) {
4123 unsigned NumParams =
4124 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4125 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
4127 if (!this->emitCallVar(
Func, VarArgSize,
E))
4130 if (!this->emitCall(
Func, 0,
E))
4140 for (
unsigned I = 0, N =
E->getNumArgs(); I != N; ++I)
4145 if (isa<CXXMemberCallExpr>(
E) && CalleeOffset) {
4148 if (!this->emitGetMemberPtrDecl(
E))
4151 if (!this->emitGetLocal(
PT_FnPtr, *CalleeOffset,
E))
4154 if (!this->emitCallPtr(ArgSize,
E,
E))
4159 if (DiscardResult && !ReturnType->
isVoidType() &&
T)
4160 return this->emitPop(*
T,
E);
4165 template <
class Emitter>
4169 return this->delegate(
E->getExpr());
4172 template <
class Emitter>
4176 const Expr *SubExpr =
E->getExpr();
4177 if (std::optional<PrimType>
T = classify(
E->getExpr()))
4178 return this->visit(SubExpr);
4180 assert(Initializing);
4181 return this->visitInitializer(SubExpr);
4184 template <
class Emitter>
4189 return this->emitConstBool(
E->getValue(),
E);
4192 template <
class Emitter>
4198 return this->emitNullPtr(
nullptr,
E);
4201 template <
class Emitter>
4209 return this->emitZero(
T,
E);
4212 template <
class Emitter>
4217 if (this->LambdaThisCapture.Offset > 0) {
4218 if (this->LambdaThisCapture.IsPtr)
4219 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset,
E);
4220 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset,
E);
4227 if (!InitStackActive || !
E->isImplicit())
4228 return this->emitThis(
E);
4230 if (InitStackActive && !InitStack.empty()) {
4231 unsigned StartIndex = 0;
4232 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
4238 for (
unsigned I = StartIndex, N = InitStack.size(); I != N; ++I) {
4239 if (!InitStack[I].
template emit<Emitter>(
this,
E))
4244 return this->emitThis(
E);
4248 switch (S->getStmtClass()) {
4249 case Stmt::CompoundStmtClass:
4250 return visitCompoundStmt(cast<CompoundStmt>(S));
4251 case Stmt::DeclStmtClass:
4252 return visitDeclStmt(cast<DeclStmt>(S));
4253 case Stmt::ReturnStmtClass:
4254 return visitReturnStmt(cast<ReturnStmt>(S));
4255 case Stmt::IfStmtClass:
4256 return visitIfStmt(cast<IfStmt>(S));
4257 case Stmt::WhileStmtClass:
4258 return visitWhileStmt(cast<WhileStmt>(S));
4259 case Stmt::DoStmtClass:
4260 return visitDoStmt(cast<DoStmt>(S));
4261 case Stmt::ForStmtClass:
4262 return visitForStmt(cast<ForStmt>(S));
4263 case Stmt::CXXForRangeStmtClass:
4264 return visitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
4265 case Stmt::BreakStmtClass:
4266 return visitBreakStmt(cast<BreakStmt>(S));
4267 case Stmt::ContinueStmtClass:
4268 return visitContinueStmt(cast<ContinueStmt>(S));
4269 case Stmt::SwitchStmtClass:
4270 return visitSwitchStmt(cast<SwitchStmt>(S));
4271 case Stmt::CaseStmtClass:
4272 return visitCaseStmt(cast<CaseStmt>(S));
4273 case Stmt::DefaultStmtClass:
4274 return visitDefaultStmt(cast<DefaultStmt>(S));
4275 case Stmt::AttributedStmtClass:
4276 return visitAttributedStmt(cast<AttributedStmt>(S));
4277 case Stmt::CXXTryStmtClass:
4278 return visitCXXTryStmt(cast<CXXTryStmt>(S));
4279 case Stmt::NullStmtClass:
4282 case Stmt::GCCAsmStmtClass:
4283 case Stmt::MSAsmStmtClass:
4284 case Stmt::GotoStmtClass:
4285 return this->emitInvalid(S);
4286 case Stmt::LabelStmtClass:
4287 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
4289 if (
const auto *
E = dyn_cast<Expr>(S))
4290 return this->discard(
E);
4296 template <
class Emitter>
4299 for (
const auto *InnerStmt : S->body())
4300 if (!visitStmt(InnerStmt))
4302 return Scope.destroyLocals();
4305 template <
class Emitter>
4307 for (
const auto *
D : DS->
decls()) {
4312 const auto *VD = dyn_cast<VarDecl>(
D);
4315 if (!this->visitVarDecl(VD))
4322 template <
class Emitter>
4324 if (this->InStmtExpr)
4325 return this->emitUnsupported(RS);
4331 if (!this->visit(RE))
4333 this->emitCleanup();
4334 return this->emitRet(*ReturnType, RS);
4335 }
else if (RE->getType()->isVoidType()) {
4336 if (!this->visit(RE))
4340 if (!this->emitRVOPtr(RE))
4342 if (!this->visitInitializer(RE))
4344 if (!this->emitPopPtr(RE))
4347 this->emitCleanup();
4348 return this->emitRetVoid(RS);
4353 this->emitCleanup();
4354 return this->emitRetVoid(RS);
4359 return visitStmt(IS->
getThen());
4363 if (
auto *CondInit = IS->
getInit())
4364 if (!visitStmt(CondInit))
4368 if (!visitDeclStmt(CondDecl))
4371 if (!this->visitBool(IS->
getCond()))
4375 LabelTy LabelElse = this->getLabel();
4376 LabelTy LabelEnd = this->getLabel();
4377 if (!this->jumpFalse(LabelElse))
4379 if (!visitStmt(IS->
getThen()))
4381 if (!this->jump(LabelEnd))
4383 this->emitLabel(LabelElse);
4384 if (!visitStmt(Else))
4386 this->emitLabel(LabelEnd);
4388 LabelTy LabelEnd = this->getLabel();
4389 if (!this->jumpFalse(LabelEnd))
4391 if (!visitStmt(IS->
getThen()))
4393 this->emitLabel(LabelEnd);
4399 template <
class Emitter>
4401 const Expr *Cond = S->getCond();
4402 const Stmt *Body = S->getBody();
4404 LabelTy CondLabel = this->getLabel();
4405 LabelTy EndLabel = this->getLabel();
4408 this->fallthrough(CondLabel);
4409 this->emitLabel(CondLabel);
4411 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
4412 if (!visitDeclStmt(CondDecl))
4415 if (!this->visitBool(Cond))
4417 if (!this->jumpFalse(EndLabel))
4420 if (!this->visitStmt(Body))
4423 if (!this->jump(CondLabel))
4425 this->fallthrough(EndLabel);
4426 this->emitLabel(EndLabel);
4432 const Expr *Cond = S->getCond();
4433 const Stmt *Body = S->getBody();
4435 LabelTy StartLabel = this->getLabel();
4436 LabelTy EndLabel = this->getLabel();
4437 LabelTy CondLabel = this->getLabel();
4440 this->fallthrough(StartLabel);
4441 this->emitLabel(StartLabel);
4443 if (!this->visitStmt(Body))
4445 this->fallthrough(CondLabel);
4446 this->emitLabel(CondLabel);
4447 if (!this->visitBool(Cond))
4450 if (!this->jumpTrue(StartLabel))
4453 this->fallthrough(EndLabel);
4454 this->emitLabel(EndLabel);
4458 template <
class Emitter>
4462 const Expr *Cond = S->getCond();
4463 const Expr *
Inc = S->getInc();
4464 const Stmt *Body = S->getBody();
4466 LabelTy EndLabel = this->getLabel();
4467 LabelTy CondLabel = this->getLabel();
4468 LabelTy IncLabel = this->getLabel();
4471 if (
Init && !this->visitStmt(
Init))
4474 this->fallthrough(CondLabel);
4475 this->emitLabel(CondLabel);
4477 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
4478 if (!visitDeclStmt(CondDecl))
4482 if (!this->visitBool(Cond))
4484 if (!this->jumpFalse(EndLabel))
4489 if (Body && !this->visitStmt(Body))
4492 this->fallthrough(IncLabel);
4493 this->emitLabel(IncLabel);
4494 if (
Inc && !this->discard(
Inc))
4498 if (!this->jump(CondLabel))
4500 this->fallthrough(EndLabel);
4501 this->emitLabel(EndLabel);
4505 template <
class Emitter>
4508 const Expr *Cond = S->getCond();
4509 const Expr *
Inc = S->getInc();
4510 const Stmt *Body = S->getBody();
4511 const Stmt *BeginStmt = S->getBeginStmt();
4512 const Stmt *RangeStmt = S->getRangeStmt();
4513 const Stmt *EndStmt = S->getEndStmt();
4514 const VarDecl *LoopVar = S->getLoopVariable();
4516 LabelTy EndLabel = this->getLabel();
4517 LabelTy CondLabel = this->getLabel();
4518 LabelTy IncLabel = this->getLabel();
4522 if (
Init && !this->visitStmt(
Init))
4524 if (!this->visitStmt(RangeStmt))
4526 if (!this->visitStmt(BeginStmt))
4528 if (!this->visitStmt(EndStmt))
4532 this->fallthrough(CondLabel);
4533 this->emitLabel(CondLabel);
4534 if (!this->visitBool(Cond))
4536 if (!this->jumpFalse(EndLabel))
4539 if (!this->visitVarDecl(LoopVar))
4544 if (!this->visitStmt(Body))
4547 this->fallthrough(IncLabel);
4548 this->emitLabel(IncLabel);
4549 if (!this->discard(
Inc))
4553 if (!this->jump(CondLabel))
4556 this->fallthrough(EndLabel);
4557 this->emitLabel(EndLabel);
4561 template <
class Emitter>
4566 this->emitCleanup();
4567 return this->jump(*BreakLabel);
4570 template <
class Emitter>
4575 this->emitCleanup();
4576 return this->jump(*ContinueLabel);
4579 template <
class Emitter>
4581 const Expr *Cond = S->getCond();
4584 LabelTy EndLabel = this->getLabel();
4586 unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT,
true,
false);
4588 if (
const auto *CondInit = S->getInit())
4589 if (!visitStmt(CondInit))
4592 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
4593 if (!visitDeclStmt(CondDecl))
4597 if (!this->visit(Cond))
4599 if (!this->emitSetLocal(CondT, CondVar, S))
4604 for (
const SwitchCase *SC = S->getSwitchCaseList(); SC;
4605 SC = SC->getNextSwitchCase()) {
4606 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
4608 if (CS->caseStmtIsGNURange())
4610 CaseLabels[SC] = this->getLabel();
4616 if (!this->emitGetLocal(CondT, CondVar, CS))
4618 if (!this->visit(
Value))
4622 if (!this->emitEQ(ValueT, S))
4624 if (!this->jumpTrue(CaseLabels[CS]))
4627 assert(!DefaultLabel);
4628 DefaultLabel = this->getLabel();
4635 if (!this->jump(*DefaultLabel))
4638 if (!this->jump(EndLabel))
4643 if (!this->visitStmt(S->getBody()))
4645 this->emitLabel(EndLabel);
4649 template <
class Emitter>
4651 this->emitLabel(CaseLabels[S]);
4652 return this->visitStmt(S->getSubStmt());
4655 template <
class Emitter>
4657 this->emitLabel(*DefaultLabel);
4658 return this->visitStmt(S->getSubStmt());
4661 template <
class Emitter>
4663 if (this->Ctx.getLangOpts().CXXAssumptions &&
4664 !this->Ctx.getLangOpts().MSVCCompat) {
4665 for (
const Attr *A : S->getAttrs()) {
4666 auto *AA = dyn_cast<CXXAssumeAttr>(A);
4670 assert(isa<NullStmt>(S->getSubStmt()));
4672 const Expr *Assumption = AA->getAssumption();
4680 if (!this->visitBool(Assumption))
4683 if (!this->emitAssume(Assumption))
4689 return this->visitStmt(S->getSubStmt());
4692 template <
class Emitter>
4695 return this->visitStmt(S->getTryBlock());
4698 template <
class Emitter>
4702 assert(cast<CompoundStmt>(MD->
getBody())->body_empty());
4707 const Function *
Func = this->getFunction(LambdaCallOp);
4710 assert(
Func->hasThisPointer());
4713 if (
Func->hasRVO()) {
4714 if (!this->emitRVOPtr(MD))
4722 if (!this->emitNullPtr(
nullptr, MD))
4727 auto It = this->Params.find(PVD);
4728 assert(It != this->Params.end());
4732 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
4733 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
4737 if (!this->emitCall(Func, 0, LambdaCallOp))
4740 this->emitCleanup();
4742 return this->emitRet(*ReturnType, MD);
4745 return this->emitRetVoid(MD);
4748 template <
class Emitter>
4750 if (Ctx.getLangOpts().CPlusPlus23)
4759 template <
class Emitter>
4761 assert(!ReturnType);
4763 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
4764 const Expr *InitExpr) ->
bool {
4766 if (InitExpr->getType().isNull())
4769 if (std::optional<PrimType>
T = this->classify(InitExpr)) {
4770 if (!this->visit(InitExpr))
4773 if (F->isBitField())
4774 return this->emitInitThisBitField(*
T, F, FieldOffset, InitExpr);
4775 return this->emitInitThisField(*
T, FieldOffset, InitExpr);
4780 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
4783 if (!this->visitInitializer(InitExpr))
4786 return this->emitFinishInitPop(InitExpr);
4790 const Record *R = this->getRecord(RD);
4796 assert(cast<CompoundStmt>(Ctor->
getBody())->body_empty());
4797 if (!this->emitThis(Ctor))
4806 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
4807 this->emitRetVoid(Ctor);
4811 for (
const auto *
Init : Ctor->
inits()) {
4815 const Expr *InitExpr =
Init->getInit();
4817 const Record::Field *F = R->
getField(Member);
4819 if (!emitFieldInitializer(F, F->Offset, InitExpr))
4822 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
4825 if (
Init->isBaseVirtual()) {
4827 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
4835 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
4839 if (!this->visitInitializer(InitExpr))
4841 if (!this->emitFinishInitPop(InitExpr))
4844 assert(IFD->getChainingSize() >= 2);
4846 unsigned NestedFieldOffset = 0;
4847 const Record::Field *NestedField =
nullptr;
4848 for (
const NamedDecl *ND : IFD->chain()) {
4849 const auto *FD = cast<FieldDecl>(ND);
4850 const Record *FieldRecord = this->
P.getOrCreateRecord(FD->getParent());
4851 assert(FieldRecord);
4853 NestedField = FieldRecord->
getField(FD);
4854 assert(NestedField);
4856 NestedFieldOffset += NestedField->Offset;
4858 assert(NestedField);
4860 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
4863 assert(
Init->isDelegatingInitializer());
4864 if (!this->emitThis(InitExpr))
4866 if (!this->visitInitializer(
Init->getInit()))
4868 if (!this->emitPopPtr(InitExpr))
4872 if (!
Scope.destroyLocals())
4876 if (
const auto *Body = Ctor->
getBody())
4877 if (!visitStmt(Body))
4883 template <
class Emitter>
4886 const Record *R = this->getRecord(RD);
4891 if (!this->visitStmt(Dtor->
getBody()))
4895 if (!this->emitThis(Dtor))
4901 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
4903 if (!
D->isPrimitive() && !
D->isPrimitiveArray()) {
4906 if (!this->emitDestruction(
D))
4917 if (!this->emitRecordDestruction(
Base.R))
4924 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
4927 template <
class Emitter>
4932 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
4933 return this->compileConstructor(Ctor);
4934 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
4935 return this->compileDestructor(Dtor);
4938 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F);
4940 return this->emitLambdaStaticInvokerBody(MD);
4943 if (
const auto *Body = F->
getBody())
4944 if (!visitStmt(Body))
4953 template <
class Emitter>
4955 const Expr *SubExpr =
E->getSubExpr();
4957 return this->VisitComplexUnaryOperator(
E);
4958 std::optional<PrimType>
T = classify(SubExpr->
getType());
4960 switch (
E->getOpcode()) {
4962 if (!Ctx.getLangOpts().CPlusPlus14)
4963 return this->emitInvalid(
E);
4965 return this->emitError(
E);
4967 if (!this->visit(SubExpr))
4971 if (!this->emitIncPtr(
E))
4974 return DiscardResult ? this->emitPopPtr(
E) :
true;
4978 return DiscardResult ? this->emitIncfPop(getRoundingMode(
E),
E)
4979 : this->emitIncf(getRoundingMode(
E),
E);
4982 return DiscardResult ? this->emitIncPop(*
T,
E) : this->emitInc(*
T,
E);
4985 if (!Ctx.getLangOpts().CPlusPlus14)
4986 return this->emitInvalid(
E);
4988 return this->emitError(
E);
4990 if (!this->visit(SubExpr))
4994 if (!this->emitDecPtr(
E))
4997 return DiscardResult ? this->emitPopPtr(
E) :
true;
5001 return DiscardResult ? this->emitDecfPop(getRoundingMode(
E),
E)
5002 : this->emitDecf(getRoundingMode(
E),
E);
5005 return DiscardResult ? this->emitDecPop(*
T,
E) : this->emitDec(*
T,
E);
5008 if (!Ctx.getLangOpts().CPlusPlus14)
5009 return this->emitInvalid(
E);
5011 return this->emitError(
E);
5013 if (!this->visit(SubExpr))
5017 if (!this->emitLoadPtr(
E))
5019 if (!this->emitConstUint8(1,
E))
5021 if (!this->emitAddOffsetUint8(
E))
5023 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5027 if (DiscardResult) {
5029 return this->emitIncfPop(getRoundingMode(
E),
E);
5030 return this->emitIncPop(*
T,
E);
5034 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5035 if (!this->emitLoadFloat(
E))
5039 if (!this->emitAddf(getRoundingMode(
E),
E))
5041 if (!this->emitStoreFloat(
E))
5045 if (!this->emitLoad(*
T,
E))
5047 if (!this->emitConst(1,
E))
5049 if (!this->emitAdd(*
T,
E))
5051 if (!this->emitStore(*
T,
E))
5057 if (!Ctx.getLangOpts().CPlusPlus14)
5058 return this->emitInvalid(
E);
5060 return this->emitError(
E);
5062 if (!this->visit(SubExpr))
5066 if (!this->emitLoadPtr(
E))
5068 if (!this->emitConstUint8(1,
E))
5070 if (!this->emitSubOffsetUint8(
E))
5072 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5076 if (DiscardResult) {
5078 return this->emitDecfPop(getRoundingMode(
E),
E);
5079 return this->emitDecPop(*
T,
E);
5083 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5084 if (!this->emitLoadFloat(
E))
5088 if (!this->emitSubf(getRoundingMode(
E),
E))
5090 if (!this->emitStoreFloat(
E))
5094 if (!this->emitLoad(*
T,
E))
5096 if (!this->emitConst(1,
E))
5098 if (!this->emitSub(*
T,
E))
5100 if (!this->emitStore(*
T,
E))
5107 return this->emitError(
E);
5110 return this->discard(SubExpr);
5112 if (!this->visitBool(SubExpr))
5115 if (!this->emitInv(
E))
5119 return this->emitCast(
PT_Bool, ET,
E);
5123 return this->emitError(
E);
5125 if (!this->visit(SubExpr))
5127 return DiscardResult ? this->emitPop(*
T,
E) : this->emitNeg(*
T,
E);
5130 return this->emitError(
E);
5132 if (!this->visit(SubExpr))
5134 return DiscardResult ? this->emitPop(*
T,
E) :
true;
5139 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(),
E);
5142 return this->delegate(SubExpr);
5145 return this->discard(SubExpr);
5146 return this->visit(SubExpr);
5149 return this->emitError(
E);
5151 if (!this->visit(SubExpr))
5153 return DiscardResult ? this->emitPop(*
T,
E) : this->emitComp(*
T,
E);
5156 return this->delegate(SubExpr);
5159 if (!this->discard(SubExpr))
5161 return this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
5164 return this->delegate(SubExpr);
5166 assert(
false &&
"Unhandled opcode");
5172 template <
class Emitter>
5174 const Expr *SubExpr =
E->getSubExpr();
5178 return this->discard(SubExpr);
5180 std::optional<PrimType> ResT = classify(
E);
5181 auto prepareResult = [=]() ->
bool {
5182 if (!ResT && !Initializing) {
5183 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5186 return this->emitGetPtrLocal(*LocalIndex,
E);
5193 unsigned SubExprOffset = ~0u;
5194 auto createTemp = [=, &SubExprOffset]() ->
bool {
5195 SubExprOffset = this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
5196 if (!this->visit(SubExpr))
5198 return this->emitSetLocal(
PT_Ptr, SubExprOffset,
E);
5202 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
5205 return this->emitArrayElemPop(ElemT, Index,
E);
5208 switch (
E->getOpcode()) {
5210 if (!prepareResult())
5214 for (
unsigned I = 0; I != 2; ++I) {
5215 if (!getElem(SubExprOffset, I))
5217 if (!this->emitNeg(ElemT,
E))
5219 if (!this->emitInitElem(ElemT, I,
E))
5227 return this->delegate(SubExpr);
5230 if (!this->visit(SubExpr))
5232 if (!this->emitComplexBoolCast(SubExpr))
5234 if (!this->emitInv(
E))
5237 return this->emitCast(
PT_Bool, ET,
E);
5241 return this->emitComplexReal(SubExpr);
5244 if (!this->visit(SubExpr))
5248 if (!this->emitConstUint8(1,
E))
5250 return this->emitArrayElemPtrPopUint8(
E);
5255 return this->emitArrayElemPop(classifyPrim(
E->
getType()), 1,
E);
5258 if (!this->visit(SubExpr))
5261 if (!this->emitArrayElem(ElemT, 1,
E))
5263 if (!this->emitNeg(ElemT,
E))
5265 if (!this->emitInitElem(ElemT, 1,
E))
5267 return DiscardResult ? this->emitPopPtr(
E) :
true;
5270 return this->delegate(SubExpr);
5273 return this->emitInvalid(
E);
5279 template <
class Emitter>
5284 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(
D)) {
5285 return this->emitConst(ECD->getInitVal(),
E);
5286 }
else if (
const auto *BD = dyn_cast<BindingDecl>(
D)) {
5287 return this->visit(BD->getBinding());
5288 }
else if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(
D)) {
5289 const Function *F = getFunction(FuncDecl);
5290 return F && this->emitGetFnPtr(F,
E);
5291 }
else if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(
D)) {
5292 if (std::optional<unsigned> Index =
P.getOrCreateGlobal(
D)) {
5293 if (!this->emitGetPtrGlobal(*Index,
E))
5295 if (std::optional<PrimType>
T = classify(
E->
getType())) {
5296 if (!this->visitAPValue(TPOD->getValue(), *
T,
E))
5298 return this->emitInitGlobal(*
T, *Index,
E);
5300 return this->visitAPValueInitializer(TPOD->getValue(),
E);
5309 bool IsReference =
D->getType()->isReferenceType();
5312 if (
auto It = Locals.find(
D); It != Locals.end()) {
5313 const unsigned Offset = It->second.Offset;
5316 return this->emitGetPtrLocal(
Offset,
E);
5317 }
else if (
auto GlobalIndex =
P.getGlobal(
D)) {
5319 if (!Ctx.getLangOpts().CPlusPlus11)
5320 return this->emitGetGlobal(classifyPrim(
E), *GlobalIndex,
E);
5321 return this->emitGetGlobalUnchecked(classifyPrim(
E), *GlobalIndex,
E);
5324 return this->emitGetPtrGlobal(*GlobalIndex,
E);
5325 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(
D)) {
5326 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
5327 if (IsReference || !It->second.IsPtr)
5328 return this->emitGetParam(classifyPrim(
E), It->second.Offset,
E);
5330 return this->emitGetPtrParam(It->second.Offset,
E);
5335 auto revisit = [&](
const VarDecl *VD) ->
bool {
5336 auto VarState = this->visitDecl(VD);
5338 if (VarState.notCreated())
5343 return this->visitDeclRef(
D,
E);
5347 if (
auto It = this->LambdaCaptures.find(
D);
5348 It != this->LambdaCaptures.end()) {
5349 auto [
Offset, IsPtr] = It->second;
5352 return this->emitGetThisFieldPtr(
Offset,
E);
5353 return this->emitGetPtrThisField(
Offset,
E);
5354 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E);
5355 DRE && DRE->refersToEnclosingVariableOrCapture()) {
5356 if (
const auto *VD = dyn_cast<VarDecl>(
D); VD && VD->isInitCapture())
5360 if (
D != InitializingDecl) {
5363 if (Ctx.getLangOpts().CPlusPlus) {
5364 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
5365 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
5366 if (
T.isConstant(Ctx.getASTContext()))
5369 return RT->getPointeeType().isConstQualified();
5374 if (isa<DecompositionDecl>(VD))
5378 if ((VD->hasGlobalStorage() || VD->isLocalVarDecl() ||
5379 VD->isStaticDataMember()) &&
5380 typeShouldBeVisited(VD->getType()))
5384 if (
const auto *VD = dyn_cast<VarDecl>(
D);
5385 VD && VD->getAnyInitializer() &&
5386 VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak())
5391 if (std::optional<unsigned> I =
P.getOrCreateDummy(
D)) {
5392 if (!this->emitGetPtrGlobal(*I,
E))
5399 return this->emitDecayPtr(
PT_Ptr, PT,
E);
5405 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E))
5406 return this->emitInvalidDeclRef(DRE,
E);
5410 template <
class Emitter>
5412 const auto *
D =
E->getDecl();
5413 return this->visitDeclRef(
D,
E);
5418 C->emitDestruction();
5421 template <
class Emitter>
5425 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
5427 return Ty->getAsCXXRecordDecl();
5429 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
5430 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
5432 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
5436 template <
class Emitter>
5443 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
5444 return this->emitCastFP(ToSem, getRoundingMode(
E),
E);
5448 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
E);
5450 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
E);
5454 return this->emitCastFloatingIntegral(ToT,
E);
5459 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT),
E);
5461 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT),
E);
5465 return FromT != ToT ? this->emitCast(FromT, ToT,
E) :
true;
5469 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
5470 return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(
E),
5479 template <
class Emitter>
5484 return this->discard(SubExpr);
5486 if (!this->visit(SubExpr))
5489 if (!this->emitConstUint8(0, SubExpr))
5491 return this->emitArrayElemPtrPopUint8(SubExpr);
5495 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
5499 template <
class Emitter>
5501 assert(!DiscardResult);
5505 if (!this->emitArrayElem(ElemT, 0,
E))
5508 if (!this->emitCastFloatingIntegral(
PT_Bool,
E))
5511 if (!this->emitCast(ElemT,
PT_Bool,
E))
5516 LabelTy LabelTrue = this->getLabel();
5517 if (!this->jumpTrue(LabelTrue))
5520 if (!this->emitArrayElemPop(ElemT, 1,
E))
5523 if (!this->emitCastFloatingIntegral(
PT_Bool,
E))
5526 if (!this->emitCast(ElemT,
PT_Bool,
E))
5530 LabelTy EndLabel = this->getLabel();
5531 this->jump(EndLabel);
5533 this->emitLabel(LabelTrue);
5534 if (!this->emitPopPtr(
E))
5536 if (!this->emitConstBool(
true,
E))
5539 this->fallthrough(EndLabel);
5540 this->emitLabel(EndLabel);
5545 template <
class Emitter>
5548 assert(
E->isComparisonOp());
5549 assert(!Initializing);
5550 assert(!DiscardResult);
5556 LHSIsComplex =
true;
5557 ElemT = classifyComplexElementType(LHS->
getType());
5558 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true,
5560 if (!this->visit(LHS))
5562 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
5565 LHSIsComplex =
false;
5567 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
5568 if (!this->visit(LHS))
5570 if (!this->emitSetLocal(LHST, LHSOffset,
E))
5577 RHSIsComplex =
true;
5578 ElemT = classifyComplexElementType(RHS->
getType());
5579 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true,
5581 if (!this->visit(RHS))
5583 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
5586 RHSIsComplex =
false;
5588 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
5589 if (!this->visit(RHS))
5591 if (!this->emitSetLocal(RHST, RHSOffset,
E))
5595 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
5596 bool IsComplex) ->
bool {
5598 if (!this->emitGetLocal(
PT_Ptr, LocalOffset,
E))
5600 return this->emitArrayElemPop(ElemT, Index,
E);
5602 return this->emitGetLocal(ElemT, LocalOffset,
E);
5605 for (
unsigned I = 0; I != 2; ++I) {
5607 if (!getElem(LHSOffset, I, LHSIsComplex))
5609 if (!getElem(RHSOffset, I, RHSIsComplex))
5612 if (!this->emitEQ(ElemT,
E))
5615 if (!this->emitCastBoolUint8(
E))
5620 if (!this->emitAddUint8(
E))
5622 if (!this->emitConstUint8(2,
E))
5625 if (
E->getOpcode() == BO_EQ) {
5626 if (!this->emitEQUint8(
E))
5628 }
else if (
E->getOpcode() == BO_NE) {
5629 if (!this->emitNEUint8(
E))
5636 return this->emitCast(
PT_Bool, ResT,
E);
5643 template <
class Emitter>
5651 const Function *DtorFunc = getFunction(Dtor);
5658 return this->emitCall(DtorFunc, 0,
SourceInfo{});
5663 template <
class Emitter>
5687 for (ssize_t I = Desc->
getNumElems() - 1; I >= 0; --I) {
5690 if (!this->emitArrayElemPtrUint64(
SourceInfo{}))
5692 if (!this->emitDestruction(ElemDesc))
5701 return this->emitRecordDestruction(Desc->
ElemRecord);
enum clang::sema::@1659::IndirectLocalPathEntry::EntryKind Kind
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
__DEVICE__ int min(int __a, int __b)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
ArrayRef< LValuePathEntry > getLValuePath() const
APValue & getUnionValue()
unsigned getStructNumFields() const
const ValueDecl * getMemberPointerDecl() const
APValue & getStructField(unsigned i)
bool isMemberPointer() const
const FieldDecl * getUnionField() const
APValue & getArrayInitializedElt(unsigned I)
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
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.
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 bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
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 a value-initialized rvalue of type T, which is a non-class type.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Represents the this expression in C++.
A C++ throw-expression (C++ [except.throw]).
CXXTryStmt - A C++ try block, including all handlers.
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
CharUnits - This is an opaque type for sizes expressed in character units.
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
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.
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
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.
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
QualType getReturnType() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isDefaulted() const
Whether this function is defaulted.
ArrayRef< ParmVarDecl * > parameters() const
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.
const ParmVarDecl * getParamDecl(unsigned i) const
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...
@ Ver7
Attempt to be ABI-compatible with code generated by Clang 7.0.x (SVN r338536).
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.
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 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 isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isMemberPointerType() const
bool isAtomicType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
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 * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
const Expr * getInit() const
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
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.
llvm::SmallVector< InitLink > InitStack
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 visitExpr(const Expr *E) override
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 VisitCastExpr(const CastExpr *E)
bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E)
bool VisitComplexUnaryOperator(const UnaryOperator *E)
llvm::DenseMap< const SwitchCase *, LabelTy > CaseMap
bool visitDeclStmt(const DeclStmt *DS)
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 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)
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
bool VisitCXXNewExpr(const CXXNewExpr *E)
const ValueDecl * InitializingDecl
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)
std::optional< unsigned > allocateLocal(DeclTy &&Decl, const ValueDecl *ExtendingDecl=nullptr)
Allocates a space storing a local given its type.
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 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)
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 VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
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 VisitBuiltinCallExpr(const CallExpr *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)
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.
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 Field * getField(const FieldDecl *FD) const
Returns a field.
llvm::iterator_range< const_base_iter > bases() const
llvm::iterator_range< const_field_iter > fields() const
const CXXDestructorDecl * getDestructor() const
Returns the destructor of the record, if any.
const Base * getVirtualBase(const RecordDecl *RD) const
Returns a virtual base descriptor.
unsigned getNumFields() 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.
bool LT(InterpState &S, CodePtr OpPC)
constexpr bool isPtrType(PrimType T)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
unsigned llvm::PointerUnion< const Decl *, const Expr * > DeclTy
bool InitScope(InterpState &S, CodePtr OpPC, uint32_t I)
bool Inc(InterpState &S, CodePtr OpPC)
1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...
bool LE(InterpState &S, CodePtr OpPC)
PrimType
Enumeration of the primitive types of the VM.
bool Init(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.
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
Describes a memory block created by an allocation site.
unsigned getNumElems() const
Returns the number of elements stored in the block.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
const Descriptor *const ElemDesc
Descriptor of the array element.
static constexpr MetadataSize InlineDescMD
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
const Record *const ElemRecord
Pointer to the record, if block contains records.
bool isArray() const
Checks if the descriptor is of an array.
Descriptor used for global variables.
GlobalInitState InitState
static InitLink Elem(unsigned Index)
bool emit(Compiler< Emitter > *Ctx, const Expr *E) const
static InitLink Field(unsigned Offset)
static InitLink Decl(const ValueDecl *D)
static InitLink Temp(unsigned Offset)
Information about a local's storage.
State encapsulating if a the variable creation has been successful, unsuccessful, or no variable has ...
static VarCreationState NotCreated()