29 if (
const auto *CE = dyn_cast_if_present<ConstantExpr>(
E);
30 CE && CE->hasAPValueResult() &&
32 return CE->getResultAsAPSInt().getBoolValue();
43 OldInitializingDecl(
Ctx->InitializingDecl) {
44 Ctx->InitializingDecl = VD;
49 this->
Ctx->InitializingDecl = OldInitializingDecl;
50 this->
Ctx->InitStack.pop_back();
63 bool NewInitializing,
bool NewToLValue)
64 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
65 OldInitializing(Ctx->
Initializing), OldToLValue(Ctx->ToLValue) {
66 Ctx->DiscardResult = NewDiscardResult;
67 Ctx->Initializing = NewInitializing;
68 Ctx->ToLValue = NewToLValue;
72 Ctx->DiscardResult = OldDiscardResult;
73 Ctx->Initializing = OldInitializing;
74 Ctx->ToLValue = OldToLValue;
81 bool OldDiscardResult;
86template <
class Emitter>
90 return Ctx->emitThis(
E);
93 return Ctx->emitGetPtrFieldPop(
Offset,
E);
95 return Ctx->emitGetPtrLocal(
Offset,
E);
97 return Ctx->visitDeclRef(
D,
E);
99 if (!Ctx->emitConstUint32(
Offset,
E))
101 return Ctx->emitArrayElemPtrPopUint32(
E);
103 return Ctx->emitRVOPtr(
E);
107 llvm_unreachable(
"Unhandled InitLink kind");
119 : Ctx(Ctx), OldBreakLabel(Ctx->BreakLabel),
120 OldContinueLabel(Ctx->ContinueLabel),
121 OldBreakVarScope(Ctx->BreakVarScope),
122 OldContinueVarScope(Ctx->ContinueVarScope) {
130 this->Ctx->BreakLabel = OldBreakLabel;
131 this->Ctx->ContinueLabel = OldContinueLabel;
132 this->Ctx->ContinueVarScope = OldContinueVarScope;
133 this->Ctx->BreakVarScope = OldBreakVarScope;
153 : Ctx(Ctx), OldBreakLabel(Ctx->BreakLabel),
154 OldDefaultLabel(this->Ctx->DefaultLabel),
155 OldCaseLabels(
std::move(this->Ctx->CaseLabels)),
156 OldLabelVarScope(Ctx->BreakVarScope) {
159 this->Ctx->
CaseLabels = std::move(CaseLabels);
164 this->Ctx->BreakLabel = OldBreakLabel;
165 this->Ctx->DefaultLabel = OldDefaultLabel;
166 this->Ctx->CaseLabels = std::move(OldCaseLabels);
167 this->Ctx->BreakVarScope = OldLabelVarScope;
181 Ctx->InStmtExpr =
true;
199 : Ctx(Ctx), OldFlag(Ctx->LocOverride), Enabled(Enabled) {
202 Ctx->LocOverride = NewValue;
207 Ctx->LocOverride = OldFlag;
212 std::optional<SourceInfo> OldFlag;
219template <
class Emitter>
224 return this->delegate(SubExpr);
227 case CK_LValueToRValue: {
229 return this->delegate(SubExpr);
232 return this->emitInvalidCast(CastKind::Volatile,
true, CE);
238 if (
const auto *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
240 bool IsReference =
D->getType()->isReferenceType();
244 if (
auto GlobalIndex =
P.getGlobal(
D))
245 return this->emitGetGlobal(*SubExprT, *GlobalIndex, CE);
246 }
else if (
auto It = Locals.find(
D); It != Locals.end()) {
247 return this->emitGetLocal(*SubExprT, It->second.Offset, CE);
248 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(
D)) {
249 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
250 return this->emitGetParam(*SubExprT, It->second.Offset, CE);
262 if (!this->emitGetPtrLocal(*LocalIndex, CE))
266 if (!this->visit(SubExpr))
270 return this->emitLoadPop(*SubExprT, CE);
275 return this->emitMemcpy(CE);
278 case CK_DerivedToBaseMemberPointer: {
284 unsigned DerivedOffset =
286 FromMP->getMostRecentCXXRecordDecl());
288 if (!this->delegate(SubExpr))
291 return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
294 case CK_BaseToDerivedMemberPointer: {
300 unsigned DerivedOffset =
301 Ctx.collectBaseOffset(FromMP->getMostRecentCXXRecordDecl(),
304 if (!this->delegate(SubExpr))
306 return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
309 case CK_UncheckedDerivedToBase:
310 case CK_DerivedToBase: {
311 if (!this->delegate(SubExpr))
315 if (
const auto *PT = dyn_cast<PointerType>(Ty))
316 return PT->getPointeeType()->getAsCXXRecordDecl();
317 return Ty->getAsCXXRecordDecl();
324 if (B->isVirtual()) {
325 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))
327 CurType = B->getType();
329 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
330 if (!this->emitGetPtrBasePop(
333 CurType = B->getType();
340 case CK_BaseToDerived: {
341 if (!this->delegate(SubExpr))
343 unsigned DerivedOffset =
349 return this->emitGetPtrDerivedPop(DerivedOffset,
354 case CK_FloatingCast: {
359 if (!this->visit(SubExpr))
361 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
365 case CK_IntegralToFloating: {
368 if (!this->visit(SubExpr))
370 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
371 return this->emitCastIntegralFloating(
372 classifyPrim(SubExpr), TargetSemantics, getFPOptions(CE), CE);
375 case CK_FloatingToBoolean: {
379 if (
const auto *FL = dyn_cast<FloatingLiteral>(SubExpr))
380 return this->emitConstBool(FL->getValue().isNonZero(), CE);
381 if (!this->visit(SubExpr))
383 return this->emitCastFloatingIntegralBool(getFPOptions(CE), CE);
386 case CK_FloatingToIntegral: {
389 if (!this->visit(SubExpr))
393 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->
getType()),
394 getFPOptions(CE), CE);
396 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->
getType()),
397 getFPOptions(CE), CE);
399 return this->emitCastFloatingIntegral(ToT, getFPOptions(CE), CE);
402 case CK_NullToPointer:
403 case CK_NullToMemberPointer: {
408 if (!PointeeType.
isNull()) {
410 Desc =
P.createDescriptor(SubExpr, *
T);
412 Desc =
P.createDescriptor(SubExpr, PointeeType.
getTypePtr(),
417 return this->emitNull(classifyPrim(CE->
getType()), Val, Desc, CE);
420 case CK_PointerToIntegral: {
421 if (!this->visit(SubExpr))
427 if (!this->emitDecayPtr(FromT,
PT_Ptr, CE))
433 return this->emitCastPointerIntegralAP(Ctx.getBitWidth(CE->
getType()),
436 return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(CE->
getType()),
438 return this->emitCastPointerIntegral(
T, CE);
441 case CK_ArrayToPointerDecay: {
442 if (!this->visit(SubExpr))
444 return this->emitArrayDecay(CE);
447 case CK_IntegralToPointer: {
450 if (!this->visit(SubExpr))
458 Desc =
P.createDescriptor(SubExpr, *
T);
465 if (!this->emitGetIntPtr(
T, Desc, CE))
468 PrimType DestPtrT = classifyPrim(PtrType);
473 return this->emitDecayPtr(
PT_Ptr, DestPtrT, CE);
476 case CK_AtomicToNonAtomic:
477 case CK_ConstructorConversion:
478 case CK_FunctionToPointerDecay:
479 case CK_NonAtomicToAtomic:
481 case CK_UserDefinedConversion:
482 case CK_AddressSpaceConversion:
483 case CK_CPointerToObjCPointerCast:
484 return this->delegate(SubExpr);
491 return this->emitInvalidCast(CastKind::Reinterpret,
true, CE);
497 return this->emitBuiltinBitCast(CE);
508 return this->delegate(SubExpr);
511 if (!this->visit(SubExpr))
515 return this->emitFnPtrCast(CE);
522 if (!this->visit(SubExpr))
524 return this->emitDecayPtr(*FromT, *ToT, CE);
526 case CK_IntegralToBoolean:
527 case CK_FixedPointToBoolean: {
533 if (
const auto *IL = dyn_cast<IntegerLiteral>(SubExpr))
534 return this->emitConst(IL->getValue(), CE);
535 if (!this->visit(SubExpr))
537 return this->emitCast(*FromT, classifyPrim(CE), CE);
540 case CK_BooleanToSignedIntegral:
541 case CK_IntegralCast: {
548 if (
const auto *IL = dyn_cast<IntegerLiteral>(SubExpr)) {
551 return this->emitConst(IL->getValue(), CE);
552 if (!this->emitConst(IL->getValue(), SubExpr))
555 if (!this->visit(SubExpr))
563 if (!ED->isFixed()) {
564 if (!this->emitCheckEnumValue(*FromT, ED, CE))
570 if (!this->emitCastAP(*FromT, Ctx.getBitWidth(CE->
getType()), CE))
573 if (!this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->
getType()), CE))
578 if (!this->emitCast(*FromT, *ToT, CE))
581 if (CE->
getCastKind() == CK_BooleanToSignedIntegral)
582 return this->emitNeg(*ToT, CE);
586 case CK_PointerToBoolean:
587 case CK_MemberPointerToBoolean: {
590 if (!this->visit(SubExpr))
592 return this->emitIsNonNull(PtrT, CE);
595 case CK_IntegralComplexToBoolean:
596 case CK_FloatingComplexToBoolean: {
597 if (!this->visit(SubExpr))
599 return this->emitComplexBoolCast(SubExpr);
602 case CK_IntegralComplexToReal:
603 case CK_FloatingComplexToReal:
604 return this->emitComplexReal(SubExpr);
606 case CK_IntegralRealToComplex:
607 case CK_FloatingRealToComplex: {
614 if (!this->emitGetPtrLocal(*LocalIndex, CE))
620 if (!this->visitArrayElemInit(0, SubExpr,
T))
623 if (!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
625 return this->emitInitElem(
T, 1, SubExpr);
628 case CK_IntegralComplexCast:
629 case CK_FloatingComplexCast:
630 case CK_IntegralComplexToFloatingComplex:
631 case CK_FloatingComplexToIntegralComplex: {
638 if (!this->emitGetPtrLocal(*LocalIndex, CE))
645 unsigned SubExprOffset =
646 allocateLocalPrimitive(SubExpr,
PT_Ptr,
true);
647 if (!this->visit(SubExpr))
649 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, CE))
655 PrimType DestElemT = classifyPrim(DestElemType);
657 for (
unsigned I = 0; I != 2; ++I) {
658 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, CE))
660 if (!this->emitArrayElemPop(SourceElemT, I, CE))
664 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
668 if (!this->emitInitElem(DestElemT, I, CE))
674 case CK_VectorSplat: {
675 assert(!canClassify(CE->
getType()));
676 assert(canClassify(SubExpr->
getType()));
683 if (!this->emitGetPtrLocal(*LocalIndex, CE))
689 unsigned ElemOffset =
690 allocateLocalPrimitive(SubExpr, ElemT,
true);
693 if (!this->visit(SubExpr))
695 if (classifyPrim(SubExpr) ==
PT_Ptr && !this->emitLoadPop(ElemT, CE))
698 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
701 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
702 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
704 if (!this->emitInitElem(ElemT, I, CE))
711 case CK_HLSLVectorTruncation: {
714 assert(!DiscardResult);
716 if (!this->visit(SubExpr))
718 return this->emitArrayElemPop(*ResultT, 0, CE);
727 if (!this->emitGetPtrLocal(*LocalIndex, CE))
732 if (!this->visit(SubExpr))
734 return this->emitCopyArray(classifyVectorElementType(CE->
getType()), 0, 0,
738 case CK_IntegralToFixedPoint: {
739 if (!this->visit(SubExpr))
744 return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->
getType()),
747 case CK_FloatingToFixedPoint: {
748 if (!this->visit(SubExpr))
753 return this->emitCastFloatingFixedPoint(Sem, CE);
755 case CK_FixedPointToFloating: {
756 if (!this->visit(SubExpr))
758 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
759 return this->emitCastFixedPointFloating(TargetSemantics, CE);
761 case CK_FixedPointToIntegral: {
762 if (!this->visit(SubExpr))
764 return this->emitCastFixedPointIntegral(classifyPrim(CE->
getType()), CE);
766 case CK_FixedPointCast: {
767 if (!this->visit(SubExpr))
771 return this->emitCastFixedPoint(Sem, CE);
778 return this->emitInvalid(CE);
780 llvm_unreachable(
"Unhandled clang::CastKind enum");
783template <
class Emitter>
785 return this->emitBuiltinBitCast(
E);
788template <
class Emitter>
793 return this->emitConst(
LE->getValue(),
LE);
796template <
class Emitter>
802 return this->emitFloat(F,
E);
805template <
class Emitter>
815 if (!this->emitGetPtrLocal(*LocalIndex,
E))
819 const Expr *SubExpr =
E->getSubExpr();
822 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
824 if (!this->emitInitElem(SubExprT, 0, SubExpr))
826 return this->visitArrayElemInit(1, SubExpr, SubExprT);
829template <
class Emitter>
842template <
class Emitter>
844 return this->delegate(
E->getSubExpr());
847template <
class Emitter>
851 return this->VisitLogicalBinOp(BO);
864 return this->delegate(RHS);
868 return this->VisitComplexBinOp(BO);
870 return this->VisitVectorBinOp(BO);
874 return this->emitComplexComparison(LHS, RHS, BO);
876 return this->VisitFixedPointBinOp(BO);
879 if (!this->visit(LHS))
882 if (!this->visit(RHS))
885 if (!this->emitToMemberPtr(BO))
891 if (!this->emitCastMemberPtrPtr(BO))
893 return DiscardResult ? this->emitPopPtr(BO) :
true;
914 if (!this->emitGetPtrLocal(*ResultIndex, BO))
918 if (!visit(LHS) || !visit(RHS))
921 return this->emitCMP3(*
LT, CmpInfo, BO);
924 if (!
LT || !RT || !
T)
930 return this->VisitPointerArithBinOp(BO);
934 return this->visitAssignment(LHS, RHS, BO);
936 if (!visit(LHS) || !visit(RHS))
941 auto MaybeCastToBool = [
this,
T, BO](
bool Result) {
945 return this->emitPop(*
T, BO);
947 return this->emitCast(
PT_Bool, *
T, BO);
951 auto Discard = [
this,
T, BO](
bool Result) {
954 return DiscardResult ? this->emitPop(*
T, BO) :
true;
959 return MaybeCastToBool(this->emitEQ(*
LT, BO));
961 return MaybeCastToBool(this->emitNE(*
LT, BO));
963 return MaybeCastToBool(this->emitLT(*
LT, BO));
965 return MaybeCastToBool(this->emitLE(*
LT, BO));
967 return MaybeCastToBool(this->emitGT(*
LT, BO));
969 return MaybeCastToBool(this->emitGE(*
LT, BO));
972 return Discard(this->emitSubf(getFPOptions(BO), BO));
973 return Discard(this->emitSub(*
T, BO));
976 return Discard(this->emitAddf(getFPOptions(BO), BO));
977 return Discard(this->emitAdd(*
T, BO));
980 return Discard(this->emitMulf(getFPOptions(BO), BO));
981 return Discard(this->emitMul(*
T, BO));
983 return Discard(this->emitRem(*
T, BO));
986 return Discard(this->emitDivf(getFPOptions(BO), BO));
987 return Discard(this->emitDiv(*
T, BO));
989 return Discard(this->emitBitAnd(*
T, BO));
991 return Discard(this->emitBitOr(*
T, BO));
993 return Discard(this->emitShl(*
LT, *RT, BO));
995 return Discard(this->emitShr(*
LT, *RT, BO));
997 return Discard(this->emitBitXor(*
T, BO));
1000 llvm_unreachable(
"Already handled earlier");
1005 llvm_unreachable(
"Unhandled binary op");
1010template <
class Emitter>
1013 const Expr *LHS =
E->getLHS();
1014 const Expr *RHS =
E->getRHS();
1016 if ((Op != BO_Add && Op != BO_Sub) ||
1028 if (!this->visit(
E))
1031 return this->emitDecayPtr(
T,
PT_Ptr,
E);
1040 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *
LT))
1044 if (!this->emitSubPtr(IntT,
E))
1046 return DiscardResult ? this->emitPop(IntT,
E) :
true;
1051 if (!visitAsPointer(RHS, *RT))
1053 if (!this->visit(LHS))
1057 if (!visitAsPointer(LHS, *
LT))
1059 if (!this->visit(RHS))
1069 if (!this->emitAddOffset(OffsetType,
E))
1072 if (classifyPrim(
E) !=
PT_Ptr)
1073 return this->emitDecayPtr(
PT_Ptr, classifyPrim(
E),
E);
1077 if (!this->emitSubOffset(OffsetType,
E))
1080 if (classifyPrim(
E) !=
PT_Ptr)
1081 return this->emitDecayPtr(
PT_Ptr, classifyPrim(
E),
E);
1088template <
class Emitter>
1090 assert(
E->isLogicalOp());
1092 const Expr *LHS =
E->getLHS();
1093 const Expr *RHS =
E->getRHS();
1098 LabelTy LabelTrue = this->getLabel();
1099 LabelTy LabelEnd = this->getLabel();
1101 if (!this->visitBool(LHS))
1103 if (!this->jumpTrue(LabelTrue))
1106 if (!this->visitBool(RHS))
1108 if (!this->jump(LabelEnd))
1111 this->emitLabel(LabelTrue);
1112 this->emitConstBool(
true,
E);
1113 this->fallthrough(LabelEnd);
1114 this->emitLabel(LabelEnd);
1117 assert(Op == BO_LAnd);
1120 LabelTy LabelFalse = this->getLabel();
1121 LabelTy LabelEnd = this->getLabel();
1123 if (!this->visitBool(LHS))
1125 if (!this->jumpFalse(LabelFalse))
1128 if (!this->visitBool(RHS))
1130 if (!this->jump(LabelEnd))
1133 this->emitLabel(LabelFalse);
1134 this->emitConstBool(
false,
E);
1135 this->fallthrough(LabelEnd);
1136 this->emitLabel(LabelEnd);
1140 return this->emitPopBool(
E);
1149template <
class Emitter>
1156 if (!this->emitGetPtrLocal(*LocalIndex,
E))
1162 const Expr *LHS =
E->getLHS();
1163 const Expr *RHS =
E->getRHS();
1166 unsigned ResultOffset = ~0u;
1168 ResultOffset = this->allocateLocalPrimitive(
E,
PT_Ptr,
true);
1171 if (!this->DiscardResult) {
1172 if (!this->emitDupPtr(
E))
1174 if (!this->emitSetLocal(
PT_Ptr, ResultOffset,
E))
1179 LHSType = AT->getValueType();
1182 RHSType = AT->getValueType();
1191 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1196 if (!this->visit(LHS))
1198 if (!this->visit(RHS))
1200 return this->emitMulc(ElemT,
E);
1203 if (Op == BO_Div && RHSIsComplex) {
1205 PrimType ElemT = classifyPrim(ElemQT);
1210 if (!LHSIsComplex) {
1215 LHSOffset = *LocalIndex;
1217 if (!this->emitGetPtrLocal(LHSOffset,
E))
1220 if (!this->visit(LHS))
1223 if (!this->emitInitElem(ElemT, 0,
E))
1226 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1228 if (!this->emitInitElem(ElemT, 1,
E))
1231 if (!this->visit(LHS))
1235 if (!this->visit(RHS))
1237 return this->emitDivc(ElemT,
E);
1242 LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true);
1243 if (!this->visit(LHS))
1245 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1248 PrimType LHST = classifyPrim(LHSType);
1249 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true);
1250 if (!this->visit(LHS))
1252 if (!this->emitSetLocal(LHST, LHSOffset,
E))
1259 RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true);
1260 if (!this->visit(RHS))
1262 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1265 PrimType RHST = classifyPrim(RHSType);
1266 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true);
1267 if (!this->visit(RHS))
1269 if (!this->emitSetLocal(RHST, RHSOffset,
E))
1276 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1277 unsigned ElemIndex,
unsigned Offset,
1278 const Expr *
E) ->
bool {
1280 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
1282 return this->emitArrayElemPop(classifyComplexElementType(
E->
getType()),
1285 if (ElemIndex == 0 || !LoadZero)
1286 return this->emitGetLocal(classifyPrim(
E->
getType()), Offset,
E);
1287 return this->visitZeroInitializer(classifyPrim(
E->
getType()),
E->
getType(),
1292 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1294 if (!this->DiscardResult) {
1295 if (!this->emitGetLocal(
PT_Ptr, ResultOffset,
E))
1302 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1305 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1308 if (!this->emitAddf(getFPOptions(
E),
E))
1311 if (!this->emitAdd(ResultElemT,
E))
1316 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1319 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1322 if (!this->emitSubf(getFPOptions(
E),
E))
1325 if (!this->emitSub(ResultElemT,
E))
1330 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1333 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1337 if (!this->emitMulf(getFPOptions(
E),
E))
1340 if (!this->emitMul(ResultElemT,
E))
1345 assert(!RHSIsComplex);
1346 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1349 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1353 if (!this->emitDivf(getFPOptions(
E),
E))
1356 if (!this->emitDiv(ResultElemT,
E))
1365 if (!this->DiscardResult) {
1367 if (!this->emitInitElemPop(ResultElemT, ElemIndex,
E))
1370 if (!this->emitPop(ResultElemT,
E))
1377template <
class Emitter>
1379 const Expr *LHS =
E->getLHS();
1380 const Expr *RHS =
E->getRHS();
1381 assert(!
E->isCommaOp() &&
1382 "Comma op should be handled in VisitBinaryOperator");
1392 if (!
Initializing && !
E->isCompoundAssignmentOp() && !
E->isAssignmentOp()) {
1396 if (!this->emitGetPtrLocal(*LocalIndex,
E))
1401 auto Op =
E->isCompoundAssignmentOp()
1409 if (
E->getOpcode() == BO_Assign) {
1413 if (!this->visit(LHS))
1415 if (!this->visit(RHS))
1417 if (!this->emitCopyArray(ElemT, 0, 0, VecTy->getNumElements(),
E))
1420 return this->emitPopPtr(
E);
1425 unsigned LHSOffset =
1426 this->allocateLocalPrimitive(LHS,
PT_Ptr,
true);
1427 if (!this->visit(LHS))
1429 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
1433 unsigned RHSOffset =
1434 this->allocateLocalPrimitive(RHS,
PT_Ptr,
true);
1435 if (!this->visit(RHS))
1437 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
1440 if (
E->isCompoundAssignmentOp() && !this->emitGetLocal(
PT_Ptr, LHSOffset,
E))
1445 bool NeedIntPromot = ElemT ==
PT_Bool && (
E->isBitwiseOp() ||
E->isShiftOp());
1449 if (NeedIntPromot) {
1452 PromotT = classifyPrim(PromotTy);
1456 auto getElem = [=](
unsigned Offset,
PrimType ElemT,
unsigned Index) {
1457 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
1459 if (!this->emitArrayElemPop(ElemT, Index,
E))
1461 if (
E->isLogicalOp()) {
1462 if (!this->emitPrimCast(ElemT,
PT_Bool, Ctx.getASTContext().
BoolTy,
E))
1464 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(),
E))
1466 }
else if (NeedIntPromot) {
1467 if (!this->emitPrimCast(ElemT, PromotT, PromotTy,
E))
1473#define EMIT_ARITH_OP(OP) \
1475 if (ElemT == PT_Float) { \
1476 if (!this->emit##OP##f(getFPOptions(E), E)) \
1479 if (!this->emit##OP(ElemT, E)) \
1485 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
1486 if (!getElem(LHSOffset, ElemT, I))
1488 if (!getElem(RHSOffset, RHSElemT, I))
1500 if (!this->emitRem(ElemT,
E))
1504 if (!this->emitBitAnd(OpT,
E))
1508 if (!this->emitBitOr(OpT,
E))
1512 if (!this->emitBitXor(OpT,
E))
1516 if (!this->emitShl(OpT, RHSElemT,
E))
1520 if (!this->emitShr(OpT, RHSElemT,
E))
1524 if (!this->emitEQ(ElemT,
E))
1528 if (!this->emitNE(ElemT,
E))
1532 if (!this->emitLE(ElemT,
E))
1536 if (!this->emitLT(ElemT,
E))
1540 if (!this->emitGE(ElemT,
E))
1544 if (!this->emitGT(ElemT,
E))
1549 if (!this->emitBitAnd(ResultElemT,
E))
1554 if (!this->emitBitOr(ResultElemT,
E))
1558 return this->emitInvalid(
E);
1566 if (
E->isComparisonOp()) {
1567 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(),
E))
1569 if (!this->emitNeg(ResultElemT,
E))
1575 if (NeedIntPromot &&
1576 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(),
E))
1580 if (!this->emitInitElem(ResultElemT, I,
E))
1584 if (DiscardResult &&
E->isCompoundAssignmentOp() && !this->emitPopPtr(
E))
1589template <
class Emitter>
1591 const Expr *LHS =
E->getLHS();
1592 const Expr *RHS =
E->getRHS();
1593 const ASTContext &ASTCtx = Ctx.getASTContext();
1599 auto LHSSemaInt = LHSSema.toOpaqueInt();
1601 auto RHSSemaInt = RHSSema.toOpaqueInt();
1603 if (!this->visit(LHS))
1606 if (!this->emitCastIntegralFixedPoint(classifyPrim(LHS->
getType()),
1611 if (!this->visit(RHS))
1614 if (!this->emitCastIntegralFixedPoint(classifyPrim(RHS->
getType()),
1620 auto ConvertResult = [&](
bool R) ->
bool {
1624 auto CommonSema = LHSSema.getCommonSemantics(RHSSema).toOpaqueInt();
1625 if (ResultSema != CommonSema)
1626 return this->emitCastFixedPoint(ResultSema,
E);
1630 auto MaybeCastToBool = [&](
bool Result) {
1635 return this->emitPop(
T,
E);
1641 switch (
E->getOpcode()) {
1643 return MaybeCastToBool(this->emitEQFixedPoint(
E));
1645 return MaybeCastToBool(this->emitNEFixedPoint(
E));
1647 return MaybeCastToBool(this->emitLTFixedPoint(
E));
1649 return MaybeCastToBool(this->emitLEFixedPoint(
E));
1651 return MaybeCastToBool(this->emitGTFixedPoint(
E));
1653 return MaybeCastToBool(this->emitGEFixedPoint(
E));
1655 return ConvertResult(this->emitAddFixedPoint(
E));
1657 return ConvertResult(this->emitSubFixedPoint(
E));
1659 return ConvertResult(this->emitMulFixedPoint(
E));
1661 return ConvertResult(this->emitDivFixedPoint(
E));
1663 return ConvertResult(this->emitShiftFixedPoint(
true,
E));
1665 return ConvertResult(this->emitShiftFixedPoint(
false,
E));
1668 return this->emitInvalid(
E);
1671 llvm_unreachable(
"unhandled binop opcode");
1674template <
class Emitter>
1676 const Expr *SubExpr =
E->getSubExpr();
1679 switch (
E->getOpcode()) {
1681 return this->delegate(SubExpr);
1683 if (!this->visit(SubExpr))
1685 return this->emitNegFixedPoint(
E);
1690 llvm_unreachable(
"Unhandled unary opcode");
1693template <
class Emitter>
1699 return this->visitZeroInitializer(*
T, QT,
E);
1707 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1708 CXXRD && CXXRD->getNumVBases() > 0) {
1713 const Record *R = getRecord(QT);
1718 return this->visitZeroRecordInitializer(R,
E);
1725 return this->visitZeroArrayInitializer(QT,
E);
1729 QualType ElemQT = ComplexTy->getElementType();
1730 PrimType ElemT = classifyPrim(ElemQT);
1731 for (
unsigned I = 0; I < 2; ++I) {
1732 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1734 if (!this->emitInitElem(ElemT, I,
E))
1741 unsigned NumVecElements = VecT->getNumElements();
1742 QualType ElemQT = VecT->getElementType();
1743 PrimType ElemT = classifyPrim(ElemQT);
1745 for (
unsigned I = 0; I < NumVecElements; ++I) {
1746 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
1748 if (!this->emitInitElem(ElemT, I,
E))
1757template <
class Emitter>
1759 const Expr *LHS =
E->getLHS();
1760 const Expr *RHS =
E->getRHS();
1761 const Expr *Index =
E->getIdx();
1767 for (
const Expr *SubExpr : {LHS, RHS}) {
1768 if (!this->visit(SubExpr)) {
1775 if (SubExpr ==
Base &&
Base->getType()->isPointerType()) {
1776 if (!this->emitExpandPtr(
E))
1787 return this->emitError(
E);
1790 if (!this->emitFlip(
PT_Ptr, *IndexT,
E))
1794 if (!this->emitArrayElemPtrPop(*IndexT,
E))
1797 return this->emitPopPtr(
E);
1801template <
class Emitter>
1803 const Expr *ArrayFiller,
const Expr *
E) {
1808 QT = AT->getValueType();
1811 if (Inits.size() == 0)
1813 return this->emitInvalid(
E);
1817 if (DiscardResult) {
1827 assert(!DiscardResult);
1828 if (Inits.size() == 0)
1829 return this->visitZeroInitializer(*
T, QT,
E);
1830 assert(Inits.size() == 1);
1831 return this->delegate(Inits[0]);
1835 const Record *R = getRecord(QT);
1837 if (Inits.size() == 1 &&
E->
getType() == Inits[0]->getType())
1838 return this->delegate(Inits[0]);
1843 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
1848 if (!this->visit(
Init))
1851 bool BitField = FieldToInit->isBitField();
1853 return this->emitInitBitFieldActivate(
T, FieldToInit,
E);
1855 return this->emitInitBitField(
T, FieldToInit,
E);
1857 return this->emitInitFieldActivate(
T, FieldToInit->Offset,
E);
1858 return this->emitInitField(
T, FieldToInit->Offset,
E);
1861 auto initCompositeField = [=](
const Record::Field *FieldToInit,
1869 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
1875 if (!this->visitInitializer(
Init))
1877 return this->emitPopPtr(
E);
1881 if (Inits.size() == 0) {
1882 if (!this->visitZeroRecordInitializer(R,
E))
1887 if (
const auto *ILE = dyn_cast<InitListExpr>(
E))
1888 FToInit = ILE->getInitializedFieldInUnion();
1890 FToInit = cast<CXXParenListInitExpr>(
E)->getInitializedFieldInUnion();
1892 const Record::Field *FieldToInit = R->
getField(FToInit);
1894 if (!initPrimitiveField(FieldToInit,
Init, *
T,
true))
1897 if (!initCompositeField(FieldToInit,
Init,
true))
1901 return this->emitFinishInit(
E);
1905 unsigned InitIndex = 0;
1908 while (InitIndex < R->getNumFields() &&
1913 const Record::Field *FieldToInit = R->
getField(InitIndex);
1914 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1919 if (
const Record::Base *B = R->
getBase(
Init->getType())) {
1920 if (!this->emitGetPtrBase(B->Offset,
Init))
1923 if (!this->visitInitializer(
Init))
1926 if (!this->emitFinishInitPop(
E))
1931 const Record::Field *FieldToInit = R->
getField(InitIndex);
1932 if (!initCompositeField(FieldToInit,
Init))
1938 return this->emitFinishInit(
E);
1942 if (Inits.size() == 1 && QT == Inits[0]->getType())
1943 return this->delegate(Inits[0]);
1949 if (!this->emitCheckArraySize(NumElems,
E))
1953 unsigned ElementIndex = 0;
1955 if (
const auto *EmbedS =
1956 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1961 if (!this->emitConst(IL->
getValue(), classifyPrim(IL),
Init))
1964 if (!this->emitCastIntegralFloating(classifyPrim(IL), Sem,
1965 getFPOptions(
E),
E))
1971 return this->emitInitElem(TargetT, ElemIndex, IL);
1973 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
1976 if (!this->visitArrayElemInit(ElementIndex,
Init, InitT))
1985 for (; ElementIndex != NumElems; ++ElementIndex) {
1986 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller, InitT))
1991 return this->emitFinishInit(
E);
1995 unsigned NumInits = Inits.size();
1998 return this->delegate(Inits[0]);
2000 QualType ElemQT = ComplexTy->getElementType();
2001 PrimType ElemT = classifyPrim(ElemQT);
2002 if (NumInits == 0) {
2004 for (
unsigned I = 0; I < 2; ++I) {
2005 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
2007 if (!this->emitInitElem(ElemT, I,
E))
2010 }
else if (NumInits == 2) {
2011 unsigned InitIndex = 0;
2013 if (!this->visit(
Init))
2016 if (!this->emitInitElem(ElemT, InitIndex,
E))
2025 unsigned NumVecElements = VecT->getNumElements();
2026 assert(NumVecElements >= Inits.size());
2028 QualType ElemQT = VecT->getElementType();
2029 PrimType ElemT = classifyPrim(ElemQT);
2032 unsigned InitIndex = 0;
2034 if (!this->visit(
Init))
2039 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
2040 if (!this->emitCopyArray(ElemT, 0, InitIndex,
2041 InitVecT->getNumElements(),
E))
2043 InitIndex += InitVecT->getNumElements();
2045 if (!this->emitInitElem(ElemT, InitIndex,
E))
2051 assert(InitIndex <= NumVecElements);
2054 for (; InitIndex != NumVecElements; ++InitIndex) {
2055 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
2057 if (!this->emitInitElem(ElemT, InitIndex,
E))
2068template <
class Emitter>
2073 if (!this->visit(
Init))
2075 return this->emitInitElem(*InitT, ElemIndex,
Init);
2081 if (!this->emitConstUint32(ElemIndex,
Init))
2083 if (!this->emitArrayElemPtrUint32(
Init))
2085 if (!this->visitInitializer(
Init))
2087 return this->emitFinishInitPop(
Init);
2090template <
class Emitter>
2093 bool Activate,
bool IsOperatorCall) {
2094 assert(VarScope->getKind() == ScopeKind::Call);
2095 llvm::BitVector NonNullArgs;
2096 if (FuncDecl && FuncDecl->
hasAttr<NonNullAttr>())
2099 bool ExplicitMemberFn =
false;
2100 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl))
2101 ExplicitMemberFn = MD->isExplicitObjectMemberFunction();
2103 unsigned ArgIndex = 0;
2104 for (
const Expr *Arg : Args) {
2105 if (canClassify(Arg)) {
2106 if (!this->visit(Arg))
2114 unsigned DeclIndex = ArgIndex - IsOperatorCall + ExplicitMemberFn;
2115 if (DeclIndex < FuncDecl->getNumParams())
2116 Source = FuncDecl->
getParamDecl(ArgIndex - IsOperatorCall +
2121 allocateLocal(std::move(Source), Arg->getType(),
2122 nullptr, ScopeKind::Call);
2126 if (!this->emitGetPtrLocal(*LocalIndex, Arg))
2129 if (!this->visitInitializer(Arg))
2134 if (!this->emitActivate(Arg))
2138 if (!NonNullArgs.empty() && NonNullArgs[ArgIndex]) {
2141 if (!this->emitCheckNonNullArg(ArgT, Arg))
2152template <
class Emitter>
2154 return this->visitInitList(
E->inits(),
E->getArrayFiller(),
E);
2157template <
class Emitter>
2160 return this->visitInitList(
E->getInitExprs(),
E->getArrayFiller(),
E);
2163template <
class Emitter>
2166 return this->delegate(
E->getReplacement());
2169template <
class Emitter>
2172 if (
T &&
E->hasAPValueResult()) {
2179 if (this->visitAPValue(
E->getAPValueResult(), *
T,
E))
2182 return this->delegate(
E->getSubExpr());
2185template <
class Emitter>
2187 auto It =
E->begin();
2188 return this->visit(*It);
2193 bool AlignOfReturnsPreferred =
2194 ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
2202 if (
T.getQualifiers().hasUnaligned())
2208 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2214template <
class Emitter>
2218 const ASTContext &ASTCtx = Ctx.getASTContext();
2220 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2221 QualType ArgType =
E->getTypeOfArgument();
2233 return this->emitInvalid(
E);
2235 if (Kind == UETT_SizeOf)
2244 return this->emitConst(Size.getQuantity(),
E);
2247 if (Kind == UETT_CountOf) {
2253 if (
const auto *CAT =
2257 return this->emitConst(CAT->getSize(),
E);
2267 if (VAT->getElementType()->isArrayType()) {
2268 std::optional<APSInt> Res =
2270 ? VAT->getSizeExpr()->getIntegerConstantExpr(ASTCtx)
2275 return this->emitConst(*Res,
E);
2280 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2283 if (
E->isArgumentType()) {
2284 QualType ArgType =
E->getTypeOfArgument();
2297 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2300 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
2310 return this->emitConst(Size.getQuantity(),
E);
2313 if (Kind == UETT_VectorElements) {
2314 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>())
2315 return this->emitConst(VT->getNumElements(),
E);
2316 assert(
E->getTypeOfArgument()->isSizelessVectorType());
2317 return this->emitSizelessVectorElementSize(
E);
2320 if (Kind == UETT_VecStep) {
2321 if (
const auto *VT =
E->getTypeOfArgument()->getAs<
VectorType>()) {
2322 unsigned N = VT->getNumElements();
2329 return this->emitConst(N,
E);
2331 return this->emitConst(1,
E);
2334 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2335 assert(
E->isArgumentType());
2341 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2342 if (
E->getArgumentType()->isDependentType())
2343 return this->emitInvalid(
E);
2345 return this->emitConst(
2346 const_cast<ASTContext &
>(ASTCtx).getPointerAuthTypeDiscriminator(
2347 E->getArgumentType()),
2354template <
class Emitter>
2365 const auto maybeLoadValue = [&]() ->
bool {
2369 return this->emitLoadPop(*
T,
E);
2373 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
2377 if (
auto GlobalIndex =
P.getGlobal(VD))
2378 return this->emitGetPtrGlobal(*GlobalIndex,
E) && maybeLoadValue();
2382 if (!isa<FieldDecl>(
Member)) {
2383 if (!this->
discard(Base) && !this->emitSideEffect(
E))
2386 return this->visitDeclRef(
Member,
E);
2390 if (!this->delegate(
Base))
2393 if (!this->visit(
Base))
2398 const auto *FD = cast<FieldDecl>(
Member);
2400 const Record *R = getRecord(RD);
2403 const Record::Field *F = R->
getField(FD);
2405 if (F->Decl->getType()->isReferenceType())
2406 return this->emitGetFieldPop(
PT_Ptr, F->Offset,
E) && maybeLoadValue();
2407 return this->emitGetPtrFieldPop(F->Offset,
E) && maybeLoadValue();
2410template <
class Emitter>
2416 return this->emitConst(*ArrayIndex,
E);
2419template <
class Emitter>
2422 assert(!DiscardResult);
2431 const Expr *SubExpr =
E->getSubExpr();
2432 size_t Size =
E->getArraySize().getZExtValue();
2438 for (
size_t I = 0; I != Size; ++I) {
2442 if (!this->visitArrayElemInit(I, SubExpr, SubExprT))
2450template <
class Emitter>
2452 const Expr *SourceExpr =
E->getSourceExpr();
2457 return this->visitInitializer(SourceExpr);
2460 if (
auto It = OpaqueExprs.find(
E); It != OpaqueExprs.end())
2461 return this->emitGetLocal(SubExprT, It->second,
E);
2463 if (!this->visit(SourceExpr))
2469 unsigned LocalIndex = allocateLocalPrimitive(
E, SubExprT,
true);
2470 if (!this->emitSetLocal(SubExprT, LocalIndex,
E))
2475 if (!DiscardResult) {
2476 if (!this->emitGetLocal(SubExprT, LocalIndex,
E))
2481 OpaqueExprs.insert({
E, LocalIndex});
2486template <
class Emitter>
2490 const Expr *TrueExpr =
E->getTrueExpr();
2491 const Expr *FalseExpr =
E->getFalseExpr();
2493 auto visitChildExpr = [&](
const Expr *
E) ->
bool {
2495 if (!this->delegate(
E))
2497 return S.destroyLocals();
2502 return visitChildExpr(TrueExpr);
2503 return visitChildExpr(FalseExpr);
2506 bool IsBcpCall =
false;
2507 if (
const auto *CE = dyn_cast<CallExpr>(
Condition->IgnoreParenCasts());
2508 CE && CE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) {
2512 LabelTy LabelEnd = this->getLabel();
2513 LabelTy LabelFalse = this->getLabel();
2516 if (!this->emitStartSpeculation(
E))
2524 if (this->checkingForUndefinedBehavior()) {
2527 if (!this->
discard(FalseExpr))
2533 if (!this->jumpFalse(LabelFalse))
2535 if (!visitChildExpr(TrueExpr))
2537 if (!this->jump(LabelEnd))
2539 this->emitLabel(LabelFalse);
2540 if (!visitChildExpr(FalseExpr))
2542 this->fallthrough(LabelEnd);
2543 this->emitLabel(LabelEnd);
2546 return this->emitEndSpeculation(
E);
2550template <
class Emitter>
2556 unsigned StringIndex =
P.createGlobalString(
E);
2557 return this->emitGetPtrGlobal(StringIndex,
E);
2563 assert(CAT &&
"a string literal that's not a constant array?");
2568 unsigned N = std::min(ArraySize,
E->getLength());
2569 unsigned CharWidth =
E->getCharByteWidth();
2571 for (
unsigned I = 0; I != N; ++I) {
2572 uint32_t CodeUnit =
E->getCodeUnit(I);
2574 if (CharWidth == 1) {
2575 this->emitConstSint8(CodeUnit,
E);
2576 this->emitInitElemSint8(I,
E);
2577 }
else if (CharWidth == 2) {
2578 this->emitConstUint16(CodeUnit,
E);
2579 this->emitInitElemUint16(I,
E);
2580 }
else if (CharWidth == 4) {
2581 this->emitConstUint32(CodeUnit,
E);
2582 this->emitInitElemUint32(I,
E);
2584 llvm_unreachable(
"unsupported character width");
2589 for (
unsigned I = N; I != ArraySize; ++I) {
2590 if (CharWidth == 1) {
2591 this->emitConstSint8(0,
E);
2592 this->emitInitElemSint8(I,
E);
2593 }
else if (CharWidth == 2) {
2594 this->emitConstUint16(0,
E);
2595 this->emitInitElemUint16(I,
E);
2596 }
else if (CharWidth == 4) {
2597 this->emitConstUint32(0,
E);
2598 this->emitInitElemUint32(I,
E);
2600 llvm_unreachable(
"unsupported character width");
2607template <
class Emitter>
2611 return this->emitDummyPtr(
E,
E);
2614template <
class Emitter>
2616 auto &A = Ctx.getASTContext();
2622 return this->delegate(SL);
2625template <
class Emitter>
2633 auto &A = Ctx.getASTContext();
2634 std::string ResultStr =
E->ComputeName(A);
2637 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
2638 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
2639 ArraySizeModifier::Normal, 0);
2643 false, ArrayTy,
E->getLocation());
2645 unsigned StringIndex =
P.createGlobalString(SL);
2646 return this->emitGetPtrGlobal(StringIndex,
E);
2649template <
class Emitter>
2653 return this->emitConst(
E->getValue(),
E);
2656template <
class Emitter>
2660 const Expr *LHS =
E->getLHS();
2661 const Expr *RHS =
E->getRHS();
2663 QualType LHSComputationType =
E->getComputationLHSType();
2664 QualType ResultType =
E->getComputationResultType();
2673 PrimType LHST = classifyPrim(LHSType);
2681 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2682 if (!this->emitSetLocal(*RT, TempOffset,
E))
2688 if (!this->emitLoad(LHST,
E))
2692 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
2693 LHSComputationType,
E))
2697 if (!this->emitGetLocal(*RT, TempOffset,
E))
2700 switch (
E->getOpcode()) {
2702 if (!this->emitAddf(getFPOptions(
E),
E))
2706 if (!this->emitSubf(getFPOptions(
E),
E))
2710 if (!this->emitMulf(getFPOptions(
E),
E))
2714 if (!this->emitDivf(getFPOptions(
E),
E))
2721 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->
getType(),
E))
2725 return this->emitStorePop(LHST,
E);
2726 return this->emitStore(LHST,
E);
2729template <
class Emitter>
2733 const Expr *LHS =
E->getLHS();
2734 const Expr *RHS =
E->getRHS();
2738 if (Op != BO_AddAssign && Op != BO_SubAssign)
2747 if (!this->emitLoad(*
LT, LHS))
2753 if (Op == BO_AddAssign) {
2754 if (!this->emitAddOffset(*RT,
E))
2757 if (!this->emitSubOffset(*RT,
E))
2762 return this->emitStorePopPtr(
E);
2763 return this->emitStorePtr(
E);
2766template <
class Emitter>
2770 return VisitVectorBinOp(
E);
2772 const Expr *LHS =
E->getLHS();
2773 const Expr *RHS =
E->getRHS();
2774 OptPrimType LHSComputationT = classify(
E->getComputationLHSType());
2780 return this->visit(RHS) && this->visit(LHS) && this->emitError(
E);
2782 if (!
LT || !RT || !ResultT || !LHSComputationT)
2789 return VisitFloatCompoundAssignOperator(
E);
2792 return VisitPointerCompoundAssignOperator(
E);
2805 unsigned TempOffset = this->allocateLocalPrimitive(
E, *RT,
true);
2807 if (!this->emitSetLocal(*RT, TempOffset,
E))
2814 if (!this->emitLoad(*
LT,
E))
2816 if (
LT != LHSComputationT) {
2817 if (!this->emitCast(*
LT, *LHSComputationT,
E))
2822 if (!this->emitGetLocal(*RT, TempOffset,
E))
2826 switch (
E->getOpcode()) {
2828 if (!this->emitAdd(*LHSComputationT,
E))
2832 if (!this->emitSub(*LHSComputationT,
E))
2836 if (!this->emitMul(*LHSComputationT,
E))
2840 if (!this->emitDiv(*LHSComputationT,
E))
2844 if (!this->emitRem(*LHSComputationT,
E))
2848 if (!this->emitShl(*LHSComputationT, *RT,
E))
2852 if (!this->emitShr(*LHSComputationT, *RT,
E))
2856 if (!this->emitBitAnd(*LHSComputationT,
E))
2860 if (!this->emitBitXor(*LHSComputationT,
E))
2864 if (!this->emitBitOr(*LHSComputationT,
E))
2868 llvm_unreachable(
"Unimplemented compound assign operator");
2872 if (ResultT != LHSComputationT) {
2873 if (!this->emitCast(*LHSComputationT, *ResultT,
E))
2878 if (DiscardResult) {
2880 return this->emitStoreBitFieldPop(*ResultT,
E);
2881 return this->emitStorePop(*ResultT,
E);
2884 return this->emitStoreBitField(*ResultT,
E);
2885 return this->emitStore(*ResultT,
E);
2888template <
class Emitter>
2891 const Expr *SubExpr =
E->getSubExpr();
2896template <
class Emitter>
2899 const Expr *SubExpr =
E->getSubExpr();
2903 return this->delegate(SubExpr);
2908 return this->
discard(SubExpr);
2915 std::optional<unsigned> GlobalIndex =
P.createGlobal(
E);
2920 E->getLifetimeExtendedTemporaryDecl();
2925 if (!this->visit(SubExpr))
2928 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl,
E))
2931 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex,
E))
2934 return this->emitGetPtrGlobal(*GlobalIndex,
E);
2937 if (!this->checkLiteralType(SubExpr))
2940 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
2942 if (!this->visitInitializer(SubExpr))
2945 return this->emitInitGlobalTempComp(TempDecl,
E);
2952 unsigned LocalIndex =
2953 allocateLocalPrimitive(
E, *SubExprT, IsConst,
E->getExtendingDecl());
2954 if (!this->visit(SubExpr))
2956 if (!this->emitSetLocal(*SubExprT, LocalIndex,
E))
2958 return this->emitGetPtrLocal(LocalIndex,
E);
2961 if (!this->checkLiteralType(SubExpr))
2966 allocateLocal(
E, Inner->getType(),
E->getExtendingDecl())) {
2968 if (!this->emitGetPtrLocal(*LocalIndex,
E))
2970 return this->visitInitializer(SubExpr) && this->emitFinishInit(
E);
2976template <
class Emitter>
2979 const Expr *SubExpr =
E->getSubExpr();
2982 return this->delegate(SubExpr);
2987 if (!this->visit(SubExpr))
2991 return this->emitPopPtr(
E);
2995template <
class Emitter>
3003 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
3007 if (
E->isFileScope()) {
3010 return this->delegate(
Init);
3012 std::optional<unsigned> GlobalIndex =
P.createGlobal(
E);
3016 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
3021 if (
P.isGlobalInitialized(*GlobalIndex))
3025 if (!this->visit(
Init))
3027 return this->emitInitGlobal(*
T, *GlobalIndex,
E);
3030 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
3036 return this->delegate(
Init);
3039 unsigned LocalIndex;
3041 LocalIndex = this->allocateLocalPrimitive(
Init, *
T,
false);
3043 LocalIndex = *MaybeIndex;
3047 if (!this->emitGetPtrLocal(LocalIndex,
E))
3051 return this->visit(
Init) && this->emitInit(*
T,
E);
3052 return this->visitInitializer(
Init) && this->emitFinishInit(
E);
3055template <
class Emitter>
3059 if (
E->isStoredAsBoolean()) {
3061 return this->emitConstBool(
E->getBoolValue(),
E);
3062 return this->emitConst(
E->getBoolValue(),
E);
3065 return this->visitAPValue(
E->getAPValue(),
T,
E);
3068template <
class Emitter>
3072 return this->emitConst(
E->getValue(),
E);
3075template <
class Emitter>
3081 const Record *R =
P.getOrCreateRecord(
E->getLambdaClass());
3085 auto *CaptureInitIt =
E->capture_init_begin();
3088 for (
const Record::Field &F : R->
fields()) {
3090 if (!
Init ||
Init->containsErrors())
3095 if (!this->visit(
Init))
3098 if (!this->emitInitField(*
T, F.Offset,
E))
3101 if (!this->emitGetPtrField(F.Offset,
E))
3104 if (!this->visitInitializer(
Init))
3107 if (!this->emitPopPtr(
E))
3115template <
class Emitter>
3121 unsigned StringIndex =
P.createGlobalString(
E->getFunctionName(),
E);
3122 return this->emitGetPtrGlobal(StringIndex,
E);
3125 return this->delegate(
E->getFunctionName());
3128template <
class Emitter>
3130 if (
E->getSubExpr() && !this->discard(
E->getSubExpr()))
3133 return this->emitInvalid(
E);
3136template <
class Emitter>
3139 const Expr *SubExpr =
E->getSubExpr();
3145 return this->emitInvalidCast(CastKind::Reinterpret,
true,
E);
3153 PointeeFromT = classify(SubExpr->
getType());
3159 PointeeToT = classify(
E->
getType());
3162 if (PointeeToT && PointeeFromT) {
3169 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal,
E))
3172 if (
E->getCastKind() == CK_LValueBitCast)
3173 return this->delegate(SubExpr);
3174 return this->VisitCastExpr(
E);
3178 bool Fatal = (ToT != FromT);
3179 if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal,
E))
3182 return this->VisitCastExpr(
E);
3185template <
class Emitter>
3189 if (!this->emitInvalidCast(CastKind::Dynamic,
false,
E))
3193 return this->VisitCastExpr(
E);
3196template <
class Emitter>
3202 return this->emitConstBool(
E->getValue(),
E);
3205template <
class Emitter>
3208 assert(!canClassify(
T));
3215 if (DiscardResult) {
3224 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3233 return this->visitInitializer(
E->getArg(0));
3236 if (
E->requiresZeroInitialization()) {
3239 if (!this->visitZeroRecordInitializer(R,
E))
3252 assert(
Func->hasThisPointer());
3253 assert(!
Func->hasRVO());
3257 if (!this->emitDupPtr(
E))
3261 for (
const auto *Arg :
E->arguments()) {
3262 if (!this->visit(Arg))
3266 if (
Func->isVariadic()) {
3267 uint32_t VarArgSize = 0;
3268 unsigned NumParams =
Func->getNumWrittenParams();
3269 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I) {
3273 if (!this->emitCallVar(
Func, VarArgSize,
E))
3276 if (!this->emitCall(
Func, 0,
E)) {
3281 (void)this->emitPopPtr(
E);
3287 return this->emitPopPtr(
E);
3288 return this->emitFinishInit(
E);
3304 for (
size_t I = 0; I != NumElems; ++I) {
3305 if (!this->emitConstUint64(I,
E))
3307 if (!this->emitArrayElemPtrUint64(
E))
3311 for (
const auto *Arg :
E->arguments()) {
3312 if (!this->visit(Arg))
3316 if (!this->emitCall(
Func, 0,
E))
3325template <
class Emitter>
3331 E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
3335 assert(Val.
isInt());
3337 return this->emitConst(I,
E);
3344 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
3345 return this->visit(LValueExpr);
3354 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
3356 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(UGCD);
3360 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
3364 const APValue &
V = UGCD->getValue();
3365 for (
unsigned I = 0, N = R->
getNumFields(); I != N; ++I) {
3366 const Record::Field *F = R->
getField(I);
3367 const APValue &FieldValue =
V.getStructField(I);
3369 PrimType FieldT = classifyPrim(F->Decl->getType());
3371 if (!this->visitAPValue(FieldValue, FieldT,
E))
3373 if (!this->emitInitField(FieldT, F->Offset,
E))
3381template <
class Emitter>
3383 unsigned N =
E->getNumComponents();
3387 for (
unsigned I = 0; I != N; ++I) {
3390 const Expr *ArrayIndexExpr =
E->getIndexExpr(
Node.getArrayExprIndex());
3393 if (DiscardResult) {
3394 if (!this->
discard(ArrayIndexExpr))
3399 if (!this->visit(ArrayIndexExpr))
3413 return this->emitOffsetOf(
T,
E,
E);
3416template <
class Emitter>
3425 return this->visitZeroInitializer(*
T, Ty,
E);
3432 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3437 QualType ElemQT = CT->getElementType();
3438 PrimType ElemT = classifyPrim(ElemQT);
3440 for (
unsigned I = 0; I != 2; ++I) {
3441 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
3443 if (!this->emitInitElem(ElemT, I,
E))
3455 if (!this->emitGetPtrLocal(*LocalIndex,
E))
3460 QualType ElemQT = VT->getElementType();
3461 PrimType ElemT = classifyPrim(ElemQT);
3463 for (
unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
3464 if (!this->visitZeroInitializer(ElemT, ElemQT,
E))
3466 if (!this->emitInitElem(ElemT, I,
E))
3475template <
class Emitter>
3477 return this->emitConst(
E->getPackLength(),
E);
3480template <
class Emitter>
3483 return this->delegate(
E->getResultExpr());
3486template <
class Emitter>
3488 return this->delegate(
E->getChosenSubExpr());
3491template <
class Emitter>
3496 return this->emitConst(
E->getValue(),
E);
3499template <
class Emitter>
3504 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
3505 const Function *F = this->getFunction(Ctor);
3522 if (!this->emitGetParam(PT, Offset,
E))
3527 return this->emitCall(F, 0,
E);
3532template <
class Emitter>
3536 QualType ElementType =
E->getAllocatedType();
3538 unsigned PlacementArgs =
E->getNumPlacementArgs();
3540 const Expr *PlacementDest =
nullptr;
3541 bool IsNoThrow =
false;
3543 if (PlacementArgs != 0) {
3552 if (PlacementArgs == 1) {
3553 const Expr *Arg1 =
E->getPlacementArg(0);
3560 if (!this->emitInvalidNewDeleteExpr(
E,
E))
3565 if (OperatorNew->isReservedGlobalPlacementOperator())
3566 PlacementDest = Arg1;
3570 return this->emitInvalid(
E);
3572 }
else if (!OperatorNew
3573 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
3574 return this->emitInvalidNewDeleteExpr(
E,
E);
3577 if (!PlacementDest) {
3582 Desc =
P.createDescriptor(
E, *ElemT,
nullptr,
3585 Desc =
P.createDescriptor(
3588 false,
false,
false,
3594 std::optional<const Expr *> ArraySizeExpr =
E->getArraySize();
3598 const Expr *Stripped = *ArraySizeExpr;
3599 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
3600 Stripped = ICE->getSubExpr())
3601 if (ICE->getCastKind() != CK_NoOp &&
3602 ICE->getCastKind() != CK_IntegralCast)
3609 allocateLocalPrimitive(Stripped,
SizeT,
false);
3610 if (!this->visit(Stripped))
3612 if (!this->emitSetLocal(
SizeT, ArrayLen,
E))
3615 if (PlacementDest) {
3616 if (!this->visit(PlacementDest))
3618 if (!this->emitStartLifetime(
E))
3620 if (!this->emitGetLocal(
SizeT, ArrayLen,
E))
3622 if (!this->emitCheckNewTypeMismatchArray(
SizeT,
E,
E))
3625 if (!this->emitGetLocal(
SizeT, ArrayLen,
E))
3630 if (!this->emitAllocN(
SizeT, *ElemT,
E, IsNoThrow,
E))
3634 if (!this->emitAllocCN(
SizeT, Desc, IsNoThrow,
E))
3641 size_t StaticInitElems = 0;
3642 const Expr *DynamicInit =
nullptr;
3645 StaticInitElems = CAT->getZExtSize();
3646 if (!this->visitInitializer(
Init))
3649 if (
const auto *ILE = dyn_cast<InitListExpr>(
Init);
3650 ILE && ILE->hasArrayFiller())
3651 DynamicInit = ILE->getArrayFiller();
3665 const Function *CtorFunc =
nullptr;
3666 if (
const auto *CE = dyn_cast<CXXConstructExpr>(
Init)) {
3667 CtorFunc = getFunction(CE->getConstructor());
3670 }
else if (!DynamicInit)
3673 LabelTy EndLabel = this->getLabel();
3674 LabelTy StartLabel = this->getLabel();
3679 if (!this->emitDupPtr(
E))
3681 if (!this->emitNullPtr(0,
nullptr,
E))
3683 if (!this->emitEQPtr(
E))
3685 if (!this->jumpTrue(EndLabel))
3691 allocateLocalPrimitive(Stripped,
SizeT,
false);
3692 if (!this->emitConst(StaticInitElems,
SizeT,
E))
3697 this->fallthrough(StartLabel);
3698 this->emitLabel(StartLabel);
3702 if (!this->emitGetLocal(
SizeT, ArrayLen,
E))
3704 if (!this->emitLT(
SizeT,
E))
3706 if (!this->jumpFalse(EndLabel))
3712 if (!this->emitArrayElemPtr(
SizeT,
E))
3715 if (isa_and_nonnull<ImplicitValueInitExpr>(DynamicInit) &&
3719 PrimType InitT = classifyPrim(ElemType);
3720 if (!this->visitZeroInitializer(InitT, ElemType,
E))
3722 if (!this->emitStorePop(InitT,
E))
3724 }
else if (DynamicInit) {
3726 if (!this->visit(DynamicInit))
3728 if (!this->emitStorePop(*InitT,
E))
3731 if (!this->visitInitializer(DynamicInit))
3733 if (!this->emitPopPtr(
E))
3738 if (!this->emitCall(CtorFunc, 0,
E))
3743 if (!this->emitGetPtrLocal(
Iter,
E))
3745 if (!this->emitIncPop(
SizeT,
false,
E))
3748 if (!this->jump(StartLabel))
3751 this->fallthrough(EndLabel);
3752 this->emitLabel(EndLabel);
3756 if (PlacementDest) {
3757 if (!this->visit(PlacementDest))
3759 if (!this->emitStartLifetime(
E))
3761 if (!this->emitCheckNewTypeMismatch(
E,
E))
3765 if (!this->emitAlloc(Desc,
E))
3771 if (!this->visit(
Init))
3774 if (!this->emitInit(*ElemT,
E))
3778 if (!this->visitInitializer(
Init))
3785 return this->emitPopPtr(
E);
3790template <
class Emitter>
3792 const Expr *Arg =
E->getArgument();
3794 const FunctionDecl *OperatorDelete =
E->getOperatorDelete();
3796 if (!OperatorDelete->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
3797 return this->emitInvalidNewDeleteExpr(
E,
E);
3800 if (!this->visit(Arg))
3803 return this->emitFree(
E->isArrayForm(),
E->isGlobalDelete(),
E);
3806template <
class Emitter>
3812 if (
const Function *F = Ctx.getOrCreateObjCBlock(
E))
3817 return this->emitGetFnPtr(
Func,
E);
3820template <
class Emitter>
3824 auto canonType = [](
const Type *
T) {
3828 if (!
E->isPotentiallyEvaluated()) {
3832 if (
E->isTypeOperand())
3833 return this->emitGetTypeid(
3834 canonType(
E->getTypeOperand(Ctx.getASTContext()).getTypePtr()),
3837 return this->emitGetTypeid(
3843 assert(
E->getExprOperand());
3844 assert(
E->getExprOperand()->
isLValue());
3846 if (!Ctx.
getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(
E))
3849 if (!this->visit(
E->getExprOperand()))
3852 if (!this->emitGetTypeidPtr(TypeInfoType,
E))
3855 return this->emitPopPtr(
E);
3859template <
class Emitter>
3862 return this->emitConstBool(
E->getValue(),
E);
3865template <
class Emitter>
3877 return this->emitDummyPtr(GuidDecl,
E);
3879 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(GuidDecl);
3882 if (!this->emitGetPtrGlobal(*GlobalIndex,
E))
3885 assert(this->getRecord(
E->
getType()));
3891 assert(
V.isStruct());
3892 assert(
V.getStructNumBases() == 0);
3893 if (!this->visitAPValueInitializer(
V,
E,
E->
getType()))
3896 return this->emitFinishInit(
E);
3899template <
class Emitter>
3906 return this->emitConstBool(
E->isSatisfied(),
E);
3909template <
class Emitter>
3915 return this->emitConstBool(
E->isSatisfied(),
E);
3918template <
class Emitter>
3921 return this->delegate(
E->getSemanticForm());
3924template <
class Emitter>
3927 for (
const Expr *SemE :
E->semantics()) {
3928 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
3929 if (SemE ==
E->getResultExpr())
3932 if (OVE->isUnique())
3937 }
else if (SemE ==
E->getResultExpr()) {
3938 if (!this->delegate(SemE))
3948template <
class Emitter>
3950 return this->delegate(
E->getSelectedExpr());
3953template <
class Emitter>
3955 return this->emitError(
E);
3958template <
class Emitter>
3962 return this->emitDummyPtr(
E,
E);
3965template <
class Emitter>
3969 QualType ElemType = VT->getElementType();
3970 PrimType ElemT = classifyPrim(ElemType);
3971 const Expr *Src =
E->getSrcExpr();
3973 PrimType SrcElemT = classifyVectorElementType(SrcType);
3975 unsigned SrcOffset =
3976 this->allocateLocalPrimitive(Src,
PT_Ptr,
true);
3977 if (!this->visit(Src))
3979 if (!this->emitSetLocal(
PT_Ptr, SrcOffset,
E))
3982 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
3983 if (!this->emitGetLocal(
PT_Ptr, SrcOffset,
E))
3985 if (!this->emitArrayElemPop(SrcElemT, I,
E))
3989 if (SrcElemT != ElemT) {
3990 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType,
E))
3992 }
else if (ElemType->isFloatingType() && SrcType != ElemType) {
3993 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
3997 if (!this->emitInitElem(ElemT, I,
E))
4004template <
class Emitter>
4007 assert(
E->getNumSubExprs() > 2);
4009 const Expr *Vecs[] = {
E->getExpr(0),
E->getExpr(1)};
4013 unsigned NumOutputElems =
E->getNumSubExprs() - 2;
4014 assert(NumOutputElems > 0);
4017 unsigned VectorOffsets[2];
4018 for (
unsigned I = 0; I != 2; ++I) {
4020 this->allocateLocalPrimitive(Vecs[I],
PT_Ptr,
true);
4021 if (!this->visit(Vecs[I]))
4023 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I],
E))
4026 for (
unsigned I = 0; I != NumOutputElems; ++I) {
4027 APSInt ShuffleIndex =
E->getShuffleMaskIdx(I);
4028 assert(ShuffleIndex >= -1);
4029 if (ShuffleIndex == -1)
4030 return this->emitInvalidShuffleVectorIndex(I,
E);
4032 assert(ShuffleIndex < (NumInputElems * 2));
4033 if (!this->emitGetLocal(
PT_Ptr,
4034 VectorOffsets[ShuffleIndex >= NumInputElems],
E))
4036 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
4037 if (!this->emitArrayElemPop(ElemT, InputVectorIndex,
E))
4040 if (!this->emitInitElem(ElemT, I,
E))
4047template <
class Emitter>
4052 Base->getType()->isVectorType() ||
4056 E->getEncodedElementAccess(Indices);
4058 if (Indices.size() == 1) {
4059 if (!this->visit(
Base))
4063 if (!this->emitConstUint32(Indices[0],
E))
4065 return this->emitArrayElemPtrPop(
PT_Uint32,
E);
4068 return this->emitArrayElemPop(classifyPrim(
E->
getType()), Indices[0],
E);
4072 unsigned BaseOffset = allocateLocalPrimitive(
Base,
PT_Ptr,
true);
4073 if (!this->visit(
Base))
4075 if (!this->emitSetLocal(
PT_Ptr, BaseOffset,
E))
4083 if (!this->emitGetPtrLocal(*ResultIndex,
E))
4091 uint32_t DstIndex = 0;
4092 for (uint32_t I : Indices) {
4093 if (!this->emitGetLocal(
PT_Ptr, BaseOffset,
E))
4095 if (!this->emitArrayElemPop(ElemT, I,
E))
4097 if (!this->emitInitElem(ElemT, DstIndex,
E))
4103 assert(!DiscardResult);
4107template <
class Emitter>
4109 const Expr *SubExpr =
E->getSubExpr();
4110 if (!
E->isExpressibleAsConstantInitializer())
4111 return this->
discard(SubExpr) && this->emitInvalid(
E);
4116 assert(classifyPrim(
E) ==
PT_Ptr);
4117 return this->emitDummyPtr(
E,
E);
4120template <
class Emitter>
4123 const Expr *SubExpr =
E->getSubExpr();
4130 if (!this->visit(SubExpr))
4132 if (!this->emitConstUint8(0,
E))
4134 if (!this->emitArrayElemPtrPopUint8(
E))
4141 if (!this->emitConst(
ArrayType->getSize(), SecondFieldT,
E))
4145 assert(SecondFieldT ==
PT_Ptr);
4149 if (!this->emitExpandPtr(
E))
4153 if (!this->emitArrayElemPtrPop(
PT_Uint64,
E))
4158template <
class Emitter>
4167 if (!this->visitStmt(S))
4172 assert(S == Result);
4173 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
4174 return this->delegate(ResultExpr);
4175 return this->emitUnsupported(
E);
4184 return this->Visit(
E);
4191 return this->Visit(
E);
4208 if (!this->emitGetPtrLocal(*LocalIndex,
E))
4211 return this->visitInitializer(
E);
4218 return this->Visit(
E);
4221template <
class Emitter>
4223 assert(!canClassify(
E->
getType()));
4227 return this->Visit(
E);
4233 return this->Visit(
E);
4241 if (!this->visit(
E))
4243 return this->emitComplexBoolCast(
E);
4248 if (!this->visit(
E))
4256 return this->emitIsNonNullPtr(
E);
4260 return this->emitCastFloatingIntegralBool(getFPOptions(
E),
E);
4266template <
class Emitter>
4270 QT = AT->getValueType();
4274 return this->emitZeroBool(
E);
4276 return this->emitZeroSint8(
E);
4278 return this->emitZeroUint8(
E);
4280 return this->emitZeroSint16(
E);
4282 return this->emitZeroUint16(
E);
4284 return this->emitZeroSint32(
E);
4286 return this->emitZeroUint32(
E);
4288 return this->emitZeroSint64(
E);
4290 return this->emitZeroUint64(
E);
4292 return this->emitZeroIntAP(Ctx.getBitWidth(QT),
E);
4294 return this->emitZeroIntAPS(Ctx.getBitWidth(QT),
E);
4299 return this->emitNullMemberPtr(0,
nullptr,
E);
4301 APFloat F = APFloat::getZero(Ctx.getFloatSemantics(QT));
4302 return this->emitFloat(F,
E);
4309 llvm_unreachable(
"unknown primitive type");
4312template <
class Emitter>
4318 for (
const Record::Field &Field : R->
fields()) {
4319 if (
Field.isUnnamedBitField())
4323 if (
D->isPrimitive()) {
4326 if (!this->visitZeroInitializer(
T, QT,
E))
4329 if (!this->emitInitFieldActivate(
T,
Field.Offset,
E))
4333 if (!this->emitInitField(
T,
Field.Offset,
E))
4338 if (!this->emitGetPtrField(
Field.Offset,
E))
4341 if (
D->isPrimitiveArray()) {
4344 for (uint32_t I = 0, N =
D->getNumElems(); I != N; ++I) {
4345 if (!this->visitZeroInitializer(
T, ET,
E))
4347 if (!this->emitInitElem(
T, I,
E))
4350 }
else if (
D->isCompositeArray()) {
4352 if (!this->visitZeroArrayInitializer(
D->getType(),
E))
4354 }
else if (
D->isRecord()) {
4355 if (!this->visitZeroRecordInitializer(
D->ElemRecord,
E))
4363 if (!this->emitFinishInitActivatePop(
E))
4367 if (!this->emitFinishInitPop(
E))
4371 for (
const Record::Base &B : R->
bases()) {
4372 if (!this->emitGetPtrBase(B.Offset,
E))
4374 if (!this->visitZeroRecordInitializer(B.R,
E))
4376 if (!this->emitFinishInitPop(
E))
4385template <
class Emitter>
4390 size_t NumElems = cast<ConstantArrayType>(AT)->getZExtSize();
4393 for (
size_t I = 0; I != NumElems; ++I) {
4394 if (!this->visitZeroInitializer(*ElemT, ElemType,
E))
4396 if (!this->emitInitElem(*ElemT, I,
E))
4402 const Record *R = getRecord(ElemType);
4404 for (
size_t I = 0; I != NumElems; ++I) {
4405 if (!this->emitConstUint32(I,
E))
4409 if (!this->visitZeroRecordInitializer(R,
E))
4411 if (!this->emitPopPtr(
E))
4417 for (
size_t I = 0; I != NumElems; ++I) {
4418 if (!this->emitConstUint32(I,
E))
4422 if (!this->visitZeroArrayInitializer(ElemType,
E))
4424 if (!this->emitPopPtr(
E))
4433template <
class Emitter>
4439 if (!this->visit(RHS))
4441 if (!this->visit(LHS))
4445 if (!Ctx.
getLangOpts().CPlusPlus && !this->emitInvalid(
E))
4449 bool Activates = refersToUnion(LHS);
4452 if (!this->emitFlip(
PT_Ptr, RHT,
E))
4455 if (DiscardResult) {
4456 if (BitField && Activates)
4457 return this->emitStoreBitFieldActivatePop(RHT,
E);
4459 return this->emitStoreBitFieldPop(RHT,
E);
4461 return this->emitStoreActivatePop(RHT,
E);
4463 return this->emitStorePop(RHT,
E);
4466 auto maybeLoad = [&](
bool Result) ->
bool {
4472 return this->emitLoadPop(RHT,
E);
4476 if (BitField && Activates)
4477 return maybeLoad(this->emitStoreBitFieldActivate(RHT,
E));
4479 return maybeLoad(this->emitStoreBitField(RHT,
E));
4481 return maybeLoad(this->emitStoreActivate(RHT,
E));
4483 return maybeLoad(this->emitStore(RHT,
E));
4486template <
class Emitter>
4487template <
typename T>
4491 return this->emitConstSint8(
Value,
E);
4493 return this->emitConstUint8(
Value,
E);
4495 return this->emitConstSint16(
Value,
E);
4497 return this->emitConstUint16(
Value,
E);
4499 return this->emitConstSint32(
Value,
E);
4501 return this->emitConstUint32(
Value,
E);
4503 return this->emitConstSint64(
Value,
E);
4505 return this->emitConstUint64(
Value,
E);
4507 return this->emitConstBool(
Value,
E);
4514 llvm_unreachable(
"Invalid integral type");
4517 llvm_unreachable(
"unknown primitive type");
4520template <
class Emitter>
4521template <
typename T>
4526template <
class Emitter>
4529 return this->emitConst(
static_cast<const APInt &
>(
Value), Ty,
E);
4532template <
class Emitter>
4536 return this->emitConstIntAPS(
Value,
E);
4538 return this->emitConstIntAP(
Value,
E);
4541 return this->emitConst(
Value.getSExtValue(), Ty,
E);
4542 return this->emitConst(
Value.getZExtValue(), Ty,
E);
4545template <
class Emitter>
4550template <
class Emitter>
4553 ScopeKind SC,
bool IsConstexprUnknown) {
4558 IsConst, isa<const Expr *>(Src));
4559 D->IsConstexprUnknown = IsConstexprUnknown;
4561 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
4562 Locals.insert({VD, Local});
4564 VarScope->addExtended(Local, ExtendingDecl);
4566 VarScope->addForScopeKind(Local, SC);
4567 return Local.Offset;
4570template <
class Emitter>
4574 bool IsConstexprUnknown) {
4577 bool IsTemporary =
false;
4578 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4581 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
4582 Init = VarD->getInit();
4584 if (
auto *
E = Src.dyn_cast<
const Expr *>()) {
4592 IsTemporary,
false,
false,
Init);
4594 return std::nullopt;
4595 D->IsConstexprUnknown = IsConstexprUnknown;
4599 Locals.insert({Key, Local});
4601 VarScope->addExtended(Local, ExtendingDecl);
4603 VarScope->addForScopeKind(Local, SC);
4604 return Local.Offset;
4607template <
class Emitter>
4617 return std::nullopt;
4623 while (S->getParent())
4625 assert(S && !S->getParent());
4627 return Local.Offset;
4630template <
class Emitter>
4632 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
4638 if (
const auto *RecordTy = getRecordTy(Ty))
4639 return getRecord(RecordTy->getOriginalDecl()->getDefinitionOrSelf());
4643template <
class Emitter>
4645 return P.getOrCreateRecord(RD);
4648template <
class Emitter>
4650 return Ctx.getOrCreateFunction(FD);
4653template <
class Emitter>
4658 if (!DestroyToplevelScope) {
4659 if (!this->emitCheckAllocations(
E))
4663 auto maybeDestroyLocals = [&]() ->
bool {
4664 if (DestroyToplevelScope)
4665 return RootScope.
destroyLocals() && this->emitCheckAllocations(
E);
4666 return this->emitCheckAllocations(
E);
4673 return this->emitRetVoid(
E) && maybeDestroyLocals();
4681 return this->emitRet(*
T,
E) && maybeDestroyLocals();
4689 if (!this->emitGetPtrLocal(*LocalOffset,
E))
4692 if (!visitInitializer(
E))
4695 if (!this->emitFinishInit(
E))
4700 return this->emitRetValue(
E) && maybeDestroyLocals();
4703 return maybeDestroyLocals() && this->emitCheckAllocations(
E) &&
false;
4706template <
class Emitter>
4708 bool IsConstexprUnknown) {
4710 auto R = this->visitVarDecl(VD,
true, IsConstexprUnknown);
4719 if (
auto GlobalIndex =
P.getGlobal(VD)) {
4720 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
4724 GD.
InitState = GlobalInitState::InitializerFailed;
4735template <
class Emitter>
4737 bool ConstantContext) {
4741 if (!ConstantContext) {
4744 if (!this->visit(
Init))
4746 return this->emitRet(classify(
Init).value_or(
PT_Ptr), VD) &&
4751 if (!this->visitVarDecl(VD,
true))
4756 auto GlobalIndex =
P.getGlobal(VD);
4757 assert(GlobalIndex);
4759 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
4762 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
4766 auto Local = Locals.find(VD);
4767 assert(Local != Locals.end());
4769 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
4772 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
4782 auto GlobalIndex =
P.getGlobal(VD);
4783 assert(GlobalIndex);
4784 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
4788 GD.
InitState = GlobalInitState::InitializerFailed;
4794 return VDScope.
destroyLocals() && this->emitCheckAllocations(VD);
4797template <
class Emitter>
4800 bool IsConstexprUnknown) {
4807 if (!this->isActive())
4813 if (
Init &&
Init->isValueDependent())
4817 auto checkDecl = [&]() ->
bool {
4819 return !NeedsOp || this->emitCheckDecl(VD, VD);
4822 auto initGlobal = [&](
unsigned GlobalIndex) ->
bool {
4826 if (!this->visit(
Init))
4827 return checkDecl() &&
false;
4829 return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
4835 if (!this->emitGetPtrGlobal(GlobalIndex,
Init))
4838 if (!visitInitializer(
Init))
4841 return this->emitFinishInitGlobal(
Init);
4847 if (std::optional<unsigned> GlobalIndex =
P.getGlobal(VD)) {
4848 if (
P.getPtrGlobal(*GlobalIndex).isInitialized())
4853 return Init && checkDecl() && initGlobal(*GlobalIndex);
4856 std::optional<unsigned> GlobalIndex =
P.createGlobal(VD,
Init);
4861 return !
Init || (checkDecl() && initGlobal(*GlobalIndex));
4867 unsigned Offset = this->allocateLocalPrimitive(
4869 IsConstexprUnknown);
4875 if (!this->visit(
Init))
4877 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
4879 if (!this->visit(
Init))
4881 return this->emitSetLocal(*VarT, Offset, VD);
4885 VD, VD->
getType(),
nullptr, ScopeKind::Block, IsConstexprUnknown)) {
4889 if (!this->emitGetPtrLocal(*Offset,
Init))
4892 if (!visitInitializer(
Init))
4895 return this->emitFinishInitPop(
Init);
4902template <
class Emitter>
4905 assert(!DiscardResult);
4907 return this->emitConst(Val.
getInt(), ValType,
E);
4910 return this->emitFloat(F,
E);
4915 return this->emitNull(ValType, 0,
nullptr,
E);
4917 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
4918 return this->visit(BaseExpr);
4920 return this->visitDeclRef(VD,
E);
4923 return this->emitGetMemberPtr(MemberDecl,
E);
4924 return this->emitNullMemberPtr(0,
nullptr,
E);
4930template <
class Emitter>
4934 const Record *R = this->getRecord(
T);
4938 const Record::Field *RF = R->
getField(I);
4939 QualType FieldType = RF->Decl->getType();
4942 if (!this->visitAPValue(F, *PT,
E))
4944 if (!this->emitInitField(*PT, RF->Offset,
E))
4947 if (!this->emitGetPtrField(RF->Offset,
E))
4949 if (!this->visitAPValueInitializer(F,
E, FieldType))
4951 if (!this->emitPopPtr(
E))
4962 const Record::Field *RF = R->
getField(UnionField);
4963 PrimType T = classifyPrim(RF->Decl->getType());
4964 if (!this->visitAPValue(F,
T,
E))
4966 return this->emitInitField(
T, RF->Offset,
E);
4970 QualType ElemType = ArrType->getElementType();
4971 for (
unsigned A = 0, AN = Val.
getArraySize(); A != AN; ++A) {
4974 if (!this->visitAPValue(Elem, *ElemT,
E))
4976 if (!this->emitInitElem(*ElemT, A,
E))
4979 if (!this->emitConstUint32(A,
E))
4981 if (!this->emitArrayElemPtrUint32(
E))
4983 if (!this->visitAPValueInitializer(Elem,
E, ElemType))
4985 if (!this->emitPopPtr(
E))
4996template <
class Emitter>
4998 unsigned BuiltinID) {
4999 if (BuiltinID == Builtin::BI__builtin_constant_p) {
5004 return this->emitConst(0,
E);
5007 if (!this->emitStartSpeculation(
E))
5009 LabelTy EndLabel = this->getLabel();
5010 if (!this->speculate(
E, EndLabel))
5012 this->fallthrough(EndLabel);
5013 if (!this->emitEndSpeculation(
E))
5016 return this->emitPop(classifyPrim(
E),
E);
5022 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
5023 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
5024 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
5025 BuiltinID == Builtin::BI__builtin_function_start) {
5028 return this->emitDummyPtr(
E,
E);
5039 if (!this->emitGetPtrLocal(*LocalIndex,
E))
5044 switch (BuiltinID) {
5045 case Builtin::BI__builtin_object_size:
5046 case Builtin::BI__builtin_dynamic_object_size: {
5047 assert(
E->getNumArgs() == 2);
5048 const Expr *Arg0 =
E->getArg(0);
5050 if (!this->visit(Arg0))
5054 if (!this->visitAsLValue(Arg0))
5057 if (!this->visit(
E->getArg(1)))
5064 for (
const auto *Arg :
E->arguments()) {
5065 if (!this->visit(Arg))
5071 if (!this->emitCallBI(
E, BuiltinID,
E))
5074 if (DiscardResult && !ReturnType->
isVoidType()) {
5076 return this->emitPop(*ReturnT,
E);
5083 if (
const auto *PE = dyn_cast<ParenExpr>(
E))
5086 if (
const auto *CE = dyn_cast<CastExpr>(
E);
5088 (CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp))
5094template <
class Emitter>
5100 return VisitBuiltinCallExpr(
E, BuiltinID);
5105 return VisitBuiltinCallExpr(
E, Builtin::BI__builtin_operator_new);
5107 return VisitBuiltinCallExpr(
E, Builtin::BI__builtin_operator_delete);
5111 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(FuncDecl);
5112 DD && DD->isTrivial()) {
5113 const auto *MemberCall = cast<CXXMemberCallExpr>(
E);
5114 if (!this->visit(MemberCall->getImplicitObjectArgument()))
5116 return this->emitCheckDestruction(
E) && this->emitEndLifetime(
E) &&
5117 this->emitPopPtr(
E);
5123 QualType ReturnType =
E->getCallReturnType(Ctx.getASTContext());
5128 if (DiscardResult) {
5133 if (!this->emitGetPtrLocal(*LocalIndex,
E))
5141 if (!this->emitGetPtrLocal(*LocalIndex,
E))
5145 if (!this->emitDupPtr(
E))
5152 bool IsAssignmentOperatorCall =
false;
5153 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
5154 OCE && OCE->isAssignmentOp()) {
5158 assert(Args.size() == 2);
5159 IsAssignmentOperatorCall =
true;
5160 std::reverse(Args.begin(), Args.end());
5165 if (isa<CXXOperatorCallExpr>(
E)) {
5166 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
5167 MD && MD->isStatic()) {
5171 Args.erase(Args.begin());
5175 bool Devirtualized =
false;
5178 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(
E)) {
5179 if (!FuncDecl && classifyPrim(
E->getCallee()) ==
PT_MemberPtr) {
5183 const Expr *Callee =
E->getCallee();
5185 this->allocateLocalPrimitive(Callee,
PT_MemberPtr,
true);
5186 if (!this->visit(Callee))
5192 if (!this->emitGetMemberPtrBase(
E))
5195 const auto *InstancePtr = MC->getImplicitObjectArgument();
5196 if (isa_and_nonnull<CXXDestructorDecl>(CompilingFunction) ||
5197 isa_and_nonnull<CXXConstructorDecl>(CompilingFunction)) {
5199 if (isa<CXXThisExpr>(Stripped)) {
5201 cast<CXXMethodDecl>(FuncDecl)->getCorrespondingMethodInClass(
5202 Stripped->getType()->getPointeeType()->getAsCXXRecordDecl());
5203 Devirtualized =
true;
5204 if (!this->visit(Stripped))
5207 if (!this->visit(InstancePtr))
5211 if (!this->visit(InstancePtr))
5215 }
else if (
const auto *PD =
5216 dyn_cast<CXXPseudoDestructorExpr>(
E->getCallee())) {
5217 if (!this->emitCheckPseudoDtor(
E))
5223 if (!this->visit(
Base))
5225 return this->emitEndLifetimePop(
E);
5226 }
else if (!FuncDecl) {
5227 const Expr *Callee =
E->getCallee();
5229 this->allocateLocalPrimitive(Callee,
PT_Ptr,
true);
5230 if (!this->visit(Callee))
5232 if (!this->emitSetLocal(
PT_Ptr, *CalleeOffset,
E))
5236 if (!this->visitCallArgs(Args, FuncDecl, IsAssignmentOperatorCall,
5237 isa<CXXOperatorCallExpr>(
E)))
5241 if (IsAssignmentOperatorCall) {
5242 assert(Args.size() == 2);
5245 if (!this->emitFlip(Arg2T, Arg1T,
E))
5256 if (
E->getNumArgs() <
Func->getNumWrittenParams())
5259 assert(HasRVO ==
Func->hasRVO());
5261 bool HasQualifier =
false;
5262 if (
const auto *ME = dyn_cast<MemberExpr>(
E->getCallee()))
5263 HasQualifier = ME->hasQualifier();
5265 bool IsVirtual =
false;
5266 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
5267 IsVirtual = !Devirtualized && MD->isVirtual();
5272 if (IsVirtual && !HasQualifier) {
5273 uint32_t VarArgSize = 0;
5274 unsigned NumParams =
5275 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
5276 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
5279 if (!this->emitCallVirt(
Func, VarArgSize,
E))
5281 }
else if (
Func->isVariadic()) {
5282 uint32_t VarArgSize = 0;
5283 unsigned NumParams =
5284 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(
E);
5285 for (
unsigned I = NumParams, N =
E->getNumArgs(); I != N; ++I)
5287 if (!this->emitCallVar(
Func, VarArgSize,
E))
5290 if (!this->emitCall(
Func, 0,
E))
5299 uint32_t ArgSize = 0;
5300 for (
unsigned I = 0, N =
E->getNumArgs(); I != N; ++I)
5305 if (isa<CXXMemberCallExpr>(
E) && CalleeOffset) {
5308 if (!this->emitGetMemberPtrDecl(
E))
5311 if (!this->emitGetLocal(
PT_Ptr, *CalleeOffset,
E))
5314 if (!this->emitCallPtr(ArgSize,
E,
E))
5319 if (DiscardResult && !ReturnType->
isVoidType() &&
T)
5325template <
class Emitter>
5329 return this->delegate(
E->getExpr());
5332template <
class Emitter>
5336 return this->delegate(
E->getExpr());
5339template <
class Emitter>
5344 return this->emitConstBool(
E->getValue(),
E);
5347template <
class Emitter>
5354 return this->emitNullPtr(Val,
nullptr,
E);
5357template <
class Emitter>
5365 return this->emitZero(
T,
E);
5368template <
class Emitter>
5373 if (this->LambdaThisCapture.Offset > 0) {
5374 if (this->LambdaThisCapture.IsPtr)
5375 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset,
E);
5376 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset,
E);
5383 if (!InitStackActive)
5384 return this->emitThis(
E);
5386 if (!InitStack.empty()) {
5400 unsigned StartIndex = 0;
5401 unsigned EndIndex = 0;
5403 for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
5406 EndIndex = StartIndex;
5413 for (; StartIndex > 0; --StartIndex) {
5423 for (
unsigned I = StartIndex; I != EndIndex; ++I) {
5426 if (!InitStack[I].
template emit<Emitter>(
this,
E))
5431 return this->emitThis(
E);
5435 switch (S->getStmtClass()) {
5436 case Stmt::CompoundStmtClass:
5437 return visitCompoundStmt(cast<CompoundStmt>(S));
5438 case Stmt::DeclStmtClass:
5439 return visitDeclStmt(cast<DeclStmt>(S),
true);
5440 case Stmt::ReturnStmtClass:
5441 return visitReturnStmt(cast<ReturnStmt>(S));
5442 case Stmt::IfStmtClass:
5443 return visitIfStmt(cast<IfStmt>(S));
5444 case Stmt::WhileStmtClass:
5445 return visitWhileStmt(cast<WhileStmt>(S));
5446 case Stmt::DoStmtClass:
5447 return visitDoStmt(cast<DoStmt>(S));
5448 case Stmt::ForStmtClass:
5449 return visitForStmt(cast<ForStmt>(S));
5450 case Stmt::CXXForRangeStmtClass:
5451 return visitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
5452 case Stmt::BreakStmtClass:
5453 return visitBreakStmt(cast<BreakStmt>(S));
5454 case Stmt::ContinueStmtClass:
5455 return visitContinueStmt(cast<ContinueStmt>(S));
5456 case Stmt::SwitchStmtClass:
5457 return visitSwitchStmt(cast<SwitchStmt>(S));
5458 case Stmt::CaseStmtClass:
5459 return visitCaseStmt(cast<CaseStmt>(S));
5460 case Stmt::DefaultStmtClass:
5461 return visitDefaultStmt(cast<DefaultStmt>(S));
5462 case Stmt::AttributedStmtClass:
5463 return visitAttributedStmt(cast<AttributedStmt>(S));
5464 case Stmt::CXXTryStmtClass:
5465 return visitCXXTryStmt(cast<CXXTryStmt>(S));
5466 case Stmt::NullStmtClass:
5469 case Stmt::GCCAsmStmtClass:
5470 case Stmt::MSAsmStmtClass:
5471 case Stmt::GotoStmtClass:
5472 return this->emitInvalid(S);
5473 case Stmt::LabelStmtClass:
5474 return this->visitStmt(cast<LabelStmt>(S)->getSubStmt());
5476 if (
const auto *
E = dyn_cast<Expr>(S))
5483template <
class Emitter>
5486 for (
const auto *InnerStmt : S->body())
5487 if (!visitStmt(InnerStmt))
5489 return Scope.destroyLocals();
5492template <
class Emitter>
5494 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5495 for (
auto *BD : DD->flat_bindings())
5496 if (
auto *KD = BD->getHoldingVar(); KD && !this->visitVarDecl(KD))
5505 const auto *CXXRD = dyn_cast<CXXRecordDecl>(FD->
getParent());
5506 return !CXXRD || CXXRD->hasTrivialDefaultConstructor();
5511 if (
const auto *ME = dyn_cast<MemberExpr>(
E)) {
5512 if (
const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
5519 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(
E)) {
5524 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(
E);
5525 ICE && (ICE->getCastKind() == CK_NoOp ||
5526 ICE->getCastKind() == CK_DerivedToBase ||
5527 ICE->getCastKind() == CK_UncheckedDerivedToBase)) {
5528 E = ICE->getSubExpr();
5532 if (
const auto *
This = dyn_cast<CXXThisExpr>(
E)) {
5533 const auto *ThisRecord =
5534 This->getType()->getPointeeType()->getAsRecordDecl();
5535 if (!ThisRecord->isUnion())
5538 if (
const auto *Ctor =
5539 dyn_cast_if_present<CXXConstructorDecl>(CompilingFunction))
5540 return Ctor->getParent() == ThisRecord;
5549template <
class Emitter>
5551 bool EvaluateConditionDecl) {
5552 for (
const auto *
D : DS->
decls()) {
5557 const auto *VD = dyn_cast<VarDecl>(
D);
5560 if (!this->visitVarDecl(VD))
5564 if (EvaluateConditionDecl && !this->maybeEmitDeferredVarInit(VD))
5571template <
class Emitter>
5573 if (this->InStmtExpr)
5574 return this->emitUnsupported(RS);
5580 if (!this->visit(RE))
5583 return this->emitRet(*ReturnType, RS);
5586 if (RE->getType()->isVoidType()) {
5587 if (!this->visit(RE))
5592 if (!this->emitRVOPtr(RE))
5594 if (!this->visitInitializer(RE))
5596 if (!this->emitPopPtr(RE))
5600 return this->emitRetVoid(RS);
5606 return this->emitRetVoid(RS);
5610 auto visitChildStmt = [&](
const Stmt *S) ->
bool {
5616 if (
auto *CondInit = IS->
getInit())
5617 if (!visitStmt(CondInit))
5621 if (!visitDeclStmt(CondDecl))
5630 return visitChildStmt(IS->
getThen());
5632 return visitChildStmt(Else);
5638 if (!this->emitIsConstantContext(IS))
5641 if (!this->emitIsConstantContext(IS))
5643 if (!this->emitInv(IS))
5646 if (!this->visitBool(IS->
getCond()))
5654 LabelTy LabelElse = this->getLabel();
5655 LabelTy LabelEnd = this->getLabel();
5656 if (!this->jumpFalse(LabelElse))
5658 if (!visitChildStmt(IS->
getThen()))
5660 if (!this->jump(LabelEnd))
5662 this->emitLabel(LabelElse);
5663 if (!visitChildStmt(Else))
5665 this->emitLabel(LabelEnd);
5667 LabelTy LabelEnd = this->getLabel();
5668 if (!this->jumpFalse(LabelEnd))
5670 if (!visitChildStmt(IS->
getThen()))
5672 this->emitLabel(LabelEnd);
5678template <
class Emitter>
5680 const Expr *Cond = S->getCond();
5681 const Stmt *Body = S->getBody();
5683 LabelTy CondLabel = this->getLabel();
5684 LabelTy EndLabel = this->getLabel();
5687 this->fallthrough(CondLabel);
5688 this->emitLabel(CondLabel);
5692 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5693 if (!visitDeclStmt(CondDecl))
5696 if (!this->visitBool(Cond))
5699 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
5702 if (!this->jumpFalse(EndLabel))
5705 if (!this->visitStmt(Body))
5711 if (!this->jump(CondLabel))
5713 this->fallthrough(EndLabel);
5714 this->emitLabel(EndLabel);
5720 const Expr *Cond = S->getCond();
5721 const Stmt *Body = S->getBody();
5723 LabelTy StartLabel = this->getLabel();
5724 LabelTy EndLabel = this->getLabel();
5725 LabelTy CondLabel = this->getLabel();
5728 this->fallthrough(StartLabel);
5729 this->emitLabel(StartLabel);
5733 if (!this->visitStmt(Body))
5735 this->fallthrough(CondLabel);
5736 this->emitLabel(CondLabel);
5737 if (!this->visitBool(Cond))
5743 if (!this->jumpTrue(StartLabel))
5746 this->fallthrough(EndLabel);
5747 this->emitLabel(EndLabel);
5751template <
class Emitter>
5755 const Expr *Cond = S->getCond();
5756 const Expr *
Inc = S->getInc();
5757 const Stmt *Body = S->getBody();
5759 LabelTy EndLabel = this->getLabel();
5760 LabelTy CondLabel = this->getLabel();
5761 LabelTy IncLabel = this->getLabel();
5764 if (
Init && !this->visitStmt(
Init))
5767 this->fallthrough(CondLabel);
5768 this->emitLabel(CondLabel);
5772 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5773 if (!visitDeclStmt(CondDecl))
5777 if (!this->visitBool(Cond))
5779 if (!this->jumpFalse(EndLabel))
5782 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
5785 if (Body && !this->visitStmt(Body))
5788 this->fallthrough(IncLabel);
5789 this->emitLabel(IncLabel);
5795 if (!this->jump(CondLabel))
5799 this->emitLabel(EndLabel);
5805template <
class Emitter>
5808 const Expr *Cond = S->getCond();
5809 const Expr *
Inc = S->getInc();
5810 const Stmt *Body = S->getBody();
5811 const Stmt *BeginStmt = S->getBeginStmt();
5812 const Stmt *RangeStmt = S->getRangeStmt();
5813 const Stmt *EndStmt = S->getEndStmt();
5815 LabelTy EndLabel = this->getLabel();
5816 LabelTy CondLabel = this->getLabel();
5817 LabelTy IncLabel = this->getLabel();
5821 if (
Init && !this->visitStmt(
Init))
5823 if (!this->visitStmt(RangeStmt))
5825 if (!this->visitStmt(BeginStmt))
5827 if (!this->visitStmt(EndStmt))
5831 this->fallthrough(CondLabel);
5832 this->emitLabel(CondLabel);
5833 if (!this->visitBool(Cond))
5835 if (!this->jumpFalse(EndLabel))
5838 if (!this->visitDeclStmt(S->getLoopVarStmt(),
true))
5843 if (!this->visitStmt(Body))
5846 this->fallthrough(IncLabel);
5847 this->emitLabel(IncLabel);
5852 if (!this->jump(CondLabel))
5855 this->fallthrough(EndLabel);
5856 this->emitLabel(EndLabel);
5860template <
class Emitter>
5867 C->emitDestruction();
5868 return this->jump(*BreakLabel);
5871template <
class Emitter>
5877 C &&
C->getParent() != ContinueVarScope;
C =
C->getParent())
5878 C->emitDestruction();
5879 return this->jump(*ContinueLabel);
5882template <
class Emitter>
5884 const Expr *Cond = S->getCond();
5891 LabelTy EndLabel = this->getLabel();
5894 this->allocateLocalPrimitive(Cond, CondT,
true);
5896 if (
const auto *CondInit = S->getInit())
5897 if (!visitStmt(CondInit))
5900 if (
const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
5901 if (!visitDeclStmt(CondDecl))
5905 if (!this->visit(Cond))
5907 if (!this->emitSetLocal(CondT, CondVar, S))
5910 if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
5915 for (
const SwitchCase *SC = S->getSwitchCaseList(); SC;
5916 SC = SC->getNextSwitchCase()) {
5917 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
5919 if (CS->caseStmtIsGNURange())
5921 CaseLabels[SC] = this->getLabel();
5927 if (!this->emitGetLocal(CondT, CondVar, CS))
5929 if (!this->visit(
Value))
5933 if (!this->emitEQ(ValueT, S))
5935 if (!this->jumpTrue(CaseLabels[CS]))
5938 assert(!DefaultLabel);
5939 DefaultLabel = this->getLabel();
5946 if (!this->jump(*DefaultLabel))
5949 if (!this->jump(EndLabel))
5954 if (!this->visitStmt(S->getBody()))
5956 this->emitLabel(EndLabel);
5961template <
class Emitter>
5963 this->emitLabel(CaseLabels[S]);
5964 return this->visitStmt(S->getSubStmt());
5967template <
class Emitter>
5969 this->emitLabel(*DefaultLabel);
5970 return this->visitStmt(S->getSubStmt());
5973template <
class Emitter>
5976 !this->Ctx.getLangOpts().MSVCCompat) {
5977 for (
const Attr *A : S->getAttrs()) {
5978 auto *AA = dyn_cast<CXXAssumeAttr>(A);
5982 assert(isa<NullStmt>(S->getSubStmt()));
5984 const Expr *Assumption = AA->getAssumption();
5992 if (!this->visitBool(Assumption))
5995 if (!this->emitAssume(Assumption))
6001 return this->visitStmt(S->getSubStmt());
6004template <
class Emitter>
6007 return this->visitStmt(S->getTryBlock());
6010template <
class Emitter>
6014 assert(cast<CompoundStmt>(MD->
getBody())->body_empty());
6018 assert(ClosureClass->
captures().empty());
6019 const Function *
Func = this->getFunction(LambdaCallOp);
6022 assert(
Func->hasThisPointer());
6025 if (
Func->hasRVO()) {
6026 if (!this->emitRVOPtr(MD))
6034 if (!this->emitNullPtr(0,
nullptr, MD))
6039 auto It = this->Params.find(PVD);
6040 assert(It != this->Params.end());
6044 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
6045 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
6049 if (!this->emitCall(
Func, 0, LambdaCallOp))
6054 return this->emitRet(*ReturnType, MD);
6057 return this->emitRetVoid(MD);
6060template <
class Emitter>
6072 const Expr *InitExpr =
Init->getInit();
6074 if (!
Init->isWritten() && !
Init->isInClassMemberInitializer() &&
6075 !isa<CXXConstructExpr>(InitExpr))
6078 if (
const auto *CE = dyn_cast<CXXConstructExpr>(InitExpr)) {
6088template <
class Emitter>
6090 assert(!ReturnType);
6092 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
6093 const Expr *InitExpr,
6096 if (InitExpr->getType().isNull())
6100 if (
Activate && !this->emitActivateThisField(FieldOffset, InitExpr))
6103 if (!this->visit(InitExpr))
6106 bool BitField = F->isBitField();
6108 return this->emitInitThisBitField(*
T, F, FieldOffset, InitExpr);
6109 return this->emitInitThisField(*
T, FieldOffset, InitExpr);
6114 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
6117 if (
Activate && !this->emitActivate(InitExpr))
6120 if (!this->visitInitializer(InitExpr))
6123 return this->emitFinishInitPop(InitExpr);
6127 const Record *R = this->getRecord(RD);
6136 return this->emitRetVoid(Ctor);
6138 assert(cast<CompoundStmt>(Ctor->
getBody())->body_empty());
6139 if (!this->emitThis(Ctor))
6148 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
6149 this->emitRetVoid(Ctor);
6153 for (
const auto *
Init : Ctor->
inits()) {
6157 const Expr *InitExpr =
Init->getInit();
6163 if (!emitFieldInitializer(F, F->Offset, InitExpr, IsUnion))
6166 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
6169 if (
Init->isBaseVirtual()) {
6171 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
6177 const Record::Base *B = R->
getBase(BaseDecl);
6179 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
6183 if (IsUnion && !this->emitActivate(InitExpr))
6186 if (!this->visitInitializer(InitExpr))
6188 if (!this->emitFinishInitPop(InitExpr))
6193 assert(IFD->getChainingSize() >= 2);
6195 unsigned NestedFieldOffset = 0;
6196 const Record::Field *NestedField =
nullptr;
6197 for (
const NamedDecl *ND : IFD->chain()) {
6198 const auto *FD = cast<FieldDecl>(ND);
6199 const Record *FieldRecord = this->
P.getOrCreateRecord(FD->getParent());
6200 assert(FieldRecord);
6202 NestedField = FieldRecord->
getField(FD);
6203 assert(NestedField);
6204 IsUnion = IsUnion || FieldRecord->
isUnion();
6206 NestedFieldOffset += NestedField->Offset;
6208 assert(NestedField);
6210 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
6215 unsigned InitFieldOffset = 0;
6216 for (
const NamedDecl *ND : IFD->chain().drop_back()) {
6217 const auto *FD = cast<FieldDecl>(ND);
6218 const Record *FieldRecord = this->
P.getOrCreateRecord(FD->getParent());
6219 assert(FieldRecord);
6220 NestedField = FieldRecord->
getField(FD);
6221 InitFieldOffset += NestedField->Offset;
6222 assert(NestedField);
6223 if (!this->emitGetPtrThisField(InitFieldOffset, InitExpr))
6225 if (!this->emitFinishInitPop(InitExpr))
6230 assert(
Init->isDelegatingInitializer());
6231 if (!this->emitThis(InitExpr))
6233 if (!this->visitInitializer(
Init->getInit()))
6235 if (!this->emitPopPtr(InitExpr))
6239 if (!
Scope.destroyLocals())
6243 if (
const auto *Body = Ctor->
getBody())
6244 if (!visitStmt(Body))
6250template <
class Emitter>
6253 const Record *R = this->getRecord(RD);
6258 if (!this->visitStmt(Dtor->
getBody()))
6262 if (!this->emitThis(Dtor))
6265 if (!this->emitCheckDestruction(Dtor))
6273 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
6275 if (!
D->isPrimitive() && !
D->isPrimitiveArray()) {
6286 for (
const Record::Base &
Base : llvm::reverse(R->
bases())) {
6287 if (
Base.R->isAnonymousUnion())
6292 if (!this->emitRecordDestruction(
Base.R, {}))
6299 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
6302template <
class Emitter>
6305 if (!this->emitThis(MD))
6314 return this->emitMemcpy(MD) && this->emitRet(
PT_Ptr, MD);
6317template <
class Emitter>
6322 this->CompilingFunction = F;
6324 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
6325 return this->compileConstructor(Ctor);
6326 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
6327 return this->compileDestructor(Dtor);
6330 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
6335 return this->compileUnionAssignmentOperator(MD);
6338 return this->emitLambdaStaticInvokerBody(MD);
6342 if (
const auto *Body = F->
getBody())
6343 if (!visitStmt(Body))
6352template <
class Emitter>
6354 const Expr *SubExpr =
E->getSubExpr();
6356 return this->VisitComplexUnaryOperator(
E);
6358 return this->VisitVectorUnaryOperator(
E);
6360 return this->VisitFixedPointUnaryOperator(
E);
6363 switch (
E->getOpcode()) {
6366 return this->emitInvalid(
E);
6368 return this->emitError(
E);
6370 if (!this->visit(SubExpr))
6374 if (!this->emitIncPtr(
E))
6377 return DiscardResult ? this->emitPopPtr(
E) :
true;
6381 return DiscardResult ? this->emitIncfPop(getFPOptions(
E),
E)
6382 : this->emitIncf(getFPOptions(
E),
E);
6385 return DiscardResult ? this->emitIncPop(*
T,
E->canOverflow(),
E)
6386 : this->emitInc(*
T,
E->canOverflow(),
E);
6390 return this->emitInvalid(
E);
6392 return this->emitError(
E);
6394 if (!this->visit(SubExpr))
6398 if (!this->emitDecPtr(
E))
6401 return DiscardResult ? this->emitPopPtr(
E) :
true;
6405 return DiscardResult ? this->emitDecfPop(getFPOptions(
E),
E)
6406 : this->emitDecf(getFPOptions(
E),
E);
6409 return DiscardResult ? this->emitDecPop(*
T,
E->canOverflow(),
E)
6410 : this->emitDec(*
T,
E->canOverflow(),
E);
6414 return this->emitInvalid(
E);
6416 return this->emitError(
E);
6418 if (!this->visit(SubExpr))
6422 if (!this->emitLoadPtr(
E))
6424 if (!this->emitConstUint8(1,
E))
6426 if (!this->emitAddOffsetUint8(
E))
6428 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
6432 if (DiscardResult) {
6434 return this->emitIncfPop(getFPOptions(
E),
E);
6435 return this->emitIncPop(*
T,
E->canOverflow(),
E);
6439 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
6440 if (!this->emitLoadFloat(
E))
6442 APFloat F(TargetSemantics, 1);
6443 if (!this->emitFloat(F,
E))
6446 if (!this->emitAddf(getFPOptions(
E),
E))
6448 if (!this->emitStoreFloat(
E))
6452 if (!this->emitPreInc(*
T,
E->canOverflow(),
E))
6459 return this->emitInvalid(
E);
6461 return this->emitError(
E);
6463 if (!this->visit(SubExpr))
6467 if (!this->emitLoadPtr(
E))
6469 if (!this->emitConstUint8(1,
E))
6471 if (!this->emitSubOffsetUint8(
E))
6473 return DiscardResult ? this->emitStorePopPtr(
E) : this->emitStorePtr(
E);
6477 if (DiscardResult) {
6479 return this->emitDecfPop(getFPOptions(
E),
E);
6480 return this->emitDecPop(*
T,
E->canOverflow(),
E);
6484 const auto &TargetSemantics = Ctx.getFloatSemantics(
E->
getType());
6485 if (!this->emitLoadFloat(
E))
6487 APFloat F(TargetSemantics, 1);
6488 if (!this->emitFloat(F,
E))
6491 if (!this->emitSubf(getFPOptions(
E),
E))
6493 if (!this->emitStoreFloat(
E))
6497 if (!this->emitPreDec(*
T,
E->canOverflow(),
E))
6504 return this->emitError(
E);
6507 return this->
discard(SubExpr);
6509 if (!this->visitBool(SubExpr))
6512 if (!this->emitInv(
E))
6516 return this->emitCast(
PT_Bool, ET,
E);
6520 return this->emitError(
E);
6522 if (!this->visit(SubExpr))
6524 return DiscardResult ? this->emitPop(*
T,
E) : this->emitNeg(*
T,
E);
6527 return this->emitError(
E);
6529 if (!this->visit(SubExpr))
6531 return DiscardResult ? this->emitPop(*
T,
E) :
true;
6536 return this->emitGetMemberPtr(cast<DeclRefExpr>(SubExpr)->getDecl(),
E);
6539 return this->delegate(SubExpr);
6542 return this->
discard(SubExpr);
6544 if (!this->visit(SubExpr))
6547 if (!this->emitCheckNull(
E))
6550 if (classifyPrim(SubExpr) ==
PT_Ptr)
6551 return this->emitNarrowPtr(
E);
6556 return this->emitError(
E);
6558 if (!this->visit(SubExpr))
6560 return DiscardResult ? this->emitPop(*
T,
E) : this->emitComp(*
T,
E);
6563 return this->delegate(SubExpr);
6568 return this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
6571 return this->delegate(SubExpr);
6573 assert(
false &&
"Unhandled opcode");
6579template <
class Emitter>
6581 const Expr *SubExpr =
E->getSubExpr();
6585 return this->
discard(SubExpr);
6588 auto prepareResult = [=]() ->
bool {
6593 return this->emitGetPtrLocal(*LocalIndex,
E);
6600 unsigned SubExprOffset = ~0u;
6601 auto createTemp = [=, &SubExprOffset]() ->
bool {
6603 this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true);
6604 if (!this->visit(SubExpr))
6606 return this->emitSetLocal(
PT_Ptr, SubExprOffset,
E);
6610 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
6611 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
6613 return this->emitArrayElemPop(ElemT, Index,
E);
6616 switch (
E->getOpcode()) {
6618 if (!prepareResult())
6622 for (
unsigned I = 0; I != 2; ++I) {
6623 if (!getElem(SubExprOffset, I))
6625 if (!this->emitNeg(ElemT,
E))
6627 if (!this->emitInitElem(ElemT, I,
E))
6635 return this->delegate(SubExpr);
6638 if (!this->visit(SubExpr))
6640 if (!this->emitComplexBoolCast(SubExpr))
6642 if (!this->emitInv(
E))
6645 return this->emitCast(
PT_Bool, ET,
E);
6649 return this->emitComplexReal(SubExpr);
6652 if (!this->visit(SubExpr))
6656 if (!this->emitConstUint8(1,
E))
6658 return this->emitArrayElemPtrPopUint8(
E);
6663 return this->emitArrayElemPop(classifyPrim(
E->
getType()), 1,
E);
6666 if (!this->visit(SubExpr))
6669 if (!this->emitArrayElem(ElemT, 1,
E))
6671 if (!this->emitNeg(ElemT,
E))
6673 if (!this->emitInitElem(ElemT, 1,
E))
6675 return DiscardResult ? this->emitPopPtr(
E) :
true;
6678 return this->delegate(SubExpr);
6681 return this->emitInvalid(
E);
6687template <
class Emitter>
6689 const Expr *SubExpr =
E->getSubExpr();
6693 return this->
discard(SubExpr);
6695 auto UnaryOp =
E->getOpcode();
6696 if (UnaryOp == UO_Extension)
6697 return this->delegate(SubExpr);
6699 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
6700 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
6701 return this->emitInvalid(
E);
6704 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
6705 return this->delegate(SubExpr);
6711 if (!this->emitGetPtrLocal(*LocalIndex,
E))
6716 unsigned SubExprOffset =
6717 this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true);
6718 if (!this->visit(SubExpr))
6720 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset,
E))
6725 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
6726 if (!this->emitGetLocal(
PT_Ptr, Offset,
E))
6728 return this->emitArrayElemPop(ElemT, Index,
E);
6733 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6734 if (!getElem(SubExprOffset, I))
6736 if (!this->emitNeg(ElemT,
E))
6738 if (!this->emitInitElem(ElemT, I,
E))
6753 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6754 if (!getElem(SubExprOffset, I))
6757 if (!this->emitPrimCast(ElemT,
PT_Bool, Ctx.getASTContext().
BoolTy,
E))
6759 if (!this->emitInv(
E))
6761 if (!this->emitPrimCast(
PT_Bool, ElemT, VecTy->getElementType(),
E))
6763 if (!this->emitNeg(ElemT,
E))
6765 if (ElemT != ResultVecElemT &&
6766 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy,
E))
6768 if (!this->emitInitElem(ResultVecElemT, I,
E))
6774 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6775 if (!getElem(SubExprOffset, I))
6778 if (!this->emitInv(
E))
6781 if (!this->emitComp(ElemT,
E))
6784 if (!this->emitInitElem(ElemT, I,
E))
6789 llvm_unreachable(
"Unsupported unary operators should be handled up front");
6794template <
class Emitter>
6799 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(
D))
6800 return this->emitConst(ECD->getInitVal(),
E);
6801 if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(
D)) {
6802 const Function *F = getFunction(FuncDecl);
6803 return F && this->emitGetFnPtr(F,
E);
6805 if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(
D)) {
6806 if (std::optional<unsigned> Index =
P.getOrCreateGlobal(
D)) {
6807 if (!this->emitGetPtrGlobal(*Index,
E))
6810 if (!this->visitAPValue(TPOD->getValue(), *
T,
E))
6812 return this->emitInitGlobal(*
T, *Index,
E);
6814 return this->visitAPValueInitializer(TPOD->getValue(),
E,
6824 bool IsReference =
D->getType()->isReferenceType();
6829 if (
const auto *PVD = dyn_cast<ParmVarDecl>(
D)) {
6831 !
D->getType()->isIntegralOrEnumerationType()) {
6832 return this->emitInvalidDeclRef(cast<DeclRefExpr>(
E),
6835 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
6836 if (IsReference || !It->second.IsPtr)
6837 return this->emitGetParam(classifyPrim(
E), It->second.Offset,
E);
6839 return this->emitGetPtrParam(It->second.Offset,
E);
6843 if (
auto It = Locals.find(
D); It != Locals.end()) {
6844 const unsigned Offset = It->second.Offset;
6846 return this->emitGetLocal(classifyPrim(
E), Offset,
E);
6847 return this->emitGetPtrLocal(Offset,
E);
6850 if (
auto GlobalIndex =
P.getGlobal(
D)) {
6853 return this->emitGetGlobal(classifyPrim(
E), *GlobalIndex,
E);
6854 return this->emitGetGlobalUnchecked(classifyPrim(
E), *GlobalIndex,
E);
6857 return this->emitGetPtrGlobal(*GlobalIndex,
E);
6861 auto revisit = [&](
const VarDecl *VD) ->
bool {
6864 auto VarState = this->visitDecl(VD,
true);
6866 if (!this->emitPopCC(
E))
6869 if (VarState.notCreated())
6874 return this->visitDeclRef(
D,
E);
6878 if (
auto It = this->LambdaCaptures.find(
D);
6879 It != this->LambdaCaptures.end()) {
6880 auto [Offset, IsPtr] = It->second;
6883 return this->emitGetThisFieldPtr(Offset,
E);
6884 return this->emitGetPtrThisField(Offset,
E);
6887 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E);
6888 DRE && DRE->refersToEnclosingVariableOrCapture()) {
6889 if (
const auto *VD = dyn_cast<VarDecl>(
D); VD && VD->
isInitCapture())
6893 if (
const auto *BD = dyn_cast<BindingDecl>(
D))
6894 return this->visit(BD->getBinding());
6897 if (
D == InitializingDecl)
6898 return this->emitDummyPtr(
D,
E);
6904 if (
const auto *VD = dyn_cast<VarDecl>(
D);
6908 return this->emitDummyPtr(
D,
E);
6912 const auto *VD = dyn_cast<VarDecl>(
D);
6914 return this->emitDummyPtr(
D,
E);
6916 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
6917 if (
T.isConstant(Ctx.getASTContext()))
6923 typeShouldBeVisited(VD->
getType())) {
6925 Init && !
Init->isValueDependent()) {
6931 (void)
Init->EvaluateAsInitializer(
V, Ctx.getASTContext(), VD, Notes,
6933 return this->visitDeclRef(
D,
E);
6949 return this->emitDummyPtr(
D,
E);
6951 return this->emitInvalidDeclRef(cast<DeclRefExpr>(
E),
6955 return this->emitDummyPtr(
D,
E);
6958template <
class Emitter>
6960 const auto *
D =
E->getDecl();
6961 return this->visitDeclRef(
D,
E);
6966 C->emitDestruction();
6969template <
class Emitter>
6973 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
6975 return Ty->getAsCXXRecordDecl();
6977 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
6978 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
6980 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
6984template <
class Emitter>
6991 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
6996 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
6997 getFPOptions(
E),
E);
6999 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
7000 getFPOptions(
E),
E);
7004 return this->emitCastFloatingIntegral(ToT, getFPOptions(
E),
E);
7009 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT),
E);
7011 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT),
E);
7015 return FromT != ToT ? this->emitCast(FromT, ToT,
E) :
true;
7019 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
7020 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(
E),
E);
7028template <
class Emitter>
7033 return this->
discard(SubExpr);
7035 if (!this->visit(SubExpr))
7038 if (!this->emitConstUint8(0, SubExpr))
7040 return this->emitArrayElemPtrPopUint8(SubExpr);
7044 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
7048template <
class Emitter>
7050 assert(!DiscardResult);
7054 if (!this->emitArrayElem(ElemT, 0,
E))
7057 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(
E),
E))
7060 if (!this->emitCast(ElemT,
PT_Bool,
E))
7065 LabelTy LabelTrue = this->getLabel();
7066 if (!this->jumpTrue(LabelTrue))
7069 if (!this->emitArrayElemPop(ElemT, 1,
E))
7072 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(
E),
E))
7075 if (!this->emitCast(ElemT,
PT_Bool,
E))
7079 LabelTy EndLabel = this->getLabel();
7080 this->jump(EndLabel);
7082 this->emitLabel(LabelTrue);
7083 if (!this->emitPopPtr(
E))
7085 if (!this->emitConstBool(
true,
E))
7088 this->fallthrough(EndLabel);
7089 this->emitLabel(EndLabel);
7094template <
class Emitter>
7097 assert(
E->isComparisonOp());
7099 assert(!DiscardResult);
7105 LHSIsComplex =
true;
7106 ElemT = classifyComplexElementType(LHS->
getType());
7107 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true);
7108 if (!this->visit(LHS))
7110 if (!this->emitSetLocal(
PT_Ptr, LHSOffset,
E))
7113 LHSIsComplex =
false;
7115 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true);
7116 if (!this->visit(LHS))
7118 if (!this->emitSetLocal(LHST, LHSOffset,
E))
7125 RHSIsComplex =
true;
7126 ElemT = classifyComplexElementType(RHS->
getType());
7127 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true);
7128 if (!this->visit(RHS))
7130 if (!this->emitSetLocal(
PT_Ptr, RHSOffset,
E))
7133 RHSIsComplex =
false;
7135 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true);
7136 if (!this->visit(RHS))
7138 if (!this->emitSetLocal(RHST, RHSOffset,
E))
7142 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
7143 bool IsComplex) ->
bool {
7145 if (!this->emitGetLocal(
PT_Ptr, LocalOffset,
E))
7147 return this->emitArrayElemPop(ElemT, Index,
E);
7149 return this->emitGetLocal(ElemT, LocalOffset,
E);
7152 for (
unsigned I = 0; I != 2; ++I) {
7154 if (!getElem(LHSOffset, I, LHSIsComplex))
7156 if (!getElem(RHSOffset, I, RHSIsComplex))
7159 if (!this->emitEQ(ElemT,
E))
7162 if (!this->emitCastBoolUint8(
E))
7167 if (!this->emitAddUint8(
E))
7169 if (!this->emitConstUint8(2,
E))
7172 if (
E->getOpcode() == BO_EQ) {
7173 if (!this->emitEQUint8(
E))
7175 }
else if (
E->getOpcode() == BO_NE) {
7176 if (!this->emitNEUint8(
E))
7183 return this->emitCast(
PT_Bool, ResT,
E);
7190template <
class Emitter>
7199 const Function *DtorFunc = getFunction(Dtor);
7204 if (!this->emitDupPtr(
Loc))
7206 return this->emitCall(DtorFunc, 0,
Loc);
7211template <
class Emitter>
7237 for (ssize_t I = N - 1; I >= 0; --I) {
7238 if (!this->emitConstUint64(I,
Loc))
7240 if (!this->emitArrayElemPtrUint64(
Loc))
7242 if (!this->emitDestruction(ElemDesc,
Loc))
7244 if (!this->emitPopPtr(
Loc))
7260template <
class Emitter>
7262 assert(!DiscardResult &&
"Should've been checked before");
7264 unsigned DummyID =
P.getOrCreateDummy(
D);
7266 if (!this->emitGetPtrGlobal(DummyID,
E))
7274 return this->emitDecayPtr(
PT_Ptr, PT,
E);
7280template <
class Emitter>
7282 assert(!DiscardResult &&
"Should've been checked before");
7285 return this->emitConstFloat(
Floating(F),
E);
7287 APInt I = F.bitcastToAPInt();
7288 return this->emitConstFloat(
7290 llvm::APFloatBase::SemanticsToEnum(F.getSemantics())),
7301template <
class Emitter>
7303 const Expr *SubExpr =
E->getSubExpr();
7315 if (!this->emitGetPtrLocal(*LocalIndex,
E))
7325 if (!this->visit(SubExpr))
7327 }
else if (
OptPrimType FromT = classify(SubExpr)) {
7328 unsigned TempOffset =
7329 allocateLocalPrimitive(SubExpr, *FromT,
true);
7330 if (!this->visit(SubExpr))
7332 if (!this->emitSetLocal(*FromT, TempOffset,
E))
7334 if (!this->emitGetPtrLocal(TempOffset,
E))
7341 if (!this->emitBitCast(
E))
7343 return DiscardResult ? this->emitPopPtr(
E) :
true;
7347 const llvm::fltSemantics *TargetSemantics =
nullptr;
7349 TargetSemantics = &Ctx.getFloatSemantics(ToType);
7355 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
7357 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->
isStdByteType(),
7358 ResultBitWidth, TargetSemantics,
E))
7362 return this->emitPop(*ToT,
E);
ASTImporterLookupTable & LT
static void emitCleanup(CIRGenFunction &cgf, EHScopeStack::Cleanup *cleanup)
#define EMIT_ARITH_OP(OP)
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
static const Expr * stripDerivedToBaseCasts(const Expr *E)
static bool hasTrivialDefaultCtorParent(const FieldDecl *FD)
static bool initNeedsOverridenLoc(const CXXCtorInitializer *Init)
a trap message and trap category.
llvm::APInt getValue() const
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
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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...
const VariableArrayType * getAsVariableArrayType(QualType T) const
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.
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source 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 C++2a __builtin_bit_cast(T, v) expression.
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.
Represents a C++ base or member initializer.
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.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
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 isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
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_range captures() 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]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
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...
bool isAnyOperatorNew() const
DoStmt - This represents a 'do/while' stmt.
Represents a reference to #emded data.
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 * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
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.
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.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
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...
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
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.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
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.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
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.
bool isConstant(const ASTContext &Ctx) 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, ArrayRef< SourceLocation > Locs)
This is the "fully general" constructor that allows representation of strings formed from one or more...
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.
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
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() 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
EnumDecl * castAsEnumDecl() 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 isRealFloatingType() const
Floating point categories.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represents C++ using-directive.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool isStaticDataMember() const
Determines whether this is a static data member.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
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.
VarCreationState visitVarDecl(const VarDecl *VD, bool Toplevel=false, bool IsConstexprUnknown=false)
Creates and initializes a variable from the given decl.
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 visitArrayElemInit(unsigned ElemIndex, const Expr *Init, OptPrimType InitT)
Pointer to the array(not the element!) must be on the stack when calling this.
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)
VarCreationState visitDecl(const VarDecl *VD, bool IsConstexprUnknown=false)
bool visitAPValueInitializer(const APValue &Val, const Expr *E, QualType T)
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 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)
bool VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *E)
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 visit(const Expr *E) override
Evaluates an expression and places the result on the stack.
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.
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 visitDeclStmt(const DeclStmt *DS, bool EvaluateConditionDecl=false)
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 visitCallArgs(ArrayRef< const Expr * > Args, const FunctionDecl *FuncDecl, bool Activate, bool IsOperatorCall)
bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E)
bool visitDefaultStmt(const DefaultStmt *S)
typename Emitter::LabelTy LabelTy
bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E)
bool visitStmt(const Stmt *S)
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
bool VisitVectorUnaryOperator(const UnaryOperator *E)
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, const ValueDecl *ExtendingDecl=nullptr, ScopeKind SC=ScopeKind::Block, bool IsConstexprUnknown=false)
Creates a local primitive value.
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)
UnsignedOrNone allocateTemporary(const Expr *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)
UnsignedOrNone allocateLocal(DeclTy &&Decl, QualType Ty=QualType(), const ValueDecl *ExtendingDecl=nullptr, ScopeKind=ScopeKind::Block, bool IsConstexprUnknown=false)
Allocates a space storing a local given its type.
bool VisitVectorBinOp(const BinaryOperator *E)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
VariableScope< Emitter > * BreakVarScope
Scope to cleanup until when we see a break statement.
std::optional< LabelTy > OptLabelTy
bool 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)
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool visitAsLValue(const Expr *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)
bool visitCXXTryStmt(const CXXTryStmt *S)
static bool isUnevaluatedBuiltin(unsigned ID)
Unevaluated builtins don't get their arguments put on the stack automatically.
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.
DeclScope(Compiler< Emitter > *Ctx, const ValueDecl *VD)
Wrapper around fixed point types.
static FixedPoint zero(llvm::FixedPointSemantics Sem)
If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY.
unsigned getNumParams() const
bool hasThisPointer() const
bool hasRVO() const
Checks if the first argument is a RVO pointer.
When generating code for e.g.
LocOverrideScope(Compiler< Emitter > *Ctx, SourceInfo NewValue, bool Enabled=true)
Generic scope for local variables.
bool destroyLocals(const Expr *E=nullptr) override
Explicit destruction of local variables.
Sets the context for break/continue statements.
typename Compiler< Emitter >::LabelTy LabelTy
LoopScope(Compiler< Emitter > *Ctx, LabelTy BreakLabel, LabelTy ContinueLabel)
typename Compiler< Emitter >::OptLabelTy OptLabelTy
PrimType value_or(PrimType PT) const
Scope used to handle initialization methods.
OptionScope(Compiler< Emitter > *Ctx, bool NewDiscardResult, bool NewInitializing, bool NewToLValue)
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)
constexpr bool isSignedType(PrimType T)
bool Div(InterpState &S, CodePtr OpPC)
1) Pops the RHS from the stack.
static bool Activate(InterpState &S, CodePtr OpPC)
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)
static void discard(InterpStack &Stk, PrimType T)
bool LE(InterpState &S, CodePtr OpPC)
PrimType
Enumeration of the primitive types of the VM.
static std::optional< bool > getBoolValue(const Expr *E)
bool Mul(InterpState &S, CodePtr OpPC)
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
llvm::BitVector collectNonNullArgs(const FunctionDecl *F, ArrayRef< const Expr * > Args)
constexpr bool isIntegralType(PrimType T)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Success
Annotation was successful.
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
@ SD_Static
Static storage duration.
const FunctionProtoType * T
Describes a memory block created by an allocation site.
unsigned getNumElems() const
Returns the number of elements stored in the block.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
const Descriptor *const ElemDesc
Descriptor of the array element.
static constexpr MetadataSize InlineDescMD
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
const Record *const ElemRecord
Pointer to the record, if block contains records.
bool isArray() const
Checks if the descriptor is of an array.
Descriptor used for global variables.
GlobalInitState InitState
static InitLink 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)
bool isUnnamedBitField() const
Information about a local's storage.
State encapsulating if a the variable creation has been successful, unsuccessful, or no variable has ...
static VarCreationState NotCreated()