21#include "llvm/Support/SaveAndRestore.h"
32 if (
const auto *CE = dyn_cast_if_present<ConstantExpr>(E);
33 CE && CE->hasAPValueResult() &&
35 return CE->getResultAsAPSInt().getBoolValue();
67 llvm_unreachable(
"Shouldn't be called");
133 this->
Ctx->emitDestroy(*
Idx, E);
140 Idx =
static_cast<unsigned>(this->
Ctx->Descriptors.size());
141 this->
Ctx->Descriptors.emplace_back();
142 this->
Ctx->emitInitScope(*
Idx, {});
146 this->
Ctx->Descriptors[*
Idx].emplace_back(Local);
156 Idx =
static_cast<unsigned>(this->
Ctx->Descriptors.size());
157 this->
Ctx->Descriptors.emplace_back();
158 this->
Ctx->emitInitScope(*
Idx, {});
169 if (Local.Desc->hasTrivialDtor())
172 if (!Local.EnabledByDefault) {
173 typename Emitter::LabelTy EndLabel = this->
Ctx->getLabel();
174 if (!this->
Ctx->emitGetLocalEnabled(Local.Offset, E))
176 if (!this->
Ctx->jumpFalse(EndLabel, E))
179 if (!this->
Ctx->emitGetPtrLocal(Local.Offset, E))
182 if (!this->
Ctx->emitDestructionPop(Local.Desc, Local.Desc->getLoc()))
185 this->
Ctx->fallthrough(EndLabel);
186 this->
Ctx->emitLabel(EndLabel);
188 if (!this->
Ctx->emitGetPtrLocal(Local.Offset, E))
190 if (!this->
Ctx->emitDestructionPop(Local.Desc, Local.Desc->getLoc()))
209 if (
const auto *OVE =
210 llvm::dyn_cast_if_present<OpaqueValueExpr>(Local.Desc->asExpr())) {
211 this->
Ctx->OpaqueExprs.erase(OVE);
223 OldArrayIndex = Ctx->ArrayIndex;
224 Ctx->ArrayIndex = Index;
231 std::optional<uint64_t> OldArrayIndex;
239 if (!Ctx->SourceLocDefaultExpr) {
241 Ctx->SourceLocDefaultExpr = DefaultExpr;
247 Ctx->SourceLocDefaultExpr =
nullptr;
252 bool Enabled =
false;
258 Ctx->InitStack.push_back(std::move(
Link));
270 : Ctx(Ctx), OldValue(Ctx->InitStackActive), Active(Active) {
271 Ctx->InitStackActive = Active;
277 this->Ctx->InitStackActive = OldValue;
279 Ctx->InitStack.pop_back();
293 OldInitializingDecl(
Ctx->InitializingDecl) {
294 Ctx->InitializingDecl = VD;
299 this->
Ctx->InitializingDecl = OldInitializingDecl;
300 this->
Ctx->InitStack.pop_back();
305 const VarDecl *OldInitializingDecl;
313 bool NewInitializing,
bool NewToLValue)
314 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
315 OldInitializing(Ctx->
Initializing), OldToLValue(Ctx->ToLValue) {
316 Ctx->DiscardResult = NewDiscardResult;
317 Ctx->Initializing = NewInitializing;
318 Ctx->ToLValue = NewToLValue;
322 Ctx->DiscardResult = OldDiscardResult;
323 Ctx->Initializing = OldInitializing;
324 Ctx->ToLValue = OldToLValue;
331 bool OldDiscardResult;
332 bool OldInitializing;
336template <
class Emitter>
340 return Ctx->emitThis(E);
343 return Ctx->emitGetPtrFieldPop(
Offset, E);
345 return Ctx->emitGetPtrBasePop(
Offset,
false, E);
347 return Ctx->emitGetPtrLocal(
Offset, E);
351 if (!Ctx->emitConstUint32(
Offset, E))
353 return Ctx->emitArrayElemPtrPopUint32(E);
355 return Ctx->emitRVOPtr(E);
359 llvm_unreachable(
"Unhandled InitLink kind");
375 for (
const LabelInfo &LI : Ctx->LabelInfoStack)
376 assert(LI.Name != Name);
379 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel, ContinueLabel,
400 : Ctx(Ctx), OldCaseLabels(
std::move(this->Ctx->CaseLabels)) {
402 for (
const LabelInfo &LI : Ctx->LabelInfoStack)
403 assert(LI.Name != Name);
406 this->Ctx->CaseLabels = std::move(CaseLabels);
407 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel,
409 DefaultLabel, Ctx->VarScope);
413 this->Ctx->CaseLabels = std::move(OldCaseLabels);
414 this->Ctx->LabelInfoStack.pop_back();
419 CaseMap OldCaseLabels;
430 : Ctx(Ctx), OldFlag(Ctx->LocOverride), Enabled(Enabled) {
433 Ctx->LocOverride = NewValue;
438 Ctx->LocOverride = OldFlag;
443 std::optional<SourceInfo> OldFlag;
450template <
class Emitter>
458 case CK_LValueToRValue: {
461 if (!this->
visit(SubExpr))
463 return this->emitLoadPopL(E);
473 if (
const auto *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
479 if (
auto GlobalIndex =
P.getGlobal(D))
480 return this->emitGetGlobal(*SubExprT, *GlobalIndex, E);
481 }
else if (
auto It =
Locals.find(D); It !=
Locals.end()) {
482 return this->emitGetLocal(*SubExprT, It->second.Offset, E);
483 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
484 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
485 return this->emitGetParam(*SubExprT, It->second.Index, E);
497 if (!this->emitGetPtrLocal(*LocalIndex, E))
501 if (!this->
visit(SubExpr))
505 return this->emitLoadPop(*SubExprT, E);
510 return this->emitMemcpy(E);
513 case CK_DerivedToBaseMemberPointer: {
524 ->getMostRecentCXXRecordDecl();
526 const CXXRecordDecl *ToDecl = B->getType()->getAsCXXRecordDecl();
527 unsigned DerivedOffset =
Ctx.collectBaseOffset(ToDecl, CurDecl);
529 if (!this->emitCastMemberPtrBasePop(DerivedOffset, ToDecl, E))
537 case CK_BaseToDerivedMemberPointer: {
548 ->getMostRecentCXXRecordDecl();
552 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
554 PathI != PathE; ++PathI) {
555 const CXXRecordDecl *ToDecl = (*PathI)->getType()->getAsCXXRecordDecl();
556 unsigned DerivedOffset =
Ctx.collectBaseOffset(CurDecl, ToDecl);
558 if (!this->emitCastMemberPtrDerivedPop(-DerivedOffset, ToDecl, E))
565 assert(ToDecl != CurDecl);
566 unsigned DerivedOffset =
Ctx.collectBaseOffset(CurDecl, ToDecl);
568 if (!this->emitCastMemberPtrDerivedPop(-DerivedOffset, ToDecl, E))
574 case CK_UncheckedDerivedToBase:
575 case CK_DerivedToBase: {
580 if (
const auto *PT = dyn_cast<PointerType>(Ty))
581 return PT->getPointeeType()->getAsCXXRecordDecl();
582 return Ty->getAsCXXRecordDecl();
589 if (B->isVirtual()) {
590 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), E))
592 CurType = B->getType();
594 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
595 if (!this->emitGetPtrBasePop(
598 CurType = B->getType();
605 case CK_BaseToDerived: {
608 unsigned DerivedOffset =
614 return this->emitGetPtrDerivedPop(DerivedOffset,
619 case CK_FloatingCast: {
622 return this->emitVectorConversion(E->
getSubExpr(), E);
626 if (!this->
visit(SubExpr))
628 const auto *TargetSemantics = &
Ctx.getFloatSemantics(E->
getType());
632 case CK_IntegralToFloating: {
634 return this->emitVectorConversion(E->
getSubExpr(), E);
637 if (!this->
visit(SubExpr))
639 const auto *TargetSemantics = &
Ctx.getFloatSemantics(E->
getType());
640 return this->emitCastIntegralFloating(
classifyPrim(SubExpr),
641 TargetSemantics, getFPOptions(E), E);
644 case CK_FloatingToBoolean: {
646 return this->emitVectorConversion(E->
getSubExpr(), E);
650 if (
const auto *FL = dyn_cast<FloatingLiteral>(SubExpr))
651 return this->emitConstBool(FL->getValue().isNonZero(), E);
652 if (!this->
visit(SubExpr))
654 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
657 case CK_FloatingToIntegral: {
659 return this->emitVectorConversion(E->
getSubExpr(), E);
662 if (!this->
visit(SubExpr))
666 return this->emitCastFloatingIntegralAP(
Ctx.getBitWidth(E->
getType()),
669 return this->emitCastFloatingIntegralAPS(
Ctx.getBitWidth(E->
getType()),
672 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
675 case CK_NullToPointer:
676 case CK_NullToMemberPointer: {
679 uint64_t Val =
Ctx.getASTContext().getTargetNullPointerValue(E->
getType());
684 case CK_PointerToIntegral: {
685 if (!this->
visit(SubExpr))
691 if (!this->emitDecayPtr(FromT,
PT_Ptr, E))
697 return this->emitCastPointerIntegralAP(
Ctx.getBitWidth(E->
getType()), E);
699 return this->emitCastPointerIntegralAPS(
Ctx.getBitWidth(E->
getType()), E);
700 return this->emitCastPointerIntegral(
T, E);
703 case CK_ArrayToPointerDecay: {
704 if (!this->
visit(SubExpr))
706 return this->emitArrayDecay(E);
709 case CK_IntegralToPointer: {
711 assert(IntType->isIntegralOrEnumerationType());
712 if (!this->
visit(SubExpr))
726 return this->emitDecayPtr(
PT_Ptr, DestPtrT, E);
729 case CK_AtomicToNonAtomic:
730 case CK_ConstructorConversion:
731 case CK_FunctionToPointerDecay:
732 case CK_NonAtomicToAtomic:
734 case CK_UserDefinedConversion:
735 case CK_AddressSpaceConversion:
736 case CK_CPointerToObjCPointerCast:
753 return this->emitBuiltinBitCast(E);
768 if (!this->
visit(SubExpr))
776 return this->emitFnPtrCast(E);
784 if (!this->
visit(SubExpr))
786 return this->emitDecayPtr(*FromT, *ToT, E);
788 case CK_IntegralToBoolean:
789 case CK_FixedPointToBoolean: {
791 return this->emitVectorConversion(E->
getSubExpr(), E);
797 if (
const auto *IL = dyn_cast<IntegerLiteral>(SubExpr))
798 return this->emitConst(IL->getValue(), E);
799 if (!this->
visit(SubExpr))
804 case CK_IntegralCast:
806 return this->emitVectorConversion(E->
getSubExpr(), E);
808 case CK_BooleanToSignedIntegral: {
815 if (
const auto *IL = dyn_cast<IntegerLiteral>(SubExpr)) {
820 if (!this->emitConst(IL->getValue(), SubExpr))
823 if (!this->
visit(SubExpr))
831 if (!ED->isFixed()) {
832 if (!this->emitCheckEnumValue(*FromT, ED, E))
838 if (!this->emitCastAP(*FromT,
Ctx.getBitWidth(E->
getType()), E))
841 if (!this->emitCastAPS(*FromT,
Ctx.getBitWidth(E->
getType()), E))
846 if (!this->emitCast(*FromT, *ToT, E))
849 if (E->
getCastKind() == CK_BooleanToSignedIntegral)
850 return this->emitNeg(*ToT, E);
854 case CK_PointerToBoolean:
855 if (!this->
visit(SubExpr))
857 return this->emitIsNonNullPtr(E);
859 case CK_MemberPointerToBoolean:
860 if (!this->
visit(SubExpr))
862 return this->emitIsNonNullMemberPtr(E);
864 case CK_IntegralComplexToBoolean:
865 case CK_FloatingComplexToBoolean: {
866 if (!this->
visit(SubExpr))
868 return this->emitComplexBoolCast(SubExpr);
871 case CK_IntegralComplexToReal:
872 case CK_FloatingComplexToReal:
873 return this->emitComplexReal(SubExpr);
875 case CK_IntegralRealToComplex:
876 case CK_FloatingRealToComplex: {
883 if (!this->emitGetPtrLocal(*LocalIndex, E))
892 if (!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
894 return this->emitInitElem(
T, 1, SubExpr);
897 case CK_IntegralComplexCast:
898 case CK_FloatingComplexCast:
899 case CK_IntegralComplexToFloatingComplex:
900 case CK_FloatingComplexToIntegralComplex: {
907 if (!this->emitGetPtrLocal(*LocalIndex, E))
914 unsigned SubExprOffset =
916 if (!this->
visit(SubExpr))
918 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, E))
926 for (
unsigned I = 0; I != 2; ++I) {
927 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, E))
929 if (!this->emitArrayElemPop(SourceElemT, I, E))
933 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, E))
937 if (!this->emitInitElem(DestElemT, I, E))
943 case CK_VectorSplat: {
954 if (!this->emitGetPtrLocal(*LocalIndex, E))
960 unsigned ElemOffset =
964 if (!this->
visit(SubExpr))
969 if (!this->emitSetLocal(ElemT, ElemOffset, E))
972 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
973 if (!this->emitGetLocal(ElemT, ElemOffset, E))
975 if (!this->emitInitElem(ElemT, I, E))
982 case CK_HLSLVectorTruncation: {
987 if (!this->
visit(SubExpr))
989 return this->emitArrayElemPop(*ResultT, 0, E);
998 if (!this->emitGetPtrLocal(*LocalIndex, E))
1003 if (!this->
visit(SubExpr))
1005 return this->emitCopyArray(classifyVectorElementType(E->
getType()), 0, 0,
1009 case CK_IntegralToFixedPoint: {
1010 if (!this->
visit(SubExpr))
1014 Ctx.getASTContext().getFixedPointSemantics(E->
getType()).toOpaqueInt();
1019 return this->emitPopFixedPoint(E);
1022 case CK_FloatingToFixedPoint: {
1023 if (!this->
visit(SubExpr))
1027 Ctx.getASTContext().getFixedPointSemantics(E->
getType()).toOpaqueInt();
1028 if (!this->emitCastFloatingFixedPoint(Sem, E))
1031 return this->emitPopFixedPoint(E);
1034 case CK_FixedPointToFloating: {
1035 if (!this->
visit(SubExpr))
1037 const auto *TargetSemantics = &
Ctx.getFloatSemantics(E->
getType());
1038 if (!this->emitCastFixedPointFloating(TargetSemantics, E))
1041 return this->emitPopFloat(E);
1044 case CK_FixedPointToIntegral: {
1045 if (!this->
visit(SubExpr))
1048 if (!this->emitCastFixedPointIntegral(IntegralT, E))
1051 return this->emitPop(IntegralT, E);
1054 case CK_FixedPointCast: {
1055 if (!this->
visit(SubExpr))
1058 Ctx.getASTContext().getFixedPointSemantics(E->
getType()).toOpaqueInt();
1059 if (!this->emitCastFixedPoint(Sem, E))
1062 return this->emitPopFixedPoint(E);
1070 llvm_unreachable(
"CXXDynamicCastExpr has its own function");
1072 case CK_LValueBitCast:
1077 case CK_HLSLArrayRValue: {
1084 if (!this->emitGetPtrLocal(*LocalIndex, E))
1087 if (!this->
visit(SubExpr))
1089 return this->emitMemcpy(E);
1092 case CK_HLSLMatrixTruncation: {
1097 if (!this->
visit(SubExpr))
1099 return this->emitArrayElemPop(*ResultT, 0, E);
1108 if (!this->emitGetPtrLocal(*LocalIndex, E))
1113 if (!this->
visit(SubExpr))
1115 return this->emitCopyArray(classifyMatrixElementType(SubExpr->
getType()), 0,
1119 case CK_HLSLAggregateSplatCast: {
1129 if (!this->emitGetPtrLocal(*LocalIndex, E))
1136 unsigned SrcOffset =
1139 if (!this->
visit(SubExpr))
1141 if (!this->emitSetLocal(SrcElemT, SrcOffset, E))
1145 return emitHLSLAggregateSplat(SrcElemT, SrcOffset, E->
getType(), E);
1148 case CK_HLSLElementwiseCast: {
1159 unsigned SrcPtrOffset =
1161 if (!this->
visit(SubExpr))
1163 if (!this->emitSetLocal(
PT_Ptr, SrcPtrOffset, E))
1167 if (!emitHLSLFlattenAggregate(SrcType, SrcPtrOffset, Elements, 1, E))
1169 if (Elements.empty())
1172 const HLSLFlatElement &Src = Elements[0];
1173 if (!this->emitGetLocal(Src.Type, Src.LocalOffset, E))
1175 return this->emitPrimCast(Src.Type, *DestT, DestType, E);
1182 if (!this->emitGetPtrLocal(*LocalIndex, E))
1186 unsigned SrcOffset =
1188 if (!this->
visit(SubExpr))
1190 if (!this->emitSetLocal(
PT_Ptr, SrcOffset, E))
1194 unsigned ElemCount = countHLSLFlatElements(DestType);
1197 Elements.reserve(ElemCount);
1198 if (!emitHLSLFlattenAggregate(SrcType, SrcOffset, Elements, ElemCount, E))
1203 assert(Elements.size() == ElemCount &&
1204 "Source type has fewer scalar elements than the destination type");
1206 return emitHLSLConstructAggregate(DestType, Elements, E);
1213 const Record::Field *RF = R->getField(UnionField);
1216 if (!this->
visit(SubExpr))
1218 if (RF->isBitField())
1219 return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(),
1221 return this->emitInitFieldActivate(*PT, RF->Offset, E);
1224 if (!this->emitGetPtrField(RF->Offset, E))
1226 if (!this->emitActivate(E))
1232 return this->emitInvalid(E);
1234 llvm_unreachable(
"Unhandled clang::CastKind enum");
1237template <
class Emitter>
1239 return this->emitBuiltinBitCast(E);
1242template <
class Emitter>
1247 return this->emitConst(
LE->getValue(),
LE);
1250template <
class Emitter>
1256 return this->emitFloat(F, E);
1259template <
class Emitter>
1269 if (!this->emitGetPtrLocal(*LocalIndex, E))
1276 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
1278 if (!this->emitInitElem(SubExprT, 0, SubExpr))
1283template <
class Emitter>
1291 auto Sem =
Ctx.getASTContext().getFixedPointSemantics(E->
getType());
1296template <
class Emitter>
1301template <
class Emitter>
1328 return this->emitComplexComparison(LHS, RHS, E);
1336 if (!this->
visit(LHS))
1339 if (!this->
visit(RHS))
1342 if (!this->emitToMemberPtr(E))
1348 if (!this->emitCastMemberPtrPtr(E))
1365 Ctx.getASTContext().CompCategories.lookupInfoForType(E->
getType());
1371 if (!this->emitGetPtrLocal(*ResultIndex, E))
1378 return this->emitCMP3(*
LT, CmpInfo, E);
1381 if (!
LT || !RT || !
T)
1391 return this->visitAssignment(LHS, RHS, E);
1398 auto MaybeCastToBool = [
this,
T, E](
bool Result) {
1402 return this->emitPopBool(E);
1404 return this->emitCast(
PT_Bool, *
T, E);
1408 auto Discard = [
this,
T, E](
bool Result) {
1416 return MaybeCastToBool(this->emitEQ(*
LT, E));
1418 return MaybeCastToBool(this->emitNE(*
LT, E));
1420 return MaybeCastToBool(this->emitLT(*
LT, E));
1422 return MaybeCastToBool(this->emitLE(*
LT, E));
1424 return MaybeCastToBool(this->emitGT(*
LT, E));
1426 return MaybeCastToBool(this->emitGE(*
LT, E));
1429 return Discard(this->emitSubf(getFPOptions(E), E));
1430 return Discard(this->emitSub(*
T, E));
1433 return Discard(this->emitAddf(getFPOptions(E), E));
1434 return Discard(this->emitAdd(*
T, E));
1437 return Discard(this->emitMulf(getFPOptions(E), E));
1438 return Discard(this->emitMul(*
T, E));
1440 return Discard(this->emitRem(*
T, E));
1443 return Discard(this->emitDivf(getFPOptions(E), E));
1444 return Discard(this->emitDiv(*
T, E));
1446 return Discard(this->emitBitAnd(*
T, E));
1448 return Discard(this->emitBitOr(*
T, E));
1450 return Discard(this->emitShl(*
LT, *RT, E));
1452 return Discard(this->emitShr(*
LT, *RT, E));
1454 return Discard(this->emitBitXor(*
T, E));
1457 llvm_unreachable(
"Already handled earlier");
1462 llvm_unreachable(
"Unhandled binary op");
1467template <
class Emitter>
1473 if ((Op != BO_Add && Op != BO_Sub) ||
1484 auto visitAsPointer = [&](
const Expr *E,
PrimType T) ->
bool {
1485 if (!this->
visit(E))
1488 return this->emitDecayPtr(
T,
PT_Ptr, E);
1497 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *
LT))
1505 ElemTypeSize =
Ctx.getASTContext().getTypeSizeInChars(ElemType);
1508 if (!this->emitSubPtr(IntT, ElemTypeSize.
getQuantity(), E))
1515 if (!visitAsPointer(RHS, *RT))
1517 if (!this->
visit(LHS))
1521 if (!visitAsPointer(LHS, *
LT))
1523 if (!this->
visit(RHS))
1534 if (!this->emitAddOffset(OffsetType, E))
1538 if (!this->emitSubOffset(OffsetType, E))
1547 if (!this->emitDecayPtr(
PT_Ptr, ExprT, E))
1552 return this->emitPop(ExprT, E);
1556template <
class Emitter>
1565 LabelTy LabelTrue = this->getLabel();
1566 LabelTy LabelEnd = this->getLabel();
1570 if (!this->jumpTrue(LabelTrue, E))
1575 if (!this->jump(LabelEnd, E))
1578 this->emitLabel(LabelTrue);
1579 this->emitConstBool(
true, E);
1580 this->fallthrough(LabelEnd);
1581 this->emitLabel(LabelEnd);
1584 assert(Op == BO_LAnd);
1587 LabelTy LabelFalse = this->getLabel();
1588 LabelTy LabelEnd = this->getLabel();
1592 if (!this->jumpFalse(LabelFalse, E))
1597 if (!this->jump(LabelEnd, E))
1600 this->emitLabel(LabelFalse);
1601 this->emitConstBool(
false, E);
1602 this->fallthrough(LabelEnd);
1603 this->emitLabel(LabelEnd);
1607 return this->emitPopBool(E);
1612 return this->emitCast(
PT_Bool,
T, E);
1617template <
class Emitter>
1624 if (!this->emitGetPtrLocal(*LocalIndex, E))
1633 PrimType ResultElemT = this->classifyComplexElementType(E->
getType());
1634 unsigned ResultOffset = ~0u;
1640 if (!this->emitDupPtr(E))
1642 if (!this->emitSetLocal(
PT_Ptr, ResultOffset, E))
1647 LHSType = AT->getValueType();
1650 RHSType = AT->getValueType();
1659 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1664 if (!this->
visit(LHS))
1666 if (!this->
visit(RHS))
1668 if (!this->emitMulc(ElemT, E))
1671 return this->emitPopPtr(E);
1675 if (Op == BO_Div && RHSIsComplex) {
1682 if (!LHSIsComplex) {
1687 LHSOffset = *LocalIndex;
1689 if (!this->emitGetPtrLocal(LHSOffset, E))
1692 if (!this->
visit(LHS))
1695 if (!this->emitInitElem(ElemT, 0, E))
1698 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1700 if (!this->emitInitElem(ElemT, 1, E))
1703 if (!this->
visit(LHS))
1707 if (!this->
visit(RHS))
1709 if (!this->emitDivc(ElemT, E))
1712 return this->emitPopPtr(E);
1719 if (!this->
visit(LHS))
1721 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
1726 if (!this->
visit(LHS))
1728 if (!this->emitSetLocal(LHST, LHSOffset, E))
1736 if (!this->
visit(RHS))
1738 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
1743 if (!this->
visit(RHS))
1745 if (!this->emitSetLocal(RHST, RHSOffset, E))
1752 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1753 unsigned ElemIndex,
unsigned Offset,
1754 const Expr *E) ->
bool {
1756 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
1758 return this->emitArrayElemPop(classifyComplexElementType(E->
getType()),
1761 if (ElemIndex == 0 || !LoadZero)
1768 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1771 if (!this->emitGetLocal(
PT_Ptr, ResultOffset, E))
1778 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1781 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1784 if (!this->emitAddf(getFPOptions(E), E))
1787 if (!this->emitAdd(ResultElemT, E))
1792 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1795 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1798 if (!this->emitSubf(getFPOptions(E), E))
1801 if (!this->emitSub(ResultElemT, E))
1806 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1809 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1813 if (!this->emitMulf(getFPOptions(E), E))
1816 if (!this->emitMul(ResultElemT, E))
1821 assert(!RHSIsComplex);
1822 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1825 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1829 if (!this->emitDivf(getFPOptions(E), E))
1832 if (!this->emitDiv(ResultElemT, E))
1843 if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))
1846 if (!this->emitPop(ResultElemT, E))
1851 return this->emitPopPtr(E);
1857template <
class Emitter>
1862 "Comma op should be handled in VisitBinaryOperator");
1876 if (!this->emitGetPtrLocal(*LocalIndex, E))
1890 assert(
Ctx.getASTContext().hasSameUnqualifiedType(
1893 if (!this->
visit(LHS))
1895 if (!this->
visit(RHS))
1897 if (!this->emitCopyArray(ElemT, 0, 0, VecTy->getNumElements(), E))
1900 return this->emitPopPtr(E);
1905 unsigned LHSOffset =
1907 if (!this->
visit(LHS))
1909 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
1913 unsigned RHSOffset =
1915 if (!this->
visit(RHS))
1917 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
1929 if (NeedIntPromot) {
1931 Ctx.getASTContext().getPromotedIntegerType(
Ctx.getASTContext().BoolTy);
1936 auto getElem = [=](
unsigned Offset,
PrimType ElemT,
unsigned Index) {
1937 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
1939 if (!this->emitArrayElemPop(ElemT, Index, E))
1942 if (!this->emitPrimCast(ElemT,
PT_Bool,
Ctx.getASTContext().BoolTy, E))
1944 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(), E))
1946 }
else if (NeedIntPromot) {
1947 if (!this->emitPrimCast(ElemT, PromotT, PromotTy, E))
1953#define EMIT_ARITH_OP(OP) \
1955 if (ElemT == PT_Float) { \
1956 if (!this->emit##OP##f(getFPOptions(E), E)) \
1959 if (!this->emit##OP(ElemT, E)) \
1965 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
1966 if (!getElem(LHSOffset, ElemT, I))
1968 if (!getElem(RHSOffset, RHSElemT, I))
1980 if (!this->emitRem(ElemT, E))
1984 if (!this->emitBitAnd(OpT, E))
1988 if (!this->emitBitOr(OpT, E))
1992 if (!this->emitBitXor(OpT, E))
1996 if (!this->emitShl(OpT, RHSElemT, E))
2000 if (!this->emitShr(OpT, RHSElemT, E))
2004 if (!this->emitEQ(ElemT, E))
2008 if (!this->emitNE(ElemT, E))
2012 if (!this->emitLE(ElemT, E))
2016 if (!this->emitLT(ElemT, E))
2020 if (!this->emitGE(ElemT, E))
2024 if (!this->emitGT(ElemT, E))
2029 if (!this->emitBitAnd(ResultElemT, E))
2034 if (!this->emitBitOr(ResultElemT, E))
2038 return this->emitInvalid(E);
2047 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(), E))
2049 if (!this->emitNeg(ResultElemT, E))
2055 if (NeedIntPromot &&
2056 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(), E))
2060 if (!this->emitInitElem(ResultElemT, I, E))
2069template <
class Emitter>
2079 auto LHSSemaInt = LHSSema.toOpaqueInt();
2081 auto RHSSemaInt = RHSSema.toOpaqueInt();
2083 if (!this->
visit(LHS))
2091 if (!this->
visit(RHS))
2100 auto ConvertResult = [&](
bool R) ->
bool {
2104 auto CommonSema = LHSSema.getCommonSemantics(RHSSema).toOpaqueInt();
2105 if (ResultSema != CommonSema)
2106 return this->emitCastFixedPoint(ResultSema, E);
2110 auto MaybeCastToBool = [&](
bool Result) {
2115 return this->emitPop(
T, E);
2117 return this->emitCast(
PT_Bool,
T, E);
2123 return MaybeCastToBool(this->emitEQFixedPoint(E));
2125 return MaybeCastToBool(this->emitNEFixedPoint(E));
2127 return MaybeCastToBool(this->emitLTFixedPoint(E));
2129 return MaybeCastToBool(this->emitLEFixedPoint(E));
2131 return MaybeCastToBool(this->emitGTFixedPoint(E));
2133 return MaybeCastToBool(this->emitGEFixedPoint(E));
2135 return ConvertResult(this->emitAddFixedPoint(E));
2137 return ConvertResult(this->emitSubFixedPoint(E));
2139 return ConvertResult(this->emitMulFixedPoint(E));
2141 return ConvertResult(this->emitDivFixedPoint(E));
2143 return ConvertResult(this->emitShiftFixedPoint(
true, E));
2145 return ConvertResult(this->emitShiftFixedPoint(
false, E));
2148 return this->emitInvalid(E);
2151 llvm_unreachable(
"unhandled binop opcode");
2154template <
class Emitter>
2163 if (!this->
visit(SubExpr))
2165 if (!this->emitNegFixedPoint(E))
2168 return this->emitPopFixedPoint(E);
2174 llvm_unreachable(
"Unhandled unary opcode");
2177template <
class Emitter>
2186 return this->visitZeroInitializer(*
T, QT, E);
2199 return this->visitZeroRecordInitializer(R, E);
2206 return this->visitZeroArrayInitializer(QT, E);
2210 QualType ElemQT = ComplexTy->getElementType();
2212 for (
unsigned I = 0; I < 2; ++I) {
2213 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2215 if (!this->emitInitElem(ElemT, I, E))
2222 unsigned NumVecElements = VecT->getNumElements();
2223 QualType ElemQT = VecT->getElementType();
2226 for (
unsigned I = 0; I < NumVecElements; ++I) {
2227 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2229 if (!this->emitInitElem(ElemT, I, E))
2236 unsigned NumElems = MT->getNumElementsFlattened();
2237 QualType ElemQT = MT->getElementType();
2240 for (
unsigned I = 0; I != NumElems; ++I) {
2241 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2243 if (!this->emitInitElem(ElemT, I, E))
2252template <
class Emitter>
2265 for (
const Expr *SubExpr : {LHS, RHS}) {
2266 if (!this->
visit(SubExpr)) {
2273 if (SubExpr ==
Base &&
Base->getType()->isPointerType()) {
2274 if (!this->emitExpandPtr(E))
2285 return this->emitError(E);
2288 if (!this->emitFlip(
PT_Ptr, *IndexT, E))
2292 if (!this->emitArrayElemPtrPop(*IndexT, E))
2295 return this->emitPopPtr(E);
2301 return this->emitLoadPop(*
T, E);
2304template <
class Emitter>
2306 const Expr *ArrayFiller,
const Expr *E) {
2311 QT = AT->getValueType();
2314 if (
Inits.size() == 0)
2316 return this->emitInvalid(E);
2331 if (
Inits.size() == 0)
2332 return this->visitZeroInitializer(*
T, QT, E);
2333 assert(
Inits.size() == 1);
2346 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
2353 bool BitField = FieldToInit->isBitField();
2355 return this->emitInitBitFieldActivate(
T, FieldToInit->Offset,
2356 FieldToInit->bitWidth(), E);
2358 return this->emitInitBitField(
T, FieldToInit->Offset,
2359 FieldToInit->bitWidth(), E);
2361 return this->emitInitFieldActivate(
T, FieldToInit->Offset, E);
2362 return this->emitInitField(
T, FieldToInit->Offset, E);
2365 auto initCompositeField = [=](
const Record::Field *FieldToInit,
2373 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
2376 if (
Activate && !this->emitActivate(E))
2383 if (
Inits.size() == 0) {
2384 if (!this->visitZeroRecordInitializer(R, E))
2389 if (
const auto *ILE = dyn_cast<InitListExpr>(E))
2390 FToInit = ILE->getInitializedFieldInUnion();
2394 const Record::Field *FieldToInit = R->getField(FToInit);
2396 if (!initPrimitiveField(FieldToInit,
Init, *
T,
true))
2399 if (!initCompositeField(FieldToInit,
Init,
true))
2403 return this->emitFinishInit(E);
2406 assert(!R->isUnion());
2407 for (
unsigned BI = 0; BI != R->getNumBases(); ++BI) {
2409 const Record::Base *B = R->getBase(BI);
2412 if (!this->emitGetPtrBase(B->Offset,
Init))
2418 unsigned FieldIndex = 0;
2419 for (
unsigned FI = R->getNumBases(); FI !=
Inits.size();) {
2420 const Record::Field *FieldToInit = R->getField(FieldIndex);
2421 if (FieldToInit->isUnnamedBitField()) {
2436 if (!initPrimitiveField(FieldToInit,
Init, *
T))
2438 }
else if (!initCompositeField(FieldToInit,
Init)) {
2446 assert(R->getNumVirtualBases() == 0);
2448 return this->emitFinishInit(E);
2453 Ctx.getASTContext().getAsConstantArrayType(QT);
2458 !this->emitCheckArrayDestSize(NumElems, E))
2461 if (
Inits.size() == 1 && QT ==
Inits[0]->getType())
2465 unsigned ElementIndex = 0;
2467 if (
const auto *EmbedS =
2468 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
2476 if (!this->emitCastIntegralFloating(
classifyPrim(IL), Sem,
2477 getFPOptions(E), E))
2483 return this->emitInitElem(TargetT, ElemIndex, IL);
2485 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
2501 for (; ElementIndex != NumElems; ++ElementIndex) {
2507 return this->emitFinishInit(E);
2511 unsigned NumInits =
Inits.size();
2516 QualType ElemQT = ComplexTy->getElementType();
2518 if (NumInits == 0) {
2520 for (
unsigned I = 0; I < 2; ++I) {
2521 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2523 if (!this->emitInitElem(ElemT, I, E))
2526 }
else if (NumInits == 2) {
2527 unsigned InitIndex = 0;
2532 if (!this->emitInitElem(ElemT, InitIndex, E))
2541 unsigned NumVecElements = VecT->getNumElements();
2542 assert(NumVecElements >=
Inits.size());
2544 QualType ElemQT = VecT->getElementType();
2548 unsigned InitIndex = 0;
2555 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
2556 if (!this->emitCopyArray(ElemT, 0, InitIndex,
2557 InitVecT->getNumElements(), E))
2559 InitIndex += InitVecT->getNumElements();
2561 if (!this->emitInitElem(ElemT, InitIndex, E))
2567 assert(InitIndex <= NumVecElements);
2570 for (; InitIndex != NumVecElements; ++InitIndex) {
2571 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2573 if (!this->emitInitElem(ElemT, InitIndex, E))
2580 unsigned NumElems = MT->getNumElementsFlattened();
2581 assert(
Inits.size() == NumElems);
2583 QualType ElemQT = MT->getElementType();
2589 for (
unsigned I = 0; I != NumElems; ++I) {
2592 if (!this->emitInitElem(ElemT, I, E))
2603template <
class Emitter>
2610 return this->emitInitElem(*InitT, ElemIndex,
Init);
2616 if (!this->emitConstUint32(ElemIndex,
Init))
2618 if (!this->emitArrayElemPtrUint32(
Init))
2623template <
class Emitter>
2626 bool Activate,
bool IsOperatorCall) {
2628 llvm::BitVector NonNullArgs;
2629 if (FuncDecl && FuncDecl->
hasAttr<NonNullAttr>())
2632 bool ExplicitMemberFn =
false;
2633 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl))
2634 ExplicitMemberFn = MD->isExplicitObjectMemberFunction();
2636 unsigned ArgIndex = 0;
2637 for (
const Expr *Arg : Args) {
2639 if (!this->
visit(Arg))
2647 unsigned DeclIndex = ArgIndex - IsOperatorCall + ExplicitMemberFn;
2648 if (DeclIndex < FuncDecl->getNumParams())
2649 Source = FuncDecl->
getParamDecl(ArgIndex - IsOperatorCall +
2658 if (!this->emitGetPtrLocal(*LocalIndex, Arg))
2666 if (!this->emitActivate(Arg))
2670 if (!NonNullArgs.empty() && NonNullArgs[ArgIndex]) {
2673 if (!this->emitCheckNonNullArg(ArgT, Arg))
2684template <
class Emitter>
2689template <
class Emitter>
2695template <
class Emitter>
2701template <
class Emitter>
2719template <
class Emitter>
2721 auto It = E->
begin();
2722 return this->
visit(*It);
2726 UnaryExprOrTypeTrait Kind) {
2727 bool AlignOfReturnsPreferred =
2734 T = Ref->getPointeeType();
2736 if (
T.getQualifiers().hasUnaligned())
2742 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2748template <
class Emitter>
2752 UnaryExprOrTypeTrait Kind = E->
getKind();
2755 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2761 ArgType = Ref->getPointeeType();
2767 if (
ArgType->isDependentType() || !
ArgType->isConstantSizeType())
2768 return this->emitInvalid(E);
2770 if (Kind == UETT_SizeOf)
2779 return this->emitConst(Size.getQuantity(), E);
2782 if (Kind == UETT_CountOf) {
2788 if (
const auto *CAT =
2792 return this->emitConst(CAT->getSize(), E);
2802 if (VAT->getElementType()->isArrayType()) {
2803 std::optional<APSInt> Res =
2805 ? VAT->getSizeExpr()->getIntegerConstantExpr(ASTCtx)
2810 return this->emitConst(*Res, E);
2815 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2835 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2838 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
2848 return this->emitConst(Size.getQuantity(), E);
2851 if (Kind == UETT_VectorElements) {
2856 return this->emitConst(VT->getNumElements(), E);
2858 return this->emitSizelessVectorElementSize(E);
2861 if (Kind == UETT_VecStep) {
2863 unsigned N = VT->getNumElements();
2870 return this->emitConst(N, E);
2872 return this->emitConst(1, E);
2875 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2884 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2886 return this->emitInvalid(E);
2888 return this->emitConst(
2889 const_cast<ASTContext &
>(ASTCtx).getPointerAuthTypeDiscriminator(
2897template <
class Emitter>
2906 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
2909 if (
auto GlobalIndex =
P.getGlobal(VD)) {
2910 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2912 if (
Member->getType()->isReferenceType())
2913 return this->emitLoadPopPtr(E);
2922 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
Member);
2923 MD && !MD->isStatic()) {
2927 if (!this->
discard(Base) && !this->emitSideEffect(E))
2942 const Record::Field *F = R->getField(FD);
2946 const auto maybeLoadValue = [&]() ->
bool {
2950 return this->emitLoadPop(*
T, E);
2955 if (F->Decl->getType()->isReferenceType())
2956 return this->emitGetFieldPop(
PT_Ptr, F->Offset, E) && maybeLoadValue();
2957 return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue();
2960template <
class Emitter>
2970template <
class Emitter>
2984 if (!this->
visit(Common))
2986 return this->emitCopyArray(*SubExprT, 0, 0, Size, E);
3000 for (
size_t I = 0; I != Size; ++I) {
3012template <
class Emitter>
3027 return this->emitGetLocal(SubExprT, It->second, E);
3030 if (!this->
visit(SourceExpr))
3037 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
3046 return this->emitGetLocal(SubExprT, LocalIndex, E);
3050template <
class Emitter>
3063 bool IsBcpCall =
false;
3064 if (
const auto *CE = dyn_cast<CallExpr>(
Condition->IgnoreParenCasts());
3065 CE && CE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) {
3069 LabelTy LabelEnd = this->getLabel();
3070 LabelTy LabelFalse = this->getLabel();
3073 if (!this->emitPushIgnoreDiags(E))
3081 if (this->checkingForUndefinedBehavior()) {
3084 if (!this->
discard(FalseExpr))
3101 if (!this->jumpFalse(LabelFalse, E))
3106 if (!this->jump(LabelEnd, E))
3108 this->emitLabel(LabelFalse);
3112 this->fallthrough(LabelEnd);
3113 this->emitLabel(LabelEnd);
3116 return this->emitPopIgnoreDiags(E);
3120template <
class Emitter>
3126 return this->emitGetStringPtr(E, E);
3130 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
3131 assert(CAT &&
"a string literal that's not a constant array?");
3136 unsigned N = std::min(ArraySize, E->
getLength());
3139 for (
unsigned I = 0; I != N; ++I) {
3142 if (CharWidth == 1) {
3143 this->emitConstSint8(CodeUnit, E);
3144 this->emitInitElemSint8(I, E);
3145 }
else if (CharWidth == 2) {
3146 this->emitConstUint16(CodeUnit, E);
3147 this->emitInitElemUint16(I, E);
3148 }
else if (CharWidth == 4) {
3149 this->emitConstUint32(CodeUnit, E);
3150 this->emitInitElemUint32(I, E);
3152 llvm_unreachable(
"unsupported character width");
3157 for (
unsigned I = N; I != ArraySize; ++I) {
3158 if (CharWidth == 1) {
3159 this->emitConstSint8(0, E);
3160 this->emitInitElemSint8(I, E);
3161 }
else if (CharWidth == 2) {
3162 this->emitConstUint16(0, E);
3163 this->emitInitElemUint16(I, E);
3164 }
else if (CharWidth == 4) {
3165 this->emitConstUint32(0, E);
3166 this->emitInitElemUint32(I, E);
3168 llvm_unreachable(
"unsupported character width");
3175template <
class Emitter>
3179 return this->emitDummyPtr(E, E);
3182template <
class Emitter>
3184 auto &A =
Ctx.getASTContext();
3193template <
class Emitter>
3201 auto &A =
Ctx.getASTContext();
3205 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
3206 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
3212 return this->emitGetStringPtr(SL, E);
3215template <
class Emitter>
3219 return this->emitConst(E->
getValue(), E);
3222template <
class Emitter>
3244 if (!this->emitLoad(LHST, E))
3247 if (!this->emitPrimCast(LHST,
classifyPrim(LHSComputationType),
3248 LHSComputationType, E))
3260 unsigned TempOffset =
3262 if (!this->emitSetLocal(*RT, TempOffset, E))
3268 if (!this->emitLoad(LHST, E))
3272 if (!this->emitPrimCast(LHST,
classifyPrim(LHSComputationType),
3273 LHSComputationType, E))
3277 if (!this->emitGetLocal(*RT, TempOffset, E))
3283 if (!this->emitAddf(getFPOptions(E), E))
3287 if (!this->emitSubf(getFPOptions(E), E))
3291 if (!this->emitMulf(getFPOptions(E), E))
3295 if (!this->emitDivf(getFPOptions(E), E))
3306 return this->emitStorePop(LHST, E);
3307 return this->emitStore(LHST, E);
3310template <
class Emitter>
3319 if (Op != BO_AddAssign && Op != BO_SubAssign)
3328 if (!this->emitLoad(*
LT, LHS))
3334 if (Op == BO_AddAssign) {
3335 if (!this->emitAddOffset(*RT, E))
3338 if (!this->emitSubOffset(*RT, E))
3343 return this->emitStorePopPtr(E);
3344 return this->emitStorePtr(E);
3347template <
class Emitter>
3360 if (!
Ctx.getLangOpts().CPlusPlus14)
3361 return this->
visit(RHS) && this->
visit(LHS) && this->emitError(E);
3363 if (!
LT || !RT || !ResultT || !LHSComputationT)
3380 if (!this->emitLoad(*
LT, E))
3382 if (
LT != LHSComputationT &&
3383 !this->emitIntegralCast(*
LT, *LHSComputationT,
3397 unsigned TempOffset =
3400 if (!this->emitSetLocal(*RT, TempOffset, E))
3407 if (!this->emitLoad(*
LT, E))
3409 if (
LT != LHSComputationT &&
3410 !this->emitIntegralCast(*
LT, *LHSComputationT,
3415 if (!this->emitGetLocal(*RT, TempOffset, E))
3422 if (!this->emitAdd(*LHSComputationT, E))
3426 if (!this->emitSub(*LHSComputationT, E))
3430 if (!this->emitMul(*LHSComputationT, E))
3434 if (!this->emitDiv(*LHSComputationT, E))
3438 if (!this->emitRem(*LHSComputationT, E))
3442 if (!this->emitShl(*LHSComputationT, *RT, E))
3446 if (!this->emitShr(*LHSComputationT, *RT, E))
3450 if (!this->emitBitAnd(*LHSComputationT, E))
3454 if (!this->emitBitXor(*LHSComputationT, E))
3458 if (!this->emitBitOr(*LHSComputationT, E))
3462 llvm_unreachable(
"Unimplemented compound assign operator");
3466 if (ResultT != LHSComputationT &&
3467 !this->emitIntegralCast(*LHSComputationT, *ResultT, E->
getType(), E))
3473 return this->emitStoreBitFieldPop(*ResultT, E);
3474 return this->emitStorePop(*ResultT, E);
3477 return this->emitStoreBitField(*ResultT, E);
3478 return this->emitStore(*ResultT, E);
3481template <
class Emitter>
3489template <
class Emitter>
3504 if (!
Ctx.getLangOpts().CPlusPlus11)
3511 for (
const Expr *LHS : CommaLHSs) {
3533 if (!this->
visit(Inner))
3538 if (!this->emitInitGlobalTemp(*InnerT, *GlobalIndex, TempDecl, E))
3541 if (!this->emitInitGlobal(*InnerT, *GlobalIndex, E))
3544 return this->emitGetPtrGlobal(*GlobalIndex, E);
3547 if (!this->checkLiteralType(Inner))
3550 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3556 return this->emitInitGlobalTempComp(TempDecl, E);
3569 unsigned LocalIndex =
3571 if (!this->VarScope->LocalsAlwaysEnabled &&
3572 !this->emitEnableLocal(LocalIndex, E))
3575 if (!this->
visit(Inner))
3577 if (!this->emitSetLocal(*InnerT, LocalIndex, E))
3580 return this->emitGetPtrLocal(LocalIndex, E);
3583 if (!this->checkLiteralType(Inner))
3590 if (!this->VarScope->LocalsAlwaysEnabled &&
3591 !this->emitEnableLocal(*LocalIndex, E))
3594 if (!this->emitGetPtrLocal(*LocalIndex, E))
3601template <
class Emitter>
3612 if (!this->
visit(SubExpr))
3616 return this->emitPopPtr(E);
3620template <
class Emitter>
3641 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3646 if (
P.isGlobalInitialized(*GlobalIndex))
3652 return this->emitInitGlobal(*
T, *GlobalIndex, E);
3664 unsigned LocalIndex;
3668 LocalIndex = *MaybeIndex;
3672 if (!this->emitGetPtrLocal(LocalIndex, E))
3676 return this->
visit(
Init) && this->emitInit(*
T, E);
3680template <
class Emitter>
3691 Ctx.getASTContext().CompCategories.getInfoForType(E->
getType());
3695 if (!R || R->getNumFields() == 0)
3697 const Record::Field *Field = R->getField(0
U);
3702 return this->emitInitField(*Field->T, Field->Offset, E);
3709template <
class Emitter>
3713 return this->emitConst(E->
getValue(), E);
3716template <
class Emitter>
3729 for (
const Record::Field &F : R->fields()) {
3731 if (!
Init ||
Init->containsErrors())
3739 if (!this->emitInitField(*
T, F.Offset, E))
3742 if (!this->emitGetPtrField(F.Offset, E))
3753template <
class Emitter>
3759 return this->emitGetStringPtr(E, E);
3763template <
class Emitter>
3768 return this->emitInvalid(E);
3771template <
class Emitter>
3785 if (!this->emitInvalidCast(
CastKind,
false, E))
3793 bool Fatal = (ToT != FromT);
3800template <
class Emitter>
3802 if (!
Ctx.getLangOpts().CPlusPlus20) {
3823 if (!this->emitDynamicCast(DestType.
getTypePtr(),
3828 return this->emitPopPtr(E);
3832template <
class Emitter>
3838 return this->emitConstBool(E->
getValue(), E);
3841template <
class Emitter>
3846 if (
T->isRecordType()) {
3860 if (!this->emitGetPtrLocal(*LocalIndex, E))
3868 T->getAsCXXRecordDecl()))
3878 if (!this->visitZeroRecordInitializer(R, E))
3890 assert(
Ctx.getASTContext().hasSameUnqualifiedType(E->
getType(),
3892 if (
const auto *ME = dyn_cast<MaterializeTemporaryExpr>(SrcObj)) {
3893 if (!this->emitCheckFunctionDecl(Ctor, E))
3904 assert(
Func->hasThisPointer());
3905 assert(!
Func->hasRVO());
3909 if (!this->emitDupPtr(E))
3913 for (
const auto *Arg : E->
arguments()) {
3914 if (!this->
visit(Arg))
3918 if (
Func->isVariadic()) {
3919 uint32_t VarArgSize = 0;
3920 unsigned NumParams =
Func->getNumWrittenParams();
3921 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I) {
3925 if (!this->emitCallVar(
Func, VarArgSize, E))
3928 if (!this->emitCall(
Func, 0, E)) {
3933 (void)this->emitPopPtr(E);
3939 return this->emitPopPtr(E);
3943 if (
T->isArrayType()) {
3948 if (!this->emitDupPtr(E))
3952 initArrayDimension = [&](
QualType T) ->
bool {
3953 if (!
T->isArrayType()) {
3955 for (
const auto *Arg : E->
arguments()) {
3956 if (!this->
visit(Arg))
3960 return this->emitCall(
Func, 0, E);
3964 Ctx.getASTContext().getAsConstantArrayType(
T);
3969 for (
size_t I = 0; I != NumElems; ++I) {
3970 if (!this->emitConstUint64(I, E))
3972 if (!this->emitArrayElemPtrUint64(E))
3974 if (!initArrayDimension(ElemTy))
3977 return this->emitPopPtr(E);
3980 return initArrayDimension(E->
getType());
3986template <
class Emitter>
3996 assert(Val.
isInt());
3998 return this->emitConst(I, E);
4005 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
4006 return this->
visit(LValueExpr);
4021 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4025 const APValue &
V = UGCD->getValue();
4026 for (
unsigned I = 0, N = R->getNumFields(); I != N; ++I) {
4027 const Record::Field *F = R->getField(I);
4028 const APValue &FieldValue =
V.getStructField(I);
4032 if (!this->emitInitField(*F->T, F->Offset, E))
4040template <
class Emitter>
4046 for (
unsigned I = 0; I != N; ++I) {
4053 if (!this->
discard(ArrayIndexExpr))
4059 if (!this->
visit(ArrayIndexExpr))
4061 if (!this->emitCastAPToOffsetIndex(IndexT, E))
4065 if (!this->
visit(ArrayIndexExpr))
4069 if (!this->emitCast(IndexT,
PT_Sint64, E))
4079 return this->emitOffsetOf(
T, E, E);
4082template <
class Emitter>
4091 return this->visitZeroInitializer(*
T, Ty, E);
4098 if (!this->emitGetPtrLocal(*LocalIndex, E))
4106 ElemQT = CT->getElementType();
4109 NumElems = VT->getNumElements();
4110 ElemQT = VT->getElementType();
4116 for (
unsigned I = 0; I != NumElems; ++I) {
4117 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
4119 if (!this->emitInitElem(ElemT, I, E))
4128template <
class Emitter>
4133template <
class Emitter>
4139template <
class Emitter>
4144template <
class Emitter>
4149 return this->emitConst(E->
getValue(), E);
4152template <
class Emitter>
4157 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
4172 unsigned ParamIndex = 0;
4176 if (!this->emitGetParam(PT, ParamIndex, E))
4181 return this->emitCall(F, 0, E);
4186template <
class Emitter>
4194 const Expr *PlacementDest =
nullptr;
4195 bool IsNoThrow =
false;
4200 if (PlacementArgs != 0) {
4209 if (PlacementArgs == 1) {
4217 if (!this->emitInvalidNewDeleteExpr(E, E))
4222 if (OperatorNew->isReservedGlobalPlacementOperator())
4223 PlacementDest = Arg1;
4227 return this->emitInvalid(E);
4229 }
else if (!OperatorNew
4230 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4231 return this->emitInvalidNewDeleteExpr(E, E);
4234 if (!PlacementDest) {
4239 Desc =
P.createDescriptor(E, *ElemT);
4241 Desc =
P.createDescriptor(E, ElementType.getTypePtr(),
false,
4248 std::optional<const Expr *> ArraySizeExpr = E->
getArraySize();
4252 const Expr *Stripped = *ArraySizeExpr;
4253 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
4254 Stripped = ICE->getSubExpr())
4255 if (ICE->getCastKind() != CK_NoOp &&
4256 ICE->getCastKind() != CK_IntegralCast)
4264 if (!this->
visit(Stripped))
4266 if (!this->emitSetLocal(
SizeT, ArrayLen, E))
4269 if (PlacementDest) {
4270 if (!this->
visit(PlacementDest))
4272 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
4274 if (!this->emitCheckNewTypeMismatchArray(
SizeT, E, E))
4277 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
4282 if (!this->emitAllocN(
SizeT, *ElemT, E, IsNoThrow, E))
4286 if (!this->emitAllocCN(
SizeT, Desc, IsNoThrow, E))
4293 size_t StaticInitElems = 0;
4294 const Expr *DynamicInit =
nullptr;
4298 Ctx.getASTContext().getAsConstantArrayType(InitType)) {
4299 StaticInitElems = CAT->getZExtSize();
4304 if (
const auto *ILE = dyn_cast<InitListExpr>(
Init)) {
4305 if (ILE->hasArrayFiller())
4306 DynamicInit = ILE->getArrayFiller();
4325 const Function *CtorFunc =
nullptr;
4326 if (
const auto *CE = dyn_cast<CXXConstructExpr>(
Init)) {
4330 }
else if (!DynamicInit && !ElemT)
4333 LabelTy EndLabel = this->getLabel();
4334 LabelTy StartLabel = this->getLabel();
4339 if (!this->emitDupPtr(E))
4341 if (!this->emitIsNonNullPtr(E))
4343 if (!this->jumpFalse(EndLabel, E))
4350 if (!this->emitConst(StaticInitElems,
SizeT, E))
4352 if (!this->emitSetLocal(
SizeT, Iter, E))
4355 this->fallthrough(StartLabel);
4356 this->emitLabel(StartLabel);
4358 if (!this->emitGetLocal(
SizeT, Iter, E))
4360 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
4362 if (!this->emitLT(
SizeT, E))
4364 if (!this->jumpFalse(EndLabel, E))
4368 if (!this->emitGetLocal(
SizeT, Iter, E))
4370 if (!this->emitArrayElemPtr(
SizeT, E))
4373 if (isa_and_nonnull<ImplicitValueInitExpr>(DynamicInit) &&
4378 if (!this->visitZeroInitializer(*InitT, ElemType, E))
4380 if (!this->emitStorePop(*InitT, E))
4384 if (!this->visitZeroArrayInitializer(ElemType, E))
4387 }
else if (DynamicInit) {
4389 if (!this->
visit(DynamicInit))
4391 if (!this->emitStorePop(*InitT, E))
4398 if (!this->visitZeroInitializer(
4402 if (!this->emitStorePop(*ElemT, E))
4406 if (!this->emitCall(CtorFunc, 0, E))
4411 if (!this->emitGetPtrLocal(Iter, E))
4413 if (!this->emitIncPop(
SizeT,
false, E))
4416 if (!this->jump(StartLabel, E))
4419 this->fallthrough(EndLabel);
4420 this->emitLabel(EndLabel);
4424 if (PlacementDest) {
4425 if (!this->
visit(PlacementDest))
4427 if (!this->emitCheckNewTypeMismatch(E, E))
4432 if (!this->emitAlloc(Desc, E))
4441 if (!this->emitInit(*ElemT, E))
4452 return this->emitPopPtr(E);
4457template <
class Emitter>
4463 if (!OperatorDelete->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4464 return this->emitInvalidNewDeleteExpr(E, E);
4473template <
class Emitter>
4479 if (
const Function *F =
Ctx.getOrCreateObjCBlock(E))
4484 return this->emitGetFnPtr(
Func, E);
4487template <
class Emitter>
4491 auto canonType = [](
const Type *
T) {
4492 return T->getCanonicalTypeUnqualified().getTypePtr();
4500 return this->emitGetTypeid(
4504 return this->emitGetTypeid(
4513 if (!
Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(E))
4519 if (!this->emitGetTypeidPtr(TypeInfoType, E))
4522 return this->emitPopPtr(E);
4526template <
class Emitter>
4530 return this->emitDummyPtr(E, E);
4531 return this->emitError(E);
4534template <
class Emitter>
4537 return this->emitDummyPtr(E, E);
4538 return this->emitError(E);
4541template <
class Emitter>
4543 assert(
Ctx.getLangOpts().CPlusPlus);
4544 return this->emitConstBool(E->
getValue(), E);
4547template <
class Emitter>
4559 return this->emitDummyPtr(GuidDecl, E);
4564 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4573 assert(
V.isStruct());
4574 assert(
V.getStructNumBases() == 0);
4578 return this->emitFinishInit(E);
4581template <
class Emitter>
4591template <
class Emitter>
4600template <
class Emitter>
4606template <
class Emitter>
4610 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
4614 if (OVE->isUnique())
4630template <
class Emitter>
4635template <
class Emitter>
4637 return this->emitError(E);
4640template <
class Emitter>
4646 return this->emitDummyPtr(E, E);
4649template <
class Emitter>
4650bool Compiler<Emitter>::emitVectorConversion(
const Expr *Src,
const Expr *E) {
4655 QualType ElemType = VT->getElementType();
4656 PrimType ElemT = classifyPrim(ElemType);
4658 PrimType SrcElemT = classifyVectorElementType(SrcType);
4664 if (!this->emitGetPtrLocal(*LocalIndex, E))
4668 unsigned SrcOffset =
4669 this->allocateLocalPrimitive(Src,
PT_Ptr,
true);
4670 if (!this->visit(Src))
4672 if (!this->emitSetLocal(
PT_Ptr, SrcOffset, E))
4675 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
4676 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
4678 if (!this->emitArrayElemPop(SrcElemT, I, E))
4682 if (SrcElemT != ElemT) {
4683 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
4685 }
else if (ElemType->isFloatingType() && SrcType != ElemType) {
4686 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
4690 if (!this->emitInitElem(ElemT, I, E))
4696template <
class Emitter>
4698 return emitVectorConversion(E->
getSrcExpr(), E);
4701template <
class Emitter>
4705 return this->emitInvalid(E);
4714 assert(NumOutputElems > 0);
4720 if (!this->emitGetPtrLocal(*LocalIndex, E))
4725 unsigned VectorOffsets[2];
4726 for (
unsigned I = 0; I != 2; ++I) {
4729 if (!this->
visit(Vecs[I]))
4731 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I], E))
4734 for (
unsigned I = 0; I != NumOutputElems; ++I) {
4736 assert(ShuffleIndex >= -1);
4737 if (ShuffleIndex == -1)
4738 return this->emitInvalidShuffleVectorIndex(I, E);
4740 assert(ShuffleIndex < (NumInputElems * 2));
4741 if (!this->emitGetLocal(
PT_Ptr,
4742 VectorOffsets[ShuffleIndex >= NumInputElems], E))
4744 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
4745 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
4748 if (!this->emitInitElem(ElemT, I, E))
4753 return this->emitPopPtr(E);
4758template <
class Emitter>
4763 Base->getType()->isVectorType() ||
4769 if (Indices.size() == 1) {
4774 if (!this->emitConstUint32(Indices[0], E))
4776 return this->emitArrayElemPtrPop(
PT_Uint32, E);
4786 if (!this->emitSetLocal(
PT_Ptr, BaseOffset, E))
4794 if (!this->emitGetPtrLocal(*ResultIndex, E))
4802 uint32_t DstIndex = 0;
4803 for (uint32_t I : Indices) {
4804 if (!this->emitGetLocal(
PT_Ptr, BaseOffset, E))
4806 if (!this->emitArrayElemPop(ElemT, I, E))
4808 if (!this->emitInitElem(ElemT, DstIndex, E))
4818template <
class Emitter>
4822 return this->
discard(SubExpr) && this->emitInvalid(E);
4828 return this->emitDummyPtr(E, E);
4831template <
class Emitter>
4836 Ctx.getASTContext().getAsConstantArrayType(SubExpr->
getType());
4841 if (!this->
visit(SubExpr))
4843 if (!this->emitConstUint8(0, E))
4845 if (!this->emitArrayElemPtrPopUint8(E))
4847 if (!this->emitInitFieldPtr(R->getField(0u)->Offset, E))
4850 PrimType SecondFieldT = *R->getField(1u)->T;
4852 if (!this->emitConst(
ArrayType->getSize(), SecondFieldT, E))
4854 return this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E);
4856 assert(SecondFieldT ==
PT_Ptr);
4858 if (!this->emitGetFieldPtr(R->getField(0u)->Offset, E))
4860 if (!this->emitExpandPtr(E))
4864 if (!this->emitArrayElemPtrPop(
PT_Uint64, E))
4866 return this->emitInitFieldPtr(R->getField(1u)->Offset, E);
4869template <
class Emitter>
4884 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
4888 return this->emitUnsupported(E);
4897 return this->
Visit(E);
4904 return this->
Visit(E);
4908 if (
const auto *PE = dyn_cast<ParenExpr>(E))
4911 if (
const auto *CE = dyn_cast<CastExpr>(E);
4913 (CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp))
4920 if (
const auto *PE = dyn_cast<ParenExpr>(E))
4923 if (
const auto *CE = dyn_cast<CastExpr>(E);
4924 CE && (CE->getCastKind() == CK_DerivedToBase ||
4925 CE->getCastKind() == CK_UncheckedDerivedToBase ||
4926 CE->getCastKind() == CK_NoOp))
4946 if (!this->emitGetPtrLocal(*LocalIndex, E))
4956 return this->
Visit(E);
4959template <
class Emitter>
4965 return this->
Visit(E) && this->emitFinishInit(E);
4968template <
class Emitter>
4974 return this->
Visit(E) && this->emitFinishInitPop(E);
4980 return this->
Visit(E);
4991 if (!this->
visit(E))
4993 return this->emitComplexBoolCast(E);
4998 if (!this->
visit(E))
5006 return this->emitIsNonNullPtr(E);
5010 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
5013 return this->emitCast(*
T,
PT_Bool, E);
5016template <
class Emitter>
5020 QT = AT->getValueType();
5024 return this->emitZeroBool(E);
5026 return this->emitZeroSint8(E);
5028 return this->emitZeroUint8(E);
5030 return this->emitZeroSint16(E);
5032 return this->emitZeroUint16(E);
5034 return this->emitZeroSint32(E);
5036 return this->emitZeroUint32(E);
5038 return this->emitZeroSint64(E);
5040 return this->emitZeroUint64(E);
5042 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
5044 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
5046 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
5049 return this->emitNullMemberPtr(0,
nullptr, E);
5051 APFloat F = APFloat::getZero(Ctx.getFloatSemantics(QT));
5052 return this->emitFloat(F, E);
5055 auto Sem = Ctx.getASTContext().getFixedPointSemantics(QT);
5059 llvm_unreachable(
"unknown primitive type");
5062template <
class Emitter>
5063bool Compiler<Emitter>::visitZeroRecordInitializer(
const Record *R,
5065 bool IsCompleteClass) {
5069 for (
const Record::Field &Field :
R->fields()) {
5070 if (Field.isUnnamedBitField())
5077 if (!this->visitZeroInitializer(
T, QT, E))
5080 if (!this->emitInitFieldActivate(
T, Field.Offset, E))
5084 if (!this->emitInitField(
T, Field.Offset, E))
5089 if (!this->emitGetPtrField(Field.Offset, E))
5096 if (!this->visitZeroInitializer(
T, ET, E))
5098 if (!this->emitInitElem(
T, I, E))
5103 if (!this->visitZeroArrayInitializer(D->
getType(), E))
5106 if (!this->visitZeroRecordInitializer(D->
ElemRecord, E))
5114 if (!this->emitFinishInitActivatePop(E))
5118 if (!this->emitFinishInitPop(E))
5122 for (
const Record::Base &B :
R->bases()) {
5123 if (!this->emitGetPtrBase(B.Offset, E))
5125 if (!this->visitZeroRecordInitializer(B.R, E,
false))
5127 if (!this->emitFinishInitPop(E))
5131 if (IsCompleteClass) {
5132 for (
const Record::Base &B :
R->virtual_bases()) {
5135 if (!this->visitZeroRecordInitializer(B.R, E,
false))
5137 if (!this->emitFinishInitPop(E))
5145template <
class Emitter>
5146bool Compiler<Emitter>::visitZeroArrayInitializer(
QualType T,
const Expr *E) {
5147 assert(
T->isArrayType() ||
T->isAnyComplexType() ||
T->isVectorType());
5148 const ArrayType *AT =
T->getAsArrayTypeUnsafe();
5153 for (
size_t I = 0; I != NumElems; ++I) {
5154 if (!this->visitZeroInitializer(*ElemT, ElemType, E))
5156 if (!this->emitInitElem(*ElemT, I, E))
5162 const Record *
R = getRecord(ElemType);
5166 for (
size_t I = 0; I != NumElems; ++I) {
5167 if (!this->emitConstUint32(I, E))
5169 if (!this->emitArrayElemPtr(
PT_Uint32, E))
5171 if (!this->visitZeroRecordInitializer(R, E))
5173 if (!this->emitPopPtr(E))
5179 for (
size_t I = 0; I != NumElems; ++I) {
5180 if (!this->emitConstUint32(I, E))
5182 if (!this->emitArrayElemPtr(
PT_Uint32, E))
5184 if (!this->visitZeroArrayInitializer(ElemType, E))
5186 if (!this->emitPopPtr(E))
5195template <
class Emitter>
5196bool Compiler<Emitter>::visitAssignment(
const Expr *LHS,
const Expr *RHS,
5198 if (!canClassify(E->
getType()))
5203 if (!this->visit(LHS))
5205 if (!this->visit(RHS))
5208 if (!this->visit(RHS))
5210 if (!this->visit(LHS))
5218 if (!Ctx.getLangOpts().CPlusPlus && !this->emitInvalid(E))
5222 bool Activates = refersToUnion(LHS);
5225 if (NeedsFlip && !this->emitFlip(
PT_Ptr, RHT, E))
5228 if (DiscardResult) {
5229 if (BitField && Activates)
5230 return this->emitStoreBitFieldActivatePop(RHT, E);
5232 return this->emitStoreBitFieldPop(RHT, E);
5234 return this->emitStoreActivatePop(RHT, E);
5236 return this->emitStorePop(RHT, E);
5239 auto maybeLoad = [&](
bool Result) ->
bool {
5245 return this->emitLoadPop(RHT, E);
5249 if (BitField && Activates)
5250 return maybeLoad(this->emitStoreBitFieldActivate(RHT, E));
5252 return maybeLoad(this->emitStoreBitField(RHT, E));
5254 return maybeLoad(this->emitStoreActivate(RHT, E));
5256 return maybeLoad(this->emitStore(RHT, E));
5259template <
class Emitter>
5260template <
typename T>
5264 return this->emitConstSint8(
Value, Info);
5266 return this->emitConstUint8(
Value, Info);
5268 return this->emitConstSint16(
Value, Info);
5270 return this->emitConstUint16(
Value, Info);
5272 return this->emitConstSint32(
Value, Info);
5274 return this->emitConstUint32(
Value, Info);
5276 return this->emitConstSint64(
Value, Info);
5278 return this->emitConstUint64(
Value, Info);
5280 return this->emitConstBool(
Value, Info);
5287 llvm_unreachable(
"Invalid integral type");
5290 llvm_unreachable(
"unknown primitive type");
5293template <
class Emitter>
5294template <
typename T>
5295bool Compiler<Emitter>::emitConst(
T Value,
const Expr *E) {
5296 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
5299template <
class Emitter>
5303 return this->emitConstIntAPS(
Value, Info);
5305 return this->emitConstIntAP(
Value, Info);
5307 if (
Value.isSigned())
5308 return this->emitConst(
Value.getSExtValue(), Ty, Info);
5309 return this->emitConst(
Value.getZExtValue(), Ty, Info);
5312template <
class Emitter>
5316 return this->emitConstIntAPS(
Value, Info);
5318 return this->emitConstIntAP(
Value, Info);
5321 return this->emitConst(
Value.getSExtValue(), Ty, Info);
5322 return this->emitConst(
Value.getZExtValue(), Ty, Info);
5325template <
class Emitter>
5326bool Compiler<Emitter>::emitConst(
const APSInt &
Value,
const Expr *E) {
5327 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
5330template <
class Emitter>
5343 Locals.insert({VD, Local});
5344 VarScope->addForScopeKind(Local, SC);
5345 return Local.Offset;
5348template <
class Emitter>
5353 bool IsTemporary =
false;
5357 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
5358 Init = VarD->getInit();
5360 if (
const auto *E = Src.
asExpr()) {
5370 return std::nullopt;
5375 Locals.insert({Key, Local});
5376 VarScope->addForScopeKind(Local, SC);
5377 return Local.Offset;
5380template <
class Emitter>
5389 return std::nullopt;
5399 return Local.Offset;
5402template <
class Emitter>
5404 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
5405 return PT->getPointeeType()->getAsCanonical<RecordType>();
5411 return getRecord(RecordTy->getDecl()->getDefinitionOrSelf());
5415template <
class Emitter>
5417 return P.getOrCreateRecord(RD);
5420template <
class Emitter>
5422 return Ctx.getOrCreateFunction(FD);
5425template <
class Emitter>
5429 auto maybeDestroyLocals = [&]() ->
bool {
5430 if (DestroyToplevelScope)
5431 return RootScope.
destroyLocals() && this->emitCheckAllocations(E);
5432 return this->emitCheckAllocations(E);
5439 return this->emitRetVoid(E) && maybeDestroyLocals();
5447 return this->emitRet(*
T, E) && maybeDestroyLocals();
5455 if (!this->emitGetPtrLocal(*LocalOffset, E))
5463 return this->emitRetValue(E) && maybeDestroyLocals();
5466 return maybeDestroyLocals() &&
false;
5469template <
class Emitter>
5471 bool DestroyToplevelScope) {
5475 return this->
visitExpr(E, DestroyToplevelScope);
5478template <
class Emitter>
5490 if (
auto GlobalIndex =
P.getGlobal(VD)) {
5491 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
5505template <
class Emitter>
5507 bool ConstantContext) {
5510 if (!ConstantContext) {
5525 auto GlobalIndex =
P.getGlobal(VD);
5526 assert(GlobalIndex);
5528 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
5531 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
5535 auto Local =
Locals.find(VD);
5536 assert(Local !=
Locals.end());
5539 if (!this->emitGetRefLocal(Local->second.Offset, VD))
5541 }
else if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
5544 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
5554 auto GlobalIndex =
P.getGlobal(VD);
5555 assert(GlobalIndex);
5556 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
5565 return VDScope.
destroyLocals() && this->emitCheckAllocations(VD);
5568template <
class Emitter>
5579 if (!this->isActive())
5584 if (
Init &&
Init->isValueDependent())
5588 auto checkDecl = [&]() ->
bool {
5590 return !NeedsOp || this->emitCheckDecl(VD, VD);
5597 if (!
P.getGlobal(*GlobalIndex)->isInitialized())
5600 if (
P.isGlobalInitialized(*GlobalIndex))
5604 }
else if ((GlobalIndex =
5619 return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
5622 if (!this->emitGetPtrGlobal(*GlobalIndex,
Init))
5625 if (!this->emitStartInit(
Init))
5631 if (!this->emitEndInit(
Init))
5634 return this->emitFinishInitGlobal(
Init);
5644 if (!
Init ||
Init->getType()->isVoidType())
5653 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
5665 if (!this->emitCheckRefInit(
Init))
5669 return this->emitSetLocal(*VarT, Offset, VD);
5677 if (!this->emitGetPtrLocal(*Offset,
Init))
5685template <
class Emitter>
5705 Locals.insert({VD, Local});
5708 if (!this->emitGetPtrLocal(Local.Offset, VD))
5714 return this->emitDestructionPop(D, VD);
5723 if (
const auto *P = dyn_cast<ParmVarDecl>(E->
getDecl()))
5747template <
class Emitter>
5762 unsigned ParamIndex = 0;
5769 const Expr *Arg = Args[ParamIndex];
5770 const ParmVarDecl *Param = Callee->getParamDecl(ParamIndex);
5772 unsigned ArgOffset =
5774 if (!this->
visit(Arg))
5776 if (!this->emitSetLocal(*ParamT, ArgOffset, Arg))
5782 if (!this->emitGetPtrLocal(*ArgOffset, Arg))
5794 if (
This->getType()->isPointerType()) {
5797 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(
This)) {
5804 if (!this->emitGetPtrLocal(*ArgOffset,
This))
5826template <
class Emitter>
5832 return this->emitConst(Val.
getInt(), ValType, Info);
5834 return this->emitFloat(Val.
getFloat(), Info);
5838 if (!this->emitGetMemberPtr(MemberDecl, Info))
5844 if (!this->emitCopyMemberPtrPath(PathEntry, IsDerived, Info))
5850 return this->emitNullMemberPtr(0,
nullptr, Info);
5855 return this->emitNull(ValType, 0,
nullptr, Info);
5860 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
5861 return this->
visit(BaseExpr);
5866 QualType EntryType = VD->getType();
5867 for (
auto &Entry : Path) {
5869 uint64_t Index = Entry.getAsArrayIndex();
5872 if (!this->emitConst(Index,
PT_Uint64, Info))
5874 if (!this->emitArrayElemPtrPop(
PT_Uint64, Info))
5876 EntryType = ElemType;
5883 const Decl *BaseOrMember = Entry.getAsBaseOrMember().getPointer();
5884 if (
const auto *FD = dyn_cast<FieldDecl>(BaseOrMember)) {
5886 if (!this->emitGetPtrFieldPop(EntryOffset, Info))
5888 EntryType = FD->getType();
5892 if (!this->emitGetPtrBasePop(B->Offset,
false, Info))
5897 if (!this->emitGetPtrVirtBasePop(
Base, Info))
5900 EntryType =
Ctx.getASTContext().getCanonicalTagType(
Base);
5912template <
class Emitter>
5915 bool IsCompleteClass) {
5921 if (IsCompleteClass)
5928 const Record::Base *RB = R->getBase(I);
5929 QualType BaseType =
Ctx.getASTContext().getCanonicalTagType(RB->Decl);
5931 if (!this->emitGetPtrBase(RB->Offset, Info))
5936 if (!this->emitFinishInitPop(Info))
5944 const Record::Field *RF = R->getField(I);
5945 QualType FieldType = RF->Decl->getType();
5950 if (!this->emitInitField(*PT, RF->Offset, Info))
5953 if (!this->emitGetPtrField(RF->Offset, Info))
5957 if (!this->emitFinishInitPop(Info))
5963 if (IsCompleteClass) {
5968 const Record::Base *RB = R->getVirtualBase(I);
5969 QualType BaseType =
Ctx.getASTContext().getCanonicalTagType(RB->Decl);
5977 if (!this->emitFinishInitPop(Info))
5993 const Record::Field *RF = R->getField(UnionField);
5994 QualType FieldType = RF->Decl->getType();
5999 if (RF->isBitField())
6000 return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(),
6002 return this->emitInitFieldActivate(*PT, RF->Offset, Info);
6005 if (!this->emitGetPtrField(RF->Offset, Info))
6007 if (!this->emitActivate(Info))
6011 return this->emitPopPtr(Info);
6015 const auto *ArrType =
T->getAsArrayTypeUnsafe();
6016 QualType ElemType = ArrType->getElementType();
6019 for (
unsigned A = 0, AN = Val.
getArraySize(); A != AN; ++A) {
6020 const APValue &Elem = A >= InitializedElems
6029 if (!this->emitInitElem(*ElemT, A, Info))
6032 if (!this->emitConstUint32(A, Info))
6034 if (!this->emitArrayElemPtrUint32(Info))
6038 if (!this->emitPopPtr(Info))
6049template <
class Emitter>
6051 unsigned BuiltinID) {
6052 if (BuiltinID == Builtin::BI__builtin_constant_p) {
6057 return this->emitConst(0, E);
6060 if (!this->emitStartSpeculation(E))
6062 LabelTy EndLabel = this->getLabel();
6063 if (!this->speculate(E, EndLabel))
6065 if (!this->emitEndSpeculation(E))
6067 this->fallthrough(EndLabel);
6075 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6076 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
6077 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
6078 BuiltinID == Builtin::BI__builtin_function_start) {
6081 return this->emitDummyPtr(E, E);
6092 if (!this->emitGetPtrLocal(*LocalIndex, E))
6097 switch (BuiltinID) {
6098 case Builtin::BI__builtin_object_size:
6099 case Builtin::BI__builtin_dynamic_object_size: {
6103 if (!this->
visit(Arg0))
6114 case Builtin::BI__assume:
6115 case Builtin::BI__builtin_assume:
6118 case Builtin::BI__atomic_is_lock_free:
6119 case Builtin::BI__atomic_always_lock_free: {
6130 for (
const auto *Arg : E->
arguments()) {
6131 if (!this->
visit(Arg))
6137 if (!this->emitCallBI(E, BuiltinID, E))
6155template <
class Emitter>
6176 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(FuncDecl);
6177 DD && DD->isTrivial()) {
6179 if (!this->
visit(MemberCall->getImplicitObjectArgument()))
6181 return this->emitCheckDestruction(E) && this->emitEndLifetime(E) &&
6182 this->emitPopPtr(E);
6188 bool ActivateLHS =
false;
6196 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
6197 OCE && OCE->isAssignmentOp()) {
6198 const CXXRecordDecl *LHSRecord = Args[0]->getType()->getAsCXXRecordDecl();
6201 if (
const auto *MCE = dyn_cast<CXXMemberCallExpr>(E))
6202 if (!this->
visit(MCE->getImplicitObjectArgument()))
6209 if (!this->emitTrivialCopy(ActivateLHS,
Func, E))
6227 if (!this->emitGetPtrLocal(*LocalIndex, E))
6235 if (!this->emitGetPtrLocal(*LocalIndex, E))
6239 if (!this->emitDupPtr(E))
6244 const Expr *ReversedArgs[2];
6245 bool IsAssignmentOperatorCall =
false;
6246 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
6247 OCE && OCE->isAssignmentOp()) {
6251 assert(Args.size() == 2);
6252 const CXXRecordDecl *LHSRecord = Args[0]->getType()->getAsCXXRecordDecl();
6254 IsAssignmentOperatorCall =
true;
6255 ReversedArgs[0] = Args[1];
6256 ReversedArgs[1] = Args[0];
6257 Args = ReversedArgs;
6264 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
6265 MD && MD->isStatic()) {
6269 Args = Args.drop_front();
6273 bool Devirtualized =
false;
6276 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
6284 if (!this->
visit(Callee))
6286 if (!this->emitSetLocal(
PT_MemberPtr, *CalleeOffset, E))
6288 if (!this->emitGetLocal(
PT_MemberPtr, *CalleeOffset, E))
6290 if (!this->emitGetMemberPtrBase(E))
6293 const auto *InstancePtr = MC->getImplicitObjectArgument();
6300 Stripped->getType()->getPointeeType()->getAsCXXRecordDecl());
6301 Devirtualized =
true;
6302 if (!this->
visit(Stripped))
6305 if (!this->
visit(InstancePtr))
6309 if (!this->
visit(InstancePtr))
6313 }
else if (
const auto *PD =
6314 dyn_cast<CXXPseudoDestructorExpr>(E->
getCallee())) {
6315 if (!this->emitCheckPseudoDtor(E))
6323 return this->emitPseudoDtor(E);
6324 }
else if (!FuncDecl) {
6328 if (!this->
visit(Callee))
6330 if (!this->emitSetLocal(
PT_Ptr, *CalleeOffset, E))
6339 if (IsAssignmentOperatorCall) {
6340 assert(Args.size() == 2);
6343 if (!this->emitFlip(Arg2T, Arg1T, E))
6357 assert(HasRVO ==
Func->hasRVO());
6359 bool HasQualifier =
false;
6360 if (
const auto *ME = dyn_cast<MemberExpr>(E->
getCallee()))
6361 HasQualifier = ME->hasQualifier();
6363 bool IsVirtual =
false;
6364 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
6365 IsVirtual = !Devirtualized && MD->isVirtual();
6370 if (IsVirtual && !HasQualifier) {
6371 uint32_t VarArgSize = 0;
6372 unsigned NumParams =
6373 Func->getNumWrittenParams() +
6375 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
6378 if (!this->emitCallVirt(
Func, VarArgSize, E))
6380 }
else if (
Func->isVariadic()) {
6381 uint32_t VarArgSize = 0;
6382 unsigned NumParams =
6383 Func->getNumWrittenParams() +
6385 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
6387 if (!this->emitCallVar(
Func, VarArgSize, E))
6390 if (!this->emitCall(
Func, 0, E))
6399 uint32_t ArgSize = 0;
6400 for (
unsigned I = 0, N = E->
getNumArgs(); I != N; ++I)
6406 if (!this->emitGetLocal(
PT_MemberPtr, *CalleeOffset, E))
6408 if (!this->emitGetMemberPtrDecl(E))
6411 if (!this->emitGetLocal(
PT_Ptr, *CalleeOffset, E))
6414 if (!this->emitCallPtr(ArgSize, E, E))
6425template <
class Emitter>
6432template <
class Emitter>
6439template <
class Emitter>
6444 return this->emitConstBool(E->
getValue(), E);
6447template <
class Emitter>
6453 uint64_t Val =
Ctx.getASTContext().getTargetNullPointerValue(E->
getType());
6454 return this->emitNullPtr(Val,
nullptr, E);
6457template <
class Emitter>
6465 return this->emitZero(
T, E);
6468template <
class Emitter>
6473 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
6474 if (this->LambdaThisCapture.Offset > 0) {
6475 if (this->LambdaThisCapture.IsPtr)
6476 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
6477 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
6486 return this->emitThis(E);
6501 unsigned StartIndex = 0;
6502 unsigned EndIndex = 0;
6504 for (StartIndex =
InitStack.size() - 1; StartIndex > 0; --StartIndex) {
6506 EndIndex = StartIndex;
6513 for (; StartIndex > 0; --StartIndex) {
6524 if (StartIndex == 0 && EndIndex == 0)
6535 assert(StartIndex <= EndIndex);
6538 for (
unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
6550 case Stmt::CompoundStmtClass:
6552 case Stmt::DeclStmtClass:
6554 case Stmt::ReturnStmtClass:
6556 case Stmt::IfStmtClass:
6558 case Stmt::WhileStmtClass:
6560 case Stmt::DoStmtClass:
6562 case Stmt::ForStmtClass:
6564 case Stmt::CXXForRangeStmtClass:
6566 case Stmt::BreakStmtClass:
6568 case Stmt::ContinueStmtClass:
6570 case Stmt::SwitchStmtClass:
6572 case Stmt::CaseStmtClass:
6574 case Stmt::DefaultStmtClass:
6576 case Stmt::AttributedStmtClass:
6578 case Stmt::CXXTryStmtClass:
6580 case Stmt::NullStmtClass:
6583 case Stmt::GCCAsmStmtClass:
6584 case Stmt::MSAsmStmtClass:
6585 case Stmt::GotoStmtClass:
6586 return this->emitInvalid(S);
6587 case Stmt::LabelStmtClass:
6589 case Stmt::CXXExpansionStmtInstantiationClass:
6593 if (
const auto *E = dyn_cast<Expr>(S))
6600template <
class Emitter>
6603 for (
const auto *InnerStmt : S->
body())
6606 return Scope.destroyLocals();
6609template <
class Emitter>
6610bool Compiler<Emitter>::maybeEmitDeferredVarInit(
const VarDecl *VD) {
6611 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
6612 for (
auto *BD : DD->flat_bindings())
6613 if (
auto *KD = BD->getHoldingVar();
6614 KD && !this->visitVarDecl(KD, KD->getInit()))
6628template <
class Emitter>
bool Compiler<Emitter>::refersToUnion(
const Expr *E) {
6630 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
6631 if (
const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6638 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6643 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E);
6644 ICE && (ICE->getCastKind() == CK_NoOp ||
6645 ICE->getCastKind() == CK_DerivedToBase ||
6646 ICE->getCastKind() == CK_UncheckedDerivedToBase)) {
6647 E = ICE->getSubExpr();
6651 if (
const auto *
This = dyn_cast<CXXThisExpr>(E)) {
6652 const auto *ThisRecord =
6653 This->getType()->getPointeeType()->getAsRecordDecl();
6654 if (!ThisRecord->isUnion())
6657 if (
const auto *Ctor =
6658 dyn_cast_if_present<CXXConstructorDecl>(CompilingFunction))
6659 return Ctor->getParent() == ThisRecord;
6668template <
class Emitter>
6670 bool EvaluateConditionDecl) {
6671 for (
const auto *D : DS->
decls()) {
6676 if (
const auto *ESD = dyn_cast<CXXExpansionStmtDecl>(D)) {
6677 assert(ESD->getInstantiations() &&
"not expanded?");
6678 if (!this->
visitStmt(ESD->getInstantiations()))
6683 const auto *VD = dyn_cast<VarDecl>(D);
6690 if (EvaluateConditionDecl && !this->maybeEmitDeferredVarInit(VD))
6697template <
class Emitter>
6700 return this->emitUnsupported(RS);
6706 if (!this->
visit(RE))
6712 if (RE->getType()->isVoidType()) {
6713 if (!this->
visit(RE))
6716 if (RE->containsErrors())
6721 if (!this->emitRVOPtr(RE))
6727 return this->emitRetVoid(RS);
6733 return this->emitRetVoid(RS);
6739 auto visitChildStmt = [&](
const Stmt *S) ->
bool {
6746 if (
auto *CondInit = IS->
getInit()) {
6762 return visitChildStmt(IS->
getThen());
6764 return visitChildStmt(Else);
6770 if (!this->emitIsConstantContext(IS))
6773 if (!this->emitIsConstantContext(IS))
6775 if (!this->emitInv(IS))
6789 LabelTy LabelElse = this->getLabel();
6790 LabelTy LabelEnd = this->getLabel();
6791 if (!this->jumpFalse(LabelElse, IS))
6793 if (!visitChildStmt(IS->
getThen()))
6795 if (!this->jump(LabelEnd, IS))
6797 this->emitLabel(LabelElse);
6798 if (!visitChildStmt(Else))
6800 this->emitLabel(LabelEnd);
6802 LabelTy LabelEnd = this->getLabel();
6803 if (!this->jumpFalse(LabelEnd, IS))
6805 if (!visitChildStmt(IS->
getThen()))
6807 this->emitLabel(LabelEnd);
6816template <
class Emitter>
6821 LabelTy CondLabel = this->getLabel();
6822 LabelTy EndLabel = this->getLabel();
6826 this->fallthrough(CondLabel);
6827 this->emitLabel(CondLabel);
6843 if (!this->jumpFalse(EndLabel, S))
6853 if (!this->jump(CondLabel, S))
6855 this->fallthrough(EndLabel);
6856 this->emitLabel(EndLabel);
6865 LabelTy StartLabel = this->getLabel();
6866 LabelTy EndLabel = this->getLabel();
6867 LabelTy CondLabel = this->getLabel();
6871 this->fallthrough(StartLabel);
6872 this->emitLabel(StartLabel);
6878 this->fallthrough(CondLabel);
6879 this->emitLabel(CondLabel);
6886 if (!this->jumpTrue(StartLabel, S))
6889 this->fallthrough(EndLabel);
6890 this->emitLabel(EndLabel);
6894template <
class Emitter>
6902 LabelTy EndLabel = this->getLabel();
6903 LabelTy CondLabel = this->getLabel();
6904 LabelTy IncLabel = this->getLabel();
6911 this->fallthrough(CondLabel);
6912 this->emitLabel(CondLabel);
6924 if (!this->jumpFalse(EndLabel, S))
6933 this->fallthrough(IncLabel);
6934 this->emitLabel(IncLabel);
6940 if (!this->jump(CondLabel, S))
6944 this->emitLabel(EndLabel);
6950template <
class Emitter>
6960 LabelTy EndLabel = this->getLabel();
6961 LabelTy CondLabel = this->getLabel();
6962 LabelTy IncLabel = this->getLabel();
6978 this->fallthrough(CondLabel);
6979 this->emitLabel(CondLabel);
6982 if (!this->jumpFalse(EndLabel, S))
6993 this->fallthrough(IncLabel);
6994 this->emitLabel(IncLabel);
7001 if (!this->jump(CondLabel, S))
7004 this->fallthrough(EndLabel);
7005 this->emitLabel(EndLabel);
7009template <
class Emitter>
7020 if (LI.BreakLabel) {
7021 TargetLabel = *LI.BreakLabel;
7022 BreakScope = LI.BreakOrContinueScope;
7028 if (LI.Name == TargetLoop) {
7029 TargetLabel = *LI.BreakLabel;
7030 BreakScope = LI.BreakOrContinueScope;
7041 C =
C->getParent()) {
7042 if (!
C->destroyLocals())
7046 return this->jump(*TargetLabel, S);
7049template <
class Emitter>
7060 if (LI.ContinueLabel) {
7061 TargetLabel = *LI.ContinueLabel;
7062 ContinueScope = LI.BreakOrContinueScope;
7068 if (LI.Name == TargetLoop) {
7069 TargetLabel = *LI.ContinueLabel;
7070 ContinueScope = LI.BreakOrContinueScope;
7080 C =
C->getParent()) {
7081 if (!
C->destroyLocals())
7085 return this->jump(*TargetLabel, S);
7088template <
class Emitter>
7098 LabelTy EndLabel = this->getLabel();
7103 if (
const auto *CondInit = S->
getInit())
7112 if (!this->
visit(Cond))
7114 if (!this->emitSetLocal(CondT, CondVar, S))
7124 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
7127 if (CS->caseStmtIsGNURange()) {
7128 LabelTy EndOfRangeCheck = this->getLabel();
7129 const Expr *Low = CS->getLHS();
7130 const Expr *High = CS->getRHS();
7134 if (!this->emitGetLocal(CondT, CondVar, CS))
7136 if (!this->
visit(Low))
7139 if (!this->emitGE(
LT, S))
7141 if (!this->jumpFalse(EndOfRangeCheck, S))
7144 if (!this->emitGetLocal(CondT, CondVar, CS))
7146 if (!this->
visit(High))
7149 if (!this->emitLE(HT, S))
7153 this->emitLabel(EndOfRangeCheck);
7158 if (
Value->isValueDependent())
7163 if (!this->emitGetLocal(CondT, CondVar, CS))
7169 if (!this->emitEQ(ValueT, S))
7174 assert(!DefaultLabel);
7175 DefaultLabel = this->getLabel();
7182 if (!this->jump(*DefaultLabel, S))
7185 if (!this->jump(EndLabel, S))
7193 this->fallthrough(EndLabel);
7194 this->emitLabel(EndLabel);
7199template <
class Emitter>
7207 return this->emitUnsupported(S);
7212template <
class Emitter>
7219 if (LI.DefaultLabel) {
7220 DefaultLabel = *LI.DefaultLabel;
7225 this->emitLabel(DefaultLabel);
7229template <
class Emitter>
7236 if (IsMSVCConstexprAttr && !this->emitPushMSVCCE(S))
7239 if (this->
Ctx.getLangOpts().CXXAssumptions &&
7240 !this->Ctx.getLangOpts().MSVCCompat) {
7242 auto *AA = dyn_cast<CXXAssumeAttr>(A);
7248 const Expr *Assumption = AA->getAssumption();
7259 if (!this->emitAssume(Assumption))
7268 if (IsMSVCConstexprAttr)
7269 return this->emitPopMSVCCE(S);
7273template <
class Emitter>
7286template <
class Emitter>
7296 LabelTy EndLabel = this->getLabel();
7298 LabelTy ContinueLabel = this->getLabel();
7303 this->emitLabel(ContinueLabel);
7306 this->emitLabel(EndLabel);
7311template <
class Emitter>
7312bool Compiler<Emitter>::emitLambdaStaticInvokerBody(
const CXXMethodDecl *MD) {
7319 assert(ClosureClass->
captures().empty());
7323 "A generic lambda's static-invoker function must be a "
7324 "template specialization");
7328 llvm::FoldingSetInsertToken InsertToken;
7329 const FunctionDecl *CorrespondingCallOpSpecialization =
7331 assert(CorrespondingCallOpSpecialization);
7332 LambdaCallOp = CorrespondingCallOpSpecialization;
7336 assert(ClosureClass->
captures().empty());
7337 const Function *
Func = this->getFunction(LambdaCallOp);
7340 assert(
Func->hasThisPointer());
7343 if (
Func->hasRVO()) {
7344 if (!this->emitRVOPtr(MD))
7352 if (!this->emitNullPtr(0,
nullptr, MD))
7357 auto It = this->Params.find(PVD);
7358 assert(It != this->Params.end());
7362 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
7363 if (!this->emitGetParam(ParamType, It->second.Index, MD))
7367 if (!this->emitCall(
Func, 0, LambdaCallOp))
7372 return this->emitRet(*ReturnType, MD);
7375 return this->emitRetVoid(MD);
7378template <
class Emitter>
7379bool Compiler<Emitter>::checkLiteralType(
const Expr *E) {
7380 if (Ctx.getLangOpts().CPlusPlus23)
7390 const Expr *InitExpr =
Init->getInit();
7392 if (!
Init->isWritten() && !
Init->isInClassMemberInitializer() &&
7396 if (
const auto *CE = dyn_cast<CXXConstructExpr>(InitExpr)) {
7406template <
class Emitter>
7408 assert(!ReturnType);
7411 if (!this->emitStartThisLifetime1(Ctor))
7414 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
7415 const Expr *InitExpr,
7418 if (InitExpr->getType().isNull())
7422 if (
Activate && !this->emitActivateThisField(FieldOffset, InitExpr))
7425 if (!this->visit(InitExpr))
7428 if (F->isBitField())
7429 return this->emitInitThisBitField(*
T, FieldOffset, F->bitWidth(),
7431 return this->emitInitThisField(*
T, FieldOffset, InitExpr);
7436 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
7439 if (
Activate && !this->emitActivate(InitExpr))
7442 return this->visitInitializerPop(InitExpr);
7446 const Record *
R = this->getRecord(RD);
7449 bool IsUnion =
R->isUnion();
7459 if (!this->emitThis(Ctor))
7462 if (!this->emitGetParam(
PT_Ptr, 0, Ctor))
7465 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
7466 this->emitRetVoid(Ctor);
7469 unsigned FieldInits = 0;
7472 if (
R->getNumVirtualBases() > 0) {
7473 if (!this->emitThis(Ctor))
7475 LabelTy AfterVirtBasesLabel = this->getLabel();
7478 if (!this->emitIsBaseClass({}))
7480 if (!this->jumpTrue(AfterVirtBasesLabel, {}))
7483 for (
const auto *
Init : Ctor->
inits()) {
7486 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
7488 assert(
R->findVirtualBase(BaseDecl));
7489 if (!this->emitGetPtrThisVirtBase(BaseDecl, Ctor))
7491 if (!this->visitInitializerPop(
Init->getInit()))
7496 this->fallthrough(AfterVirtBasesLabel);
7497 this->emitLabel(AfterVirtBasesLabel);
7499 if (!this->emitPopPtr(Ctor))
7503 for (
const auto *
Init : Ctor->
inits()) {
7507 const Expr *InitExpr =
Init->getInit();
7509 const Record::Field *F =
R->getField(
Member);
7513 if (!emitFieldInitializer(F, F->Offset, InitExpr, IsUnion))
7517 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
7520 if (
Init->isBaseVirtual()) {
7526 const Record::Base *B =
R->getBase(BaseDecl);
7528 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
7532 if (!this->visitInitializerPop(InitExpr))
7537 unsigned ChainSize = IFD->getChainingSize();
7538 assert(ChainSize >= 2);
7540 unsigned NestedFieldOffset = 0;
7541 const Record::Field *NestedField =
nullptr;
7542 for (
unsigned I = 0; I != ChainSize; ++I) {
7544 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
7545 assert(FieldRecord);
7547 NestedField = FieldRecord->
getField(FD);
7548 assert(NestedField);
7549 IsUnion = IsUnion || FieldRecord->
isUnion();
7551 NestedFieldOffset += NestedField->Offset;
7554 if (I != ChainSize - 1)
7557 assert(NestedField);
7560 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
7565 unsigned InitFieldOffset = 0;
7566 for (
const NamedDecl *ND : IFD->chain().drop_back()) {
7568 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
7569 assert(FieldRecord);
7570 NestedField = FieldRecord->
getField(FD);
7571 InitFieldOffset += NestedField->Offset;
7572 assert(NestedField);
7573 if (!this->emitGetPtrThisField(InitFieldOffset, InitExpr))
7575 if (!this->emitFinishInitPop(InitExpr))
7579 InitStack.pop_back_n(ChainSize - 1);
7582 assert(
Init->isDelegatingInitializer());
7583 if (!this->emitThis(InitExpr))
7585 if (!this->visitInitializerPop(
Init->getInit()))
7589 if (!
Scope.destroyLocals())
7593 if (FieldInits !=
R->getNumFields()) {
7594 assert(FieldInits < R->getNumFields());
7596 if (!this->emitStartThisLifetime(Ctor))
7603 if (
const auto *CS = dyn_cast<CompoundStmt>(Body)) {
7604 if (!CS->body_empty() && !this->emitCtorCheck(
SourceInfo{}))
7611 if (!visitStmt(Body))
7618template <
class Emitter>
7621 const Record *
R = this->getRecord(RD);
7625 if (!
Dtor->isTrivial() &&
Dtor->getBody()) {
7626 if (!this->visitStmt(
Dtor->getBody()))
7630 if (!this->emitThis(
Dtor))
7633 if (!this->emitCheckDestruction(
Dtor))
7637 if (!
R->isUnion()) {
7641 for (
const Record::Field &Field : llvm::reverse(
R->fields())) {
7645 if (!this->emitGetPtrField(Field.Offset,
SourceInfo{}))
7647 if (!this->emitDestructionPop(D,
SourceInfo{}))
7652 for (
const Record::Base &
Base : llvm::reverse(
R->bases())) {
7653 if (
Base.R->hasTrivialDtor())
7657 if (!this->emitRecordDestructionPop(
Base.R, {}))
7661 if (
R->getNumVirtualBases() > 0) {
7662 LabelTy EndLabel = this->getLabel();
7664 if (!this->emitIsBaseClass({}))
7666 if (!this->jumpTrue(EndLabel, {}))
7669 for (
const Record::Base &
Base : llvm::reverse(
R->virtual_bases())) {
7670 if (
Base.R->hasTrivialDtor())
7675 if (!this->emitRecordDestructionPop(
Base.R, {}))
7679 this->fallthrough(EndLabel);
7680 this->emitLabel(EndLabel);
7683 if (!this->emitMarkDestroyed(
Dtor))
7686 return this->emitPopPtr(
Dtor) && this->emitRetVoid(
Dtor);
7689template <
class Emitter>
7690bool Compiler<Emitter>::compileUnionAssignmentOperator(
7692 if (!this->emitThis(MD))
7695 if (!this->emitGetParam(
PT_Ptr, 0, MD))
7698 return this->emitMemcpy(MD) && this->emitRet(
PT_Ptr, MD);
7701template <
class Emitter>
7711 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
7712 return this->compileConstructor(Ctor);
7713 if (
const auto *
Dtor = dyn_cast<CXXDestructorDecl>(F))
7714 return this->compileDestructor(
Dtor);
7717 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
7722 return this->compileUnionAssignmentOperator(MD);
7725 return this->emitLambdaStaticInvokerBody(MD);
7729 if (
const auto *Body = F->
getBody())
7743 return FD->getBitWidthValue();
7746template <
class Emitter>
7762 if (!
Ctx.getLangOpts().CPlusPlus14)
7763 return this->emitInvalid(E);
7765 return this->emitError(E);
7767 if (!this->
visit(SubExpr))
7771 if (!this->emitIncPtr(E))
7778 return DiscardResult ? this->emitIncfPop(getFPOptions(E), E)
7779 : this->emitIncf(getFPOptions(E), E);
7791 if (!
Ctx.getLangOpts().CPlusPlus14)
7792 return this->emitInvalid(E);
7794 return this->emitError(E);
7796 if (!this->
visit(SubExpr))
7800 if (!this->emitDecPtr(E))
7807 return DiscardResult ? this->emitDecfPop(getFPOptions(E), E)
7808 : this->emitDecf(getFPOptions(E), E);
7821 if (!
Ctx.getLangOpts().CPlusPlus14)
7822 return this->emitInvalid(E);
7824 return this->emitError(E);
7826 if (!this->
visit(SubExpr))
7830 if (!this->emitLoadPtr(E))
7832 if (!this->emitConstUint8(1, E))
7834 if (!this->emitAddOffsetUint8(E))
7836 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7842 return this->emitIncfPop(getFPOptions(E), E);
7852 const auto &TargetSemantics =
Ctx.getFloatSemantics(E->
getType());
7853 if (!this->emitLoadFloat(E))
7855 APFloat F(TargetSemantics, 1);
7856 if (!this->emitFloat(F, E))
7859 if (!this->emitAddf(getFPOptions(E), E))
7861 if (!this->emitStoreFloat(E))
7873 return E->
isGLValue() || this->emitLoadPop(*
T, E);
7876 if (!
Ctx.getLangOpts().CPlusPlus14)
7877 return this->emitInvalid(E);
7879 return this->emitError(E);
7881 if (!this->
visit(SubExpr))
7885 if (!this->emitLoadPtr(E))
7887 if (!this->emitConstUint8(1, E))
7889 if (!this->emitSubOffsetUint8(E))
7891 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7897 return this->emitDecfPop(getFPOptions(E), E);
7907 const auto &TargetSemantics =
Ctx.getFloatSemantics(E->
getType());
7908 if (!this->emitLoadFloat(E))
7910 APFloat F(TargetSemantics, 1);
7911 if (!this->emitFloat(F, E))
7914 if (!this->emitSubf(getFPOptions(E), E))
7916 if (!this->emitStoreFloat(E))
7928 return E->
isGLValue() || this->emitLoadPop(*
T, E);
7932 return this->emitError(E);
7935 return this->
discard(SubExpr);
7940 if (!this->emitInv(E))
7944 return this->emitCast(
PT_Bool, ET, E);
7948 return this->emitError(E);
7950 if (!this->
visit(SubExpr))
7955 return this->emitError(E);
7957 if (!this->
visit(SubExpr))
7973 if (!
Ctx.getLangOpts().CPlusPlus) {
7976 if (
const auto *Deref = dyn_cast<UnaryOperator>(
Sub);
7977 Deref && Deref->getOpcode() == UO_Deref) {
7979 return this->
discard(Deref->getSubExpr());
7980 return this->
visit(Deref->getSubExpr()) && this->emitAddrOf(E);
7985 return this->
discard(SubExpr);
7986 return this->
delegate(SubExpr) && this->emitAddrOf(E);
7989 return this->
discard(SubExpr);
7991 if (!this->
visit(SubExpr))
7998 return this->emitNarrowPtr(E);
8003 return this->emitError(E);
8005 if (!this->
visit(SubExpr))
8019 : this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
8024 assert(
false &&
"Unhandled opcode");
8030template <
class Emitter>
8036 return this->
discard(SubExpr);
8039 auto prepareResult = [=]() ->
bool {
8044 return this->emitGetPtrLocal(*LocalIndex, E);
8051 unsigned SubExprOffset = ~0u;
8052 auto createTemp = [=, &SubExprOffset]() ->
bool {
8055 if (!this->
visit(SubExpr))
8057 return this->emitSetLocal(
PT_Ptr, SubExprOffset, E);
8061 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
8062 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
8064 return this->emitArrayElemPop(ElemT, Index, E);
8069 if (!prepareResult())
8073 for (
unsigned I = 0; I != 2; ++I) {
8074 if (!getElem(SubExprOffset, I))
8076 if (!this->emitNeg(ElemT, E))
8078 if (!this->emitInitElem(ElemT, I, E))
8089 if (!this->
visit(SubExpr))
8091 if (!this->emitComplexBoolCast(SubExpr))
8093 if (!this->emitInv(E))
8096 return this->emitCast(
PT_Bool, ET, E);
8100 return this->emitComplexReal(SubExpr);
8103 if (!this->
visit(SubExpr))
8107 if (!this->emitConstUint8(1, E))
8109 return this->emitArrayElemPtrPopUint8(E);
8120 if (!this->emitArrayElem(ElemT, 1, E))
8122 if (!this->emitNeg(ElemT, E))
8124 if (!this->emitInitElem(ElemT, 1, E))
8132 return this->emitInvalid(E);
8138template <
class Emitter>
8144 return this->
discard(SubExpr);
8147 if (UnaryOp == UO_Extension)
8150 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
8151 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
8152 return this->emitInvalid(E);
8155 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
8162 if (!this->emitGetPtrLocal(*LocalIndex, E))
8167 unsigned SubExprOffset =
8169 if (!this->
visit(SubExpr))
8171 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, E))
8176 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
8177 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
8179 return this->emitArrayElemPop(ElemT, Index, E);
8184 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8185 if (!getElem(SubExprOffset, I))
8187 if (!this->emitNeg(ElemT, E))
8189 if (!this->emitInitElem(ElemT, I, E))
8204 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8205 if (!getElem(SubExprOffset, I))
8208 if (!this->emitPrimCast(ElemT,
PT_Bool,
Ctx.getASTContext().BoolTy, E))
8210 if (!this->emitInv(E))
8212 if (!this->emitPrimCast(
PT_Bool, ElemT, VecTy->getElementType(), E))
8214 if (!this->emitNeg(ElemT, E))
8216 if (ElemT != ResultVecElemT &&
8217 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy, E))
8219 if (!this->emitInitElem(ResultVecElemT, I, E))
8225 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8226 if (!getElem(SubExprOffset, I))
8229 if (!this->emitInv(E))
8232 if (!this->emitComp(ElemT, E))
8235 if (!this->emitInitElem(ElemT, I, E))
8240 llvm_unreachable(
"Unsupported unary operators should be handled up front");
8245template <
class Emitter>
8247 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
8250 return this->emitConst(ECD->getInitVal(), E);
8252 if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
8256 return F && this->emitGetFnPtr(F, E);
8258 if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
8259 TPOD = TPOD->getFirstDecl();
8263 return this->emitGetPtrGlobal(*GlobalIndex, E);
8269 return this->emitInitGlobal(*
T, *Index, E);
8272 if (!this->emitGetPtrGlobal(*Index, E))
8276 return this->emitFinishInit(E);
8288 auto maybePopPtr = [&]() ->
bool {
8290 return this->emitPopPtr(E);
8297 if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
8301 if (
Ctx.getLangOpts().CPlusPlus && !
Ctx.getLangOpts().CPlusPlus11 &&
8306 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
8307 if (IsReference || !It->second.IsPtr)
8308 return this->emitGetParam(
classifyPrim(E), It->second.Index, E);
8310 return this->emitGetPtrParam(It->second.Index, E);
8313 if (!
Ctx.getLangOpts().CPlusPlus23 && IsReference && !
Locals.contains(D))
8320 const unsigned Offset = It->second.Offset;
8323 return this->emitGetRefLocal(Offset, E) && maybePopPtr();
8325 return this->emitGetPtrLocal(Offset, E) && maybePopPtr();
8328 if (
auto GlobalIndex =
P.getGlobal(D)) {
8330 if (!
Ctx.getLangOpts().CPlusPlus11)
8331 return this->emitGetGlobal(
classifyPrim(E), *GlobalIndex, E);
8332 if (!
Ctx.getLangOpts().CPlusPlus23)
8333 return this->emitGetGlobalUnchecked(
classifyPrim(E), *GlobalIndex, E);
8335 return this->emitGetRefGlobal(*GlobalIndex, E) && maybePopPtr();
8338 return this->emitGetPtrGlobal(*GlobalIndex, E) && maybePopPtr();
8342 auto revisit = [&](
const VarDecl *VD,
8343 bool IsConstexprUnknown =
true) ->
bool {
8345 IsConstexprUnknown);
8346 if constexpr (std::is_same_v<Emitter, EvalEmitter>) {
8352 if constexpr (std::is_same_v<Emitter, EvalEmitter>) {
8353 if (!this->emitPopCC(E))
8357 if (VarState.notCreated())
8365 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
8367 if (
auto It = this->LambdaCaptures.find(D);
8368 It != this->LambdaCaptures.end()) {
8369 auto [Offset, IsPtr] = It->second;
8372 return this->emitGetThisFieldPtr(Offset, E) && maybePopPtr();
8373 return this->emitGetPtrThisField(Offset, E) && maybePopPtr();
8377 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E);
8378 DRE && DRE->refersToEnclosingVariableOrCapture()) {
8379 if (
const auto *VD = dyn_cast<VarDecl>(D); VD && VD->
isInitCapture())
8383 if (
const auto *BD = dyn_cast<BindingDecl>(D))
8384 return this->
delegate(BD->getBinding());
8390 return this->emitDummyPtr(D, E);
8395 const auto *VD = dyn_cast<VarDecl>(D);
8397 return this->emitError(E);
8400 if (!
Ctx.getLangOpts().CPlusPlus) {
8404 return revisit(VD,
false);
8408 return this->emitDummyPtr(D, E);
8412 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
8413 if (
T.isConstant(
Ctx.getASTContext()))
8415 return T->isReferenceType();
8419 typeShouldBeVisited(DeclType)) {
8421 Init && !
Init->isValueDependent()) {
8426 (void)
Init->EvaluateAsInitializer(
Ctx.getASTContext(), VD,
Result,
true);
8439 bool IsConstexprUnknown = !DeclType.
isConstant(
Ctx.getASTContext()) &&
8444 return revisit(VD, IsConstexprUnknown);
8445 }
else if (
Ctx.getLangOpts().CPlusPlus23 && IsReference)
8446 return revisit(VD,
true);
8455 return this->emitDummyPtr(
8459template <
class Emitter>
8465template <
class Emitter>
8475 if (!
C->destroyLocals())
8481template <
class Emitter>
8482unsigned Compiler<Emitter>::collectBaseOffset(
const QualType BaseType,
8485 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
8487 return Ty->getAsCXXRecordDecl();
8489 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
8490 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
8492 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
8496template <
class Emitter>
8503 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
8508 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
8509 getFPOptions(E), E);
8511 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
8512 getFPOptions(E), E);
8516 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
8521 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
8523 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
8527 return FromT != ToT ? this->emitCast(FromT, ToT, E) :
true;
8531 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
8532 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E);
8539template <
class Emitter>
8542 assert(FromT != ToT);
8545 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
8547 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
8549 return this->emitCast(FromT, ToT, E);
8553template <
class Emitter>
8554bool Compiler<Emitter>::emitComplexReal(
const Expr *SubExpr) {
8558 return this->
discard(SubExpr);
8560 if (!this->visit(SubExpr))
8563 if (!this->emitConstUint8(0, SubExpr))
8565 return this->emitArrayElemPtrPopUint8(SubExpr);
8569 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
8573template <
class Emitter>
8574bool Compiler<Emitter>::emitComplexBoolCast(
const Expr *E) {
8575 assert(!DiscardResult);
8579 if (!this->emitArrayElem(ElemT, 0, E))
8582 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(E), E))
8585 if (!this->emitCast(ElemT,
PT_Bool, E))
8590 LabelTy LabelTrue = this->getLabel();
8591 if (!this->jumpTrue(LabelTrue, E))
8594 if (!this->emitArrayElemPop(ElemT, 1, E))
8597 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(E), E))
8600 if (!this->emitCast(ElemT,
PT_Bool, E))
8604 LabelTy EndLabel = this->getLabel();
8605 this->jump(EndLabel, E);
8607 this->emitLabel(LabelTrue);
8608 if (!this->emitPopPtr(E))
8610 if (!this->emitConstBool(
true, E))
8613 this->fallthrough(EndLabel);
8614 this->emitLabel(EndLabel);
8619template <
class Emitter>
8620bool Compiler<Emitter>::emitComplexComparison(
const Expr *LHS,
const Expr *RHS,
8631 LHSIsComplex =
true;
8632 ElemT = classifyComplexElementType(LHS->
getType());
8633 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true);
8634 if (!this->visit(LHS))
8636 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
8639 LHSIsComplex =
false;
8641 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true);
8642 if (!this->visit(LHS))
8644 if (!this->emitSetLocal(LHST, LHSOffset, E))
8651 RHSIsComplex =
true;
8652 ElemT = classifyComplexElementType(RHS->
getType());
8653 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true);
8654 if (!this->visit(RHS))
8656 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
8659 RHSIsComplex =
false;
8661 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true);
8662 if (!this->visit(RHS))
8664 if (!this->emitSetLocal(RHST, RHSOffset, E))
8668 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
8669 bool IsComplex) ->
bool {
8671 if (!this->emitGetLocal(
PT_Ptr, LocalOffset, E))
8673 return this->emitArrayElemPop(ElemT, Index, E);
8675 return this->emitGetLocal(ElemT, LocalOffset, E);
8678 for (
unsigned I = 0; I != 2; ++I) {
8680 if (!getElem(LHSOffset, I, LHSIsComplex))
8682 if (!getElem(RHSOffset, I, RHSIsComplex))
8685 if (!this->emitEQ(ElemT, E))
8688 if (!this->emitCastBoolUint8(E))
8693 if (!this->emitAddUint8(E))
8695 if (!this->emitConstUint8(2, E))
8699 if (!this->emitEQUint8(E))
8702 if (!this->emitNEUint8(E))
8709 return this->emitCast(
PT_Bool, ResT, E);
8716template <
class Emitter>
8717bool Compiler<Emitter>::emitRecordDestructionPop(
const Record *R,
8720 assert(!
R->hasTrivialDtor());
8723 const Function *DtorFunc = getFunction(
Dtor);
8726 assert(DtorFunc->hasThisPointer());
8727 assert(DtorFunc->getNumParams() == 1);
8728 return this->emitCall(DtorFunc, 0, Loc);
8733template <
class Emitter>
8734bool Compiler<Emitter>::emitDestructionPop(
const Descriptor *Desc,
8746 return this->emitPopPtr(Loc);
8748 for (ssize_t I = N - 1; I >= 1; --I) {
8749 if (!this->emitConstUint64(I, Loc))
8751 if (!this->emitArrayElemPtrUint64(Loc))
8753 if (!this->emitDestructionPop(ElemDesc, Loc))
8757 if (!this->emitConstUint64(0, Loc))
8759 if (!this->emitArrayElemPtrPopUint64(Loc))
8761 return this->emitDestructionPop(ElemDesc, Loc);
8766 return this->emitRecordDestructionPop(Desc->
ElemRecord, Loc);
8771template <
class Emitter>
8772bool Compiler<Emitter>::emitDummyPtr(
DeclOrExpr D,
const Expr *E,
bool CU) {
8773 assert(!DiscardResult &&
"Should've been checked before");
8774 return this->emitGetOpaquePtr(D, CU, E);
8777template <
class Emitter>
8780 return this->emitConstFloat(
Floating(F), Info);
8782 APInt I = F.bitcastToAPInt();
8783 return this->emitConstFloat(
8784 Floating(
const_cast<uint64_t *
>(I.getRawData()),
8785 llvm::APFloatBase::SemanticsToEnum(F.getSemantics())),
8796template <
class Emitter>
8797bool Compiler<Emitter>::emitBuiltinBitCast(
const CastExpr *E) {
8810 if (!this->emitGetPtrLocal(*LocalIndex, E))
8820 if (!this->visit(SubExpr))
8822 }
else if (
OptPrimType FromT = classify(SubExpr)) {
8823 unsigned TempOffset =
8824 allocateLocalPrimitive(SubExpr, *FromT,
true);
8825 if (!this->visit(SubExpr))
8827 if (!this->emitSetLocal(*FromT, TempOffset, E))
8829 if (!this->emitGetPtrLocal(TempOffset, E))
8836 if (!this->emitBitCast(E))
8838 return DiscardResult ? this->emitPopPtr(E) :
true;
8842 const llvm::fltSemantics *TargetSemantics =
nullptr;
8844 TargetSemantics = &Ctx.getFloatSemantics(ToType);
8850 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
8852 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->
isStdByteType(),
8853 ResultBitWidth, TargetSemantics,
8858 return this->emitPop(*ToT, E);
8867template <
class Emitter>
8868bool Compiler<Emitter>::emitHLSLAggregateSplat(
PrimType SrcT,
8873 unsigned NumElems = 0;
8876 NumElems = VT->getNumElements();
8877 ElemType = VT->getElementType();
8879 NumElems = MT->getNumElementsFlattened();
8880 ElemType = MT->getElementType();
8883 PrimType ElemT = classifyPrim(ElemType);
8884 for (
unsigned I = 0; I != NumElems; ++I) {
8885 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8887 if (!this->emitPrimCast(SrcT, ElemT, ElemType, E))
8889 if (!this->emitInitElem(ElemT, I, E))
8899 QualType ArrElemType = CAT->getElementType();
8900 unsigned ArrSize = CAT->getZExtSize();
8903 for (
unsigned I = 0; I != ArrSize; ++I) {
8904 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8906 if (!this->emitPrimCast(SrcT, *ElemT, ArrElemType, E))
8908 if (!this->emitInitElem(*ElemT, I, E))
8912 for (
unsigned I = 0; I != ArrSize; ++I) {
8913 if (!this->emitConstUint32(I, E))
8915 if (!this->emitArrayElemPtrUint32(E))
8917 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, ArrElemType, E))
8919 if (!this->emitFinishInitPop(E))
8929 const Record *
R = getRecord(DestType);
8933 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
8935 const Record::Base *B =
R->getBase(BS.getType());
8937 if (!this->emitGetPtrBase(B->Offset, E))
8939 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, BS.getType(), E))
8941 if (!this->emitFinishInitPop(E))
8946 for (
const Record::Field &F :
R->fields()) {
8947 if (F.isUnnamedBitField())
8950 QualType FieldType = F.Decl->getType();
8952 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8954 if (!this->emitPrimCast(SrcT, *FieldT, FieldType, E))
8956 if (F.isBitField()) {
8957 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
8960 if (!this->emitInitField(*FieldT, F.Offset, E))
8964 if (!this->emitGetPtrField(F.Offset, E))
8966 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, FieldType, E))
8968 if (!this->emitPopPtr(E))
8981template <
class Emitter>
8982unsigned Compiler<Emitter>::countHLSLFlatElements(
QualType Ty) {
8985 return VT->getNumElements();
8987 return MT->getNumElementsFlattened();
8991 return CAT->getZExtSize() * countHLSLFlatElements(CAT->getElementType());
8995 const Record *
R = getRecord(Ty);
8999 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
9001 Count += countHLSLFlatElements(BS.getType());
9003 for (
const Record::Field &F :
R->fields()) {
9004 if (F.isUnnamedBitField())
9006 Count += countHLSLFlatElements(F.Decl->getType());
9011 if (canClassify(Ty))
9020template <
class Emitter>
9021bool Compiler<Emitter>::emitHLSLFlattenAggregate(
9022 QualType SrcType,
unsigned SrcOffset,
9027 auto saveToLocal = [&](
PrimType T) ->
bool {
9028 unsigned Offset = allocateLocalPrimitive(E,
T,
true);
9029 if (!this->emitSetLocal(
T, Offset, E))
9031 Elements.push_back({Offset,
T});
9037 unsigned Offset = allocateLocalPrimitive(E,
PT_Ptr,
true);
9038 if (!this->emitSetLocal(
PT_Ptr, Offset, E))
9039 return std::nullopt;
9044 unsigned NumElems = 0;
9047 NumElems = VT->getNumElements();
9048 ElemType = VT->getElementType();
9050 NumElems = MT->getNumElementsFlattened();
9051 ElemType = MT->getElementType();
9054 PrimType ElemT = classifyPrim(ElemType);
9055 for (
unsigned I = 0; I != NumElems && Elements.size() < MaxElements; ++I) {
9056 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9058 if (!this->emitArrayElemPop(ElemT, I, E))
9060 if (!saveToLocal(ElemT))
9070 QualType ArrElemType = CAT->getElementType();
9071 unsigned ArrSize = CAT->getZExtSize();
9074 for (
unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
9075 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9077 if (!this->emitArrayElemPop(*ElemT, I, E))
9079 if (!saveToLocal(*ElemT))
9083 for (
unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
9084 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9086 if (!this->emitConstUint32(I, E))
9088 if (!this->emitArrayElemPtrPopUint32(E))
9093 if (!emitHLSLFlattenAggregate(ArrElemType, *ElemPtrOffset, Elements,
9104 const Record *
R = getRecord(SrcType);
9108 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
9110 if (Elements.size() >= MaxElements)
9112 const Record::Base *B =
R->getBase(BS.getType());
9114 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9116 if (!this->emitGetPtrBasePop(B->Offset,
false, E))
9121 if (!emitHLSLFlattenAggregate(BS.getType(), *BasePtrOffset, Elements,
9127 for (
const Record::Field &F :
R->fields()) {
9128 if (Elements.size() >= MaxElements)
9130 if (F.isUnnamedBitField())
9133 QualType FieldType = F.Decl->getType();
9134 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9136 if (!this->emitGetPtrFieldPop(F.Offset, E))
9140 if (!this->emitLoadPop(*FieldT, E))
9142 if (!saveToLocal(*FieldT))
9146 if (!FieldPtrOffset)
9148 if (!emitHLSLFlattenAggregate(FieldType, *FieldPtrOffset, Elements,
9164template <
class Emitter>
9165bool Compiler<Emitter>::emitHLSLConstructAggregate(
9171 const auto &Src = Elements[ElemIdx++];
9172 if (!this->emitGetLocal(Src.Type, Src.LocalOffset, E))
9174 return this->emitPrimCast(Src.Type, DestT, DestQT, E);
9178 unsigned NumElems = 0;
9181 NumElems = VT->getNumElements();
9182 ElemType = VT->getElementType();
9184 NumElems = MT->getNumElementsFlattened();
9185 ElemType = MT->getElementType();
9188 PrimType DestElemT = classifyPrim(ElemType);
9189 for (
unsigned I = 0; I != NumElems; ++I) {
9190 if (!loadAndCast(DestElemT, ElemType))
9192 if (!this->emitInitElem(DestElemT, I, E))
9202 QualType ArrElemType = CAT->getElementType();
9203 unsigned ArrSize = CAT->getZExtSize();
9206 for (
unsigned I = 0; I != ArrSize; ++I) {
9207 if (!loadAndCast(*ElemT, ArrElemType))
9209 if (!this->emitInitElem(*ElemT, I, E))
9213 for (
unsigned I = 0; I != ArrSize; ++I) {
9214 if (!this->emitConstUint32(I, E))
9216 if (!this->emitArrayElemPtrUint32(E))
9218 if (!emitHLSLConstructAggregate(ArrElemType, Elements, ElemIdx, E))
9220 if (!this->emitFinishInitPop(E))
9230 const Record *
R = getRecord(DestType);
9234 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
9236 const Record::Base *B =
R->getBase(BS.getType());
9238 if (!this->emitGetPtrBase(B->Offset, E))
9240 if (!emitHLSLConstructAggregate(BS.getType(), Elements, ElemIdx, E))
9242 if (!this->emitFinishInitPop(E))
9247 for (
const Record::Field &F :
R->fields()) {
9248 if (F.isUnnamedBitField())
9251 QualType FieldType = F.Decl->getType();
9253 if (!loadAndCast(*FieldT, FieldType))
9255 if (F.isBitField()) {
9256 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
9259 if (!this->emitInitField(*FieldT, F.Offset, E))
9263 if (!this->emitGetPtrField(F.Offset, E))
9265 if (!emitHLSLConstructAggregate(FieldType, Elements, ElemIdx, E))
9267 if (!this->emitPopPtr(E))
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static void emitCleanup(CIRGenFunction &cgf, cir::CleanupScopeOp cleanupScope, EHScopeStack::Cleanup *cleanup, EHScopeStack::Cleanup::Flags flags, Address activeFlag)
static uint32_t getBitWidth(const Expr *E)
#define EMIT_ARITH_OP(OP)
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
static const Expr * stripDerivedToBaseCasts(const Expr *E)
static bool isTrivialMemoryOperation(const CXXMethodDecl *MD)
static const Expr * stripCheckedDerivedToBaseCasts(const Expr *E)
static bool hasTrivialDefaultCtorParent(const FieldDecl *FD)
static bool initNeedsOverridenLoc(const CXXCtorInitializer *Init)
const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. This ignores some c...
bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
Result
Implement __builtin_bit_cast and related operations.
llvm::SmallPtrSet< const ParmVarDecl *, 1 > FoundParams
bool VisitDeclRefExpr(const DeclRefExpr *E) override
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
APValue & getStructVirtualBase(unsigned i)
bool isMemberPointerToDerivedMember() const
unsigned getArrayInitializedElts() const
unsigned getStructNumBases() const
unsigned getStructNumVirtualBases() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
APValue & getArrayFiller()
bool isIndeterminate() const
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
bool isMemberPointer() const
unsigned getArraySize() const
@ None
There is no such object (it's outside its lifetime).
bool isNullPointer() const
APValue & getStructBase(unsigned i)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
const LangOptions & getLangOpts() const
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const VariableArrayType * getAsVariableArrayType(QualType T) const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
AddrLabelExpr - The GNU address of label extension, representing &&label.
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Represents a loop initializing the elements of an array.
llvm::APInt getArraySize() const
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
uint64_t getValue() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Attr - This represents one attribute.
Represents an attribute applied to a statement.
ArrayRef< const Attr * > getAttrs() const
Represents a C++ declaration that introduces decls from somewhere else.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
static bool isShiftOp(Opcode Opc)
static bool isCommaOp(Opcode Opc)
static Opcode getOpForCompoundAssignment(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
static bool isAssignmentOp(Opcode Opc)
static bool isCompoundAssignmentOp(Opcode Opc)
static bool isBitwiseOp(Opcode Opc)
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
BreakStmt - This represents a break.
Represents a C++2a __builtin_bit_cast(T, v) expression.
Represents a base class of a C++ class.
Represents binding an expression to a temporary.
const Expr * getSubExpr() const
A boolean literal, per ([C++ lex.bool] Boolean literals).
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Expr * getArg(unsigned Arg)
Return the specified argument.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
Represents a C++ base or member initializer.
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Expr * getExpr()
Get the initialization expression that will be used.
Represents a delete expression for memory deallocation and destructor calls, e.g.
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a C++ destructor within a class.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Represents the code generated for an expanded expansion statement.
ArrayRef< Stmt * > getInstantiations() const
ArrayRef< Stmt * > getPreambleStmts() const
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
DeclStmt * getBeginStmt()
DeclStmt * getLoopVarStmt()
DeclStmt * getRangeStmt()
Represents a call to an inherited base class constructor from an inheriting constructor.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
QualType getAllocatedType() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Expr * getPlacementArg(unsigned I)
unsigned getNumPlacementArgs() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a list-initialization with parenthesis.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
capture_const_range captures() const
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
A rewritten comparison expression that was originally written using operator syntax.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
An expression "T()" which creates an rvalue of a non-class type T.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Represents the this expression in C++.
A C++ throw-expression (C++ [except.throw]).
const Expr * getSubExpr() const
CXXTryStmt - A C++ try block, including all handlers.
CompoundStmt * getTryBlock()
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
bool isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
MSGuidDecl * getGuidDecl() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Expr ** getArgs()
Retrieve the call arguments.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
const FieldDecl * getTargetUnionField() const
CharUnits - This is an opaque type for sizes expressed in character units.
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.
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
CompoundLiteralExpr - [C99 6.5.2.5].
const Expr * getInitializer() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Represents the specialization of a concept - evaluates to a prvalue of type bool.
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
Represents the canonical version of C arrays with a specified constant size.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
ContinueStmt - This represents a continue.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInvalidDecl() const
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
bool isAnyOperatorNew() const
InitListExpr * getUpdater() const
DoStmt - This represents a 'do/while' stmt.
virtual bool TraverseStmt(MaybeConst< Stmt > *S)
Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...
const Expr * getBase() const
Represents a reference to emded data.
ChildElementIter< false > begin()
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool isValueDependent() const
Determines whether the value of this expression depends on.
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
An expression trait intrinsic.
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
Represents a member of a struct/union/class.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
DeclStmt * getConditionVariableDeclStmt()
If this ForStmt has a condition variable, return the faux DeclStmt associated with the creation of th...
const Expr * getSubExpr() const
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
bool isDefaulted() const
Whether this function is defaulted.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
Expr * getResultExpr()
Return the result expression of this controlling expression.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
bool isNegatedConsteval() const
DeclStmt * getConditionVariableDeclStmt()
If this IfStmt has a condition variable, return the faux DeclStmt associated with the creation of tha...
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
Describes an C or C++ initializer list.
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
ArrayRef< Expr * > inits() const
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
bool isCompatibleWith(ClangABI Version) const
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
const Stmt * getNamedLoopOrSwitch() const
If this is a named break/continue, get the loop or switch statement that this targets.
APValue & getAsAPValue() const
Get the value of this MSGuidDecl as an APValue.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
LifetimeExtendedTemporaryDecl * getLifetimeExtendedTemporaryDecl()
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a C++ namespace alias.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
ObjCEncodeExpr, used for @encode in Objective-C.
QualType getEncodedType() const
SourceLocation getAtLoc() const
bool isExpressibleAsConstantInitializer() const
ObjCStringLiteral, used for Objective-C string literals i.e.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
unsigned getNumComponents() const
Helper class for OffsetOfExpr.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
@ Array
An index into an array.
Kind getKind() const
Determine what kind of offsetof node this is.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
ParenExpr - This represents a parenthesized expression, e.g.
const Expr * getSubExpr() const
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
[C99 6.4.2.2] - A predefined identifier such as func.
StringLiteral * getFunctionName()
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
bool isConstant(const ASTContext &Ctx) const
bool isConstQualified() const
Determine whether this type is const-qualified.
Represents a struct/union/class.
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Base for LValueReferenceType and RValueReferenceType.
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
bool isSatisfied() const
Whether or not the requires clause is satisfied.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
SourceLocation getLocation() const
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Represents an expression that computes the length of a parameter pack.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Represents a C++11 static_assert declaration.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
CompoundStmt * getSubStmt()
bool Visit(PTR(Stmt) S, ParamTys... P)
Stmt - This represents one statement.
StmtClass getStmtClass() const
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
uint32_t getCodeUnit(size_t I) const
Return the code unit at the given position.
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...
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
bool isStoredAsComparisonResult() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
The base class of the type hierarchy.
bool isBooleanType() const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isConstantMatrixType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isAtomicType() const
EnumDecl * castAsEnumDecl() const
bool isStdByteType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isPointerOrReferenceType() const
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasBooleanRepresentation() const
Determine whether this type has a boolean representation – i.e., it is a boolean type,...
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represents C++ using-directive.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
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
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
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.
ArrayIndexScope(Compiler< Emitter > *Ctx, uint64_t Index)
A memory block, either on the stack or in the heap.
void invokeDtor()
Invokes the Destructor.
Compilation context for expressions.
llvm::SmallVector< InitLink > InitStack
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E)
bool VisitCXXDeleteExpr(const CXXDeleteExpr *E)
bool VisitOffsetOfExpr(const OffsetOfExpr *E)
bool visitContinueStmt(const ContinueStmt *S)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init, OptPrimType InitT)
Pointer to the array(not the element!) must be on the stack when calling this.
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E)
bool visitInitializerPop(const Expr *E)
Similar, but will also pop the pointer.
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
PrimType classifyPrim(QualType Ty) const
Classifies a known primitive type.
bool VisitTypeTraitExpr(const TypeTraitExpr *E)
bool VisitLambdaExpr(const LambdaExpr *E)
bool VisitMemberExpr(const MemberExpr *E)
llvm::DenseMap< const OpaqueValueExpr *, unsigned > OpaqueExprs
OpaqueValueExpr to location mapping.
bool VisitBinaryOperator(const BinaryOperator *E)
bool visitCXXExpansionStmtInstantiation(const CXXExpansionStmtInstantiation *S)
template for (auto x : {1, 2}) {}
bool visitAttributedStmt(const AttributedStmt *S)
bool VisitPackIndexingExpr(const PackIndexingExpr *E)
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)
bool visitAPValueInitializer(const APValue &Val, SourceInfo Info, QualType T, bool IsCompleteClass=true)
const Function * getFunction(const FunctionDecl *FD)
Returns a function for the given FunctionDecl.
bool VisitFixedPointBinOp(const BinaryOperator *E)
bool VisitCastExpr(const CastExpr *E)
bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E)
bool VisitFixedPointUnaryOperator(const UnaryOperator *E)
bool VisitComplexUnaryOperator(const UnaryOperator *E)
llvm::DenseMap< const SwitchCase *, LabelTy > CaseMap
bool VisitBlockExpr(const BlockExpr *E)
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
bool VisitLogicalBinOp(const BinaryOperator *E)
bool visitCompoundStmt(const CompoundStmt *S)
Context & Ctx
Current compilation context.
const VarDecl * InitializingDecl
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 visitAPValue(const APValue &Val, PrimType ValType, SourceInfo Info)
Visit an APValue.
bool VisitStmtExpr(const StmtExpr *E)
bool VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *E)
bool VisitFixedPointLiteral(const FixedPointLiteral *E)
const FunctionDecl * CompilingFunction
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
VarCreationState visitVarDecl(const VarDecl *VD, const Expr *Init, bool Toplevel=false)
Creates and initializes a variable from the given decl.
VariableScope< Emitter > * VarScope
Current scope.
bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init, bool ConstantContext) override
Toplevel visitDeclAndReturn().
bool VisitCXXNewExpr(const CXXNewExpr *E)
bool VisitCompoundAssignOperator(const CompoundAssignOperator *E)
bool visit(const Expr *E) override
Evaluates an expression and places the result on the stack.
bool delegate(const Expr *E)
Just pass evaluation on to E.
bool visitLValueExpr(const Expr *E, bool DestroyToplevelScope) override
bool discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
CaseMap CaseLabels
Switch case mapping.
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
const RecordType * getRecordTy(QualType Ty)
Returns a record type from a record or pointer type.
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E)
bool visitInitList(ArrayRef< const Expr * > Inits, const Expr *ArrayFiller, const Expr *E)
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E)
bool VisitPredefinedExpr(const PredefinedExpr *E)
bool VisitSourceLocExpr(const SourceLocExpr *E)
bool visitDeclStmt(const DeclStmt *DS, bool EvaluateConditionDecl=false)
bool emitCleanup()
Emits scope cleanup instructions.
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E)
bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E)
bool visitInitializer(const Expr *E)
Compiles an initializer.
bool visitDtorCall(const VarDecl *VD, const APValue &Value) override
const Expr * SourceLocDefaultExpr
DefaultInit- or DefaultArgExpr, needed for SourceLocExpr.
bool VisitObjCArrayLiteral(const ObjCArrayLiteral *E)
UnsignedOrNone OptLabelTy
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E)
bool VisitPointerArithBinOp(const BinaryOperator *E)
Perform addition/subtraction of a pointer and an integer or subtraction of two pointers.
bool visitCallArgs(ArrayRef< const Expr * > Args, const FunctionDecl *FuncDecl, bool Activate, bool IsOperatorCall)
bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E)
bool visitDefaultStmt(const DefaultStmt *S)
bool VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
bool visitWithSubstitutions(const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This, const Expr *Condition) override
Evaluate the Condition as if it was in the body of Callee.
typename Emitter::LabelTy LabelTy
VarCreationState visitDecl(const VarDecl *VD)
bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E)
bool visitStmt(const Stmt *S)
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
bool VisitVectorUnaryOperator(const UnaryOperator *E)
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
bool VisitDesignatedInitUpdateExpr(const DesignatedInitUpdateExpr *E)
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
bool VisitRecoveryExpr(const RecoveryExpr *E)
bool VisitRequiresExpr(const RequiresExpr *E)
bool Initializing
Flag inidicating if we're initializing an already created variable.
bool visitReturnStmt(const ReturnStmt *RS)
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitChooseExpr(const ChooseExpr *E)
bool visitFunc(const FunctionDecl *F) override
bool visitCXXForRangeStmt(const CXXForRangeStmt *S)
bool visitCaseStmt(const CaseStmt *S)
bool VisitComplexBinOp(const BinaryOperator *E)
llvm::DenseMap< const ValueDecl *, Scope::Local > Locals
Variable to storage mapping.
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
bool VisitCXXTypeidExpr(const CXXTypeidExpr *E)
UnsignedOrNone allocateTemporary(const Expr *E)
bool VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinID)
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
OptPrimType ReturnType
Type of the expression returned by the function.
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
OptPrimType classify(const Expr *E) const
llvm::SmallVector< LabelInfo > LabelInfoStack
Stack of label information for loops and switch statements.
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
bool visitDoStmt(const DoStmt *S)
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitInitListExpr(const InitListExpr *E)
bool VisitVectorBinOp(const BinaryOperator *E)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
bool DiscardResult
Flag indicating if return value is to be discarded.
bool VisitEmbedExpr(const EmbedExpr *E)
UnsignedOrNone allocateLocal(DeclOrExpr Decl, QualType Ty=QualType(), ScopeKind=ScopeKind::Block)
Allocates a space storing a local given its type.
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)
unsigned allocateLocalPrimitive(DeclOrExpr Decl, PrimType Ty, bool IsConst, bool IsVolatile=false, ScopeKind SC=ScopeKind::Block)
Creates a local primitive value.
bool visitWhileStmt(const WhileStmt *S)
bool visitIfStmt(const IfStmt *IS)
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
bool canClassify(const Expr *E) const
bool VisitFloatingLiteral(const FloatingLiteral *E)
Program & P
Program to link to.
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
bool VariablesAreConstexprUnknown
bool VisitGNUNullExpr(const GNUNullExpr *E)
bool VisitImaginaryLiteral(const ImaginaryLiteral *E)
bool VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E)
bool visitCXXTryStmt(const CXXTryStmt *S)
static bool isUnevaluatedBuiltin(unsigned ID)
Unevaluated builtins don't get their arguments put on the stack automatically.
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Scope used to handle temporaries in toplevel variable declarations.
DeclScope(Compiler< Emitter > *Ctx, const VarDecl *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.
InitLinkScope(Compiler< Emitter > *Ctx, InitLink &&Link)
Compiler< Emitter > * Ctx
InitStackScope(Compiler< Emitter > *Ctx, bool Active)
When generating code for e.g.
LocOverrideScope(Compiler< Emitter > *Ctx, SourceInfo NewValue, bool Enabled=true)
Generic scope for local variables.
UnsignedOrNone Idx
Index of the scope in the chain.
~LocalScope() override
Emit a Destroy op for this scope.
bool destroyLocals(const Expr *E=nullptr) override
Explicit destruction of local variables.
bool emitDestructors(const Expr *E=nullptr) override
void removeIfStoredOpaqueValue(const Scope::Local &Local)
void addLocal(Scope::Local Local) override
void removeStoredOpaqueValues()
void forceInit() override
Force-initialize this scope.
LocalScope(Compiler< Emitter > *Ctx, ScopeKind Kind=ScopeKind::Block)
Sets the context for break/continue statements.
typename Compiler< Emitter >::LabelTy LabelTy
typename Compiler< Emitter >::OptLabelTy OptLabelTy
typename Compiler< Emitter >::LabelInfo LabelInfo
LoopScope(Compiler< Emitter > *Ctx, const Stmt *Name, LabelTy BreakLabel, LabelTy ContinueLabel)
PrimType value_or(PrimType PT) const
Scope used to handle initialization methods.
OptionScope(Compiler< Emitter > *Ctx, bool NewDiscardResult, bool NewInitializing, bool NewToLValue)
Root constructor, compiling or discarding primitives.
Context to manage declaration lifetimes.
Structure/Class descriptor.
bool isUnion() const
Checks if the record is a union.
const Field * getField(unsigned I) const
const Base * getBaseOrNull(const RecordDecl *RD) const
bool hasTrivialDtor() const
Returns true for anonymous unions and records with no destructor or for those with a trivial destruct...
const Base * findVirtualBase(const RecordDecl *RD) const
Returns a virtual base descriptor.
Describes the statement/declaration an opcode was generated from.
const Expr * asExpr() const
SourceLocScope(Compiler< Emitter > *Ctx, const Expr *DefaultExpr)
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.
void addForScopeKind(const Scope::Local &Local, ScopeKind Kind)
Like addExtended, but adds to the nearest scope of the given kind.
bool LocalsAlwaysEnabled
Whether locals added to this scope are enabled by default.
Compiler< Emitter > * Ctx
Compiler instance.
virtual bool emitDestructors(const Expr *E=nullptr)
VariableScope(Compiler< Emitter > *Ctx, ScopeKind Kind=ScopeKind::Block)
virtual bool destroyLocals(const Expr *E=nullptr)
virtual void addLocal(Scope::Local Local)
VariableScope * Parent
Link to the parent scope.
ScopeKind getKind() const
VariableScope * getParent() const
bool Sub(InterpState &S, CodePtr OpPC)
bool LT(InterpState &S, CodePtr OpPC)
static llvm::RoundingMode getRoundingMode(FPOptions FPO)
constexpr bool isSignedType(PrimType T)
bool Div(InterpState &S, CodePtr OpPC)
1) Pops the RHS from the stack.
constexpr bool isPtrType(PrimType T)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool This(InterpState &S, CodePtr OpPC)
constexpr bool isIntegerOrBoolType(PrimType T)
bool InitScope(InterpState &S, uint32_t I)
static void discard(InterpStack &Stk, PrimType T)
static bool isSideEffectFree(const Expr *E)
Check if E has side-effects.
bool LE(InterpState &S, CodePtr OpPC)
PrimType
Enumeration of the primitive types of the VM.
static std::optional< bool > getBoolValue(const Expr *E)
static bool Activate(InterpState &S)
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 isIntegerType(PrimType T)
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
bool hasSpecificAttr(const Container &container)
@ Success
Annotation was successful.
@ Link
'link' clause, allowed on 'declare' construct.
DynamicRecursiveASTVisitorBase< true > ConstDynamicRecursiveASTVisitor
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
@ Result
The result type of a method or function.
OptionalUnsigned< unsigned > UnsignedOrNone
const FunctionProtoType * T
U cast(CodeGen::Address addr)
int const char * function
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
llvm::APSInt getIntValue() const
Get the constant integer value used by this variable to represent the comparison category result type...
EvalResult is a struct with detailed info about an evaluated expression.
const ValueDecl * asValueDecl() const
const Expr * asExpr() const
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.
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
PrimType getPrimType() const
bool isRecord() const
Checks if the descriptor is of a record.
const Record *const ElemRecord
Pointer to the record, if block contains records.
bool isArray() const
Checks if the descriptor is of an array.
Descriptor used for global variables.
GlobalInitState InitState
static InitLink InitList()
static InitLink Elem(unsigned Index)
bool emit(Compiler< Emitter > *Ctx, const Expr *E) const
static InitLink Field(unsigned Offset)
static InitLink Base(unsigned Offset)
static InitLink Decl(const ValueDecl *D)
static InitLink Temp(unsigned Offset)
Information about a local's storage.
State encapsulating if a the variable creation has been successful, unsuccessful, or no variable has ...
static VarCreationState NotCreated()