29 if (
const auto *CE = dyn_cast_if_present<ConstantExpr>(E);
30 CE && CE->hasAPValueResult() &&
32 return CE->getResultAsAPSInt().getBoolValue();
43 OldInitializingDecl(
Ctx->InitializingDecl) {
44 Ctx->InitializingDecl = VD;
49 this->
Ctx->InitializingDecl = OldInitializingDecl;
50 this->
Ctx->InitStack.pop_back();
63 bool NewInitializing,
bool NewToLValue)
64 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
65 OldInitializing(Ctx->
Initializing), OldToLValue(Ctx->ToLValue) {
66 Ctx->DiscardResult = NewDiscardResult;
67 Ctx->Initializing = NewInitializing;
68 Ctx->ToLValue = NewToLValue;
72 Ctx->DiscardResult = OldDiscardResult;
73 Ctx->Initializing = OldInitializing;
74 Ctx->ToLValue = OldToLValue;
81 bool OldDiscardResult;
86template <
class Emitter>
90 return Ctx->emitThis(E);
93 return Ctx->emitGetPtrFieldPop(
Offset, E);
95 return Ctx->emitGetPtrLocal(
Offset, E);
99 if (!Ctx->emitConstUint32(
Offset, E))
101 return Ctx->emitArrayElemPtrPopUint32(E);
103 return Ctx->emitRVOPtr(E);
107 llvm_unreachable(
"Unhandled InitLink kind");
123 for (
const LabelInfo &LI : Ctx->LabelInfoStack)
124 assert(LI.Name != Name);
127 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel, ContinueLabel,
148 : Ctx(Ctx), OldCaseLabels(
std::move(this->Ctx->CaseLabels)) {
150 for (
const LabelInfo &LI : Ctx->LabelInfoStack)
151 assert(LI.Name != Name);
154 this->Ctx->CaseLabels = std::move(CaseLabels);
155 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel,
157 DefaultLabel, Ctx->VarScope);
161 this->Ctx->CaseLabels = std::move(OldCaseLabels);
162 this->Ctx->LabelInfoStack.pop_back();
167 CaseMap OldCaseLabels;
173 Ctx->InStmtExpr =
true;
191 : Ctx(Ctx), OldFlag(Ctx->LocOverride), Enabled(Enabled) {
194 Ctx->LocOverride = NewValue;
199 Ctx->LocOverride = OldFlag;
204 std::optional<SourceInfo> OldFlag;
211template <
class Emitter>
219 case CK_LValueToRValue: {
230 if (
const auto *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
236 if (
auto GlobalIndex =
P.getGlobal(D))
237 return this->emitGetGlobal(*SubExprT, *GlobalIndex, CE);
238 }
else if (
auto It =
Locals.find(D); It !=
Locals.end()) {
239 return this->emitGetLocal(*SubExprT, It->second.Offset, CE);
240 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
241 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
242 return this->emitGetParam(*SubExprT, It->second.Offset, CE);
254 if (!this->emitGetPtrLocal(*LocalIndex, CE))
258 if (!this->
visit(SubExpr))
262 return this->emitLoadPop(*SubExprT, CE);
267 return this->emitMemcpy(CE);
270 case CK_DerivedToBaseMemberPointer: {
276 unsigned DerivedOffset =
278 FromMP->getMostRecentCXXRecordDecl());
283 return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
286 case CK_BaseToDerivedMemberPointer: {
292 unsigned DerivedOffset =
293 Ctx.collectBaseOffset(FromMP->getMostRecentCXXRecordDecl(),
298 return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
301 case CK_UncheckedDerivedToBase:
302 case CK_DerivedToBase: {
307 if (
const auto *PT = dyn_cast<PointerType>(Ty))
308 return PT->getPointeeType()->getAsCXXRecordDecl();
309 return Ty->getAsCXXRecordDecl();
316 if (B->isVirtual()) {
317 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))
319 CurType = B->getType();
321 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
322 if (!this->emitGetPtrBasePop(
325 CurType = B->getType();
332 case CK_BaseToDerived: {
335 unsigned DerivedOffset =
341 return this->emitGetPtrDerivedPop(DerivedOffset,
346 case CK_FloatingCast: {
351 if (!this->
visit(SubExpr))
353 const auto *TargetSemantics = &
Ctx.getFloatSemantics(CE->
getType());
357 case CK_IntegralToFloating: {
360 if (!this->
visit(SubExpr))
362 const auto *TargetSemantics = &
Ctx.getFloatSemantics(CE->
getType());
363 return this->emitCastIntegralFloating(
364 classifyPrim(SubExpr), TargetSemantics, getFPOptions(CE), CE);
367 case CK_FloatingToBoolean: {
371 if (
const auto *FL = dyn_cast<FloatingLiteral>(SubExpr))
372 return this->emitConstBool(FL->getValue().isNonZero(), CE);
373 if (!this->
visit(SubExpr))
375 return this->emitCastFloatingIntegralBool(getFPOptions(CE), CE);
378 case CK_FloatingToIntegral: {
381 if (!this->
visit(SubExpr))
385 return this->emitCastFloatingIntegralAP(
Ctx.getBitWidth(CE->
getType()),
386 getFPOptions(CE), CE);
388 return this->emitCastFloatingIntegralAPS(
Ctx.getBitWidth(CE->
getType()),
389 getFPOptions(CE), CE);
391 return this->emitCastFloatingIntegral(ToT, getFPOptions(CE), CE);
394 case CK_NullToPointer:
395 case CK_NullToMemberPointer: {
400 if (!PointeeType.
isNull()) {
402 Desc =
P.createDescriptor(SubExpr, *
T);
404 Desc =
P.createDescriptor(SubExpr, PointeeType.
getTypePtr(),
408 uint64_t Val =
Ctx.getASTContext().getTargetNullPointerValue(CE->
getType());
412 case CK_PointerToIntegral: {
413 if (!this->
visit(SubExpr))
419 if (!this->emitDecayPtr(FromT,
PT_Ptr, CE))
425 return this->emitCastPointerIntegralAP(
Ctx.getBitWidth(CE->
getType()),
428 return this->emitCastPointerIntegralAPS(
Ctx.getBitWidth(CE->
getType()),
430 return this->emitCastPointerIntegral(
T, CE);
433 case CK_ArrayToPointerDecay: {
434 if (!this->
visit(SubExpr))
436 return this->emitArrayDecay(CE);
439 case CK_IntegralToPointer: {
441 assert(IntType->isIntegralOrEnumerationType());
442 if (!this->
visit(SubExpr))
450 Desc =
P.createDescriptor(SubExpr, *
T);
457 if (!this->emitGetIntPtr(
T, Desc, CE))
465 return this->emitDecayPtr(
PT_Ptr, DestPtrT, CE);
468 case CK_AtomicToNonAtomic:
469 case CK_ConstructorConversion:
470 case CK_FunctionToPointerDecay:
471 case CK_NonAtomicToAtomic:
473 case CK_UserDefinedConversion:
474 case CK_AddressSpaceConversion:
475 case CK_CPointerToObjCPointerCast:
490 return this->emitBuiltinBitCast(CE);
505 if (!this->
visit(SubExpr))
513 return this->emitFnPtrCast(CE);
520 if (!this->
visit(SubExpr))
522 return this->emitDecayPtr(*FromT, *ToT, CE);
524 case CK_IntegralToBoolean:
525 case CK_FixedPointToBoolean: {
531 if (
const auto *IL = dyn_cast<IntegerLiteral>(SubExpr))
532 return this->emitConst(IL->getValue(), CE);
533 if (!this->
visit(SubExpr))
538 case CK_BooleanToSignedIntegral:
539 case CK_IntegralCast: {
546 if (
const auto *IL = dyn_cast<IntegerLiteral>(SubExpr)) {
551 if (!this->emitConst(IL->getValue(), SubExpr))
554 if (!this->
visit(SubExpr))
562 if (!ED->isFixed()) {
563 if (!this->emitCheckEnumValue(*FromT, ED, CE))
569 if (!this->emitCastAP(*FromT,
Ctx.getBitWidth(CE->
getType()), CE))
572 if (!this->emitCastAPS(*FromT,
Ctx.getBitWidth(CE->
getType()), CE))
577 if (!this->emitCast(*FromT, *ToT, CE))
580 if (CE->
getCastKind() == CK_BooleanToSignedIntegral)
581 return this->emitNeg(*ToT, CE);
585 case CK_PointerToBoolean:
586 case CK_MemberPointerToBoolean: {
589 if (!this->
visit(SubExpr))
591 return this->emitIsNonNull(PtrT, CE);
594 case CK_IntegralComplexToBoolean:
595 case CK_FloatingComplexToBoolean: {
596 if (!this->
visit(SubExpr))
598 return this->emitComplexBoolCast(SubExpr);
601 case CK_IntegralComplexToReal:
602 case CK_FloatingComplexToReal:
603 return this->emitComplexReal(SubExpr);
605 case CK_IntegralRealToComplex:
606 case CK_FloatingRealToComplex: {
613 if (!this->emitGetPtrLocal(*LocalIndex, CE))
622 if (!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
624 return this->emitInitElem(
T, 1, SubExpr);
627 case CK_IntegralComplexCast:
628 case CK_FloatingComplexCast:
629 case CK_IntegralComplexToFloatingComplex:
630 case CK_FloatingComplexToIntegralComplex: {
637 if (!this->emitGetPtrLocal(*LocalIndex, CE))
644 unsigned SubExprOffset =
646 if (!this->
visit(SubExpr))
648 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, CE))
656 for (
unsigned I = 0; I != 2; ++I) {
657 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, CE))
659 if (!this->emitArrayElemPop(SourceElemT, I, CE))
663 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
667 if (!this->emitInitElem(DestElemT, I, CE))
673 case CK_VectorSplat: {
682 if (!this->emitGetPtrLocal(*LocalIndex, CE))
688 unsigned ElemOffset =
692 if (!this->
visit(SubExpr))
697 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
700 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
701 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
703 if (!this->emitInitElem(ElemT, I, CE))
710 case CK_HLSLVectorTruncation: {
715 if (!this->
visit(SubExpr))
717 return this->emitArrayElemPop(*ResultT, 0, CE);
726 if (!this->emitGetPtrLocal(*LocalIndex, CE))
731 if (!this->
visit(SubExpr))
733 return this->emitCopyArray(classifyVectorElementType(CE->
getType()), 0, 0,
737 case CK_IntegralToFixedPoint: {
738 if (!this->
visit(SubExpr))
742 Ctx.getASTContext().getFixedPointSemantics(CE->
getType()).toOpaqueInt();
746 case CK_FloatingToFixedPoint: {
747 if (!this->
visit(SubExpr))
751 Ctx.getASTContext().getFixedPointSemantics(CE->
getType()).toOpaqueInt();
752 return this->emitCastFloatingFixedPoint(Sem, CE);
754 case CK_FixedPointToFloating: {
755 if (!this->
visit(SubExpr))
757 const auto *TargetSemantics = &
Ctx.getFloatSemantics(CE->
getType());
758 return this->emitCastFixedPointFloating(TargetSemantics, CE);
760 case CK_FixedPointToIntegral: {
761 if (!this->
visit(SubExpr))
765 case CK_FixedPointCast: {
766 if (!this->
visit(SubExpr))
769 Ctx.getASTContext().getFixedPointSemantics(CE->
getType()).toOpaqueInt();
770 return this->emitCastFixedPoint(Sem, CE);
777 return this->emitInvalid(CE);
779 llvm_unreachable(
"Unhandled clang::CastKind enum");
782template <
class Emitter>
784 return this->emitBuiltinBitCast(E);
787template <
class Emitter>
792 return this->emitConst(
LE->getValue(),
LE);
795template <
class Emitter>
801 return this->emitFloat(F, E);
804template <
class Emitter>
814 if (!this->emitGetPtrLocal(*LocalIndex, E))
821 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
823 if (!this->emitInitElem(SubExprT, 0, SubExpr))
828template <
class Emitter>
836 auto Sem =
Ctx.getASTContext().getFixedPointSemantics(E->
getType());
841template <
class Emitter>
846template <
class Emitter>
873 return this->emitComplexComparison(LHS, RHS, BO);
878 if (!this->
visit(LHS))
881 if (!this->
visit(RHS))
884 if (!this->emitToMemberPtr(BO))
890 if (!this->emitCastMemberPtrPtr(BO))
907 Ctx.getASTContext().CompCategories.lookupInfoForType(BO->
getType());
913 if (!this->emitGetPtrLocal(*ResultIndex, BO))
920 return this->emitCMP3(*
LT, CmpInfo, BO);
923 if (!
LT || !RT || !
T)
933 return this->visitAssignment(LHS, RHS, BO);
940 auto MaybeCastToBool = [
this,
T, BO](
bool Result) {
944 return this->emitPopBool(BO);
946 return this->emitCast(
PT_Bool, *
T, BO);
950 auto Discard = [
this,
T, BO](
bool Result) {
958 return MaybeCastToBool(this->emitEQ(*
LT, BO));
960 return MaybeCastToBool(this->emitNE(*
LT, BO));
962 return MaybeCastToBool(this->emitLT(*
LT, BO));
964 return MaybeCastToBool(this->emitLE(*
LT, BO));
966 return MaybeCastToBool(this->emitGT(*
LT, BO));
968 return MaybeCastToBool(this->emitGE(*
LT, BO));
971 return Discard(this->emitSubf(getFPOptions(BO), BO));
972 return Discard(this->emitSub(*
T, BO));
975 return Discard(this->emitAddf(getFPOptions(BO), BO));
976 return Discard(this->emitAdd(*
T, BO));
979 return Discard(this->emitMulf(getFPOptions(BO), BO));
980 return Discard(this->emitMul(*
T, BO));
982 return Discard(this->emitRem(*
T, BO));
985 return Discard(this->emitDivf(getFPOptions(BO), BO));
986 return Discard(this->emitDiv(*
T, BO));
988 return Discard(this->emitBitAnd(*
T, BO));
990 return Discard(this->emitBitOr(*
T, BO));
992 return Discard(this->emitShl(*
LT, *RT, BO));
994 return Discard(this->emitShr(*
LT, *RT, BO));
996 return Discard(this->emitBitXor(*
T, BO));
999 llvm_unreachable(
"Already handled earlier");
1004 llvm_unreachable(
"Unhandled binary op");
1009template <
class Emitter>
1015 if ((Op != BO_Add && Op != BO_Sub) ||
1026 auto visitAsPointer = [&](
const Expr *E,
PrimType T) ->
bool {
1027 if (!this->
visit(E))
1030 return this->emitDecayPtr(
T,
PT_Ptr, E);
1039 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *
LT))
1047 ElemTypeSize =
Ctx.getASTContext().getTypeSizeInChars(ElemType);
1050 if (!this->emitSubPtr(IntT, ElemTypeSize.
isZero(), E))
1057 if (!visitAsPointer(RHS, *RT))
1059 if (!this->
visit(LHS))
1063 if (!visitAsPointer(LHS, *
LT))
1065 if (!this->
visit(RHS))
1075 if (!this->emitAddOffset(OffsetType, E))
1083 if (!this->emitSubOffset(OffsetType, E))
1094template <
class Emitter>
1104 LabelTy LabelTrue = this->getLabel();
1105 LabelTy LabelEnd = this->getLabel();
1109 if (!this->jumpTrue(LabelTrue))
1114 if (!this->jump(LabelEnd))
1117 this->emitLabel(LabelTrue);
1118 this->emitConstBool(
true, E);
1119 this->fallthrough(LabelEnd);
1120 this->emitLabel(LabelEnd);
1123 assert(Op == BO_LAnd);
1126 LabelTy LabelFalse = this->getLabel();
1127 LabelTy LabelEnd = this->getLabel();
1131 if (!this->jumpFalse(LabelFalse))
1136 if (!this->jump(LabelEnd))
1139 this->emitLabel(LabelFalse);
1140 this->emitConstBool(
false, E);
1141 this->fallthrough(LabelEnd);
1142 this->emitLabel(LabelEnd);
1146 return this->emitPopBool(E);
1151 return this->emitCast(
PT_Bool, *
T, E);
1155template <
class Emitter>
1162 if (!this->emitGetPtrLocal(*LocalIndex, E))
1171 PrimType ResultElemT = this->classifyComplexElementType(E->
getType());
1172 unsigned ResultOffset = ~0u;
1178 if (!this->emitDupPtr(E))
1180 if (!this->emitSetLocal(
PT_Ptr, ResultOffset, E))
1185 LHSType = AT->getValueType();
1188 RHSType = AT->getValueType();
1197 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1202 if (!this->
visit(LHS))
1204 if (!this->
visit(RHS))
1206 return this->emitMulc(ElemT, E);
1209 if (Op == BO_Div && RHSIsComplex) {
1216 if (!LHSIsComplex) {
1221 LHSOffset = *LocalIndex;
1223 if (!this->emitGetPtrLocal(LHSOffset, E))
1226 if (!this->
visit(LHS))
1229 if (!this->emitInitElem(ElemT, 0, E))
1232 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1234 if (!this->emitInitElem(ElemT, 1, E))
1237 if (!this->
visit(LHS))
1241 if (!this->
visit(RHS))
1243 return this->emitDivc(ElemT, E);
1249 if (!this->
visit(LHS))
1251 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
1256 if (!this->
visit(LHS))
1258 if (!this->emitSetLocal(LHST, LHSOffset, E))
1266 if (!this->
visit(RHS))
1268 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
1273 if (!this->
visit(RHS))
1275 if (!this->emitSetLocal(RHST, RHSOffset, E))
1282 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1283 unsigned ElemIndex,
unsigned Offset,
1284 const Expr *E) ->
bool {
1286 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
1288 return this->emitArrayElemPop(classifyComplexElementType(E->
getType()),
1291 if (ElemIndex == 0 || !LoadZero)
1298 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1301 if (!this->emitGetLocal(
PT_Ptr, ResultOffset, E))
1308 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1311 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1314 if (!this->emitAddf(getFPOptions(E), E))
1317 if (!this->emitAdd(ResultElemT, E))
1322 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1325 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1328 if (!this->emitSubf(getFPOptions(E), E))
1331 if (!this->emitSub(ResultElemT, E))
1336 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1339 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1343 if (!this->emitMulf(getFPOptions(E), E))
1346 if (!this->emitMul(ResultElemT, E))
1351 assert(!RHSIsComplex);
1352 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1355 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1359 if (!this->emitDivf(getFPOptions(E), E))
1362 if (!this->emitDiv(ResultElemT, E))
1373 if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))
1376 if (!this->emitPop(ResultElemT, E))
1383template <
class Emitter>
1388 "Comma op should be handled in VisitBinaryOperator");
1402 if (!this->emitGetPtrLocal(*LocalIndex, E))
1416 assert(
Ctx.getASTContext().hasSameUnqualifiedType(
1419 if (!this->
visit(LHS))
1421 if (!this->
visit(RHS))
1423 if (!this->emitCopyArray(ElemT, 0, 0, VecTy->getNumElements(), E))
1426 return this->emitPopPtr(E);
1431 unsigned LHSOffset =
1433 if (!this->
visit(LHS))
1435 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
1439 unsigned RHSOffset =
1441 if (!this->
visit(RHS))
1443 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
1455 if (NeedIntPromot) {
1457 Ctx.getASTContext().getPromotedIntegerType(
Ctx.getASTContext().BoolTy);
1462 auto getElem = [=](
unsigned Offset,
PrimType ElemT,
unsigned Index) {
1463 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
1465 if (!this->emitArrayElemPop(ElemT, Index, E))
1468 if (!this->emitPrimCast(ElemT,
PT_Bool,
Ctx.getASTContext().BoolTy, E))
1470 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(), E))
1472 }
else if (NeedIntPromot) {
1473 if (!this->emitPrimCast(ElemT, PromotT, PromotTy, E))
1479#define EMIT_ARITH_OP(OP) \
1481 if (ElemT == PT_Float) { \
1482 if (!this->emit##OP##f(getFPOptions(E), E)) \
1485 if (!this->emit##OP(ElemT, E)) \
1491 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
1492 if (!getElem(LHSOffset, ElemT, I))
1494 if (!getElem(RHSOffset, RHSElemT, I))
1506 if (!this->emitRem(ElemT, E))
1510 if (!this->emitBitAnd(OpT, E))
1514 if (!this->emitBitOr(OpT, E))
1518 if (!this->emitBitXor(OpT, E))
1522 if (!this->emitShl(OpT, RHSElemT, E))
1526 if (!this->emitShr(OpT, RHSElemT, E))
1530 if (!this->emitEQ(ElemT, E))
1534 if (!this->emitNE(ElemT, E))
1538 if (!this->emitLE(ElemT, E))
1542 if (!this->emitLT(ElemT, E))
1546 if (!this->emitGE(ElemT, E))
1550 if (!this->emitGT(ElemT, E))
1555 if (!this->emitBitAnd(ResultElemT, E))
1560 if (!this->emitBitOr(ResultElemT, E))
1564 return this->emitInvalid(E);
1573 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(), E))
1575 if (!this->emitNeg(ResultElemT, E))
1581 if (NeedIntPromot &&
1582 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(), E))
1586 if (!this->emitInitElem(ResultElemT, I, E))
1595template <
class Emitter>
1605 auto LHSSemaInt = LHSSema.toOpaqueInt();
1607 auto RHSSemaInt = RHSSema.toOpaqueInt();
1609 if (!this->
visit(LHS))
1617 if (!this->
visit(RHS))
1626 auto ConvertResult = [&](
bool R) ->
bool {
1630 auto CommonSema = LHSSema.getCommonSemantics(RHSSema).toOpaqueInt();
1631 if (ResultSema != CommonSema)
1632 return this->emitCastFixedPoint(ResultSema, E);
1636 auto MaybeCastToBool = [&](
bool Result) {
1641 return this->emitPop(
T, E);
1643 return this->emitCast(
PT_Bool,
T, E);
1649 return MaybeCastToBool(this->emitEQFixedPoint(E));
1651 return MaybeCastToBool(this->emitNEFixedPoint(E));
1653 return MaybeCastToBool(this->emitLTFixedPoint(E));
1655 return MaybeCastToBool(this->emitLEFixedPoint(E));
1657 return MaybeCastToBool(this->emitGTFixedPoint(E));
1659 return MaybeCastToBool(this->emitGEFixedPoint(E));
1661 return ConvertResult(this->emitAddFixedPoint(E));
1663 return ConvertResult(this->emitSubFixedPoint(E));
1665 return ConvertResult(this->emitMulFixedPoint(E));
1667 return ConvertResult(this->emitDivFixedPoint(E));
1669 return ConvertResult(this->emitShiftFixedPoint(
true, E));
1671 return ConvertResult(this->emitShiftFixedPoint(
false, E));
1674 return this->emitInvalid(E);
1677 llvm_unreachable(
"unhandled binop opcode");
1680template <
class Emitter>
1689 if (!this->
visit(SubExpr))
1691 return this->emitNegFixedPoint(E);
1696 llvm_unreachable(
"Unhandled unary opcode");
1699template <
class Emitter>
1705 return this->visitZeroInitializer(*
T, QT, E);
1713 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1714 CXXRD && CXXRD->getNumVBases() > 0) {
1724 return this->visitZeroRecordInitializer(R, E);
1731 return this->visitZeroArrayInitializer(QT, E);
1735 QualType ElemQT = ComplexTy->getElementType();
1737 for (
unsigned I = 0; I < 2; ++I) {
1738 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1740 if (!this->emitInitElem(ElemT, I, E))
1747 unsigned NumVecElements = VecT->getNumElements();
1748 QualType ElemQT = VecT->getElementType();
1751 for (
unsigned I = 0; I < NumVecElements; ++I) {
1752 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1754 if (!this->emitInitElem(ElemT, I, E))
1763template <
class Emitter>
1773 for (
const Expr *SubExpr : {LHS, RHS}) {
1774 if (!this->
visit(SubExpr)) {
1781 if (SubExpr ==
Base &&
Base->getType()->isPointerType()) {
1782 if (!this->emitExpandPtr(E))
1793 return this->emitError(E);
1796 if (!this->emitFlip(
PT_Ptr, *IndexT, E))
1800 if (!this->emitArrayElemPtrPop(*IndexT, E))
1803 return this->emitPopPtr(E);
1809 return this->emitLoadPop(*
T, E);
1812template <
class Emitter>
1814 const Expr *ArrayFiller,
const Expr *E) {
1819 QT = AT->getValueType();
1822 if (Inits.size() == 0)
1824 return this->emitInvalid(E);
1839 if (Inits.size() == 0)
1840 return this->visitZeroInitializer(*
T, QT, E);
1841 assert(Inits.size() == 1);
1848 if (Inits.size() == 1 && E->
getType() == Inits[0]->getType())
1854 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
1861 bool BitField = FieldToInit->isBitField();
1863 return this->emitInitBitFieldActivate(
T, FieldToInit, E);
1865 return this->emitInitBitField(
T, FieldToInit, E);
1867 return this->emitInitFieldActivate(
T, FieldToInit->Offset, E);
1868 return this->emitInitField(
T, FieldToInit->Offset, E);
1871 auto initCompositeField = [=](
const Record::Field *FieldToInit,
1879 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
1882 if (
Activate && !this->emitActivate(E))
1887 return this->emitPopPtr(E);
1891 if (Inits.size() == 0) {
1892 if (!this->visitZeroRecordInitializer(R, E))
1897 if (
const auto *ILE = dyn_cast<InitListExpr>(E))
1898 FToInit = ILE->getInitializedFieldInUnion();
1902 const Record::Field *FieldToInit = R->
getField(FToInit);
1904 if (!initPrimitiveField(FieldToInit,
Init, *
T,
true))
1907 if (!initCompositeField(FieldToInit,
Init,
true))
1911 return this->emitFinishInit(E);
1915 unsigned InitIndex = 0;
1918 while (InitIndex < R->getNumFields() &&
1923 const Record::Field *FieldToInit = R->
getField(InitIndex);
1924 if (!initPrimitiveField(FieldToInit,
Init, *
T))
1929 if (
const Record::Base *B = R->
getBase(
Init->getType())) {
1930 if (!this->emitGetPtrBase(B->Offset,
Init))
1936 if (!this->emitFinishInitPop(E))
1941 const Record::Field *FieldToInit = R->
getField(InitIndex);
1942 if (!initCompositeField(FieldToInit,
Init))
1948 return this->emitFinishInit(E);
1952 if (Inits.size() == 1 && QT == Inits[0]->getType())
1956 Ctx.getASTContext().getAsConstantArrayType(QT);
1959 if (!this->emitCheckArraySize(NumElems, E))
1963 unsigned ElementIndex = 0;
1965 if (
const auto *EmbedS =
1966 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
1974 if (!this->emitCastIntegralFloating(
classifyPrim(IL), Sem,
1975 getFPOptions(E), E))
1981 return this->emitInitElem(TargetT, ElemIndex, IL);
1983 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
1995 for (; ElementIndex != NumElems; ++ElementIndex) {
2001 return this->emitFinishInit(E);
2005 unsigned NumInits = Inits.size();
2010 QualType ElemQT = ComplexTy->getElementType();
2012 if (NumInits == 0) {
2014 for (
unsigned I = 0; I < 2; ++I) {
2015 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2017 if (!this->emitInitElem(ElemT, I, E))
2020 }
else if (NumInits == 2) {
2021 unsigned InitIndex = 0;
2026 if (!this->emitInitElem(ElemT, InitIndex, E))
2035 unsigned NumVecElements = VecT->getNumElements();
2036 assert(NumVecElements >= Inits.size());
2038 QualType ElemQT = VecT->getElementType();
2042 unsigned InitIndex = 0;
2049 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
2050 if (!this->emitCopyArray(ElemT, 0, InitIndex,
2051 InitVecT->getNumElements(), E))
2053 InitIndex += InitVecT->getNumElements();
2055 if (!this->emitInitElem(ElemT, InitIndex, E))
2061 assert(InitIndex <= NumVecElements);
2064 for (; InitIndex != NumVecElements; ++InitIndex) {
2065 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2067 if (!this->emitInitElem(ElemT, InitIndex, E))
2078template <
class Emitter>
2085 return this->emitInitElem(*InitT, ElemIndex,
Init);
2091 if (!this->emitConstUint32(ElemIndex,
Init))
2093 if (!this->emitArrayElemPtrUint32(
Init))
2097 return this->emitFinishInitPop(
Init);
2100template <
class Emitter>
2103 bool Activate,
bool IsOperatorCall) {
2105 llvm::BitVector NonNullArgs;
2106 if (FuncDecl && FuncDecl->
hasAttr<NonNullAttr>())
2109 bool ExplicitMemberFn =
false;
2110 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl))
2111 ExplicitMemberFn = MD->isExplicitObjectMemberFunction();
2113 unsigned ArgIndex = 0;
2114 for (
const Expr *Arg : Args) {
2116 if (!this->
visit(Arg))
2124 unsigned DeclIndex = ArgIndex - IsOperatorCall + ExplicitMemberFn;
2125 if (DeclIndex < FuncDecl->getNumParams())
2126 Source = FuncDecl->
getParamDecl(ArgIndex - IsOperatorCall +
2136 if (!this->emitGetPtrLocal(*LocalIndex, Arg))
2144 if (!this->emitActivate(Arg))
2148 if (!NonNullArgs.empty() && NonNullArgs[ArgIndex]) {
2151 if (!this->emitCheckNonNullArg(ArgT, Arg))
2162template <
class Emitter>
2167template <
class Emitter>
2173template <
class Emitter>
2179template <
class Emitter>
2195template <
class Emitter>
2197 auto It = E->
begin();
2198 return this->
visit(*It);
2203 bool AlignOfReturnsPreferred =
2204 ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
2210 T = Ref->getPointeeType();
2212 if (
T.getQualifiers().hasUnaligned())
2218 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2224template <
class Emitter>
2230 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2236 ArgType = Ref->getPointeeType();
2242 if (
ArgType->isDependentType() || !
ArgType->isConstantSizeType())
2243 return this->emitInvalid(E);
2245 if (Kind == UETT_SizeOf)
2254 return this->emitConst(Size.getQuantity(), E);
2257 if (Kind == UETT_CountOf) {
2263 if (
const auto *CAT =
2267 return this->emitConst(CAT->getSize(), E);
2277 if (VAT->getElementType()->isArrayType()) {
2278 std::optional<APSInt> Res =
2280 ? VAT->getSizeExpr()->getIntegerConstantExpr(ASTCtx)
2285 return this->emitConst(*Res, E);
2290 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2307 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2310 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
2320 return this->emitConst(Size.getQuantity(), E);
2323 if (Kind == UETT_VectorElements) {
2325 return this->emitConst(VT->getNumElements(), E);
2327 return this->emitSizelessVectorElementSize(E);
2330 if (Kind == UETT_VecStep) {
2332 unsigned N = VT->getNumElements();
2339 return this->emitConst(N, E);
2341 return this->emitConst(1, E);
2344 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2351 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2353 return this->emitInvalid(E);
2355 return this->emitConst(
2356 const_cast<ASTContext &
>(ASTCtx).getPointerAuthTypeDiscriminator(
2364template <
class Emitter>
2375 const auto maybeLoadValue = [&]() ->
bool {
2379 return this->emitLoadPop(*
T, E);
2383 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
2387 if (
auto GlobalIndex =
P.getGlobal(VD))
2388 return this->emitGetPtrGlobal(*GlobalIndex, E) && maybeLoadValue();
2393 if (!this->
discard(Base) && !this->emitSideEffect(E))
2408 const Record::Field *F = R->
getField(FD);
2410 if (F->Decl->getType()->isReferenceType())
2411 return this->emitGetFieldPop(
PT_Ptr, F->Offset, E) && maybeLoadValue();
2412 return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue();
2415template <
class Emitter>
2424template <
class Emitter>
2443 for (
size_t I = 0; I != Size; ++I) {
2455template <
class Emitter>
2466 return this->emitGetLocal(SubExprT, It->second, E);
2468 if (!this->
visit(SourceExpr))
2475 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
2481 if (!this->emitGetLocal(SubExprT, LocalIndex, E))
2491template <
class Emitter>
2498 auto visitChildExpr = [&](
const Expr *E) ->
bool {
2507 return visitChildExpr(TrueExpr);
2508 return visitChildExpr(FalseExpr);
2511 bool IsBcpCall =
false;
2512 if (
const auto *CE = dyn_cast<CallExpr>(
Condition->IgnoreParenCasts());
2513 CE && CE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) {
2517 LabelTy LabelEnd = this->getLabel();
2518 LabelTy LabelFalse = this->getLabel();
2521 if (!this->emitStartSpeculation(E))
2529 if (this->checkingForUndefinedBehavior()) {
2532 if (!this->
discard(FalseExpr))
2538 if (!this->jumpFalse(LabelFalse))
2540 if (!visitChildExpr(TrueExpr))
2542 if (!this->jump(LabelEnd))
2544 this->emitLabel(LabelFalse);
2545 if (!visitChildExpr(FalseExpr))
2547 this->fallthrough(LabelEnd);
2548 this->emitLabel(LabelEnd);
2551 return this->emitEndSpeculation(E);
2555template <
class Emitter>
2561 unsigned StringIndex =
P.createGlobalString(E);
2562 return this->emitGetPtrGlobal(StringIndex, E);
2567 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
2568 assert(CAT &&
"a string literal that's not a constant array?");
2573 unsigned N = std::min(ArraySize, E->
getLength());
2576 for (
unsigned I = 0; I != N; ++I) {
2579 if (CharWidth == 1) {
2580 this->emitConstSint8(CodeUnit, E);
2581 this->emitInitElemSint8(I, E);
2582 }
else if (CharWidth == 2) {
2583 this->emitConstUint16(CodeUnit, E);
2584 this->emitInitElemUint16(I, E);
2585 }
else if (CharWidth == 4) {
2586 this->emitConstUint32(CodeUnit, E);
2587 this->emitInitElemUint32(I, E);
2589 llvm_unreachable(
"unsupported character width");
2594 for (
unsigned I = N; I != ArraySize; ++I) {
2595 if (CharWidth == 1) {
2596 this->emitConstSint8(0, E);
2597 this->emitInitElemSint8(I, E);
2598 }
else if (CharWidth == 2) {
2599 this->emitConstUint16(0, E);
2600 this->emitInitElemUint16(I, E);
2601 }
else if (CharWidth == 4) {
2602 this->emitConstUint32(0, E);
2603 this->emitInitElemUint32(I, E);
2605 llvm_unreachable(
"unsupported character width");
2612template <
class Emitter>
2616 return this->emitDummyPtr(E, E);
2619template <
class Emitter>
2621 auto &A =
Ctx.getASTContext();
2630template <
class Emitter>
2638 auto &A =
Ctx.getASTContext();
2642 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
2643 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
2650 unsigned StringIndex =
P.createGlobalString(SL);
2651 return this->emitGetPtrGlobal(StringIndex, E);
2654template <
class Emitter>
2658 return this->emitConst(E->
getValue(), E);
2661template <
class Emitter>
2687 if (!this->emitSetLocal(*RT, TempOffset, E))
2693 if (!this->emitLoad(LHST, E))
2697 if (!this->emitPrimCast(LHST,
classifyPrim(LHSComputationType),
2698 LHSComputationType, E))
2702 if (!this->emitGetLocal(*RT, TempOffset, E))
2707 if (!this->emitAddf(getFPOptions(E), E))
2711 if (!this->emitSubf(getFPOptions(E), E))
2715 if (!this->emitMulf(getFPOptions(E), E))
2719 if (!this->emitDivf(getFPOptions(E), E))
2730 return this->emitStorePop(LHST, E);
2731 return this->emitStore(LHST, E);
2734template <
class Emitter>
2743 if (Op != BO_AddAssign && Op != BO_SubAssign)
2752 if (!this->emitLoad(*
LT, LHS))
2758 if (Op == BO_AddAssign) {
2759 if (!this->emitAddOffset(*RT, E))
2762 if (!this->emitSubOffset(*RT, E))
2767 return this->emitStorePopPtr(E);
2768 return this->emitStorePtr(E);
2771template <
class Emitter>
2784 if (!
Ctx.getLangOpts().CPlusPlus14)
2785 return this->
visit(RHS) && this->
visit(LHS) && this->emitError(E);
2787 if (!
LT || !RT || !ResultT || !LHSComputationT)
2812 if (!this->emitSetLocal(*RT, TempOffset, E))
2819 if (!this->emitLoad(*
LT, E))
2821 if (
LT != LHSComputationT) {
2822 if (!this->emitCast(*
LT, *LHSComputationT, E))
2827 if (!this->emitGetLocal(*RT, TempOffset, E))
2833 if (!this->emitAdd(*LHSComputationT, E))
2837 if (!this->emitSub(*LHSComputationT, E))
2841 if (!this->emitMul(*LHSComputationT, E))
2845 if (!this->emitDiv(*LHSComputationT, E))
2849 if (!this->emitRem(*LHSComputationT, E))
2853 if (!this->emitShl(*LHSComputationT, *RT, E))
2857 if (!this->emitShr(*LHSComputationT, *RT, E))
2861 if (!this->emitBitAnd(*LHSComputationT, E))
2865 if (!this->emitBitXor(*LHSComputationT, E))
2869 if (!this->emitBitOr(*LHSComputationT, E))
2873 llvm_unreachable(
"Unimplemented compound assign operator");
2877 if (ResultT != LHSComputationT) {
2878 if (!this->emitCast(*LHSComputationT, *ResultT, E))
2885 return this->emitStoreBitFieldPop(*ResultT, E);
2886 return this->emitStorePop(*ResultT, E);
2889 return this->emitStoreBitField(*ResultT, E);
2890 return this->emitStore(*ResultT, E);
2893template <
class Emitter>
2901template <
class Emitter>
2913 return this->
discard(SubExpr);
2930 if (!this->
visit(SubExpr))
2932 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl, E))
2934 return this->emitGetPtrGlobal(*GlobalIndex, E);
2937 if (!this->checkLiteralType(SubExpr))
2940 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2944 return this->emitInitGlobalTempComp(TempDecl, E);
2953 if (!this->
visit(SubExpr))
2955 if (!this->emitSetLocal(*SubExprT, LocalIndex, E))
2957 return this->emitGetPtrLocal(LocalIndex, E);
2960 if (!this->checkLiteralType(SubExpr))
2966 if (!this->emitGetPtrLocal(*LocalIndex, E))
2973template <
class Emitter>
2984 if (!this->
visit(SubExpr))
2988 return this->emitPopPtr(E);
2992template <
class Emitter>
3013 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3018 if (
P.isGlobalInitialized(*GlobalIndex))
3024 return this->emitInitGlobal(*
T, *GlobalIndex, E);
3036 unsigned LocalIndex;
3040 LocalIndex = *MaybeIndex;
3044 if (!this->emitGetPtrLocal(LocalIndex, E))
3048 return this->
visit(
Init) && this->emitInit(*
T, E);
3052template <
class Emitter>
3065template <
class Emitter>
3069 return this->emitConst(E->
getValue(), E);
3072template <
class Emitter>
3085 for (
const Record::Field &F : R->
fields()) {
3087 if (!
Init ||
Init->containsErrors())
3095 if (!this->emitInitField(*
T, F.Offset, E))
3098 if (!this->emitGetPtrField(F.Offset, E))
3104 if (!this->emitPopPtr(E))
3112template <
class Emitter>
3119 return this->emitGetPtrGlobal(StringIndex, E);
3125template <
class Emitter>
3130 return this->emitInvalid(E);
3133template <
class Emitter>
3159 if (PointeeToT && PointeeFromT) {
3175 bool Fatal = (ToT != FromT);
3182template <
class Emitter>
3185 if (!
Ctx.getLangOpts().CPlusPlus20) {
3193template <
class Emitter>
3199 return this->emitConstBool(E->
getValue(), E);
3202template <
class Emitter>
3207 if (
T->isRecordType()) {
3221 if (!this->emitGetPtrLocal(*LocalIndex, E))
3229 T->getAsCXXRecordDecl()))
3237 if (!this->visitZeroRecordInitializer(R, E))
3249 assert(
Ctx.getASTContext().hasSameUnqualifiedType(E->
getType(),
3251 if (
const auto *ME = dyn_cast<MaterializeTemporaryExpr>(SrcObj)) {
3252 if (!this->emitCheckFunctionDecl(Ctor, E))
3263 assert(
Func->hasThisPointer());
3264 assert(!
Func->hasRVO());
3268 if (!this->emitDupPtr(E))
3272 for (
const auto *Arg : E->
arguments()) {
3273 if (!this->
visit(Arg))
3277 if (
Func->isVariadic()) {
3278 uint32_t VarArgSize = 0;
3279 unsigned NumParams =
Func->getNumWrittenParams();
3280 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I) {
3284 if (!this->emitCallVar(
Func, VarArgSize, E))
3287 if (!this->emitCall(
Func, 0, E)) {
3292 (void)this->emitPopPtr(E);
3298 return this->emitPopPtr(E);
3299 return this->emitFinishInit(E);
3302 if (
T->isArrayType()) {
3307 if (!this->emitDupPtr(E))
3311 initArrayDimension = [&](
QualType T) ->
bool {
3312 if (!
T->isArrayType()) {
3314 for (
const auto *Arg : E->
arguments()) {
3315 if (!this->
visit(Arg))
3319 return this->emitCall(
Func, 0, E);
3323 Ctx.getASTContext().getAsConstantArrayType(
T);
3328 for (
size_t I = 0; I != NumElems; ++I) {
3329 if (!this->emitConstUint64(I, E))
3331 if (!this->emitArrayElemPtrUint64(E))
3333 if (!initArrayDimension(ElemTy))
3336 return this->emitPopPtr(E);
3339 return initArrayDimension(E->
getType());
3345template <
class Emitter>
3355 assert(Val.
isInt());
3357 return this->emitConst(I, E);
3364 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
3365 return this->
visit(LValueExpr);
3380 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3384 const APValue &
V = UGCD->getValue();
3385 for (
unsigned I = 0, N = R->
getNumFields(); I != N; ++I) {
3386 const Record::Field *F = R->
getField(I);
3387 const APValue &FieldValue =
V.getStructField(I);
3393 if (!this->emitInitField(FieldT, F->Offset, E))
3401template <
class Emitter>
3407 for (
unsigned I = 0; I != N; ++I) {
3414 if (!this->
discard(ArrayIndexExpr))
3419 if (!this->
visit(ArrayIndexExpr))
3423 if (!this->emitCast(IndexT,
PT_Sint64, E))
3433 return this->emitOffsetOf(
T, E, E);
3436template <
class Emitter>
3445 return this->visitZeroInitializer(*
T, Ty, E);
3452 if (!this->emitGetPtrLocal(*LocalIndex, E))
3457 QualType ElemQT = CT->getElementType();
3460 for (
unsigned I = 0; I != 2; ++I) {
3461 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
3463 if (!this->emitInitElem(ElemT, I, E))
3475 if (!this->emitGetPtrLocal(*LocalIndex, E))
3480 QualType ElemQT = VT->getElementType();
3483 for (
unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
3484 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
3486 if (!this->emitInitElem(ElemT, I, E))
3495template <
class Emitter>
3500template <
class Emitter>
3506template <
class Emitter>
3511template <
class Emitter>
3516 return this->emitConst(E->
getValue(), E);
3519template <
class Emitter>
3524 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
3542 if (!this->emitGetParam(PT, Offset, E))
3547 return this->emitCall(F, 0, E);
3552template <
class Emitter>
3560 const Expr *PlacementDest =
nullptr;
3561 bool IsNoThrow =
false;
3563 if (PlacementArgs != 0) {
3572 if (PlacementArgs == 1) {
3580 if (!this->emitInvalidNewDeleteExpr(E, E))
3585 if (OperatorNew->isReservedGlobalPlacementOperator())
3586 PlacementDest = Arg1;
3590 return this->emitInvalid(E);
3592 }
else if (!OperatorNew
3593 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
3594 return this->emitInvalidNewDeleteExpr(E, E);
3597 if (!PlacementDest) {
3602 Desc =
P.createDescriptor(E, *ElemT,
nullptr,
3605 Desc =
P.createDescriptor(
3608 false,
false,
false,
3614 std::optional<const Expr *> ArraySizeExpr = E->
getArraySize();
3618 const Expr *Stripped = *ArraySizeExpr;
3619 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
3620 Stripped = ICE->getSubExpr())
3621 if (ICE->getCastKind() != CK_NoOp &&
3622 ICE->getCastKind() != CK_IntegralCast)
3630 if (!this->
visit(Stripped))
3632 if (!this->emitSetLocal(
SizeT, ArrayLen, E))
3635 if (PlacementDest) {
3636 if (!this->
visit(PlacementDest))
3638 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
3640 if (!this->emitCheckNewTypeMismatchArray(
SizeT, E, E))
3643 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
3648 if (!this->emitAllocN(
SizeT, *ElemT, E, IsNoThrow, E))
3652 if (!this->emitAllocCN(
SizeT, Desc, IsNoThrow, E))
3659 size_t StaticInitElems = 0;
3660 const Expr *DynamicInit =
nullptr;
3662 Ctx.getASTContext().getAsConstantArrayType(InitType)) {
3663 StaticInitElems = CAT->getZExtSize();
3667 if (
const auto *ILE = dyn_cast<InitListExpr>(
Init);
3668 ILE && ILE->hasArrayFiller())
3669 DynamicInit = ILE->getArrayFiller();
3683 const Function *CtorFunc =
nullptr;
3684 if (
const auto *CE = dyn_cast<CXXConstructExpr>(
Init)) {
3688 }
else if (!DynamicInit)
3691 LabelTy EndLabel = this->getLabel();
3692 LabelTy StartLabel = this->getLabel();
3697 if (!this->emitDupPtr(E))
3699 if (!this->emitNullPtr(0,
nullptr, E))
3701 if (!this->emitEQPtr(E))
3703 if (!this->jumpTrue(EndLabel))
3710 if (!this->emitConst(StaticInitElems,
SizeT, E))
3712 if (!this->emitSetLocal(
SizeT, Iter, E))
3715 this->fallthrough(StartLabel);
3716 this->emitLabel(StartLabel);
3718 if (!this->emitGetLocal(
SizeT, Iter, E))
3720 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
3722 if (!this->emitLT(
SizeT, E))
3724 if (!this->jumpFalse(EndLabel))
3728 if (!this->emitGetLocal(
SizeT, Iter, E))
3730 if (!this->emitArrayElemPtr(
SizeT, E))
3733 if (isa_and_nonnull<ImplicitValueInitExpr>(DynamicInit) &&
3738 if (!this->visitZeroInitializer(InitT, ElemType, E))
3740 if (!this->emitStorePop(InitT, E))
3742 }
else if (DynamicInit) {
3744 if (!this->
visit(DynamicInit))
3746 if (!this->emitStorePop(*InitT, E))
3751 if (!this->emitPopPtr(E))
3756 if (!this->emitCall(CtorFunc, 0, E))
3761 if (!this->emitGetPtrLocal(Iter, E))
3763 if (!this->emitIncPop(
SizeT,
false, E))
3766 if (!this->jump(StartLabel))
3769 this->fallthrough(EndLabel);
3770 this->emitLabel(EndLabel);
3774 if (PlacementDest) {
3775 if (!this->
visit(PlacementDest))
3777 if (!this->emitCheckNewTypeMismatch(E, E))
3782 if (!this->emitAlloc(Desc, E))
3791 if (!this->emitInit(*ElemT, E))
3802 return this->emitPopPtr(E);
3807template <
class Emitter>
3813 if (!OperatorDelete->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
3814 return this->emitInvalidNewDeleteExpr(E, E);
3817 if (!this->
visit(Arg))
3823template <
class Emitter>
3829 if (
const Function *F =
Ctx.getOrCreateObjCBlock(E))
3834 return this->emitGetFnPtr(
Func, E);
3837template <
class Emitter>
3841 auto canonType = [](
const Type *
T) {
3842 return T->getCanonicalTypeUnqualified().getTypePtr();
3850 return this->emitGetTypeid(
3854 return this->emitGetTypeid(
3863 if (!
Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(E))
3869 if (!this->emitGetTypeidPtr(TypeInfoType, E))
3872 return this->emitPopPtr(E);
3876template <
class Emitter>
3878 assert(
Ctx.getLangOpts().CPlusPlus);
3879 return this->emitConstBool(E->
getValue(), E);
3882template <
class Emitter>
3894 return this->emitDummyPtr(GuidDecl, E);
3899 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3908 assert(
V.isStruct());
3909 assert(
V.getStructNumBases() == 0);
3913 return this->emitFinishInit(E);
3916template <
class Emitter>
3926template <
class Emitter>
3935template <
class Emitter>
3941template <
class Emitter>
3945 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
3949 if (OVE->isUnique())
3965template <
class Emitter>
3970template <
class Emitter>
3972 return this->emitError(E);
3975template <
class Emitter>
3981 return this->emitDummyPtr(E, E);
3984template <
class Emitter>
3988 QualType ElemType = VT->getElementType();
3992 PrimType SrcElemT = classifyVectorElementType(SrcType);
3994 unsigned SrcOffset =
3996 if (!this->
visit(Src))
3998 if (!this->emitSetLocal(
PT_Ptr, SrcOffset, E))
4001 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
4002 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
4004 if (!this->emitArrayElemPop(SrcElemT, I, E))
4008 if (SrcElemT != ElemT) {
4009 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
4011 }
else if (ElemType->isFloatingType() && SrcType != ElemType) {
4012 const auto *TargetSemantics = &
Ctx.getFloatSemantics(ElemType);
4016 if (!this->emitInitElem(ElemT, I, E))
4023template <
class Emitter>
4027 return this->emitInvalid(E);
4037 assert(NumOutputElems > 0);
4040 unsigned VectorOffsets[2];
4041 for (
unsigned I = 0; I != 2; ++I) {
4044 if (!this->
visit(Vecs[I]))
4046 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I], E))
4049 for (
unsigned I = 0; I != NumOutputElems; ++I) {
4051 assert(ShuffleIndex >= -1);
4052 if (ShuffleIndex == -1)
4053 return this->emitInvalidShuffleVectorIndex(I, E);
4055 assert(ShuffleIndex < (NumInputElems * 2));
4056 if (!this->emitGetLocal(
PT_Ptr,
4057 VectorOffsets[ShuffleIndex >= NumInputElems], E))
4059 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
4060 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
4063 if (!this->emitInitElem(ElemT, I, E))
4070template <
class Emitter>
4075 Base->getType()->isVectorType() ||
4081 if (Indices.size() == 1) {
4086 if (!this->emitConstUint32(Indices[0], E))
4088 return this->emitArrayElemPtrPop(
PT_Uint32, E);
4098 if (!this->emitSetLocal(
PT_Ptr, BaseOffset, E))
4106 if (!this->emitGetPtrLocal(*ResultIndex, E))
4114 uint32_t DstIndex = 0;
4115 for (uint32_t I : Indices) {
4116 if (!this->emitGetLocal(
PT_Ptr, BaseOffset, E))
4118 if (!this->emitArrayElemPop(ElemT, I, E))
4120 if (!this->emitInitElem(ElemT, DstIndex, E))
4130template <
class Emitter>
4134 return this->
discard(SubExpr) && this->emitInvalid(E);
4140 return this->emitDummyPtr(E, E);
4143template <
class Emitter>
4148 Ctx.getASTContext().getAsConstantArrayType(SubExpr->
getType());
4153 if (!this->
visit(SubExpr))
4155 if (!this->emitConstUint8(0, E))
4157 if (!this->emitArrayElemPtrPopUint8(E))
4164 if (!this->emitConst(
ArrayType->getSize(), SecondFieldT, E))
4166 return this->emitInitField(SecondFieldT, R->
getField(1u)->
Offset, E);
4168 assert(SecondFieldT ==
PT_Ptr);
4172 if (!this->emitExpandPtr(E))
4176 if (!this->emitArrayElemPtrPop(
PT_Uint64, E))
4181template <
class Emitter>
4196 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
4198 return this->emitUnsupported(E);
4207 return this->
Visit(E);
4214 return this->
Visit(E);
4218 if (
const auto *PE = dyn_cast<ParenExpr>(E))
4221 if (
const auto *CE = dyn_cast<CastExpr>(E);
4223 (CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp))
4230 if (
const auto *PE = dyn_cast<ParenExpr>(E))
4233 if (
const auto *CE = dyn_cast<CastExpr>(E);
4234 CE && (CE->getCastKind() == CK_DerivedToBase ||
4235 CE->getCastKind() == CK_UncheckedDerivedToBase ||
4236 CE->getCastKind() == CK_NoOp))
4255 if (!this->emitGetPtrLocal(*LocalIndex, E))
4265 return this->
Visit(E);
4268template <
class Emitter>
4274 return this->
Visit(E);
4280 return this->
Visit(E);
4288 if (!this->
visit(E))
4290 return this->emitComplexBoolCast(E);
4295 if (!this->
visit(E))
4303 return this->emitIsNonNullPtr(E);
4307 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
4310 return this->emitCast(*
T,
PT_Bool, E);
4313template <
class Emitter>
4317 QT = AT->getValueType();
4321 return this->emitZeroBool(E);
4323 return this->emitZeroSint8(E);
4325 return this->emitZeroUint8(E);
4327 return this->emitZeroSint16(E);
4329 return this->emitZeroUint16(E);
4331 return this->emitZeroSint32(E);
4333 return this->emitZeroUint32(E);
4335 return this->emitZeroSint64(E);
4337 return this->emitZeroUint64(E);
4339 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
4341 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
4343 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
4346 return this->emitNullMemberPtr(0,
nullptr, E);
4348 APFloat F = APFloat::getZero(Ctx.getFloatSemantics(QT));
4349 return this->emitFloat(F, E);
4352 auto Sem = Ctx.getASTContext().getFixedPointSemantics(E->
getType());
4356 llvm_unreachable(
"unknown primitive type");
4359template <
class Emitter>
4360bool Compiler<Emitter>::visitZeroRecordInitializer(
const Record *R,
4365 for (
const Record::Field &Field : R->
fields()) {
4366 if (Field.isUnnamedBitField())
4373 if (!this->visitZeroInitializer(
T, QT, E))
4376 if (!this->emitInitFieldActivate(
T, Field.Offset, E))
4380 if (!this->emitInitField(
T, Field.Offset, E))
4385 if (!this->emitGetPtrField(Field.Offset, E))
4391 for (uint32_t I = 0, N = D->
getNumElems(); I != N; ++I) {
4392 if (!this->visitZeroInitializer(
T, ET, E))
4394 if (!this->emitInitElem(
T, I, E))
4399 if (!this->visitZeroArrayInitializer(D->
getType(), E))
4402 if (!this->visitZeroRecordInitializer(D->
ElemRecord, E))
4410 if (!this->emitFinishInitActivatePop(E))
4414 if (!this->emitFinishInitPop(E))
4418 for (
const Record::Base &B : R->
bases()) {
4419 if (!this->emitGetPtrBase(B.Offset, E))
4421 if (!this->visitZeroRecordInitializer(B.R, E))
4423 if (!this->emitFinishInitPop(E))
4432template <
class Emitter>
4433bool Compiler<Emitter>::visitZeroArrayInitializer(
QualType T,
const Expr *E) {
4434 assert(
T->isArrayType() ||
T->isAnyComplexType() ||
T->isVectorType());
4435 const ArrayType *AT =
T->getAsArrayTypeUnsafe();
4440 for (
size_t I = 0; I != NumElems; ++I) {
4441 if (!this->visitZeroInitializer(*ElemT, ElemType, E))
4443 if (!this->emitInitElem(*ElemT, I, E))
4449 const Record *R = getRecord(ElemType);
4451 for (
size_t I = 0; I != NumElems; ++I) {
4452 if (!this->emitConstUint32(I, E))
4454 if (!this->emitArrayElemPtr(
PT_Uint32, E))
4456 if (!this->visitZeroRecordInitializer(R, E))
4458 if (!this->emitPopPtr(E))
4464 for (
size_t I = 0; I != NumElems; ++I) {
4465 if (!this->emitConstUint32(I, E))
4467 if (!this->emitArrayElemPtr(
PT_Uint32, E))
4469 if (!this->visitZeroArrayInitializer(ElemType, E))
4471 if (!this->emitPopPtr(E))
4480template <
class Emitter>
4481bool Compiler<Emitter>::visitAssignment(
const Expr *LHS,
const Expr *RHS,
4483 if (!canClassify(E->
getType()))
4486 if (!this->visit(RHS))
4488 if (!this->visit(LHS))
4495 if (!Ctx.getLangOpts().CPlusPlus && !this->emitInvalid(E))
4499 bool Activates = refersToUnion(LHS);
4502 if (!this->emitFlip(
PT_Ptr, RHT, E))
4505 if (DiscardResult) {
4506 if (BitField && Activates)
4507 return this->emitStoreBitFieldActivatePop(RHT, E);
4509 return this->emitStoreBitFieldPop(RHT, E);
4511 return this->emitStoreActivatePop(RHT, E);
4513 return this->emitStorePop(RHT, E);
4516 auto maybeLoad = [&](
bool Result) ->
bool {
4522 return this->emitLoadPop(RHT, E);
4526 if (BitField && Activates)
4527 return maybeLoad(this->emitStoreBitFieldActivate(RHT, E));
4529 return maybeLoad(this->emitStoreBitField(RHT, E));
4531 return maybeLoad(this->emitStoreActivate(RHT, E));
4533 return maybeLoad(this->emitStore(RHT, E));
4536template <
class Emitter>
4537template <
typename T>
4541 return this->emitConstSint8(
Value, E);
4543 return this->emitConstUint8(
Value, E);
4545 return this->emitConstSint16(
Value, E);
4547 return this->emitConstUint16(
Value, E);
4549 return this->emitConstSint32(
Value, E);
4551 return this->emitConstUint32(
Value, E);
4553 return this->emitConstSint64(
Value, E);
4555 return this->emitConstUint64(
Value, E);
4557 return this->emitConstBool(
Value, E);
4564 llvm_unreachable(
"Invalid integral type");
4567 llvm_unreachable(
"unknown primitive type");
4570template <
class Emitter>
4571template <
typename T>
4572bool Compiler<Emitter>::emitConst(
T Value,
const Expr *E) {
4573 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
4576template <
class Emitter>
4580 return this->emitConstIntAPS(
Value, E);
4582 return this->emitConstIntAP(
Value, E);
4584 if (
Value.isSigned())
4585 return this->emitConst(
Value.getSExtValue(), Ty, E);
4586 return this->emitConst(
Value.getZExtValue(), Ty, E);
4589template <
class Emitter>
4593 return this->emitConstIntAPS(
Value, E);
4595 return this->emitConstIntAP(
Value, E);
4598 return this->emitConst(
Value.getSExtValue(), Ty, E);
4599 return this->emitConst(
Value.getZExtValue(), Ty, E);
4602template <
class Emitter>
4603bool Compiler<Emitter>::emitConst(
const APSInt &
Value,
const Expr *E) {
4604 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
4607template <
class Emitter>
4619 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
4620 Locals.insert({VD, Local});
4622 VarScope->addExtended(Local, ExtendingDecl);
4624 VarScope->addForScopeKind(Local, SC);
4625 return Local.Offset;
4628template <
class Emitter>
4632 bool IsConstexprUnknown) {
4635 bool IsTemporary =
false;
4636 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4639 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
4640 Init = VarD->getInit();
4642 if (
auto *E = Src.dyn_cast<
const Expr *>()) {
4650 IsTemporary,
false,
false,
Init);
4652 return std::nullopt;
4657 Locals.insert({Key, Local});
4659 VarScope->addExtended(Local, ExtendingDecl);
4661 VarScope->addForScopeKind(Local, SC);
4662 return Local.Offset;
4665template <
class Emitter>
4675 return std::nullopt;
4685 return Local.Offset;
4688template <
class Emitter>
4690 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
4691 return PT->getPointeeType()->getAsCanonical<RecordType>();
4697 return getRecord(RecordTy->getDecl()->getDefinitionOrSelf());
4701template <
class Emitter>
4703 return P.getOrCreateRecord(RD);
4706template <
class Emitter>
4708 return Ctx.getOrCreateFunction(FD);
4711template <
class Emitter>
4716 if (!DestroyToplevelScope) {
4717 if (!this->emitCheckAllocations(E))
4721 auto maybeDestroyLocals = [&]() ->
bool {
4722 if (DestroyToplevelScope)
4723 return RootScope.
destroyLocals() && this->emitCheckAllocations(E);
4724 return this->emitCheckAllocations(E);
4731 return this->emitRetVoid(E) && maybeDestroyLocals();
4739 return this->emitRet(*
T, E) && maybeDestroyLocals();
4747 if (!this->emitGetPtrLocal(*LocalOffset, E))
4753 if (!this->emitFinishInit(E))
4758 return this->emitRetValue(E) && maybeDestroyLocals();
4761 return maybeDestroyLocals() && this->emitCheckAllocations(E) &&
false;
4764template <
class Emitter>
4766 bool IsConstexprUnknown) {
4769 IsConstexprUnknown);
4778 if (
auto GlobalIndex =
P.getGlobal(VD)) {
4779 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
4794template <
class Emitter>
4796 bool ConstantContext) {
4799 if (!ConstantContext) {
4813 auto GlobalIndex =
P.getGlobal(VD);
4814 assert(GlobalIndex);
4816 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
4819 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
4823 auto Local =
Locals.find(VD);
4824 assert(Local !=
Locals.end());
4826 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
4829 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
4839 auto GlobalIndex =
P.getGlobal(VD);
4840 assert(GlobalIndex);
4841 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
4851 return VDScope.
destroyLocals() && this->emitCheckAllocations(VD);
4854template <
class Emitter>
4857 bool Toplevel,
bool IsConstexprUnknown) {
4864 if (!this->isActive())
4869 if (
Init &&
Init->isValueDependent())
4873 auto checkDecl = [&]() ->
bool {
4875 return !NeedsOp || this->emitCheckDecl(VD, VD);
4883 if (
P.getPtrGlobal(*GlobalIndex).isInitialized())
4887 }
else if ((GlobalIndex =
P.createGlobal(VD,
Init))) {
4901 return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
4904 if (!this->emitGetPtrGlobal(*GlobalIndex,
Init))
4910 return this->emitFinishInitGlobal(
Init);
4919 IsConstexprUnknown);
4930 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
4934 return this->emitSetLocal(*VarT, Offset, VD);
4942 if (!this->emitGetPtrLocal(*Offset,
Init))
4948 return this->emitFinishInitPop(
Init);
4953template <
class Emitter>
4958 return this->emitConst(Val.
getInt(), ValType, E);
4961 return this->emitFloat(F, E);
4966 return this->emitNull(ValType, 0,
nullptr, E);
4968 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
4969 return this->
visit(BaseExpr);
4974 return this->emitGetMemberPtr(MemberDecl, E);
4975 return this->emitNullMemberPtr(0,
nullptr, E);
4981template <
class Emitter>
4989 const Record::Field *RF = R->
getField(I);
4990 QualType FieldType = RF->Decl->getType();
4995 if (!this->emitInitField(*PT, RF->Offset, E))
4998 if (!this->emitGetPtrField(RF->Offset, E))
5002 if (!this->emitPopPtr(E))
5013 const Record::Field *RF = R->
getField(UnionField);
5017 return this->emitInitField(
T, RF->Offset, E);
5020 const auto *ArrType =
T->getAsArrayTypeUnsafe();
5021 QualType ElemType = ArrType->getElementType();
5022 for (
unsigned A = 0, AN = Val.
getArraySize(); A != AN; ++A) {
5027 if (!this->emitInitElem(*ElemT, A, E))
5030 if (!this->emitConstUint32(A, E))
5032 if (!this->emitArrayElemPtrUint32(E))
5036 if (!this->emitPopPtr(E))
5047template <
class Emitter>
5049 unsigned BuiltinID) {
5050 if (BuiltinID == Builtin::BI__builtin_constant_p) {
5055 return this->emitConst(0, E);
5058 if (!this->emitStartSpeculation(E))
5060 LabelTy EndLabel = this->getLabel();
5061 if (!this->speculate(E, EndLabel))
5063 this->fallthrough(EndLabel);
5064 if (!this->emitEndSpeculation(E))
5073 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
5074 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
5075 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
5076 BuiltinID == Builtin::BI__builtin_function_start) {
5079 return this->emitDummyPtr(E, E);
5090 if (!this->emitGetPtrLocal(*LocalIndex, E))
5095 switch (BuiltinID) {
5096 case Builtin::BI__builtin_object_size:
5097 case Builtin::BI__builtin_dynamic_object_size: {
5101 if (!this->
visit(Arg0))
5115 for (
const auto *Arg : E->
arguments()) {
5116 if (!this->
visit(Arg))
5122 if (!this->emitCallBI(E, BuiltinID, E))
5127 return this->emitPop(*ReturnT, E);
5133template <
class Emitter>
5150 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(FuncDecl);
5151 DD && DD->isTrivial()) {
5153 if (!this->
visit(MemberCall->getImplicitObjectArgument()))
5155 return this->emitCheckDestruction(E) && this->emitEndLifetime(E) &&
5156 this->emitPopPtr(E);
5172 if (!this->emitGetPtrLocal(*LocalIndex, E))
5180 if (!this->emitGetPtrLocal(*LocalIndex, E))
5184 if (!this->emitDupPtr(E))
5191 bool IsAssignmentOperatorCall =
false;
5192 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
5193 OCE && OCE->isAssignmentOp()) {
5197 assert(Args.size() == 2);
5198 IsAssignmentOperatorCall =
true;
5199 std::reverse(Args.begin(), Args.end());
5205 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
5206 MD && MD->isStatic()) {
5210 Args.erase(Args.begin());
5214 bool Devirtualized =
false;
5217 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
5225 if (!this->
visit(Callee))
5227 if (!this->emitSetLocal(
PT_MemberPtr, *CalleeOffset, E))
5229 if (!this->emitGetLocal(
PT_MemberPtr, *CalleeOffset, E))
5231 if (!this->emitGetMemberPtrBase(E))
5234 const auto *InstancePtr = MC->getImplicitObjectArgument();
5241 Stripped->getType()->getPointeeType()->getAsCXXRecordDecl());
5242 Devirtualized =
true;
5243 if (!this->
visit(Stripped))
5246 if (!this->
visit(InstancePtr))
5250 if (!this->
visit(InstancePtr))
5254 }
else if (
const auto *PD =
5255 dyn_cast<CXXPseudoDestructorExpr>(E->
getCallee())) {
5256 if (!this->emitCheckPseudoDtor(E))
5264 return this->emitEndLifetimePop(E);
5265 }
else if (!FuncDecl) {
5269 if (!this->
visit(Callee))
5271 if (!this->emitSetLocal(
PT_Ptr, *CalleeOffset, E))
5275 if (!this->
visitCallArgs(Args, FuncDecl, IsAssignmentOperatorCall,
5280 if (IsAssignmentOperatorCall) {
5281 assert(Args.size() == 2);
5284 if (!this->emitFlip(Arg2T, Arg1T, E))
5298 assert(HasRVO ==
Func->hasRVO());
5300 bool HasQualifier =
false;
5301 if (
const auto *ME = dyn_cast<MemberExpr>(E->
getCallee()))
5302 HasQualifier = ME->hasQualifier();
5304 bool IsVirtual =
false;
5305 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
5306 IsVirtual = !Devirtualized && MD->isVirtual();
5311 if (IsVirtual && !HasQualifier) {
5312 uint32_t VarArgSize = 0;
5313 unsigned NumParams =
5315 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
5318 if (!this->emitCallVirt(
Func, VarArgSize, E))
5320 }
else if (
Func->isVariadic()) {
5321 uint32_t VarArgSize = 0;
5322 unsigned NumParams =
5324 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
5326 if (!this->emitCallVar(
Func, VarArgSize, E))
5329 if (!this->emitCall(
Func, 0, E))
5338 uint32_t ArgSize = 0;
5339 for (
unsigned I = 0, N = E->
getNumArgs(); I != N; ++I)
5345 if (!this->emitGetLocal(
PT_MemberPtr, *CalleeOffset, E))
5347 if (!this->emitGetMemberPtrDecl(E))
5350 if (!this->emitGetLocal(
PT_Ptr, *CalleeOffset, E))
5353 if (!this->emitCallPtr(ArgSize, E, E))
5364template <
class Emitter>
5371template <
class Emitter>
5378template <
class Emitter>
5383 return this->emitConstBool(E->
getValue(), E);
5386template <
class Emitter>
5392 uint64_t Val =
Ctx.getASTContext().getTargetNullPointerValue(E->
getType());
5393 return this->emitNullPtr(Val,
nullptr, E);
5396template <
class Emitter>
5404 return this->emitZero(
T, E);
5407template <
class Emitter>
5412 if (this->LambdaThisCapture.Offset > 0) {
5413 if (this->LambdaThisCapture.IsPtr)
5414 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
5415 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
5423 return this->emitThis(E);
5438 unsigned StartIndex = 0;
5439 unsigned EndIndex = 0;
5441 for (StartIndex =
InitStack.size() - 1; StartIndex > 0; --StartIndex) {
5443 EndIndex = StartIndex;
5450 for (; StartIndex > 0; --StartIndex) {
5460 if (StartIndex == 0 && EndIndex == 0)
5463 assert(StartIndex < EndIndex);
5466 for (
unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
5478 case Stmt::CompoundStmtClass:
5480 case Stmt::DeclStmtClass:
5482 case Stmt::ReturnStmtClass:
5484 case Stmt::IfStmtClass:
5486 case Stmt::WhileStmtClass:
5488 case Stmt::DoStmtClass:
5490 case Stmt::ForStmtClass:
5492 case Stmt::CXXForRangeStmtClass:
5494 case Stmt::BreakStmtClass:
5496 case Stmt::ContinueStmtClass:
5498 case Stmt::SwitchStmtClass:
5500 case Stmt::CaseStmtClass:
5502 case Stmt::DefaultStmtClass:
5504 case Stmt::AttributedStmtClass:
5506 case Stmt::CXXTryStmtClass:
5508 case Stmt::NullStmtClass:
5511 case Stmt::GCCAsmStmtClass:
5512 case Stmt::MSAsmStmtClass:
5513 case Stmt::GotoStmtClass:
5514 return this->emitInvalid(S);
5515 case Stmt::LabelStmtClass:
5518 if (
const auto *E = dyn_cast<Expr>(S))
5525template <
class Emitter>
5528 for (
const auto *InnerStmt : S->
body())
5531 return Scope.destroyLocals();
5534template <
class Emitter>
5535bool Compiler<Emitter>::maybeEmitDeferredVarInit(
const VarDecl *VD) {
5536 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5537 for (
auto *BD : DD->flat_bindings())
5538 if (
auto *KD = BD->getHoldingVar();
5539 KD && !this->visitVarDecl(KD, KD->getInit()))
5548 const auto *CXXRD = dyn_cast<CXXRecordDecl>(FD->
getParent());
5549 return !CXXRD || CXXRD->hasTrivialDefaultConstructor();
5552template <
class Emitter>
bool Compiler<Emitter>::refersToUnion(
const Expr *E) {
5554 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
5555 if (
const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
5562 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
5567 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E);
5568 ICE && (ICE->getCastKind() == CK_NoOp ||
5569 ICE->getCastKind() == CK_DerivedToBase ||
5570 ICE->getCastKind() == CK_UncheckedDerivedToBase)) {
5571 E = ICE->getSubExpr();
5575 if (
const auto *
This = dyn_cast<CXXThisExpr>(E)) {
5576 const auto *ThisRecord =
5577 This->getType()->getPointeeType()->getAsRecordDecl();
5578 if (!ThisRecord->isUnion())
5581 if (
const auto *Ctor =
5582 dyn_cast_if_present<CXXConstructorDecl>(CompilingFunction))
5583 return Ctor->getParent() == ThisRecord;
5592template <
class Emitter>
5594 bool EvaluateConditionDecl) {
5595 for (
const auto *D : DS->
decls()) {
5600 const auto *VD = dyn_cast<VarDecl>(D);
5607 if (EvaluateConditionDecl && !this->maybeEmitDeferredVarInit(VD))
5614template <
class Emitter>
5617 return this->emitUnsupported(RS);
5623 if (!this->
visit(RE))
5629 if (RE->getType()->isVoidType()) {
5630 if (!this->
visit(RE))
5635 if (!this->emitRVOPtr(RE))
5639 if (!this->emitPopPtr(RE))
5643 return this->emitRetVoid(RS);
5649 return this->emitRetVoid(RS);
5653 auto visitChildStmt = [&](
const Stmt *S) ->
bool {
5659 if (
auto *CondInit = IS->
getInit())
5673 return visitChildStmt(IS->
getThen());
5675 return visitChildStmt(Else);
5681 if (!this->emitIsConstantContext(IS))
5684 if (!this->emitIsConstantContext(IS))
5686 if (!this->emitInv(IS))
5697 LabelTy LabelElse = this->getLabel();
5698 LabelTy LabelEnd = this->getLabel();
5699 if (!this->jumpFalse(LabelElse))
5701 if (!visitChildStmt(IS->
getThen()))
5703 if (!this->jump(LabelEnd))
5705 this->emitLabel(LabelElse);
5706 if (!visitChildStmt(Else))
5708 this->emitLabel(LabelEnd);
5710 LabelTy LabelEnd = this->getLabel();
5711 if (!this->jumpFalse(LabelEnd))
5713 if (!visitChildStmt(IS->
getThen()))
5715 this->emitLabel(LabelEnd);
5721template <
class Emitter>
5726 LabelTy CondLabel = this->getLabel();
5727 LabelTy EndLabel = this->getLabel();
5731 this->fallthrough(CondLabel);
5732 this->emitLabel(CondLabel);
5746 if (!this->jumpFalse(EndLabel))
5755 if (!this->jump(CondLabel))
5757 this->fallthrough(EndLabel);
5758 this->emitLabel(EndLabel);
5766 LabelTy StartLabel = this->getLabel();
5767 LabelTy EndLabel = this->getLabel();
5768 LabelTy CondLabel = this->getLabel();
5772 this->fallthrough(StartLabel);
5773 this->emitLabel(StartLabel);
5779 this->fallthrough(CondLabel);
5780 this->emitLabel(CondLabel);
5787 if (!this->jumpTrue(StartLabel))
5790 this->fallthrough(EndLabel);
5791 this->emitLabel(EndLabel);
5795template <
class Emitter>
5803 LabelTy EndLabel = this->getLabel();
5804 LabelTy CondLabel = this->getLabel();
5805 LabelTy IncLabel = this->getLabel();
5812 this->fallthrough(CondLabel);
5813 this->emitLabel(CondLabel);
5825 if (!this->jumpFalse(EndLabel))
5834 this->fallthrough(IncLabel);
5835 this->emitLabel(IncLabel);
5841 if (!this->jump(CondLabel))
5845 this->emitLabel(EndLabel);
5851template <
class Emitter>
5861 LabelTy EndLabel = this->getLabel();
5862 LabelTy CondLabel = this->getLabel();
5863 LabelTy IncLabel = this->getLabel();
5878 this->fallthrough(CondLabel);
5879 this->emitLabel(CondLabel);
5882 if (!this->jumpFalse(EndLabel))
5893 this->fallthrough(IncLabel);
5894 this->emitLabel(IncLabel);
5899 if (!this->jump(CondLabel))
5902 this->fallthrough(EndLabel);
5903 this->emitLabel(EndLabel);
5907template <
class Emitter>
5918 if (LI.BreakLabel) {
5919 TargetLabel = *LI.BreakLabel;
5920 BreakScope = LI.BreakOrContinueScope;
5926 if (LI.Name == TargetLoop) {
5927 TargetLabel = *LI.BreakLabel;
5928 BreakScope = LI.BreakOrContinueScope;
5934 assert(TargetLabel);
5938 C->emitDestruction();
5940 return this->jump(*TargetLabel);
5943template <
class Emitter>
5954 if (LI.ContinueLabel) {
5955 TargetLabel = *LI.ContinueLabel;
5956 ContinueScope = LI.BreakOrContinueScope;
5962 if (LI.Name == TargetLoop) {
5963 TargetLabel = *LI.ContinueLabel;
5964 ContinueScope = LI.BreakOrContinueScope;
5969 assert(TargetLabel);
5973 C->emitDestruction();
5975 return this->jump(*TargetLabel);
5978template <
class Emitter>
5981 if (
Cond->containsErrors())
5987 LabelTy EndLabel = this->getLabel();
5992 if (
const auto *CondInit = S->
getInit())
6003 if (!this->emitSetLocal(CondT, CondVar, S))
6013 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
6015 if (CS->caseStmtIsGNURange())
6020 if (
Value->isValueDependent())
6025 if (!this->emitGetLocal(CondT, CondVar, CS))
6031 if (!this->emitEQ(ValueT, S))
6036 assert(!DefaultLabel);
6037 DefaultLabel = this->getLabel();
6044 if (!this->jump(*DefaultLabel))
6047 if (!this->jump(EndLabel))
6055 this->emitLabel(EndLabel);
6060template <
class Emitter>
6066template <
class Emitter>
6073 if (LI.DefaultLabel) {
6074 DefaultLabel = *LI.DefaultLabel;
6079 this->emitLabel(DefaultLabel);
6083template <
class Emitter>
6085 if (this->
Ctx.getLangOpts().CXXAssumptions &&
6086 !this->Ctx.getLangOpts().MSVCCompat) {
6088 auto *AA = dyn_cast<CXXAssumeAttr>(A);
6094 const Expr *Assumption = AA->getAssumption();
6105 if (!this->emitAssume(Assumption))
6114template <
class Emitter>
6120template <
class Emitter>
6121bool Compiler<Emitter>::emitLambdaStaticInvokerBody(
const CXXMethodDecl *MD) {
6128 assert(ClosureClass->
captures().empty());
6132 "A generic lambda's static-invoker function must be a "
6133 "template specialization");
6137 void *InsertPos =
nullptr;
6138 const FunctionDecl *CorrespondingCallOpSpecialization =
6140 assert(CorrespondingCallOpSpecialization);
6141 LambdaCallOp = CorrespondingCallOpSpecialization;
6145 assert(ClosureClass->
captures().empty());
6146 const Function *
Func = this->getFunction(LambdaCallOp);
6149 assert(
Func->hasThisPointer());
6152 if (
Func->hasRVO()) {
6153 if (!this->emitRVOPtr(MD))
6161 if (!this->emitNullPtr(0,
nullptr, MD))
6166 auto It = this->Params.find(PVD);
6167 assert(It != this->Params.end());
6171 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
6172 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
6176 if (!this->emitCall(
Func, 0, LambdaCallOp))
6181 return this->emitRet(*ReturnType, MD);
6184 return this->emitRetVoid(MD);
6187template <
class Emitter>
6188bool Compiler<Emitter>::checkLiteralType(
const Expr *E) {
6189 if (Ctx.getLangOpts().CPlusPlus23)
6199 const Expr *InitExpr =
Init->getInit();
6201 if (!
Init->isWritten() && !
Init->isInClassMemberInitializer() &&
6205 if (
const auto *CE = dyn_cast<CXXConstructExpr>(InitExpr)) {
6215template <
class Emitter>
6217 assert(!ReturnType);
6219 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
6220 const Expr *InitExpr,
6223 if (InitExpr->getType().isNull())
6227 if (
Activate && !this->emitActivateThisField(FieldOffset, InitExpr))
6230 if (!this->visit(InitExpr))
6233 bool BitField = F->isBitField();
6235 return this->emitInitThisBitField(*
T, F, FieldOffset, InitExpr);
6236 return this->emitInitThisField(*
T, FieldOffset, InitExpr);
6241 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
6244 if (
Activate && !this->emitActivate(InitExpr))
6247 if (!this->visitInitializer(InitExpr))
6250 return this->emitFinishInitPop(InitExpr);
6254 const Record *R = this->getRecord(RD);
6263 return this->emitRetVoid(Ctor);
6266 if (!this->emitThis(Ctor))
6275 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
6276 this->emitRetVoid(Ctor);
6280 for (
const auto *
Init : Ctor->
inits()) {
6282 LocalScope<Emitter>
Scope(
this);
6284 const Expr *InitExpr =
Init->getInit();
6290 if (!emitFieldInitializer(F, F->Offset, InitExpr, IsUnion))
6293 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
6296 if (
Init->isBaseVirtual()) {
6298 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
6304 const Record::Base *B = R->
getBase(BaseDecl);
6306 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
6310 if (IsUnion && !this->emitActivate(InitExpr))
6313 if (!this->visitInitializer(InitExpr))
6315 if (!this->emitFinishInitPop(InitExpr))
6320 assert(IFD->getChainingSize() >= 2);
6322 unsigned NestedFieldOffset = 0;
6323 const Record::Field *NestedField =
nullptr;
6324 for (
const NamedDecl *ND : IFD->chain()) {
6326 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
6327 assert(FieldRecord);
6329 NestedField = FieldRecord->
getField(FD);
6330 assert(NestedField);
6331 IsUnion = IsUnion || FieldRecord->
isUnion();
6333 NestedFieldOffset += NestedField->Offset;
6335 assert(NestedField);
6337 unsigned FirstLinkOffset =
6341 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
6346 unsigned InitFieldOffset = 0;
6347 for (
const NamedDecl *ND : IFD->chain().drop_back()) {
6349 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
6350 assert(FieldRecord);
6351 NestedField = FieldRecord->
getField(FD);
6352 InitFieldOffset += NestedField->Offset;
6353 assert(NestedField);
6354 if (!this->emitGetPtrThisField(InitFieldOffset, InitExpr))
6356 if (!this->emitFinishInitPop(InitExpr))
6361 assert(
Init->isDelegatingInitializer());
6362 if (!this->emitThis(InitExpr))
6364 if (!this->visitInitializer(
Init->getInit()))
6366 if (!this->emitPopPtr(InitExpr))
6370 if (!
Scope.destroyLocals())
6374 if (
const auto *Body = Ctor->
getBody())
6375 if (!visitStmt(Body))
6381template <
class Emitter>
6384 const Record *R = this->getRecord(RD);
6389 if (!this->visitStmt(Dtor->
getBody()))
6393 if (!this->emitThis(Dtor))
6396 if (!this->emitCheckDestruction(Dtor))
6404 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
6408 if (!this->emitGetPtrField(Field.Offset,
SourceInfo{}))
6410 if (!this->emitDestructionPop(D,
SourceInfo{}))
6415 for (
const Record::Base &
Base : llvm::reverse(R->
bases())) {
6416 if (
Base.R->hasTrivialDtor())
6420 if (!this->emitRecordDestructionPop(
Base.R, {}))
6425 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
6428template <
class Emitter>
6429bool Compiler<Emitter>::compileUnionAssignmentOperator(
6431 if (!this->emitThis(MD))
6440 return this->emitMemcpy(MD) && this->emitRet(
PT_Ptr, MD);
6443template <
class Emitter>
6450 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
6451 return this->compileConstructor(Ctor);
6452 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
6453 return this->compileDestructor(Dtor);
6456 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
6461 return this->compileUnionAssignmentOperator(MD);
6464 return this->emitLambdaStaticInvokerBody(MD);
6468 if (
const auto *Body = F->
getBody())
6482 return FD->getBitWidthValue();
6485template <
class Emitter>
6498 if (!
Ctx.getLangOpts().CPlusPlus14)
6499 return this->emitInvalid(E);
6501 return this->emitError(E);
6503 if (!this->
visit(SubExpr))
6507 if (!this->emitIncPtr(E))
6514 return DiscardResult ? this->emitIncfPop(getFPOptions(E), E)
6515 : this->emitIncf(getFPOptions(E), E);
6527 if (!
Ctx.getLangOpts().CPlusPlus14)
6528 return this->emitInvalid(E);
6530 return this->emitError(E);
6532 if (!this->
visit(SubExpr))
6536 if (!this->emitDecPtr(E))
6543 return DiscardResult ? this->emitDecfPop(getFPOptions(E), E)
6544 : this->emitDecf(getFPOptions(E), E);
6557 if (!
Ctx.getLangOpts().CPlusPlus14)
6558 return this->emitInvalid(E);
6560 return this->emitError(E);
6562 if (!this->
visit(SubExpr))
6566 if (!this->emitLoadPtr(E))
6568 if (!this->emitConstUint8(1, E))
6570 if (!this->emitAddOffsetUint8(E))
6572 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
6578 return this->emitIncfPop(getFPOptions(E), E);
6588 const auto &TargetSemantics =
Ctx.getFloatSemantics(E->
getType());
6589 if (!this->emitLoadFloat(E))
6591 APFloat F(TargetSemantics, 1);
6592 if (!this->emitFloat(F, E))
6595 if (!this->emitAddf(getFPOptions(E), E))
6597 if (!this->emitStoreFloat(E))
6609 return E->
isGLValue() || this->emitLoadPop(*
T, E);
6612 if (!
Ctx.getLangOpts().CPlusPlus14)
6613 return this->emitInvalid(E);
6615 return this->emitError(E);
6617 if (!this->
visit(SubExpr))
6621 if (!this->emitLoadPtr(E))
6623 if (!this->emitConstUint8(1, E))
6625 if (!this->emitSubOffsetUint8(E))
6627 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
6633 return this->emitDecfPop(getFPOptions(E), E);
6643 const auto &TargetSemantics =
Ctx.getFloatSemantics(E->
getType());
6644 if (!this->emitLoadFloat(E))
6646 APFloat F(TargetSemantics, 1);
6647 if (!this->emitFloat(F, E))
6650 if (!this->emitSubf(getFPOptions(E), E))
6652 if (!this->emitStoreFloat(E))
6664 return E->
isGLValue() || this->emitLoadPop(*
T, E);
6668 return this->emitError(E);
6671 return this->
discard(SubExpr);
6676 if (!this->emitInv(E))
6680 return this->emitCast(
PT_Bool, ET, E);
6684 return this->emitError(E);
6686 if (!this->
visit(SubExpr))
6691 return this->emitError(E);
6693 if (!this->
visit(SubExpr))
6706 return this->
discard(SubExpr);
6708 if (!this->
visit(SubExpr))
6715 return this->emitNarrowPtr(E);
6720 return this->emitError(E);
6722 if (!this->
visit(SubExpr))
6732 return this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
6737 assert(
false &&
"Unhandled opcode");
6743template <
class Emitter>
6749 return this->
discard(SubExpr);
6752 auto prepareResult = [=]() ->
bool {
6757 return this->emitGetPtrLocal(*LocalIndex, E);
6764 unsigned SubExprOffset = ~0u;
6765 auto createTemp = [=, &SubExprOffset]() ->
bool {
6768 if (!this->
visit(SubExpr))
6770 return this->emitSetLocal(
PT_Ptr, SubExprOffset, E);
6774 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
6775 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
6777 return this->emitArrayElemPop(ElemT, Index, E);
6782 if (!prepareResult())
6786 for (
unsigned I = 0; I != 2; ++I) {
6787 if (!getElem(SubExprOffset, I))
6789 if (!this->emitNeg(ElemT, E))
6791 if (!this->emitInitElem(ElemT, I, E))
6802 if (!this->
visit(SubExpr))
6804 if (!this->emitComplexBoolCast(SubExpr))
6806 if (!this->emitInv(E))
6809 return this->emitCast(
PT_Bool, ET, E);
6813 return this->emitComplexReal(SubExpr);
6816 if (!this->
visit(SubExpr))
6820 if (!this->emitConstUint8(1, E))
6822 return this->emitArrayElemPtrPopUint8(E);
6830 if (!this->
visit(SubExpr))
6833 if (!this->emitArrayElem(ElemT, 1, E))
6835 if (!this->emitNeg(ElemT, E))
6837 if (!this->emitInitElem(ElemT, 1, E))
6845 return this->emitInvalid(E);
6851template <
class Emitter>
6857 return this->
discard(SubExpr);
6860 if (UnaryOp == UO_Extension)
6863 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
6864 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
6865 return this->emitInvalid(E);
6868 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
6875 if (!this->emitGetPtrLocal(*LocalIndex, E))
6880 unsigned SubExprOffset =
6882 if (!this->
visit(SubExpr))
6884 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, E))
6889 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
6890 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
6892 return this->emitArrayElemPop(ElemT, Index, E);
6897 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6898 if (!getElem(SubExprOffset, I))
6900 if (!this->emitNeg(ElemT, E))
6902 if (!this->emitInitElem(ElemT, I, E))
6917 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6918 if (!getElem(SubExprOffset, I))
6921 if (!this->emitPrimCast(ElemT,
PT_Bool,
Ctx.getASTContext().BoolTy, E))
6923 if (!this->emitInv(E))
6925 if (!this->emitPrimCast(
PT_Bool, ElemT, VecTy->getElementType(), E))
6927 if (!this->emitNeg(ElemT, E))
6929 if (ElemT != ResultVecElemT &&
6930 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy, E))
6932 if (!this->emitInitElem(ResultVecElemT, I, E))
6938 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
6939 if (!getElem(SubExprOffset, I))
6942 if (!this->emitInv(E))
6945 if (!this->emitComp(ElemT, E))
6948 if (!this->emitInitElem(ElemT, I, E))
6953 llvm_unreachable(
"Unsupported unary operators should be handled up front");
6958template <
class Emitter>
6963 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(D))
6964 return this->emitConst(ECD->getInitVal(), E);
6965 if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
6967 return F && this->emitGetFnPtr(F, E);
6969 if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
6971 if (!this->emitGetPtrGlobal(*Index, E))
6976 return this->emitInitGlobal(*
T, *Index, E);
6993 if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
6994 if (
Ctx.getLangOpts().CPlusPlus && !
Ctx.getLangOpts().CPlusPlus11 &&
6999 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
7000 if (IsReference || !It->second.IsPtr)
7001 return this->emitGetParam(
classifyPrim(E), It->second.Offset, E);
7003 return this->emitGetPtrParam(It->second.Offset, E);
7008 const unsigned Offset = It->second.Offset;
7011 return this->emitGetPtrLocal(Offset, E);
7014 if (
auto GlobalIndex =
P.getGlobal(D)) {
7016 if (!
Ctx.getLangOpts().CPlusPlus11)
7017 return this->emitGetGlobal(
classifyPrim(E), *GlobalIndex, E);
7018 return this->emitGetGlobalUnchecked(
classifyPrim(E), *GlobalIndex, E);
7021 return this->emitGetPtrGlobal(*GlobalIndex, E);
7025 auto revisit = [&](
const VarDecl *VD) ->
bool {
7028 auto VarState = this->
visitDecl(VD,
true);
7030 if (!this->emitPopCC(E))
7033 if (VarState.notCreated())
7042 if (
auto It = this->LambdaCaptures.find(D);
7043 It != this->LambdaCaptures.end()) {
7044 auto [Offset, IsPtr] = It->second;
7047 return this->emitGetThisFieldPtr(Offset, E);
7048 return this->emitGetPtrThisField(Offset, E);
7051 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E);
7052 DRE && DRE->refersToEnclosingVariableOrCapture()) {
7053 if (
const auto *VD = dyn_cast<VarDecl>(D); VD && VD->
isInitCapture())
7057 if (
const auto *BD = dyn_cast<BindingDecl>(D))
7058 return this->
visit(BD->getBinding());
7062 return this->emitDummyPtr(D, E);
7067 if (!
Ctx.getLangOpts().CPlusPlus) {
7068 if (
const auto *VD = dyn_cast<VarDecl>(D);
7072 return this->emitDummyPtr(D, E);
7076 const auto *VD = dyn_cast<VarDecl>(D);
7078 return this->emitDummyPtr(D, E);
7080 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
7081 if (
T.isConstant(
Ctx.getASTContext()))
7083 return T->isReferenceType();
7087 typeShouldBeVisited(VD->
getType())) {
7089 Init && !
Init->isValueDependent()) {
7095 (void)
Init->EvaluateAsInitializer(
V,
Ctx.getASTContext(), VD, Notes,
7113 return this->emitDummyPtr(D, E);
7119 return this->emitDummyPtr(D, E);
7122template <
class Emitter>
7130 C->emitDestruction();
7133template <
class Emitter>
7134unsigned Compiler<Emitter>::collectBaseOffset(
const QualType BaseType,
7137 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
7139 return Ty->getAsCXXRecordDecl();
7141 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
7142 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
7144 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
7148template <
class Emitter>
7155 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
7160 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
7161 getFPOptions(E), E);
7163 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
7164 getFPOptions(E), E);
7168 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
7173 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
7175 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
7179 return FromT != ToT ? this->emitCast(FromT, ToT, E) :
true;
7183 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
7184 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E);
7192template <
class Emitter>
7193bool Compiler<Emitter>::emitComplexReal(
const Expr *SubExpr) {
7197 return this->
discard(SubExpr);
7199 if (!this->visit(SubExpr))
7202 if (!this->emitConstUint8(0, SubExpr))
7204 return this->emitArrayElemPtrPopUint8(SubExpr);
7208 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
7212template <
class Emitter>
7213bool Compiler<Emitter>::emitComplexBoolCast(
const Expr *E) {
7214 assert(!DiscardResult);
7218 if (!this->emitArrayElem(ElemT, 0, E))
7221 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(E), E))
7224 if (!this->emitCast(ElemT,
PT_Bool, E))
7229 LabelTy LabelTrue = this->getLabel();
7230 if (!this->jumpTrue(LabelTrue))
7233 if (!this->emitArrayElemPop(ElemT, 1, E))
7236 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(E), E))
7239 if (!this->emitCast(ElemT,
PT_Bool, E))
7243 LabelTy EndLabel = this->getLabel();
7244 this->jump(EndLabel);
7246 this->emitLabel(LabelTrue);
7247 if (!this->emitPopPtr(E))
7249 if (!this->emitConstBool(
true, E))
7252 this->fallthrough(EndLabel);
7253 this->emitLabel(EndLabel);
7258template <
class Emitter>
7259bool Compiler<Emitter>::emitComplexComparison(
const Expr *LHS,
const Expr *RHS,
7263 assert(!DiscardResult);
7269 LHSIsComplex =
true;
7270 ElemT = classifyComplexElementType(LHS->
getType());
7271 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true);
7272 if (!this->visit(LHS))
7274 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
7277 LHSIsComplex =
false;
7279 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true);
7280 if (!this->visit(LHS))
7282 if (!this->emitSetLocal(LHST, LHSOffset, E))
7289 RHSIsComplex =
true;
7290 ElemT = classifyComplexElementType(RHS->
getType());
7291 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true);
7292 if (!this->visit(RHS))
7294 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
7297 RHSIsComplex =
false;
7299 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true);
7300 if (!this->visit(RHS))
7302 if (!this->emitSetLocal(RHST, RHSOffset, E))
7306 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
7307 bool IsComplex) ->
bool {
7309 if (!this->emitGetLocal(
PT_Ptr, LocalOffset, E))
7311 return this->emitArrayElemPop(ElemT, Index, E);
7313 return this->emitGetLocal(ElemT, LocalOffset, E);
7316 for (
unsigned I = 0; I != 2; ++I) {
7318 if (!getElem(LHSOffset, I, LHSIsComplex))
7320 if (!getElem(RHSOffset, I, RHSIsComplex))
7323 if (!this->emitEQ(ElemT, E))
7326 if (!this->emitCastBoolUint8(E))
7331 if (!this->emitAddUint8(E))
7333 if (!this->emitConstUint8(2, E))
7337 if (!this->emitEQUint8(E))
7340 if (!this->emitNEUint8(E))
7347 return this->emitCast(
PT_Bool, ResT, E);
7354template <
class Emitter>
7355bool Compiler<Emitter>::emitRecordDestructionPop(
const Record *R,
7361 const Function *DtorFunc = getFunction(Dtor);
7364 assert(DtorFunc->hasThisPointer());
7365 assert(DtorFunc->getNumParams() == 1);
7366 return this->emitCall(DtorFunc, 0, Loc);
7371template <
class Emitter>
7372bool Compiler<Emitter>::emitDestructionPop(
const Descriptor *Desc,
7384 return this->emitPopPtr(Loc);
7386 for (ssize_t I = N - 1; I >= 1; --I) {
7387 if (!this->emitConstUint64(I, Loc))
7389 if (!this->emitArrayElemPtrUint64(Loc))
7391 if (!this->emitDestructionPop(ElemDesc, Loc))
7395 if (!this->emitConstUint64(0, Loc))
7397 if (!this->emitArrayElemPtrPopUint64(Loc))
7399 return this->emitDestructionPop(ElemDesc, Loc);
7404 return this->emitRecordDestructionPop(Desc->
ElemRecord, Loc);
7409template <
class Emitter>
7410bool Compiler<Emitter>::emitDummyPtr(
const DeclTy &D,
const Expr *E) {
7411 assert(!DiscardResult &&
"Should've been checked before");
7413 unsigned DummyID = P.getOrCreateDummy(D);
7415 if (!this->emitGetPtrGlobal(DummyID, E))
7423 return this->emitDecayPtr(
PT_Ptr, PT, E);
7429template <
class Emitter>
7430bool Compiler<Emitter>::emitFloat(
const APFloat &F,
const Expr *E) {
7431 assert(!DiscardResult &&
"Should've been checked before");
7434 return this->emitConstFloat(
Floating(F), E);
7436 APInt I = F.bitcastToAPInt();
7437 return this->emitConstFloat(
7438 Floating(
const_cast<uint64_t *
>(I.getRawData()),
7439 llvm::APFloatBase::SemanticsToEnum(F.getSemantics())),
7450template <
class Emitter>
7451bool Compiler<Emitter>::emitBuiltinBitCast(
const CastExpr *E) {
7464 if (!this->emitGetPtrLocal(*LocalIndex, E))
7474 if (!this->visit(SubExpr))
7476 }
else if (
OptPrimType FromT = classify(SubExpr)) {
7477 unsigned TempOffset =
7478 allocateLocalPrimitive(SubExpr, *FromT,
true);
7479 if (!this->visit(SubExpr))
7481 if (!this->emitSetLocal(*FromT, TempOffset, E))
7483 if (!this->emitGetPtrLocal(TempOffset, E))
7490 if (!this->emitBitCast(E))
7492 return DiscardResult ? this->emitPopPtr(E) :
true;
7496 const llvm::fltSemantics *TargetSemantics =
nullptr;
7498 TargetSemantics = &Ctx.getFloatSemantics(ToType);
7504 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
7506 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->
isStdByteType(),
7507 ResultBitWidth, TargetSemantics,
7512 return this->emitPop(*ToT, 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, EHScopeStack::Cleanup *cleanup)
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)
a trap message and trap category.
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
ArrayRef< LValuePathEntry > getLValuePath() const
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
unsigned getStructNumFields() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
bool isMemberPointer() const
unsigned getArraySize() const
@ None
There is no such object (it's outside its lifetime).
bool isNullPointer() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
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 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...
CastKind getCastKind() const
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
CharUnits - This is an opaque type for sizes expressed in character units.
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
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
DoStmt - This represents a 'do/while' stmt.
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.
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...
const Expr * getBase() const
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()
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.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a C++ namespace alias.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
bool isExpressibleAsConstantInitializer() const
ObjCEncodeExpr, used for @encode in Objective-C.
QualType getEncodedType() const
SourceLocation getAtLoc() 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
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool isMemberPointerType() const
bool isAtomicType() const
EnumDecl * castAsEnumDecl() const
bool isStdByteType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isPointerOrReferenceType() const
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
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 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.
std::byte * rawData()
Returns a pointer to the raw data, including metadata.
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.
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E)
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
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)
VarCreationState visitDecl(const VarDecl *VD, bool IsConstexprUnknown=false)
bool visitAPValueInitializer(const APValue &Val, const Expr *E, QualType T)
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
bool VisitCallExpr(const CallExpr *E)
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.
void emitCleanup()
Emits scope cleanup instructions.
bool VisitFixedPointBinOp(const BinaryOperator *E)
bool VisitCastExpr(const CastExpr *E)
bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E)
bool VisitFixedPointUnaryOperator(const UnaryOperator *E)
bool VisitComplexUnaryOperator(const UnaryOperator *E)
llvm::DenseMap< const SwitchCase *, LabelTy > CaseMap
bool VisitBlockExpr(const BlockExpr *E)
bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E)
Visit an APValue.
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
bool VisitLogicalBinOp(const BinaryOperator *E)
bool visitCompoundStmt(const CompoundStmt *S)
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)
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 discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
CaseMap CaseLabels
Switch case mapping.
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
const RecordType * getRecordTy(QualType Ty)
Returns a record type from a record or pointer type.
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E)
bool visitInitList(ArrayRef< const Expr * > Inits, const Expr *ArrayFiller, const Expr *E)
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E)
bool VisitPredefinedExpr(const PredefinedExpr *E)
bool VisitSourceLocExpr(const SourceLocExpr *E)
bool visitDeclStmt(const DeclStmt *DS, bool EvaluateConditionDecl=false)
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E)
bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E)
bool visitInitializer(const Expr *E)
Compiles an initializer.
const Expr * SourceLocDefaultExpr
DefaultInit- or DefaultArgExpr, needed for SourceLocExpr.
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)
typename Emitter::LabelTy LabelTy
bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E)
bool visitStmt(const Stmt *S)
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
bool VisitVectorUnaryOperator(const UnaryOperator *E)
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
VarCreationState visitVarDecl(const VarDecl *VD, const Expr *Init, bool Toplevel=false, bool IsConstexprUnknown=false)
Creates and initializes a variable from the given decl.
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)
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsVolatile=false, const ValueDecl *ExtendingDecl=nullptr, ScopeKind SC=ScopeKind::Block, bool IsConstexprUnknown=false)
Creates a local primitive value.
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)
UnsignedOrNone allocateLocal(DeclTy &&Decl, QualType Ty=QualType(), const ValueDecl *ExtendingDecl=nullptr, ScopeKind=ScopeKind::Block, bool IsConstexprUnknown=false)
Allocates a space storing a local given its type.
bool VisitVectorBinOp(const BinaryOperator *E)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
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 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 CXXDestructorDecl * getDestructor() const
Returns the destructor of the record, if any.
const Field * getField(const FieldDecl *FD) const
Returns a field.
bool hasTrivialDtor() const
Returns true for anonymous unions and records with no destructor or for those with a trivial destruct...
llvm::iterator_range< const_base_iter > bases() const
const Base * getVirtualBase(const RecordDecl *RD) const
Returns a virtual base descriptor.
unsigned getNumFields() const
llvm::iterator_range< const_field_iter > fields() const
const Base * getBase(const RecordDecl *FD) const
Returns a base descriptor.
Describes the statement/declaration an opcode was generated from.
StmtExprScope(Compiler< Emitter > *Ctx)
typename Compiler< Emitter >::LabelTy LabelTy
typename Compiler< Emitter >::OptLabelTy OptLabelTy
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(const 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)
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)
constexpr bool isIntegralType(PrimType T)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Success
Annotation was successful.
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
@ SD_Static
Static storage duration.
@ Result
The result type of a method or function.
const FunctionProtoType * T
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.
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)
bool isUnnamedBitField() const
Information about a local's storage.
State encapsulating if a the variable creation has been successful, unsuccessful, or no variable has ...
static VarCreationState NotCreated()