19#include "llvm/Support/SaveAndRestore.h"
30 if (
const auto *CE = dyn_cast_if_present<ConstantExpr>(E);
31 CE && CE->hasAPValueResult() &&
33 return CE->getResultAsAPSInt().getBoolValue();
44 OldInitializingDecl(
Ctx->InitializingDecl) {
45 Ctx->InitializingDecl = VD;
50 this->
Ctx->InitializingDecl = OldInitializingDecl;
51 this->
Ctx->InitStack.pop_back();
64 bool NewInitializing,
bool NewToLValue)
65 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
66 OldInitializing(Ctx->
Initializing), OldToLValue(Ctx->ToLValue) {
67 Ctx->DiscardResult = NewDiscardResult;
68 Ctx->Initializing = NewInitializing;
69 Ctx->ToLValue = NewToLValue;
73 Ctx->DiscardResult = OldDiscardResult;
74 Ctx->Initializing = OldInitializing;
75 Ctx->ToLValue = OldToLValue;
82 bool OldDiscardResult;
87template <
class Emitter>
91 return Ctx->emitThis(E);
94 return Ctx->emitGetPtrFieldPop(
Offset, E);
96 return Ctx->emitGetPtrLocal(
Offset, E);
100 if (!Ctx->emitConstUint32(
Offset, E))
102 return Ctx->emitArrayElemPtrPopUint32(E);
104 return Ctx->emitRVOPtr(E);
108 llvm_unreachable(
"Unhandled InitLink kind");
124 for (
const LabelInfo &LI : Ctx->LabelInfoStack)
125 assert(LI.Name != Name);
128 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel, ContinueLabel,
149 : Ctx(Ctx), OldCaseLabels(
std::move(this->Ctx->CaseLabels)) {
151 for (
const LabelInfo &LI : Ctx->LabelInfoStack)
152 assert(LI.Name != Name);
155 this->Ctx->CaseLabels = std::move(CaseLabels);
156 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel,
158 DefaultLabel, Ctx->VarScope);
162 this->Ctx->CaseLabels = std::move(OldCaseLabels);
163 this->Ctx->LabelInfoStack.pop_back();
168 CaseMap OldCaseLabels;
174 Ctx->InStmtExpr =
true;
192 : Ctx(Ctx), OldFlag(Ctx->LocOverride), Enabled(Enabled) {
195 Ctx->LocOverride = NewValue;
200 Ctx->LocOverride = OldFlag;
205 std::optional<SourceInfo> OldFlag;
212template <
class Emitter>
220 case CK_LValueToRValue: {
231 if (
const auto *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
237 if (
auto GlobalIndex =
P.getGlobal(D))
238 return this->emitGetGlobal(*SubExprT, *GlobalIndex, E);
239 }
else if (
auto It =
Locals.find(D); It !=
Locals.end()) {
240 return this->emitGetLocal(*SubExprT, It->second.Offset, E);
241 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
242 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
243 return this->emitGetParam(*SubExprT, It->second.Index, E);
255 if (!this->emitGetPtrLocal(*LocalIndex, E))
259 if (!this->
visit(SubExpr))
263 return this->emitLoadPop(*SubExprT, E);
268 return this->emitMemcpy(E);
271 case CK_DerivedToBaseMemberPointer: {
282 ->getMostRecentCXXRecordDecl();
284 const CXXRecordDecl *ToDecl = B->getType()->getAsCXXRecordDecl();
285 unsigned DerivedOffset =
Ctx.collectBaseOffset(ToDecl, CurDecl);
287 if (!this->emitCastMemberPtrBasePop(DerivedOffset, ToDecl, E))
295 case CK_BaseToDerivedMemberPointer: {
306 ->getMostRecentCXXRecordDecl();
310 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
312 PathI != PathE; ++PathI) {
313 const CXXRecordDecl *ToDecl = (*PathI)->getType()->getAsCXXRecordDecl();
314 unsigned DerivedOffset =
Ctx.collectBaseOffset(CurDecl, ToDecl);
316 if (!this->emitCastMemberPtrDerivedPop(-DerivedOffset, ToDecl, E))
323 assert(ToDecl != CurDecl);
324 unsigned DerivedOffset =
Ctx.collectBaseOffset(CurDecl, ToDecl);
326 if (!this->emitCastMemberPtrDerivedPop(-DerivedOffset, ToDecl, E))
332 case CK_UncheckedDerivedToBase:
333 case CK_DerivedToBase: {
338 if (
const auto *PT = dyn_cast<PointerType>(Ty))
339 return PT->getPointeeType()->getAsCXXRecordDecl();
340 return Ty->getAsCXXRecordDecl();
347 if (B->isVirtual()) {
348 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), E))
350 CurType = B->getType();
352 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
353 if (!this->emitGetPtrBasePop(
356 CurType = B->getType();
363 case CK_BaseToDerived: {
366 unsigned DerivedOffset =
372 return this->emitGetPtrDerivedPop(DerivedOffset,
377 case CK_FloatingCast: {
382 if (!this->
visit(SubExpr))
384 const auto *TargetSemantics = &
Ctx.getFloatSemantics(E->
getType());
388 case CK_IntegralToFloating: {
391 if (!this->
visit(SubExpr))
393 const auto *TargetSemantics = &
Ctx.getFloatSemantics(E->
getType());
394 return this->emitCastIntegralFloating(
classifyPrim(SubExpr),
395 TargetSemantics, getFPOptions(E), E);
398 case CK_FloatingToBoolean: {
402 if (
const auto *FL = dyn_cast<FloatingLiteral>(SubExpr))
403 return this->emitConstBool(FL->getValue().isNonZero(), E);
404 if (!this->
visit(SubExpr))
406 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
409 case CK_FloatingToIntegral: {
412 if (!this->
visit(SubExpr))
416 return this->emitCastFloatingIntegralAP(
Ctx.getBitWidth(E->
getType()),
419 return this->emitCastFloatingIntegralAPS(
Ctx.getBitWidth(E->
getType()),
422 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
425 case CK_NullToPointer:
426 case CK_NullToMemberPointer: {
431 if (!PointeeType.
isNull()) {
433 Desc =
P.createDescriptor(SubExpr, *T);
435 Desc =
P.createDescriptor(SubExpr, PointeeType.
getTypePtr(),
439 uint64_t Val =
Ctx.getASTContext().getTargetNullPointerValue(E->
getType());
443 case CK_PointerToIntegral: {
444 if (!this->
visit(SubExpr))
450 if (!this->emitDecayPtr(FromT,
PT_Ptr, E))
456 return this->emitCastPointerIntegralAP(
Ctx.getBitWidth(E->
getType()), E);
458 return this->emitCastPointerIntegralAPS(
Ctx.getBitWidth(E->
getType()), E);
459 return this->emitCastPointerIntegral(T, E);
462 case CK_ArrayToPointerDecay: {
463 if (!this->
visit(SubExpr))
465 return this->emitArrayDecay(E);
468 case CK_IntegralToPointer: {
470 assert(IntType->isIntegralOrEnumerationType());
471 if (!this->
visit(SubExpr))
479 Desc =
P.createDescriptor(SubExpr, *T);
486 if (!this->emitGetIntPtr(T, Desc, E))
494 return this->emitDecayPtr(
PT_Ptr, DestPtrT, E);
497 case CK_AtomicToNonAtomic:
498 case CK_ConstructorConversion:
499 case CK_FunctionToPointerDecay:
500 case CK_NonAtomicToAtomic:
502 case CK_UserDefinedConversion:
503 case CK_AddressSpaceConversion:
504 case CK_CPointerToObjCPointerCast:
521 return this->emitBuiltinBitCast(E);
536 if (!this->
visit(SubExpr))
544 return this->emitFnPtrCast(E);
551 if (!this->
visit(SubExpr))
553 return this->emitDecayPtr(*FromT, *ToT, E);
555 case CK_IntegralToBoolean:
556 case CK_FixedPointToBoolean: {
562 if (
const auto *IL = dyn_cast<IntegerLiteral>(SubExpr))
563 return this->emitConst(IL->getValue(), E);
564 if (!this->
visit(SubExpr))
569 case CK_BooleanToSignedIntegral:
570 case CK_IntegralCast: {
577 if (
const auto *IL = dyn_cast<IntegerLiteral>(SubExpr)) {
582 if (!this->emitConst(IL->getValue(), SubExpr))
585 if (!this->
visit(SubExpr))
593 if (!ED->isFixed()) {
594 if (!this->emitCheckEnumValue(*FromT, ED, E))
600 if (!this->emitCastAP(*FromT,
Ctx.getBitWidth(E->
getType()), E))
603 if (!this->emitCastAPS(*FromT,
Ctx.getBitWidth(E->
getType()), E))
608 if (!this->emitCast(*FromT, *ToT, E))
611 if (E->
getCastKind() == CK_BooleanToSignedIntegral)
612 return this->emitNeg(*ToT, E);
616 case CK_PointerToBoolean:
617 case CK_MemberPointerToBoolean: {
620 if (!this->
visit(SubExpr))
622 return this->emitIsNonNull(PtrT, E);
625 case CK_IntegralComplexToBoolean:
626 case CK_FloatingComplexToBoolean: {
627 if (!this->
visit(SubExpr))
629 return this->emitComplexBoolCast(SubExpr);
632 case CK_IntegralComplexToReal:
633 case CK_FloatingComplexToReal:
634 return this->emitComplexReal(SubExpr);
636 case CK_IntegralRealToComplex:
637 case CK_FloatingRealToComplex: {
644 if (!this->emitGetPtrLocal(*LocalIndex, E))
653 if (!this->visitZeroInitializer(T, SubExpr->
getType(), SubExpr))
655 return this->emitInitElem(T, 1, SubExpr);
658 case CK_IntegralComplexCast:
659 case CK_FloatingComplexCast:
660 case CK_IntegralComplexToFloatingComplex:
661 case CK_FloatingComplexToIntegralComplex: {
668 if (!this->emitGetPtrLocal(*LocalIndex, E))
675 unsigned SubExprOffset =
677 if (!this->
visit(SubExpr))
679 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, E))
687 for (
unsigned I = 0; I != 2; ++I) {
688 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, E))
690 if (!this->emitArrayElemPop(SourceElemT, I, E))
694 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, E))
698 if (!this->emitInitElem(DestElemT, I, E))
704 case CK_VectorSplat: {
715 if (!this->emitGetPtrLocal(*LocalIndex, E))
721 unsigned ElemOffset =
725 if (!this->
visit(SubExpr))
730 if (!this->emitSetLocal(ElemT, ElemOffset, E))
733 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
734 if (!this->emitGetLocal(ElemT, ElemOffset, E))
736 if (!this->emitInitElem(ElemT, I, E))
743 case CK_HLSLVectorTruncation: {
748 if (!this->
visit(SubExpr))
750 return this->emitArrayElemPop(*ResultT, 0, E);
759 if (!this->emitGetPtrLocal(*LocalIndex, E))
764 if (!this->
visit(SubExpr))
766 return this->emitCopyArray(classifyVectorElementType(E->
getType()), 0, 0,
770 case CK_IntegralToFixedPoint: {
771 if (!this->
visit(SubExpr))
775 Ctx.getASTContext().getFixedPointSemantics(E->
getType()).toOpaqueInt();
780 return this->emitPopFixedPoint(E);
783 case CK_FloatingToFixedPoint: {
784 if (!this->
visit(SubExpr))
788 Ctx.getASTContext().getFixedPointSemantics(E->
getType()).toOpaqueInt();
789 if (!this->emitCastFloatingFixedPoint(Sem, E))
792 return this->emitPopFixedPoint(E);
795 case CK_FixedPointToFloating: {
796 if (!this->
visit(SubExpr))
798 const auto *TargetSemantics = &
Ctx.getFloatSemantics(E->
getType());
799 if (!this->emitCastFixedPointFloating(TargetSemantics, E))
802 return this->emitPopFloat(E);
805 case CK_FixedPointToIntegral: {
806 if (!this->
visit(SubExpr))
809 if (!this->emitCastFixedPointIntegral(IntegralT, E))
812 return this->emitPop(IntegralT, E);
815 case CK_FixedPointCast: {
816 if (!this->
visit(SubExpr))
819 Ctx.getASTContext().getFixedPointSemantics(E->
getType()).toOpaqueInt();
820 if (!this->emitCastFixedPoint(Sem, E))
823 return this->emitPopFixedPoint(E);
835 case CK_LValueBitCast:
840 case CK_HLSLArrayRValue: {
847 if (!this->emitGetPtrLocal(*LocalIndex, E))
850 if (!this->
visit(SubExpr))
852 return this->emitMemcpy(E);
855 case CK_HLSLMatrixTruncation: {
860 if (!this->
visit(SubExpr))
862 return this->emitArrayElemPop(*ResultT, 0, E);
871 if (!this->emitGetPtrLocal(*LocalIndex, E))
876 if (!this->
visit(SubExpr))
878 return this->emitCopyArray(classifyMatrixElementType(SubExpr->
getType()), 0,
882 case CK_HLSLAggregateSplatCast: {
892 if (!this->emitGetPtrLocal(*LocalIndex, E))
902 if (!this->
visit(SubExpr))
904 if (!this->emitSetLocal(SrcElemT, SrcOffset, E))
908 return emitHLSLAggregateSplat(SrcElemT, SrcOffset, E->
getType(), E);
911 case CK_HLSLElementwiseCast: {
922 unsigned SrcPtrOffset =
924 if (!this->
visit(SubExpr))
926 if (!this->emitSetLocal(
PT_Ptr, SrcPtrOffset, E))
930 if (!emitHLSLFlattenAggregate(SrcType, SrcPtrOffset, Elements, 1, E))
932 if (Elements.empty())
935 const HLSLFlatElement &Src = Elements[0];
936 if (!this->emitGetLocal(Src.Type, Src.LocalOffset, E))
938 return this->emitPrimCast(Src.Type, *DestT, DestType, E);
945 if (!this->emitGetPtrLocal(*LocalIndex, E))
951 if (!this->
visit(SubExpr))
953 if (!this->emitSetLocal(
PT_Ptr, SrcOffset, E))
957 unsigned ElemCount = countHLSLFlatElements(DestType);
960 Elements.reserve(ElemCount);
961 if (!emitHLSLFlattenAggregate(SrcType, SrcOffset, Elements, ElemCount, E))
966 assert(Elements.size() == ElemCount &&
967 "Source type has fewer scalar elements than the destination type");
969 return emitHLSLConstructAggregate(DestType, Elements, E);
976 const Record::Field *RF = R->getField(UnionField);
977 QualType FieldType = RF->Decl->getType();
980 if (!this->
visit(SubExpr))
982 if (RF->isBitField())
983 return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(),
985 return this->emitInitFieldActivate(*PT, RF->Offset, E);
988 if (!this->emitGetPtrField(RF->Offset, E))
990 if (!this->emitActivate(E))
996 return this->emitInvalid(E);
998 llvm_unreachable(
"Unhandled clang::CastKind enum");
1001template <
class Emitter>
1003 return this->emitBuiltinBitCast(E);
1006template <
class Emitter>
1011 return this->emitConst(
LE->getValue(),
LE);
1014template <
class Emitter>
1020 return this->emitFloat(F, E);
1023template <
class Emitter>
1033 if (!this->emitGetPtrLocal(*LocalIndex, E))
1040 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
1042 if (!this->emitInitElem(SubExprT, 0, SubExpr))
1047template <
class Emitter>
1055 auto Sem =
Ctx.getASTContext().getFixedPointSemantics(E->
getType());
1060template <
class Emitter>
1065template <
class Emitter>
1092 return this->emitComplexComparison(LHS, RHS, E);
1100 if (!this->
visit(LHS))
1103 if (!this->
visit(RHS))
1106 if (!this->emitToMemberPtr(E))
1112 if (!this->emitCastMemberPtrPtr(E))
1129 Ctx.getASTContext().CompCategories.lookupInfoForType(E->
getType());
1135 if (!this->emitGetPtrLocal(*ResultIndex, E))
1142 return this->emitCMP3(*
LT, CmpInfo, E);
1145 if (!
LT || !RT || !T)
1155 return this->visitAssignment(LHS, RHS, E);
1162 auto MaybeCastToBool = [
this, T, E](
bool Result) {
1166 return this->emitPopBool(E);
1168 return this->emitCast(
PT_Bool, *T, E);
1172 auto Discard = [
this, T, E](
bool Result) {
1180 return MaybeCastToBool(this->emitEQ(*
LT, E));
1182 return MaybeCastToBool(this->emitNE(*
LT, E));
1184 return MaybeCastToBool(this->emitLT(*
LT, E));
1186 return MaybeCastToBool(this->emitLE(*
LT, E));
1188 return MaybeCastToBool(this->emitGT(*
LT, E));
1190 return MaybeCastToBool(this->emitGE(*
LT, E));
1193 return Discard(this->emitSubf(getFPOptions(E), E));
1194 return Discard(this->emitSub(*T, E));
1197 return Discard(this->emitAddf(getFPOptions(E), E));
1198 return Discard(this->emitAdd(*T, E));
1201 return Discard(this->emitMulf(getFPOptions(E), E));
1202 return Discard(this->emitMul(*T, E));
1204 return Discard(this->emitRem(*T, E));
1207 return Discard(this->emitDivf(getFPOptions(E), E));
1208 return Discard(this->emitDiv(*T, E));
1210 return Discard(this->emitBitAnd(*T, E));
1212 return Discard(this->emitBitOr(*T, E));
1214 return Discard(this->emitShl(*
LT, *RT, E));
1216 return Discard(this->emitShr(*
LT, *RT, E));
1218 return Discard(this->emitBitXor(*T, E));
1221 llvm_unreachable(
"Already handled earlier");
1226 llvm_unreachable(
"Unhandled binary op");
1231template <
class Emitter>
1237 if ((Op != BO_Add && Op != BO_Sub) ||
1248 auto visitAsPointer = [&](
const Expr *E,
PrimType T) ->
bool {
1249 if (!this->
visit(E))
1252 return this->emitDecayPtr(T,
PT_Ptr, E);
1261 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *
LT))
1269 ElemTypeSize =
Ctx.getASTContext().getTypeSizeInChars(ElemType);
1272 if (!this->emitSubPtr(IntT, ElemTypeSize.
isZero(), E))
1279 if (!visitAsPointer(RHS, *RT))
1281 if (!this->
visit(LHS))
1285 if (!visitAsPointer(LHS, *
LT))
1287 if (!this->
visit(RHS))
1298 if (!this->emitAddOffset(OffsetType, E))
1302 if (!this->emitSubOffset(OffsetType, E))
1319template <
class Emitter>
1329 LabelTy LabelTrue = this->getLabel();
1330 LabelTy LabelEnd = this->getLabel();
1334 if (!this->jumpTrue(LabelTrue, E))
1339 if (!this->jump(LabelEnd, E))
1342 this->emitLabel(LabelTrue);
1343 this->emitConstBool(
true, E);
1344 this->fallthrough(LabelEnd);
1345 this->emitLabel(LabelEnd);
1348 assert(Op == BO_LAnd);
1351 LabelTy LabelFalse = this->getLabel();
1352 LabelTy LabelEnd = this->getLabel();
1356 if (!this->jumpFalse(LabelFalse, E))
1361 if (!this->jump(LabelEnd, E))
1364 this->emitLabel(LabelFalse);
1365 this->emitConstBool(
false, E);
1366 this->fallthrough(LabelEnd);
1367 this->emitLabel(LabelEnd);
1371 return this->emitPopBool(E);
1376 return this->emitCast(
PT_Bool, *T, E);
1380template <
class Emitter>
1387 if (!this->emitGetPtrLocal(*LocalIndex, E))
1396 PrimType ResultElemT = this->classifyComplexElementType(E->
getType());
1397 unsigned ResultOffset = ~0u;
1403 if (!this->emitDupPtr(E))
1405 if (!this->emitSetLocal(
PT_Ptr, ResultOffset, E))
1410 LHSType = AT->getValueType();
1413 RHSType = AT->getValueType();
1422 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1427 if (!this->
visit(LHS))
1429 if (!this->
visit(RHS))
1431 if (!this->emitMulc(ElemT, E))
1434 return this->emitPopPtr(E);
1438 if (Op == BO_Div && RHSIsComplex) {
1445 if (!LHSIsComplex) {
1450 LHSOffset = *LocalIndex;
1452 if (!this->emitGetPtrLocal(LHSOffset, E))
1455 if (!this->
visit(LHS))
1458 if (!this->emitInitElem(ElemT, 0, E))
1461 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1463 if (!this->emitInitElem(ElemT, 1, E))
1466 if (!this->
visit(LHS))
1470 if (!this->
visit(RHS))
1472 if (!this->emitDivc(ElemT, E))
1475 return this->emitPopPtr(E);
1482 if (!this->
visit(LHS))
1484 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
1489 if (!this->
visit(LHS))
1491 if (!this->emitSetLocal(LHST, LHSOffset, E))
1499 if (!this->
visit(RHS))
1501 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
1506 if (!this->
visit(RHS))
1508 if (!this->emitSetLocal(RHST, RHSOffset, E))
1515 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1516 unsigned ElemIndex,
unsigned Offset,
1517 const Expr *E) ->
bool {
1519 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
1521 return this->emitArrayElemPop(classifyComplexElementType(E->
getType()),
1524 if (ElemIndex == 0 || !LoadZero)
1531 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1534 if (!this->emitGetLocal(
PT_Ptr, ResultOffset, E))
1541 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1544 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1547 if (!this->emitAddf(getFPOptions(E), E))
1550 if (!this->emitAdd(ResultElemT, E))
1555 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1558 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1561 if (!this->emitSubf(getFPOptions(E), E))
1564 if (!this->emitSub(ResultElemT, E))
1569 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1572 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1576 if (!this->emitMulf(getFPOptions(E), E))
1579 if (!this->emitMul(ResultElemT, E))
1584 assert(!RHSIsComplex);
1585 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1588 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1592 if (!this->emitDivf(getFPOptions(E), E))
1595 if (!this->emitDiv(ResultElemT, E))
1606 if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))
1609 if (!this->emitPop(ResultElemT, E))
1614 return this->emitPopPtr(E);
1620template <
class Emitter>
1625 "Comma op should be handled in VisitBinaryOperator");
1639 if (!this->emitGetPtrLocal(*LocalIndex, E))
1653 assert(
Ctx.getASTContext().hasSameUnqualifiedType(
1656 if (!this->
visit(LHS))
1658 if (!this->
visit(RHS))
1660 if (!this->emitCopyArray(ElemT, 0, 0, VecTy->getNumElements(), E))
1663 return this->emitPopPtr(E);
1668 unsigned LHSOffset =
1670 if (!this->
visit(LHS))
1672 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
1676 unsigned RHSOffset =
1678 if (!this->
visit(RHS))
1680 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
1692 if (NeedIntPromot) {
1694 Ctx.getASTContext().getPromotedIntegerType(
Ctx.getASTContext().BoolTy);
1699 auto getElem = [=](
unsigned Offset,
PrimType ElemT,
unsigned Index) {
1700 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
1702 if (!this->emitArrayElemPop(ElemT, Index, E))
1705 if (!this->emitPrimCast(ElemT,
PT_Bool,
Ctx.getASTContext().BoolTy, E))
1707 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(), E))
1709 }
else if (NeedIntPromot) {
1710 if (!this->emitPrimCast(ElemT, PromotT, PromotTy, E))
1716#define EMIT_ARITH_OP(OP) \
1718 if (ElemT == PT_Float) { \
1719 if (!this->emit##OP##f(getFPOptions(E), E)) \
1722 if (!this->emit##OP(ElemT, E)) \
1728 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
1729 if (!getElem(LHSOffset, ElemT, I))
1731 if (!getElem(RHSOffset, RHSElemT, I))
1743 if (!this->emitRem(ElemT, E))
1747 if (!this->emitBitAnd(OpT, E))
1751 if (!this->emitBitOr(OpT, E))
1755 if (!this->emitBitXor(OpT, E))
1759 if (!this->emitShl(OpT, RHSElemT, E))
1763 if (!this->emitShr(OpT, RHSElemT, E))
1767 if (!this->emitEQ(ElemT, E))
1771 if (!this->emitNE(ElemT, E))
1775 if (!this->emitLE(ElemT, E))
1779 if (!this->emitLT(ElemT, E))
1783 if (!this->emitGE(ElemT, E))
1787 if (!this->emitGT(ElemT, E))
1792 if (!this->emitBitAnd(ResultElemT, E))
1797 if (!this->emitBitOr(ResultElemT, E))
1801 return this->emitInvalid(E);
1810 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(), E))
1812 if (!this->emitNeg(ResultElemT, E))
1818 if (NeedIntPromot &&
1819 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(), E))
1823 if (!this->emitInitElem(ResultElemT, I, E))
1832template <
class Emitter>
1842 auto LHSSemaInt = LHSSema.toOpaqueInt();
1844 auto RHSSemaInt = RHSSema.toOpaqueInt();
1846 if (!this->
visit(LHS))
1854 if (!this->
visit(RHS))
1863 auto ConvertResult = [&](
bool R) ->
bool {
1867 auto CommonSema = LHSSema.getCommonSemantics(RHSSema).toOpaqueInt();
1868 if (ResultSema != CommonSema)
1869 return this->emitCastFixedPoint(ResultSema, E);
1873 auto MaybeCastToBool = [&](
bool Result) {
1878 return this->emitPop(T, E);
1880 return this->emitCast(
PT_Bool, T, E);
1886 return MaybeCastToBool(this->emitEQFixedPoint(E));
1888 return MaybeCastToBool(this->emitNEFixedPoint(E));
1890 return MaybeCastToBool(this->emitLTFixedPoint(E));
1892 return MaybeCastToBool(this->emitLEFixedPoint(E));
1894 return MaybeCastToBool(this->emitGTFixedPoint(E));
1896 return MaybeCastToBool(this->emitGEFixedPoint(E));
1898 return ConvertResult(this->emitAddFixedPoint(E));
1900 return ConvertResult(this->emitSubFixedPoint(E));
1902 return ConvertResult(this->emitMulFixedPoint(E));
1904 return ConvertResult(this->emitDivFixedPoint(E));
1906 return ConvertResult(this->emitShiftFixedPoint(
true, E));
1908 return ConvertResult(this->emitShiftFixedPoint(
false, E));
1911 return this->emitInvalid(E);
1914 llvm_unreachable(
"unhandled binop opcode");
1917template <
class Emitter>
1926 if (!this->
visit(SubExpr))
1928 if (!this->emitNegFixedPoint(E))
1931 return this->emitPopFixedPoint(E);
1937 llvm_unreachable(
"Unhandled unary opcode");
1940template <
class Emitter>
1949 return this->visitZeroInitializer(*T, QT, E);
1957 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1958 CXXRD && CXXRD->getNumVBases() > 0) {
1968 return this->visitZeroRecordInitializer(R, E);
1975 return this->visitZeroArrayInitializer(QT, E);
1979 QualType ElemQT = ComplexTy->getElementType();
1981 for (
unsigned I = 0; I < 2; ++I) {
1982 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1984 if (!this->emitInitElem(ElemT, I, E))
1991 unsigned NumVecElements = VecT->getNumElements();
1992 QualType ElemQT = VecT->getElementType();
1995 for (
unsigned I = 0; I < NumVecElements; ++I) {
1996 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1998 if (!this->emitInitElem(ElemT, I, E))
2005 unsigned NumElems = MT->getNumElementsFlattened();
2006 QualType ElemQT = MT->getElementType();
2009 for (
unsigned I = 0; I != NumElems; ++I) {
2010 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2012 if (!this->emitInitElem(ElemT, I, E))
2021template <
class Emitter>
2034 for (
const Expr *SubExpr : {LHS, RHS}) {
2035 if (!this->
visit(SubExpr)) {
2042 if (SubExpr ==
Base &&
Base->getType()->isPointerType()) {
2043 if (!this->emitExpandPtr(E))
2054 return this->emitError(E);
2057 if (!this->emitFlip(
PT_Ptr, *IndexT, E))
2061 if (!this->emitArrayElemPtrPop(*IndexT, E))
2064 return this->emitPopPtr(E);
2070 return this->emitLoadPop(*T, E);
2073template <
class Emitter>
2075 const Expr *ArrayFiller,
const Expr *E) {
2080 QT = AT->getValueType();
2083 if (
Inits.size() == 0)
2085 return this->emitInvalid(E);
2100 if (
Inits.size() == 0)
2101 return this->visitZeroInitializer(*T, QT, E);
2102 assert(
Inits.size() == 1);
2115 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
2122 bool BitField = FieldToInit->isBitField();
2124 return this->emitInitBitFieldActivate(T, FieldToInit->Offset,
2125 FieldToInit->bitWidth(), E);
2127 return this->emitInitBitField(T, FieldToInit->Offset,
2128 FieldToInit->bitWidth(), E);
2130 return this->emitInitFieldActivate(T, FieldToInit->Offset, E);
2131 return this->emitInitField(T, FieldToInit->Offset, E);
2134 auto initCompositeField = [=](
const Record::Field *FieldToInit,
2142 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
2145 if (
Activate && !this->emitActivate(E))
2152 if (
Inits.size() == 0) {
2153 if (!this->visitZeroRecordInitializer(R, E))
2158 if (
const auto *ILE = dyn_cast<InitListExpr>(E))
2159 FToInit = ILE->getInitializedFieldInUnion();
2163 const Record::Field *FieldToInit = R->getField(FToInit);
2165 if (!initPrimitiveField(FieldToInit,
Init, *T,
true))
2168 if (!initCompositeField(FieldToInit,
Init,
true))
2172 return this->emitFinishInit(E);
2175 assert(!R->isUnion());
2176 unsigned InitIndex = 0;
2179 while (InitIndex < R->getNumFields() &&
2180 R->getField(InitIndex)->isUnnamedBitField())
2191 const Record::Field *FieldToInit = R->getField(InitIndex);
2192 if (!initPrimitiveField(FieldToInit,
Init, *T))
2197 if (
const Record::Base *B = R->getBase(
Init->getType())) {
2198 if (!this->emitGetPtrBase(B->Offset,
Init))
2206 const Record::Field *FieldToInit = R->getField(InitIndex);
2207 if (!initCompositeField(FieldToInit,
Init))
2213 return this->emitFinishInit(E);
2218 Ctx.getASTContext().getAsConstantArrayType(QT);
2221 if (
Initializing && !this->emitCheckArrayDestSize(NumElems, E))
2224 if (
Inits.size() == 1 && QT ==
Inits[0]->getType())
2228 unsigned ElementIndex = 0;
2230 if (
const auto *EmbedS =
2231 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
2239 if (!this->emitCastIntegralFloating(
classifyPrim(IL), Sem,
2240 getFPOptions(E), E))
2246 return this->emitInitElem(TargetT, ElemIndex, IL);
2248 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
2264 for (; ElementIndex != NumElems; ++ElementIndex) {
2270 return this->emitFinishInit(E);
2274 unsigned NumInits =
Inits.size();
2279 QualType ElemQT = ComplexTy->getElementType();
2281 if (NumInits == 0) {
2283 for (
unsigned I = 0; I < 2; ++I) {
2284 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2286 if (!this->emitInitElem(ElemT, I, E))
2289 }
else if (NumInits == 2) {
2290 unsigned InitIndex = 0;
2295 if (!this->emitInitElem(ElemT, InitIndex, E))
2304 unsigned NumVecElements = VecT->getNumElements();
2305 assert(NumVecElements >=
Inits.size());
2307 QualType ElemQT = VecT->getElementType();
2311 unsigned InitIndex = 0;
2318 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
2319 if (!this->emitCopyArray(ElemT, 0, InitIndex,
2320 InitVecT->getNumElements(), E))
2322 InitIndex += InitVecT->getNumElements();
2324 if (!this->emitInitElem(ElemT, InitIndex, E))
2330 assert(InitIndex <= NumVecElements);
2333 for (; InitIndex != NumVecElements; ++InitIndex) {
2334 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2336 if (!this->emitInitElem(ElemT, InitIndex, E))
2343 unsigned NumElems = MT->getNumElementsFlattened();
2344 assert(
Inits.size() == NumElems);
2346 QualType ElemQT = MT->getElementType();
2352 for (
unsigned I = 0; I != NumElems; ++I) {
2355 if (!this->emitInitElem(ElemT, I, E))
2366template <
class Emitter>
2373 return this->emitInitElem(*InitT, ElemIndex,
Init);
2379 if (!this->emitConstUint32(ElemIndex,
Init))
2381 if (!this->emitArrayElemPtrUint32(
Init))
2386template <
class Emitter>
2389 bool Activate,
bool IsOperatorCall) {
2391 llvm::BitVector NonNullArgs;
2392 if (FuncDecl && FuncDecl->
hasAttr<NonNullAttr>())
2395 bool ExplicitMemberFn =
false;
2396 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl))
2397 ExplicitMemberFn = MD->isExplicitObjectMemberFunction();
2399 unsigned ArgIndex = 0;
2400 for (
const Expr *Arg : Args) {
2402 if (!this->
visit(Arg))
2410 unsigned DeclIndex = ArgIndex - IsOperatorCall + ExplicitMemberFn;
2411 if (DeclIndex < FuncDecl->getNumParams())
2412 Source = FuncDecl->
getParamDecl(ArgIndex - IsOperatorCall +
2421 if (!this->emitGetPtrLocal(*LocalIndex, Arg))
2429 if (!this->emitActivate(Arg))
2433 if (!NonNullArgs.empty() && NonNullArgs[ArgIndex]) {
2436 if (!this->emitCheckNonNullArg(ArgT, Arg))
2447template <
class Emitter>
2452template <
class Emitter>
2458template <
class Emitter>
2464template <
class Emitter>
2482template <
class Emitter>
2484 auto It = E->
begin();
2485 return this->
visit(*It);
2490 bool AlignOfReturnsPreferred =
2491 ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
2497 T = Ref->getPointeeType();
2499 if (T.getQualifiers().hasUnaligned())
2505 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2511template <
class Emitter>
2518 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2524 ArgType = Ref->getPointeeType();
2530 if (
ArgType->isDependentType() || !
ArgType->isConstantSizeType())
2531 return this->emitInvalid(E);
2533 if (Kind == UETT_SizeOf)
2542 return this->emitConst(Size.getQuantity(), E);
2545 if (Kind == UETT_CountOf) {
2551 if (
const auto *CAT =
2555 return this->emitConst(CAT->getSize(), E);
2565 if (VAT->getElementType()->isArrayType()) {
2566 std::optional<APSInt> Res =
2568 ? VAT->getSizeExpr()->getIntegerConstantExpr(ASTCtx)
2573 return this->emitConst(*Res, E);
2578 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2598 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2601 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
2611 return this->emitConst(Size.getQuantity(), E);
2614 if (Kind == UETT_VectorElements) {
2619 return this->emitConst(VT->getNumElements(), E);
2621 return this->emitSizelessVectorElementSize(E);
2624 if (Kind == UETT_VecStep) {
2626 unsigned N = VT->getNumElements();
2633 return this->emitConst(N, E);
2635 return this->emitConst(1, E);
2638 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2645 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2647 return this->emitInvalid(E);
2649 return this->emitConst(
2650 const_cast<ASTContext &
>(ASTCtx).getPointerAuthTypeDiscriminator(
2658template <
class Emitter>
2667 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
2670 if (
auto GlobalIndex =
P.getGlobal(VD)) {
2671 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2673 if (
Member->getType()->isReferenceType())
2674 return this->emitLoadPopPtr(E);
2683 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
Member);
2684 MD && !MD->isStatic()) {
2688 if (!this->
discard(Base) && !this->emitSideEffect(E))
2703 const Record::Field *F = R->getField(FD);
2707 const auto maybeLoadValue = [&]() ->
bool {
2711 return this->emitLoadPop(*T, E);
2716 if (F->Decl->getType()->isReferenceType())
2717 return this->emitGetFieldPop(
PT_Ptr, F->Offset, E) && maybeLoadValue();
2718 return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue();
2721template <
class Emitter>
2731template <
class Emitter>
2745 if (!this->
visit(Common))
2747 return this->emitCopyArray(*SubExprT, 0, 0, Size, E);
2761 for (
size_t I = 0; I != Size; ++I) {
2773template <
class Emitter>
2788 return this->emitGetLocal(SubExprT, It->second, E);
2791 if (!this->
visit(SourceExpr))
2798 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
2807 return this->emitGetLocal(SubExprT, LocalIndex, E);
2811template <
class Emitter>
2834 bool IsBcpCall =
false;
2835 if (
const auto *CE = dyn_cast<CallExpr>(
Condition->IgnoreParenCasts());
2836 CE && CE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) {
2840 LabelTy LabelEnd = this->getLabel();
2841 LabelTy LabelFalse = this->getLabel();
2844 if (!this->emitPushIgnoreDiags(E))
2852 if (this->checkingForUndefinedBehavior()) {
2855 if (!this->
discard(FalseExpr))
2861 if (!this->jumpFalse(LabelFalse, E))
2866 if (!this->jump(LabelEnd, E))
2868 this->emitLabel(LabelFalse);
2872 this->fallthrough(LabelEnd);
2873 this->emitLabel(LabelEnd);
2876 return this->emitPopIgnoreDiags(E);
2880template <
class Emitter>
2886 unsigned StringIndex =
P.createGlobalString(E);
2887 return this->emitGetPtrGlobal(StringIndex, E);
2892 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
2893 assert(CAT &&
"a string literal that's not a constant array?");
2898 unsigned N = std::min(ArraySize, E->
getLength());
2901 for (
unsigned I = 0; I != N; ++I) {
2904 if (CharWidth == 1) {
2905 this->emitConstSint8(CodeUnit, E);
2906 this->emitInitElemSint8(I, E);
2907 }
else if (CharWidth == 2) {
2908 this->emitConstUint16(CodeUnit, E);
2909 this->emitInitElemUint16(I, E);
2910 }
else if (CharWidth == 4) {
2911 this->emitConstUint32(CodeUnit, E);
2912 this->emitInitElemUint32(I, E);
2914 llvm_unreachable(
"unsupported character width");
2919 for (
unsigned I = N; I != ArraySize; ++I) {
2920 if (CharWidth == 1) {
2921 this->emitConstSint8(0, E);
2922 this->emitInitElemSint8(I, E);
2923 }
else if (CharWidth == 2) {
2924 this->emitConstUint16(0, E);
2925 this->emitInitElemUint16(I, E);
2926 }
else if (CharWidth == 4) {
2927 this->emitConstUint32(0, E);
2928 this->emitInitElemUint32(I, E);
2930 llvm_unreachable(
"unsupported character width");
2937template <
class Emitter>
2941 return this->emitDummyPtr(E, E);
2944template <
class Emitter>
2946 auto &A =
Ctx.getASTContext();
2955template <
class Emitter>
2963 auto &A =
Ctx.getASTContext();
2967 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
2968 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
2975 unsigned StringIndex =
P.createGlobalString(SL);
2976 return this->emitGetPtrGlobal(StringIndex, E);
2979template <
class Emitter>
2983 return this->emitConst(E->
getValue(), E);
2986template <
class Emitter>
3012 if (!this->emitSetLocal(*RT, TempOffset, E))
3018 if (!this->emitLoad(LHST, E))
3022 if (!this->emitPrimCast(LHST,
classifyPrim(LHSComputationType),
3023 LHSComputationType, E))
3027 if (!this->emitGetLocal(*RT, TempOffset, E))
3032 if (!this->emitAddf(getFPOptions(E), E))
3036 if (!this->emitSubf(getFPOptions(E), E))
3040 if (!this->emitMulf(getFPOptions(E), E))
3044 if (!this->emitDivf(getFPOptions(E), E))
3055 return this->emitStorePop(LHST, E);
3056 return this->emitStore(LHST, E);
3059template <
class Emitter>
3068 if (Op != BO_AddAssign && Op != BO_SubAssign)
3077 if (!this->emitLoad(*
LT, LHS))
3083 if (Op == BO_AddAssign) {
3084 if (!this->emitAddOffset(*RT, E))
3087 if (!this->emitSubOffset(*RT, E))
3092 return this->emitStorePopPtr(E);
3093 return this->emitStorePtr(E);
3096template <
class Emitter>
3109 if (!
Ctx.getLangOpts().CPlusPlus14)
3110 return this->
visit(RHS) && this->
visit(LHS) && this->emitError(E);
3112 if (!
LT || !RT || !ResultT || !LHSComputationT)
3137 if (!this->emitSetLocal(*RT, TempOffset, E))
3144 if (!this->emitLoad(*
LT, E))
3146 if (
LT != LHSComputationT &&
3152 if (!this->emitGetLocal(*RT, TempOffset, E))
3158 if (!this->emitAdd(*LHSComputationT, E))
3162 if (!this->emitSub(*LHSComputationT, E))
3166 if (!this->emitMul(*LHSComputationT, E))
3170 if (!this->emitDiv(*LHSComputationT, E))
3174 if (!this->emitRem(*LHSComputationT, E))
3178 if (!this->emitShl(*LHSComputationT, *RT, E))
3182 if (!this->emitShr(*LHSComputationT, *RT, E))
3186 if (!this->emitBitAnd(*LHSComputationT, E))
3190 if (!this->emitBitXor(*LHSComputationT, E))
3194 if (!this->emitBitOr(*LHSComputationT, E))
3198 llvm_unreachable(
"Unimplemented compound assign operator");
3202 if (ResultT != LHSComputationT &&
3203 !this->emitIntegralCast(*LHSComputationT, *ResultT, E->
getType(), E))
3209 return this->emitStoreBitFieldPop(*ResultT, E);
3210 return this->emitStorePop(*ResultT, E);
3213 return this->emitStoreBitField(*ResultT, E);
3214 return this->emitStore(*ResultT, E);
3217template <
class Emitter>
3225template <
class Emitter>
3240 if (!
Ctx.getLangOpts().CPlusPlus11)
3247 for (
const Expr *LHS : CommaLHSs) {
3269 if (!this->
visit(Inner))
3274 if (!this->emitInitGlobalTemp(*InnerT, *GlobalIndex, TempDecl, E))
3277 if (!this->emitInitGlobal(*InnerT, *GlobalIndex, E))
3280 return this->emitGetPtrGlobal(*GlobalIndex, E);
3283 if (!this->checkLiteralType(Inner))
3286 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3292 return this->emitInitGlobalTempComp(TempDecl, E);
3305 unsigned LocalIndex =
3307 if (!this->VarScope->LocalsAlwaysEnabled &&
3308 !this->emitEnableLocal(LocalIndex, E))
3311 if (!this->
visit(Inner))
3313 if (!this->emitSetLocal(*InnerT, LocalIndex, E))
3316 return this->emitGetPtrLocal(LocalIndex, E);
3319 if (!this->checkLiteralType(Inner))
3326 if (!this->VarScope->LocalsAlwaysEnabled &&
3327 !this->emitEnableLocal(*LocalIndex, E))
3330 if (!this->emitGetPtrLocal(*LocalIndex, E))
3337template <
class Emitter>
3348 if (!this->
visit(SubExpr))
3352 return this->emitPopPtr(E);
3356template <
class Emitter>
3377 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3382 if (
P.isGlobalInitialized(*GlobalIndex))
3388 return this->emitInitGlobal(*T, *GlobalIndex, E);
3400 unsigned LocalIndex;
3404 LocalIndex = *MaybeIndex;
3408 if (!this->emitGetPtrLocal(LocalIndex, E))
3412 return this->
visit(
Init) && this->emitInit(*T, E);
3416template <
class Emitter>
3429template <
class Emitter>
3433 return this->emitConst(E->
getValue(), E);
3436template <
class Emitter>
3449 for (
const Record::Field &F : R->fields()) {
3451 if (!
Init ||
Init->containsErrors())
3459 if (!this->emitInitField(*T, F.Offset, E))
3462 if (!this->emitGetPtrField(F.Offset, E))
3473template <
class Emitter>
3480 return this->emitGetPtrGlobal(StringIndex, E);
3486template <
class Emitter>
3491 return this->emitInvalid(E);
3494template <
class Emitter>
3520 if (PointeeToT && PointeeFromT) {
3539 bool Fatal = (ToT != FromT);
3546template <
class Emitter>
3549 if (!
Ctx.getLangOpts().CPlusPlus20) {
3557 if (!this->emitCheckDynamicCast(E))
3563template <
class Emitter>
3569 return this->emitConstBool(E->
getValue(), E);
3572template <
class Emitter>
3577 if (T->isRecordType()) {
3591 if (!this->emitGetPtrLocal(*LocalIndex, E))
3599 T->getAsCXXRecordDecl()))
3609 if (!this->visitZeroRecordInitializer(R, E))
3621 assert(
Ctx.getASTContext().hasSameUnqualifiedType(E->
getType(),
3623 if (
const auto *ME = dyn_cast<MaterializeTemporaryExpr>(SrcObj)) {
3624 if (!this->emitCheckFunctionDecl(Ctor, E))
3635 assert(
Func->hasThisPointer());
3636 assert(!
Func->hasRVO());
3640 if (!this->emitDupPtr(E))
3644 for (
const auto *Arg : E->
arguments()) {
3645 if (!this->
visit(Arg))
3649 if (
Func->isVariadic()) {
3650 uint32_t VarArgSize = 0;
3651 unsigned NumParams =
Func->getNumWrittenParams();
3652 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I) {
3656 if (!this->emitCallVar(
Func, VarArgSize, E))
3659 if (!this->emitCall(
Func, 0, E)) {
3664 (void)this->emitPopPtr(E);
3670 return this->emitPopPtr(E);
3674 if (T->isArrayType()) {
3679 if (!this->emitDupPtr(E))
3683 initArrayDimension = [&](
QualType T) ->
bool {
3684 if (!T->isArrayType()) {
3686 for (
const auto *Arg : E->
arguments()) {
3687 if (!this->
visit(Arg))
3691 return this->emitCall(
Func, 0, E);
3695 Ctx.getASTContext().getAsConstantArrayType(T);
3700 for (
size_t I = 0; I != NumElems; ++I) {
3701 if (!this->emitConstUint64(I, E))
3703 if (!this->emitArrayElemPtrUint64(E))
3705 if (!initArrayDimension(ElemTy))
3708 return this->emitPopPtr(E);
3711 return initArrayDimension(E->
getType());
3717template <
class Emitter>
3727 assert(Val.
isInt());
3729 return this->emitConst(I, E);
3736 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
3737 return this->
visit(LValueExpr);
3752 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3756 const APValue &
V = UGCD->getValue();
3757 for (
unsigned I = 0, N = R->getNumFields(); I != N; ++I) {
3758 const Record::Field *F = R->getField(I);
3759 const APValue &FieldValue =
V.getStructField(I);
3765 if (!this->emitInitField(FieldT, F->Offset, E))
3773template <
class Emitter>
3779 for (
unsigned I = 0; I != N; ++I) {
3786 if (!this->
discard(ArrayIndexExpr))
3791 if (!this->
visit(ArrayIndexExpr))
3795 if (!this->emitCast(IndexT,
PT_Sint64, E))
3805 return this->emitOffsetOf(T, E, E);
3808template <
class Emitter>
3817 return this->visitZeroInitializer(*T, Ty, E);
3824 if (!this->emitGetPtrLocal(*LocalIndex, E))
3829 QualType ElemQT = CT->getElementType();
3832 for (
unsigned I = 0; I != 2; ++I) {
3833 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
3835 if (!this->emitInitElem(ElemT, I, E))
3847 if (!this->emitGetPtrLocal(*LocalIndex, E))
3852 QualType ElemQT = VT->getElementType();
3855 for (
unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
3856 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
3858 if (!this->emitInitElem(ElemT, I, E))
3867template <
class Emitter>
3872template <
class Emitter>
3878template <
class Emitter>
3883template <
class Emitter>
3888 return this->emitConst(E->
getValue(), E);
3891template <
class Emitter>
3896 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
3910 unsigned ParamIndex = 0;
3914 if (!this->emitGetParam(PT, ParamIndex, E))
3919 return this->emitCall(F, 0, E);
3924template <
class Emitter>
3932 const Expr *PlacementDest =
nullptr;
3933 bool IsNoThrow =
false;
3938 if (PlacementArgs != 0) {
3947 if (PlacementArgs == 1) {
3955 if (!this->emitInvalidNewDeleteExpr(E, E))
3960 if (OperatorNew->isReservedGlobalPlacementOperator())
3961 PlacementDest = Arg1;
3965 return this->emitInvalid(E);
3967 }
else if (!OperatorNew
3968 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
3969 return this->emitInvalidNewDeleteExpr(E, E);
3972 if (!PlacementDest) {
3977 Desc =
P.createDescriptor(E, *ElemT,
nullptr,
3980 Desc =
P.createDescriptor(
3983 false,
false,
false,
3989 std::optional<const Expr *> ArraySizeExpr = E->
getArraySize();
3993 const Expr *Stripped = *ArraySizeExpr;
3994 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
3995 Stripped = ICE->getSubExpr())
3996 if (ICE->getCastKind() != CK_NoOp &&
3997 ICE->getCastKind() != CK_IntegralCast)
4005 if (!this->
visit(Stripped))
4007 if (!this->emitSetLocal(
SizeT, ArrayLen, E))
4010 if (PlacementDest) {
4011 if (!this->
visit(PlacementDest))
4013 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
4015 if (!this->emitCheckNewTypeMismatchArray(
SizeT, E, E))
4018 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
4023 if (!this->emitAllocN(
SizeT, *ElemT, E, IsNoThrow, E))
4027 if (!this->emitAllocCN(
SizeT, Desc, IsNoThrow, E))
4034 size_t StaticInitElems = 0;
4035 const Expr *DynamicInit =
nullptr;
4039 Ctx.getASTContext().getAsConstantArrayType(InitType)) {
4040 StaticInitElems = CAT->getZExtSize();
4045 if (
const auto *ILE = dyn_cast<InitListExpr>(
Init)) {
4046 if (ILE->hasArrayFiller())
4047 DynamicInit = ILE->getArrayFiller();
4066 const Function *CtorFunc =
nullptr;
4067 if (
const auto *CE = dyn_cast<CXXConstructExpr>(
Init)) {
4071 }
else if (!DynamicInit && !ElemT)
4074 LabelTy EndLabel = this->getLabel();
4075 LabelTy StartLabel = this->getLabel();
4080 if (!this->emitDupPtr(E))
4082 if (!this->emitNullPtr(0,
nullptr, E))
4084 if (!this->emitEQPtr(E))
4086 if (!this->jumpTrue(EndLabel, E))
4093 if (!this->emitConst(StaticInitElems,
SizeT, E))
4095 if (!this->emitSetLocal(
SizeT, Iter, E))
4098 this->fallthrough(StartLabel);
4099 this->emitLabel(StartLabel);
4101 if (!this->emitGetLocal(
SizeT, Iter, E))
4103 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
4105 if (!this->emitLT(
SizeT, E))
4107 if (!this->jumpFalse(EndLabel, E))
4111 if (!this->emitGetLocal(
SizeT, Iter, E))
4113 if (!this->emitArrayElemPtr(
SizeT, E))
4116 if (isa_and_nonnull<ImplicitValueInitExpr>(DynamicInit) &&
4121 if (!this->visitZeroInitializer(InitT, ElemType, E))
4123 if (!this->emitStorePop(InitT, E))
4125 }
else if (DynamicInit) {
4127 if (!this->
visit(DynamicInit))
4129 if (!this->emitStorePop(*InitT, E))
4136 if (!this->visitZeroInitializer(
4140 if (!this->emitStorePop(*ElemT, E))
4144 if (!this->emitCall(CtorFunc, 0, E))
4149 if (!this->emitGetPtrLocal(Iter, E))
4151 if (!this->emitIncPop(
SizeT,
false, E))
4154 if (!this->jump(StartLabel, E))
4157 this->fallthrough(EndLabel);
4158 this->emitLabel(EndLabel);
4162 if (PlacementDest) {
4163 if (!this->
visit(PlacementDest))
4165 if (!this->emitCheckNewTypeMismatch(E, E))
4170 if (!this->emitAlloc(Desc, E))
4179 if (!this->emitInit(*ElemT, E))
4190 return this->emitPopPtr(E);
4195template <
class Emitter>
4201 if (!OperatorDelete->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4202 return this->emitInvalidNewDeleteExpr(E, E);
4211template <
class Emitter>
4217 if (
const Function *F =
Ctx.getOrCreateObjCBlock(E))
4222 return this->emitGetFnPtr(
Func, E);
4225template <
class Emitter>
4229 auto canonType = [](
const Type *T) {
4230 return T->getCanonicalTypeUnqualified().getTypePtr();
4238 return this->emitGetTypeid(
4242 return this->emitGetTypeid(
4251 if (!
Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(E))
4257 if (!this->emitGetTypeidPtr(TypeInfoType, E))
4260 return this->emitPopPtr(E);
4264template <
class Emitter>
4268 return this->emitDummyPtr(E, E);
4269 return this->emitError(E);
4272template <
class Emitter>
4275 return this->emitDummyPtr(E, E);
4276 return this->emitError(E);
4279template <
class Emitter>
4281 assert(
Ctx.getLangOpts().CPlusPlus);
4282 return this->emitConstBool(E->
getValue(), E);
4285template <
class Emitter>
4297 return this->emitDummyPtr(GuidDecl, E);
4302 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4311 assert(
V.isStruct());
4312 assert(
V.getStructNumBases() == 0);
4316 return this->emitFinishInit(E);
4319template <
class Emitter>
4329template <
class Emitter>
4338template <
class Emitter>
4344template <
class Emitter>
4348 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
4352 if (OVE->isUnique())
4368template <
class Emitter>
4373template <
class Emitter>
4375 return this->emitError(E);
4378template <
class Emitter>
4384 return this->emitDummyPtr(E, E);
4387template <
class Emitter>
4391 QualType ElemType = VT->getElementType();
4395 PrimType SrcElemT = classifyVectorElementType(SrcType);
4397 unsigned SrcOffset =
4399 if (!this->
visit(Src))
4401 if (!this->emitSetLocal(
PT_Ptr, SrcOffset, E))
4404 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
4405 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
4407 if (!this->emitArrayElemPop(SrcElemT, I, E))
4411 if (SrcElemT != ElemT) {
4412 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
4414 }
else if (ElemType->isFloatingType() && SrcType != ElemType) {
4415 const auto *TargetSemantics = &
Ctx.getFloatSemantics(ElemType);
4419 if (!this->emitInitElem(ElemT, I, E))
4426template <
class Emitter>
4430 return this->emitInvalid(E);
4439 assert(NumOutputElems > 0);
4445 if (!this->emitGetPtrLocal(*LocalIndex, E))
4450 unsigned VectorOffsets[2];
4451 for (
unsigned I = 0; I != 2; ++I) {
4454 if (!this->
visit(Vecs[I]))
4456 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I], E))
4459 for (
unsigned I = 0; I != NumOutputElems; ++I) {
4461 assert(ShuffleIndex >= -1);
4462 if (ShuffleIndex == -1)
4463 return this->emitInvalidShuffleVectorIndex(I, E);
4465 assert(ShuffleIndex < (NumInputElems * 2));
4466 if (!this->emitGetLocal(
PT_Ptr,
4467 VectorOffsets[ShuffleIndex >= NumInputElems], E))
4469 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
4470 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
4473 if (!this->emitInitElem(ElemT, I, E))
4478 return this->emitPopPtr(E);
4483template <
class Emitter>
4488 Base->getType()->isVectorType() ||
4494 if (Indices.size() == 1) {
4499 if (!this->emitConstUint32(Indices[0], E))
4501 return this->emitArrayElemPtrPop(
PT_Uint32, E);
4511 if (!this->emitSetLocal(
PT_Ptr, BaseOffset, E))
4519 if (!this->emitGetPtrLocal(*ResultIndex, E))
4527 uint32_t DstIndex = 0;
4528 for (uint32_t I : Indices) {
4529 if (!this->emitGetLocal(
PT_Ptr, BaseOffset, E))
4531 if (!this->emitArrayElemPop(ElemT, I, E))
4533 if (!this->emitInitElem(ElemT, DstIndex, E))
4543template <
class Emitter>
4547 return this->
discard(SubExpr) && this->emitInvalid(E);
4553 return this->emitDummyPtr(E, E);
4556template <
class Emitter>
4561 Ctx.getASTContext().getAsConstantArrayType(SubExpr->
getType());
4566 if (!this->
visit(SubExpr))
4568 if (!this->emitConstUint8(0, E))
4570 if (!this->emitArrayElemPtrPopUint8(E))
4572 if (!this->emitInitFieldPtr(R->getField(0u)->Offset, E))
4577 if (!this->emitConst(
ArrayType->getSize(), SecondFieldT, E))
4579 return this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E);
4581 assert(SecondFieldT ==
PT_Ptr);
4583 if (!this->emitGetFieldPtr(R->getField(0u)->Offset, E))
4585 if (!this->emitExpandPtr(E))
4589 if (!this->emitArrayElemPtrPop(
PT_Uint64, E))
4591 return this->emitInitFieldPtr(R->getField(1u)->Offset, E);
4594template <
class Emitter>
4609 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
4611 return this->emitUnsupported(E);
4620 return this->
Visit(E);
4627 return this->
Visit(E);
4631 if (
const auto *PE = dyn_cast<ParenExpr>(E))
4634 if (
const auto *CE = dyn_cast<CastExpr>(E);
4636 (CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp))
4643 if (
const auto *PE = dyn_cast<ParenExpr>(E))
4646 if (
const auto *CE = dyn_cast<CastExpr>(E);
4647 CE && (CE->getCastKind() == CK_DerivedToBase ||
4648 CE->getCastKind() == CK_UncheckedDerivedToBase ||
4649 CE->getCastKind() == CK_NoOp))
4669 if (!this->emitGetPtrLocal(*LocalIndex, E))
4679 return this->
Visit(E);
4682template <
class Emitter>
4688 return this->
Visit(E) && this->emitFinishInit(E);
4691template <
class Emitter>
4697 return this->
Visit(E) && this->emitFinishInitPop(E);
4703 return this->
Visit(E);
4714 if (!this->
visit(E))
4716 return this->emitComplexBoolCast(E);
4721 if (!this->
visit(E))
4729 return this->emitIsNonNullPtr(E);
4733 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
4736 return this->emitCast(*T,
PT_Bool, E);
4739template <
class Emitter>
4743 QT = AT->getValueType();
4747 return this->emitZeroBool(E);
4749 return this->emitZeroSint8(E);
4751 return this->emitZeroUint8(E);
4753 return this->emitZeroSint16(E);
4755 return this->emitZeroUint16(E);
4757 return this->emitZeroSint32(E);
4759 return this->emitZeroUint32(E);
4761 return this->emitZeroSint64(E);
4763 return this->emitZeroUint64(E);
4765 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
4767 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
4769 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
4772 return this->emitNullMemberPtr(0,
nullptr, E);
4774 APFloat F = APFloat::getZero(Ctx.getFloatSemantics(QT));
4775 return this->emitFloat(F, E);
4778 auto Sem = Ctx.getASTContext().getFixedPointSemantics(QT);
4782 llvm_unreachable(
"unknown primitive type");
4785template <
class Emitter>
4786bool Compiler<Emitter>::visitZeroRecordInitializer(
const Record *R,
4791 for (
const Record::Field &Field :
R->fields()) {
4792 if (Field.isUnnamedBitField())
4799 if (!this->visitZeroInitializer(T, QT, E))
4802 if (!this->emitInitFieldActivate(T, Field.Offset, E))
4806 if (!this->emitInitField(T, Field.Offset, E))
4811 if (!this->emitGetPtrField(Field.Offset, E))
4817 for (uint32_t I = 0, N = D->
getNumElems(); I != N; ++I) {
4818 if (!this->visitZeroInitializer(T, ET, E))
4820 if (!this->emitInitElem(T, I, E))
4825 if (!this->visitZeroArrayInitializer(D->
getType(), E))
4828 if (!this->visitZeroRecordInitializer(D->
ElemRecord, E))
4836 if (!this->emitFinishInitActivatePop(E))
4840 if (!this->emitFinishInitPop(E))
4844 for (
const Record::Base &B :
R->bases()) {
4845 if (!this->emitGetPtrBase(B.Offset, E))
4847 if (!this->visitZeroRecordInitializer(B.R, E))
4849 if (!this->emitFinishInitPop(E))
4858template <
class Emitter>
4859bool Compiler<Emitter>::visitZeroArrayInitializer(
QualType T,
const Expr *E) {
4860 assert(T->isArrayType() || T->isAnyComplexType() || T->isVectorType());
4866 for (
size_t I = 0; I != NumElems; ++I) {
4867 if (!this->visitZeroInitializer(*ElemT, ElemType, E))
4869 if (!this->emitInitElem(*ElemT, I, E))
4875 const Record *
R = getRecord(ElemType);
4879 for (
size_t I = 0; I != NumElems; ++I) {
4880 if (!this->emitConstUint32(I, E))
4882 if (!this->emitArrayElemPtr(
PT_Uint32, E))
4884 if (!this->visitZeroRecordInitializer(R, E))
4886 if (!this->emitPopPtr(E))
4892 for (
size_t I = 0; I != NumElems; ++I) {
4893 if (!this->emitConstUint32(I, E))
4895 if (!this->emitArrayElemPtr(
PT_Uint32, E))
4897 if (!this->visitZeroArrayInitializer(ElemType, E))
4899 if (!this->emitPopPtr(E))
4908template <
class Emitter>
4909bool Compiler<Emitter>::visitAssignment(
const Expr *LHS,
const Expr *RHS,
4911 if (!canClassify(E->
getType()))
4914 if (!this->visit(RHS))
4916 if (!this->visit(LHS))
4923 if (!Ctx.getLangOpts().CPlusPlus && !this->emitInvalid(E))
4927 bool Activates = refersToUnion(LHS);
4930 if (!this->emitFlip(
PT_Ptr, RHT, E))
4933 if (DiscardResult) {
4934 if (BitField && Activates)
4935 return this->emitStoreBitFieldActivatePop(RHT, E);
4937 return this->emitStoreBitFieldPop(RHT, E);
4939 return this->emitStoreActivatePop(RHT, E);
4941 return this->emitStorePop(RHT, E);
4944 auto maybeLoad = [&](
bool Result) ->
bool {
4950 return this->emitLoadPop(RHT, E);
4954 if (BitField && Activates)
4955 return maybeLoad(this->emitStoreBitFieldActivate(RHT, E));
4957 return maybeLoad(this->emitStoreBitField(RHT, E));
4959 return maybeLoad(this->emitStoreActivate(RHT, E));
4961 return maybeLoad(this->emitStore(RHT, E));
4964template <
class Emitter>
4965template <
typename T>
4969 return this->emitConstSint8(
Value, E);
4971 return this->emitConstUint8(
Value, E);
4973 return this->emitConstSint16(
Value, E);
4975 return this->emitConstUint16(
Value, E);
4977 return this->emitConstSint32(
Value, E);
4979 return this->emitConstUint32(
Value, E);
4981 return this->emitConstSint64(
Value, E);
4983 return this->emitConstUint64(
Value, E);
4985 return this->emitConstBool(
Value, E);
4992 llvm_unreachable(
"Invalid integral type");
4995 llvm_unreachable(
"unknown primitive type");
4998template <
class Emitter>
4999template <
typename T>
5000bool Compiler<Emitter>::emitConst(T
Value,
const Expr *E) {
5001 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
5004template <
class Emitter>
5008 return this->emitConstIntAPS(
Value, E);
5010 return this->emitConstIntAP(
Value, E);
5012 if (
Value.isSigned())
5013 return this->emitConst(
Value.getSExtValue(), Ty, E);
5014 return this->emitConst(
Value.getZExtValue(), Ty, E);
5017template <
class Emitter>
5021 return this->emitConstIntAPS(
Value, E);
5023 return this->emitConstIntAP(
Value, E);
5026 return this->emitConst(
Value.getSExtValue(), Ty, E);
5027 return this->emitConst(
Value.getZExtValue(), Ty, E);
5030template <
class Emitter>
5031bool Compiler<Emitter>::emitConst(
const APSInt &
Value,
const Expr *E) {
5032 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
5035template <
class Emitter>
5048 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
5049 Locals.insert({VD, Local});
5050 VarScope->addForScopeKind(Local, SC);
5051 return Local.Offset;
5054template <
class Emitter>
5059 bool IsTemporary =
false;
5060 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
5063 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
5064 Init = VarD->getInit();
5066 if (
auto *E = Src.dyn_cast<
const Expr *>()) {
5077 return std::nullopt;
5082 Locals.insert({Key, Local});
5083 VarScope->addForScopeKind(Local, SC);
5084 return Local.Offset;
5087template <
class Emitter>
5097 return std::nullopt;
5107 return Local.Offset;
5110template <
class Emitter>
5112 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
5113 return PT->getPointeeType()->getAsCanonical<RecordType>();
5119 return getRecord(RecordTy->getDecl()->getDefinitionOrSelf());
5123template <
class Emitter>
5125 return P.getOrCreateRecord(RD);
5128template <
class Emitter>
5130 return Ctx.getOrCreateFunction(FD);
5133template <
class Emitter>
5137 auto maybeDestroyLocals = [&]() ->
bool {
5138 if (DestroyToplevelScope)
5139 return RootScope.
destroyLocals() && this->emitCheckAllocations(E);
5140 return this->emitCheckAllocations(E);
5147 return this->emitRetVoid(E) && maybeDestroyLocals();
5155 return this->emitRet(*T, E) && maybeDestroyLocals();
5163 if (!this->emitGetPtrLocal(*LocalOffset, E))
5171 return this->emitRetValue(E) && maybeDestroyLocals();
5174 return maybeDestroyLocals() &&
false;
5177template <
class Emitter>
5179 bool DestroyToplevelScope) {
5183 return this->
visitExpr(E, DestroyToplevelScope);
5186template <
class Emitter>
5198 if (
auto GlobalIndex =
P.getGlobal(VD)) {
5199 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
5213template <
class Emitter>
5215 bool ConstantContext) {
5218 if (!ConstantContext) {
5232 auto GlobalIndex =
P.getGlobal(VD);
5233 assert(GlobalIndex);
5235 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
5238 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
5242 auto Local =
Locals.find(VD);
5243 assert(Local !=
Locals.end());
5245 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
5248 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
5258 auto GlobalIndex =
P.getGlobal(VD);
5259 assert(GlobalIndex);
5260 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
5269 return VDScope.
destroyLocals() && this->emitCheckAllocations(VD);
5272template <
class Emitter>
5283 if (!this->isActive())
5288 if (
Init &&
Init->isValueDependent())
5292 auto checkDecl = [&]() ->
bool {
5294 return !NeedsOp || this->emitCheckDecl(VD, VD);
5301 if (!
P.getGlobal(*GlobalIndex)->isInitialized())
5304 if (
P.isGlobalInitialized(*GlobalIndex))
5308 }
else if ((GlobalIndex =
5323 return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
5326 if (!this->emitGetPtrGlobal(*GlobalIndex,
Init))
5329 if (!this->emitStartInit(
Init))
5335 if (!this->emitEndInit(
Init))
5338 return this->emitFinishInitGlobal(
Init);
5348 if (!
Init ||
Init->getType()->isVoidType())
5357 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
5369 if (!this->emitCheckRefInit(
Init))
5373 return this->emitSetLocal(*VarT, Offset, VD);
5381 if (!this->emitGetPtrLocal(*Offset,
Init))
5389template <
class Emitter>
5404 Locals.insert({VD, Local});
5407 if (!this->emitGetPtrLocal(Local.Offset, VD))
5411 return this->emitDestructionPop(D, VD);
5414template <
class Emitter>
5419 return this->emitConst(Val.
getInt(), ValType, E);
5422 return this->emitFloat(F, E);
5427 if (!this->emitGetMemberPtr(MemberDecl, E))
5433 if (!this->emitCopyMemberPtrPath(PathEntry, IsDerived, E))
5439 return this->emitNullMemberPtr(0,
nullptr, E);
5444 return this->emitNull(ValType, 0,
nullptr, E);
5449 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
5450 return this->
visit(BaseExpr);
5455 QualType EntryType = VD->getType();
5456 for (
auto &Entry : Path) {
5458 uint64_t Index = Entry.getAsArrayIndex();
5461 if (!this->emitConst(Index,
PT_Uint64, E))
5463 if (!this->emitArrayElemPtrPop(
PT_Uint64, E))
5465 EntryType = ElemType;
5475 const Decl *BaseOrMember = Entry.getAsBaseOrMember().getPointer();
5476 if (
const auto *FD = dyn_cast<FieldDecl>(BaseOrMember)) {
5478 if (!this->emitGetPtrFieldPop(EntryOffset, E))
5480 EntryType = FD->getType();
5484 if (!this->emitGetPtrBasePop(BaseOffset,
false, E))
5486 EntryType =
Ctx.getASTContext().getCanonicalTagType(
Base);
5498template <
class Emitter>
5506 const Record::Field *RF = R->getField(I);
5507 QualType FieldType = RF->Decl->getType();
5513 if (!this->emitInitField(*PT, RF->Offset, E))
5516 if (!this->emitGetPtrField(RF->Offset, E))
5520 if (!this->emitFinishInitPop(E))
5528 const Record::Base *RB = R->getBase(I);
5529 QualType BaseType =
Ctx.getASTContext().getCanonicalTagType(RB->Decl);
5531 if (!this->emitGetPtrBase(RB->Offset, E))
5535 if (!this->emitFinishInitPop(E))
5548 const Record::Field *RF = R->getField(UnionField);
5549 QualType FieldType = RF->Decl->getType();
5554 if (RF->isBitField())
5555 return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(),
5557 return this->emitInitFieldActivate(*PT, RF->Offset, E);
5560 if (!this->emitGetPtrField(RF->Offset, E))
5562 if (!this->emitActivate(E))
5566 return this->emitPopPtr(E);
5570 const auto *ArrType = T->getAsArrayTypeUnsafe();
5571 QualType ElemType = ArrType->getElementType();
5574 for (
unsigned A = 0, AN = Val.
getArraySize(); A != AN; ++A) {
5575 const APValue &Elem = A >= InitializedElems
5582 if (!this->emitInitElem(*ElemT, A, E))
5585 if (!this->emitConstUint32(A, E))
5587 if (!this->emitArrayElemPtrUint32(E))
5591 if (!this->emitPopPtr(E))
5602template <
class Emitter>
5604 unsigned BuiltinID) {
5605 if (BuiltinID == Builtin::BI__builtin_constant_p) {
5610 return this->emitConst(0, E);
5613 if (!this->emitStartSpeculation(E))
5615 LabelTy EndLabel = this->getLabel();
5616 if (!this->speculate(E, EndLabel))
5618 if (!this->emitEndSpeculation(E))
5620 this->fallthrough(EndLabel);
5628 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
5629 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
5630 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
5631 BuiltinID == Builtin::BI__builtin_function_start) {
5634 return this->emitDummyPtr(E, E);
5645 if (!this->emitGetPtrLocal(*LocalIndex, E))
5650 switch (BuiltinID) {
5651 case Builtin::BI__builtin_object_size:
5652 case Builtin::BI__builtin_dynamic_object_size: {
5656 if (!this->
visit(Arg0))
5667 case Builtin::BI__assume:
5668 case Builtin::BI__builtin_assume:
5671 case Builtin::BI__atomic_is_lock_free:
5672 case Builtin::BI__atomic_always_lock_free: {
5683 for (
const auto *Arg : E->
arguments()) {
5684 if (!this->
visit(Arg))
5690 if (!this->emitCallBI(E, BuiltinID, E))
5699template <
class Emitter>
5718 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(FuncDecl);
5719 DD && DD->isTrivial()) {
5721 if (!this->
visit(MemberCall->getImplicitObjectArgument()))
5723 return this->emitCheckDestruction(E) && this->emitEndLifetime(E) &&
5724 this->emitPopPtr(E);
5732 bool HasRVO = !
ReturnType->isVoidType() && !T;
5740 if (!this->emitGetPtrLocal(*LocalIndex, E))
5748 if (!this->emitGetPtrLocal(*LocalIndex, E))
5752 if (!this->emitDupPtr(E))
5759 bool IsAssignmentOperatorCall =
false;
5760 bool ActivateLHS =
false;
5761 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
5762 OCE && OCE->isAssignmentOp()) {
5766 assert(Args.size() == 2);
5767 const CXXRecordDecl *LHSRecord = Args[0]->getType()->getAsCXXRecordDecl();
5769 IsAssignmentOperatorCall =
true;
5770 std::reverse(Args.begin(), Args.end());
5776 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
5777 MD && MD->isStatic()) {
5781 Args.erase(Args.begin());
5785 bool Devirtualized =
false;
5788 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
5796 if (!this->
visit(Callee))
5798 if (!this->emitSetLocal(
PT_MemberPtr, *CalleeOffset, E))
5800 if (!this->emitGetLocal(
PT_MemberPtr, *CalleeOffset, E))
5802 if (!this->emitGetMemberPtrBase(E))
5805 const auto *InstancePtr = MC->getImplicitObjectArgument();
5812 Stripped->getType()->getPointeeType()->getAsCXXRecordDecl());
5813 Devirtualized =
true;
5814 if (!this->
visit(Stripped))
5817 if (!this->
visit(InstancePtr))
5821 if (!this->
visit(InstancePtr))
5825 }
else if (
const auto *PD =
5826 dyn_cast<CXXPseudoDestructorExpr>(E->
getCallee())) {
5827 if (!this->emitCheckPseudoDtor(E))
5835 return this->emitEndLifetimePop(E);
5836 }
else if (!FuncDecl) {
5840 if (!this->
visit(Callee))
5842 if (!this->emitSetLocal(
PT_Ptr, *CalleeOffset, E))
5851 if (IsAssignmentOperatorCall) {
5852 assert(Args.size() == 2);
5855 if (!this->emitFlip(Arg2T, Arg1T, E))
5869 assert(HasRVO ==
Func->hasRVO());
5871 bool HasQualifier =
false;
5872 if (
const auto *ME = dyn_cast<MemberExpr>(E->
getCallee()))
5873 HasQualifier = ME->hasQualifier();
5875 bool IsVirtual =
false;
5876 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
5877 IsVirtual = !Devirtualized && MD->isVirtual();
5882 if (IsVirtual && !HasQualifier) {
5883 uint32_t VarArgSize = 0;
5884 unsigned NumParams =
5885 Func->getNumWrittenParams() +
5887 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
5890 if (!this->emitCallVirt(
Func, VarArgSize, E))
5892 }
else if (
Func->isVariadic()) {
5893 uint32_t VarArgSize = 0;
5894 unsigned NumParams =
5895 Func->getNumWrittenParams() +
5897 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
5899 if (!this->emitCallVar(
Func, VarArgSize, E))
5902 if (!this->emitCall(
Func, 0, E))
5911 uint32_t ArgSize = 0;
5912 for (
unsigned I = 0, N = E->
getNumArgs(); I != N; ++I)
5918 if (!this->emitGetLocal(
PT_MemberPtr, *CalleeOffset, E))
5920 if (!this->emitGetMemberPtrDecl(E))
5923 if (!this->emitGetLocal(
PT_Ptr, *CalleeOffset, E))
5926 if (!this->emitCallPtr(ArgSize, E, E))
5937template <
class Emitter>
5944template <
class Emitter>
5951template <
class Emitter>
5956 return this->emitConstBool(E->
getValue(), E);
5959template <
class Emitter>
5965 uint64_t Val =
Ctx.getASTContext().getTargetNullPointerValue(E->
getType());
5966 return this->emitNullPtr(Val,
nullptr, E);
5969template <
class Emitter>
5977 return this->emitZero(T, E);
5980template <
class Emitter>
5985 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
5986 if (this->LambdaThisCapture.Offset > 0) {
5987 if (this->LambdaThisCapture.IsPtr)
5988 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
5989 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
5998 return this->emitThis(E);
6013 unsigned StartIndex = 0;
6014 unsigned EndIndex = 0;
6016 for (StartIndex =
InitStack.size() - 1; StartIndex > 0; --StartIndex) {
6018 EndIndex = StartIndex;
6025 for (; StartIndex > 0; --StartIndex) {
6035 if (StartIndex == 0 && EndIndex == 0)
6038 assert(StartIndex < EndIndex);
6041 for (
unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
6053 case Stmt::CompoundStmtClass:
6055 case Stmt::DeclStmtClass:
6057 case Stmt::ReturnStmtClass:
6059 case Stmt::IfStmtClass:
6061 case Stmt::WhileStmtClass:
6063 case Stmt::DoStmtClass:
6065 case Stmt::ForStmtClass:
6067 case Stmt::CXXForRangeStmtClass:
6069 case Stmt::BreakStmtClass:
6071 case Stmt::ContinueStmtClass:
6073 case Stmt::SwitchStmtClass:
6075 case Stmt::CaseStmtClass:
6077 case Stmt::DefaultStmtClass:
6079 case Stmt::AttributedStmtClass:
6081 case Stmt::CXXTryStmtClass:
6083 case Stmt::NullStmtClass:
6086 case Stmt::GCCAsmStmtClass:
6087 case Stmt::MSAsmStmtClass:
6088 case Stmt::GotoStmtClass:
6089 return this->emitInvalid(S);
6090 case Stmt::LabelStmtClass:
6093 if (
const auto *E = dyn_cast<Expr>(S))
6100template <
class Emitter>
6103 for (
const auto *InnerStmt : S->
body())
6106 return Scope.destroyLocals();
6109template <
class Emitter>
6110bool Compiler<Emitter>::maybeEmitDeferredVarInit(
const VarDecl *VD) {
6111 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
6112 for (
auto *BD : DD->flat_bindings())
6113 if (
auto *KD = BD->getHoldingVar();
6114 KD && !this->visitVarDecl(KD, KD->getInit()))
6128template <
class Emitter>
bool Compiler<Emitter>::refersToUnion(
const Expr *E) {
6130 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
6131 if (
const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6138 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6143 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E);
6144 ICE && (ICE->getCastKind() == CK_NoOp ||
6145 ICE->getCastKind() == CK_DerivedToBase ||
6146 ICE->getCastKind() == CK_UncheckedDerivedToBase)) {
6147 E = ICE->getSubExpr();
6151 if (
const auto *
This = dyn_cast<CXXThisExpr>(E)) {
6152 const auto *ThisRecord =
6153 This->getType()->getPointeeType()->getAsRecordDecl();
6154 if (!ThisRecord->isUnion())
6157 if (
const auto *Ctor =
6158 dyn_cast_if_present<CXXConstructorDecl>(CompilingFunction))
6159 return Ctor->getParent() == ThisRecord;
6168template <
class Emitter>
6170 bool EvaluateConditionDecl) {
6171 for (
const auto *D : DS->
decls()) {
6176 const auto *VD = dyn_cast<VarDecl>(D);
6183 if (EvaluateConditionDecl && !this->maybeEmitDeferredVarInit(VD))
6190template <
class Emitter>
6193 return this->emitUnsupported(RS);
6199 if (!this->
visit(RE))
6205 if (RE->getType()->isVoidType()) {
6206 if (!this->
visit(RE))
6209 if (RE->containsErrors())
6214 if (!this->emitRVOPtr(RE))
6220 return this->emitRetVoid(RS);
6226 return this->emitRetVoid(RS);
6232 auto visitChildStmt = [&](
const Stmt *S) ->
bool {
6239 if (
auto *CondInit = IS->
getInit()) {
6255 return visitChildStmt(IS->
getThen());
6257 return visitChildStmt(Else);
6263 if (!this->emitIsConstantContext(IS))
6266 if (!this->emitIsConstantContext(IS))
6268 if (!this->emitInv(IS))
6282 LabelTy LabelElse = this->getLabel();
6283 LabelTy LabelEnd = this->getLabel();
6284 if (!this->jumpFalse(LabelElse, IS))
6286 if (!visitChildStmt(IS->
getThen()))
6288 if (!this->jump(LabelEnd, IS))
6290 this->emitLabel(LabelElse);
6291 if (!visitChildStmt(Else))
6293 this->emitLabel(LabelEnd);
6295 LabelTy LabelEnd = this->getLabel();
6296 if (!this->jumpFalse(LabelEnd, IS))
6298 if (!visitChildStmt(IS->
getThen()))
6300 this->emitLabel(LabelEnd);
6309template <
class Emitter>
6314 LabelTy CondLabel = this->getLabel();
6315 LabelTy EndLabel = this->getLabel();
6319 this->fallthrough(CondLabel);
6320 this->emitLabel(CondLabel);
6336 if (!this->jumpFalse(EndLabel, S))
6346 if (!this->jump(CondLabel, S))
6348 this->fallthrough(EndLabel);
6349 this->emitLabel(EndLabel);
6358 LabelTy StartLabel = this->getLabel();
6359 LabelTy EndLabel = this->getLabel();
6360 LabelTy CondLabel = this->getLabel();
6364 this->fallthrough(StartLabel);
6365 this->emitLabel(StartLabel);
6371 this->fallthrough(CondLabel);
6372 this->emitLabel(CondLabel);
6379 if (!this->jumpTrue(StartLabel, S))
6382 this->fallthrough(EndLabel);
6383 this->emitLabel(EndLabel);
6387template <
class Emitter>
6395 LabelTy EndLabel = this->getLabel();
6396 LabelTy CondLabel = this->getLabel();
6397 LabelTy IncLabel = this->getLabel();
6404 this->fallthrough(CondLabel);
6405 this->emitLabel(CondLabel);
6417 if (!this->jumpFalse(EndLabel, S))
6426 this->fallthrough(IncLabel);
6427 this->emitLabel(IncLabel);
6433 if (!this->jump(CondLabel, S))
6437 this->emitLabel(EndLabel);
6443template <
class Emitter>
6453 LabelTy EndLabel = this->getLabel();
6454 LabelTy CondLabel = this->getLabel();
6455 LabelTy IncLabel = this->getLabel();
6470 this->fallthrough(CondLabel);
6471 this->emitLabel(CondLabel);
6474 if (!this->jumpFalse(EndLabel, S))
6485 this->fallthrough(IncLabel);
6486 this->emitLabel(IncLabel);
6491 if (!this->jump(CondLabel, S))
6494 this->fallthrough(EndLabel);
6495 this->emitLabel(EndLabel);
6499template <
class Emitter>
6510 if (LI.BreakLabel) {
6511 TargetLabel = *LI.BreakLabel;
6512 BreakScope = LI.BreakOrContinueScope;
6518 if (LI.Name == TargetLoop) {
6519 TargetLabel = *LI.BreakLabel;
6520 BreakScope = LI.BreakOrContinueScope;
6531 C =
C->getParent()) {
6532 if (!
C->destroyLocals())
6536 return this->jump(*TargetLabel, S);
6539template <
class Emitter>
6550 if (LI.ContinueLabel) {
6551 TargetLabel = *LI.ContinueLabel;
6552 ContinueScope = LI.BreakOrContinueScope;
6558 if (LI.Name == TargetLoop) {
6559 TargetLabel = *LI.ContinueLabel;
6560 ContinueScope = LI.BreakOrContinueScope;
6565 assert(TargetLabel);
6568 C =
C->getParent()) {
6569 if (!
C->destroyLocals())
6573 return this->jump(*TargetLabel, S);
6576template <
class Emitter>
6579 if (
Cond->containsErrors())
6585 LabelTy EndLabel = this->getLabel();
6590 if (
const auto *CondInit = S->
getInit())
6601 if (!this->emitSetLocal(CondT, CondVar, S))
6611 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
6614 if (CS->caseStmtIsGNURange()) {
6615 LabelTy EndOfRangeCheck = this->getLabel();
6616 const Expr *Low = CS->getLHS();
6617 const Expr *High = CS->getRHS();
6621 if (!this->emitGetLocal(CondT, CondVar, CS))
6623 if (!this->
visit(Low))
6626 if (!this->emitGE(
LT, S))
6628 if (!this->jumpFalse(EndOfRangeCheck, S))
6631 if (!this->emitGetLocal(CondT, CondVar, CS))
6633 if (!this->
visit(High))
6636 if (!this->emitLE(HT, S))
6640 this->emitLabel(EndOfRangeCheck);
6645 if (
Value->isValueDependent())
6650 if (!this->emitGetLocal(CondT, CondVar, CS))
6656 if (!this->emitEQ(ValueT, S))
6661 assert(!DefaultLabel);
6662 DefaultLabel = this->getLabel();
6669 if (!this->jump(*DefaultLabel, S))
6672 if (!this->jump(EndLabel, S))
6680 this->fallthrough(EndLabel);
6681 this->emitLabel(EndLabel);
6686template <
class Emitter>
6693template <
class Emitter>
6700 if (LI.DefaultLabel) {
6701 DefaultLabel = *LI.DefaultLabel;
6706 this->emitLabel(DefaultLabel);
6710template <
class Emitter>
6717 if (IsMSVCConstexprAttr && !this->emitPushMSVCCE(S))
6720 if (this->
Ctx.getLangOpts().CXXAssumptions &&
6721 !this->Ctx.getLangOpts().MSVCCompat) {
6723 auto *AA = dyn_cast<CXXAssumeAttr>(A);
6729 const Expr *Assumption = AA->getAssumption();
6740 if (!this->emitAssume(Assumption))
6749 if (IsMSVCConstexprAttr)
6750 return this->emitPopMSVCCE(S);
6754template <
class Emitter>
6760template <
class Emitter>
6761bool Compiler<Emitter>::emitLambdaStaticInvokerBody(
const CXXMethodDecl *MD) {
6768 assert(ClosureClass->
captures().empty());
6772 "A generic lambda's static-invoker function must be a "
6773 "template specialization");
6777 void *InsertPos =
nullptr;
6778 const FunctionDecl *CorrespondingCallOpSpecialization =
6780 assert(CorrespondingCallOpSpecialization);
6781 LambdaCallOp = CorrespondingCallOpSpecialization;
6785 assert(ClosureClass->
captures().empty());
6786 const Function *
Func = this->getFunction(LambdaCallOp);
6789 assert(
Func->hasThisPointer());
6792 if (
Func->hasRVO()) {
6793 if (!this->emitRVOPtr(MD))
6801 if (!this->emitNullPtr(0,
nullptr, MD))
6806 auto It = this->Params.find(PVD);
6807 assert(It != this->Params.end());
6811 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
6812 if (!this->emitGetParam(ParamType, It->second.Index, MD))
6816 if (!this->emitCall(
Func, 0, LambdaCallOp))
6821 return this->emitRet(*ReturnType, MD);
6824 return this->emitRetVoid(MD);
6827template <
class Emitter>
6828bool Compiler<Emitter>::checkLiteralType(
const Expr *E) {
6829 if (Ctx.getLangOpts().CPlusPlus23)
6839 const Expr *InitExpr =
Init->getInit();
6841 if (!
Init->isWritten() && !
Init->isInClassMemberInitializer() &&
6845 if (
const auto *CE = dyn_cast<CXXConstructExpr>(InitExpr)) {
6855template <
class Emitter>
6857 assert(!ReturnType);
6860 if (!this->emitStartThisLifetime1(Ctor))
6863 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
6864 const Expr *InitExpr,
6867 if (InitExpr->getType().isNull())
6871 if (
Activate && !this->emitActivateThisField(FieldOffset, InitExpr))
6874 if (!this->visit(InitExpr))
6877 if (F->isBitField())
6878 return this->emitInitThisBitField(*T, FieldOffset, F->bitWidth(),
6880 return this->emitInitThisField(*T, FieldOffset, InitExpr);
6885 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
6888 if (
Activate && !this->emitActivate(InitExpr))
6891 return this->visitInitializerPop(InitExpr);
6895 const Record *
R = this->getRecord(RD);
6898 bool IsUnion =
R->isUnion();
6908 if (!this->emitThis(Ctor))
6911 if (!this->emitGetParam(
PT_Ptr, 0, Ctor))
6914 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
6915 this->emitRetVoid(Ctor);
6918 unsigned FieldInits = 0;
6920 for (
const auto *
Init : Ctor->
inits()) {
6924 const Expr *InitExpr =
Init->getInit();
6926 const Record::Field *F =
R->getField(
Member);
6930 if (!emitFieldInitializer(F, F->Offset, InitExpr, IsUnion))
6934 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
6937 if (
Init->isBaseVirtual()) {
6938 assert(
R->getVirtualBase(BaseDecl));
6939 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
6945 const Record::Base *B =
R->getBase(BaseDecl);
6947 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
6951 if (IsUnion && !this->emitActivate(InitExpr))
6954 if (!this->visitInitializerPop(InitExpr))
6959 unsigned ChainSize = IFD->getChainingSize();
6960 assert(ChainSize >= 2);
6962 unsigned NestedFieldOffset = 0;
6963 const Record::Field *NestedField =
nullptr;
6964 for (
unsigned I = 0; I != ChainSize; ++I) {
6966 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
6967 assert(FieldRecord);
6969 NestedField = FieldRecord->
getField(FD);
6970 assert(NestedField);
6971 IsUnion = IsUnion || FieldRecord->
isUnion();
6973 NestedFieldOffset += NestedField->Offset;
6976 if (I != ChainSize - 1)
6979 assert(NestedField);
6982 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
6987 unsigned InitFieldOffset = 0;
6988 for (
const NamedDecl *ND : IFD->chain().drop_back()) {
6990 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
6991 assert(FieldRecord);
6992 NestedField = FieldRecord->
getField(FD);
6993 InitFieldOffset += NestedField->Offset;
6994 assert(NestedField);
6995 if (!this->emitGetPtrThisField(InitFieldOffset, InitExpr))
6997 if (!this->emitFinishInitPop(InitExpr))
7001 InitStack.pop_back_n(ChainSize - 1);
7004 assert(
Init->isDelegatingInitializer());
7005 if (!this->emitThis(InitExpr))
7007 if (!this->visitInitializerPop(
Init->getInit()))
7011 if (!
Scope.destroyLocals())
7015 if (FieldInits !=
R->getNumFields()) {
7016 assert(FieldInits < R->getNumFields());
7018 if (!this->emitStartThisLifetime(Ctor))
7025 if (
const auto *CS = dyn_cast<CompoundStmt>(Body)) {
7026 if (!CS->body_empty() && !this->emitCtorCheck(
SourceInfo{}))
7033 if (!visitStmt(Body))
7040template <
class Emitter>
7043 const Record *
R = this->getRecord(RD);
7048 if (!this->visitStmt(Dtor->
getBody()))
7052 if (!this->emitThis(Dtor))
7055 if (!this->emitCheckDestruction(Dtor))
7059 if (!
R->isUnion()) {
7063 for (
const Record::Field &Field : llvm::reverse(
R->fields())) {
7067 if (!this->emitGetPtrField(Field.Offset,
SourceInfo{}))
7069 if (!this->emitDestructionPop(D,
SourceInfo{}))
7074 for (
const Record::Base &
Base : llvm::reverse(
R->bases())) {
7075 if (
Base.R->hasTrivialDtor())
7079 if (!this->emitRecordDestructionPop(
Base.R, {}))
7083 if (!this->emitMarkDestroyed(Dtor))
7087 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
7090template <
class Emitter>
7091bool Compiler<Emitter>::compileUnionAssignmentOperator(
7093 if (!this->emitThis(MD))
7096 if (!this->emitGetParam(
PT_Ptr, 0, MD))
7099 return this->emitMemcpy(MD) && this->emitRet(
PT_Ptr, MD);
7102template <
class Emitter>
7112 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
7113 return this->compileConstructor(Ctor);
7114 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
7115 return this->compileDestructor(Dtor);
7118 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
7123 return this->compileUnionAssignmentOperator(MD);
7126 return this->emitLambdaStaticInvokerBody(MD);
7130 if (
const auto *Body = F->
getBody())
7144 return FD->getBitWidthValue();
7147template <
class Emitter>
7160 if (!
Ctx.getLangOpts().CPlusPlus14)
7161 return this->emitInvalid(E);
7163 return this->emitError(E);
7165 if (!this->
visit(SubExpr))
7169 if (!this->emitIncPtr(E))
7176 return DiscardResult ? this->emitIncfPop(getFPOptions(E), E)
7177 : this->emitIncf(getFPOptions(E), E);
7189 if (!
Ctx.getLangOpts().CPlusPlus14)
7190 return this->emitInvalid(E);
7192 return this->emitError(E);
7194 if (!this->
visit(SubExpr))
7198 if (!this->emitDecPtr(E))
7205 return DiscardResult ? this->emitDecfPop(getFPOptions(E), E)
7206 : this->emitDecf(getFPOptions(E), E);
7219 if (!
Ctx.getLangOpts().CPlusPlus14)
7220 return this->emitInvalid(E);
7222 return this->emitError(E);
7224 if (!this->
visit(SubExpr))
7228 if (!this->emitLoadPtr(E))
7230 if (!this->emitConstUint8(1, E))
7232 if (!this->emitAddOffsetUint8(E))
7234 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7240 return this->emitIncfPop(getFPOptions(E), E);
7250 const auto &TargetSemantics =
Ctx.getFloatSemantics(E->
getType());
7251 if (!this->emitLoadFloat(E))
7253 APFloat F(TargetSemantics, 1);
7254 if (!this->emitFloat(F, E))
7257 if (!this->emitAddf(getFPOptions(E), E))
7259 if (!this->emitStoreFloat(E))
7271 return E->
isGLValue() || this->emitLoadPop(*T, E);
7274 if (!
Ctx.getLangOpts().CPlusPlus14)
7275 return this->emitInvalid(E);
7277 return this->emitError(E);
7279 if (!this->
visit(SubExpr))
7283 if (!this->emitLoadPtr(E))
7285 if (!this->emitConstUint8(1, E))
7287 if (!this->emitSubOffsetUint8(E))
7289 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7295 return this->emitDecfPop(getFPOptions(E), E);
7305 const auto &TargetSemantics =
Ctx.getFloatSemantics(E->
getType());
7306 if (!this->emitLoadFloat(E))
7308 APFloat F(TargetSemantics, 1);
7309 if (!this->emitFloat(F, E))
7312 if (!this->emitSubf(getFPOptions(E), E))
7314 if (!this->emitStoreFloat(E))
7326 return E->
isGLValue() || this->emitLoadPop(*T, E);
7330 return this->emitError(E);
7333 return this->
discard(SubExpr);
7338 if (!this->emitInv(E))
7342 return this->emitCast(
PT_Bool, ET, E);
7346 return this->emitError(E);
7348 if (!this->
visit(SubExpr))
7350 return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
7353 return this->emitError(E);
7355 if (!this->
visit(SubExpr))
7370 return this->
discard(SubExpr);
7372 if (!this->
visit(SubExpr))
7379 return this->emitNarrowPtr(E);
7384 return this->emitError(E);
7386 if (!this->
visit(SubExpr))
7388 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
7400 : this->visitZeroInitializer(*T, SubExpr->
getType(), SubExpr);
7405 assert(
false &&
"Unhandled opcode");
7411template <
class Emitter>
7417 return this->
discard(SubExpr);
7420 auto prepareResult = [=]() ->
bool {
7425 return this->emitGetPtrLocal(*LocalIndex, E);
7432 unsigned SubExprOffset = ~0u;
7433 auto createTemp = [=, &SubExprOffset]() ->
bool {
7436 if (!this->
visit(SubExpr))
7438 return this->emitSetLocal(
PT_Ptr, SubExprOffset, E);
7442 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
7443 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
7445 return this->emitArrayElemPop(ElemT, Index, E);
7450 if (!prepareResult())
7454 for (
unsigned I = 0; I != 2; ++I) {
7455 if (!getElem(SubExprOffset, I))
7457 if (!this->emitNeg(ElemT, E))
7459 if (!this->emitInitElem(ElemT, I, E))
7470 if (!this->
visit(SubExpr))
7472 if (!this->emitComplexBoolCast(SubExpr))
7474 if (!this->emitInv(E))
7477 return this->emitCast(
PT_Bool, ET, E);
7481 return this->emitComplexReal(SubExpr);
7484 if (!this->
visit(SubExpr))
7488 if (!this->emitConstUint8(1, E))
7490 return this->emitArrayElemPtrPopUint8(E);
7501 if (!this->emitArrayElem(ElemT, 1, E))
7503 if (!this->emitNeg(ElemT, E))
7505 if (!this->emitInitElem(ElemT, 1, E))
7513 return this->emitInvalid(E);
7519template <
class Emitter>
7525 return this->
discard(SubExpr);
7528 if (UnaryOp == UO_Extension)
7531 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
7532 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
7533 return this->emitInvalid(E);
7536 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
7543 if (!this->emitGetPtrLocal(*LocalIndex, E))
7548 unsigned SubExprOffset =
7550 if (!this->
visit(SubExpr))
7552 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, E))
7557 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
7558 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
7560 return this->emitArrayElemPop(ElemT, Index, E);
7565 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
7566 if (!getElem(SubExprOffset, I))
7568 if (!this->emitNeg(ElemT, E))
7570 if (!this->emitInitElem(ElemT, I, E))
7585 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
7586 if (!getElem(SubExprOffset, I))
7589 if (!this->emitPrimCast(ElemT,
PT_Bool,
Ctx.getASTContext().BoolTy, E))
7591 if (!this->emitInv(E))
7593 if (!this->emitPrimCast(
PT_Bool, ElemT, VecTy->getElementType(), E))
7595 if (!this->emitNeg(ElemT, E))
7597 if (ElemT != ResultVecElemT &&
7598 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy, E))
7600 if (!this->emitInitElem(ResultVecElemT, I, E))
7606 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
7607 if (!getElem(SubExprOffset, I))
7610 if (!this->emitInv(E))
7613 if (!this->emitComp(ElemT, E))
7616 if (!this->emitInitElem(ElemT, I, E))
7621 llvm_unreachable(
"Unsupported unary operators should be handled up front");
7626template <
class Emitter>
7631 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(D))
7632 return this->emitConst(ECD->getInitVal(), E);
7633 if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
7635 return F && this->emitGetFnPtr(F, E);
7637 if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
7642 return this->emitInitGlobal(*T, *Index, E);
7645 if (!this->emitGetPtrGlobal(*Index, E))
7649 return this->emitFinishInit(E);
7664 if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
7665 if (
Ctx.getLangOpts().CPlusPlus && !
Ctx.getLangOpts().CPlusPlus11 &&
7670 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
7671 if (IsReference || !It->second.IsPtr)
7672 return this->emitGetParam(
classifyPrim(E), It->second.Index, E);
7674 return this->emitGetPtrParam(It->second.Index, E);
7677 if (!
Ctx.getLangOpts().CPlusPlus23 && IsReference)
7683 const unsigned Offset = It->second.Offset;
7686 return this->emitGetRefLocal(Offset, E);
7688 return this->emitGetPtrLocal(Offset, E);
7691 if (
auto GlobalIndex =
P.getGlobal(D)) {
7693 if (!
Ctx.getLangOpts().CPlusPlus11)
7694 return this->emitGetGlobal(
classifyPrim(E), *GlobalIndex, E);
7695 if (!
Ctx.getLangOpts().CPlusPlus23)
7696 return this->emitGetGlobalUnchecked(
classifyPrim(E), *GlobalIndex, E);
7697 return this->emitGetRefGlobal(*GlobalIndex, E);
7700 return this->emitGetPtrGlobal(*GlobalIndex, E);
7704 auto revisit = [&](
const VarDecl *VD,
7705 bool IsConstexprUnknown =
true) ->
bool {
7707 IsConstexprUnknown);
7712 if (!this->emitPopCC(E))
7715 if (VarState.notCreated())
7723 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
7725 if (
auto It = this->LambdaCaptures.find(D);
7726 It != this->LambdaCaptures.end()) {
7727 auto [Offset, IsPtr] = It->second;
7730 return this->emitGetThisFieldPtr(Offset, E);
7731 return this->emitGetPtrThisField(Offset, E);
7735 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E);
7736 DRE && DRE->refersToEnclosingVariableOrCapture()) {
7737 if (
const auto *VD = dyn_cast<VarDecl>(D); VD && VD->
isInitCapture())
7741 if (
const auto *BD = dyn_cast<BindingDecl>(D))
7742 return this->
visit(BD->getBinding());
7746 return this->emitDummyPtr(D, E);
7750 const auto *VD = dyn_cast<VarDecl>(D);
7752 return this->emitError(E);
7755 if (!
Ctx.getLangOpts().CPlusPlus) {
7759 return revisit(VD,
false);
7760 return this->emitDummyPtr(D, E);
7764 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
7765 if (T.isConstant(
Ctx.getASTContext()))
7767 return T->isReferenceType();
7771 typeShouldBeVisited(DeclType)) {
7773 Init && !
Init->isValueDependent()) {
7779 (void)
Init->EvaluateAsInitializer(
V,
Ctx.getASTContext(), VD, Notes,
7793 bool IsConstexprUnknown = !DeclType.
isConstant(
Ctx.getASTContext()) &&
7798 return revisit(VD, IsConstexprUnknown);
7799 }
else if (
Ctx.getLangOpts().CPlusPlus23 && IsReference)
7800 return revisit(VD,
true);
7807 return this->emitDummyPtr(
7811template <
class Emitter>
7817template <
class Emitter>
7828 if (!
C->destroyLocals())
7834template <
class Emitter>
7835unsigned Compiler<Emitter>::collectBaseOffset(
const QualType BaseType,
7838 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
7840 return Ty->getAsCXXRecordDecl();
7842 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
7843 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
7845 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
7849template <
class Emitter>
7856 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
7861 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
7862 getFPOptions(E), E);
7864 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
7865 getFPOptions(E), E);
7869 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
7874 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
7876 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
7880 return FromT != ToT ? this->emitCast(FromT, ToT, E) :
true;
7884 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
7885 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E);
7892template <
class Emitter>
7895 assert(FromT != ToT);
7898 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
7900 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
7902 return this->emitCast(FromT, ToT, E);
7906template <
class Emitter>
7907bool Compiler<Emitter>::emitComplexReal(
const Expr *SubExpr) {
7911 return this->
discard(SubExpr);
7913 if (!this->visit(SubExpr))
7916 if (!this->emitConstUint8(0, SubExpr))
7918 return this->emitArrayElemPtrPopUint8(SubExpr);
7922 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
7926template <
class Emitter>
7927bool Compiler<Emitter>::emitComplexBoolCast(
const Expr *E) {
7928 assert(!DiscardResult);
7932 if (!this->emitArrayElem(ElemT, 0, E))
7935 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(E), E))
7938 if (!this->emitCast(ElemT,
PT_Bool, E))
7943 LabelTy LabelTrue = this->getLabel();
7944 if (!this->jumpTrue(LabelTrue, E))
7947 if (!this->emitArrayElemPop(ElemT, 1, E))
7950 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(E), E))
7953 if (!this->emitCast(ElemT,
PT_Bool, E))
7957 LabelTy EndLabel = this->getLabel();
7958 this->jump(EndLabel, E);
7960 this->emitLabel(LabelTrue);
7961 if (!this->emitPopPtr(E))
7963 if (!this->emitConstBool(
true, E))
7966 this->fallthrough(EndLabel);
7967 this->emitLabel(EndLabel);
7972template <
class Emitter>
7973bool Compiler<Emitter>::emitComplexComparison(
const Expr *LHS,
const Expr *RHS,
7984 LHSIsComplex =
true;
7985 ElemT = classifyComplexElementType(LHS->
getType());
7986 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true);
7987 if (!this->visit(LHS))
7989 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
7992 LHSIsComplex =
false;
7994 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true);
7995 if (!this->visit(LHS))
7997 if (!this->emitSetLocal(LHST, LHSOffset, E))
8004 RHSIsComplex =
true;
8005 ElemT = classifyComplexElementType(RHS->
getType());
8006 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true);
8007 if (!this->visit(RHS))
8009 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
8012 RHSIsComplex =
false;
8014 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true);
8015 if (!this->visit(RHS))
8017 if (!this->emitSetLocal(RHST, RHSOffset, E))
8021 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
8022 bool IsComplex) ->
bool {
8024 if (!this->emitGetLocal(
PT_Ptr, LocalOffset, E))
8026 return this->emitArrayElemPop(ElemT, Index, E);
8028 return this->emitGetLocal(ElemT, LocalOffset, E);
8031 for (
unsigned I = 0; I != 2; ++I) {
8033 if (!getElem(LHSOffset, I, LHSIsComplex))
8035 if (!getElem(RHSOffset, I, RHSIsComplex))
8038 if (!this->emitEQ(ElemT, E))
8041 if (!this->emitCastBoolUint8(E))
8046 if (!this->emitAddUint8(E))
8048 if (!this->emitConstUint8(2, E))
8052 if (!this->emitEQUint8(E))
8055 if (!this->emitNEUint8(E))
8062 return this->emitCast(
PT_Bool, ResT, E);
8069template <
class Emitter>
8070bool Compiler<Emitter>::emitRecordDestructionPop(
const Record *R,
8073 assert(!
R->hasTrivialDtor());
8076 const Function *DtorFunc = getFunction(Dtor);
8079 assert(DtorFunc->hasThisPointer());
8080 assert(DtorFunc->getNumParams() == 1);
8081 return this->emitCall(DtorFunc, 0, Loc);
8086template <
class Emitter>
8087bool Compiler<Emitter>::emitDestructionPop(
const Descriptor *Desc,
8099 return this->emitPopPtr(Loc);
8101 for (ssize_t I = N - 1; I >= 1; --I) {
8102 if (!this->emitConstUint64(I, Loc))
8104 if (!this->emitArrayElemPtrUint64(Loc))
8106 if (!this->emitDestructionPop(ElemDesc, Loc))
8110 if (!this->emitConstUint64(0, Loc))
8112 if (!this->emitArrayElemPtrPopUint64(Loc))
8114 return this->emitDestructionPop(ElemDesc, Loc);
8119 return this->emitRecordDestructionPop(Desc->
ElemRecord, Loc);
8124template <
class Emitter>
8125bool Compiler<Emitter>::emitDummyPtr(
const DeclTy &D,
const Expr *E,
bool CU) {
8126 assert(!DiscardResult &&
"Should've been checked before");
8127 unsigned DummyID = P.getOrCreateDummy(D, CU);
8129 if (!this->emitGetPtrGlobal(DummyID, E))
8137 return this->emitDecayPtr(
PT_Ptr, PT, E);
8143template <
class Emitter>
8144bool Compiler<Emitter>::emitFloat(
const APFloat &F,
const Expr *E) {
8146 return this->emitConstFloat(
Floating(F), E);
8148 APInt I = F.bitcastToAPInt();
8149 return this->emitConstFloat(
8150 Floating(
const_cast<uint64_t *
>(I.getRawData()),
8151 llvm::APFloatBase::SemanticsToEnum(F.getSemantics())),
8162template <
class Emitter>
8163bool Compiler<Emitter>::emitBuiltinBitCast(
const CastExpr *E) {
8176 if (!this->emitGetPtrLocal(*LocalIndex, E))
8186 if (!this->visit(SubExpr))
8188 }
else if (
OptPrimType FromT = classify(SubExpr)) {
8189 unsigned TempOffset =
8190 allocateLocalPrimitive(SubExpr, *FromT,
true);
8191 if (!this->visit(SubExpr))
8193 if (!this->emitSetLocal(*FromT, TempOffset, E))
8195 if (!this->emitGetPtrLocal(TempOffset, E))
8202 if (!this->emitBitCast(E))
8204 return DiscardResult ? this->emitPopPtr(E) :
true;
8208 const llvm::fltSemantics *TargetSemantics =
nullptr;
8210 TargetSemantics = &Ctx.getFloatSemantics(ToType);
8216 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
8218 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->
isStdByteType(),
8219 ResultBitWidth, TargetSemantics,
8224 return this->emitPop(*ToT, E);
8233template <
class Emitter>
8234bool Compiler<Emitter>::emitHLSLAggregateSplat(
PrimType SrcT,
8239 unsigned NumElems = 0;
8242 NumElems = VT->getNumElements();
8243 ElemType = VT->getElementType();
8245 NumElems = MT->getNumElementsFlattened();
8246 ElemType = MT->getElementType();
8249 PrimType ElemT = classifyPrim(ElemType);
8250 for (
unsigned I = 0; I != NumElems; ++I) {
8251 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8253 if (!this->emitPrimCast(SrcT, ElemT, ElemType, E))
8255 if (!this->emitInitElem(ElemT, I, E))
8265 QualType ArrElemType = CAT->getElementType();
8266 unsigned ArrSize = CAT->getZExtSize();
8269 for (
unsigned I = 0; I != ArrSize; ++I) {
8270 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8272 if (!this->emitPrimCast(SrcT, *ElemT, ArrElemType, E))
8274 if (!this->emitInitElem(*ElemT, I, E))
8278 for (
unsigned I = 0; I != ArrSize; ++I) {
8279 if (!this->emitConstUint32(I, E))
8281 if (!this->emitArrayElemPtrUint32(E))
8283 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, ArrElemType, E))
8285 if (!this->emitFinishInitPop(E))
8295 const Record *
R = getRecord(DestType);
8299 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
8301 const Record::Base *B =
R->getBase(BS.getType());
8303 if (!this->emitGetPtrBase(B->Offset, E))
8305 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, BS.getType(), E))
8307 if (!this->emitFinishInitPop(E))
8312 for (
const Record::Field &F :
R->fields()) {
8313 if (F.isUnnamedBitField())
8316 QualType FieldType = F.Decl->getType();
8318 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8320 if (!this->emitPrimCast(SrcT, *FieldT, FieldType, E))
8322 if (F.isBitField()) {
8323 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
8326 if (!this->emitInitField(*FieldT, F.Offset, E))
8330 if (!this->emitGetPtrField(F.Offset, E))
8332 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, FieldType, E))
8334 if (!this->emitPopPtr(E))
8347template <
class Emitter>
8348unsigned Compiler<Emitter>::countHLSLFlatElements(
QualType Ty) {
8351 return VT->getNumElements();
8353 return MT->getNumElementsFlattened();
8357 return CAT->getZExtSize() * countHLSLFlatElements(CAT->getElementType());
8361 const Record *
R = getRecord(Ty);
8365 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
8367 Count += countHLSLFlatElements(BS.getType());
8369 for (
const Record::Field &F :
R->fields()) {
8370 if (F.isUnnamedBitField())
8372 Count += countHLSLFlatElements(F.Decl->getType());
8377 if (canClassify(Ty))
8386template <
class Emitter>
8387bool Compiler<Emitter>::emitHLSLFlattenAggregate(
8388 QualType SrcType,
unsigned SrcOffset,
8393 auto saveToLocal = [&](
PrimType T) ->
bool {
8394 unsigned Offset = allocateLocalPrimitive(E, T,
true);
8395 if (!this->emitSetLocal(T, Offset, E))
8397 Elements.push_back({Offset, T});
8403 unsigned Offset = allocateLocalPrimitive(E,
PT_Ptr,
true);
8404 if (!this->emitSetLocal(
PT_Ptr, Offset, E))
8405 return std::nullopt;
8410 unsigned NumElems = 0;
8413 NumElems = VT->getNumElements();
8414 ElemType = VT->getElementType();
8416 NumElems = MT->getNumElementsFlattened();
8417 ElemType = MT->getElementType();
8420 PrimType ElemT = classifyPrim(ElemType);
8421 for (
unsigned I = 0; I != NumElems && Elements.size() < MaxElements; ++I) {
8422 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
8424 if (!this->emitArrayElemPop(ElemT, I, E))
8426 if (!saveToLocal(ElemT))
8436 QualType ArrElemType = CAT->getElementType();
8437 unsigned ArrSize = CAT->getZExtSize();
8440 for (
unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
8441 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
8443 if (!this->emitArrayElemPop(*ElemT, I, E))
8445 if (!saveToLocal(*ElemT))
8449 for (
unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
8450 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
8452 if (!this->emitConstUint32(I, E))
8454 if (!this->emitArrayElemPtrPopUint32(E))
8459 if (!emitHLSLFlattenAggregate(ArrElemType, *ElemPtrOffset, Elements,
8470 const Record *
R = getRecord(SrcType);
8474 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
8476 if (Elements.size() >= MaxElements)
8478 const Record::Base *B =
R->getBase(BS.getType());
8480 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
8482 if (!this->emitGetPtrBasePop(B->Offset,
false, E))
8487 if (!emitHLSLFlattenAggregate(BS.getType(), *BasePtrOffset, Elements,
8493 for (
const Record::Field &F :
R->fields()) {
8494 if (Elements.size() >= MaxElements)
8496 if (F.isUnnamedBitField())
8499 QualType FieldType = F.Decl->getType();
8500 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
8502 if (!this->emitGetPtrFieldPop(F.Offset, E))
8506 if (!this->emitLoadPop(*FieldT, E))
8508 if (!saveToLocal(*FieldT))
8512 if (!FieldPtrOffset)
8514 if (!emitHLSLFlattenAggregate(FieldType, *FieldPtrOffset, Elements,
8530template <
class Emitter>
8531bool Compiler<Emitter>::emitHLSLConstructAggregate(
8537 const auto &Src = Elements[ElemIdx++];
8538 if (!this->emitGetLocal(Src.Type, Src.LocalOffset, E))
8540 return this->emitPrimCast(Src.Type, DestT, DestQT, E);
8544 unsigned NumElems = 0;
8547 NumElems = VT->getNumElements();
8548 ElemType = VT->getElementType();
8550 NumElems = MT->getNumElementsFlattened();
8551 ElemType = MT->getElementType();
8554 PrimType DestElemT = classifyPrim(ElemType);
8555 for (
unsigned I = 0; I != NumElems; ++I) {
8556 if (!loadAndCast(DestElemT, ElemType))
8558 if (!this->emitInitElem(DestElemT, I, E))
8568 QualType ArrElemType = CAT->getElementType();
8569 unsigned ArrSize = CAT->getZExtSize();
8572 for (
unsigned I = 0; I != ArrSize; ++I) {
8573 if (!loadAndCast(*ElemT, ArrElemType))
8575 if (!this->emitInitElem(*ElemT, I, E))
8579 for (
unsigned I = 0; I != ArrSize; ++I) {
8580 if (!this->emitConstUint32(I, E))
8582 if (!this->emitArrayElemPtrUint32(E))
8584 if (!emitHLSLConstructAggregate(ArrElemType, Elements, ElemIdx, E))
8586 if (!this->emitFinishInitPop(E))
8596 const Record *
R = getRecord(DestType);
8600 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
8602 const Record::Base *B =
R->getBase(BS.getType());
8604 if (!this->emitGetPtrBase(B->Offset, E))
8606 if (!emitHLSLConstructAggregate(BS.getType(), Elements, ElemIdx, E))
8608 if (!this->emitFinishInitPop(E))
8613 for (
const Record::Field &F :
R->fields()) {
8614 if (F.isUnnamedBitField())
8617 QualType FieldType = F.Decl->getType();
8619 if (!loadAndCast(*FieldT, FieldType))
8621 if (F.isBitField()) {
8622 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
8625 if (!this->emitInitField(*FieldT, F.Offset, E))
8629 if (!this->emitGetPtrField(F.Offset, E))
8631 if (!emitHLSLConstructAggregate(FieldType, Elements, ElemIdx, E))
8633 if (!this->emitPopPtr(E))
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static void emitCleanup(CIRGenFunction &cgf, cir::CleanupScopeOp cleanupScope, EHScopeStack::Cleanup *cleanup, EHScopeStack::Cleanup::Flags flags, Address activeFlag)
static uint32_t getBitWidth(const Expr *E)
#define EMIT_ARITH_OP(OP)
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
static const Expr * stripDerivedToBaseCasts(const Expr *E)
static const Expr * stripCheckedDerivedToBaseCasts(const Expr *E)
static bool hasTrivialDefaultCtorParent(const FieldDecl *FD)
static bool initNeedsOverridenLoc(const CXXCtorInitializer *Init)
Result
Implement __builtin_bit_cast and related operations.
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
bool isMemberPointerToDerivedMember() const
unsigned getArrayInitializedElts() const
unsigned getStructNumBases() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
APValue & getArrayFiller()
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
bool isMemberPointer() const
unsigned getArraySize() const
@ None
There is no such object (it's outside its lifetime).
bool isNullPointer() const
APValue & getStructBase(unsigned i)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
const LangOptions & getLangOpts() const
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
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...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
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.
llvm::APInt getArraySize() const
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
uint64_t getValue() const
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.
ArrayRef< const Attr * > getAttrs() const
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 isShiftOp(Opcode Opc)
static bool isCommaOp(Opcode Opc)
static Opcode getOpForCompoundAssignment(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
static bool isAssignmentOp(Opcode Opc)
static bool isCompoundAssignmentOp(Opcode Opc)
static bool isBitwiseOp(Opcode Opc)
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.
const Expr * getSubExpr() const
A boolean literal, per ([C++ lex.bool] Boolean literals).
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Expr * getArg(unsigned Arg)
Return the specified argument.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
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.
Expr * getExpr()
Get the initialization expression that will be used.
Represents a delete expression for memory deallocation and destructor calls, e.g.
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
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...
DeclStmt * getBeginStmt()
DeclStmt * getLoopVarStmt()
DeclStmt * getRangeStmt()
Represents a call to an inherited base class constructor from an inheriting constructor.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
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)".
QualType getAllocatedType() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Expr * getPlacementArg(unsigned I)
unsigned getNumPlacementArgs() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a list-initialization with parenthesis.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
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.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
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]).
const Expr * getSubExpr() const
CXXTryStmt - A C++ try block, including all handlers.
CompoundStmt * getTryBlock()
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
bool isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
MSGuidDecl * getGuidDecl() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Expr ** getArgs()
Retrieve the call arguments.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
const FieldDecl * getTargetUnionField() const
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
unsigned getValue() const
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
CompoundLiteralExpr - [C99 6.5.2.5].
const Expr * getInitializer() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Represents the specialization of a concept - evaluates to a prvalue of type bool.
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
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...
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
ContinueStmt - This represents a continue.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
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
InitListExpr * getUpdater() const
DoStmt - This represents a 'do/while' stmt.
const Expr * getBase() const
Represents a reference to emded data.
ChildElementIter< false > begin()
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 ...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
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.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
DeclStmt * getConditionVariableDeclStmt()
If this ForStmt has a condition variable, return the faux DeclStmt associated with the creation of th...
const Expr * getSubExpr() const
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.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
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.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
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.
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
Expr * getResultExpr()
Return the result expression of this controlling expression.
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....
const Expr * getSubExpr() const
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.
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
ArrayRef< Expr * > inits() const
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
const Stmt * getNamedLoopOrSwitch() const
If this is a named break/continue, get the loop or switch statement that this targets.
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.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
LifetimeExtendedTemporaryDecl * getLifetimeExtendedTemporaryDecl()
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
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.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
ObjCEncodeExpr, used for @encode in Objective-C.
QualType getEncodedType() const
SourceLocation getAtLoc() const
bool isExpressibleAsConstantInitializer() const
ObjCStringLiteral, used for Objective-C string literals i.e.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
unsigned getNumComponents() const
Helper class for OffsetOfExpr.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
@ Array
An index into an array.
Kind getKind() const
Determine what kind of offsetof node this is.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
ParenExpr - This represents a parenthesized expression, e.g.
const Expr * getSubExpr() const
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.
StringLiteral * getFunctionName()
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
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.
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...
bool isSatisfied() const
Whether or not the requires clause is satisfied.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
SourceLocation getLocation() const
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Represents an expression that computes the length of a parameter pack.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Represents a C++11 static_assert declaration.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
CompoundStmt * getSubStmt()
bool Visit(PTR(Stmt) S, ParamTys... P)
Stmt - This represents one statement.
StmtClass getStmtClass() const
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
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...
uint32_t getCodeUnit(size_t i) const
unsigned getCharByteWidth() const
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Expr * getReplacement() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
DeclStmt * getConditionVariableDeclStmt()
If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
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 isConstantMatrixType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
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
bool isSizelessVectorType() const
Returns true for all scalable vector types.
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
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 isConstexpr() const
Whether this variable is (C++11) constexpr.
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.
DeclStmt * getConditionVariableDeclStmt()
If this WhileStmt has a condition variable, return the faux DeclStmt associated with the creation of ...
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
A memory block, either on the stack or in the heap.
void invokeDtor()
Invokes the Destructor.
Compilation context for expressions.
llvm::SmallVector< InitLink > InitStack
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.
UnsignedOrNone allocateLocal(DeclTy &&Decl, QualType Ty=QualType(), ScopeKind=ScopeKind::Block)
Allocates a space storing a local given its type.
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E)
bool visitInitializerPop(const Expr *E)
Similar, but will also pop the pointer.
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
PrimType classifyPrim(QualType Ty) const
Classifies a known primitive type.
bool VisitTypeTraitExpr(const TypeTraitExpr *E)
bool VisitLambdaExpr(const LambdaExpr *E)
bool VisitMemberExpr(const MemberExpr *E)
llvm::DenseMap< const OpaqueValueExpr *, unsigned > OpaqueExprs
OpaqueValueExpr to location mapping.
bool VisitBinaryOperator(const BinaryOperator *E)
bool visitAttributedStmt(const AttributedStmt *S)
bool VisitPackIndexingExpr(const PackIndexingExpr *E)
bool visitAPValueInitializer(const APValue &Val, const Expr *E, QualType T)
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
bool VisitCallExpr(const CallExpr *E)
std::optional< uint64_t > ArrayIndex
Current argument index. Needed to emit ArrayInitIndexExpr.
bool VisitPseudoObjectExpr(const PseudoObjectExpr *E)
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E)
const Function * getFunction(const FunctionDecl *FD)
Returns a function for the given FunctionDecl.
bool VisitFixedPointBinOp(const BinaryOperator *E)
bool VisitCastExpr(const CastExpr *E)
bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E)
bool VisitFixedPointUnaryOperator(const UnaryOperator *E)
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsVolatile=false, ScopeKind SC=ScopeKind::Block)
Creates a local primitive value.
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)
Context & Ctx
Current compilation context.
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)
bool VisitStmtExpr(const StmtExpr *E)
bool VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *E)
bool VisitFixedPointLiteral(const FixedPointLiteral *E)
const FunctionDecl * CompilingFunction
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
VarCreationState visitVarDecl(const VarDecl *VD, const Expr *Init, bool Toplevel=false)
Creates and initializes a variable from the given decl.
VariableScope< Emitter > * VarScope
Current scope.
bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init, bool ConstantContext) override
Toplevel visitDeclAndReturn().
bool VisitCXXNewExpr(const CXXNewExpr *E)
const ValueDecl * InitializingDecl
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 visitLValueExpr(const Expr *E, bool DestroyToplevelScope) override
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 emitCleanup()
Emits scope cleanup instructions.
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E)
bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E)
bool visitInitializer(const Expr *E)
Compiles an initializer.
bool visitDtorCall(const VarDecl *VD, const APValue &Value) override
const Expr * SourceLocDefaultExpr
DefaultInit- or DefaultArgExpr, needed for SourceLocExpr.
bool VisitObjCArrayLiteral(const ObjCArrayLiteral *E)
UnsignedOrNone OptLabelTy
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)
bool VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
typename Emitter::LabelTy LabelTy
VarCreationState visitDecl(const VarDecl *VD)
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)
bool VisitDesignatedInitUpdateExpr(const DesignatedInitUpdateExpr *E)
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
bool VisitRecoveryExpr(const RecoveryExpr *E)
bool VisitRequiresExpr(const RequiresExpr *E)
bool Initializing
Flag inidicating if we're initializing an already created variable.
bool visitReturnStmt(const ReturnStmt *RS)
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitChooseExpr(const ChooseExpr *E)
bool visitFunc(const FunctionDecl *F) override
bool visitCXXForRangeStmt(const CXXForRangeStmt *S)
bool visitCaseStmt(const CaseStmt *S)
bool VisitComplexBinOp(const BinaryOperator *E)
llvm::DenseMap< const ValueDecl *, Scope::Local > Locals
Variable to storage mapping.
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
bool VisitCXXTypeidExpr(const CXXTypeidExpr *E)
UnsignedOrNone allocateTemporary(const Expr *E)
bool VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinID)
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
OptPrimType ReturnType
Type of the expression returned by the function.
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
OptPrimType classify(const Expr *E) const
llvm::SmallVector< LabelInfo > LabelInfoStack
Stack of label information for loops and switch statements.
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
bool visitDoStmt(const DoStmt *S)
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitInitListExpr(const InitListExpr *E)
bool VisitVectorBinOp(const BinaryOperator *E)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
bool DiscardResult
Flag indicating if return value is to be discarded.
bool VisitEmbedExpr(const EmbedExpr *E)
bool VisitConvertVectorExpr(const ConvertVectorExpr *E)
bool VisitCXXThisExpr(const CXXThisExpr *E)
bool VisitConstantExpr(const ConstantExpr *E)
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 canClassify(const Expr *E) const
bool VisitFloatingLiteral(const FloatingLiteral *E)
Program & P
Program to link to.
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
bool VariablesAreConstexprUnknown
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.
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.
LocalScope(Compiler< Emitter > *Ctx, ScopeKind Kind=ScopeKind::Block)
Sets the context for break/continue statements.
typename Compiler< Emitter >::LabelTy LabelTy
typename Compiler< Emitter >::OptLabelTy OptLabelTy
typename Compiler< Emitter >::LabelInfo LabelInfo
LoopScope(Compiler< Emitter > *Ctx, const Stmt *Name, LabelTy BreakLabel, LabelTy ContinueLabel)
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 Field * getField(unsigned I) const
const Base * getBase(unsigned I) const
bool hasTrivialDtor() const
Returns true for anonymous unions and records with no destructor or for those with a trivial destruct...
Describes the statement/declaration an opcode was generated from.
StmtExprScope(Compiler< Emitter > *Ctx)
typename Compiler< Emitter >::LabelTy LabelTy
typename Compiler< Emitter >::OptLabelTy OptLabelTy
typename Compiler< Emitter >::LabelInfo LabelInfo
typename Compiler< Emitter >::CaseMap CaseMap
SwitchScope(Compiler< Emitter > *Ctx, const Stmt *Name, CaseMap &&CaseLabels, LabelTy BreakLabel, OptLabelTy DefaultLabel)
Scope chain managing the variable lifetimes.
Compiler< Emitter > * Ctx
Compiler instance.
virtual void addLocal(Scope::Local Local)
VariableScope * getParent() const
bool Sub(InterpState &S, CodePtr OpPC)
bool LT(InterpState &S, CodePtr OpPC)
static llvm::RoundingMode getRoundingMode(FPOptions FPO)
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
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)
constexpr bool isIntegerOrBoolType(PrimType T)
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 Init(InterpState &S, CodePtr OpPC)
bool Mul(InterpState &S, CodePtr OpPC)
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
bool Inc(InterpState &S, CodePtr OpPC, bool CanOverflow)
1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...
bool Add(InterpState &S, CodePtr OpPC)
llvm::BitVector collectNonNullArgs(const FunctionDecl *F, ArrayRef< const Expr * > Args)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
bool hasSpecificAttr(const Container &container)
@ Success
Annotation was successful.
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
@ Result
The result type of a method or function.
OptionalUnsigned< unsigned > UnsignedOrNone
U cast(CodeGen::Address addr)
int const char * function
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.
QualType getElemQualType() const
bool hasTrivialDtor() const
Whether variables of this descriptor need their destructor called or not.
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
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.
PrimType getPrimType() const
bool isRecord() const
Checks if the descriptor is of a record.
const Record *const ElemRecord
Pointer to the record, if block contains records.
bool isArray() const
Checks if the descriptor is of an array.
Descriptor used for global variables.
GlobalInitState InitState
static InitLink InitList()
static InitLink Elem(unsigned Index)
bool emit(Compiler< Emitter > *Ctx, const Expr *E) const
static InitLink Field(unsigned Offset)
static InitLink Decl(const ValueDecl *D)
static InitLink Temp(unsigned Offset)
Information about a local's storage.
State encapsulating if a the variable creation has been successful, unsuccessful, or no variable has ...
static VarCreationState NotCreated()