;
33OldInitializingDecl(
Ctx->InitializingDecl) {
34 Ctx->InitializingDecl = VD;
43this->
Ctx->InitializingDecl = OldInitializingDecl;
44this->
Ctx->InitStack.pop_back();
58: Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
60Ctx->DiscardResult = NewDiscardResult;
61Ctx->Initializing = NewInitializing;
65Ctx->DiscardResult = OldDiscardResult;
66Ctx->Initializing = OldInitializing;
73 boolOldDiscardResult;
77template<
classEmitter>
81 returnCtx->emitThis(
E);
84 returnCtx->emitGetPtrFieldPop(
Offset,
E);
86 returnCtx->emitGetPtrLocal(
Offset,
E);
88 returnCtx->visitDeclRef(
D,
E);
90 if(!Ctx->emitConstUint32(
Offset,
E))
92 returnCtx->emitArrayElemPtrPopUint32(
E);
94 returnCtx->emitRVOPtr(
E);
98llvm_unreachable(
"Unhandled InitLink kind");
122OldContinueLabel(
Ctx->ContinueLabel),
123OldBreakVarScope(
Ctx->BreakVarScope),
124OldContinueVarScope(
Ctx->ContinueVarScope) {
132this->
Ctx->BreakLabel = OldBreakLabel;
133this->
Ctx->ContinueLabel = OldContinueLabel;
134this->
Ctx->ContinueVarScope = OldContinueVarScope;
135this->
Ctx->BreakVarScope = OldBreakVarScope;
155OldDefaultLabel(this->
Ctx->DefaultLabel),
156OldCaseLabels(
std::move(this->
Ctx->CaseLabels)),
157OldLabelVarScope(
Ctx->BreakVarScope) {
160this->Ctx->
CaseLabels= std::move(CaseLabels);
165this->
Ctx->BreakLabel = OldBreakLabel;
166this->
Ctx->DefaultLabel = OldDefaultLabel;
167this->
Ctx->CaseLabels = std::move(OldCaseLabels);
168this->
Ctx->BreakVarScope = OldLabelVarScope;
181Ctx->InStmtExpr =
true;
194template<
classEmitter>
199 caseCK_LValueToRValue: {
201 returnthis->discard(SubExpr);
203std::optional<PrimType> SubExprT = classify(SubExpr->
getType());
206std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
209 if(!this->emitGetPtrLocal(*LocalIndex, CE))
213 if(!this->visit(SubExpr))
217 returnthis->emitLoadPop(*SubExprT, CE);
222 returnthis->emitMemcpy(CE);
225 caseCK_DerivedToBaseMemberPointer: {
231 unsignedDerivedOffset = collectBaseOffset(
QualType(ToMP->
getClass(), 0),
234 if(!this->delegate(SubExpr))
237 returnthis->emitGetMemberPtrBasePop(DerivedOffset, CE);
240 caseCK_BaseToDerivedMemberPointer: {
246 unsignedDerivedOffset = collectBaseOffset(
QualType(FromMP->getClass(), 0),
249 if(!this->delegate(SubExpr))
251 returnthis->emitGetMemberPtrBasePop(-DerivedOffset, CE);
254 caseCK_UncheckedDerivedToBase:
255 caseCK_DerivedToBase: {
257 returnthis->discard(SubExpr);
259 if(!this->delegate(SubExpr))
263 if(
const auto*PT = dyn_cast<PointerType>(Ty))
264 returnPT->getPointeeType()->getAsCXXRecordDecl();
265 returnTy->getAsCXXRecordDecl();
272 if(B->isVirtual()) {
273 if(!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))
275CurType = B->getType();
277 unsignedDerivedOffset = collectBaseOffset(B->getType(), CurType);
278 if(!this->emitGetPtrBasePop(DerivedOffset, CE))
280CurType = B->getType();
287 caseCK_BaseToDerived: {
289 returnthis->discard(SubExpr);
291 if(!this->delegate(SubExpr))
294 unsignedDerivedOffset =
297 returnthis->emitGetPtrDerivedPop(DerivedOffset, CE);
300 caseCK_FloatingCast: {
306 returnthis->discard(SubExpr);
307 if(!this->visit(SubExpr))
309 const auto*TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
313 caseCK_IntegralToFloating: {
315 returnthis->discard(SubExpr);
316std::optional<PrimType> FromT = classify(SubExpr->
getType());
320 if(!this->visit(SubExpr))
323 const auto*TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
324 returnthis->emitCastIntegralFloating(*FromT, TargetSemantics,
325getFPOptions(CE), CE);
328 caseCK_FloatingToBoolean:
329 caseCK_FloatingToIntegral: {
331 returnthis->discard(SubExpr);
333std::optional<PrimType> ToT = classify(CE->
getType());
338 if(!this->visit(SubExpr))
342 returnthis->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->
getType()),
343getFPOptions(CE), CE);
345 returnthis->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->
getType()),
346getFPOptions(CE), CE);
348 returnthis->emitCastFloatingIntegral(*ToT, getFPOptions(CE), CE);
351 caseCK_NullToPointer:
352 caseCK_NullToMemberPointer: {
353 if(!this->discard(SubExpr))
360 if(!PointeeType.
isNull()) {
361 if(std::optional<PrimType>
T= classify(PointeeType))
362Desc =
P.createDescriptor(SubExpr, *
T);
364Desc =
P.createDescriptor(SubExpr, PointeeType.
getTypePtr(),
365std::nullopt,
true,
false,
370 returnthis->emitNull(classifyPrim(CE->
getType()), Val, Desc, CE);
373 caseCK_PointerToIntegral: {
375 returnthis->discard(SubExpr);
377 if(!this->visit(SubExpr))
383 if(!this->emitDecayPtr(FromT,
PT_Ptr, CE))
389 returnthis->emitCastPointerIntegralAP(Ctx.getBitWidth(CE->
getType()),
392 returnthis->emitCastPointerIntegralAPS(Ctx.getBitWidth(CE->
getType()),
394 returnthis->emitCastPointerIntegral(
T, CE);
397 caseCK_ArrayToPointerDecay: {
398 if(!this->visit(SubExpr))
400 if(!this->emitArrayDecay(CE))
403 returnthis->emitPopPtr(CE);
407 caseCK_IntegralToPointer: {
410 if(!this->visit(SubExpr))
416 returnthis->emitPop(
T, CE);
421Desc =
P.createDescriptor(SubExpr, *
T);
429 if(!this->emitGetIntPtr(
T, Desc, CE))
432 PrimTypeDestPtrT = classifyPrim(PtrType);
437 returnthis->emitDecayPtr(
PT_Ptr, DestPtrT, CE);
440 caseCK_AtomicToNonAtomic:
441 caseCK_ConstructorConversion:
442 caseCK_FunctionToPointerDecay:
443 caseCK_NonAtomicToAtomic:
445 caseCK_UserDefinedConversion:
446 caseCK_AddressSpaceConversion:
447 caseCK_CPointerToObjCPointerCast:
448 returnthis->delegate(SubExpr);
453 if(!this->discard(SubExpr))
455 returnthis->emitInvalidCast(CastKind::Reinterpret,
true, CE);
459 returnthis->discard(SubExpr);
462std::optional<PrimType> FromT = classify(SubExprTy);
465 returnthis->emitBuiltinBitCast(CE);
467std::optional<PrimType> ToT = classify(CE->
getType());
475 returnthis->delegate(SubExpr);
477 if(!this->visit(SubExpr))
484 if(!this->visit(SubExpr))
486 returnthis->emitDecayPtr(*FromT, *ToT, CE);
489 caseCK_LValueToRValueBitCast:
490 returnthis->emitBuiltinBitCast(CE);
492 caseCK_IntegralToBoolean:
493 caseCK_FixedPointToBoolean:
494 caseCK_BooleanToSignedIntegral:
495 caseCK_IntegralCast: {
497 returnthis->discard(SubExpr);
498std::optional<PrimType> FromT = classify(SubExpr->
getType());
499std::optional<PrimType> ToT = classify(CE->
getType());
504 if(!this->visit(SubExpr))
512 if(!this->emitCheckEnumValue(*FromT, ET->getDecl(), CE))
517 automaybeNegate = [&]() ->
bool{
518 if(CE->
getCastKind() == CK_BooleanToSignedIntegral)
519 returnthis->emitNeg(*ToT, CE);
524 returnthis->emitCastAP(*FromT, Ctx.getBitWidth(CE->
getType()), CE) &&
527 returnthis->emitCastAPS(*FromT, Ctx.getBitWidth(CE->
getType()), CE) &&
532 if(!this->emitCast(*FromT, *ToT, CE))
535 returnmaybeNegate();
538 caseCK_PointerToBoolean:
539 caseCK_MemberPointerToBoolean: {
542 if(!this->visit(SubExpr))
544 returnthis->emitIsNonNull(PtrT, CE);
547 caseCK_IntegralComplexToBoolean:
548 caseCK_FloatingComplexToBoolean: {
550 returnthis->discard(SubExpr);
551 if(!this->visit(SubExpr))
553 returnthis->emitComplexBoolCast(SubExpr);
556 caseCK_IntegralComplexToReal:
557 caseCK_FloatingComplexToReal:
558 returnthis->emitComplexReal(SubExpr);
560 caseCK_IntegralRealToComplex:
561 caseCK_FloatingRealToComplex: {
565std::optional<unsigned> LocalIndex = allocateTemporary(CE);
568 if(!this->emitGetPtrLocal(*LocalIndex, CE))
573 if(!this->visitArrayElemInit(0, SubExpr))
577 if(!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
579 returnthis->emitInitElem(
T, 1, SubExpr);
582 caseCK_IntegralComplexCast:
583 caseCK_FloatingComplexCast:
584 caseCK_IntegralComplexToFloatingComplex:
585 caseCK_FloatingComplexToIntegralComplex: {
589 returnthis->discard(SubExpr);
592std::optional<unsigned> LocalIndex = allocateLocal(CE);
595 if(!this->emitGetPtrLocal(*LocalIndex, CE))
602 unsignedSubExprOffset = allocateLocalPrimitive(
603SubExpr,
PT_Ptr,
true,
false);
604 if(!this->visit(SubExpr))
606 if(!this->emitSetLocal(
PT_Ptr, SubExprOffset, CE))
609 PrimTypeSourceElemT = classifyComplexElementType(SubExpr->
getType());
612 PrimTypeDestElemT = classifyPrim(DestElemType);
614 for(
unsignedI = 0; I != 2; ++I) {
615 if(!this->emitGetLocal(
PT_Ptr, SubExprOffset, CE))
617 if(!this->emitArrayElemPop(SourceElemT, I, CE))
621 if(!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
625 if(!this->emitInitElem(DestElemT, I, CE))
631 caseCK_VectorSplat: {
632assert(!classify(CE->
getType()));
633assert(classify(SubExpr->
getType()));
637 returnthis->discard(SubExpr);
640std::optional<unsigned> LocalIndex = allocateLocal(CE);
643 if(!this->emitGetPtrLocal(*LocalIndex, CE))
649 unsignedElemOffset = allocateLocalPrimitive(
650SubExpr, ElemT,
true,
false);
653 if(!this->visit(SubExpr))
655 if(classifyPrim(SubExpr) ==
PT_Ptr&& !this->emitLoadPop(ElemT, CE))
658 if(!this->emitSetLocal(ElemT, ElemOffset, CE))
661 for(
unsignedI = 0; I != VT->getNumElements(); ++I) {
662 if(!this->emitGetLocal(ElemT, ElemOffset, CE))
664 if(!this->emitInitElem(ElemT, I, CE))
671 caseCK_HLSLVectorTruncation: {
673 if(std::optional<PrimType> ResultT = classify(CE)) {
674assert(!DiscardResult);
676 if(!this->visit(SubExpr))
678 returnthis->emitArrayElemPop(*ResultT, 0, CE);
684std::optional<unsigned> LocalIndex = allocateTemporary(CE);
687 if(!this->emitGetPtrLocal(*LocalIndex, CE))
692 if(!this->visit(SubExpr))
694 returnthis->emitCopyArray(classifyVectorElementType(CE->
getType()), 0, 0,
698 caseCK_IntegralToFixedPoint: {
699 if(!this->visit(SubExpr))
704 returnthis->emitCastIntegralFixedPoint(classifyPrim(SubExpr->
getType()),
707 caseCK_FloatingToFixedPoint: {
708 if(!this->visit(SubExpr))
713 returnthis->emitCastFloatingFixedPoint(Sem, CE);
715 caseCK_FixedPointToFloating: {
716 if(!this->visit(SubExpr))
718 const auto*TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
719 returnthis->emitCastFixedPointFloating(TargetSemantics, CE);
721 caseCK_FixedPointToIntegral: {
722 if(!this->visit(SubExpr))
724 returnthis->emitCastFixedPointIntegral(classifyPrim(CE->
getType()), CE);
726 caseCK_FixedPointCast: {
727 if(!this->visit(SubExpr))
731 returnthis->emitCastFixedPoint(Sem, CE);
735 returndiscard(SubExpr);
738 returnthis->emitInvalid(CE);
740llvm_unreachable(
"Unhandled clang::CastKind enum");
743template<
classEmitter>
748 returnthis->emitConst(
LE->getValue(),
LE);
751template<
classEmitter>
756 returnthis->emitConstFloat(
E->getValue(),
E);
759template<
classEmitter>
766std::optional<unsigned> LocalIndex = allocateTemporary(
E);
769 if(!this->emitGetPtrLocal(*LocalIndex,
E))
773 const Expr*SubExpr =
E->getSubExpr();
776 if(!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
778 if(!this->emitInitElem(SubExprT, 0, SubExpr))
780 returnthis->visitArrayElemInit(1, SubExpr);
783template<
classEmitter>
796template<
classEmitter>
798 returnthis->delegate(
E->getSubExpr());
801template<
classEmitter>
805 returnthis->VisitLogicalBinOp(BO);
813 if(!this->discard(LHS))
816 returnthis->discard(RHS);
818 returnthis->delegate(RHS);
822 returnthis->VisitComplexBinOp(BO);
824 returnthis->VisitVectorBinOp(BO);
828 returnthis->emitComplexComparison(LHS, RHS, BO);
830 returnthis->VisitFixedPointBinOp(BO);
833 if(!this->visit(LHS))
836 if(!this->visit(RHS))
839 if(!this->emitToMemberPtr(BO))
845 if(!this->emitCastMemberPtrPtr(BO))
847 returnDiscardResult ? this->emitPopPtr(BO) :
true;
851std::optional<PrimType>
LT= classify(LHS);
852std::optional<PrimType> RT = classify(RHS);
853std::optional<PrimType>
T= classify(BO->
getType());
867std::optional<unsigned> ResultIndex = this->allocateLocal(BO);
868 if(!this->emitGetPtrLocal(*ResultIndex, BO))
872 if(!visit(LHS) || !visit(RHS))
875 returnthis->emitCMP3(*
LT, CmpInfo, BO);
878 if(!
LT|| !RT || !
T)
884 returnthis->VisitPointerArithBinOp(BO);
889 if(!visit(RHS) || !visit(LHS))
891 if(!this->emitFlip(*
LT, *RT, BO))
894 if(!visit(LHS) || !visit(RHS))
900 autoMaybeCastToBool = [
this,
T, BO](
boolResult) {
904 returnthis->emitPop(*
T, BO);
906 returnthis->emitCast(
PT_Bool, *
T, BO);
910 autoDiscard = [
this,
T, BO](
boolResult) {
913 returnDiscardResult ? this->emitPop(*
T, BO) :
true;
918 returnMaybeCastToBool(this->emitEQ(*
LT, BO));
920 returnMaybeCastToBool(this->emitNE(*
LT, BO));
922 returnMaybeCastToBool(this->emitLT(*
LT, BO));
924 returnMaybeCastToBool(this->emitLE(*
LT, BO));
926 returnMaybeCastToBool(this->emitGT(*
LT, BO));
928 returnMaybeCastToBool(this->emitGE(*
LT, BO));
931 returnDiscard(this->emitSubf(getFPOptions(BO), BO));
932 returnDiscard(this->emitSub(*
T, BO));
935 returnDiscard(this->emitAddf(getFPOptions(BO), BO));
936 returnDiscard(this->emitAdd(*
T, BO));
939 returnDiscard(this->emitMulf(getFPOptions(BO), BO));
940 returnDiscard(this->emitMul(*
T, BO));
942 returnDiscard(this->emitRem(*
T, BO));
945 returnDiscard(this->emitDivf(getFPOptions(BO), BO));
946 returnDiscard(this->emitDiv(*
T, BO));
950: this->emitStorePop(*
T, BO);
952 if(!this->emitStoreBitField(*
T, BO))
955 if(!this->emitStore(*
T, BO))
961 returnthis->emitLoadPop(*
T, BO);
964 returnDiscard(this->emitBitAnd(*
T, BO));
966 returnDiscard(this->emitBitOr(*
T, BO));
968 returnDiscard(this->emitShl(*
LT, *RT, BO));
970 returnDiscard(this->emitShr(*
LT, *RT, BO));
972 returnDiscard(this->emitBitXor(*
T, BO));
975llvm_unreachable(
"Already handled earlier");
980llvm_unreachable(
"Unhandled binary op");
985template<
classEmitter>
988 const Expr*LHS =
E->getLHS();
989 const Expr*RHS =
E->getRHS();
991 if((Op != BO_Add && Op != BO_Sub) ||
995std::optional<PrimType>
LT= classify(LHS);
996std::optional<PrimType> RT = classify(RHS);
1002 autovisitAsPointer = [&](
const Expr*
E,
PrimType T) ->
bool{
1003 if(!this->visit(
E))
1006 returnthis->emitDecayPtr(
T,
PT_Ptr,
E);
1015 if(!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *
LT))
1019 if(!this->emitSubPtr(IntT,
E))
1021 returnDiscardResult ? this->emitPop(IntT,
E) :
true;
1026 if(!visitAsPointer(RHS, *RT))
1028 if(!this->visit(LHS))
1032 if(!visitAsPointer(LHS, *
LT))
1034 if(!this->visit(RHS))
1044 if(!this->emitAddOffset(OffsetType,
E))
1047 if(classifyPrim(
E) !=
PT_Ptr)
1048 returnthis->emitDecayPtr(
PT_Ptr, classifyPrim(
E),
E);
1050}
else if(Op == BO_Sub) {
1051 if(!this->emitSubOffset(OffsetType,
E))
1054 if(classifyPrim(
E) !=
PT_Ptr)
1055 returnthis->emitDecayPtr(
PT_Ptr, classifyPrim(
E),
E);
1062template<
classEmitter>
1064assert(
E->isLogicalOp());
1066 const Expr*LHS =
E->getLHS();
1067 const Expr*RHS =
E->getRHS();
1068std::optional<PrimType>
T= classify(
E->
getType());
1072 LabelTyLabelTrue = this->getLabel();
1073 LabelTyLabelEnd = this->getLabel();
1075 if(!this->visitBool(LHS))
1077 if(!this->jumpTrue(LabelTrue))
1080 if(!this->visitBool(RHS))
1082 if(!this->jump(LabelEnd))
1085this->emitLabel(LabelTrue);
1086this->emitConstBool(
true,
E);
1087this->fallthrough(LabelEnd);
1088this->emitLabel(LabelEnd);
1091assert(Op == BO_LAnd);
1094 LabelTyLabelFalse = this->getLabel();
1095 LabelTyLabelEnd = this->getLabel();
1097 if(!this->visitBool(LHS))
1099 if(!this->jumpFalse(LabelFalse))
1102 if(!this->visitBool(RHS))
1104 if(!this->jump(LabelEnd))
1107this->emitLabel(LabelFalse);
1108this->emitConstBool(
false,
E);
1109this->fallthrough(LabelEnd);
1110this->emitLabel(LabelEnd);
1114 returnthis->emitPopBool(
E);
1119 returnthis->emitCast(
PT_Bool, *
T,
E);
1123template<
classEmitter>
1127std::optional<unsigned> LocalIndex = allocateTemporary(
E);
1130 if(!this->emitGetPtrLocal(*LocalIndex,
E))
1136 const Expr*LHS =
E->getLHS();
1137 const Expr*RHS =
E->getRHS();
1140 unsignedResultOffset = ~0u;
1142ResultOffset = this->allocateLocalPrimitive(
E,
PT_Ptr,
true,
false);
1145 if(!this->DiscardResult) {
1146 if(!this->emitDupPtr(
E))
1148 if(!this->emitSetLocal(
PT_Ptr, ResultOffset,
E))
1153LHSType = AT->getValueType();
1156RHSType = AT->getValueType();
1165 if(Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1170 if(!this->visit(LHS))
1172 if(!this->visit(RHS))
1174 returnthis->emitMulc(ElemT,
E);
1177 if(Op == BO_Div && RHSIsComplex) {
1179 PrimTypeElemT = classifyPrim(ElemQT);
1184 if(!LHSIsComplex) {
1186std::optional<unsigned> LocalIndex = allocateTemporary(RHS);
1189LHSOffset = *LocalIndex;
1191 if(!this->emitGetPtrLocal(LHSOffset,
E))
1194 if(!this->visit(LHS))
1197 if(!this->emitInitElem(ElemT, 0,
E))
1200 if(!this->visitZeroInitializer(ElemT, ElemQT,
E))
1202 if(!this->emitInitElem(ElemT, 1,
E))
1205 if(!this->visit(LHS))
1209 if(!this->visit(RHS))
1211 returnthis->emitDivc(ElemT,
E);
1216LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
1217 if(!this->visit(LHS))
1219 if(!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1222 PrimTypeLHST = classifyPrim(LHSType);
1223LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
1224 if(!this->visit(LHS))
1226 if(!this->emitSetLocal(LHST, LHSOffset,
E))
1233RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
1234 if(!this->visit(RHS))
1236 if(!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1239 PrimTypeRHST = classifyPrim(RHSType);
1240RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
1241 if(!this->visit(RHS))
1243 if(!this->emitSetLocal(RHST, RHSOffset,
E))
1250 autoloadComplexValue = [
this](
boolIsComplex,
boolLoadZero,
1251 unsignedElemIndex,
unsignedOffset,
1252 const Expr*
E) ->
bool{
1254 if(!this->emitGetLocal(
PT_Ptr, Offset,
E))
1256 returnthis->emitArrayElemPop(classifyComplexElementType(
E->
getType()),
1259 if(ElemIndex == 0 || !LoadZero)
1260 returnthis->emitGetLocal(classifyPrim(
E->
getType()), Offset,
E);
1261 returnthis->visitZeroInitializer(classifyPrim(
E->
getType()),
E->
getType(),
1266 for(
unsignedElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1268 if(!this->DiscardResult) {
1269 if(!this->emitGetLocal(
PT_Ptr, ResultOffset,
E))
1276 if(!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1279 if(!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1282 if(!this->emitAddf(getFPOptions(
E),
E))
1285 if(!this->emitAdd(ResultElemT,
E))
1290 if(!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1293 if(!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1296 if(!this->emitSubf(getFPOptions(
E),
E))
1299 if(!this->emitSub(ResultElemT,
E))
1304 if(!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1307 if(!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1311 if(!this->emitMulf(getFPOptions(
E),
E))
1314 if(!this->emitMul(ResultElemT,
E))
1319assert(!RHSIsComplex);
1320 if(!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1323 if(!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1327 if(!this->emitDivf(getFPOptions(
E),
E))
1330 if(!this->emitDiv(ResultElemT,
E))
1339 if(!this->DiscardResult) {
1341 if(!this->emitInitElemPop(ResultElemT, ElemIndex,
E))
1344 if(!this->emitPop(ResultElemT,
E))
1351template<
classEmitter>
1353assert(!
E->isCommaOp() &&
1354 "Comma op should be handled in VisitBinaryOperator");
1361std::optional<unsigned> LocalIndex = allocateTemporary(
E);
1364 if(!this->emitGetPtrLocal(*LocalIndex,
E))
1368 const Expr*LHS =
E->getLHS();
1369 const Expr*RHS =
E->getRHS();
1371 autoOp =
E->isCompoundAssignmentOp()
1376 PrimTypeRHSElemT = this->classifyVectorElementType(RHS->
getType());
1380 unsignedLHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
1381 if(!this->visit(LHS))
1383 if(!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1387 unsignedRHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
1388 if(!this->visit(RHS))
1390 if(!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1393 if(
E->isCompoundAssignmentOp() && !this->emitGetLocal(
PT_Ptr, LHSOffset,
E))
1398 boolNeedIntPromot = ElemT ==
PT_Bool&& (
E->isBitwiseOp() ||
E->isShiftOp());
1401 PrimTypePromotT = classifyPrim(PromotTy);
1402 PrimTypeOpT = NeedIntPromot ? PromotT : ElemT;
1404 autogetElem = [=](
unsignedOffset,
PrimTypeElemT,
unsignedIndex) {
1405 if(!this->emitGetLocal(
PT_Ptr, Offset,
E))
1407 if(!this->emitArrayElemPop(ElemT, Index,
E))
1409 if(
E->isLogicalOp()) {
1410 if(!this->emitPrimCast(ElemT,
PT_Bool, Ctx.getASTContext().
BoolTy,
E))
1412 if(!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(),
E))
1414}
else if(NeedIntPromot) {
1415 if(!this->emitPrimCast(ElemT, PromotT, PromotTy,
E))
1421#define EMIT_ARITH_OP(OP) \ 1423 if (ElemT == PT_Float) { \ 1424 if (!this->emit##OP##f(getFPOptions(E), E)) \ 1427 if (!this->emit##OP(ElemT, E)) \ 1433 for(
unsignedI = 0; I != VecTy->getNumElements(); ++I) {
1434 if(!getElem(LHSOffset, ElemT, I))
1436 if(!getElem(RHSOffset, RHSElemT, I))
1448 if(!this->emitRem(ElemT,
E))
1452 if(!this->emitBitAnd(OpT,
E))
1456 if(!this->emitBitOr(OpT,
E))
1460 if(!this->emitBitXor(OpT,
E))
1464 if(!this->emitShl(OpT, RHSElemT,
E))
1468 if(!this->emitShr(OpT, RHSElemT,
E))
1472 if(!this->emitEQ(ElemT,
E))
1476 if(!this->emitNE(ElemT,
E))
1480 if(!this->emitLE(ElemT,
E))
1484 if(!this->emitLT(ElemT,
E))
1488 if(!this->emitGE(ElemT,
E))
1492 if(!this->emitGT(ElemT,
E))
1497 if(!this->emitBitAnd(ResultElemT,
E))
1502 if(!this->emitBitOr(ResultElemT,
E))
1506 returnthis->emitInvalid(
E);
1514 if(
E->isComparisonOp()) {
1515 if(!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(),
E))
1517 if(!this->emitNeg(ResultElemT,
E))
1523 if(NeedIntPromot &&
1524!this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(),
E))
1528 if(!this->emitInitElem(ResultElemT, I,
E))
1532 if(DiscardResult &&
E->isCompoundAssignmentOp() && !this->emitPopPtr(
E))
1537template<
classEmitter>
1539 const Expr*LHS =
E->getLHS();
1540 const Expr*RHS =
E->getRHS();
1541 const ASTContext&ASTCtx = Ctx.getASTContext();
1547 autoLHSSemaInt = LHSSema.toOpaqueInt();
1549 autoRHSSemaInt = RHSSema.toOpaqueInt();
1551 if(!this->visit(LHS))
1554 if(!this->emitCastIntegralFixedPoint(classifyPrim(LHS->
getType()),
1559 if(!this->visit(RHS))
1562 if(!this->emitCastIntegralFixedPoint(classifyPrim(RHS->
getType()),
1568 autoConvertResult = [&](
boolR) ->
bool{
1572 autoCommonSema = LHSSema.getCommonSemantics(RHSSema).toOpaqueInt();
1573 if(ResultSema != CommonSema)
1574 returnthis->emitCastFixedPoint(ResultSema,
E);
1578 autoMaybeCastToBool = [&](
boolResult) {
1583 returnthis->emitPop(
T,
E);
1585 returnthis->emitCast(
PT_Bool,
T,
E);
1589 switch(
E->getOpcode()) {
1591 returnMaybeCastToBool(this->emitEQFixedPoint(
E));
1593 returnMaybeCastToBool(this->emitNEFixedPoint(
E));
1595 returnMaybeCastToBool(this->emitLTFixedPoint(
E));
1597 returnMaybeCastToBool(this->emitLEFixedPoint(
E));
1599 returnMaybeCastToBool(this->emitGTFixedPoint(
E));
1601 returnMaybeCastToBool(this->emitGEFixedPoint(
E));
1603 returnConvertResult(this->emitAddFixedPoint(
E));
1605 returnConvertResult(this->emitSubFixedPoint(
E));
1607 returnConvertResult(this->emitMulFixedPoint(
E));
1609 returnConvertResult(this->emitDivFixedPoint(
E));
1611 returnConvertResult(this->emitShiftFixedPoint(
true,
E));
1613 returnConvertResult(this->emitShiftFixedPoint(
false,
E));
1616 returnthis->emitInvalid(
E);
1619llvm_unreachable(
"unhandled binop opcode");
1622template<
classEmitter>
1624 const Expr*SubExpr =
E->getSubExpr();
1627 switch(
E->getOpcode()) {
1629 returnthis->delegate(SubExpr);
1631 if(!this->visit(SubExpr))
1633 returnthis->emitNegFixedPoint(
E);
1638llvm_unreachable(
"Unhandled unary opcode");
1641template<
classEmitter>
1646 if(std::optional<PrimType>
T= classify(QT))
1647 returnthis->visitZeroInitializer(*
T, QT,
E);
1655 if(
const auto*CXXRD = dyn_cast<CXXRecordDecl>(RD);
1656CXXRD && CXXRD->getNumVBases() > 0) {
1661 const Record*R = getRecord(QT);
1666 returnthis->visitZeroRecordInitializer(R,
E);
1673 returnthis->visitZeroArrayInitializer(QT,
E);
1677 QualTypeElemQT = ComplexTy->getElementType();
1678 PrimTypeElemT = classifyPrim(ElemQT);
1679 for(
unsignedI = 0; I < 2; ++I) {
1680 if(!this->visitZeroInitializer(ElemT, ElemQT,
E))
1682 if(!this->emitInitElem(ElemT, I,
E))
1689 unsignedNumVecElements = VecT->getNumElements();
1690 QualTypeElemQT = VecT->getElementType();
1691 PrimTypeElemT = classifyPrim(ElemQT);
1693 for(
unsignedI = 0; I < NumVecElements; ++I) {
1694 if(!this->visitZeroInitializer(ElemT, ElemQT,
E))
1696 if(!this->emitInitElem(ElemT, I,
E))
1705template<
classEmitter>
1707 const Expr*LHS =
E->getLHS();
1708 const Expr*RHS =
E->getRHS();
1709 const Expr*Index =
E->getIdx();
1712 returnthis->discard(LHS) && this->discard(RHS);
1717 for(
const Expr*SubExpr : {LHS, RHS}) {
1718 if(!this->visit(SubExpr))
1725 PrimTypeIndexT = classifyPrim(Index->getType());
1728 if(!this->emitFlip(
PT_Ptr, IndexT,
E))
1732 returnthis->emitArrayElemPtrPop(IndexT,
E);
1735template<
classEmitter>
1737 const Expr*ArrayFiller,
const Expr*
E) {
1742QT = AT->getValueType();
1745 if(Inits.size() == 0)
1747 returnthis->emitInvalid(
E);
1751 if(DiscardResult) {
1753 if(!this->discard(
Init))
1760 if(std::optional<PrimType>
T= classify(QT)) {
1761assert(!DiscardResult);
1762 if(Inits.size() == 0)
1763 returnthis->visitZeroInitializer(*
T, QT,
E);
1764assert(Inits.size() == 1);
1765 returnthis->delegate(Inits[0]);
1769 const Record*R = getRecord(QT);
1771 if(Inits.size() == 1 &&
E->
getType() == Inits[0]->getType())
1772 returnthis->delegate(Inits[0]);
1774 autoinitPrimitiveField = [=](
constRecord::Field *FieldToInit,
1778 if(!this->visit(
Init))
1781 if(FieldToInit->isBitField())
1782 returnthis->emitInitBitField(
T, FieldToInit,
E);
1783 returnthis->emitInitField(
T, FieldToInit->Offset,
E);
1786 autoinitCompositeField = [=](
constRecord::Field *FieldToInit,
1793 if(!this->emitGetPtrField(FieldToInit->Offset,
Init))
1795 if(!this->visitInitializer(
Init))
1797 returnthis->emitPopPtr(
E);
1801 if(Inits.size() == 0) {
1802 if(!this->visitZeroRecordInitializer(R,
E))
1807 if(
const auto*ILE = dyn_cast<InitListExpr>(
E))
1808FToInit = ILE->getInitializedFieldInUnion();
1810FToInit = cast<CXXParenListInitExpr>(
E)->getInitializedFieldInUnion();
1812 constRecord::Field *FieldToInit = R->
getField(FToInit);
1813 if(std::optional<PrimType>
T= classify(
Init)) {
1814 if(!initPrimitiveField(FieldToInit,
Init, *
T))
1817 if(!initCompositeField(FieldToInit,
Init))
1821 returnthis->emitFinishInit(
E);
1825 unsignedInitIndex = 0;
1828 while(InitIndex < R->getNumFields() &&
1832 if(std::optional<PrimType>
T= classify(
Init)) {
1833 constRecord::Field *FieldToInit = R->
getField(InitIndex);
1834 if(!initPrimitiveField(FieldToInit,
Init, *
T))
1839 if(
constRecord::Base *B = R->
getBase(
Init->getType())) {
1840 if(!this->emitGetPtrBase(B->Offset,
Init))
1843 if(!this->visitInitializer(
Init))
1846 if(!this->emitFinishInitPop(
E))
1851 constRecord::Field *FieldToInit = R->
getField(InitIndex);
1852 if(!initCompositeField(FieldToInit,
Init))
1858 returnthis->emitFinishInit(
E);
1862 if(Inits.size() == 1 && QT == Inits[0]->getType())
1863 returnthis->delegate(Inits[0]);
1865 unsignedElementIndex = 0;
1867 if(
const auto*EmbedS =
1868dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1871 autoEval = [&](
const Expr*
Init,
unsignedElemIndex) {
1873 if(!this->visit(
Init))
1875 if(InitT != TargetT) {
1876 if(!this->emitCast(InitT, TargetT,
E))
1879 returnthis->emitInitElem(TargetT, ElemIndex,
Init);
1881 if(!EmbedS->doForEachDataElement(Eval, ElementIndex))
1884 if(!this->visitArrayElemInit(ElementIndex,
Init))
1897 for(; ElementIndex != NumElems; ++ElementIndex) {
1898 if(!this->visitArrayElemInit(ElementIndex, ArrayFiller))
1903 returnthis->emitFinishInit(
E);
1907 unsignedNumInits = Inits.size();
1910 returnthis->delegate(Inits[0]);
1912 QualTypeElemQT = ComplexTy->getElementType();
1913 PrimTypeElemT = classifyPrim(ElemQT);
1914 if(NumInits == 0) {
1916 for(
unsignedI = 0; I < 2; ++I) {
1917 if(!this->visitZeroInitializer(ElemT, ElemQT,
E))
1919 if(!this->emitInitElem(ElemT, I,
E))
1922}
else if(NumInits == 2) {
1923 unsignedInitIndex = 0;
1925 if(!this->visit(
Init))
1928 if(!this->emitInitElem(ElemT, InitIndex,
E))
1937 unsignedNumVecElements = VecT->getNumElements();
1938assert(NumVecElements >= Inits.size());
1940 QualTypeElemQT = VecT->getElementType();
1941 PrimTypeElemT = classifyPrim(ElemQT);
1944 unsignedInitIndex = 0;
1946 if(!this->visit(
Init))
1951 if(
const auto*InitVecT =
Init->getType()->getAs<
VectorType>()) {
1952 if(!this->emitCopyArray(ElemT, 0, InitIndex,
1953InitVecT->getNumElements(),
E))
1955InitIndex += InitVecT->getNumElements();
1957 if(!this->emitInitElem(ElemT, InitIndex,
E))
1963assert(InitIndex <= NumVecElements);
1966 for(; InitIndex != NumVecElements; ++InitIndex) {
1967 if(!this->visitZeroInitializer(ElemT, ElemQT,
E))
1969 if(!this->emitInitElem(ElemT, InitIndex,
E))
1980template<
classEmitter>
1983 if(std::optional<PrimType>
T= classify(
Init->getType())) {
1985 if(!this->visit(
Init))
1987 returnthis->emitInitElem(*
T, ElemIndex,
Init);
1993 if(!this->emitConstUint32(ElemIndex,
Init))
1995 if(!this->emitArrayElemPtrUint32(
Init))
1997 if(!this->visitInitializer(
Init))
1999 returnthis->emitFinishInitPop(
Init);
2002template<
classEmitter>
2004 returnthis->visitInitList(
E->inits(),
E->getArrayFiller(),
E);
2007template<
classEmitter>
2010 returnthis->visitInitList(
E->getInitExprs(),
E->getArrayFiller(),
E);
2013template<
classEmitter>
2016 returnthis->delegate(
E->getReplacement());
2019template<
classEmitter>
2021std::optional<PrimType>
T= classify(
E->
getType());
2022 if(
T&&
E->hasAPValueResult()) {
2029 if(this->visitAPValue(
E->getAPValueResult(), *
T,
E))
2032 returnthis->delegate(
E->getSubExpr());
2035template<
classEmitter>
2037 autoIt =
E->begin();
2038 returnthis->visit(*It);
2043 boolAlignOfReturnsPreferred =
2044ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
2052 if(
T.getQualifiers().hasUnaligned())
2058 if(Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2064template<
classEmitter>
2068 const ASTContext&ASTCtx = Ctx.getASTContext();
2070 if(Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2071 QualTypeArgType =
E->getTypeOfArgument();
2083 returnthis->emitInvalid(
E);
2085 if(Kind == UETT_SizeOf)
2094 returnthis->emitConst(Size.getQuantity(),
E);
2097 if(Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2100 if(
E->isArgumentType()) {
2101 QualTypeArgType =
E->getTypeOfArgument();
2114 if(
const auto*DRE = dyn_cast<DeclRefExpr>(Arg))
2117 else if(
const auto*ME = dyn_cast<MemberExpr>(Arg))
2127 returnthis->emitConst(Size.getQuantity(),
E);
2130 if(Kind == UETT_VectorElements) {
2131 if(
const auto*VT =
E->getTypeOfArgument()->getAs<
VectorType>())
2132 returnthis->emitConst(VT->getNumElements(),
E);
2133assert(
E->getTypeOfArgument()->isSizelessVectorType());
2134 returnthis->emitSizelessVectorElementSize(
E);
2137 if(Kind == UETT_VecStep) {
2138 if(
const auto*VT =
E->getTypeOfArgument()->getAs<
VectorType>()) {
2139 unsignedN = VT->getNumElements();
2146 returnthis->emitConst(N,
E);
2148 returnthis->emitConst(1,
E);
2151 if(Kind == UETT_OpenMPRequiredSimdAlign) {
2152assert(
E->isArgumentType());
2158 if(Kind == UETT_PtrAuthTypeDiscriminator) {
2159 if(
E->getArgumentType()->isDependentType())
2160 returnthis->emitInvalid(
E);
2162 returnthis->emitConst(
2163 const_cast<ASTContext&
>(ASTCtx).getPointerAuthTypeDiscriminator(
2164 E->getArgumentType()),
2171template<
classEmitter>
2178 returnthis->discard(
Base);
2182 const automaybeLoadValue = [&]() ->
bool{
2185 if(std::optional<PrimType>
T= classify(
E))
2186 returnthis->emitLoadPop(*
T,
E);
2190 if(
const auto*VD = dyn_cast<VarDecl>(
Member)) {
2194 if(
autoGlobalIndex =
P.getGlobal(VD))
2195 returnthis->emitGetPtrGlobal(*GlobalIndex,
E) && maybeLoadValue();
2199 if(!isa<FieldDecl>(
Member)) {
2200 if(!this->discard(
Base) && !this->emitSideEffect(
E))
2203 returnthis->visitDeclRef(
Member,
E);
2207 if(!this->delegate(
Base))
2210 if(!this->visit(
Base))
2215 const auto*FD = cast<FieldDecl>(
Member);
2217 const Record*R = getRecord(RD);
2220 constRecord::Field *F = R->
getField(FD);
2222 if(F->Decl->getType()->isReferenceType())
2223 returnthis->emitGetFieldPop(
PT_Ptr, F->Offset,
E) && maybeLoadValue();
2224 returnthis->emitGetPtrFieldPop(F->Offset,
E) && maybeLoadValue();
2227template<
classEmitter>
2233 returnthis->emitConst(*ArrayIndex,
E);
2236template<
classEmitter>
2239assert(!DiscardResult);
2243 if(!this->discard(
E->getCommonExpr()))
2248 const Expr*SubExpr =
E->getSubExpr();
2249 size_tSize =
E->getArraySize().getZExtValue();
2254 for(
size_tI = 0; I != Size; ++I) {
2258 if(!this->visitArrayElemInit(I, SubExpr))
2266template<
classEmitter>
2268 const Expr*SourceExpr =
E->getSourceExpr();
2273 returnthis->visitInitializer(SourceExpr);
2276 if(
autoIt = OpaqueExprs.find(
E); It != OpaqueExprs.end())
2277 returnthis->emitGetLocal(SubExprT, It->second,
E);
2279 if(!this->visit(SourceExpr))
2285 unsignedLocalIndex = allocateLocalPrimitive(
E, SubExprT,
true);
2286 if(!this->emitSetLocal(SubExprT, LocalIndex,
E))
2291 if(!DiscardResult) {
2292 if(!this->emitGetLocal(SubExprT, LocalIndex,
E))
2297OpaqueExprs.insert({
E, LocalIndex});
2302template<
classEmitter>
2306 const Expr*TrueExpr =
E->getTrueExpr();
2307 const Expr*FalseExpr =
E->getFalseExpr();
2309 LabelTyLabelEnd = this->getLabel();
2310 LabelTyLabelFalse = this->getLabel();
2315 if(!this->jumpFalse(LabelFalse))
2320 if(!this->delegate(TrueExpr))
2322 if(!S.destroyLocals())
2326 if(!this->jump(LabelEnd))
2329this->emitLabel(LabelFalse);
2333 if(!this->delegate(FalseExpr))
2335 if(!S.destroyLocals())
2339this->fallthrough(LabelEnd);
2340this->emitLabel(LabelEnd);
2345template<
classEmitter>
2351 unsignedStringIndex =
P.createGlobalString(
E);
2352 returnthis->emitGetPtrGlobal(StringIndex,
E);
2358assert(CAT &&
"a string literal that's not a constant array?");
2363 unsignedN = std::min(ArraySize,
E->getLength());
2364 size_tCharWidth =
E->getCharByteWidth();
2366 for(
unsignedI = 0; I != N; ++I) {
2367uint32_t CodeUnit =
E->getCodeUnit(I);
2369 if(CharWidth == 1) {
2370this->emitConstSint8(CodeUnit,
E);
2371this->emitInitElemSint8(I,
E);
2372}
else if(CharWidth == 2) {
2373this->emitConstUint16(CodeUnit,
E);
2374this->emitInitElemUint16(I,
E);
2375}
else if(CharWidth == 4) {
2376this->emitConstUint32(CodeUnit,
E);
2377this->emitInitElemUint32(I,
E);
2379llvm_unreachable(
"unsupported character width");
2384 for(
unsignedI = N; I != ArraySize; ++I) {
2385 if(CharWidth == 1) {
2386this->emitConstSint8(0,
E);
2387this->emitInitElemSint8(I,
E);
2388}
else if(CharWidth == 2) {
2389this->emitConstUint16(0,
E);
2390this->emitInitElemUint16(I,
E);
2391}
else if(CharWidth == 4) {
2392this->emitConstUint32(0,
E);
2393this->emitInitElemUint32(I,
E);
2395llvm_unreachable(
"unsupported character width");
2402template<
classEmitter>
2406 returnthis->emitDummyPtr(
E,
E);
2409template<
classEmitter>
2411 auto&A = Ctx.getASTContext();
2416 false,
E->
getType(),
E->getAtLoc());
2417 returnthis->delegate(SL);
2420template<
classEmitter>
2428 auto&A = Ctx.getASTContext();
2429std::string ResultStr =
E->ComputeName(A);
2432 APIntSize(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
2433 QualTypeArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
2434ArraySizeModifier::Normal, 0);
2438 false, ArrayTy,
E->getLocation());
2440 unsignedStringIndex =
P.createGlobalString(SL);
2441 returnthis->emitGetPtrGlobal(StringIndex,
E);
2444template<
classEmitter>
2448 returnthis->emitConst(
E->getValue(),
E);
2451template<
classEmitter>
2455 const Expr*LHS =
E->getLHS();
2456 const Expr*RHS =
E->getRHS();
2458 QualTypeLHSComputationType =
E->getComputationLHSType();
2459 QualTypeResultType =
E->getComputationResultType();
2460std::optional<PrimType>
LT= classify(LHSComputationType);
2461std::optional<PrimType> RT = classify(ResultType);
2468 PrimTypeLHST = classifyPrim(LHSType);
2476 unsignedTempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2477 if(!this->emitSetLocal(*RT, TempOffset,
E))
2483 if(!this->emitLoad(LHST,
E))
2487 if(!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
2488LHSComputationType,
E))
2492 if(!this->emitGetLocal(*RT, TempOffset,
E))
2495 switch(
E->getOpcode()) {
2497 if(!this->emitAddf(getFPOptions(
E),
E))
2501 if(!this->emitSubf(getFPOptions(
E),
E))
2505 if(!this->emitMulf(getFPOptions(
E),
E))
2509 if(!this->emitDivf(getFPOptions(
E),
E))
2516 if(!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->
getType(),
E))
2520 returnthis->emitStorePop(LHST,
E);
2521 returnthis->emitStore(LHST,
E);
2524template<
classEmitter>
2528 const Expr*LHS =
E->getLHS();
2529 const Expr*RHS =
E->getRHS();
2530std::optional<PrimType>
LT= classify(LHS->
getType());
2531std::optional<PrimType> RT = classify(RHS->
getType());
2533 if(Op != BO_AddAssign && Op != BO_SubAssign)
2542 if(!this->emitLoad(*
LT, LHS))
2548 if(Op == BO_AddAssign) {
2549 if(!this->emitAddOffset(*RT,
E))
2552 if(!this->emitSubOffset(*RT,
E))
2557 returnthis->emitStorePopPtr(
E);
2558 returnthis->emitStorePtr(
E);
2561template<
classEmitter>
2565 returnVisitVectorBinOp(
E);
2567 const Expr*LHS =
E->getLHS();
2568 const Expr*RHS =
E->getRHS();
2569std::optional<PrimType> LHSComputationT =
2570classify(
E->getComputationLHSType());
2571std::optional<PrimType>
LT= classify(LHS->
getType());
2572std::optional<PrimType> RT = classify(RHS->
getType());
2573std::optional<PrimType> ResultT = classify(
E->
getType());
2576 returnthis->visit(RHS) && this->visit(LHS) && this->emitError(
E);
2578 if(!
LT|| !RT || !ResultT || !LHSComputationT)
2585 returnVisitFloatCompoundAssignOperator(
E);
2588 returnVisitPointerCompoundAssignOperator(
E);
2601 unsignedTempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2603 if(!this->emitSetLocal(*RT, TempOffset,
E))
2610 if(!this->emitLoad(*
LT,
E))
2612 if(
LT!= LHSComputationT) {
2613 if(!this->emitCast(*
LT, *LHSComputationT,
E))
2618 if(!this->emitGetLocal(*RT, TempOffset,
E))
2622 switch(
E->getOpcode()) {
2624 if(!this->emitAdd(*LHSComputationT,
E))
2628 if(!this->emitSub(*LHSComputationT,
E))
2632 if(!this->emitMul(*LHSComputationT,
E))
2636 if(!this->emitDiv(*LHSComputationT,
E))
2640 if(!this->emitRem(*LHSComputationT,
E))
2644 if(!this->emitShl(*LHSComputationT, *RT,
E))
2648 if(!this->emitShr(*LHSComputationT, *RT,
E))
2652 if(!this->emitBitAnd(*LHSComputationT,
E))
2656 if(!this->emitBitXor(*LHSComputationT,
E))
2660 if(!this->emitBitOr(*LHSComputationT,
E))
2664llvm_unreachable(
"Unimplemented compound assign operator");
2668 if(ResultT != LHSComputationT) {
2669 if(!this->emitCast(*LHSComputationT, *ResultT,
E))
2674 if(DiscardResult) {
2676 returnthis->emitStoreBitFieldPop(*ResultT,
E);
2677 returnthis->emitStorePop(*ResultT,
E);
2680 returnthis->emitStoreBitField(*ResultT,
E);
2681 returnthis->emitStore(*ResultT,
E);
2684template<
classEmitter>
2687 const Expr*SubExpr =
E->getSubExpr();
2692template<
classEmitter>
2695 const Expr*SubExpr =
E->getSubExpr();
2699 returnthis->delegate(SubExpr);
2704 returnthis->discard(SubExpr);
2708std::optional<PrimType> SubExprT = classify(SubExpr);
2711std::optional<unsigned> GlobalIndex =
P.createGlobal(
E);
2716 E->getLifetimeExtendedTemporaryDecl();
2721 if(!this->visit(SubExpr))
2724 if(!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl,
E))
2727 if(!this->emitInitGlobal(*SubExprT, *GlobalIndex,
E))
2730 returnthis->emitGetPtrGlobal(*GlobalIndex,
E);
2733 if(!this->checkLiteralType(SubExpr))
2736 if(!this->emitGetPtrGlobal(*GlobalIndex,
E))
2738 if(!this->visitInitializer(SubExpr))
2741 returnthis->emitInitGlobalTempComp(TempDecl,
E);
2747 unsignedLocalIndex = allocateLocalPrimitive(
E, *SubExprT,
true,
2749 if(!this->visit(SubExpr))
2751 if(!this->emitSetLocal(*SubExprT, LocalIndex,
E))
2753 returnthis->emitGetPtrLocal(LocalIndex,
E);
2756 if(!this->checkLiteralType(SubExpr))
2760 if(std::optional<unsigned> LocalIndex =
2761allocateLocal(
E, Inner->getType(),
E->getExtendingDecl())) {
2763 if(!this->emitGetPtrLocal(*LocalIndex,
E))
2765 returnthis->visitInitializer(SubExpr) && this->emitFinishInit(
E);
2771template<
classEmitter>
2774 returnthis->delegate(
E->getSubExpr());
2777template<
classEmitter>
2779 const Expr*
Init=
E->getInitializer();
2781 returnthis->discard(
Init);
2785 returnthis->visitInitializer(
Init) && this->emitFinishInit(
E);
2788std::optional<PrimType>
T= classify(
E->
getType());
2789 if(
E->isFileScope()) {
2792 returnthis->delegate(
Init);
2794 if(std::optional<unsigned> GlobalIndex =
P.createGlobal(
E)) {
2795 if(!this->emitGetPtrGlobal(*GlobalIndex,
E))
2799 if(!this->visit(
Init))
2801 returnthis->emitInitGlobal(*
T, *GlobalIndex,
E);
2804 returnthis->visitInitializer(
Init) && this->emitFinishInit(
E);
2813 returnthis->delegate(
Init);
2815 unsignedLocalIndex;
2818LocalIndex = this->allocateLocalPrimitive(
Init, *
T,
false,
false);
2819 else if(std::optional<unsigned> MaybeIndex = this->allocateLocal(
Init))
2820LocalIndex = *MaybeIndex;
2824 if(!this->emitGetPtrLocal(LocalIndex,
E))
2828 if(!this->visit(
Init)) {
2831 returnthis->emitInit(*
T,
E);
2833 if(!this->visitInitializer(
Init) || !this->emitFinishInit(
E))
2842template<
classEmitter>
2847 returnthis->emitConstBool(
E->getValue(),
E);
2848 returnthis->emitConst(
E->getValue(),
E);
2851template<
classEmitter>
2855 returnthis->emitConst(
E->getValue(),
E);
2858template<
classEmitter>
2864 const Record*R =
P.getOrCreateRecord(
E->getLambdaClass());
2866 auto*CaptureInitIt =
E->capture_init_begin();
2869 for(
constRecord::Field &F : R->
fields()) {
2870 const Expr*
Init= *CaptureInitIt;
2876 if(std::optional<PrimType>
T= classify(
Init)) {
2877 if(!this->visit(
Init))
2880 if(!this->emitInitField(*
T, F.Offset,
E))
2883 if(!this->emitGetPtrField(F.Offset,
E))
2886 if(!this->visitInitializer(
Init))
2889 if(!this->emitPopPtr(
E))
2897template<
classEmitter>
2903 unsignedStringIndex =
P.createGlobalString(
E->getFunctionName(),
E);
2904 returnthis->emitGetPtrGlobal(StringIndex,
E);
2907 returnthis->delegate(
E->getFunctionName());
2910template<
classEmitter>
2912 if(
E->getSubExpr() && !this->discard(
E->getSubExpr()))
2915 returnthis->emitInvalid(
E);
2918template<
classEmitter>
2921 const Expr*SubExpr =
E->getSubExpr();
2923std::optional<PrimType> FromT = classify(SubExpr);
2924std::optional<PrimType> ToT = classify(
E);
2927 returnthis->emitInvalidCast(CastKind::Reinterpret,
true,
E);
2931std::optional<PrimType> PointeeFromT;
2935PointeeFromT = classify(SubExpr->
getType());
2937std::optional<PrimType> PointeeToT;
2941PointeeToT = classify(
E->
getType());
2944 if(PointeeToT && PointeeFromT) {
2949 if(!this->emitInvalidCast(CastKind::Reinterpret, Fatal,
E))
2952 if(
E->getCastKind() == CK_LValueBitCast)
2953 returnthis->delegate(SubExpr);
2954 returnthis->VisitCastExpr(
E);
2958 boolFatal = (ToT != FromT);
2959 if(!this->emitInvalidCast(CastKind::Reinterpret, Fatal,
E))
2962 returnthis->VisitCastExpr(
E);
2965template<
classEmitter>
2971 returnthis->emitConstBool(
E->getValue(),
E);
2974template<
classEmitter>
2977assert(!classify(
T));
2987 returnthis->visitInitializer(
E->getArg(0));
2991 if(DiscardResult) {
2995std::optional<unsigned> LocalIndex = allocateLocal(
E);
3000 if(!this->emitGetPtrLocal(*LocalIndex,
E))
3005 if(
E->requiresZeroInitialization()) {
3008 if(!this->visitZeroRecordInitializer(R,
E))
3021assert(
Func->hasThisPointer());
3022assert(!
Func->hasRVO());
3026 if(!this->emitDupPtr(
E))
3030 for(
const auto*Arg :
E->arguments()) {
3031 if(!this->visit(Arg))
3035 if(
Func->isVariadic()) {
3036uint32_t VarArgSize = 0;
3037 unsignedNumParams =
Func->getNumWrittenParams();
3038 for(
unsignedI = NumParams, N =
E->getNumArgs(); I != N; ++I) {
3042 if(!this->emitCallVar(
Func, VarArgSize,
E))
3045 if(!this->emitCall(
Func, 0,
E)) {
3050(void)this->emitPopPtr(
E);
3056 returnthis->emitPopPtr(
E);
3057 returnthis->emitFinishInit(
E);
3068 if(!
Func|| !
Func->isConstexpr())
3073 for(
size_tI = 0; I != NumElems; ++I) {
3074 if(!this->emitConstUint64(I,
E))
3076 if(!this->emitArrayElemPtrUint64(
E))
3080 for(
const auto*Arg :
E->arguments()) {
3081 if(!this->visit(Arg))
3085 if(!this->emitCall(
Func, 0,
E))
3094template<
classEmitter>
3100 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
3104assert(Val.
isInt());
3106 returnthis->emitConst(I,
E);
3113 if(
const Expr*LValueExpr =
Base.dyn_cast<
const Expr*>())
3114 returnthis->visit(LValueExpr);
3120 const auto*BaseDecl =
Base.dyn_cast<
const ValueDecl*>();
3123 auto*UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
3125std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(UGCD);
3129 if(!this->emitGetPtrGlobal(*GlobalIndex,
E))
3133 const APValue&
V= UGCD->getValue();
3134 for(
unsignedI = 0, N = R->
getNumFields(); I != N; ++I) {
3135 constRecord::Field *F = R->
getField(I);
3136 const APValue&FieldValue =
V.getStructField(I);
3138 PrimTypeFieldT = classifyPrim(F->Decl->getType());
3140 if(!this->visitAPValue(FieldValue, FieldT,
E))
3142 if(!this->emitInitField(FieldT, F->Offset,
E))
3150template<
classEmitter>
3152 unsignedN =
E->getNumComponents();
3156 for(
unsignedI = 0; I != N; ++I) {
3159 const Expr*ArrayIndexExpr =
E->getIndexExpr(
Node.getArrayExprIndex());
3162 if(DiscardResult) {
3163 if(!this->discard(ArrayIndexExpr))
3168 if(!this->visit(ArrayIndexExpr))
3182 returnthis->emitOffsetOf(
T,
E,
E);
3185template<
classEmitter>
3193 if(std::optional<PrimType>
T= classify(Ty))
3194 returnthis->visitZeroInitializer(*
T, Ty,
E);
3198std::optional<unsigned> LocalIndex = allocateLocal(
E);
3201 if(!this->emitGetPtrLocal(*LocalIndex,
E))
3206 QualTypeElemQT = CT->getElementType();
3207 PrimTypeElemT = classifyPrim(ElemQT);
3209 for(
unsignedI = 0; I != 2; ++I) {
3210 if(!this->visitZeroInitializer(ElemT, ElemQT,
E))
3212 if(!this->emitInitElem(ElemT, I,
E))
3221std::optional<unsigned> LocalIndex = allocateLocal(
E);
3224 if(!this->emitGetPtrLocal(*LocalIndex,
E))
3229 QualTypeElemQT = VT->getElementType();
3230 PrimTypeElemT = classifyPrim(ElemQT);
3232 for(
unsignedI = 0, N = VT->getNumElements(); I != N; ++I) {
3233 if(!this->visitZeroInitializer(ElemT, ElemQT,
E))
3235 if(!this->emitInitElem(ElemT, I,
E))
3244template<
classEmitter>
3246 returnthis->emitConst(
E->getPackLength(),
E);
3249template<
classEmitter>
3252 returnthis->delegate(
E->getResultExpr());
3255template<
classEmitter>
3257 returnthis->delegate(
E->getChosenSubExpr());
3260template<
classEmitter>
3265 returnthis->emitConst(
E->getValue(),
E);
3268template<
classEmitter>
3273 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
3274 const Function*F = this->getFunction(Ctor);
3291 if(!this->emitGetParam(PT, Offset,
E))
3296 returnthis->emitCall(F, 0,
E);
3299template<
classEmitter>
3302 const Expr*
Init=
E->getInitializer();
3303 QualTypeElementType =
E->getAllocatedType();
3304std::optional<PrimType> ElemT = classify(ElementType);
3305 unsignedPlacementArgs =
E->getNumPlacementArgs();
3307 const Expr*PlacementDest =
nullptr;
3308 boolIsNoThrow =
false;
3310 if(PlacementArgs != 0) {
3319 if(PlacementArgs == 1) {
3320 const Expr*Arg1 =
E->getPlacementArg(0);
3322 if(!this->discard(Arg1))
3327 if(!this->emitInvalidNewDeleteExpr(
E,
E))
3332 if(OperatorNew->isReservedGlobalPlacementOperator())
3333PlacementDest = Arg1;
3337 returnthis->emitInvalid(
E);
3339}
else if(!OperatorNew->isReplaceableGlobalAllocationFunction())
3340 returnthis->emitInvalidNewDeleteExpr(
E,
E);
3343 if(!PlacementDest) {
3352Desc =
P.createDescriptor(
3355 false,
false,
false,
Init);
3359 if(
E->isArray()) {
3360std::optional<const Expr *> ArraySizeExpr =
E->getArraySize();
3364 const Expr*Stripped = *ArraySizeExpr;
3365 for(;
auto*ICE = dyn_cast<ImplicitCastExpr>(Stripped);
3366Stripped = ICE->getSubExpr())
3367 if(ICE->getCastKind() != CK_NoOp &&
3368ICE->getCastKind() != CK_IntegralCast)
3373 if(PlacementDest) {
3374 if(!this->visit(PlacementDest))
3376 if(!this->visit(Stripped))
3378 if(!this->emitCheckNewTypeMismatchArray(SizeT,
E,
E))
3381 if(!this->visit(Stripped))
3386 if(!this->emitAllocN(SizeT, *ElemT,
E, IsNoThrow,
E))
3390 if(!this->emitAllocCN(SizeT, Desc, IsNoThrow,
E))
3395 if(
Init&& !this->visitInitializer(
Init))
3399 if(PlacementDest) {
3400 if(!this->visit(PlacementDest))
3402 if(!this->emitCheckNewTypeMismatch(
E,
E))
3406 if(!this->emitAlloc(Desc,
E))
3412 if(!this->visit(
Init))
3415 if(!this->emitInit(*ElemT,
E))
3419 if(!this->visitInitializer(
Init))
3426 returnthis->emitPopPtr(
E);
3431template<
classEmitter>
3433 const Expr*Arg =
E->getArgument();
3435 const FunctionDecl*OperatorDelete =
E->getOperatorDelete();
3437 if(!OperatorDelete->isReplaceableGlobalAllocationFunction())
3438 returnthis->emitInvalidNewDeleteExpr(
E,
E);
3441 if(!this->visit(Arg))
3444 returnthis->emitFree(
E->isArrayForm(),
E->isGlobalDelete(),
E);
3447template<
classEmitter>
3458 returnthis->emitGetFnPtr(
Func,
E);
3461template<
classEmitter>
3465 if(!
E->isPotentiallyEvaluated()) {
3469 if(
E->isTypeOperand())
3470 returnthis->emitGetTypeid(
3471 E->getTypeOperand(Ctx.getASTContext()).getTypePtr(), TypeInfoType,
E);
3477assert(
E->getExprOperand());
3478assert(
E->getExprOperand()->
isLValue());
3480 if(!Ctx.
getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(
E))
3483 if(!this->visit(
E->getExprOperand()))
3486 if(!this->emitGetTypeidPtr(TypeInfoType,
E))
3489 returnthis->emitPopPtr(
E);
3493template<
classEmitter>
3496 returnthis->emitConstBool(
E->getValue(),
E);
3499template<
classEmitter>
3511 returnthis->emitDummyPtr(GuidDecl,
E);
3513std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(GuidDecl);
3516 if(!this->emitGetPtrGlobal(*GlobalIndex,
E))
3519assert(this->getRecord(
E->
getType()));
3525assert(
V.isStruct());
3526assert(
V.getStructNumBases() == 0);
3527 if(!this->visitAPValueInitializer(
V,
E))
3530 returnthis->emitFinishInit(
E);
3533template<
classEmitter>
3538 returnthis->emitConstBool(
E->isSatisfied(),
E);
3541template<
classEmitter>
3547 returnthis->emitConstBool(
E->isSatisfied(),
E);
3550template<
classEmitter>
3553 returnthis->delegate(
E->getSemanticForm());
3556template<
classEmitter>
3559 for(
const Expr*SemE :
E->semantics()) {
3560 if(
auto*OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
3561 if(SemE ==
E->getResultExpr())
3564 if(OVE->isUnique())
3567 if(!this->discard(OVE))
3569}
else if(SemE ==
E->getResultExpr()) {
3570 if(!this->delegate(SemE))
3573 if(!this->discard(SemE))
3580template<
classEmitter>
3582 returnthis->delegate(
E->getSelectedExpr());
3585template<
classEmitter>
3587 returnthis->emitError(
E);
3590template<
classEmitter>
3594 unsignedOffset = allocateLocalPrimitive(
3595 E->getLabel(),
PT_Ptr,
true,
false);
3597 returnthis->emitGetLocal(
PT_Ptr, Offset,
E);
3600template<
classEmitter>
3604 QualTypeElemType = VT->getElementType();
3605 PrimTypeElemT = classifyPrim(ElemType);
3606 const Expr*Src =
E->getSrcExpr();
3608 PrimTypeSrcElemT = classifyVectorElementType(SrcType);
3610 unsignedSrcOffset = this->allocateLocalPrimitive(Src,
PT_Ptr,
true,
false);
3611 if(!this->visit(Src))
3613 if(!this->emitSetLocal(
PT_Ptr, SrcOffset,
E))
3616 for(
unsignedI = 0; I != VT->getNumElements(); ++I) {
3617 if(!this->emitGetLocal(
PT_Ptr, SrcOffset,
E))
3619 if(!this->emitArrayElemPop(SrcElemT, I,
E))
3623 if(SrcElemT != ElemT) {
3624 if(!this->emitPrimCast(SrcElemT, ElemT, ElemType,
E))
3626}
else if(ElemType->isFloatingType() && SrcType != ElemType) {
3627 const auto*TargetSemantics = &Ctx.getFloatSemantics(ElemType);
3631 if(!this->emitInitElem(ElemT, I,
E))
3638template<
classEmitter>
3641assert(
E->getNumSubExprs() > 2);
3643 const Expr*Vecs[] = {
E->getExpr(0),
E->getExpr(1)};
3647 unsignedNumOutputElems =
E->getNumSubExprs() - 2;
3648assert(NumOutputElems > 0);
3651 unsignedVectorOffsets[2];
3652 for(
unsignedI = 0; I != 2; ++I) {
3653VectorOffsets[I] = this->allocateLocalPrimitive(
3654Vecs[I],
PT_Ptr,
true,
false);
3655 if(!this->visit(Vecs[I]))
3657 if(!this->emitSetLocal(
PT_Ptr, VectorOffsets[I],
E))
3660 for(
unsignedI = 0; I != NumOutputElems; ++I) {
3661 APSIntShuffleIndex =
E->getShuffleMaskIdx(Ctx.getASTContext(), I);
3662assert(ShuffleIndex >= -1);
3663 if(ShuffleIndex == -1)
3664 returnthis->emitInvalidShuffleVectorIndex(I,
E);
3666assert(ShuffleIndex < (NumInputElems * 2));
3667 if(!this->emitGetLocal(
PT_Ptr,
3668VectorOffsets[ShuffleIndex >= NumInputElems],
E))
3670 unsignedInputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
3671 if(!this->emitArrayElemPop(ElemT, InputVectorIndex,
E))
3674 if(!this->emitInitElem(ElemT, I,
E))
3681template<
classEmitter>
3686 Base->getType()->isVectorType() ||
3690 E->getEncodedElementAccess(Indices);
3692 if(Indices.size() == 1) {
3693 if(!this->visit(
Base))
3697 if(!this->emitConstUint32(Indices[0],
E))
3699 returnthis->emitArrayElemPtrPop(
PT_Uint32,
E);
3702 returnthis->emitArrayElemPop(classifyPrim(
E->
getType()), Indices[0],
E);
3706 unsignedBaseOffset = allocateLocalPrimitive(
Base,
PT_Ptr,
true,
3708 if(!this->visit(
Base))
3710 if(!this->emitSetLocal(
PT_Ptr, BaseOffset,
E))
3715std::optional<unsigned> ResultIndex;
3716ResultIndex = allocateLocal(
E);
3719 if(!this->emitGetPtrLocal(*ResultIndex,
E))
3727uint32_t DstIndex = 0;
3728 for(uint32_t I : Indices) {
3729 if(!this->emitGetLocal(
PT_Ptr, BaseOffset,
E))
3731 if(!this->emitArrayElemPop(ElemT, I,
E))
3733 if(!this->emitInitElem(ElemT, DstIndex,
E))
3739assert(!DiscardResult);
3743template<
classEmitter>
3745 const Expr*SubExpr =
E->getSubExpr();
3746 if(!
E->isExpressibleAsConstantInitializer())
3747 returnthis->discard(SubExpr) && this->emitInvalid(
E);
3752assert(classifyPrim(
E) ==
PT_Ptr);
3753 returnthis->emitDummyPtr(
E,
E);
3756template<
classEmitter>
3759 const Expr*SubExpr =
E->getSubExpr();
3766 if(!this->visit(SubExpr))
3768 if(!this->emitConstUint8(0,
E))
3770 if(!this->emitArrayElemPtrPopUint8(
E))
3780 returnthis->emitInitField(SecondFieldT, R->
getField(1u)->
Offset,
E);
3782assert(SecondFieldT ==
PT_Ptr);
3786 if(!this->emitExpandPtr(
E))
3790 if(!this->emitArrayElemPtrPop(
PT_Uint64,
E))
3795template<
classEmitter>
3802 for(
const Stmt*S : CS->
body()) {
3804 if(!this->visitStmt(S))
3809assert(S == Result);
3810 if(
const Expr*ResultExpr = dyn_cast<Expr>(S))
3811 returnthis->delegate(ResultExpr);
3812 returnthis->emitUnsupported(
E);
3821 returnthis->Visit(
E);
3828 returnthis->Visit(
E);
3836 returnthis->discard(
E);
3841std::optional<unsigned> LocalIndex = allocateLocal(
E);
3845 if(!this->emitGetPtrLocal(*LocalIndex,
E))
3848 returnthis->visitInitializer(
E);
3855 returnthis->Visit(
E);
3858template<
classEmitter>
3860assert(!classify(
E->
getType()));
3864 returnthis->Visit(
E);
3868std::optional<PrimType>
T= classify(
E->
getType());
3872 if(!this->visit(
E))
3874 returnthis->emitComplexBoolCast(
E);
3879 if(!this->visit(
E))
3887 if(!this->emitNull(*
T, 0,
nullptr,
E))
3889 returnthis->emitNE(*
T,
E);
3894 returnthis->emitCastFloatingIntegralBool(getFPOptions(
E),
E);
3897 returnthis->emitCast(*
T,
PT_Bool,
E);
3900template<
classEmitter>
3905 returnthis->emitZeroBool(
E);
3907 returnthis->emitZeroSint8(
E);
3909 returnthis->emitZeroUint8(
E);
3911 returnthis->emitZeroSint16(
E);
3913 returnthis->emitZeroUint16(
E);
3915 returnthis->emitZeroSint32(
E);
3917 returnthis->emitZeroUint32(
E);
3919 returnthis->emitZeroSint64(
E);
3921 returnthis->emitZeroUint64(
E);
3923 returnthis->emitZeroIntAP(Ctx.getBitWidth(QT),
E);
3925 returnthis->emitZeroIntAPS(Ctx.getBitWidth(QT),
E);
3930 returnthis->emitNullFnPtr(0,
nullptr,
E);
3932 returnthis->emitNullMemberPtr(0,
nullptr,
E);
3934 returnthis->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)),
E);
3939llvm_unreachable(
"Implement");
3941llvm_unreachable(
"unknown primitive type");
3944template<
classEmitter>
3950 for(
constRecord::Field &Field : R->
fields()) {
3951 if(
Field.Decl->isUnnamedBitField())
3955 if(
D->isPrimitive()) {
3958 if(!this->visitZeroInitializer(
T, QT,
E))
3960 if(!this->emitInitField(
T,
Field.Offset,
E))
3967 if(!this->emitGetPtrField(
Field.Offset,
E))
3970 if(
D->isPrimitiveArray()) {
3973 for(uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
3974 if(!this->visitZeroInitializer(
T, ET,
E))
3976 if(!this->emitInitElem(
T, I,
E))
3979}
else if(
D->isCompositeArray()) {
3981 if(!this->visitZeroArrayInitializer(
D->getType(),
E))
3983}
else if(
D->isRecord()) {
3984 if(!this->visitZeroRecordInitializer(
D->ElemRecord,
E))
3990 if(!this->emitFinishInitPop(
E))
3999 for(
constRecord::Base &B : R->
bases()) {
4000 if(!this->emitGetPtrBase(B.Offset,
E))
4002 if(!this->visitZeroRecordInitializer(B.R,
E))
4004 if(!this->emitFinishInitPop(
E))
4013template<
classEmitter>
4018 size_tNumElems = cast<ConstantArrayType>(AT)->getZExtSize();
4020 if(std::optional<PrimType> ElemT = classify(ElemType)) {
4021 for(
size_tI = 0; I != NumElems; ++I) {
4022 if(!this->visitZeroInitializer(*ElemT, ElemType,
E))
4024 if(!this->emitInitElem(*ElemT, I,
E))
4029 const Record*R = getRecord(ElemType);
4031 for(
size_tI = 0; I != NumElems; ++I) {
4032 if(!this->emitConstUint32(I,
E))
4034 if(!this->emitArrayElemPtr(
PT_Uint32,
E))
4036 if(!this->visitZeroRecordInitializer(R,
E))
4038 if(!this->emitPopPtr(
E))
4043 for(
size_tI = 0; I != NumElems; ++I) {
4044 if(!this->emitConstUint32(I,
E))
4046 if(!this->emitArrayElemPtr(
PT_Uint32,
E))
4048 if(!this->visitZeroArrayInitializer(ElemType,
E))
4050 if(!this->emitPopPtr(
E))
4059template<
classEmitter>
4060template<
typenameT>
4064 returnthis->emitConstSint8(
Value,
E);
4066 returnthis->emitConstUint8(
Value,
E);
4068 returnthis->emitConstSint16(
Value,
E);
4070 returnthis->emitConstUint16(
Value,
E);
4072 returnthis->emitConstSint32(
Value,
E);
4074 returnthis->emitConstUint32(
Value,
E);
4076 returnthis->emitConstSint64(
Value,
E);
4078 returnthis->emitConstUint64(
Value,
E);
4080 returnthis->emitConstBool(
Value,
E);
4088llvm_unreachable(
"Invalid integral type");
4091llvm_unreachable(
"unknown primitive type");
4094template<
classEmitter>
4095template<
typenameT>
4097 returnthis->emitConst(
Value, classifyPrim(
E->
getType()),
E);
4100template<
classEmitter>
4104 returnthis->emitConstIntAPS(
Value,
E);
4106 returnthis->emitConstIntAP(
Value,
E);
4108 if(
Value.isSigned())
4109 returnthis->emitConst(
Value.getSExtValue(), Ty,
E);
4110 returnthis->emitConst(
Value.getZExtValue(), Ty,
E);
4113template<
classEmitter>
4115 returnthis->emitConst(
Value, classifyPrim(
E->
getType()),
E);
4118template<
classEmitter>
4123 if(
const auto*VD =
4124dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl*>())) {
4125assert(!
P.getGlobal(VD));
4126assert(!Locals.contains(VD));
4134isa<const Expr *>(Src));
4136 if(
auto*VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl*>()))
4137Locals.insert({VD, Local});
4138VarScope->add(Local, IsExtended);
4139 returnLocal.Offset;
4142template<
classEmitter>
4143std::optional<unsigned>
4147 if([[maybe_unused]]
const auto*VD =
4148dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl*>())) {
4149assert(!
P.getGlobal(VD));
4150assert(!Locals.contains(VD));
4155 boolIsTemporary =
false;
4156 if(
auto*VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl*>())) {
4160 if(
const auto*VarD = dyn_cast<VarDecl>(VD))
4161 Init= VarD->getInit();
4163 if(
auto*
E= Src.dyn_cast<
const Expr*>()) {
4164IsTemporary =
true;
4171IsTemporary,
false,
Init);
4173 returnstd::nullopt;
4177Locals.insert({Key, Local});
4179VarScope->addExtended(Local, ExtendingDecl);
4181VarScope->add(Local,
false);
4182 returnLocal.Offset;
4185template<
classEmitter>
4192 true,
false,
nullptr);
4195 returnstd::nullopt;
4201 while(S->getParent())
4203assert(S && !S->getParent());
4205 returnLocal.Offset;
4208template<
classEmitter>
4210 if(
const PointerType*PT = dyn_cast<PointerType>(Ty))
4216 if(
const auto*RecordTy = getRecordTy(Ty))
4217 returngetRecord(RecordTy->getDecl());
4221template<
classEmitter>
4223 return P.getOrCreateRecord(RD);
4226template<
classEmitter>
4228 returnCtx.getOrCreateFunction(FD);
4231template<
classEmitter>
4236 if(!DestroyToplevelScope) {
4237 if(!this->emitCheckAllocations(
E))
4241 automaybeDestroyLocals = [&]() ->
bool{
4242 if(DestroyToplevelScope)
4243 returnRootScope.
destroyLocals() && this->emitCheckAllocations(
E);
4244 returnthis->emitCheckAllocations(
E);
4251 returnthis->emitRetVoid(
E) && maybeDestroyLocals();
4255 if(std::optional<PrimType>
T= classify(
E)) {
4259 returnthis->emitRet(*
T,
E) && maybeDestroyLocals();
4265 if(std::optional<unsigned> LocalOffset = this->allocateLocal(
E)) {
4267 if(!this->emitGetPtrLocal(*LocalOffset,
E))
4270 if(!visitInitializer(
E))
4273 if(!this->emitFinishInit(
E))
4278 returnthis->emitRetValue(
E) && maybeDestroyLocals();
4281 returnmaybeDestroyLocals() && this->emitCheckAllocations(
E) &&
false;
4284template<
classEmitter>
4287 autoR = this->visitVarDecl(VD,
true);
4296 if(
autoGlobalIndex =
P.getGlobal(VD)) {
4297 Block*GlobalBlock =
P.getGlobal(*GlobalIndex);
4301GD.
InitState= GlobalInitState::InitializerFailed;
4312template<
classEmitter>
4314 boolConstantContext) {
4315std::optional<PrimType> VarT = classify(VD->
getType());
4319 if(!ConstantContext) {
4324this->emitCheckAllocations(VD);
4328 if(!this->visitVarDecl(VD,
true))
4332 autoGlobalIndex =
P.getGlobal(VD);
4333assert(GlobalIndex);
4335 if(!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
4338 if(!this->emitGetPtrGlobal(*GlobalIndex, VD))
4342 autoLocal = Locals.find(VD);
4343assert(Local != Locals.end());
4345 if(!this->emitGetLocal(*VarT, Local->second.Offset, VD))
4348 if(!this->emitGetPtrLocal(Local->second.Offset, VD))
4354 if(!this->emitRet(VarT.value_or(
PT_Ptr), VD)) {
4358 autoGlobalIndex =
P.getGlobal(VD);
4359assert(GlobalIndex);
4360 Block*GlobalBlock =
P.getGlobal(*GlobalIndex);
4364GD.
InitState= GlobalInitState::InitializerFailed;
4370 returnVDScope.
destroyLocals() && this->emitCheckAllocations(VD);
4373template<
classEmitter>
4382 if(!this->isActive())
4386std::optional<PrimType> VarT = classify(VD->
getType());
4388 if(
Init&&
Init->isValueDependent())
4392 autocheckDecl = [&]() ->
bool{
4394 return!NeedsOp || this->emitCheckDecl(VD, VD);
4397 autoinitGlobal = [&](
unsignedGlobalIndex) ->
bool{
4401 if(!this->visit(
Init))
4402 returncheckDecl() &&
false;
4404 returncheckDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
4410 if(!this->emitGetPtrGlobal(GlobalIndex,
Init))
4413 if(!visitInitializer(
Init))
4416 if(!this->emitFinishInit(
Init))
4419 returnthis->emitPopPtr(
Init);
4425 if(std::optional<unsigned> GlobalIndex =
P.getGlobal(VD)) {
4426 if(
P.getPtrGlobal(*GlobalIndex).isInitialized())
4431 return Init&& checkDecl() && initGlobal(*GlobalIndex);
4434std::optional<unsigned> GlobalIndex =
P.createGlobal(VD,
Init);
4439 return!
Init|| (checkDecl() && initGlobal(*GlobalIndex));
4444 unsignedOffset = this->allocateLocalPrimitive(
4451 if(!this->visit(
Init))
4453 returnthis->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
4455 if(!this->visit(
Init))
4457 returnthis->emitSetLocal(*VarT, Offset, VD);
4461 if(std::optional<unsigned> Offset = this->allocateLocal(VD)) {
4465 if(!this->emitGetPtrLocal(*Offset,
Init))
4468 if(!visitInitializer(
Init))
4471 if(!this->emitFinishInit(
Init))
4474 returnthis->emitPopPtr(
Init);
4484template<
classEmitter>
4487assert(!DiscardResult);
4489 returnthis->emitConst(Val.
getInt(), ValType,
E);
4491 returnthis->emitConstFloat(Val.
getFloat(),
E);
4495 returnthis->emitNull(ValType, 0,
nullptr,
E);
4497 if(
const Expr*BaseExpr =
Base.dyn_cast<
const Expr*>())
4498 returnthis->visit(BaseExpr);
4499 else if(
const auto*VD =
Base.dyn_cast<
const ValueDecl*>()) {
4500 returnthis->visitDeclRef(VD,
E);
4504 returnthis->emitGetMemberPtr(MemberDecl,
E);
4505 returnthis->emitNullMemberPtr(0,
nullptr,
E);
4511template<
classEmitter>
4520 constRecord::Field *RF = R->
getField(I);
4523 PrimType T= classifyPrim(RF->Decl->getType());
4524 if(!this->visitAPValue(F,
T,
E))
4526 if(!this->emitInitField(
T, RF->Offset,
E))
4529assert(RF->Desc->isPrimitiveArray());
4530 const auto*ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
4531 PrimTypeElemT = classifyPrim(ArrType->getElementType());
4534 if(!this->emitGetPtrField(RF->Offset,
E))
4537 for(
unsignedA = 0, AN = F.
getArraySize(); A != AN; ++A) {
4540 if(!this->emitInitElem(ElemT, A,
E))
4544 if(!this->emitPopPtr(
E))
4547 if(!this->emitGetPtrField(RF->Offset,
E))
4549 if(!this->visitAPValueInitializer(F,
E))
4551 if(!this->emitPopPtr(
E))
4554assert(
false&&
"I don't think this should be possible");
4563 constRecord::Field *RF = R->
getField(UnionField);
4564 PrimType T= classifyPrim(RF->Decl->getType());
4565 if(!this->visitAPValue(F,
T,
E))
4567 returnthis->emitInitField(
T, RF->Offset,
E);
4574template<
classEmitter>
4576 unsignedBuiltinID) {
4577 const Function*
Func= getFunction(
E->getDirectCallee());
4583 if(BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
4584BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
4585BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
4586BuiltinID == Builtin::BI__builtin_function_start) {
4589 returnthis->emitDummyPtr(
E,
E);
4593std::optional<PrimType> ReturnT = classify(
E);
4597std::optional<unsigned> LocalIndex = allocateLocal(
E);
4600 if(!this->emitGetPtrLocal(*LocalIndex,
E))
4604 if(!
Func->isUnevaluatedBuiltin()) {
4606 for(
const auto*Arg :
E->arguments()) {
4607 if(!this->visit(Arg))
4612 if(!this->emitCallBI(
Func,
E, BuiltinID,
E))
4615 if(DiscardResult && !ReturnType->
isVoidType()) {
4617 returnthis->emitPop(*ReturnT,
E);
4623template<
classEmitter>
4625 if(
unsignedBuiltinID =
E->getBuiltinCallee())
4626 returnVisitBuiltinCallExpr(
E, BuiltinID);
4633 returnVisitBuiltinCallExpr(
E, Builtin::BI__builtin_operator_new);
4636 returnVisitBuiltinCallExpr(
E, Builtin::BI__builtin_operator_delete);
4640 if(
const auto*DD = dyn_cast_if_present<CXXDestructorDecl>(FuncDecl);
4641DD && DD->isTrivial())
4644 QualTypeReturnType =
E->getCallReturnType(Ctx.getASTContext());
4645std::optional<PrimType>
T= classify(ReturnType);
4646 boolHasRVO = !ReturnType->
isVoidType() && !
T;
4649 if(DiscardResult) {
4653 if(std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4654 if(!this->emitGetPtrLocal(*LocalIndex,
E))
4661 if(std::optional<unsigned> LocalIndex = allocateLocal(
E)) {
4662 if(!this->emitGetPtrLocal(*LocalIndex,
E))
4666 if(!this->emitDupPtr(
E))
4674 boolIsAssignmentOperatorCall =
false;
4675 if(
const auto*OCE = dyn_cast<CXXOperatorCallExpr>(
E);
4676OCE && OCE->isAssignmentOp()) {
4680assert(Args.size() == 2);
4681IsAssignmentOperatorCall =
true;
4682std::reverse(Args.begin(), Args.end());
4687 if(isa<CXXOperatorCallExpr>(
E)) {
4688 if(
const auto*MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
4689MD && MD->isStatic()) {
4690 if(!this->discard(
E->getArg(0)))
4693Args.erase(Args.begin());
4697std::optional<unsigned> CalleeOffset;
4699 if(
const auto*MC = dyn_cast<CXXMemberCallExpr>(
E)) {
4700 if(!FuncDecl && classifyPrim(
E->getCallee()) ==
PT_MemberPtr) {
4704 const Expr*Callee =
E->getCallee();
4706this->allocateLocalPrimitive(Callee,
PT_MemberPtr,
true,
false);
4707 if(!this->visit(Callee))
4713 if(!this->emitGetMemberPtrBase(
E))
4715}
else if(!this->visit(MC->getImplicitObjectArgument())) {
4718}
else if(!FuncDecl) {
4719 const Expr*Callee =
E->getCallee();
4720CalleeOffset = this->allocateLocalPrimitive(Callee,
PT_FnPtr,
true,
false);
4721 if(!this->visit(Callee))
4723 if(!this->emitSetLocal(
PT_FnPtr, *CalleeOffset,
E))
4729 unsignedArgIndex = 0;
4730 for(
const auto*Arg : Args) {
4731 if(!this->visit(Arg))
4735 if(FuncDecl && NonNullArgs[ArgIndex]) {
4738 if(!this->emitCheckNonNullArg(ArgT, Arg))
4746 if(IsAssignmentOperatorCall) {
4747assert(Args.size() == 2);
4750 if(!this->emitFlip(Arg2T, Arg1T,
E))
4758assert(HasRVO ==
Func->hasRVO());
4760 boolHasQualifier =
false;
4761 if(
const auto*ME = dyn_cast<MemberExpr>(
E->getCallee()))
4762HasQualifier = ME->hasQualifier();
4764 boolIsVirtual =
false;
4765 if(
const auto*MD = dyn_cast<CXXMethodDecl>(FuncDecl))
4766IsVirtual = MD->isVirtual();
4771 if(IsVirtual && !HasQualifier) {
4772uint32_t VarArgSize = 0;
4773 unsignedNumParams =
4774 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4775 for(
unsignedI = NumParams, N =
E->getNumArgs(); I != N; ++I)
4778 if(!this->emitCallVirt(
Func, VarArgSize,
E))
4780}
else if(
Func->isVariadic()) {
4781uint32_t VarArgSize = 0;
4782 unsignedNumParams =
4783 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
4784 for(
unsignedI = NumParams, N =
E->getNumArgs(); I != N; ++I)
4786 if(!this->emitCallVar(
Func, VarArgSize,
E))
4789 if(!this->emitCall(
Func, 0,
E))
4798uint32_t ArgSize = 0;
4799 for(
unsignedI = 0, N =
E->getNumArgs(); I != N; ++I)
4804 if(isa<CXXMemberCallExpr>(
E) && CalleeOffset) {
4807 if(!this->emitGetMemberPtrDecl(
E))
4810 if(!this->emitGetLocal(
PT_FnPtr, *CalleeOffset,
E))
4813 if(!this->emitCallPtr(ArgSize,
E,
E))
4818 if(DiscardResult && !ReturnType->
isVoidType() &&
T)
4819 returnthis->emitPop(*
T,
E);
4824template<
classEmitter>
4828 returnthis->delegate(
E->getExpr());
4831template<
classEmitter>
4835 returnthis->delegate(
E->getExpr());
4838template<
classEmitter>
4843 returnthis->emitConstBool(
E->getValue(),
E);
4846template<
classEmitter>
4853 returnthis->emitNullPtr(Val,
nullptr,
E);
4856template<
classEmitter>
4864 returnthis->emitZero(
T,
E);
4867template<
classEmitter>
4872 if(this->LambdaThisCapture.Offset > 0) {
4873 if(this->LambdaThisCapture.IsPtr)
4874 returnthis->emitGetThisFieldPtr(this->LambdaThisCapture.Offset,
E);
4875 returnthis->emitGetPtrThisField(this->LambdaThisCapture.Offset,
E);
4882 if(!InitStackActive)
4883 returnthis->emitThis(
E);
4885 if(!InitStack.empty()) {
4899 unsignedStartIndex = 0;
4900 unsignedEndIndex = 0;
4902 for(StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
4905EndIndex = StartIndex;
4912 for(; StartIndex > 0; --StartIndex) {
4922 for(
unsignedI = StartIndex; I != EndIndex; ++I) {
4925 if(!InitStack[I].
templateemit<Emitter>(
this,
E))
4930 returnthis->emitThis(
E);
4934 switch(S->getStmtClass()) {
4935 caseStmt::CompoundStmtClass:
4936 returnvisitCompoundStmt(cast<CompoundStmt>(S));
4937 caseStmt::DeclStmtClass:
4938 returnvisitDeclStmt(cast<DeclStmt>(S));
4939 caseStmt::ReturnStmtClass:
4940 returnvisitReturnStmt(cast<ReturnStmt>(S));
4941 caseStmt::IfStmtClass:
4942 returnvisitIfStmt(cast<IfStmt>(S));
4943 caseStmt::WhileStmtClass:
4944 returnvisitWhileStmt(cast<WhileStmt>(S));
4945 caseStmt::DoStmtClass:
4946 returnvisitDoStmt(cast<DoStmt>(S));
4947 caseStmt::ForStmtClass:
4948 returnvisitForStmt(cast<ForStmt>(S));
4949 caseStmt::CXXForRangeStmtClass:
4950 returnvisitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
4951 caseStmt::BreakStmtClass:
4952 returnvisitBreakStmt(cast<BreakStmt>(S));
4953 caseStmt::ContinueStmtClass:
4954 returnvisitContinueStmt(cast<ContinueStmt>(S));
4955 caseStmt::SwitchStmtClass:
4956 returnvisitSwitchStmt(cast<SwitchStmt>(S));
4957 caseStmt::CaseStmtClass:
4958 returnvisitCaseStmt(cast<CaseStmt>(S));
4959 caseStmt::DefaultStmtClass:
4960 returnvisitDefaultStmt(cast<DefaultStmt>(S));
4961 caseStmt::AttributedStmtClass:
4962 returnvisitAttributedStmt(cast<AttributedStmt>(S));
4963 caseStmt::CXXTryStmtClass:
4964 returnvisitCXXTryStmt(cast<CXXTryStmt>(S));
4965 caseStmt::NullStmtClass:
4968 caseStmt::GCCAsmStmtClass:
4969 caseStmt::MSAsmStmtClass:
4970 caseStmt::GotoStmtClass:
4971 returnthis->emitInvalid(S);
4972 caseStmt::LabelStmtClass:
4973 returnthis->visitStmt(cast<LabelStmt>(S)->getSubStmt());
4975 if(
const auto*
E= dyn_cast<Expr>(S))
4976 returnthis->discard(
E);
4982template<
classEmitter>
4985 for(
const auto*InnerStmt : S->body())
4986 if(!visitStmt(InnerStmt))
4988 return Scope.destroyLocals();
4991template<
classEmitter>
4993 for(
const auto*
D: DS->
decls()) {
4998 const auto*VD = dyn_cast<VarDecl>(
D);
5001 if(!this->visitVarDecl(VD))
5005 if(
const auto*DD = dyn_cast<DecompositionDecl>(VD)) {
5006 for(
auto*BD : DD->bindings())
5007 if(
auto*KD = BD->getHoldingVar()) {
5008 if(!this->visitVarDecl(KD))
5017template<
classEmitter>
5019 if(this->InStmtExpr)
5020 returnthis->emitUnsupported(RS);
5026 if(!this->visit(RE))
5028this->emitCleanup();
5029 returnthis->emitRet(*ReturnType, RS);
5030}
else if(RE->getType()->isVoidType()) {
5031 if(!this->visit(RE))
5036 if(!this->emitRVOPtr(RE))
5038 if(!this->visitInitializer(RE))
5040 if(!this->emitPopPtr(RE))
5043this->emitCleanup();
5044 returnthis->emitRetVoid(RS);
5049this->emitCleanup();
5050 returnthis->emitRetVoid(RS);
5054 if(
auto*CondInit = IS->
getInit())
5055 if(!visitStmt(CondInit))
5059 if(!visitDeclStmt(CondDecl))
5064 if(!this->emitIsConstantContext(IS))
5067 if(!this->emitIsConstantContext(IS))
5069 if(!this->emitInv(IS))
5072 if(!this->visitBool(IS->
getCond()))
5077 LabelTyLabelElse = this->getLabel();
5078 LabelTyLabelEnd = this->getLabel();
5079 if(!this->jumpFalse(LabelElse))
5083 if(!visitStmt(IS->
getThen()))
5088 if(!this->jump(LabelEnd))
5090this->emitLabel(LabelElse);
5093 if(!visitStmt(Else))
5098this->emitLabel(LabelEnd);
5100 LabelTyLabelEnd = this->getLabel();
5101 if(!this->jumpFalse(LabelEnd))
5105 if(!visitStmt(IS->
getThen()))
5110this->emitLabel(LabelEnd);
5116template<
classEmitter>
5118 const Expr*Cond = S->getCond();
5119 const Stmt*Body = S->getBody();
5121 LabelTyCondLabel = this->getLabel();
5122 LabelTyEndLabel = this->getLabel();
5125this->fallthrough(CondLabel);
5126this->emitLabel(CondLabel);
5130 if(
const DeclStmt*CondDecl = S->getConditionVariableDeclStmt())
5131 if(!visitDeclStmt(CondDecl))
5134 if(!this->visitBool(Cond))
5136 if(!this->jumpFalse(EndLabel))
5139 if(!this->visitStmt(Body))
5145 if(!this->jump(CondLabel))
5147this->fallthrough(EndLabel);
5148this->emitLabel(EndLabel);
5154 const Expr*Cond = S->getCond();
5155 const Stmt*Body = S->getBody();
5157 LabelTyStartLabel = this->getLabel();
5158 LabelTyEndLabel = this->getLabel();
5159 LabelTyCondLabel = this->getLabel();
5162this->fallthrough(StartLabel);
5163this->emitLabel(StartLabel);
5167 if(!this->visitStmt(Body))
5169this->fallthrough(CondLabel);
5170this->emitLabel(CondLabel);
5171 if(!this->visitBool(Cond))
5177 if(!this->jumpTrue(StartLabel))
5180this->fallthrough(EndLabel);
5181this->emitLabel(EndLabel);
5185template<
classEmitter>
5189 const Expr*Cond = S->getCond();
5190 const Expr*
Inc= S->getInc();
5191 const Stmt*Body = S->getBody();
5193 LabelTyEndLabel = this->getLabel();
5194 LabelTyCondLabel = this->getLabel();
5195 LabelTyIncLabel = this->getLabel();
5198 if(
Init&& !this->visitStmt(
Init))
5201this->fallthrough(CondLabel);
5202this->emitLabel(CondLabel);
5206 if(
const DeclStmt*CondDecl = S->getConditionVariableDeclStmt())
5207 if(!visitDeclStmt(CondDecl))
5211 if(!this->visitBool(Cond))
5213 if(!this->jumpFalse(EndLabel))
5217 if(Body && !this->visitStmt(Body))
5220this->fallthrough(IncLabel);
5221this->emitLabel(IncLabel);
5222 if(
Inc&& !this->discard(
Inc))
5228 if(!this->jump(CondLabel))
5231this->fallthrough(EndLabel);
5232this->emitLabel(EndLabel);
5236template<
classEmitter>
5239 const Expr*Cond = S->getCond();
5240 const Expr*
Inc= S->getInc();
5241 const Stmt*Body = S->getBody();
5242 const Stmt*BeginStmt = S->getBeginStmt();
5243 const Stmt*RangeStmt = S->getRangeStmt();
5244 const Stmt*EndStmt = S->getEndStmt();
5245 const VarDecl*LoopVar = S->getLoopVariable();
5247 LabelTyEndLabel = this->getLabel();
5248 LabelTyCondLabel = this->getLabel();
5249 LabelTyIncLabel = this->getLabel();
5253 if(
Init&& !this->visitStmt(
Init))
5255 if(!this->visitStmt(RangeStmt))
5257 if(!this->visitStmt(BeginStmt))
5259 if(!this->visitStmt(EndStmt))
5263this->fallthrough(CondLabel);
5264this->emitLabel(CondLabel);
5265 if(!this->visitBool(Cond))
5267 if(!this->jumpFalse(EndLabel))
5270 if(!this->visitVarDecl(LoopVar))
5275 if(!this->visitStmt(Body))
5278this->fallthrough(IncLabel);
5279this->emitLabel(IncLabel);
5280 if(!this->discard(
Inc))
5284 if(!this->jump(CondLabel))
5287this->fallthrough(EndLabel);
5288this->emitLabel(EndLabel);
5292template<
classEmitter>
5298 C=
C->getParent())
5299 C->emitDestruction();
5300 returnthis->jump(*BreakLabel);
5303template<
classEmitter>
5309 C&&
C->getParent() != ContinueVarScope;
C=
C->getParent())
5310 C->emitDestruction();
5311 returnthis->jump(*ContinueLabel);
5314template<
classEmitter>
5316 const Expr*Cond = S->getCond();
5320 LabelTyEndLabel = this->getLabel();
5322 unsignedCondVar = this->allocateLocalPrimitive(Cond, CondT,
true,
false);
5324 if(
const auto*CondInit = S->getInit())
5325 if(!visitStmt(CondInit))
5328 if(
const DeclStmt*CondDecl = S->getConditionVariableDeclStmt())
5329 if(!visitDeclStmt(CondDecl))
5333 if(!this->visit(Cond))
5335 if(!this->emitSetLocal(CondT, CondVar, S))
5340 for(
const SwitchCase*SC = S->getSwitchCaseList(); SC;
5341SC = SC->getNextSwitchCase()) {
5342 if(
const auto*CS = dyn_cast<CaseStmt>(SC)) {
5344 if(CS->caseStmtIsGNURange())
5346CaseLabels[SC] = this->getLabel();
5352 if(!this->emitGetLocal(CondT, CondVar, CS))
5354 if(!this->visit(
Value))
5358 if(!this->emitEQ(ValueT, S))
5360 if(!this->jumpTrue(CaseLabels[CS]))
5363assert(!DefaultLabel);
5364DefaultLabel = this->getLabel();
5371 if(!this->jump(*DefaultLabel))
5374 if(!this->jump(EndLabel))
5379 if(!this->visitStmt(S->getBody()))
5381this->emitLabel(EndLabel);
5386template<
classEmitter>
5388this->emitLabel(CaseLabels[S]);
5389 returnthis->visitStmt(S->getSubStmt());
5392template<
classEmitter>
5394this->emitLabel(*DefaultLabel);
5395 returnthis->visitStmt(S->getSubStmt());
5398template<
classEmitter>
5401!this->Ctx.getLangOpts().MSVCCompat) {
5402 for(
const Attr*A : S->getAttrs()) {
5403 auto*AA = dyn_cast<CXXAssumeAttr>(A);
5407assert(isa<NullStmt>(S->getSubStmt()));
5409 const Expr*Assumption = AA->getAssumption();
5417 if(!this->visitBool(Assumption))
5420 if(!this->emitAssume(Assumption))
5426 returnthis->visitStmt(S->getSubStmt());
5429template<
classEmitter>
5432 returnthis->visitStmt(S->getTryBlock());
5435template<
classEmitter>
5439assert(cast<CompoundStmt>(MD->
getBody())->body_empty());
5444 const Function*
Func= this->getFunction(LambdaCallOp);
5447assert(
Func->hasThisPointer());
5450 if(
Func->hasRVO()) {
5451 if(!this->emitRVOPtr(MD))
5459 if(!this->emitNullPtr(0,
nullptr, MD))
5464 autoIt = this->Params.find(PVD);
5465assert(It != this->Params.end());
5469 PrimTypeParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
5470 if(!this->emitGetParam(ParamType, It->second.Offset, MD))
5474 if(!this->emitCall(
Func, 0, LambdaCallOp))
5477this->emitCleanup();
5479 returnthis->emitRet(*ReturnType, MD);
5482 returnthis->emitRetVoid(MD);
5485template<
classEmitter>
5496template<
classEmitter>
5498assert(!ReturnType);
5500 autoemitFieldInitializer = [&](
constRecord::Field *F,
unsignedFieldOffset,
5501 const Expr*InitExpr) ->
bool{
5503 if(InitExpr->getType().isNull())
5506 if(std::optional<PrimType>
T= this->classify(InitExpr)) {
5507 if(!this->visit(InitExpr))
5510 if(F->isBitField())
5511 returnthis->emitInitThisBitField(*
T, F, FieldOffset, InitExpr);
5512 returnthis->emitInitThisField(*
T, FieldOffset, InitExpr);
5517 if(!this->emitGetPtrThisField(FieldOffset, InitExpr))
5520 if(!this->visitInitializer(InitExpr))
5523 returnthis->emitFinishInitPop(InitExpr);
5527 const Record*R = this->getRecord(RD);
5533assert(cast<CompoundStmt>(Ctor->
getBody())->body_empty());
5534 if(!this->emitThis(Ctor))
5543 returnthis->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
5544this->emitRetVoid(Ctor);
5548 for(
const auto*
Init: Ctor->
inits()) {
5552 const Expr*InitExpr =
Init->getInit();
5556 if(!emitFieldInitializer(F, F->Offset, InitExpr))
5558}
else if(
const Type*
Base=
Init->getBaseClass()) {
5559 const auto*BaseDecl =
Base->getAsCXXRecordDecl();
5562 if(
Init->isBaseVirtual()) {
5564 if(!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
5570 constRecord::Base *B = R->
getBase(BaseDecl);
5572 if(!this->emitGetPtrThisBase(B->Offset, InitExpr))
5576 if(!this->visitInitializer(InitExpr))
5578 if(!this->emitFinishInitPop(InitExpr))
5581assert(IFD->getChainingSize() >= 2);
5583 unsignedNestedFieldOffset = 0;
5584 constRecord::Field *NestedField =
nullptr;
5585 for(
const NamedDecl*ND : IFD->chain()) {
5586 const auto*FD = cast<FieldDecl>(ND);
5587 const Record*FieldRecord = this->
P.getOrCreateRecord(FD->getParent());
5588assert(FieldRecord);
5590NestedField = FieldRecord->
getField(FD);
5591assert(NestedField);
5593NestedFieldOffset += NestedField->Offset;
5595assert(NestedField);
5597 if(!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
5600assert(
Init->isDelegatingInitializer());
5601 if(!this->emitThis(InitExpr))
5603 if(!this->visitInitializer(
Init->getInit()))
5605 if(!this->emitPopPtr(InitExpr))
5609 if(!
Scope.destroyLocals())
5613 if(
const auto*Body = Ctor->
getBody())
5614 if(!visitStmt(Body))
5620template<
classEmitter>
5623 const Record*R = this->getRecord(RD);
5628 if(!this->visitStmt(Dtor->
getBody()))
5632 if(!this->emitThis(Dtor))
5638 for(
constRecord::Field &Field : llvm::reverse(R->
fields())) {
5640 if(!
D->isPrimitive() && !
D->isPrimitiveArray()) {
5651 for(
constRecord::Base &
Base: llvm::reverse(R->
bases())) {
5652 if(
Base.R->isAnonymousUnion())
5657 if(!this->emitRecordDestruction(
Base.R, {}))
5664 returnthis->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
5667template<
classEmitter>
5670 if(!this->emitThis(MD))
5679 returnthis->emitMemcpy(MD) && this->emitRet(
PT_Ptr, MD);
5682template<
classEmitter>
5687 if(
const auto*Ctor = dyn_cast<CXXConstructorDecl>(F))
5688 returnthis->compileConstructor(Ctor);
5689 if(
const auto*Dtor = dyn_cast<CXXDestructorDecl>(F))
5690 returnthis->compileDestructor(Dtor);
5693 if(
const auto*MD = dyn_cast<CXXMethodDecl>(F)) {
5697 returnthis->compileUnionCopyAssignmentOperator(MD);
5700 returnthis->emitLambdaStaticInvokerBody(MD);
5704 if(
const auto*Body = F->
getBody())
5705 if(!visitStmt(Body))
5714template<
classEmitter>
5716 const Expr*SubExpr =
E->getSubExpr();
5718 returnthis->VisitComplexUnaryOperator(
E);
5720 returnthis->VisitVectorUnaryOperator(
E);
5722 returnthis->VisitFixedPointUnaryOperator(
E);
5723std::optional<PrimType>
T= classify(SubExpr->
getType());
5725 switch(
E->getOpcode()) {
5728 returnthis->emitInvalid(
E);
5730 returnthis->emitError(
E);
5732 if(!this->visit(SubExpr))
5736 if(!this->emitIncPtr(
E))
5739 returnDiscardResult ? this->emitPopPtr(
E) :
true;
5743 returnDiscardResult ? this->emitIncfPop(getFPOptions(
E),
E)
5744: this->emitIncf(getFPOptions(
E),
E);
5747 returnDiscardResult ? this->emitIncPop(*
T,
E) : this->emitInc(*
T,
E);
5751 returnthis->emitInvalid(
E);
5753 returnthis->emitError(
E);
5755 if(!this->visit(SubExpr))
5759 if(!this->emitDecPtr(
E))
5762 returnDiscardResult ? this->emitPopPtr(
E) :
true;
5766 returnDiscardResult ? this->emitDecfPop(getFPOptions(
E),
E)
5767: this->emitDecf(getFPOptions(
E),
E);
5770 returnDiscardResult ? this->emitDecPop(*
T,
E) : this->emitDec(*
T,
E);
5774 returnthis->emitInvalid(
E);
5776 returnthis->emitError(
E);
5778 if(!this->visit(SubExpr))
5782 if(!this->emitLoadPtr(
E))
5784 if(!this->emitConstUint8(1,
E))
5786 if(!this->emitAddOffsetUint8(
E))
5788 returnDiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5792 if(DiscardResult) {
5794 returnthis->emitIncfPop(getFPOptions(
E),
E);
5795 returnthis->emitIncPop(*
T,
E);
5799 const auto&TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5800 if(!this->emitLoadFloat(
E))
5802 if(!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5804 if(!this->emitAddf(getFPOptions(
E),
E))
5806 if(!this->emitStoreFloat(
E))
5810 if(!this->emitLoad(*
T,
E))
5812 if(!this->emitConst(1,
E))
5814 if(!this->emitAdd(*
T,
E))
5816 if(!this->emitStore(*
T,
E))
5819 return E->
isGLValue() || this->emitLoadPop(*
T,
E);
5823 returnthis->emitInvalid(
E);
5825 returnthis->emitError(
E);
5827 if(!this->visit(SubExpr))
5831 if(!this->emitLoadPtr(
E))
5833 if(!this->emitConstUint8(1,
E))
5835 if(!this->emitSubOffsetUint8(
E))
5837 returnDiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
5841 if(DiscardResult) {
5843 returnthis->emitDecfPop(getFPOptions(
E),
E);
5844 returnthis->emitDecPop(*
T,
E);
5848 const auto&TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
5849 if(!this->emitLoadFloat(
E))
5851 if(!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1),
E))
5853 if(!this->emitSubf(getFPOptions(
E),
E))
5855 if(!this->emitStoreFloat(
E))
5859 if(!this->emitLoad(*
T,
E))
5861 if(!this->emitConst(1,
E))
5863 if(!this->emitSub(*
T,
E))
5865 if(!this->emitStore(*
T,
E))
5868 return E->
isGLValue() || this->emitLoadPop(*
T,
E);
5872 returnthis->emitError(
E);
5875 returnthis->discard(SubExpr);
5877 if(!this->visitBool(SubExpr))
5880 if(!this->emitInv(
E))
5884 returnthis->emitCast(
PT_Bool, ET,
E);
5888 returnthis->emitError(
E);
5890 if(!this->visit(SubExpr))
5892 returnDiscardResult ? this->emitPop(*
T,
E) : this->emitNeg(*
T,
E);
5895 returnthis->emitError(
E);
5897 if(!this->visit(SubExpr))
5899 returnDiscardResult ? this->emitPop(*
T,
E) :
true;
5904 returnthis->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(),
E);
5907 returnthis->delegate(SubExpr);
5909 if(DiscardResult) {
5911 returnthis->discard(SubExpr);
5914 if(!this->visit(SubExpr))
5916 if(classifyPrim(SubExpr) ==
PT_Ptr)
5917 returnthis->emitNarrowPtr(
E);
5922 returnthis->emitError(
E);
5924 if(!this->visit(SubExpr))
5926 returnDiscardResult ? this->emitPop(*
T,
E) : this->emitComp(*
T,
E);
5929 returnthis->delegate(SubExpr);
5932 if(!this->discard(SubExpr))
5934 returnthis->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
5937 returnthis->delegate(SubExpr);
5939assert(
false&&
"Unhandled opcode");
5945template<
classEmitter>
5947 const Expr*SubExpr =
E->getSubExpr();
5951 returnthis->discard(SubExpr);
5953std::optional<PrimType> ResT = classify(
E);
5954 autoprepareResult = [=]() ->
bool{
5956std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
5959 returnthis->emitGetPtrLocal(*LocalIndex,
E);
5966 unsignedSubExprOffset = ~0u;
5967 autocreateTemp = [=, &SubExprOffset]() ->
bool{
5968SubExprOffset = this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
5969 if(!this->visit(SubExpr))
5971 returnthis->emitSetLocal(
PT_Ptr, SubExprOffset,
E);
5975 autogetElem = [=](
unsignedOffset,
unsignedIndex) ->
bool{
5976 if(!this->emitGetLocal(
PT_Ptr, Offset,
E))
5978 returnthis->emitArrayElemPop(ElemT, Index,
E);
5981 switch(
E->getOpcode()) {
5983 if(!prepareResult())
5987 for(
unsignedI = 0; I != 2; ++I) {
5988 if(!getElem(SubExprOffset, I))
5990 if(!this->emitNeg(ElemT,
E))
5992 if(!this->emitInitElem(ElemT, I,
E))
6000 returnthis->delegate(SubExpr);
6003 if(!this->visit(SubExpr))
6005 if(!this->emitComplexBoolCast(SubExpr))
6007 if(!this->emitInv(
E))
6010 returnthis->emitCast(
PT_Bool, ET,
E);
6014 returnthis->emitComplexReal(SubExpr);
6017 if(!this->visit(SubExpr))
6021 if(!this->emitConstUint8(1,
E))
6023 returnthis->emitArrayElemPtrPopUint8(
E);
6028 returnthis->emitArrayElemPop(classifyPrim(
E->
getType()), 1,
E);
6031 if(!this->visit(SubExpr))
6034 if(!this->emitArrayElem(ElemT, 1,
E))
6036 if(!this->emitNeg(ElemT,
E))
6038 if(!this->emitInitElem(ElemT, 1,
E))
6040 returnDiscardResult ? this->emitPopPtr(
E) :
true;
6043 returnthis->delegate(SubExpr);
6046 returnthis->emitInvalid(
E);
6052template<
classEmitter>
6054 const Expr*SubExpr =
E->getSubExpr();
6058 returnthis->discard(SubExpr);
6060 autoUnaryOp =
E->getOpcode();
6061 if(UnaryOp == UO_Extension)
6062 returnthis->delegate(SubExpr);
6064 if(UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
6065UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
6066 returnthis->emitInvalid(
E);
6069 if(UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
6070 returnthis->delegate(SubExpr);
6073std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
6076 if(!this->emitGetPtrLocal(*LocalIndex,
E))
6081 unsignedSubExprOffset =
6082this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
6083 if(!this->visit(SubExpr))
6085 if(!this->emitSetLocal(
PT_Ptr, SubExprOffset,
E))
6090 autogetElem = [=](
unsignedOffset,
unsignedIndex) ->
bool{
6091 if(!this->emitGetLocal(
PT_Ptr, Offset,
E))
6093 returnthis->emitArrayElemPop(ElemT, Index,
E);
6098 for(
unsignedI = 0; I != VecTy->getNumElements(); ++I) {
6099 if(!getElem(SubExprOffset, I))
6101 if(!this->emitNeg(ElemT,
E))
6103 if(!this->emitInitElem(ElemT, I,
E))
6118 for(
unsignedI = 0; I != VecTy->getNumElements(); ++I) {
6119 if(!getElem(SubExprOffset, I))
6122 if(!this->emitPrimCast(ElemT,
PT_Bool, Ctx.getASTContext().
BoolTy,
E))
6124 if(!this->emitInv(
E))
6126 if(!this->emitPrimCast(
PT_Bool, ElemT, VecTy->getElementType(),
E))
6128 if(!this->emitNeg(ElemT,
E))
6130 if(ElemT != ResultVecElemT &&
6131!this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy,
E))
6133 if(!this->emitInitElem(ResultVecElemT, I,
E))
6139 for(
unsignedI = 0; I != VecTy->getNumElements(); ++I) {
6140 if(!getElem(SubExprOffset, I))
6143 if(!this->emitInv(
E))
6146 if(!this->emitComp(ElemT,
E))
6149 if(!this->emitInitElem(ElemT, I,
E))
6154llvm_unreachable(
"Unsupported unary operators should be handled up front");
6159template<
classEmitter>
6164 if(
const auto*ECD = dyn_cast<EnumConstantDecl>(
D)) {
6165 returnthis->emitConst(ECD->getInitVal(),
E);
6166}
else if(
const auto*BD = dyn_cast<BindingDecl>(
D)) {
6167 returnthis->visit(BD->getBinding());
6168}
else if(
const auto*FuncDecl = dyn_cast<FunctionDecl>(
D)) {
6169 const Function*F = getFunction(FuncDecl);
6170 returnF && this->emitGetFnPtr(F,
E);
6171}
else if(
const auto*TPOD = dyn_cast<TemplateParamObjectDecl>(
D)) {
6172 if(std::optional<unsigned> Index =
P.getOrCreateGlobal(
D)) {
6173 if(!this->emitGetPtrGlobal(*Index,
E))
6175 if(std::optional<PrimType>
T= classify(
E->
getType())) {
6176 if(!this->visitAPValue(TPOD->getValue(), *
T,
E))
6178 returnthis->emitInitGlobal(*
T, *Index,
E);
6180 returnthis->visitAPValueInitializer(TPOD->getValue(),
E);
6189 boolIsReference =
D->getType()->isReferenceType();
6192 if(
autoIt = Locals.find(
D); It != Locals.end()) {
6193 const unsignedOffset = It->second.Offset;
6195 returnthis->emitGetLocal(
PT_Ptr, Offset,
E);
6196 returnthis->emitGetPtrLocal(Offset,
E);
6197}
else if(
autoGlobalIndex =
P.getGlobal(
D)) {
6200 returnthis->emitGetGlobal(classifyPrim(
E), *GlobalIndex,
E);
6201 returnthis->emitGetGlobalUnchecked(classifyPrim(
E), *GlobalIndex,
E);
6204 returnthis->emitGetPtrGlobal(*GlobalIndex,
E);
6205}
else if(
const auto*PVD = dyn_cast<ParmVarDecl>(
D)) {
6206 if(
autoIt = this->Params.find(PVD); It != this->Params.end()) {
6207 if(IsReference || !It->second.IsPtr)
6208 returnthis->emitGetParam(classifyPrim(
E), It->second.Offset,
E);
6210 returnthis->emitGetPtrParam(It->second.Offset,
E);
6213 if(
D->getType()->isReferenceType())
6214 returnthis->emitDummyPtr(
D,
E);
6218 autorevisit = [&](
const VarDecl*VD) ->
bool{
6219 autoVarState = this->visitDecl(VD);
6221 if(VarState.notCreated())
6226 returnthis->visitDeclRef(
D,
E);
6230 if(
autoIt = this->LambdaCaptures.find(
D);
6231It != this->LambdaCaptures.end()) {
6232 auto[Offset, IsPtr] = It->second;
6235 returnthis->emitGetThisFieldPtr(Offset,
E);
6236 returnthis->emitGetPtrThisField(Offset,
E);
6237}
else if(
const auto*DRE = dyn_cast<DeclRefExpr>(
E);
6238DRE && DRE->refersToEnclosingVariableOrCapture()) {
6239 if(
const auto*VD = dyn_cast<VarDecl>(
D); VD && VD->isInitCapture())
6244 if(
D== InitializingDecl)
6245 returnthis->emitDummyPtr(
D,
E);
6251 if(
const auto*VD = dyn_cast<VarDecl>(
D);
6252VD && VD->getAnyInitializer() &&
6253VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak())
6255 returnthis->emitDummyPtr(
D,
E);
6259 const auto*VD = dyn_cast<VarDecl>(
D);
6261 returnthis->emitDummyPtr(
D,
E);
6263 const autotypeShouldBeVisited = [&](
QualType T) ->
bool{
6264 if(
T.isConstant(Ctx.getASTContext()))
6270 if(isa<DecompositionDecl>(VD))
6273 if((VD->hasGlobalStorage() || VD->isStaticDataMember()) &&
6274typeShouldBeVisited(VD->getType())) {
6275 if(
const Expr*
Init= VD->getAnyInitializer();
6276 Init&& !
Init->isValueDependent()) {
6282(void)
Init->EvaluateAsInitializer(
V, Ctx.getASTContext(), VD, Notes,
6284 returnthis->visitDeclRef(
D,
E);
6293 if(VD->isLocalVarDecl() && typeShouldBeVisited(VD->getType()) &&
6294VD->getInit() && !VD->getInit()->isValueDependent()) {
6296 if(VD->evaluateValue())
6299 if(!
D->getType()->isReferenceType())
6300 returnthis->emitDummyPtr(
D,
E);
6302 returnthis->emitInvalidDeclRef(cast<DeclRefExpr>(
E),
6306 returnthis->emitDummyPtr(
D,
E);
6309template<
classEmitter>
6311 const auto*
D=
E->getDecl();
6312 returnthis->visitDeclRef(
D,
E);
6317 C->emitDestruction();
6320template<
classEmitter>
6324 if(
const auto*R = Ty->getPointeeCXXRecordDecl())
6326 returnTy->getAsCXXRecordDecl();
6328 const CXXRecordDecl*BaseDecl = extractRecordDecl(BaseType);
6329 const CXXRecordDecl*DerivedDecl = extractRecordDecl(DerivedType);
6331 returnCtx.collectBaseOffset(BaseDecl, DerivedDecl);
6335template<
classEmitter>
6342 constllvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6347 returnthis->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
6348getFPOptions(
E),
E);
6350 returnthis->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
6351getFPOptions(
E),
E);
6355 returnthis->emitCastFloatingIntegral(ToT, getFPOptions(
E),
E);
6360 returnthis->emitCastAP(FromT, Ctx.getBitWidth(ToQT),
E);
6362 returnthis->emitCastAPS(FromT, Ctx.getBitWidth(ToQT),
E);
6366 returnFromT != ToT ? this->emitCast(FromT, ToT,
E) :
true;
6370 constllvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6371 returnthis->emitCastIntegralFloating(FromT, ToSem, getFPOptions(
E),
E);
6379template<
classEmitter>
6384 returnthis->discard(SubExpr);
6386 if(!this->visit(SubExpr))
6389 if(!this->emitConstUint8(0, SubExpr))
6391 returnthis->emitArrayElemPtrPopUint8(SubExpr);
6395 returnthis->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
6399template<
classEmitter>
6401assert(!DiscardResult);
6405 if(!this->emitArrayElem(ElemT, 0,
E))
6408 if(!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(
E),
E))
6411 if(!this->emitCast(ElemT,
PT_Bool,
E))
6416LabelTy LabelTrue = this->getLabel();
6417 if(!this->jumpTrue(LabelTrue))
6420 if(!this->emitArrayElemPop(ElemT, 1,
E))
6423 if(!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(
E),
E))
6426 if(!this->emitCast(ElemT,
PT_Bool,
E))
6430LabelTy EndLabel = this->getLabel();
6431this->jump(EndLabel);
6433this->emitLabel(LabelTrue);
6434 if(!this->emitPopPtr(
E))
6436 if(!this->emitConstBool(
true,
E))
6439this->fallthrough(EndLabel);
6440this->emitLabel(EndLabel);
6445template<
classEmitter>
6448assert(
E->isComparisonOp());
6450assert(!DiscardResult);
6456LHSIsComplex =
true;
6457ElemT = classifyComplexElementType(LHS->
getType());
6458LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true,
6460 if(!this->visit(LHS))
6462 if(!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
6465LHSIsComplex =
false;
6467LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
6468 if(!this->visit(LHS))
6470 if(!this->emitSetLocal(LHST, LHSOffset,
E))
6477RHSIsComplex =
true;
6478ElemT = classifyComplexElementType(RHS->
getType());
6479RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true,
6481 if(!this->visit(RHS))
6483 if(!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
6486RHSIsComplex =
false;
6488RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
6489 if(!this->visit(RHS))
6491 if(!this->emitSetLocal(RHST, RHSOffset,
E))
6495 autogetElem = [&](
unsignedLocalOffset,
unsignedIndex,
6496 boolIsComplex) ->
bool{
6498 if(!this->emitGetLocal(
PT_Ptr, LocalOffset,
E))
6500 returnthis->emitArrayElemPop(ElemT, Index,
E);
6502 returnthis->emitGetLocal(ElemT, LocalOffset,
E);
6505 for(
unsignedI = 0; I != 2; ++I) {
6507 if(!getElem(LHSOffset, I, LHSIsComplex))
6509 if(!getElem(RHSOffset, I, RHSIsComplex))
6512 if(!this->emitEQ(ElemT,
E))
6515 if(!this->emitCastBoolUint8(
E))
6520 if(!this->emitAddUint8(
E))
6522 if(!this->emitConstUint8(2,
E))
6525 if(
E->getOpcode() == BO_EQ) {
6526 if(!this->emitEQUint8(
E))
6528}
else if(
E->getOpcode() == BO_NE) {
6529 if(!this->emitNEUint8(
E))
6536 returnthis->emitCast(
PT_Bool, ResT,
E);
6543template<
classEmitter>
6552 const Function*DtorFunc = getFunction(Dtor);
6557 if(!this->emitDupPtr(
Loc))
6559 returnthis->emitCall(DtorFunc, 0,
Loc);
6564template<
classEmitter>
6589 for(ssize_t I = Desc->
getNumElems() - 1; I >= 0; --I) {
6590 if(!this->emitConstUint64(I,
Loc))
6592 if(!this->emitArrayElemPtrUint64(
Loc))
6594 if(!this->emitDestruction(ElemDesc,
Loc))
6596 if(!this->emitPopPtr(
Loc))
6606 returnthis->emitRecordDestruction(Desc->
ElemRecord,
Loc);
6611template<
classEmitter>
6613assert(!DiscardResult &&
"Should've been checked before");
6615 unsignedDummyID =
P.getOrCreateDummy(
D);
6617 if(!this->emitGetPtrGlobal(DummyID,
E))
6625 returnthis->emitDecayPtr(
PT_Ptr, PT,
E);
6638template<
classEmitter>
6640 const Expr*SubExpr =
E->getSubExpr();
6643std::optional<PrimType> ToT = classify(ToType);
6649std::optional<unsigned> LocalIndex = allocateLocal(
E);
6652 if(!this->emitGetPtrLocal(*LocalIndex,
E))
6662 if(!this->visit(SubExpr))
6664}
else if(std::optional<PrimType> FromT = classify(SubExpr)) {
6665 unsignedTempOffset = allocateLocalPrimitive(
6666SubExpr, *FromT,
true,
false);
6667 if(!this->visit(SubExpr))
6669 if(!this->emitSetLocal(*FromT, TempOffset,
E))
6671 if(!this->emitGetPtrLocal(TempOffset,
E))
6678 if(!this->emitBitCast(
E))
6680 returnDiscardResult ? this->emitPopPtr(
E) :
true;
6684 constllvm::fltSemantics *TargetSemantics =
nullptr;
6686TargetSemantics = &Ctx.getFloatSemantics(ToType);
6692 uint32_tResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
6694 if(!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->
isStdByteType(),
6695ResultBitWidth, TargetSemantics,
E))
6699 returnthis->emitPop(*ToT,
E);
ASTImporterLookupTable & LT
#define EMIT_ARITH_OP(OP)
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
ArrayRef< LValuePathEntry > getLValuePath() const
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
unsigned getStructNumFields() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
bool isMemberPointer() const
unsigned getArraySize() const
@ None
There is no such object (it's outside its lifetime).
bool isNullPointer() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
const LangOptions & getLangOpts() const
ComparisonCategories CompCategories
Types and expressions required to build C++2a three-way comparisons using operator<=>,...
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
AddrLabelExpr - The GNU address of label extension, representing &&label.
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Represents a loop initializing the elements of an array.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Attr - This represents one attribute.
Represents an attribute applied to a statement.
Represents a C++ declaration that introduces decls from somewhere else.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
static bool isCommaOp(Opcode Opc)
static Opcode getOpForCompoundAssignment(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
BreakStmt - This represents a break.
Represents a base class of a C++ class.
Represents binding an expression to a temporary.
A boolean literal, per ([C++ lex.bool] Boolean literals).
Represents a call to a C++ constructor.
Represents a C++ constructor within a class.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Represents a delete expression for memory deallocation and destructor calls, e.g.
Represents a C++ destructor within a class.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Represents a call to an inherited base class constructor from an inheriting constructor.
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a list-initialization with parenthesis.
Represents a C++ struct/union/class.
capture_const_iterator captures_end() const
capture_const_iterator captures_begin() const
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
A rewritten comparison expression that was originally written using operator syntax.
An expression "T()" which creates an rvalue of a non-class type T.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Represents the this expression in C++.
A C++ throw-expression (C++ [except.throw]).
CXXTryStmt - A C++ try block, including all handlers.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
const ComparisonCategoryInfo * lookupInfoForType(QualType Ty) const
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
CompoundLiteralExpr - [C99 6.5.2.5].
CompoundStmt - This represents a group of statements like { stmt stmt }.
Stmt * getStmtExprResult()
Represents the specialization of a concept - evaluates to a prvalue of type bool.
Represents the canonical version of C arrays with a specified constant size.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
ContinueStmt - This represents a continue.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInvalidDecl() const
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
DoStmt - This represents a 'do/while' stmt.
Represents a reference to #emded data.
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
EnumDecl * getDecl() const
Represents an expression â generally a full-expression â that introduces cleanups to be run at the en...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool isValueDependent() const
Determines whether the value of this expression depends on.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
An expression trait intrinsic.
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Represents a member of a struct/union/class.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isReplaceableGlobalAllocationFunction(std::optional< unsigned > *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
bool isDefaulted() const
Whether this function is defaulted.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
bool isNegatedConsteval() const
DeclStmt * getConditionVariableDeclStmt()
If this IfStmt has a condition variable, return the faux DeclStmt associated with the creation of tha...
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
Describes an C or C++ initializer list.
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
APValue & getAsAPValue() const
Get the value of this MSGuidDecl as an APValue.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A pointer to member type per C++ 8.3.3 - Pointers to members.
const Type * getClass() const
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a C++ namespace alias.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
ObjCEncodeExpr, used for @encode in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Helper class for OffsetOfExpr.
@ Array
An index into an array.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
[C99 6.4.2.2] - A predefined identifier such as func.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
QualType withConst() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getCanonicalType() const
bool isConstQualified() const
Determine whether this type is const-qualified.
Represents a struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Base for LValueReferenceType and RValueReferenceType.
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Represents an expression that computes the length of a parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Represents a C++11 static_assert declaration.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Stmt - This represents one statement.
StringLiteral - This represents a string literal expression, e.g.
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumConcatenated)
This is the "fully general" constructor that allows representation of strings formed from multiple co...
Represents a reference to a non-type template parameter that has been substituted with a template arg...
SwitchStmt - This represents a 'switch' stmt.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBooleanType() const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool isMemberPointerType() const
bool isAtomicType() const
bool isStdByteType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isPointerOrReferenceType() const
bool isFunctionType() const
bool isVectorType() const
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
const Expr * getInit() const
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
Scope for storage declared in a compound statement.
A memory block, either on the stack or in the heap.
void invokeDtor()
Invokes the Destructor.
std::byte * rawData()
Returns a pointer to the raw data, including metadata.
Compilation context for expressions.
OptLabelTy BreakLabel
Point to break to.
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E)
bool VisitCXXDeleteExpr(const CXXDeleteExpr *E)
bool VisitOffsetOfExpr(const OffsetOfExpr *E)
bool visitContinueStmt(const ContinueStmt *S)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E)
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
bool visitDeclAndReturn(const VarDecl *VD, bool ConstantContext) override
Toplevel visitDeclAndReturn().
bool VisitTypeTraitExpr(const TypeTraitExpr *E)
bool VisitLambdaExpr(const LambdaExpr *E)
bool VisitMemberExpr(const MemberExpr *E)
bool VisitBinaryOperator(const BinaryOperator *E)
bool visitAttributedStmt(const AttributedStmt *S)
bool VisitPackIndexingExpr(const PackIndexingExpr *E)
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
bool VisitCallExpr(const CallExpr *E)
bool VisitPseudoObjectExpr(const PseudoObjectExpr *E)
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E)
const Function * getFunction(const FunctionDecl *FD)
Returns a function for the given FunctionDecl.
void emitCleanup()
Emits scope cleanup instructions.
bool VisitFixedPointBinOp(const BinaryOperator *E)
bool VisitCastExpr(const CastExpr *E)
bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E)
bool VisitFixedPointUnaryOperator(const UnaryOperator *E)
bool VisitComplexUnaryOperator(const UnaryOperator *E)
llvm::DenseMap< const SwitchCase *, LabelTy > CaseMap
bool visitDeclStmt(const DeclStmt *DS)
bool VisitBlockExpr(const BlockExpr *E)
bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E)
Visit an APValue.
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
bool VisitLogicalBinOp(const BinaryOperator *E)
bool visitCompoundStmt(const CompoundStmt *S)
bool visitDeclRef(const ValueDecl *D, const Expr *E)
Visit the given decl as if we have a reference to it.
bool visitBreakStmt(const BreakStmt *S)
bool visitExpr(const Expr *E, bool DestroyToplevelScope) override
bool visitForStmt(const ForStmt *S)
bool VisitDeclRefExpr(const DeclRefExpr *E)
bool VisitOpaqueValueExpr(const OpaqueValueExpr *E)
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E)
OptLabelTy DefaultLabel
Default case label.
bool VisitStmtExpr(const StmtExpr *E)
std::optional< unsigned > allocateLocal(DeclTy &&Decl, QualType Ty=QualType(), const ValueDecl *ExtendingDecl=nullptr)
Allocates a space storing a local given its type.
bool VisitFixedPointLiteral(const FixedPointLiteral *E)
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
VariableScope< Emitter > * VarScope
Current scope.
VariableScope< Emitter > * ContinueVarScope
Scope to cleanup until when we see a continue statement.
bool VisitCXXNewExpr(const CXXNewExpr *E)
bool VisitCompoundAssignOperator(const CompoundAssignOperator *E)
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init)
Pointer to the array(not the element!) must be on the stack when calling this.
bool delegate(const Expr *E)
Just pass evaluation on to E.
bool discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
CaseMap CaseLabels
Switch case mapping.
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
bool visit(const Expr *E)
Evaluates an expression and places the result on the stack.
const RecordType * getRecordTy(QualType Ty)
Returns a record type from a record or pointer type.
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E)
bool visitInitList(ArrayRef< const Expr * > Inits, const Expr *ArrayFiller, const Expr *E)
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E)
bool VisitPredefinedExpr(const PredefinedExpr *E)
bool VisitSourceLocExpr(const SourceLocExpr *E)
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E)
bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E)
bool visitInitializer(const Expr *E)
Compiles an initializer.
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E)
bool VisitPointerArithBinOp(const BinaryOperator *E)
Perform addition/subtraction of a pointer and an integer or subtraction of two pointers.
bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E)
bool visitDefaultStmt(const DefaultStmt *S)
typename Emitter::LabelTy LabelTy
VarCreationState visitDecl(const VarDecl *VD)
bool visitStmt(const Stmt *S)
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
bool visitAPValueInitializer(const APValue &Val, const Expr *E)
bool VisitVectorUnaryOperator(const UnaryOperator *E)
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
bool VisitRecoveryExpr(const RecoveryExpr *E)
bool VisitRequiresExpr(const RequiresExpr *E)
bool visitReturnStmt(const ReturnStmt *RS)
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitChooseExpr(const ChooseExpr *E)
bool visitFunc(const FunctionDecl *F) override
bool visitCXXForRangeStmt(const CXXForRangeStmt *S)
bool visitCaseStmt(const CaseStmt *S)
bool VisitComplexBinOp(const BinaryOperator *E)
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
bool VisitCXXTypeidExpr(const CXXTypeidExpr *E)
bool VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinID)
OptLabelTy ContinueLabel
Point to continue to.
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
bool visitDoStmt(const DoStmt *S)
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitInitListExpr(const InitListExpr *E)
bool VisitVectorBinOp(const BinaryOperator *E)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
std::optional< unsigned > allocateTemporary(const Expr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
VariableScope< Emitter > * BreakVarScope
Scope to cleanup until when we see a break statement.
std::optional< LabelTy > OptLabelTy
bool VisitEmbedExpr(const EmbedExpr *E)
bool VisitConvertVectorExpr(const ConvertVectorExpr *E)
bool VisitCXXThisExpr(const CXXThisExpr *E)
bool VisitConstantExpr(const ConstantExpr *E)
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool visitSwitchStmt(const SwitchStmt *S)
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E)
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsExtended=false)
Creates a local primitive value.
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool visitWhileStmt(const WhileStmt *S)
bool visitIfStmt(const IfStmt *IS)
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
bool VisitFloatingLiteral(const FloatingLiteral *E)
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
bool VisitGNUNullExpr(const GNUNullExpr *E)
bool VisitImaginaryLiteral(const ImaginaryLiteral *E)
bool VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E)
VarCreationState visitVarDecl(const VarDecl *VD, bool Toplevel=false)
Creates and initializes a variable from the given decl.
bool visitCXXTryStmt(const CXXTryStmt *S)
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Scope used to handle temporaries in toplevel variable declarations.
void addExtended(const Scope::Local &Local) override
DeclScope(Compiler< Emitter > *Ctx, const ValueDecl *VD)
Wrapper around fixed point types.
static FixedPoint zero(llvm::FixedPointSemantics Sem)
unsigned getNumParams() const
bool hasThisPointer() const
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Scope managing label targets.
LabelScope(Compiler< Emitter > *Ctx)
Compiler< Emitter > * Ctx
Compiler instance.
Generic scope for local variables.
bool destroyLocals(const Expr *E=nullptr) override
Explicit destruction of local variables.
void addLocal(const Scope::Local &Local) override
Sets the context for break/continue statements.
typename Compiler< Emitter >::LabelTy LabelTy
LoopScope(Compiler< Emitter > *Ctx, LabelTy BreakLabel, LabelTy ContinueLabel)
typename Compiler< Emitter >::OptLabelTy OptLabelTy
Scope used to handle initialization methods.
OptionScope(Compiler< Emitter > *Ctx, bool NewDiscardResult, bool NewInitializing)
Root constructor, compiling or discarding primitives.
Context to manage declaration lifetimes.
Structure/Class descriptor.
bool isUnion() const
Checks if the record is a union.
const CXXDestructorDecl * getDestructor() const
Returns the destructor of the record, if any.
const Field * getField(const FieldDecl *FD) const
Returns a field.
llvm::iterator_range< const_base_iter > bases() const
const Base * getVirtualBase(const RecordDecl *RD) const
Returns a virtual base descriptor.
unsigned getNumFields() const
bool isAnonymousUnion() const
Checks if the record is an anonymous union.
llvm::iterator_range< const_field_iter > fields() const
const Base * getBase(const RecordDecl *FD) const
Returns a base descriptor.
Describes the statement/declaration an opcode was generated from.
StmtExprScope(Compiler< Emitter > *Ctx)
typename Compiler< Emitter >::LabelTy LabelTy
typename Compiler< Emitter >::OptLabelTy OptLabelTy
SwitchScope(Compiler< Emitter > *Ctx, CaseMap &&CaseLabels, LabelTy BreakLabel, OptLabelTy DefaultLabel)
typename Compiler< Emitter >::CaseMap CaseMap
Scope chain managing the variable lifetimes.
Compiler< Emitter > * Ctx
Compiler instance.
static llvm::RoundingMode getRoundingMode(FPOptions FPO)
bool Div(InterpState &S, CodePtr OpPC)
1) Pops the RHS from the stack.
constexpr bool isPtrType(PrimType T)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool InitScope(InterpState &S, CodePtr OpPC, uint32_t I)
bool LE(InterpState &S, CodePtr OpPC)
PrimType
Enumeration of the primitive types of the VM.
bool Mul(InterpState &S, CodePtr OpPC)
llvm::BitVector collectNonNullArgs(const FunctionDecl *F, const llvm::ArrayRef< const Expr * > &Args)
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
constexpr bool isIntegralType(PrimType T)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
@ SD_Static
Static storage duration.
const FunctionProtoType * T
@ Success
Template argument deduction was successful.
Describes a memory block created by an allocation site.
unsigned getNumElems() const
Returns the number of elements stored in the block.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
const Descriptor *const ElemDesc
Descriptor of the array element.
static constexpr MetadataSize InlineDescMD
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
const Record *const ElemRecord
Pointer to the record, if block contains records.
bool isArray() const
Checks if the descriptor is of an array.
Descriptor used for global variables.
GlobalInitState InitState
static InitLink InitList()
static InitLink Elem(unsigned Index)
bool emit(Compiler< Emitter > *Ctx, const Expr *E) const
static InitLink Field(unsigned Offset)
static InitLink Decl(const ValueDecl *D)
static InitLink Temp(unsigned Offset)
Information about a local's storage.
State encapsulating if a the variable creation has been successful, unsuccessful, or no variable has ...
static VarCreationState NotCreated()
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4