20#include "llvm/Support/SaveAndRestore.h"
31 if (
const auto *CE = dyn_cast_if_present<ConstantExpr>(E);
32 CE && CE->hasAPValueResult() &&
34 return CE->getResultAsAPSInt().getBoolValue();
66 llvm_unreachable(
"Shouldn't be called");
132 this->
Ctx->emitDestroy(*
Idx, E);
138 Idx =
static_cast<unsigned>(this->
Ctx->Descriptors.size());
139 this->
Ctx->Descriptors.emplace_back();
140 this->
Ctx->emitInitScope(*
Idx, {});
144 this->
Ctx->Descriptors[*
Idx].emplace_back(Local);
154 Idx =
static_cast<unsigned>(this->
Ctx->Descriptors.size());
155 this->
Ctx->Descriptors.emplace_back();
156 this->
Ctx->emitInitScope(*
Idx, {});
167 if (Local.Desc->hasTrivialDtor())
170 if (!Local.EnabledByDefault) {
171 typename Emitter::LabelTy EndLabel = this->
Ctx->getLabel();
172 if (!this->
Ctx->emitGetLocalEnabled(Local.Offset, E))
174 if (!this->
Ctx->jumpFalse(EndLabel, E))
177 if (!this->
Ctx->emitGetPtrLocal(Local.Offset, E))
180 if (!this->
Ctx->emitDestructionPop(Local.Desc, Local.Desc->getLoc()))
183 this->
Ctx->fallthrough(EndLabel);
184 this->
Ctx->emitLabel(EndLabel);
186 if (!this->
Ctx->emitGetPtrLocal(Local.Offset, E))
188 if (!this->
Ctx->emitDestructionPop(Local.Desc, Local.Desc->getLoc()))
207 if (
const auto *OVE =
208 llvm::dyn_cast_if_present<OpaqueValueExpr>(Local.Desc->asExpr())) {
209 if (
auto It = this->
Ctx->OpaqueExprs.find(OVE);
210 It != this->Ctx->OpaqueExprs.end())
211 this->
Ctx->OpaqueExprs.erase(It);
222 OldArrayIndex = Ctx->ArrayIndex;
223 Ctx->ArrayIndex = Index;
230 std::optional<uint64_t> OldArrayIndex;
238 if (!Ctx->SourceLocDefaultExpr) {
240 Ctx->SourceLocDefaultExpr = DefaultExpr;
246 Ctx->SourceLocDefaultExpr =
nullptr;
251 bool Enabled =
false;
257 Ctx->InitStack.push_back(std::move(
Link));
269 : Ctx(Ctx), OldValue(Ctx->InitStackActive), Active(Active) {
270 Ctx->InitStackActive = Active;
276 this->Ctx->InitStackActive = OldValue;
278 Ctx->InitStack.pop_back();
292 OldInitializingDecl(
Ctx->InitializingDecl) {
293 Ctx->InitializingDecl = VD;
298 this->
Ctx->InitializingDecl = OldInitializingDecl;
299 this->
Ctx->InitStack.pop_back();
304 const VarDecl *OldInitializingDecl;
312 bool NewInitializing,
bool NewToLValue)
313 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
314 OldInitializing(Ctx->
Initializing), OldToLValue(Ctx->ToLValue) {
315 Ctx->DiscardResult = NewDiscardResult;
316 Ctx->Initializing = NewInitializing;
317 Ctx->ToLValue = NewToLValue;
321 Ctx->DiscardResult = OldDiscardResult;
322 Ctx->Initializing = OldInitializing;
323 Ctx->ToLValue = OldToLValue;
330 bool OldDiscardResult;
331 bool OldInitializing;
335template <
class Emitter>
339 return Ctx->emitThis(E);
342 return Ctx->emitGetPtrFieldPop(
Offset, E);
344 return Ctx->emitGetPtrBasePop(
Offset,
false, E);
346 return Ctx->emitGetPtrLocal(
Offset, E);
350 if (!Ctx->emitConstUint32(
Offset, E))
352 return Ctx->emitArrayElemPtrPopUint32(E);
354 return Ctx->emitRVOPtr(E);
358 llvm_unreachable(
"Unhandled InitLink kind");
374 for (
const LabelInfo &LI : Ctx->LabelInfoStack)
375 assert(LI.Name != Name);
378 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel, ContinueLabel,
399 : Ctx(Ctx), OldCaseLabels(
std::move(this->Ctx->CaseLabels)) {
401 for (
const LabelInfo &LI : Ctx->LabelInfoStack)
402 assert(LI.Name != Name);
405 this->Ctx->CaseLabels = std::move(CaseLabels);
406 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel,
408 DefaultLabel, Ctx->VarScope);
412 this->Ctx->CaseLabels = std::move(OldCaseLabels);
413 this->Ctx->LabelInfoStack.pop_back();
418 CaseMap OldCaseLabels;
429 : Ctx(Ctx), OldFlag(Ctx->LocOverride), Enabled(Enabled) {
432 Ctx->LocOverride = NewValue;
437 Ctx->LocOverride = OldFlag;
442 std::optional<SourceInfo> OldFlag;
449template <
class Emitter>
457 case CK_LValueToRValue: {
468 if (
const auto *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
474 if (
auto GlobalIndex =
P.getGlobal(D))
475 return this->emitGetGlobal(*SubExprT, *GlobalIndex, E);
476 }
else if (
auto It =
Locals.find(D); It !=
Locals.end()) {
477 return this->emitGetLocal(*SubExprT, It->second.Offset, E);
478 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
479 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
480 return this->emitGetParam(*SubExprT, It->second.Index, E);
492 if (!this->emitGetPtrLocal(*LocalIndex, E))
496 if (!this->
visit(SubExpr))
500 return this->emitLoadPop(*SubExprT, E);
505 return this->emitMemcpy(E);
508 case CK_DerivedToBaseMemberPointer: {
519 ->getMostRecentCXXRecordDecl();
521 const CXXRecordDecl *ToDecl = B->getType()->getAsCXXRecordDecl();
522 unsigned DerivedOffset =
Ctx.collectBaseOffset(ToDecl, CurDecl);
524 if (!this->emitCastMemberPtrBasePop(DerivedOffset, ToDecl, E))
532 case CK_BaseToDerivedMemberPointer: {
543 ->getMostRecentCXXRecordDecl();
547 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
549 PathI != PathE; ++PathI) {
550 const CXXRecordDecl *ToDecl = (*PathI)->getType()->getAsCXXRecordDecl();
551 unsigned DerivedOffset =
Ctx.collectBaseOffset(CurDecl, ToDecl);
553 if (!this->emitCastMemberPtrDerivedPop(-DerivedOffset, ToDecl, E))
560 assert(ToDecl != CurDecl);
561 unsigned DerivedOffset =
Ctx.collectBaseOffset(CurDecl, ToDecl);
563 if (!this->emitCastMemberPtrDerivedPop(-DerivedOffset, ToDecl, E))
569 case CK_UncheckedDerivedToBase:
570 case CK_DerivedToBase: {
575 if (
const auto *PT = dyn_cast<PointerType>(Ty))
576 return PT->getPointeeType()->getAsCXXRecordDecl();
577 return Ty->getAsCXXRecordDecl();
584 if (B->isVirtual()) {
585 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), E))
587 CurType = B->getType();
589 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
590 if (!this->emitGetPtrBasePop(
593 CurType = B->getType();
600 case CK_BaseToDerived: {
603 unsigned DerivedOffset =
609 return this->emitGetPtrDerivedPop(DerivedOffset,
614 case CK_FloatingCast: {
617 return this->emitVectorConversion(E->
getSubExpr(), E);
621 if (!this->
visit(SubExpr))
623 const auto *TargetSemantics = &
Ctx.getFloatSemantics(E->
getType());
627 case CK_IntegralToFloating: {
629 return this->emitVectorConversion(E->
getSubExpr(), E);
632 if (!this->
visit(SubExpr))
634 const auto *TargetSemantics = &
Ctx.getFloatSemantics(E->
getType());
635 return this->emitCastIntegralFloating(
classifyPrim(SubExpr),
636 TargetSemantics, getFPOptions(E), E);
639 case CK_FloatingToBoolean: {
641 return this->emitVectorConversion(E->
getSubExpr(), E);
645 if (
const auto *FL = dyn_cast<FloatingLiteral>(SubExpr))
646 return this->emitConstBool(FL->getValue().isNonZero(), E);
647 if (!this->
visit(SubExpr))
649 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
652 case CK_FloatingToIntegral: {
654 return this->emitVectorConversion(E->
getSubExpr(), E);
657 if (!this->
visit(SubExpr))
661 return this->emitCastFloatingIntegralAP(
Ctx.getBitWidth(E->
getType()),
664 return this->emitCastFloatingIntegralAPS(
Ctx.getBitWidth(E->
getType()),
667 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
670 case CK_NullToPointer:
671 case CK_NullToMemberPointer: {
674 uint64_t Val =
Ctx.getASTContext().getTargetNullPointerValue(E->
getType());
679 case CK_PointerToIntegral: {
680 if (!this->
visit(SubExpr))
686 if (!this->emitDecayPtr(FromT,
PT_Ptr, E))
692 return this->emitCastPointerIntegralAP(
Ctx.getBitWidth(E->
getType()), E);
694 return this->emitCastPointerIntegralAPS(
Ctx.getBitWidth(E->
getType()), E);
695 return this->emitCastPointerIntegral(
T, E);
698 case CK_ArrayToPointerDecay: {
699 if (!this->
visit(SubExpr))
701 return this->emitArrayDecay(E);
704 case CK_IntegralToPointer: {
706 assert(IntType->isIntegralOrEnumerationType());
707 if (!this->
visit(SubExpr))
721 return this->emitDecayPtr(
PT_Ptr, DestPtrT, E);
724 case CK_AtomicToNonAtomic:
725 case CK_ConstructorConversion:
726 case CK_FunctionToPointerDecay:
727 case CK_NonAtomicToAtomic:
729 case CK_UserDefinedConversion:
730 case CK_AddressSpaceConversion:
731 case CK_CPointerToObjCPointerCast:
748 return this->emitBuiltinBitCast(E);
763 if (!this->
visit(SubExpr))
771 return this->emitFnPtrCast(E);
778 if (!this->
visit(SubExpr))
780 return this->emitDecayPtr(*FromT, *ToT, E);
782 case CK_IntegralToBoolean:
783 case CK_FixedPointToBoolean: {
785 return this->emitVectorConversion(E->
getSubExpr(), E);
791 if (
const auto *IL = dyn_cast<IntegerLiteral>(SubExpr))
792 return this->emitConst(IL->getValue(), E);
793 if (!this->
visit(SubExpr))
798 case CK_IntegralCast:
800 return this->emitVectorConversion(E->
getSubExpr(), E);
802 case CK_BooleanToSignedIntegral: {
809 if (
const auto *IL = dyn_cast<IntegerLiteral>(SubExpr)) {
814 if (!this->emitConst(IL->getValue(), SubExpr))
817 if (!this->
visit(SubExpr))
825 if (!ED->isFixed()) {
826 if (!this->emitCheckEnumValue(*FromT, ED, E))
832 if (!this->emitCastAP(*FromT,
Ctx.getBitWidth(E->
getType()), E))
835 if (!this->emitCastAPS(*FromT,
Ctx.getBitWidth(E->
getType()), E))
840 if (!this->emitCast(*FromT, *ToT, E))
843 if (E->
getCastKind() == CK_BooleanToSignedIntegral)
844 return this->emitNeg(*ToT, E);
848 case CK_PointerToBoolean:
849 case CK_MemberPointerToBoolean: {
852 if (!this->
visit(SubExpr))
854 return this->emitIsNonNull(PtrT, E);
857 case CK_IntegralComplexToBoolean:
858 case CK_FloatingComplexToBoolean: {
859 if (!this->
visit(SubExpr))
861 return this->emitComplexBoolCast(SubExpr);
864 case CK_IntegralComplexToReal:
865 case CK_FloatingComplexToReal:
866 return this->emitComplexReal(SubExpr);
868 case CK_IntegralRealToComplex:
869 case CK_FloatingRealToComplex: {
876 if (!this->emitGetPtrLocal(*LocalIndex, E))
885 if (!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
887 return this->emitInitElem(
T, 1, SubExpr);
890 case CK_IntegralComplexCast:
891 case CK_FloatingComplexCast:
892 case CK_IntegralComplexToFloatingComplex:
893 case CK_FloatingComplexToIntegralComplex: {
900 if (!this->emitGetPtrLocal(*LocalIndex, E))
907 unsigned SubExprOffset =
909 if (!this->
visit(SubExpr))
911 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, E))
919 for (
unsigned I = 0; I != 2; ++I) {
920 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, E))
922 if (!this->emitArrayElemPop(SourceElemT, I, E))
926 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, E))
930 if (!this->emitInitElem(DestElemT, I, E))
936 case CK_VectorSplat: {
947 if (!this->emitGetPtrLocal(*LocalIndex, E))
953 unsigned ElemOffset =
957 if (!this->
visit(SubExpr))
962 if (!this->emitSetLocal(ElemT, ElemOffset, E))
965 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
966 if (!this->emitGetLocal(ElemT, ElemOffset, E))
968 if (!this->emitInitElem(ElemT, I, E))
975 case CK_HLSLVectorTruncation: {
980 if (!this->
visit(SubExpr))
982 return this->emitArrayElemPop(*ResultT, 0, E);
991 if (!this->emitGetPtrLocal(*LocalIndex, E))
996 if (!this->
visit(SubExpr))
998 return this->emitCopyArray(classifyVectorElementType(E->
getType()), 0, 0,
1002 case CK_IntegralToFixedPoint: {
1003 if (!this->
visit(SubExpr))
1007 Ctx.getASTContext().getFixedPointSemantics(E->
getType()).toOpaqueInt();
1012 return this->emitPopFixedPoint(E);
1015 case CK_FloatingToFixedPoint: {
1016 if (!this->
visit(SubExpr))
1020 Ctx.getASTContext().getFixedPointSemantics(E->
getType()).toOpaqueInt();
1021 if (!this->emitCastFloatingFixedPoint(Sem, E))
1024 return this->emitPopFixedPoint(E);
1027 case CK_FixedPointToFloating: {
1028 if (!this->
visit(SubExpr))
1030 const auto *TargetSemantics = &
Ctx.getFloatSemantics(E->
getType());
1031 if (!this->emitCastFixedPointFloating(TargetSemantics, E))
1034 return this->emitPopFloat(E);
1037 case CK_FixedPointToIntegral: {
1038 if (!this->
visit(SubExpr))
1041 if (!this->emitCastFixedPointIntegral(IntegralT, E))
1044 return this->emitPop(IntegralT, E);
1047 case CK_FixedPointCast: {
1048 if (!this->
visit(SubExpr))
1051 Ctx.getASTContext().getFixedPointSemantics(E->
getType()).toOpaqueInt();
1052 if (!this->emitCastFixedPoint(Sem, E))
1055 return this->emitPopFixedPoint(E);
1063 llvm_unreachable(
"CXXDynamicCastExpr has its own function");
1065 case CK_LValueBitCast:
1070 case CK_HLSLArrayRValue: {
1077 if (!this->emitGetPtrLocal(*LocalIndex, E))
1080 if (!this->
visit(SubExpr))
1082 return this->emitMemcpy(E);
1085 case CK_HLSLMatrixTruncation: {
1090 if (!this->
visit(SubExpr))
1092 return this->emitArrayElemPop(*ResultT, 0, E);
1101 if (!this->emitGetPtrLocal(*LocalIndex, E))
1106 if (!this->
visit(SubExpr))
1108 return this->emitCopyArray(classifyMatrixElementType(SubExpr->
getType()), 0,
1112 case CK_HLSLAggregateSplatCast: {
1122 if (!this->emitGetPtrLocal(*LocalIndex, E))
1129 unsigned SrcOffset =
1132 if (!this->
visit(SubExpr))
1134 if (!this->emitSetLocal(SrcElemT, SrcOffset, E))
1138 return emitHLSLAggregateSplat(SrcElemT, SrcOffset, E->
getType(), E);
1141 case CK_HLSLElementwiseCast: {
1152 unsigned SrcPtrOffset =
1154 if (!this->
visit(SubExpr))
1156 if (!this->emitSetLocal(
PT_Ptr, SrcPtrOffset, E))
1160 if (!emitHLSLFlattenAggregate(SrcType, SrcPtrOffset, Elements, 1, E))
1162 if (Elements.empty())
1165 const HLSLFlatElement &Src = Elements[0];
1166 if (!this->emitGetLocal(Src.Type, Src.LocalOffset, E))
1168 return this->emitPrimCast(Src.Type, *DestT, DestType, E);
1175 if (!this->emitGetPtrLocal(*LocalIndex, E))
1179 unsigned SrcOffset =
1181 if (!this->
visit(SubExpr))
1183 if (!this->emitSetLocal(
PT_Ptr, SrcOffset, E))
1187 unsigned ElemCount = countHLSLFlatElements(DestType);
1190 Elements.reserve(ElemCount);
1191 if (!emitHLSLFlattenAggregate(SrcType, SrcOffset, Elements, ElemCount, E))
1196 assert(Elements.size() == ElemCount &&
1197 "Source type has fewer scalar elements than the destination type");
1199 return emitHLSLConstructAggregate(DestType, Elements, E);
1206 const Record::Field *RF = R->getField(UnionField);
1207 QualType FieldType = RF->Decl->getType();
1210 if (!this->
visit(SubExpr))
1212 if (RF->isBitField())
1213 return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(),
1215 return this->emitInitFieldActivate(*PT, RF->Offset, E);
1218 if (!this->emitGetPtrField(RF->Offset, E))
1220 if (!this->emitActivate(E))
1226 return this->emitInvalid(E);
1228 llvm_unreachable(
"Unhandled clang::CastKind enum");
1231template <
class Emitter>
1233 return this->emitBuiltinBitCast(E);
1236template <
class Emitter>
1241 return this->emitConst(
LE->getValue(),
LE);
1244template <
class Emitter>
1250 return this->emitFloat(F, E);
1253template <
class Emitter>
1263 if (!this->emitGetPtrLocal(*LocalIndex, E))
1270 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
1272 if (!this->emitInitElem(SubExprT, 0, SubExpr))
1277template <
class Emitter>
1285 auto Sem =
Ctx.getASTContext().getFixedPointSemantics(E->
getType());
1290template <
class Emitter>
1295template <
class Emitter>
1322 return this->emitComplexComparison(LHS, RHS, E);
1330 if (!this->
visit(LHS))
1333 if (!this->
visit(RHS))
1336 if (!this->emitToMemberPtr(E))
1342 if (!this->emitCastMemberPtrPtr(E))
1359 Ctx.getASTContext().CompCategories.lookupInfoForType(E->
getType());
1365 if (!this->emitGetPtrLocal(*ResultIndex, E))
1372 return this->emitCMP3(*
LT, CmpInfo, E);
1375 if (!
LT || !RT || !
T)
1385 return this->visitAssignment(LHS, RHS, E);
1392 auto MaybeCastToBool = [
this,
T, E](
bool Result) {
1396 return this->emitPopBool(E);
1398 return this->emitCast(
PT_Bool, *
T, E);
1402 auto Discard = [
this,
T, E](
bool Result) {
1410 return MaybeCastToBool(this->emitEQ(*
LT, E));
1412 return MaybeCastToBool(this->emitNE(*
LT, E));
1414 return MaybeCastToBool(this->emitLT(*
LT, E));
1416 return MaybeCastToBool(this->emitLE(*
LT, E));
1418 return MaybeCastToBool(this->emitGT(*
LT, E));
1420 return MaybeCastToBool(this->emitGE(*
LT, E));
1423 return Discard(this->emitSubf(getFPOptions(E), E));
1424 return Discard(this->emitSub(*
T, E));
1427 return Discard(this->emitAddf(getFPOptions(E), E));
1428 return Discard(this->emitAdd(*
T, E));
1431 return Discard(this->emitMulf(getFPOptions(E), E));
1432 return Discard(this->emitMul(*
T, E));
1434 return Discard(this->emitRem(*
T, E));
1437 return Discard(this->emitDivf(getFPOptions(E), E));
1438 return Discard(this->emitDiv(*
T, E));
1440 return Discard(this->emitBitAnd(*
T, E));
1442 return Discard(this->emitBitOr(*
T, E));
1444 return Discard(this->emitShl(*
LT, *RT, E));
1446 return Discard(this->emitShr(*
LT, *RT, E));
1448 return Discard(this->emitBitXor(*
T, E));
1451 llvm_unreachable(
"Already handled earlier");
1456 llvm_unreachable(
"Unhandled binary op");
1461template <
class Emitter>
1467 if ((Op != BO_Add && Op != BO_Sub) ||
1478 auto visitAsPointer = [&](
const Expr *E,
PrimType T) ->
bool {
1479 if (!this->
visit(E))
1482 return this->emitDecayPtr(
T,
PT_Ptr, E);
1491 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *
LT))
1499 ElemTypeSize =
Ctx.getASTContext().getTypeSizeInChars(ElemType);
1502 if (!this->emitSubPtr(IntT, ElemTypeSize.
getQuantity(), E))
1509 if (!visitAsPointer(RHS, *RT))
1511 if (!this->
visit(LHS))
1515 if (!visitAsPointer(LHS, *
LT))
1517 if (!this->
visit(RHS))
1528 if (!this->emitAddOffset(OffsetType, E))
1532 if (!this->emitSubOffset(OffsetType, E))
1549template <
class Emitter>
1559 LabelTy LabelTrue = this->getLabel();
1560 LabelTy LabelEnd = this->getLabel();
1564 if (!this->jumpTrue(LabelTrue, E))
1569 if (!this->jump(LabelEnd, E))
1572 this->emitLabel(LabelTrue);
1573 this->emitConstBool(
true, E);
1574 this->fallthrough(LabelEnd);
1575 this->emitLabel(LabelEnd);
1578 assert(Op == BO_LAnd);
1581 LabelTy LabelFalse = this->getLabel();
1582 LabelTy LabelEnd = this->getLabel();
1586 if (!this->jumpFalse(LabelFalse, E))
1591 if (!this->jump(LabelEnd, E))
1594 this->emitLabel(LabelFalse);
1595 this->emitConstBool(
false, E);
1596 this->fallthrough(LabelEnd);
1597 this->emitLabel(LabelEnd);
1601 return this->emitPopBool(E);
1606 return this->emitCast(
PT_Bool, *
T, E);
1610template <
class Emitter>
1617 if (!this->emitGetPtrLocal(*LocalIndex, E))
1626 PrimType ResultElemT = this->classifyComplexElementType(E->
getType());
1627 unsigned ResultOffset = ~0u;
1633 if (!this->emitDupPtr(E))
1635 if (!this->emitSetLocal(
PT_Ptr, ResultOffset, E))
1640 LHSType = AT->getValueType();
1643 RHSType = AT->getValueType();
1652 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1657 if (!this->
visit(LHS))
1659 if (!this->
visit(RHS))
1661 if (!this->emitMulc(ElemT, E))
1664 return this->emitPopPtr(E);
1668 if (Op == BO_Div && RHSIsComplex) {
1675 if (!LHSIsComplex) {
1680 LHSOffset = *LocalIndex;
1682 if (!this->emitGetPtrLocal(LHSOffset, E))
1685 if (!this->
visit(LHS))
1688 if (!this->emitInitElem(ElemT, 0, E))
1691 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1693 if (!this->emitInitElem(ElemT, 1, E))
1696 if (!this->
visit(LHS))
1700 if (!this->
visit(RHS))
1702 if (!this->emitDivc(ElemT, E))
1705 return this->emitPopPtr(E);
1712 if (!this->
visit(LHS))
1714 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
1719 if (!this->
visit(LHS))
1721 if (!this->emitSetLocal(LHST, LHSOffset, E))
1729 if (!this->
visit(RHS))
1731 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
1736 if (!this->
visit(RHS))
1738 if (!this->emitSetLocal(RHST, RHSOffset, E))
1745 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1746 unsigned ElemIndex,
unsigned Offset,
1747 const Expr *E) ->
bool {
1749 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
1751 return this->emitArrayElemPop(classifyComplexElementType(E->
getType()),
1754 if (ElemIndex == 0 || !LoadZero)
1761 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1764 if (!this->emitGetLocal(
PT_Ptr, ResultOffset, E))
1771 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1774 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1777 if (!this->emitAddf(getFPOptions(E), E))
1780 if (!this->emitAdd(ResultElemT, E))
1785 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1788 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1791 if (!this->emitSubf(getFPOptions(E), E))
1794 if (!this->emitSub(ResultElemT, E))
1799 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1802 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1806 if (!this->emitMulf(getFPOptions(E), E))
1809 if (!this->emitMul(ResultElemT, E))
1814 assert(!RHSIsComplex);
1815 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1818 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1822 if (!this->emitDivf(getFPOptions(E), E))
1825 if (!this->emitDiv(ResultElemT, E))
1836 if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))
1839 if (!this->emitPop(ResultElemT, E))
1844 return this->emitPopPtr(E);
1850template <
class Emitter>
1855 "Comma op should be handled in VisitBinaryOperator");
1869 if (!this->emitGetPtrLocal(*LocalIndex, E))
1883 assert(
Ctx.getASTContext().hasSameUnqualifiedType(
1886 if (!this->
visit(LHS))
1888 if (!this->
visit(RHS))
1890 if (!this->emitCopyArray(ElemT, 0, 0, VecTy->getNumElements(), E))
1893 return this->emitPopPtr(E);
1898 unsigned LHSOffset =
1900 if (!this->
visit(LHS))
1902 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
1906 unsigned RHSOffset =
1908 if (!this->
visit(RHS))
1910 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
1922 if (NeedIntPromot) {
1924 Ctx.getASTContext().getPromotedIntegerType(
Ctx.getASTContext().BoolTy);
1929 auto getElem = [=](
unsigned Offset,
PrimType ElemT,
unsigned Index) {
1930 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
1932 if (!this->emitArrayElemPop(ElemT, Index, E))
1935 if (!this->emitPrimCast(ElemT,
PT_Bool,
Ctx.getASTContext().BoolTy, E))
1937 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(), E))
1939 }
else if (NeedIntPromot) {
1940 if (!this->emitPrimCast(ElemT, PromotT, PromotTy, E))
1946#define EMIT_ARITH_OP(OP) \
1948 if (ElemT == PT_Float) { \
1949 if (!this->emit##OP##f(getFPOptions(E), E)) \
1952 if (!this->emit##OP(ElemT, E)) \
1958 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
1959 if (!getElem(LHSOffset, ElemT, I))
1961 if (!getElem(RHSOffset, RHSElemT, I))
1973 if (!this->emitRem(ElemT, E))
1977 if (!this->emitBitAnd(OpT, E))
1981 if (!this->emitBitOr(OpT, E))
1985 if (!this->emitBitXor(OpT, E))
1989 if (!this->emitShl(OpT, RHSElemT, E))
1993 if (!this->emitShr(OpT, RHSElemT, E))
1997 if (!this->emitEQ(ElemT, E))
2001 if (!this->emitNE(ElemT, E))
2005 if (!this->emitLE(ElemT, E))
2009 if (!this->emitLT(ElemT, E))
2013 if (!this->emitGE(ElemT, E))
2017 if (!this->emitGT(ElemT, E))
2022 if (!this->emitBitAnd(ResultElemT, E))
2027 if (!this->emitBitOr(ResultElemT, E))
2031 return this->emitInvalid(E);
2040 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(), E))
2042 if (!this->emitNeg(ResultElemT, E))
2048 if (NeedIntPromot &&
2049 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(), E))
2053 if (!this->emitInitElem(ResultElemT, I, E))
2062template <
class Emitter>
2072 auto LHSSemaInt = LHSSema.toOpaqueInt();
2074 auto RHSSemaInt = RHSSema.toOpaqueInt();
2076 if (!this->
visit(LHS))
2084 if (!this->
visit(RHS))
2093 auto ConvertResult = [&](
bool R) ->
bool {
2097 auto CommonSema = LHSSema.getCommonSemantics(RHSSema).toOpaqueInt();
2098 if (ResultSema != CommonSema)
2099 return this->emitCastFixedPoint(ResultSema, E);
2103 auto MaybeCastToBool = [&](
bool Result) {
2108 return this->emitPop(
T, E);
2110 return this->emitCast(
PT_Bool,
T, E);
2116 return MaybeCastToBool(this->emitEQFixedPoint(E));
2118 return MaybeCastToBool(this->emitNEFixedPoint(E));
2120 return MaybeCastToBool(this->emitLTFixedPoint(E));
2122 return MaybeCastToBool(this->emitLEFixedPoint(E));
2124 return MaybeCastToBool(this->emitGTFixedPoint(E));
2126 return MaybeCastToBool(this->emitGEFixedPoint(E));
2128 return ConvertResult(this->emitAddFixedPoint(E));
2130 return ConvertResult(this->emitSubFixedPoint(E));
2132 return ConvertResult(this->emitMulFixedPoint(E));
2134 return ConvertResult(this->emitDivFixedPoint(E));
2136 return ConvertResult(this->emitShiftFixedPoint(
true, E));
2138 return ConvertResult(this->emitShiftFixedPoint(
false, E));
2141 return this->emitInvalid(E);
2144 llvm_unreachable(
"unhandled binop opcode");
2147template <
class Emitter>
2156 if (!this->
visit(SubExpr))
2158 if (!this->emitNegFixedPoint(E))
2161 return this->emitPopFixedPoint(E);
2167 llvm_unreachable(
"Unhandled unary opcode");
2170template <
class Emitter>
2179 return this->visitZeroInitializer(*
T, QT, E);
2192 return this->visitZeroRecordInitializer(R, E);
2199 return this->visitZeroArrayInitializer(QT, E);
2203 QualType ElemQT = ComplexTy->getElementType();
2205 for (
unsigned I = 0; I < 2; ++I) {
2206 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2208 if (!this->emitInitElem(ElemT, I, E))
2215 unsigned NumVecElements = VecT->getNumElements();
2216 QualType ElemQT = VecT->getElementType();
2219 for (
unsigned I = 0; I < NumVecElements; ++I) {
2220 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2222 if (!this->emitInitElem(ElemT, I, E))
2229 unsigned NumElems = MT->getNumElementsFlattened();
2230 QualType ElemQT = MT->getElementType();
2233 for (
unsigned I = 0; I != NumElems; ++I) {
2234 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2236 if (!this->emitInitElem(ElemT, I, E))
2245template <
class Emitter>
2258 for (
const Expr *SubExpr : {LHS, RHS}) {
2259 if (!this->
visit(SubExpr)) {
2266 if (SubExpr ==
Base &&
Base->getType()->isPointerType()) {
2267 if (!this->emitExpandPtr(E))
2278 return this->emitError(E);
2281 if (!this->emitFlip(
PT_Ptr, *IndexT, E))
2285 if (!this->emitArrayElemPtrPop(*IndexT, E))
2288 return this->emitPopPtr(E);
2294 return this->emitLoadPop(*
T, E);
2297template <
class Emitter>
2299 const Expr *ArrayFiller,
const Expr *E) {
2304 QT = AT->getValueType();
2307 if (
Inits.size() == 0)
2309 return this->emitInvalid(E);
2324 if (
Inits.size() == 0)
2325 return this->visitZeroInitializer(*
T, QT, E);
2326 assert(
Inits.size() == 1);
2339 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
2346 bool BitField = FieldToInit->isBitField();
2348 return this->emitInitBitFieldActivate(
T, FieldToInit->Offset,
2349 FieldToInit->bitWidth(), E);
2351 return this->emitInitBitField(
T, FieldToInit->Offset,
2352 FieldToInit->bitWidth(), E);
2354 return this->emitInitFieldActivate(
T, FieldToInit->Offset, E);
2355 return this->emitInitField(
T, FieldToInit->Offset, E);
2358 auto initCompositeField = [=](
const Record::Field *FieldToInit,
2366 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
2369 if (
Activate && !this->emitActivate(E))
2376 if (
Inits.size() == 0) {
2377 if (!this->visitZeroRecordInitializer(R, E))
2382 if (
const auto *ILE = dyn_cast<InitListExpr>(E))
2383 FToInit = ILE->getInitializedFieldInUnion();
2387 const Record::Field *FieldToInit = R->getField(FToInit);
2389 if (!initPrimitiveField(FieldToInit,
Init, *
T,
true))
2392 if (!initCompositeField(FieldToInit,
Init,
true))
2396 return this->emitFinishInit(E);
2399 assert(!R->isUnion());
2400 for (
unsigned BI = 0; BI != R->getNumBases(); ++BI) {
2402 const Record::Base *B = R->getBase(BI);
2405 if (!this->emitGetPtrBase(B->Offset,
Init))
2411 unsigned FieldIndex = 0;
2412 for (
unsigned FI = R->getNumBases(); FI !=
Inits.size();) {
2413 const Record::Field *FieldToInit = R->getField(FieldIndex);
2414 if (FieldToInit->isUnnamedBitField()) {
2429 if (!initPrimitiveField(FieldToInit,
Init, *
T))
2431 }
else if (!initCompositeField(FieldToInit,
Init)) {
2439 assert(R->getNumVirtualBases() == 0);
2441 return this->emitFinishInit(E);
2446 Ctx.getASTContext().getAsConstantArrayType(QT);
2451 !this->emitCheckArrayDestSize(NumElems, E))
2454 if (
Inits.size() == 1 && QT ==
Inits[0]->getType())
2458 unsigned ElementIndex = 0;
2460 if (
const auto *EmbedS =
2461 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
2469 if (!this->emitCastIntegralFloating(
classifyPrim(IL), Sem,
2470 getFPOptions(E), E))
2476 return this->emitInitElem(TargetT, ElemIndex, IL);
2478 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
2494 for (; ElementIndex != NumElems; ++ElementIndex) {
2500 return this->emitFinishInit(E);
2504 unsigned NumInits =
Inits.size();
2509 QualType ElemQT = ComplexTy->getElementType();
2511 if (NumInits == 0) {
2513 for (
unsigned I = 0; I < 2; ++I) {
2514 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2516 if (!this->emitInitElem(ElemT, I, E))
2519 }
else if (NumInits == 2) {
2520 unsigned InitIndex = 0;
2525 if (!this->emitInitElem(ElemT, InitIndex, E))
2534 unsigned NumVecElements = VecT->getNumElements();
2535 assert(NumVecElements >=
Inits.size());
2537 QualType ElemQT = VecT->getElementType();
2541 unsigned InitIndex = 0;
2548 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
2549 if (!this->emitCopyArray(ElemT, 0, InitIndex,
2550 InitVecT->getNumElements(), E))
2552 InitIndex += InitVecT->getNumElements();
2554 if (!this->emitInitElem(ElemT, InitIndex, E))
2560 assert(InitIndex <= NumVecElements);
2563 for (; InitIndex != NumVecElements; ++InitIndex) {
2564 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2566 if (!this->emitInitElem(ElemT, InitIndex, E))
2573 unsigned NumElems = MT->getNumElementsFlattened();
2574 assert(
Inits.size() == NumElems);
2576 QualType ElemQT = MT->getElementType();
2582 for (
unsigned I = 0; I != NumElems; ++I) {
2585 if (!this->emitInitElem(ElemT, I, E))
2596template <
class Emitter>
2603 return this->emitInitElem(*InitT, ElemIndex,
Init);
2609 if (!this->emitConstUint32(ElemIndex,
Init))
2611 if (!this->emitArrayElemPtrUint32(
Init))
2616template <
class Emitter>
2619 bool Activate,
bool IsOperatorCall) {
2621 llvm::BitVector NonNullArgs;
2622 if (FuncDecl && FuncDecl->
hasAttr<NonNullAttr>())
2625 bool ExplicitMemberFn =
false;
2626 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl))
2627 ExplicitMemberFn = MD->isExplicitObjectMemberFunction();
2629 unsigned ArgIndex = 0;
2630 for (
const Expr *Arg : Args) {
2632 if (!this->
visit(Arg))
2640 unsigned DeclIndex = ArgIndex - IsOperatorCall + ExplicitMemberFn;
2641 if (DeclIndex < FuncDecl->getNumParams())
2642 Source = FuncDecl->
getParamDecl(ArgIndex - IsOperatorCall +
2651 if (!this->emitGetPtrLocal(*LocalIndex, Arg))
2659 if (!this->emitActivate(Arg))
2663 if (!NonNullArgs.empty() && NonNullArgs[ArgIndex]) {
2666 if (!this->emitCheckNonNullArg(ArgT, Arg))
2677template <
class Emitter>
2682template <
class Emitter>
2688template <
class Emitter>
2694template <
class Emitter>
2712template <
class Emitter>
2714 auto It = E->
begin();
2715 return this->
visit(*It);
2719 UnaryExprOrTypeTrait Kind) {
2720 bool AlignOfReturnsPreferred =
2727 T = Ref->getPointeeType();
2729 if (
T.getQualifiers().hasUnaligned())
2735 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2741template <
class Emitter>
2745 UnaryExprOrTypeTrait Kind = E->
getKind();
2748 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2754 ArgType = Ref->getPointeeType();
2760 if (
ArgType->isDependentType() || !
ArgType->isConstantSizeType())
2761 return this->emitInvalid(E);
2763 if (Kind == UETT_SizeOf)
2772 return this->emitConst(Size.getQuantity(), E);
2775 if (Kind == UETT_CountOf) {
2781 if (
const auto *CAT =
2785 return this->emitConst(CAT->getSize(), E);
2795 if (VAT->getElementType()->isArrayType()) {
2796 std::optional<APSInt> Res =
2798 ? VAT->getSizeExpr()->getIntegerConstantExpr(ASTCtx)
2803 return this->emitConst(*Res, E);
2808 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2828 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2831 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
2841 return this->emitConst(Size.getQuantity(), E);
2844 if (Kind == UETT_VectorElements) {
2849 return this->emitConst(VT->getNumElements(), E);
2851 return this->emitSizelessVectorElementSize(E);
2854 if (Kind == UETT_VecStep) {
2856 unsigned N = VT->getNumElements();
2863 return this->emitConst(N, E);
2865 return this->emitConst(1, E);
2868 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2877 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2879 return this->emitInvalid(E);
2881 return this->emitConst(
2882 const_cast<ASTContext &
>(ASTCtx).getPointerAuthTypeDiscriminator(
2890template <
class Emitter>
2899 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
2902 if (
auto GlobalIndex =
P.getGlobal(VD)) {
2903 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2905 if (
Member->getType()->isReferenceType())
2906 return this->emitLoadPopPtr(E);
2915 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
Member);
2916 MD && !MD->isStatic()) {
2920 if (!this->
discard(Base) && !this->emitSideEffect(E))
2935 const Record::Field *F = R->getField(FD);
2939 const auto maybeLoadValue = [&]() ->
bool {
2943 return this->emitLoadPop(*
T, E);
2948 if (F->Decl->getType()->isReferenceType())
2949 return this->emitGetFieldPop(
PT_Ptr, F->Offset, E) && maybeLoadValue();
2950 return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue();
2953template <
class Emitter>
2963template <
class Emitter>
2977 if (!this->
visit(Common))
2979 return this->emitCopyArray(*SubExprT, 0, 0, Size, E);
2993 for (
size_t I = 0; I != Size; ++I) {
3005template <
class Emitter>
3020 return this->emitGetLocal(SubExprT, It->second, E);
3023 if (!this->
visit(SourceExpr))
3030 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
3039 return this->emitGetLocal(SubExprT, LocalIndex, E);
3043template <
class Emitter>
3056 bool IsBcpCall =
false;
3057 if (
const auto *CE = dyn_cast<CallExpr>(
Condition->IgnoreParenCasts());
3058 CE && CE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) {
3062 LabelTy LabelEnd = this->getLabel();
3063 LabelTy LabelFalse = this->getLabel();
3066 if (!this->emitPushIgnoreDiags(E))
3074 if (this->checkingForUndefinedBehavior()) {
3077 if (!this->
discard(FalseExpr))
3094 if (!this->jumpFalse(LabelFalse, E))
3099 if (!this->jump(LabelEnd, E))
3101 this->emitLabel(LabelFalse);
3105 this->fallthrough(LabelEnd);
3106 this->emitLabel(LabelEnd);
3109 return this->emitPopIgnoreDiags(E);
3113template <
class Emitter>
3119 unsigned StringIndex =
P.createGlobalString(E);
3120 return this->emitGetPtrGlobal(StringIndex, E);
3125 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
3126 assert(CAT &&
"a string literal that's not a constant array?");
3131 unsigned N = std::min(ArraySize, E->
getLength());
3134 for (
unsigned I = 0; I != N; ++I) {
3137 if (CharWidth == 1) {
3138 this->emitConstSint8(CodeUnit, E);
3139 this->emitInitElemSint8(I, E);
3140 }
else if (CharWidth == 2) {
3141 this->emitConstUint16(CodeUnit, E);
3142 this->emitInitElemUint16(I, E);
3143 }
else if (CharWidth == 4) {
3144 this->emitConstUint32(CodeUnit, E);
3145 this->emitInitElemUint32(I, E);
3147 llvm_unreachable(
"unsupported character width");
3152 for (
unsigned I = N; I != ArraySize; ++I) {
3153 if (CharWidth == 1) {
3154 this->emitConstSint8(0, E);
3155 this->emitInitElemSint8(I, E);
3156 }
else if (CharWidth == 2) {
3157 this->emitConstUint16(0, E);
3158 this->emitInitElemUint16(I, E);
3159 }
else if (CharWidth == 4) {
3160 this->emitConstUint32(0, E);
3161 this->emitInitElemUint32(I, E);
3163 llvm_unreachable(
"unsupported character width");
3170template <
class Emitter>
3174 return this->emitDummyPtr(E, E);
3177template <
class Emitter>
3179 auto &A =
Ctx.getASTContext();
3188template <
class Emitter>
3196 auto &A =
Ctx.getASTContext();
3200 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
3201 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
3208 unsigned StringIndex =
P.createGlobalString(SL);
3209 return this->emitGetPtrGlobal(StringIndex, E);
3212template <
class Emitter>
3216 return this->emitConst(E->
getValue(), E);
3219template <
class Emitter>
3241 if (!this->emitLoad(LHST, E))
3244 if (!this->emitPrimCast(LHST,
classifyPrim(LHSComputationType),
3245 LHSComputationType, E))
3257 unsigned TempOffset =
3259 if (!this->emitSetLocal(*RT, TempOffset, E))
3265 if (!this->emitLoad(LHST, E))
3269 if (!this->emitPrimCast(LHST,
classifyPrim(LHSComputationType),
3270 LHSComputationType, E))
3274 if (!this->emitGetLocal(*RT, TempOffset, E))
3280 if (!this->emitAddf(getFPOptions(E), E))
3284 if (!this->emitSubf(getFPOptions(E), E))
3288 if (!this->emitMulf(getFPOptions(E), E))
3292 if (!this->emitDivf(getFPOptions(E), E))
3303 return this->emitStorePop(LHST, E);
3304 return this->emitStore(LHST, E);
3307template <
class Emitter>
3316 if (Op != BO_AddAssign && Op != BO_SubAssign)
3325 if (!this->emitLoad(*
LT, LHS))
3331 if (Op == BO_AddAssign) {
3332 if (!this->emitAddOffset(*RT, E))
3335 if (!this->emitSubOffset(*RT, E))
3340 return this->emitStorePopPtr(E);
3341 return this->emitStorePtr(E);
3344template <
class Emitter>
3357 if (!
Ctx.getLangOpts().CPlusPlus14)
3358 return this->
visit(RHS) && this->
visit(LHS) && this->emitError(E);
3360 if (!
LT || !RT || !ResultT || !LHSComputationT)
3377 if (!this->emitLoad(*
LT, E))
3379 if (
LT != LHSComputationT &&
3380 !this->emitIntegralCast(*
LT, *LHSComputationT,
3394 unsigned TempOffset =
3397 if (!this->emitSetLocal(*RT, TempOffset, E))
3404 if (!this->emitLoad(*
LT, E))
3406 if (
LT != LHSComputationT &&
3407 !this->emitIntegralCast(*
LT, *LHSComputationT,
3412 if (!this->emitGetLocal(*RT, TempOffset, E))
3419 if (!this->emitAdd(*LHSComputationT, E))
3423 if (!this->emitSub(*LHSComputationT, E))
3427 if (!this->emitMul(*LHSComputationT, E))
3431 if (!this->emitDiv(*LHSComputationT, E))
3435 if (!this->emitRem(*LHSComputationT, E))
3439 if (!this->emitShl(*LHSComputationT, *RT, E))
3443 if (!this->emitShr(*LHSComputationT, *RT, E))
3447 if (!this->emitBitAnd(*LHSComputationT, E))
3451 if (!this->emitBitXor(*LHSComputationT, E))
3455 if (!this->emitBitOr(*LHSComputationT, E))
3459 llvm_unreachable(
"Unimplemented compound assign operator");
3463 if (ResultT != LHSComputationT &&
3464 !this->emitIntegralCast(*LHSComputationT, *ResultT, E->
getType(), E))
3470 return this->emitStoreBitFieldPop(*ResultT, E);
3471 return this->emitStorePop(*ResultT, E);
3474 return this->emitStoreBitField(*ResultT, E);
3475 return this->emitStore(*ResultT, E);
3478template <
class Emitter>
3486template <
class Emitter>
3501 if (!
Ctx.getLangOpts().CPlusPlus11)
3508 for (
const Expr *LHS : CommaLHSs) {
3530 if (!this->
visit(Inner))
3535 if (!this->emitInitGlobalTemp(*InnerT, *GlobalIndex, TempDecl, E))
3538 if (!this->emitInitGlobal(*InnerT, *GlobalIndex, E))
3541 return this->emitGetPtrGlobal(*GlobalIndex, E);
3544 if (!this->checkLiteralType(Inner))
3547 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3553 return this->emitInitGlobalTempComp(TempDecl, E);
3566 unsigned LocalIndex =
3568 if (!this->VarScope->LocalsAlwaysEnabled &&
3569 !this->emitEnableLocal(LocalIndex, E))
3572 if (!this->
visit(Inner))
3574 if (!this->emitSetLocal(*InnerT, LocalIndex, E))
3577 return this->emitGetPtrLocal(LocalIndex, E);
3580 if (!this->checkLiteralType(Inner))
3587 if (!this->VarScope->LocalsAlwaysEnabled &&
3588 !this->emitEnableLocal(*LocalIndex, E))
3591 if (!this->emitGetPtrLocal(*LocalIndex, E))
3598template <
class Emitter>
3609 if (!this->
visit(SubExpr))
3613 return this->emitPopPtr(E);
3617template <
class Emitter>
3638 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3643 if (
P.isGlobalInitialized(*GlobalIndex))
3649 return this->emitInitGlobal(*
T, *GlobalIndex, E);
3661 unsigned LocalIndex;
3665 LocalIndex = *MaybeIndex;
3669 if (!this->emitGetPtrLocal(LocalIndex, E))
3673 return this->
visit(
Init) && this->emitInit(*
T, E);
3677template <
class Emitter>
3690template <
class Emitter>
3694 return this->emitConst(E->
getValue(), E);
3697template <
class Emitter>
3710 for (
const Record::Field &F : R->fields()) {
3712 if (!
Init ||
Init->containsErrors())
3720 if (!this->emitInitField(*
T, F.Offset, E))
3723 if (!this->emitGetPtrField(F.Offset, E))
3734template <
class Emitter>
3741 return this->emitGetPtrGlobal(StringIndex, E);
3747template <
class Emitter>
3752 return this->emitInvalid(E);
3755template <
class Emitter>
3775 bool Fatal = (ToT != FromT);
3782template <
class Emitter>
3784 if (!
Ctx.getLangOpts().CPlusPlus20) {
3805 if (!this->emitDynamicCast(DestType.
getTypePtr(),
3810 return this->emitPopPtr(E);
3814template <
class Emitter>
3820 return this->emitConstBool(E->
getValue(), E);
3823template <
class Emitter>
3828 if (
T->isRecordType()) {
3842 if (!this->emitGetPtrLocal(*LocalIndex, E))
3850 T->getAsCXXRecordDecl()))
3860 if (!this->visitZeroRecordInitializer(R, E))
3872 assert(
Ctx.getASTContext().hasSameUnqualifiedType(E->
getType(),
3874 if (
const auto *ME = dyn_cast<MaterializeTemporaryExpr>(SrcObj)) {
3875 if (!this->emitCheckFunctionDecl(Ctor, E))
3886 assert(
Func->hasThisPointer());
3887 assert(!
Func->hasRVO());
3891 if (!this->emitDupPtr(E))
3895 for (
const auto *Arg : E->
arguments()) {
3896 if (!this->
visit(Arg))
3900 if (
Func->isVariadic()) {
3901 uint32_t VarArgSize = 0;
3902 unsigned NumParams =
Func->getNumWrittenParams();
3903 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I) {
3907 if (!this->emitCallVar(
Func, VarArgSize, E))
3910 if (!this->emitCall(
Func, 0, E)) {
3915 (void)this->emitPopPtr(E);
3921 return this->emitPopPtr(E);
3925 if (
T->isArrayType()) {
3930 if (!this->emitDupPtr(E))
3934 initArrayDimension = [&](
QualType T) ->
bool {
3935 if (!
T->isArrayType()) {
3937 for (
const auto *Arg : E->
arguments()) {
3938 if (!this->
visit(Arg))
3942 return this->emitCall(
Func, 0, E);
3946 Ctx.getASTContext().getAsConstantArrayType(
T);
3951 for (
size_t I = 0; I != NumElems; ++I) {
3952 if (!this->emitConstUint64(I, E))
3954 if (!this->emitArrayElemPtrUint64(E))
3956 if (!initArrayDimension(ElemTy))
3959 return this->emitPopPtr(E);
3962 return initArrayDimension(E->
getType());
3968template <
class Emitter>
3978 assert(Val.
isInt());
3980 return this->emitConst(I, E);
3987 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
3988 return this->
visit(LValueExpr);
4003 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4007 const APValue &
V = UGCD->getValue();
4008 for (
unsigned I = 0, N = R->getNumFields(); I != N; ++I) {
4009 const Record::Field *F = R->getField(I);
4010 const APValue &FieldValue =
V.getStructField(I);
4016 if (!this->emitInitField(FieldT, F->Offset, E))
4024template <
class Emitter>
4030 for (
unsigned I = 0; I != N; ++I) {
4037 if (!this->
discard(ArrayIndexExpr))
4043 if (!this->
visit(ArrayIndexExpr))
4045 if (!this->emitCastAPToOffsetIndex(IndexT, E))
4049 if (!this->
visit(ArrayIndexExpr))
4053 if (!this->emitCast(IndexT,
PT_Sint64, E))
4063 return this->emitOffsetOf(
T, E, E);
4066template <
class Emitter>
4075 return this->visitZeroInitializer(*
T, Ty, E);
4082 if (!this->emitGetPtrLocal(*LocalIndex, E))
4090 ElemQT = CT->getElementType();
4093 NumElems = VT->getNumElements();
4094 ElemQT = VT->getElementType();
4100 for (
unsigned I = 0; I != NumElems; ++I) {
4101 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
4103 if (!this->emitInitElem(ElemT, I, E))
4112template <
class Emitter>
4117template <
class Emitter>
4123template <
class Emitter>
4128template <
class Emitter>
4133 return this->emitConst(E->
getValue(), E);
4136template <
class Emitter>
4141 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
4156 unsigned ParamIndex = 0;
4160 if (!this->emitGetParam(PT, ParamIndex, E))
4165 return this->emitCall(F, 0, E);
4170template <
class Emitter>
4178 const Expr *PlacementDest =
nullptr;
4179 bool IsNoThrow =
false;
4184 if (PlacementArgs != 0) {
4193 if (PlacementArgs == 1) {
4201 if (!this->emitInvalidNewDeleteExpr(E, E))
4206 if (OperatorNew->isReservedGlobalPlacementOperator())
4207 PlacementDest = Arg1;
4211 return this->emitInvalid(E);
4213 }
else if (!OperatorNew
4214 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4215 return this->emitInvalidNewDeleteExpr(E, E);
4218 if (!PlacementDest) {
4223 Desc =
P.createDescriptor(E, *ElemT,
nullptr,
4226 Desc =
P.createDescriptor(
4229 false,
false,
false,
4235 std::optional<const Expr *> ArraySizeExpr = E->
getArraySize();
4239 const Expr *Stripped = *ArraySizeExpr;
4240 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
4241 Stripped = ICE->getSubExpr())
4242 if (ICE->getCastKind() != CK_NoOp &&
4243 ICE->getCastKind() != CK_IntegralCast)
4251 if (!this->
visit(Stripped))
4253 if (!this->emitSetLocal(
SizeT, ArrayLen, E))
4256 if (PlacementDest) {
4257 if (!this->
visit(PlacementDest))
4259 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
4261 if (!this->emitCheckNewTypeMismatchArray(
SizeT, E, E))
4264 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
4269 if (!this->emitAllocN(
SizeT, *ElemT, E, IsNoThrow, E))
4273 if (!this->emitAllocCN(
SizeT, Desc, IsNoThrow, E))
4280 size_t StaticInitElems = 0;
4281 const Expr *DynamicInit =
nullptr;
4285 Ctx.getASTContext().getAsConstantArrayType(InitType)) {
4286 StaticInitElems = CAT->getZExtSize();
4291 if (
const auto *ILE = dyn_cast<InitListExpr>(
Init)) {
4292 if (ILE->hasArrayFiller())
4293 DynamicInit = ILE->getArrayFiller();
4312 const Function *CtorFunc =
nullptr;
4313 if (
const auto *CE = dyn_cast<CXXConstructExpr>(
Init)) {
4317 }
else if (!DynamicInit && !ElemT)
4320 LabelTy EndLabel = this->getLabel();
4321 LabelTy StartLabel = this->getLabel();
4326 if (!this->emitDupPtr(E))
4328 if (!this->emitNullPtr(0,
nullptr, E))
4330 if (!this->emitEQPtr(E))
4332 if (!this->jumpTrue(EndLabel, E))
4339 if (!this->emitConst(StaticInitElems,
SizeT, E))
4341 if (!this->emitSetLocal(
SizeT, Iter, E))
4344 this->fallthrough(StartLabel);
4345 this->emitLabel(StartLabel);
4347 if (!this->emitGetLocal(
SizeT, Iter, E))
4349 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
4351 if (!this->emitLT(
SizeT, E))
4353 if (!this->jumpFalse(EndLabel, E))
4357 if (!this->emitGetLocal(
SizeT, Iter, E))
4359 if (!this->emitArrayElemPtr(
SizeT, E))
4362 if (isa_and_nonnull<ImplicitValueInitExpr>(DynamicInit) &&
4367 if (!this->visitZeroInitializer(*InitT, ElemType, E))
4369 if (!this->emitStorePop(*InitT, E))
4373 if (!this->visitZeroArrayInitializer(ElemType, E))
4376 }
else if (DynamicInit) {
4378 if (!this->
visit(DynamicInit))
4380 if (!this->emitStorePop(*InitT, E))
4387 if (!this->visitZeroInitializer(
4391 if (!this->emitStorePop(*ElemT, E))
4395 if (!this->emitCall(CtorFunc, 0, E))
4400 if (!this->emitGetPtrLocal(Iter, E))
4402 if (!this->emitIncPop(
SizeT,
false, E))
4405 if (!this->jump(StartLabel, E))
4408 this->fallthrough(EndLabel);
4409 this->emitLabel(EndLabel);
4413 if (PlacementDest) {
4414 if (!this->
visit(PlacementDest))
4416 if (!this->emitCheckNewTypeMismatch(E, E))
4421 if (!this->emitAlloc(Desc, E))
4430 if (!this->emitInit(*ElemT, E))
4441 return this->emitPopPtr(E);
4446template <
class Emitter>
4452 if (!OperatorDelete->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4453 return this->emitInvalidNewDeleteExpr(E, E);
4462template <
class Emitter>
4468 if (
const Function *F =
Ctx.getOrCreateObjCBlock(E))
4473 return this->emitGetFnPtr(
Func, E);
4476template <
class Emitter>
4480 auto canonType = [](
const Type *
T) {
4481 return T->getCanonicalTypeUnqualified().getTypePtr();
4489 return this->emitGetTypeid(
4493 return this->emitGetTypeid(
4502 if (!
Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(E))
4508 if (!this->emitGetTypeidPtr(TypeInfoType, E))
4511 return this->emitPopPtr(E);
4515template <
class Emitter>
4519 return this->emitDummyPtr(E, E);
4520 return this->emitError(E);
4523template <
class Emitter>
4526 return this->emitDummyPtr(E, E);
4527 return this->emitError(E);
4530template <
class Emitter>
4532 assert(
Ctx.getLangOpts().CPlusPlus);
4533 return this->emitConstBool(E->
getValue(), E);
4536template <
class Emitter>
4548 return this->emitDummyPtr(GuidDecl, E);
4553 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4562 assert(
V.isStruct());
4563 assert(
V.getStructNumBases() == 0);
4567 return this->emitFinishInit(E);
4570template <
class Emitter>
4580template <
class Emitter>
4589template <
class Emitter>
4595template <
class Emitter>
4599 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
4603 if (OVE->isUnique())
4619template <
class Emitter>
4624template <
class Emitter>
4626 return this->emitError(E);
4629template <
class Emitter>
4635 return this->emitDummyPtr(E, E);
4638template <
class Emitter>
4639bool Compiler<Emitter>::emitVectorConversion(
const Expr *Src,
const Expr *E) {
4644 QualType ElemType = VT->getElementType();
4645 PrimType ElemT = classifyPrim(ElemType);
4647 PrimType SrcElemT = classifyVectorElementType(SrcType);
4653 if (!this->emitGetPtrLocal(*LocalIndex, E))
4657 unsigned SrcOffset =
4658 this->allocateLocalPrimitive(Src,
PT_Ptr,
true);
4659 if (!this->visit(Src))
4661 if (!this->emitSetLocal(
PT_Ptr, SrcOffset, E))
4664 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
4665 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
4667 if (!this->emitArrayElemPop(SrcElemT, I, E))
4671 if (SrcElemT != ElemT) {
4672 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
4674 }
else if (ElemType->isFloatingType() && SrcType != ElemType) {
4675 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
4679 if (!this->emitInitElem(ElemT, I, E))
4685template <
class Emitter>
4687 return emitVectorConversion(E->
getSrcExpr(), E);
4690template <
class Emitter>
4694 return this->emitInvalid(E);
4703 assert(NumOutputElems > 0);
4709 if (!this->emitGetPtrLocal(*LocalIndex, E))
4714 unsigned VectorOffsets[2];
4715 for (
unsigned I = 0; I != 2; ++I) {
4718 if (!this->
visit(Vecs[I]))
4720 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I], E))
4723 for (
unsigned I = 0; I != NumOutputElems; ++I) {
4725 assert(ShuffleIndex >= -1);
4726 if (ShuffleIndex == -1)
4727 return this->emitInvalidShuffleVectorIndex(I, E);
4729 assert(ShuffleIndex < (NumInputElems * 2));
4730 if (!this->emitGetLocal(
PT_Ptr,
4731 VectorOffsets[ShuffleIndex >= NumInputElems], E))
4733 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
4734 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
4737 if (!this->emitInitElem(ElemT, I, E))
4742 return this->emitPopPtr(E);
4747template <
class Emitter>
4752 Base->getType()->isVectorType() ||
4758 if (Indices.size() == 1) {
4763 if (!this->emitConstUint32(Indices[0], E))
4765 return this->emitArrayElemPtrPop(
PT_Uint32, E);
4775 if (!this->emitSetLocal(
PT_Ptr, BaseOffset, E))
4783 if (!this->emitGetPtrLocal(*ResultIndex, E))
4791 uint32_t DstIndex = 0;
4792 for (uint32_t I : Indices) {
4793 if (!this->emitGetLocal(
PT_Ptr, BaseOffset, E))
4795 if (!this->emitArrayElemPop(ElemT, I, E))
4797 if (!this->emitInitElem(ElemT, DstIndex, E))
4807template <
class Emitter>
4811 return this->
discard(SubExpr) && this->emitInvalid(E);
4817 return this->emitDummyPtr(E, E);
4820template <
class Emitter>
4825 Ctx.getASTContext().getAsConstantArrayType(SubExpr->
getType());
4830 if (!this->
visit(SubExpr))
4832 if (!this->emitConstUint8(0, E))
4834 if (!this->emitArrayElemPtrPopUint8(E))
4836 if (!this->emitInitFieldPtr(R->getField(0u)->Offset, E))
4841 if (!this->emitConst(
ArrayType->getSize(), SecondFieldT, E))
4843 return this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E);
4845 assert(SecondFieldT ==
PT_Ptr);
4847 if (!this->emitGetFieldPtr(R->getField(0u)->Offset, E))
4849 if (!this->emitExpandPtr(E))
4853 if (!this->emitArrayElemPtrPop(
PT_Uint64, E))
4855 return this->emitInitFieldPtr(R->getField(1u)->Offset, E);
4858template <
class Emitter>
4873 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
4877 return this->emitUnsupported(E);
4886 return this->
Visit(E);
4893 return this->
Visit(E);
4897 if (
const auto *PE = dyn_cast<ParenExpr>(E))
4900 if (
const auto *CE = dyn_cast<CastExpr>(E);
4902 (CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp))
4909 if (
const auto *PE = dyn_cast<ParenExpr>(E))
4912 if (
const auto *CE = dyn_cast<CastExpr>(E);
4913 CE && (CE->getCastKind() == CK_DerivedToBase ||
4914 CE->getCastKind() == CK_UncheckedDerivedToBase ||
4915 CE->getCastKind() == CK_NoOp))
4935 if (!this->emitGetPtrLocal(*LocalIndex, E))
4945 return this->
Visit(E);
4948template <
class Emitter>
4954 return this->
Visit(E) && this->emitFinishInit(E);
4957template <
class Emitter>
4963 return this->
Visit(E) && this->emitFinishInitPop(E);
4969 return this->
Visit(E);
4980 if (!this->
visit(E))
4982 return this->emitComplexBoolCast(E);
4987 if (!this->
visit(E))
4995 return this->emitIsNonNullPtr(E);
4999 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
5002 return this->emitCast(*
T,
PT_Bool, E);
5005template <
class Emitter>
5009 QT = AT->getValueType();
5013 return this->emitZeroBool(E);
5015 return this->emitZeroSint8(E);
5017 return this->emitZeroUint8(E);
5019 return this->emitZeroSint16(E);
5021 return this->emitZeroUint16(E);
5023 return this->emitZeroSint32(E);
5025 return this->emitZeroUint32(E);
5027 return this->emitZeroSint64(E);
5029 return this->emitZeroUint64(E);
5031 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
5033 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
5035 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
5038 return this->emitNullMemberPtr(0,
nullptr, E);
5040 APFloat F = APFloat::getZero(Ctx.getFloatSemantics(QT));
5041 return this->emitFloat(F, E);
5044 auto Sem = Ctx.getASTContext().getFixedPointSemantics(QT);
5048 llvm_unreachable(
"unknown primitive type");
5051template <
class Emitter>
5052bool Compiler<Emitter>::visitZeroRecordInitializer(
const Record *R,
5054 bool IsCompleteClass) {
5058 for (
const Record::Field &Field :
R->fields()) {
5059 if (Field.isUnnamedBitField())
5066 if (!this->visitZeroInitializer(
T, QT, E))
5069 if (!this->emitInitFieldActivate(
T, Field.Offset, E))
5073 if (!this->emitInitField(
T, Field.Offset, E))
5078 if (!this->emitGetPtrField(Field.Offset, E))
5085 if (!this->visitZeroInitializer(
T, ET, E))
5087 if (!this->emitInitElem(
T, I, E))
5092 if (!this->visitZeroArrayInitializer(D->
getType(), E))
5095 if (!this->visitZeroRecordInitializer(D->
ElemRecord, E))
5103 if (!this->emitFinishInitActivatePop(E))
5107 if (!this->emitFinishInitPop(E))
5111 for (
const Record::Base &B :
R->bases()) {
5112 if (!this->emitGetPtrBase(B.Offset, E))
5114 if (!this->visitZeroRecordInitializer(B.R, E,
false))
5116 if (!this->emitFinishInitPop(E))
5120 if (IsCompleteClass) {
5121 for (
const Record::Base &B :
R->virtual_bases()) {
5124 if (!this->visitZeroRecordInitializer(B.R, E,
false))
5126 if (!this->emitFinishInitPop(E))
5134template <
class Emitter>
5135bool Compiler<Emitter>::visitZeroArrayInitializer(
QualType T,
const Expr *E) {
5136 assert(
T->isArrayType() ||
T->isAnyComplexType() ||
T->isVectorType());
5137 const ArrayType *AT =
T->getAsArrayTypeUnsafe();
5142 for (
size_t I = 0; I != NumElems; ++I) {
5143 if (!this->visitZeroInitializer(*ElemT, ElemType, E))
5145 if (!this->emitInitElem(*ElemT, I, E))
5151 const Record *
R = getRecord(ElemType);
5155 for (
size_t I = 0; I != NumElems; ++I) {
5156 if (!this->emitConstUint32(I, E))
5158 if (!this->emitArrayElemPtr(
PT_Uint32, E))
5160 if (!this->visitZeroRecordInitializer(R, E))
5162 if (!this->emitPopPtr(E))
5168 for (
size_t I = 0; I != NumElems; ++I) {
5169 if (!this->emitConstUint32(I, E))
5171 if (!this->emitArrayElemPtr(
PT_Uint32, E))
5173 if (!this->visitZeroArrayInitializer(ElemType, E))
5175 if (!this->emitPopPtr(E))
5184template <
class Emitter>
5185bool Compiler<Emitter>::visitAssignment(
const Expr *LHS,
const Expr *RHS,
5187 if (!canClassify(E->
getType()))
5192 if (!this->visit(LHS))
5194 if (!this->visit(RHS))
5197 if (!this->visit(RHS))
5199 if (!this->visit(LHS))
5207 if (!Ctx.getLangOpts().CPlusPlus && !this->emitInvalid(E))
5211 bool Activates = refersToUnion(LHS);
5214 if (NeedsFlip && !this->emitFlip(
PT_Ptr, RHT, E))
5217 if (DiscardResult) {
5218 if (BitField && Activates)
5219 return this->emitStoreBitFieldActivatePop(RHT, E);
5221 return this->emitStoreBitFieldPop(RHT, E);
5223 return this->emitStoreActivatePop(RHT, E);
5225 return this->emitStorePop(RHT, E);
5228 auto maybeLoad = [&](
bool Result) ->
bool {
5234 return this->emitLoadPop(RHT, E);
5238 if (BitField && Activates)
5239 return maybeLoad(this->emitStoreBitFieldActivate(RHT, E));
5241 return maybeLoad(this->emitStoreBitField(RHT, E));
5243 return maybeLoad(this->emitStoreActivate(RHT, E));
5245 return maybeLoad(this->emitStore(RHT, E));
5248template <
class Emitter>
5249template <
typename T>
5253 return this->emitConstSint8(
Value, Info);
5255 return this->emitConstUint8(
Value, Info);
5257 return this->emitConstSint16(
Value, Info);
5259 return this->emitConstUint16(
Value, Info);
5261 return this->emitConstSint32(
Value, Info);
5263 return this->emitConstUint32(
Value, Info);
5265 return this->emitConstSint64(
Value, Info);
5267 return this->emitConstUint64(
Value, Info);
5269 return this->emitConstBool(
Value, Info);
5276 llvm_unreachable(
"Invalid integral type");
5279 llvm_unreachable(
"unknown primitive type");
5282template <
class Emitter>
5283template <
typename T>
5284bool Compiler<Emitter>::emitConst(
T Value,
const Expr *E) {
5285 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
5288template <
class Emitter>
5292 return this->emitConstIntAPS(
Value, Info);
5294 return this->emitConstIntAP(
Value, Info);
5296 if (
Value.isSigned())
5297 return this->emitConst(
Value.getSExtValue(), Ty, Info);
5298 return this->emitConst(
Value.getZExtValue(), Ty, Info);
5301template <
class Emitter>
5305 return this->emitConstIntAPS(
Value, Info);
5307 return this->emitConstIntAP(
Value, Info);
5310 return this->emitConst(
Value.getSExtValue(), Ty, Info);
5311 return this->emitConst(
Value.getZExtValue(), Ty, Info);
5314template <
class Emitter>
5315bool Compiler<Emitter>::emitConst(
const APSInt &
Value,
const Expr *E) {
5316 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
5319template <
class Emitter>
5328 IsConst, Src.isExpr(),
5332 if (
auto *VD = Src.asValueDecl())
5333 Locals.insert({VD, Local});
5334 VarScope->addForScopeKind(Local, SC);
5335 return Local.Offset;
5338template <
class Emitter>
5343 bool IsTemporary =
false;
5344 if (
auto *VD = Src.asValueDecl()) {
5347 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
5348 Init = VarD->getInit();
5350 if (
const auto *E = Src.asExpr()) {
5361 return std::nullopt;
5366 Locals.insert({Key, Local});
5367 VarScope->addForScopeKind(Local, SC);
5368 return Local.Offset;
5371template <
class Emitter>
5381 return std::nullopt;
5391 return Local.Offset;
5394template <
class Emitter>
5396 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
5397 return PT->getPointeeType()->getAsCanonical<RecordType>();
5403 return getRecord(RecordTy->getDecl()->getDefinitionOrSelf());
5407template <
class Emitter>
5409 return P.getOrCreateRecord(RD);
5412template <
class Emitter>
5414 return Ctx.getOrCreateFunction(FD);
5417template <
class Emitter>
5421 auto maybeDestroyLocals = [&]() ->
bool {
5422 if (DestroyToplevelScope)
5423 return RootScope.
destroyLocals() && this->emitCheckAllocations(E);
5424 return this->emitCheckAllocations(E);
5431 return this->emitRetVoid(E) && maybeDestroyLocals();
5439 return this->emitRet(*
T, E) && maybeDestroyLocals();
5447 if (!this->emitGetPtrLocal(*LocalOffset, E))
5455 return this->emitRetValue(E) && maybeDestroyLocals();
5458 return maybeDestroyLocals() &&
false;
5461template <
class Emitter>
5463 bool DestroyToplevelScope) {
5467 return this->
visitExpr(E, DestroyToplevelScope);
5470template <
class Emitter>
5482 if (
auto GlobalIndex =
P.getGlobal(VD)) {
5483 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
5497template <
class Emitter>
5499 bool ConstantContext) {
5502 if (!ConstantContext) {
5517 auto GlobalIndex =
P.getGlobal(VD);
5518 assert(GlobalIndex);
5520 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
5523 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
5527 auto Local =
Locals.find(VD);
5528 assert(Local !=
Locals.end());
5531 if (!this->emitGetRefLocal(Local->second.Offset, VD))
5533 }
else if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
5536 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
5546 auto GlobalIndex =
P.getGlobal(VD);
5547 assert(GlobalIndex);
5548 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
5557 return VDScope.
destroyLocals() && this->emitCheckAllocations(VD);
5560template <
class Emitter>
5571 if (!this->isActive())
5576 if (
Init &&
Init->isValueDependent())
5580 auto checkDecl = [&]() ->
bool {
5582 return !NeedsOp || this->emitCheckDecl(VD, VD);
5589 if (!
P.getGlobal(*GlobalIndex)->isInitialized())
5592 if (
P.isGlobalInitialized(*GlobalIndex))
5596 }
else if ((GlobalIndex =
5611 return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
5614 if (!this->emitGetPtrGlobal(*GlobalIndex,
Init))
5617 if (!this->emitStartInit(
Init))
5623 if (!this->emitEndInit(
Init))
5626 return this->emitFinishInitGlobal(
Init);
5636 if (!
Init ||
Init->getType()->isVoidType())
5645 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
5657 if (!this->emitCheckRefInit(
Init))
5661 return this->emitSetLocal(*VarT, Offset, VD);
5669 if (!this->emitGetPtrLocal(*Offset,
Init))
5677template <
class Emitter>
5698 Locals.insert({VD, Local});
5701 if (!this->emitGetPtrLocal(Local.Offset, VD))
5707 return this->emitDestructionPop(D, VD);
5716 if (
const auto *P = dyn_cast<ParmVarDecl>(E->
getDecl()))
5740template <
class Emitter>
5755 unsigned ParamIndex = 0;
5762 const Expr *Arg = Args[ParamIndex];
5763 const ParmVarDecl *Param = Callee->getParamDecl(ParamIndex);
5765 unsigned ArgOffset =
5767 if (!this->
visit(Arg))
5769 if (!this->emitSetLocal(*ParamT, ArgOffset, Arg))
5775 if (!this->emitGetPtrLocal(*ArgOffset, Arg))
5787 if (
This->getType()->isPointerType()) {
5790 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(
This)) {
5797 if (!this->emitGetPtrLocal(*ArgOffset,
This))
5819template <
class Emitter>
5825 return this->emitConst(Val.
getInt(), ValType, Info);
5828 return this->emitFloat(F, Info);
5833 if (!this->emitGetMemberPtr(MemberDecl, Info))
5839 if (!this->emitCopyMemberPtrPath(PathEntry, IsDerived, Info))
5845 return this->emitNullMemberPtr(0,
nullptr, Info);
5850 return this->emitNull(ValType, 0,
nullptr, Info);
5855 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
5856 return this->
visit(BaseExpr);
5861 QualType EntryType = VD->getType();
5862 for (
auto &Entry : Path) {
5864 uint64_t Index = Entry.getAsArrayIndex();
5867 if (!this->emitConst(Index,
PT_Uint64, Info))
5869 if (!this->emitArrayElemPtrPop(
PT_Uint64, Info))
5871 EntryType = ElemType;
5878 const Decl *BaseOrMember = Entry.getAsBaseOrMember().getPointer();
5879 if (
const auto *FD = dyn_cast<FieldDecl>(BaseOrMember)) {
5881 if (!this->emitGetPtrFieldPop(EntryOffset, Info))
5883 EntryType = FD->getType();
5887 if (!this->emitGetPtrBasePop(B->Offset,
false, Info))
5892 if (!this->emitGetPtrVirtBasePop(
Base, Info))
5895 EntryType =
Ctx.getASTContext().getCanonicalTagType(
Base);
5907template <
class Emitter>
5910 bool IsCompleteClass) {
5916 if (IsCompleteClass)
5923 const Record::Base *RB = R->getBase(I);
5924 QualType BaseType =
Ctx.getASTContext().getCanonicalTagType(RB->Decl);
5926 if (!this->emitGetPtrBase(RB->Offset, Info))
5931 if (!this->emitFinishInitPop(Info))
5939 const Record::Field *RF = R->getField(I);
5940 QualType FieldType = RF->Decl->getType();
5945 if (!this->emitInitField(*PT, RF->Offset, Info))
5948 if (!this->emitGetPtrField(RF->Offset, Info))
5952 if (!this->emitFinishInitPop(Info))
5958 if (IsCompleteClass) {
5963 const Record::Base *RB = R->getVirtualBase(I);
5964 QualType BaseType =
Ctx.getASTContext().getCanonicalTagType(RB->Decl);
5972 if (!this->emitFinishInitPop(Info))
5988 const Record::Field *RF = R->getField(UnionField);
5989 QualType FieldType = RF->Decl->getType();
5994 if (RF->isBitField())
5995 return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(),
5997 return this->emitInitFieldActivate(*PT, RF->Offset, Info);
6000 if (!this->emitGetPtrField(RF->Offset, Info))
6002 if (!this->emitActivate(Info))
6006 return this->emitPopPtr(Info);
6010 const auto *ArrType =
T->getAsArrayTypeUnsafe();
6011 QualType ElemType = ArrType->getElementType();
6014 for (
unsigned A = 0, AN = Val.
getArraySize(); A != AN; ++A) {
6015 const APValue &Elem = A >= InitializedElems
6024 if (!this->emitInitElem(*ElemT, A, Info))
6027 if (!this->emitConstUint32(A, Info))
6029 if (!this->emitArrayElemPtrUint32(Info))
6033 if (!this->emitPopPtr(Info))
6044template <
class Emitter>
6046 unsigned BuiltinID) {
6047 if (BuiltinID == Builtin::BI__builtin_constant_p) {
6052 return this->emitConst(0, E);
6055 if (!this->emitStartSpeculation(E))
6057 LabelTy EndLabel = this->getLabel();
6058 if (!this->speculate(E, EndLabel))
6060 if (!this->emitEndSpeculation(E))
6062 this->fallthrough(EndLabel);
6070 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6071 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
6072 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
6073 BuiltinID == Builtin::BI__builtin_function_start) {
6076 return this->emitDummyPtr(E, E);
6087 if (!this->emitGetPtrLocal(*LocalIndex, E))
6092 switch (BuiltinID) {
6093 case Builtin::BI__builtin_object_size:
6094 case Builtin::BI__builtin_dynamic_object_size: {
6098 if (!this->
visit(Arg0))
6109 case Builtin::BI__assume:
6110 case Builtin::BI__builtin_assume:
6113 case Builtin::BI__atomic_is_lock_free:
6114 case Builtin::BI__atomic_always_lock_free: {
6125 for (
const auto *Arg : E->
arguments()) {
6126 if (!this->
visit(Arg))
6132 if (!this->emitCallBI(E, BuiltinID, E))
6141template <
class Emitter>
6162 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(FuncDecl);
6163 DD && DD->isTrivial()) {
6165 if (!this->
visit(MemberCall->getImplicitObjectArgument()))
6167 return this->emitCheckDestruction(E) && this->emitEndLifetime(E) &&
6168 this->emitPopPtr(E);
6184 if (!this->emitGetPtrLocal(*LocalIndex, E))
6192 if (!this->emitGetPtrLocal(*LocalIndex, E))
6196 if (!this->emitDupPtr(E))
6203 bool IsAssignmentOperatorCall =
false;
6204 bool ActivateLHS =
false;
6205 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
6206 OCE && OCE->isAssignmentOp()) {
6210 assert(Args.size() == 2);
6211 const CXXRecordDecl *LHSRecord = Args[0]->getType()->getAsCXXRecordDecl();
6213 IsAssignmentOperatorCall =
true;
6214 std::reverse(Args.begin(), Args.end());
6220 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
6221 MD && MD->isStatic()) {
6225 Args.erase(Args.begin());
6229 bool Devirtualized =
false;
6232 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
6240 if (!this->
visit(Callee))
6242 if (!this->emitSetLocal(
PT_MemberPtr, *CalleeOffset, E))
6244 if (!this->emitGetLocal(
PT_MemberPtr, *CalleeOffset, E))
6246 if (!this->emitGetMemberPtrBase(E))
6249 const auto *InstancePtr = MC->getImplicitObjectArgument();
6256 Stripped->getType()->getPointeeType()->getAsCXXRecordDecl());
6257 Devirtualized =
true;
6258 if (!this->
visit(Stripped))
6261 if (!this->
visit(InstancePtr))
6265 if (!this->
visit(InstancePtr))
6269 }
else if (
const auto *PD =
6270 dyn_cast<CXXPseudoDestructorExpr>(E->
getCallee())) {
6271 if (!this->emitCheckPseudoDtor(E))
6279 return this->emitPseudoDtor(E);
6280 }
else if (!FuncDecl) {
6284 if (!this->
visit(Callee))
6286 if (!this->emitSetLocal(
PT_Ptr, *CalleeOffset, E))
6295 if (IsAssignmentOperatorCall) {
6296 assert(Args.size() == 2);
6299 if (!this->emitFlip(Arg2T, Arg1T, E))
6313 assert(HasRVO ==
Func->hasRVO());
6315 bool HasQualifier =
false;
6316 if (
const auto *ME = dyn_cast<MemberExpr>(E->
getCallee()))
6317 HasQualifier = ME->hasQualifier();
6319 bool IsVirtual =
false;
6320 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
6321 IsVirtual = !Devirtualized && MD->isVirtual();
6326 if (IsVirtual && !HasQualifier) {
6327 uint32_t VarArgSize = 0;
6328 unsigned NumParams =
6329 Func->getNumWrittenParams() +
6331 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
6334 if (!this->emitCallVirt(
Func, VarArgSize, E))
6336 }
else if (
Func->isVariadic()) {
6337 uint32_t VarArgSize = 0;
6338 unsigned NumParams =
6339 Func->getNumWrittenParams() +
6341 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
6343 if (!this->emitCallVar(
Func, VarArgSize, E))
6346 if (!this->emitCall(
Func, 0, E))
6355 uint32_t ArgSize = 0;
6356 for (
unsigned I = 0, N = E->
getNumArgs(); I != N; ++I)
6362 if (!this->emitGetLocal(
PT_MemberPtr, *CalleeOffset, E))
6364 if (!this->emitGetMemberPtrDecl(E))
6367 if (!this->emitGetLocal(
PT_Ptr, *CalleeOffset, E))
6370 if (!this->emitCallPtr(ArgSize, E, E))
6381template <
class Emitter>
6388template <
class Emitter>
6395template <
class Emitter>
6400 return this->emitConstBool(E->
getValue(), E);
6403template <
class Emitter>
6409 uint64_t Val =
Ctx.getASTContext().getTargetNullPointerValue(E->
getType());
6410 return this->emitNullPtr(Val,
nullptr, E);
6413template <
class Emitter>
6421 return this->emitZero(
T, E);
6424template <
class Emitter>
6429 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
6430 if (this->LambdaThisCapture.Offset > 0) {
6431 if (this->LambdaThisCapture.IsPtr)
6432 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
6433 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
6442 return this->emitThis(E);
6457 unsigned StartIndex = 0;
6458 unsigned EndIndex = 0;
6460 for (StartIndex =
InitStack.size() - 1; StartIndex > 0; --StartIndex) {
6462 EndIndex = StartIndex;
6469 for (; StartIndex > 0; --StartIndex) {
6480 if (StartIndex == 0 && EndIndex == 0)
6491 assert(StartIndex <= EndIndex);
6494 for (
unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
6506 case Stmt::CompoundStmtClass:
6508 case Stmt::DeclStmtClass:
6510 case Stmt::ReturnStmtClass:
6512 case Stmt::IfStmtClass:
6514 case Stmt::WhileStmtClass:
6516 case Stmt::DoStmtClass:
6518 case Stmt::ForStmtClass:
6520 case Stmt::CXXForRangeStmtClass:
6522 case Stmt::BreakStmtClass:
6524 case Stmt::ContinueStmtClass:
6526 case Stmt::SwitchStmtClass:
6528 case Stmt::CaseStmtClass:
6530 case Stmt::DefaultStmtClass:
6532 case Stmt::AttributedStmtClass:
6534 case Stmt::CXXTryStmtClass:
6536 case Stmt::NullStmtClass:
6539 case Stmt::GCCAsmStmtClass:
6540 case Stmt::MSAsmStmtClass:
6541 case Stmt::GotoStmtClass:
6542 return this->emitInvalid(S);
6543 case Stmt::LabelStmtClass:
6545 case Stmt::CXXExpansionStmtInstantiationClass:
6549 if (
const auto *E = dyn_cast<Expr>(S))
6556template <
class Emitter>
6559 for (
const auto *InnerStmt : S->
body())
6562 return Scope.destroyLocals();
6565template <
class Emitter>
6566bool Compiler<Emitter>::maybeEmitDeferredVarInit(
const VarDecl *VD) {
6567 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
6568 for (
auto *BD : DD->flat_bindings())
6569 if (
auto *KD = BD->getHoldingVar();
6570 KD && !this->visitVarDecl(KD, KD->getInit()))
6584template <
class Emitter>
bool Compiler<Emitter>::refersToUnion(
const Expr *E) {
6586 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
6587 if (
const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6594 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6599 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E);
6600 ICE && (ICE->getCastKind() == CK_NoOp ||
6601 ICE->getCastKind() == CK_DerivedToBase ||
6602 ICE->getCastKind() == CK_UncheckedDerivedToBase)) {
6603 E = ICE->getSubExpr();
6607 if (
const auto *
This = dyn_cast<CXXThisExpr>(E)) {
6608 const auto *ThisRecord =
6609 This->getType()->getPointeeType()->getAsRecordDecl();
6610 if (!ThisRecord->isUnion())
6613 if (
const auto *Ctor =
6614 dyn_cast_if_present<CXXConstructorDecl>(CompilingFunction))
6615 return Ctor->getParent() == ThisRecord;
6624template <
class Emitter>
6626 bool EvaluateConditionDecl) {
6627 for (
const auto *D : DS->
decls()) {
6632 if (
const auto *ESD = dyn_cast<CXXExpansionStmtDecl>(D)) {
6633 assert(ESD->getInstantiations() &&
"not expanded?");
6634 if (!this->
visitStmt(ESD->getInstantiations()))
6639 const auto *VD = dyn_cast<VarDecl>(D);
6646 if (EvaluateConditionDecl && !this->maybeEmitDeferredVarInit(VD))
6653template <
class Emitter>
6656 return this->emitUnsupported(RS);
6662 if (!this->
visit(RE))
6668 if (RE->getType()->isVoidType()) {
6669 if (!this->
visit(RE))
6672 if (RE->containsErrors())
6677 if (!this->emitRVOPtr(RE))
6683 return this->emitRetVoid(RS);
6689 return this->emitRetVoid(RS);
6695 auto visitChildStmt = [&](
const Stmt *S) ->
bool {
6702 if (
auto *CondInit = IS->
getInit()) {
6718 return visitChildStmt(IS->
getThen());
6720 return visitChildStmt(Else);
6726 if (!this->emitIsConstantContext(IS))
6729 if (!this->emitIsConstantContext(IS))
6731 if (!this->emitInv(IS))
6745 LabelTy LabelElse = this->getLabel();
6746 LabelTy LabelEnd = this->getLabel();
6747 if (!this->jumpFalse(LabelElse, IS))
6749 if (!visitChildStmt(IS->
getThen()))
6751 if (!this->jump(LabelEnd, IS))
6753 this->emitLabel(LabelElse);
6754 if (!visitChildStmt(Else))
6756 this->emitLabel(LabelEnd);
6758 LabelTy LabelEnd = this->getLabel();
6759 if (!this->jumpFalse(LabelEnd, IS))
6761 if (!visitChildStmt(IS->
getThen()))
6763 this->emitLabel(LabelEnd);
6772template <
class Emitter>
6777 LabelTy CondLabel = this->getLabel();
6778 LabelTy EndLabel = this->getLabel();
6782 this->fallthrough(CondLabel);
6783 this->emitLabel(CondLabel);
6799 if (!this->jumpFalse(EndLabel, S))
6809 if (!this->jump(CondLabel, S))
6811 this->fallthrough(EndLabel);
6812 this->emitLabel(EndLabel);
6821 LabelTy StartLabel = this->getLabel();
6822 LabelTy EndLabel = this->getLabel();
6823 LabelTy CondLabel = this->getLabel();
6827 this->fallthrough(StartLabel);
6828 this->emitLabel(StartLabel);
6834 this->fallthrough(CondLabel);
6835 this->emitLabel(CondLabel);
6842 if (!this->jumpTrue(StartLabel, S))
6845 this->fallthrough(EndLabel);
6846 this->emitLabel(EndLabel);
6850template <
class Emitter>
6858 LabelTy EndLabel = this->getLabel();
6859 LabelTy CondLabel = this->getLabel();
6860 LabelTy IncLabel = this->getLabel();
6867 this->fallthrough(CondLabel);
6868 this->emitLabel(CondLabel);
6880 if (!this->jumpFalse(EndLabel, S))
6889 this->fallthrough(IncLabel);
6890 this->emitLabel(IncLabel);
6896 if (!this->jump(CondLabel, S))
6900 this->emitLabel(EndLabel);
6906template <
class Emitter>
6916 LabelTy EndLabel = this->getLabel();
6917 LabelTy CondLabel = this->getLabel();
6918 LabelTy IncLabel = this->getLabel();
6933 this->fallthrough(CondLabel);
6934 this->emitLabel(CondLabel);
6937 if (!this->jumpFalse(EndLabel, S))
6948 this->fallthrough(IncLabel);
6949 this->emitLabel(IncLabel);
6954 if (!this->jump(CondLabel, S))
6957 this->fallthrough(EndLabel);
6958 this->emitLabel(EndLabel);
6962template <
class Emitter>
6973 if (LI.BreakLabel) {
6974 TargetLabel = *LI.BreakLabel;
6975 BreakScope = LI.BreakOrContinueScope;
6981 if (LI.Name == TargetLoop) {
6982 TargetLabel = *LI.BreakLabel;
6983 BreakScope = LI.BreakOrContinueScope;
6994 C =
C->getParent()) {
6995 if (!
C->destroyLocals())
6999 return this->jump(*TargetLabel, S);
7002template <
class Emitter>
7013 if (LI.ContinueLabel) {
7014 TargetLabel = *LI.ContinueLabel;
7015 ContinueScope = LI.BreakOrContinueScope;
7021 if (LI.Name == TargetLoop) {
7022 TargetLabel = *LI.ContinueLabel;
7023 ContinueScope = LI.BreakOrContinueScope;
7028 assert(TargetLabel);
7031 C =
C->getParent()) {
7032 if (!
C->destroyLocals())
7036 return this->jump(*TargetLabel, S);
7039template <
class Emitter>
7042 if (
Cond->containsErrors())
7049 LabelTy EndLabel = this->getLabel();
7054 if (
const auto *CondInit = S->
getInit())
7065 if (!this->emitSetLocal(CondT, CondVar, S))
7075 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
7078 if (CS->caseStmtIsGNURange()) {
7079 LabelTy EndOfRangeCheck = this->getLabel();
7080 const Expr *Low = CS->getLHS();
7081 const Expr *High = CS->getRHS();
7085 if (!this->emitGetLocal(CondT, CondVar, CS))
7087 if (!this->
visit(Low))
7090 if (!this->emitGE(
LT, S))
7092 if (!this->jumpFalse(EndOfRangeCheck, S))
7095 if (!this->emitGetLocal(CondT, CondVar, CS))
7097 if (!this->
visit(High))
7100 if (!this->emitLE(HT, S))
7104 this->emitLabel(EndOfRangeCheck);
7109 if (
Value->isValueDependent())
7114 if (!this->emitGetLocal(CondT, CondVar, CS))
7120 if (!this->emitEQ(ValueT, S))
7125 assert(!DefaultLabel);
7126 DefaultLabel = this->getLabel();
7133 if (!this->jump(*DefaultLabel, S))
7136 if (!this->jump(EndLabel, S))
7144 this->fallthrough(EndLabel);
7145 this->emitLabel(EndLabel);
7150template <
class Emitter>
7158 return this->emitUnsupported(S);
7163template <
class Emitter>
7170 if (LI.DefaultLabel) {
7171 DefaultLabel = *LI.DefaultLabel;
7176 this->emitLabel(DefaultLabel);
7180template <
class Emitter>
7187 if (IsMSVCConstexprAttr && !this->emitPushMSVCCE(S))
7190 if (this->
Ctx.getLangOpts().CXXAssumptions &&
7191 !this->Ctx.getLangOpts().MSVCCompat) {
7193 auto *AA = dyn_cast<CXXAssumeAttr>(A);
7199 const Expr *Assumption = AA->getAssumption();
7210 if (!this->emitAssume(Assumption))
7219 if (IsMSVCConstexprAttr)
7220 return this->emitPopMSVCCE(S);
7224template <
class Emitter>
7237template <
class Emitter>
7247 LabelTy EndLabel = this->getLabel();
7249 LabelTy ContinueLabel = this->getLabel();
7254 this->emitLabel(ContinueLabel);
7257 this->emitLabel(EndLabel);
7262template <
class Emitter>
7263bool Compiler<Emitter>::emitLambdaStaticInvokerBody(
const CXXMethodDecl *MD) {
7270 assert(ClosureClass->
captures().empty());
7274 "A generic lambda's static-invoker function must be a "
7275 "template specialization");
7279 void *InsertPos =
nullptr;
7280 const FunctionDecl *CorrespondingCallOpSpecialization =
7282 assert(CorrespondingCallOpSpecialization);
7283 LambdaCallOp = CorrespondingCallOpSpecialization;
7287 assert(ClosureClass->
captures().empty());
7288 const Function *
Func = this->getFunction(LambdaCallOp);
7291 assert(
Func->hasThisPointer());
7294 if (
Func->hasRVO()) {
7295 if (!this->emitRVOPtr(MD))
7303 if (!this->emitNullPtr(0,
nullptr, MD))
7308 auto It = this->Params.find(PVD);
7309 assert(It != this->Params.end());
7313 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
7314 if (!this->emitGetParam(ParamType, It->second.Index, MD))
7318 if (!this->emitCall(
Func, 0, LambdaCallOp))
7323 return this->emitRet(*ReturnType, MD);
7326 return this->emitRetVoid(MD);
7329template <
class Emitter>
7330bool Compiler<Emitter>::checkLiteralType(
const Expr *E) {
7331 if (Ctx.getLangOpts().CPlusPlus23)
7341 const Expr *InitExpr =
Init->getInit();
7343 if (!
Init->isWritten() && !
Init->isInClassMemberInitializer() &&
7347 if (
const auto *CE = dyn_cast<CXXConstructExpr>(InitExpr)) {
7357template <
class Emitter>
7359 assert(!ReturnType);
7362 if (!this->emitStartThisLifetime1(Ctor))
7365 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
7366 const Expr *InitExpr,
7369 if (InitExpr->getType().isNull())
7373 if (
Activate && !this->emitActivateThisField(FieldOffset, InitExpr))
7376 if (!this->visit(InitExpr))
7379 if (F->isBitField())
7380 return this->emitInitThisBitField(*
T, FieldOffset, F->bitWidth(),
7382 return this->emitInitThisField(*
T, FieldOffset, InitExpr);
7387 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
7390 if (
Activate && !this->emitActivate(InitExpr))
7393 return this->visitInitializerPop(InitExpr);
7397 const Record *
R = this->getRecord(RD);
7400 bool IsUnion =
R->isUnion();
7410 if (!this->emitThis(Ctor))
7413 if (!this->emitGetParam(
PT_Ptr, 0, Ctor))
7416 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
7417 this->emitRetVoid(Ctor);
7420 unsigned FieldInits = 0;
7423 if (
R->getNumVirtualBases() > 0) {
7424 if (!this->emitThis(Ctor))
7426 LabelTy AfterVirtBasesLabel = this->getLabel();
7429 if (!this->emitIsBaseClass({}))
7431 if (!this->jumpTrue(AfterVirtBasesLabel, {}))
7434 for (
const auto *
Init : Ctor->
inits()) {
7437 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
7439 assert(
R->getVirtualBase(BaseDecl));
7440 if (!this->emitGetPtrThisVirtBase(BaseDecl, Ctor))
7442 if (!this->visitInitializerPop(
Init->getInit()))
7447 this->fallthrough(AfterVirtBasesLabel);
7448 this->emitLabel(AfterVirtBasesLabel);
7450 if (!this->emitPopPtr(Ctor))
7454 for (
const auto *
Init : Ctor->
inits()) {
7458 const Expr *InitExpr =
Init->getInit();
7460 const Record::Field *F =
R->getField(
Member);
7464 if (!emitFieldInitializer(F, F->Offset, InitExpr, IsUnion))
7468 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
7471 if (
Init->isBaseVirtual()) {
7477 const Record::Base *B =
R->getBase(BaseDecl);
7479 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
7483 if (!this->visitInitializerPop(InitExpr))
7488 unsigned ChainSize = IFD->getChainingSize();
7489 assert(ChainSize >= 2);
7491 unsigned NestedFieldOffset = 0;
7492 const Record::Field *NestedField =
nullptr;
7493 for (
unsigned I = 0; I != ChainSize; ++I) {
7495 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
7496 assert(FieldRecord);
7498 NestedField = FieldRecord->
getField(FD);
7499 assert(NestedField);
7500 IsUnion = IsUnion || FieldRecord->
isUnion();
7502 NestedFieldOffset += NestedField->Offset;
7505 if (I != ChainSize - 1)
7508 assert(NestedField);
7511 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
7516 unsigned InitFieldOffset = 0;
7517 for (
const NamedDecl *ND : IFD->chain().drop_back()) {
7519 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
7520 assert(FieldRecord);
7521 NestedField = FieldRecord->
getField(FD);
7522 InitFieldOffset += NestedField->Offset;
7523 assert(NestedField);
7524 if (!this->emitGetPtrThisField(InitFieldOffset, InitExpr))
7526 if (!this->emitFinishInitPop(InitExpr))
7530 InitStack.pop_back_n(ChainSize - 1);
7533 assert(
Init->isDelegatingInitializer());
7534 if (!this->emitThis(InitExpr))
7536 if (!this->visitInitializerPop(
Init->getInit()))
7540 if (!
Scope.destroyLocals())
7544 if (FieldInits !=
R->getNumFields()) {
7545 assert(FieldInits < R->getNumFields());
7547 if (!this->emitStartThisLifetime(Ctor))
7554 if (
const auto *CS = dyn_cast<CompoundStmt>(Body)) {
7555 if (!CS->body_empty() && !this->emitCtorCheck(
SourceInfo{}))
7562 if (!visitStmt(Body))
7569template <
class Emitter>
7572 const Record *
R = this->getRecord(RD);
7576 if (!
Dtor->isTrivial() &&
Dtor->getBody()) {
7577 if (!this->visitStmt(
Dtor->getBody()))
7581 if (!this->emitThis(
Dtor))
7584 if (!this->emitCheckDestruction(
Dtor))
7588 if (!
R->isUnion()) {
7592 for (
const Record::Field &Field : llvm::reverse(
R->fields())) {
7596 if (!this->emitGetPtrField(Field.Offset,
SourceInfo{}))
7598 if (!this->emitDestructionPop(D,
SourceInfo{}))
7603 for (
const Record::Base &
Base : llvm::reverse(
R->bases())) {
7604 if (
Base.R->hasTrivialDtor())
7608 if (!this->emitRecordDestructionPop(
Base.R, {}))
7612 if (
R->getNumVirtualBases() > 0) {
7613 LabelTy EndLabel = this->getLabel();
7615 if (!this->emitIsBaseClass({}))
7617 if (!this->jumpTrue(EndLabel, {}))
7620 for (
const Record::Base &
Base : llvm::reverse(
R->virtual_bases())) {
7621 if (
Base.R->hasTrivialDtor())
7626 if (!this->emitRecordDestructionPop(
Base.R, {}))
7630 this->fallthrough(EndLabel);
7631 this->emitLabel(EndLabel);
7634 if (!this->emitMarkDestroyed(
Dtor))
7637 return this->emitPopPtr(
Dtor) && this->emitRetVoid(
Dtor);
7640template <
class Emitter>
7641bool Compiler<Emitter>::compileUnionAssignmentOperator(
7643 if (!this->emitThis(MD))
7646 if (!this->emitGetParam(
PT_Ptr, 0, MD))
7649 return this->emitMemcpy(MD) && this->emitRet(
PT_Ptr, MD);
7652template <
class Emitter>
7662 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
7663 return this->compileConstructor(Ctor);
7664 if (
const auto *
Dtor = dyn_cast<CXXDestructorDecl>(F))
7665 return this->compileDestructor(
Dtor);
7668 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
7673 return this->compileUnionAssignmentOperator(MD);
7676 return this->emitLambdaStaticInvokerBody(MD);
7680 if (
const auto *Body = F->
getBody())
7694 return FD->getBitWidthValue();
7697template <
class Emitter>
7713 if (!
Ctx.getLangOpts().CPlusPlus14)
7714 return this->emitInvalid(E);
7716 return this->emitError(E);
7718 if (!this->
visit(SubExpr))
7722 if (!this->emitIncPtr(E))
7729 return DiscardResult ? this->emitIncfPop(getFPOptions(E), E)
7730 : this->emitIncf(getFPOptions(E), E);
7742 if (!
Ctx.getLangOpts().CPlusPlus14)
7743 return this->emitInvalid(E);
7745 return this->emitError(E);
7747 if (!this->
visit(SubExpr))
7751 if (!this->emitDecPtr(E))
7758 return DiscardResult ? this->emitDecfPop(getFPOptions(E), E)
7759 : this->emitDecf(getFPOptions(E), E);
7772 if (!
Ctx.getLangOpts().CPlusPlus14)
7773 return this->emitInvalid(E);
7775 return this->emitError(E);
7777 if (!this->
visit(SubExpr))
7781 if (!this->emitLoadPtr(E))
7783 if (!this->emitConstUint8(1, E))
7785 if (!this->emitAddOffsetUint8(E))
7787 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7793 return this->emitIncfPop(getFPOptions(E), E);
7803 const auto &TargetSemantics =
Ctx.getFloatSemantics(E->
getType());
7804 if (!this->emitLoadFloat(E))
7806 APFloat F(TargetSemantics, 1);
7807 if (!this->emitFloat(F, E))
7810 if (!this->emitAddf(getFPOptions(E), E))
7812 if (!this->emitStoreFloat(E))
7824 return E->
isGLValue() || this->emitLoadPop(*
T, E);
7827 if (!
Ctx.getLangOpts().CPlusPlus14)
7828 return this->emitInvalid(E);
7830 return this->emitError(E);
7832 if (!this->
visit(SubExpr))
7836 if (!this->emitLoadPtr(E))
7838 if (!this->emitConstUint8(1, E))
7840 if (!this->emitSubOffsetUint8(E))
7842 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7848 return this->emitDecfPop(getFPOptions(E), E);
7858 const auto &TargetSemantics =
Ctx.getFloatSemantics(E->
getType());
7859 if (!this->emitLoadFloat(E))
7861 APFloat F(TargetSemantics, 1);
7862 if (!this->emitFloat(F, E))
7865 if (!this->emitSubf(getFPOptions(E), E))
7867 if (!this->emitStoreFloat(E))
7879 return E->
isGLValue() || this->emitLoadPop(*
T, E);
7883 return this->emitError(E);
7886 return this->
discard(SubExpr);
7891 if (!this->emitInv(E))
7895 return this->emitCast(
PT_Bool, ET, E);
7899 return this->emitError(E);
7901 if (!this->
visit(SubExpr))
7906 return this->emitError(E);
7908 if (!this->
visit(SubExpr))
7924 if (!
Ctx.getLangOpts().CPlusPlus) {
7926 if (
const auto *Deref = dyn_cast<UnaryOperator>(
Sub);
7927 Deref && Deref->getOpcode() == UO_Deref)
7928 return this->
delegate(Deref->getSubExpr());
7934 return this->
discard(SubExpr);
7936 if (!this->
visit(SubExpr))
7943 return this->emitNarrowPtr(E);
7948 return this->emitError(E);
7950 if (!this->
visit(SubExpr))
7964 : this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
7969 assert(
false &&
"Unhandled opcode");
7975template <
class Emitter>
7981 return this->
discard(SubExpr);
7984 auto prepareResult = [=]() ->
bool {
7989 return this->emitGetPtrLocal(*LocalIndex, E);
7996 unsigned SubExprOffset = ~0u;
7997 auto createTemp = [=, &SubExprOffset]() ->
bool {
8000 if (!this->
visit(SubExpr))
8002 return this->emitSetLocal(
PT_Ptr, SubExprOffset, E);
8006 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
8007 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
8009 return this->emitArrayElemPop(ElemT, Index, E);
8014 if (!prepareResult())
8018 for (
unsigned I = 0; I != 2; ++I) {
8019 if (!getElem(SubExprOffset, I))
8021 if (!this->emitNeg(ElemT, E))
8023 if (!this->emitInitElem(ElemT, I, E))
8034 if (!this->
visit(SubExpr))
8036 if (!this->emitComplexBoolCast(SubExpr))
8038 if (!this->emitInv(E))
8041 return this->emitCast(
PT_Bool, ET, E);
8045 return this->emitComplexReal(SubExpr);
8048 if (!this->
visit(SubExpr))
8052 if (!this->emitConstUint8(1, E))
8054 return this->emitArrayElemPtrPopUint8(E);
8065 if (!this->emitArrayElem(ElemT, 1, E))
8067 if (!this->emitNeg(ElemT, E))
8069 if (!this->emitInitElem(ElemT, 1, E))
8077 return this->emitInvalid(E);
8083template <
class Emitter>
8089 return this->
discard(SubExpr);
8092 if (UnaryOp == UO_Extension)
8095 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
8096 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
8097 return this->emitInvalid(E);
8100 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
8107 if (!this->emitGetPtrLocal(*LocalIndex, E))
8112 unsigned SubExprOffset =
8114 if (!this->
visit(SubExpr))
8116 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, E))
8121 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
8122 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
8124 return this->emitArrayElemPop(ElemT, Index, E);
8129 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8130 if (!getElem(SubExprOffset, I))
8132 if (!this->emitNeg(ElemT, E))
8134 if (!this->emitInitElem(ElemT, I, E))
8149 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8150 if (!getElem(SubExprOffset, I))
8153 if (!this->emitPrimCast(ElemT,
PT_Bool,
Ctx.getASTContext().BoolTy, E))
8155 if (!this->emitInv(E))
8157 if (!this->emitPrimCast(
PT_Bool, ElemT, VecTy->getElementType(), E))
8159 if (!this->emitNeg(ElemT, E))
8161 if (ElemT != ResultVecElemT &&
8162 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy, E))
8164 if (!this->emitInitElem(ResultVecElemT, I, E))
8170 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8171 if (!getElem(SubExprOffset, I))
8174 if (!this->emitInv(E))
8177 if (!this->emitComp(ElemT, E))
8180 if (!this->emitInitElem(ElemT, I, E))
8185 llvm_unreachable(
"Unsupported unary operators should be handled up front");
8190template <
class Emitter>
8192 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
8195 return this->emitConst(ECD->getInitVal(), E);
8197 if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
8201 return F && this->emitGetFnPtr(F, E);
8203 if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
8204 TPOD = TPOD->getFirstDecl();
8208 return this->emitGetPtrGlobal(*GlobalIndex, E);
8214 return this->emitInitGlobal(*
T, *Index, E);
8217 if (!this->emitGetPtrGlobal(*Index, E))
8221 return this->emitFinishInit(E);
8233 auto maybePopPtr = [&]() ->
bool {
8235 return this->emitPopPtr(E);
8242 if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
8246 if (
Ctx.getLangOpts().CPlusPlus && !
Ctx.getLangOpts().CPlusPlus11 &&
8251 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
8252 if (IsReference || !It->second.IsPtr)
8253 return this->emitGetParam(
classifyPrim(E), It->second.Index, E);
8255 return this->emitGetPtrParam(It->second.Index, E);
8258 if (!
Ctx.getLangOpts().CPlusPlus23 && IsReference && !
Locals.contains(D))
8265 const unsigned Offset = It->second.Offset;
8268 return this->emitGetRefLocal(Offset, E) && maybePopPtr();
8270 return this->emitGetPtrLocal(Offset, E) && maybePopPtr();
8273 if (
auto GlobalIndex =
P.getGlobal(D)) {
8275 if (!
Ctx.getLangOpts().CPlusPlus11)
8276 return this->emitGetGlobal(
classifyPrim(E), *GlobalIndex, E);
8277 if (!
Ctx.getLangOpts().CPlusPlus23)
8278 return this->emitGetGlobalUnchecked(
classifyPrim(E), *GlobalIndex, E);
8280 return this->emitGetRefGlobal(*GlobalIndex, E) && maybePopPtr();
8283 return this->emitGetPtrGlobal(*GlobalIndex, E) && maybePopPtr();
8287 auto revisit = [&](
const VarDecl *VD,
8288 bool IsConstexprUnknown =
true) ->
bool {
8290 IsConstexprUnknown);
8291 if constexpr (std::is_same_v<Emitter, EvalEmitter>) {
8297 if constexpr (std::is_same_v<Emitter, EvalEmitter>) {
8298 if (!this->emitPopCC(E))
8302 if (VarState.notCreated())
8310 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
8312 if (
auto It = this->LambdaCaptures.find(D);
8313 It != this->LambdaCaptures.end()) {
8314 auto [Offset, IsPtr] = It->second;
8317 return this->emitGetThisFieldPtr(Offset, E) && maybePopPtr();
8318 return this->emitGetPtrThisField(Offset, E) && maybePopPtr();
8322 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E);
8323 DRE && DRE->refersToEnclosingVariableOrCapture()) {
8324 if (
const auto *VD = dyn_cast<VarDecl>(D); VD && VD->
isInitCapture())
8328 if (
const auto *BD = dyn_cast<BindingDecl>(D))
8329 return this->
delegate(BD->getBinding());
8335 return this->emitDummyPtr(D, E);
8340 const auto *VD = dyn_cast<VarDecl>(D);
8342 return this->emitError(E);
8345 if (!
Ctx.getLangOpts().CPlusPlus) {
8349 return revisit(VD,
false);
8353 return this->emitDummyPtr(D, E);
8357 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
8358 if (
T.isConstant(
Ctx.getASTContext()))
8360 return T->isReferenceType();
8364 typeShouldBeVisited(DeclType)) {
8366 Init && !
Init->isValueDependent()) {
8371 (void)
Init->EvaluateAsInitializer(
Ctx.getASTContext(), VD,
Result,
true);
8384 bool IsConstexprUnknown = !DeclType.
isConstant(
Ctx.getASTContext()) &&
8389 return revisit(VD, IsConstexprUnknown);
8390 }
else if (
Ctx.getLangOpts().CPlusPlus23 && IsReference)
8391 return revisit(VD,
true);
8400 return this->emitDummyPtr(
8404template <
class Emitter>
8410template <
class Emitter>
8420 if (!
C->destroyLocals())
8426template <
class Emitter>
8427unsigned Compiler<Emitter>::collectBaseOffset(
const QualType BaseType,
8430 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
8432 return Ty->getAsCXXRecordDecl();
8434 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
8435 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
8437 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
8441template <
class Emitter>
8448 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
8453 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
8454 getFPOptions(E), E);
8456 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
8457 getFPOptions(E), E);
8461 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
8466 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
8468 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
8472 return FromT != ToT ? this->emitCast(FromT, ToT, E) :
true;
8476 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
8477 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E);
8484template <
class Emitter>
8487 assert(FromT != ToT);
8490 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
8492 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
8494 return this->emitCast(FromT, ToT, E);
8498template <
class Emitter>
8499bool Compiler<Emitter>::emitComplexReal(
const Expr *SubExpr) {
8503 return this->
discard(SubExpr);
8505 if (!this->visit(SubExpr))
8508 if (!this->emitConstUint8(0, SubExpr))
8510 return this->emitArrayElemPtrPopUint8(SubExpr);
8514 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
8518template <
class Emitter>
8519bool Compiler<Emitter>::emitComplexBoolCast(
const Expr *E) {
8520 assert(!DiscardResult);
8524 if (!this->emitArrayElem(ElemT, 0, E))
8527 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(E), E))
8530 if (!this->emitCast(ElemT,
PT_Bool, E))
8535 LabelTy LabelTrue = this->getLabel();
8536 if (!this->jumpTrue(LabelTrue, E))
8539 if (!this->emitArrayElemPop(ElemT, 1, E))
8542 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(E), E))
8545 if (!this->emitCast(ElemT,
PT_Bool, E))
8549 LabelTy EndLabel = this->getLabel();
8550 this->jump(EndLabel, E);
8552 this->emitLabel(LabelTrue);
8553 if (!this->emitPopPtr(E))
8555 if (!this->emitConstBool(
true, E))
8558 this->fallthrough(EndLabel);
8559 this->emitLabel(EndLabel);
8564template <
class Emitter>
8565bool Compiler<Emitter>::emitComplexComparison(
const Expr *LHS,
const Expr *RHS,
8576 LHSIsComplex =
true;
8577 ElemT = classifyComplexElementType(LHS->
getType());
8578 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true);
8579 if (!this->visit(LHS))
8581 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
8584 LHSIsComplex =
false;
8586 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true);
8587 if (!this->visit(LHS))
8589 if (!this->emitSetLocal(LHST, LHSOffset, E))
8596 RHSIsComplex =
true;
8597 ElemT = classifyComplexElementType(RHS->
getType());
8598 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true);
8599 if (!this->visit(RHS))
8601 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
8604 RHSIsComplex =
false;
8606 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true);
8607 if (!this->visit(RHS))
8609 if (!this->emitSetLocal(RHST, RHSOffset, E))
8613 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
8614 bool IsComplex) ->
bool {
8616 if (!this->emitGetLocal(
PT_Ptr, LocalOffset, E))
8618 return this->emitArrayElemPop(ElemT, Index, E);
8620 return this->emitGetLocal(ElemT, LocalOffset, E);
8623 for (
unsigned I = 0; I != 2; ++I) {
8625 if (!getElem(LHSOffset, I, LHSIsComplex))
8627 if (!getElem(RHSOffset, I, RHSIsComplex))
8630 if (!this->emitEQ(ElemT, E))
8633 if (!this->emitCastBoolUint8(E))
8638 if (!this->emitAddUint8(E))
8640 if (!this->emitConstUint8(2, E))
8644 if (!this->emitEQUint8(E))
8647 if (!this->emitNEUint8(E))
8654 return this->emitCast(
PT_Bool, ResT, E);
8661template <
class Emitter>
8662bool Compiler<Emitter>::emitRecordDestructionPop(
const Record *R,
8665 assert(!
R->hasTrivialDtor());
8668 const Function *DtorFunc = getFunction(
Dtor);
8671 assert(DtorFunc->hasThisPointer());
8672 assert(DtorFunc->getNumParams() == 1);
8673 return this->emitCall(DtorFunc, 0, Loc);
8678template <
class Emitter>
8679bool Compiler<Emitter>::emitDestructionPop(
const Descriptor *Desc,
8691 return this->emitPopPtr(Loc);
8693 for (ssize_t I = N - 1; I >= 1; --I) {
8694 if (!this->emitConstUint64(I, Loc))
8696 if (!this->emitArrayElemPtrUint64(Loc))
8698 if (!this->emitDestructionPop(ElemDesc, Loc))
8702 if (!this->emitConstUint64(0, Loc))
8704 if (!this->emitArrayElemPtrPopUint64(Loc))
8706 return this->emitDestructionPop(ElemDesc, Loc);
8711 return this->emitRecordDestructionPop(Desc->
ElemRecord, Loc);
8716template <
class Emitter>
8717bool Compiler<Emitter>::emitDummyPtr(
DeclOrExpr D,
const Expr *E,
bool CU) {
8718 assert(!DiscardResult &&
"Should've been checked before");
8719 unsigned DummyID = P.getOrCreateDummy(D, CU);
8721 if (!this->emitGetPtrGlobal(DummyID, E))
8729 return this->emitDecayPtr(
PT_Ptr, PT, E);
8735template <
class Emitter>
8738 return this->emitConstFloat(
Floating(F), Info);
8740 APInt I = F.bitcastToAPInt();
8741 return this->emitConstFloat(
8742 Floating(
const_cast<uint64_t *
>(I.getRawData()),
8743 llvm::APFloatBase::SemanticsToEnum(F.getSemantics())),
8754template <
class Emitter>
8755bool Compiler<Emitter>::emitBuiltinBitCast(
const CastExpr *E) {
8768 if (!this->emitGetPtrLocal(*LocalIndex, E))
8778 if (!this->visit(SubExpr))
8780 }
else if (
OptPrimType FromT = classify(SubExpr)) {
8781 unsigned TempOffset =
8782 allocateLocalPrimitive(SubExpr, *FromT,
true);
8783 if (!this->visit(SubExpr))
8785 if (!this->emitSetLocal(*FromT, TempOffset, E))
8787 if (!this->emitGetPtrLocal(TempOffset, E))
8794 if (!this->emitBitCast(E))
8796 return DiscardResult ? this->emitPopPtr(E) :
true;
8800 const llvm::fltSemantics *TargetSemantics =
nullptr;
8802 TargetSemantics = &Ctx.getFloatSemantics(ToType);
8808 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
8810 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->
isStdByteType(),
8811 ResultBitWidth, TargetSemantics,
8816 return this->emitPop(*ToT, E);
8825template <
class Emitter>
8826bool Compiler<Emitter>::emitHLSLAggregateSplat(
PrimType SrcT,
8831 unsigned NumElems = 0;
8834 NumElems = VT->getNumElements();
8835 ElemType = VT->getElementType();
8837 NumElems = MT->getNumElementsFlattened();
8838 ElemType = MT->getElementType();
8841 PrimType ElemT = classifyPrim(ElemType);
8842 for (
unsigned I = 0; I != NumElems; ++I) {
8843 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8845 if (!this->emitPrimCast(SrcT, ElemT, ElemType, E))
8847 if (!this->emitInitElem(ElemT, I, E))
8857 QualType ArrElemType = CAT->getElementType();
8858 unsigned ArrSize = CAT->getZExtSize();
8861 for (
unsigned I = 0; I != ArrSize; ++I) {
8862 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8864 if (!this->emitPrimCast(SrcT, *ElemT, ArrElemType, E))
8866 if (!this->emitInitElem(*ElemT, I, E))
8870 for (
unsigned I = 0; I != ArrSize; ++I) {
8871 if (!this->emitConstUint32(I, E))
8873 if (!this->emitArrayElemPtrUint32(E))
8875 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, ArrElemType, E))
8877 if (!this->emitFinishInitPop(E))
8887 const Record *
R = getRecord(DestType);
8891 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
8893 const Record::Base *B =
R->getBase(BS.getType());
8895 if (!this->emitGetPtrBase(B->Offset, E))
8897 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, BS.getType(), E))
8899 if (!this->emitFinishInitPop(E))
8904 for (
const Record::Field &F :
R->fields()) {
8905 if (F.isUnnamedBitField())
8908 QualType FieldType = F.Decl->getType();
8910 if (!this->emitGetLocal(SrcT, SrcOffset, E))
8912 if (!this->emitPrimCast(SrcT, *FieldT, FieldType, E))
8914 if (F.isBitField()) {
8915 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
8918 if (!this->emitInitField(*FieldT, F.Offset, E))
8922 if (!this->emitGetPtrField(F.Offset, E))
8924 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, FieldType, E))
8926 if (!this->emitPopPtr(E))
8939template <
class Emitter>
8940unsigned Compiler<Emitter>::countHLSLFlatElements(
QualType Ty) {
8943 return VT->getNumElements();
8945 return MT->getNumElementsFlattened();
8949 return CAT->getZExtSize() * countHLSLFlatElements(CAT->getElementType());
8953 const Record *
R = getRecord(Ty);
8957 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
8959 Count += countHLSLFlatElements(BS.getType());
8961 for (
const Record::Field &F :
R->fields()) {
8962 if (F.isUnnamedBitField())
8964 Count += countHLSLFlatElements(F.Decl->getType());
8969 if (canClassify(Ty))
8978template <
class Emitter>
8979bool Compiler<Emitter>::emitHLSLFlattenAggregate(
8980 QualType SrcType,
unsigned SrcOffset,
8985 auto saveToLocal = [&](
PrimType T) ->
bool {
8986 unsigned Offset = allocateLocalPrimitive(E,
T,
true);
8987 if (!this->emitSetLocal(
T, Offset, E))
8989 Elements.push_back({Offset,
T});
8995 unsigned Offset = allocateLocalPrimitive(E,
PT_Ptr,
true);
8996 if (!this->emitSetLocal(
PT_Ptr, Offset, E))
8997 return std::nullopt;
9002 unsigned NumElems = 0;
9005 NumElems = VT->getNumElements();
9006 ElemType = VT->getElementType();
9008 NumElems = MT->getNumElementsFlattened();
9009 ElemType = MT->getElementType();
9012 PrimType ElemT = classifyPrim(ElemType);
9013 for (
unsigned I = 0; I != NumElems && Elements.size() < MaxElements; ++I) {
9014 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9016 if (!this->emitArrayElemPop(ElemT, I, E))
9018 if (!saveToLocal(ElemT))
9028 QualType ArrElemType = CAT->getElementType();
9029 unsigned ArrSize = CAT->getZExtSize();
9032 for (
unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
9033 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9035 if (!this->emitArrayElemPop(*ElemT, I, E))
9037 if (!saveToLocal(*ElemT))
9041 for (
unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
9042 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9044 if (!this->emitConstUint32(I, E))
9046 if (!this->emitArrayElemPtrPopUint32(E))
9051 if (!emitHLSLFlattenAggregate(ArrElemType, *ElemPtrOffset, Elements,
9062 const Record *
R = getRecord(SrcType);
9066 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
9068 if (Elements.size() >= MaxElements)
9070 const Record::Base *B =
R->getBase(BS.getType());
9072 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9074 if (!this->emitGetPtrBasePop(B->Offset,
false, E))
9079 if (!emitHLSLFlattenAggregate(BS.getType(), *BasePtrOffset, Elements,
9085 for (
const Record::Field &F :
R->fields()) {
9086 if (Elements.size() >= MaxElements)
9088 if (F.isUnnamedBitField())
9091 QualType FieldType = F.Decl->getType();
9092 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9094 if (!this->emitGetPtrFieldPop(F.Offset, E))
9098 if (!this->emitLoadPop(*FieldT, E))
9100 if (!saveToLocal(*FieldT))
9104 if (!FieldPtrOffset)
9106 if (!emitHLSLFlattenAggregate(FieldType, *FieldPtrOffset, Elements,
9122template <
class Emitter>
9123bool Compiler<Emitter>::emitHLSLConstructAggregate(
9129 const auto &Src = Elements[ElemIdx++];
9130 if (!this->emitGetLocal(Src.Type, Src.LocalOffset, E))
9132 return this->emitPrimCast(Src.Type, DestT, DestQT, E);
9136 unsigned NumElems = 0;
9139 NumElems = VT->getNumElements();
9140 ElemType = VT->getElementType();
9142 NumElems = MT->getNumElementsFlattened();
9143 ElemType = MT->getElementType();
9146 PrimType DestElemT = classifyPrim(ElemType);
9147 for (
unsigned I = 0; I != NumElems; ++I) {
9148 if (!loadAndCast(DestElemT, ElemType))
9150 if (!this->emitInitElem(DestElemT, I, E))
9160 QualType ArrElemType = CAT->getElementType();
9161 unsigned ArrSize = CAT->getZExtSize();
9164 for (
unsigned I = 0; I != ArrSize; ++I) {
9165 if (!loadAndCast(*ElemT, ArrElemType))
9167 if (!this->emitInitElem(*ElemT, I, E))
9171 for (
unsigned I = 0; I != ArrSize; ++I) {
9172 if (!this->emitConstUint32(I, E))
9174 if (!this->emitArrayElemPtrUint32(E))
9176 if (!emitHLSLConstructAggregate(ArrElemType, Elements, ElemIdx, E))
9178 if (!this->emitFinishInitPop(E))
9188 const Record *
R = getRecord(DestType);
9192 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
9194 const Record::Base *B =
R->getBase(BS.getType());
9196 if (!this->emitGetPtrBase(B->Offset, E))
9198 if (!emitHLSLConstructAggregate(BS.getType(), Elements, ElemIdx, E))
9200 if (!this->emitFinishInitPop(E))
9205 for (
const Record::Field &F :
R->fields()) {
9206 if (F.isUnnamedBitField())
9209 QualType FieldType = F.Decl->getType();
9211 if (!loadAndCast(*FieldT, FieldType))
9213 if (F.isBitField()) {
9214 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
9217 if (!this->emitInitField(*FieldT, F.Offset, E))
9221 if (!this->emitGetPtrField(F.Offset, E))
9223 if (!emitHLSLConstructAggregate(FieldType, Elements, ElemIdx, E))
9225 if (!this->emitPopPtr(E))
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static void emitCleanup(CIRGenFunction &cgf, cir::CleanupScopeOp cleanupScope, EHScopeStack::Cleanup *cleanup, EHScopeStack::Cleanup::Flags flags, Address activeFlag)
static uint32_t getBitWidth(const Expr *E)
#define EMIT_ARITH_OP(OP)
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
static const Expr * stripDerivedToBaseCasts(const Expr *E)
static const Expr * stripCheckedDerivedToBaseCasts(const Expr *E)
static bool hasTrivialDefaultCtorParent(const FieldDecl *FD)
static bool initNeedsOverridenLoc(const CXXCtorInitializer *Init)
Result
Implement __builtin_bit_cast and related operations.
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.
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, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
Expr * getResultExpr()
Return the result expression of this controlling expression.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
bool isNegatedConsteval() const
DeclStmt * getConditionVariableDeclStmt()
If this IfStmt has a condition variable, return the faux DeclStmt associated with the creation of tha...
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
Describes an C or C++ initializer list.
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
ArrayRef< Expr * > inits() const
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
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
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, ArrayRef< SourceLocation > Locs)
This is the "fully general" constructor that allows representation of strings formed from one or more...
uint32_t getCodeUnit(size_t i) const
unsigned getCharByteWidth() const
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Expr * getReplacement() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
DeclStmt * getConditionVariableDeclStmt()
If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
The base class of the type hierarchy.
bool isBooleanType() const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isConstantMatrixType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isAtomicType() const
EnumDecl * castAsEnumDecl() const
bool isStdByteType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isPointerOrReferenceType() const
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represents C++ using-directive.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
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)
UnsignedOrNone allocateLocal(DeclOrExpr &&Decl, QualType Ty=QualType(), ScopeKind=ScopeKind::Block)
Allocates a space storing a local given its type.
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)
unsigned allocateLocalPrimitive(DeclOrExpr &&Decl, PrimType Ty, bool IsConst, bool IsVolatile=false, ScopeKind SC=ScopeKind::Block)
Creates a local primitive value.
bool VisitComplexBinOp(const BinaryOperator *E)
llvm::DenseMap< const ValueDecl *, Scope::Local > Locals
Variable to storage mapping.
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
bool VisitCXXTypeidExpr(const CXXTypeidExpr *E)
UnsignedOrNone allocateTemporary(const Expr *E)
bool VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinID)
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
OptPrimType ReturnType
Type of the expression returned by the function.
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
OptPrimType classify(const Expr *E) const
llvm::SmallVector< LabelInfo > LabelInfoStack
Stack of label information for loops and switch statements.
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
bool visitDoStmt(const DoStmt *S)
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitInitListExpr(const InitListExpr *E)
bool VisitVectorBinOp(const BinaryOperator *E)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
bool DiscardResult
Flag indicating if return value is to be discarded.
bool VisitEmbedExpr(const EmbedExpr *E)
bool VisitConvertVectorExpr(const ConvertVectorExpr *E)
bool VisitCXXThisExpr(const CXXThisExpr *E)
bool VisitConstantExpr(const ConstantExpr *E)
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool visitSwitchStmt(const SwitchStmt *S)
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E)
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool visitAsLValue(const Expr *E)
bool visitWhileStmt(const WhileStmt *S)
bool visitIfStmt(const IfStmt *IS)
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
bool canClassify(const Expr *E) const
bool VisitFloatingLiteral(const FloatingLiteral *E)
Program & P
Program to link to.
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
bool VariablesAreConstexprUnknown
bool VisitGNUNullExpr(const GNUNullExpr *E)
bool VisitImaginaryLiteral(const ImaginaryLiteral *E)
bool VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E)
bool visitCXXTryStmt(const CXXTryStmt *S)
static bool isUnevaluatedBuiltin(unsigned ID)
Unevaluated builtins don't get their arguments put on the stack automatically.
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Scope used to handle temporaries in toplevel variable declarations.
DeclScope(Compiler< Emitter > *Ctx, const 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 * getVirtualBase(unsigned I) const
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)
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
@ 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
EvalResult is a struct with detailed info about an evaluated expression.
Describes a memory block created by an allocation site.
unsigned getNumElems() const
Returns the number of elements stored in the block.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
QualType getElemQualType() const
bool hasTrivialDtor() const
Whether variables of this descriptor need their destructor called or not.
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
const Descriptor *const ElemDesc
Descriptor of the array element.
static constexpr MetadataSize InlineDescMD
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
PrimType getPrimType() const
bool isRecord() const
Checks if the descriptor is of a record.
const Record *const ElemRecord
Pointer to the record, if block contains records.
bool isArray() const
Checks if the descriptor is of an array.
Descriptor used for global variables.
GlobalInitState InitState
static InitLink InitList()
static InitLink Elem(unsigned Index)
bool emit(Compiler< Emitter > *Ctx, const Expr *E) const
static InitLink Field(unsigned Offset)
static InitLink 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()