21#include "llvm/Support/SaveAndRestore.h"
32 if (
const auto *CE = dyn_cast_if_present<ConstantExpr>(E);
33 CE && CE->hasAPValueResult() &&
35 return CE->getResultAsAPSInt().getBoolValue();
57 if (NumElems > std::numeric_limits<unsigned>::max())
59 uint64_t Limit = LangOpts.ConstexprStepLimit;
60 return Limit != 0 && NumElems > Limit;
76 llvm_unreachable(
"Shouldn't be called");
141 this->
Ctx->emitDestroy(*
Idx, E);
148 Idx =
static_cast<unsigned>(this->
Ctx->Descriptors.size());
149 this->
Ctx->Descriptors.emplace_back();
163 if (
Local.Desc->hasTrivialDtor())
166 if (!
Local.EnabledByDefault) {
167 typename Emitter::LabelTy EndLabel = this->
Ctx->getLabel();
168 if (!this->
Ctx->emitGetLocalEnabled(
Local.Offset, E))
170 if (!this->
Ctx->jumpFalse(EndLabel, E))
173 if (!this->
Ctx->emitGetPtrLocal(
Local.Offset, E))
176 if (!this->
Ctx->emitDestructionPop(
Local.Desc,
Local.Desc->getLoc()))
179 this->
Ctx->fallthrough(EndLabel);
180 this->
Ctx->emitLabel(EndLabel);
182 if (!this->
Ctx->emitGetPtrLocal(
Local.Offset, E))
184 if (!this->
Ctx->emitDestructionPop(
Local.Desc,
Local.Desc->getLoc()))
203 if (
const auto *OVE =
204 llvm::dyn_cast_if_present<OpaqueValueExpr>(
Local.Desc->asExpr())) {
205 this->
Ctx->OpaqueExprs.erase(OVE);
217 OldArrayIndex = Ctx->ArrayIndex;
218 Ctx->ArrayIndex = Index;
225 std::optional<uint64_t> OldArrayIndex;
233 if (!Ctx->SourceLocDefaultExpr) {
235 Ctx->SourceLocDefaultExpr = DefaultExpr;
241 Ctx->SourceLocDefaultExpr =
nullptr;
246 bool Enabled =
false;
252 Ctx->InitStack.push_back(std::move(
Link));
264 : Ctx(Ctx), OldValue(Ctx->InitStackActive), Active(Active) {
267 Ctx->InitStackActive = OldValue || Active;
273 this->Ctx->InitStackActive = OldValue;
275 Ctx->InitStack.pop_back();
289 OldInitializingDecl(
Ctx->InitializingDecl) {
290 Ctx->InitializingDecl = VD;
295 this->
Ctx->InitializingDecl = OldInitializingDecl;
296 this->
Ctx->InitStack.pop_back();
301 const VarDecl *OldInitializingDecl;
309 bool NewInitializing,
bool NewToLValue)
310 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
311 OldInitializing(Ctx->
Initializing), OldToLValue(Ctx->ToLValue) {
312 Ctx->DiscardResult = NewDiscardResult;
313 Ctx->Initializing = NewInitializing;
314 Ctx->ToLValue = NewToLValue;
318 Ctx->DiscardResult = OldDiscardResult;
319 Ctx->Initializing = OldInitializing;
320 Ctx->ToLValue = OldToLValue;
327 bool OldDiscardResult;
328 bool OldInitializing;
332template <
class Emitter>
336 return Ctx->emitThis(E);
339 return Ctx->emitGetPtrFieldPop(
Offset, E);
341 return Ctx->emitGetPtrBasePop(
Offset,
false, E);
343 return Ctx->emitGetPtrLocal(
Offset, E);
347 if (!Ctx->emitConstUint32(
Offset, E))
349 return Ctx->emitArrayElemPtrPopUint32(E);
351 return Ctx->emitRVOPtr(E);
355 llvm_unreachable(
"Unhandled InitLink kind");
371 for (
const LabelInfo &LI : Ctx->LabelInfoStack)
372 assert(LI.Name != Name);
375 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel, ContinueLabel,
396 : Ctx(Ctx), OldCaseLabels(
std::move(this->Ctx->CaseLabels)) {
398 for (
const LabelInfo &LI : Ctx->LabelInfoStack)
399 assert(LI.Name != Name);
402 this->Ctx->CaseLabels = std::move(CaseLabels);
403 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel,
405 DefaultLabel, Ctx->VarScope);
409 this->Ctx->CaseLabels = std::move(OldCaseLabels);
410 this->Ctx->LabelInfoStack.pop_back();
415 CaseMap OldCaseLabels;
426 : Ctx(Ctx), OldFlag(Ctx->LocOverride), Enabled(Enabled) {
429 Ctx->LocOverride = NewValue;
434 Ctx->LocOverride = OldFlag;
439 std::optional<SourceInfo> OldFlag;
446template <
class Emitter>
454 case CK_LValueToRValue: {
462 if (!this->
visit(SubExpr))
464 return this->emitLoadPopL(E);
474 if (
const auto *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
480 if (
auto GlobalIndex =
P.getGlobal(D))
481 return this->emitGetGlobal(*SubExprT, *GlobalIndex, E);
482 }
else if (
auto It =
Locals.find(D); It !=
Locals.end()) {
483 return this->emitGetLocal(*SubExprT, It->second.Offset, E);
484 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
485 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
486 return this->emitGetParam(*SubExprT, It->second.Index, E);
498 if (!this->emitGetPtrLocal(*LocalIndex, E))
502 if (!this->
visit(SubExpr))
506 return this->emitLoadPop(*SubExprT, E);
511 return this->emitMemcpy(E);
514 case CK_DerivedToBaseMemberPointer: {
525 ->getMostRecentCXXRecordDecl();
527 const CXXRecordDecl *ToDecl = B->getType()->castAsCXXRecordDecl();
528 unsigned DerivedOffset =
Ctx.collectBaseOffset(ToDecl, CurDecl);
530 if (!this->emitCastMemberPtrBasePop(DerivedOffset, ToDecl, E))
538 case CK_BaseToDerivedMemberPointer: {
549 ->getMostRecentCXXRecordDecl();
553 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
555 PathI != PathE; ++PathI) {
556 const CXXRecordDecl *ToDecl = (*PathI)->getType()->castAsCXXRecordDecl();
557 unsigned DerivedOffset =
Ctx.collectBaseOffset(CurDecl, ToDecl);
559 if (!this->emitCastMemberPtrDerivedPop(-DerivedOffset, ToDecl, E))
566 assert(ToDecl != CurDecl);
567 unsigned DerivedOffset =
Ctx.collectBaseOffset(CurDecl, ToDecl);
569 if (!this->emitCastMemberPtrDerivedPop(-DerivedOffset, ToDecl, E))
575 case CK_UncheckedDerivedToBase:
576 case CK_DerivedToBase: {
581 if (
const auto *PT = dyn_cast<PointerType>(Ty))
582 return PT->getPointeeType()->castAsCXXRecordDecl();
583 return Ty->castAsCXXRecordDecl();
590 if (B->isVirtual()) {
591 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), E))
593 CurType = B->getType();
595 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
596 if (!this->emitGetPtrBasePop(
599 CurType = B->getType();
606 case CK_BaseToDerived: {
610 auto unwrapPointerType = [](
const Type *
T) ->
const Type * {
611 if (
T->isPointerOrReferenceType())
612 return T->getPointeeType().getTypePtr();
624 llvm::drop_begin(llvm::reverse(E->
path()))) {
625 const Type *TargetType = unwrapPointerType(B->getType().getTypePtr());
626 if (!this->emitGetPtrDerivedPop(NullOK, TargetType, FinalType, E))
630 return this->emitGetPtrDerivedPop(NullOK, FinalType, FinalType, E);
633 case CK_FloatingCast: {
636 return this->emitVectorConversion(E->
getSubExpr(), E);
640 if (!this->
visit(SubExpr))
642 const auto *TargetSemantics = &
Ctx.getFloatSemantics(E->
getType());
646 case CK_IntegralToFloating: {
648 return this->emitVectorConversion(E->
getSubExpr(), E);
651 if (!this->
visit(SubExpr))
653 const auto *TargetSemantics = &
Ctx.getFloatSemantics(E->
getType());
654 return this->emitCastIntegralFloating(
classifyPrim(SubExpr),
655 TargetSemantics, getFPOptions(E), E);
658 case CK_FloatingToBoolean: {
660 return this->emitVectorConversion(E->
getSubExpr(), E);
664 if (
const auto *FL = dyn_cast<FloatingLiteral>(SubExpr))
665 return this->emitConstBool(FL->getValue().isNonZero(), E);
666 if (!this->
visit(SubExpr))
668 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
671 case CK_FloatingToIntegral: {
673 return this->emitVectorConversion(E->
getSubExpr(), E);
676 if (!this->
visit(SubExpr))
680 return this->emitCastFloatingIntegralAP(
Ctx.getBitWidth(E->
getType()),
683 return this->emitCastFloatingIntegralAPS(
Ctx.getBitWidth(E->
getType()),
686 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
689 case CK_NullToPointer:
690 case CK_NullToMemberPointer: {
693 uint64_t Val =
Ctx.getASTContext().getTargetNullPointerValue(E->
getType());
698 case CK_PointerToIntegral: {
699 if (!this->
visit(SubExpr))
705 if (!this->emitDecayPtr(FromT,
PT_Ptr, E))
711 return this->emitCastPointerIntegralAP(
Ctx.getBitWidth(E->
getType()), E);
713 return this->emitCastPointerIntegralAPS(
Ctx.getBitWidth(E->
getType()), E);
714 return this->emitCastPointerIntegral(
T, E);
717 case CK_ArrayToPointerDecay: {
718 if (!this->
visit(SubExpr))
720 return this->emitArrayDecay(E);
723 case CK_IntegralToPointer: {
725 assert(IntType->isIntegralOrEnumerationType());
726 if (!this->
visit(SubExpr))
740 return this->emitDecayPtr(
PT_Ptr, DestPtrT, E);
743 case CK_AtomicToNonAtomic:
744 case CK_ConstructorConversion:
745 case CK_FunctionToPointerDecay:
746 case CK_NonAtomicToAtomic:
748 case CK_UserDefinedConversion:
749 case CK_CPointerToObjCPointerCast:
752 case CK_AddressSpaceConversion: {
756 if (!this->
visit(SubExpr))
761 Val =
Ctx.getASTContext().getTargetNullPointerValue(E->
getType());
768 return this->emitPopPtr(E);
786 return this->emitBuiltinBitCast(E);
801 if (!this->
visit(SubExpr))
809 return this->emitFnPtrCast(E);
817 if (!this->
visit(SubExpr))
819 return this->emitDecayPtr(*FromT, *ToT, E);
821 case CK_IntegralToBoolean:
822 case CK_FixedPointToBoolean: {
824 return this->emitVectorConversion(E->
getSubExpr(), E);
830 if (
const auto *IL = dyn_cast<IntegerLiteral>(SubExpr))
831 return this->emitConst(IL->getValue(), E);
832 if (!this->
visit(SubExpr))
837 case CK_IntegralCast:
839 return this->emitVectorConversion(E->
getSubExpr(), E);
841 case CK_BooleanToSignedIntegral: {
848 if (
const auto *IL = dyn_cast<IntegerLiteral>(SubExpr)) {
853 if (!this->emitConst(IL->getValue(), SubExpr))
856 if (!this->
visit(SubExpr))
864 if (!ED->isFixed()) {
865 if (!this->emitCheckEnumValue(*FromT, ED, E))
871 if (!this->emitCastAP(*FromT,
Ctx.getBitWidth(E->
getType()), E))
874 if (!this->emitCastAPS(*FromT,
Ctx.getBitWidth(E->
getType()), E))
879 if (!this->emitCast(*FromT, *ToT, E))
882 if (E->
getCastKind() == CK_BooleanToSignedIntegral)
883 return this->emitNeg(*ToT, E);
887 case CK_PointerToBoolean:
888 if (!this->
visit(SubExpr))
890 return this->emitIsNonNullPtr(E);
892 case CK_MemberPointerToBoolean:
893 if (!this->
visit(SubExpr))
895 return this->emitIsNonNullMemberPtr(E);
897 case CK_IntegralComplexToBoolean:
898 case CK_FloatingComplexToBoolean: {
899 if (!this->
visit(SubExpr))
901 return this->emitComplexBoolCast(SubExpr);
904 case CK_IntegralComplexToReal:
905 case CK_FloatingComplexToReal:
906 return this->emitComplexReal(SubExpr);
908 case CK_IntegralRealToComplex:
909 case CK_FloatingRealToComplex: {
916 if (!this->emitGetPtrLocal(*LocalIndex, E))
925 if (!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
927 return this->emitInitElem(
T, 1, SubExpr);
930 case CK_IntegralComplexCast:
931 case CK_FloatingComplexCast:
932 case CK_IntegralComplexToFloatingComplex:
933 case CK_FloatingComplexToIntegralComplex: {
940 if (!this->emitGetPtrLocal(*LocalIndex, E))
947 unsigned SubExprOffset =
949 if (!this->
visit(SubExpr))
951 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, E))
959 for (
unsigned I = 0; I != 2; ++I) {
960 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, E))
962 if (!this->emitArrayElemPop(SourceElemT, I, E))
966 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, E))
970 if (!this->emitInitElem(DestElemT, I, E))
976 case CK_VectorSplat: {
987 if (!this->emitGetPtrLocal(*LocalIndex, E))
993 unsigned ElemOffset =
997 if (!this->
visit(SubExpr))
1002 if (!this->emitSetLocal(ElemT, ElemOffset, E))
1005 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
1006 if (!this->emitGetLocal(ElemT, ElemOffset, E))
1008 if (!this->emitInitElem(ElemT, I, E))
1015 case CK_HLSLVectorTruncation: {
1020 if (!this->
visit(SubExpr))
1022 return this->emitArrayElemPop(*ResultT, 0, E);
1031 if (!this->emitGetPtrLocal(*LocalIndex, E))
1036 if (!this->
visit(SubExpr))
1038 return this->emitCopyArray(classifyVectorElementType(E->
getType()), 0, 0,
1042 case CK_IntegralToFixedPoint: {
1043 if (!this->
visit(SubExpr))
1047 Ctx.getASTContext().getFixedPointSemantics(E->
getType()).toOpaqueInt();
1052 return this->emitPopFixedPoint(E);
1055 case CK_FloatingToFixedPoint: {
1056 if (!this->
visit(SubExpr))
1060 Ctx.getASTContext().getFixedPointSemantics(E->
getType()).toOpaqueInt();
1061 if (!this->emitCastFloatingFixedPoint(Sem, E))
1064 return this->emitPopFixedPoint(E);
1067 case CK_FixedPointToFloating: {
1068 if (!this->
visit(SubExpr))
1070 const auto *TargetSemantics = &
Ctx.getFloatSemantics(E->
getType());
1071 if (!this->emitCastFixedPointFloating(TargetSemantics, E))
1074 return this->emitPopFloat(E);
1077 case CK_FixedPointToIntegral: {
1078 if (!this->
visit(SubExpr))
1081 if (!this->emitCastFixedPointIntegral(IntegralT, E))
1084 return this->emitPop(IntegralT, E);
1087 case CK_FixedPointCast: {
1088 if (!this->
visit(SubExpr))
1091 Ctx.getASTContext().getFixedPointSemantics(E->
getType()).toOpaqueInt();
1092 if (!this->emitCastFixedPoint(Sem, E))
1095 return this->emitPopFixedPoint(E);
1103 llvm_unreachable(
"CXXDynamicCastExpr has its own function");
1105 case CK_LValueBitCast:
1110 case CK_HLSLArrayRValue: {
1117 if (!this->emitGetPtrLocal(*LocalIndex, E))
1120 if (!this->
visit(SubExpr))
1122 return this->emitMemcpy(E);
1125 case CK_HLSLMatrixTruncation: {
1130 if (!this->
visit(SubExpr))
1132 return this->emitArrayElemPop(*ResultT, 0, E);
1141 if (!this->emitGetPtrLocal(*LocalIndex, E))
1146 if (!this->
visit(SubExpr))
1148 return this->emitCopyArray(classifyMatrixElementType(SubExpr->
getType()), 0,
1152 case CK_HLSLAggregateSplatCast: {
1162 if (!this->emitGetPtrLocal(*LocalIndex, E))
1169 unsigned SrcOffset =
1172 if (!this->
visit(SubExpr))
1174 if (!this->emitSetLocal(SrcElemT, SrcOffset, E))
1178 return emitHLSLAggregateSplat(SrcElemT, SrcOffset, E->
getType(), E);
1181 case CK_HLSLElementwiseCast: {
1192 unsigned SrcPtrOffset =
1194 if (!this->
visit(SubExpr))
1196 if (!this->emitSetLocal(
PT_Ptr, SrcPtrOffset, E))
1200 if (!emitHLSLFlattenAggregate(SrcType, SrcPtrOffset, Elements, 1, E))
1202 if (Elements.empty())
1205 const HLSLFlatElement &Src = Elements[0];
1206 if (!this->emitGetLocal(Src.Type, Src.LocalOffset, E))
1208 return this->emitPrimCast(Src.Type, *DestT, DestType, E);
1215 if (!this->emitGetPtrLocal(*LocalIndex, E))
1219 unsigned SrcOffset =
1221 if (!this->
visit(SubExpr))
1223 if (!this->emitSetLocal(
PT_Ptr, SrcOffset, E))
1227 unsigned ElemCount = countHLSLFlatElements(DestType);
1230 Elements.reserve(ElemCount);
1231 if (!emitHLSLFlattenAggregate(SrcType, SrcOffset, Elements, ElemCount, E))
1236 assert(Elements.size() == ElemCount &&
1237 "Source type has fewer scalar elements than the destination type");
1239 return emitHLSLConstructAggregate(DestType, Elements, E);
1246 const Record::Field *RF = R->getField(UnionField);
1249 if (!this->
visit(SubExpr))
1251 if (RF->isBitField())
1252 return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(),
1254 return this->emitInitFieldActivate(*PT, RF->Offset, E);
1257 if (!this->emitGetPtrField(RF->Offset, E))
1259 if (!this->emitActivate(E))
1265 return this->emitInvalid(E);
1267 llvm_unreachable(
"Unhandled clang::CastKind enum");
1270template <
class Emitter>
1272 return this->emitBuiltinBitCast(E);
1275template <
class Emitter>
1280 return this->emitConst(
LE->getValue(),
LE);
1283template <
class Emitter>
1289 return this->emitFloat(F, E);
1292template <
class Emitter>
1302 if (!this->emitGetPtrLocal(*LocalIndex, E))
1309 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
1311 if (!this->emitInitElem(SubExprT, 0, SubExpr))
1315 return this->emitFinishInit(E);
1318template <
class Emitter>
1326 auto Sem =
Ctx.getASTContext().getFixedPointSemantics(E->
getType());
1331template <
class Emitter>
1336template <
class Emitter>
1363 return this->emitComplexComparison(LHS, RHS, E);
1371 if (!this->
visit(LHS))
1374 if (!this->
visit(RHS))
1377 if (!this->emitToMemberPtr(E))
1383 if (!this->emitCastMemberPtrPtr(E))
1400 Ctx.getASTContext().CompCategories.lookupInfoForType(E->
getType());
1406 if (!this->emitGetPtrLocal(*ResultIndex, E))
1413 return this->emitCMP3(*
LT, CmpInfo, E);
1416 if (!
LT || !RT || !
T)
1426 return this->visitAssignment(LHS, RHS, E);
1433 auto MaybeCastToBool = [
this,
T, E](
bool Result) {
1437 return this->emitPopBool(E);
1439 return this->emitCast(
PT_Bool, *
T, E);
1443 auto Discard = [
this,
T, E](
bool Result) {
1451 return MaybeCastToBool(this->emitEQ(*
LT, E));
1453 return MaybeCastToBool(this->emitNE(*
LT, E));
1455 return MaybeCastToBool(this->emitLT(*
LT, E));
1457 return MaybeCastToBool(this->emitLE(*
LT, E));
1459 return MaybeCastToBool(this->emitGT(*
LT, E));
1461 return MaybeCastToBool(this->emitGE(*
LT, E));
1464 return Discard(this->emitSubf(getFPOptions(E), E));
1465 return Discard(this->emitSub(*
T, E));
1468 return Discard(this->emitAddf(getFPOptions(E), E));
1469 return Discard(this->emitAdd(*
T, E));
1472 return Discard(this->emitMulf(getFPOptions(E), E));
1473 return Discard(this->emitMul(*
T, E));
1475 return Discard(this->emitRem(*
T, E));
1478 return Discard(this->emitDivf(getFPOptions(E), E));
1479 return Discard(this->emitDiv(*
T, E));
1481 return Discard(this->emitBitAnd(*
T, E));
1483 return Discard(this->emitBitOr(*
T, E));
1485 return Discard(this->emitShl(*
LT, *RT, E));
1487 return Discard(this->emitShr(*
LT, *RT, E));
1489 return Discard(this->emitBitXor(*
T, E));
1492 llvm_unreachable(
"Already handled earlier");
1497 llvm_unreachable(
"Unhandled binary op");
1502template <
class Emitter>
1508 if ((Op != BO_Add && Op != BO_Sub) ||
1519 auto visitAsPointer = [&](
const Expr *E,
PrimType T) ->
bool {
1520 if (!this->
visit(E))
1523 return this->emitDecayPtr(
T,
PT_Ptr, E);
1532 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *
LT))
1540 ElemTypeSize =
Ctx.getASTContext().getTypeSizeInChars(ElemType);
1543 if (!this->emitSubPtr(IntT, ElemTypeSize.
getQuantity(), E))
1550 if (!visitAsPointer(RHS, *RT))
1552 if (!this->
visit(LHS))
1556 if (!visitAsPointer(LHS, *
LT))
1558 if (!this->
visit(RHS))
1569 if (!this->emitAddOffset(OffsetType, E))
1573 if (!this->emitSubOffset(OffsetType, E))
1582 if (!this->emitDecayPtr(
PT_Ptr, ExprT, E))
1587 return this->emitPop(ExprT, E);
1591template <
class Emitter>
1600 LabelTy LabelTrue = this->getLabel();
1601 LabelTy LabelEnd = this->getLabel();
1605 if (!this->jumpTrue(LabelTrue, E))
1610 if (!this->jump(LabelEnd, E))
1613 this->emitLabel(LabelTrue);
1614 this->emitConstBool(
true, E);
1615 this->fallthrough(LabelEnd);
1616 this->emitLabel(LabelEnd);
1619 assert(Op == BO_LAnd);
1622 LabelTy LabelFalse = this->getLabel();
1623 LabelTy LabelEnd = this->getLabel();
1627 if (!this->jumpFalse(LabelFalse, E))
1632 if (!this->jump(LabelEnd, E))
1635 this->emitLabel(LabelFalse);
1636 this->emitConstBool(
false, E);
1637 this->fallthrough(LabelEnd);
1638 this->emitLabel(LabelEnd);
1642 return this->emitPopBool(E);
1647 return this->emitCast(
PT_Bool,
T, E);
1652template <
class Emitter>
1659 if (!this->emitGetPtrLocal(*LocalIndex, E))
1668 PrimType ResultElemT = this->classifyComplexElementType(E->
getType());
1669 unsigned ResultOffset = ~0u;
1675 if (!this->emitDupPtr(E))
1677 if (!this->emitSetLocal(
PT_Ptr, ResultOffset, E))
1682 LHSType = AT->getValueType();
1685 RHSType = AT->getValueType();
1694 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1699 if (!this->
visit(LHS))
1701 if (!this->
visit(RHS))
1703 if (!this->emitMulc(ElemT, E))
1706 return this->emitPopPtr(E);
1710 if (Op == BO_Div && RHSIsComplex) {
1717 if (!LHSIsComplex) {
1722 LHSOffset = *LocalIndex;
1724 if (!this->emitGetPtrLocal(LHSOffset, E))
1727 if (!this->
visit(LHS))
1730 if (!this->emitInitElem(ElemT, 0, E))
1733 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1735 if (!this->emitInitElem(ElemT, 1, E))
1738 if (!this->
visit(LHS))
1742 if (!this->
visit(RHS))
1744 if (!this->emitDivc(ElemT, E))
1747 return this->emitPopPtr(E);
1754 if (!this->
visit(LHS))
1756 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
1761 if (!this->
visit(LHS))
1763 if (!this->emitSetLocal(LHST, LHSOffset, E))
1771 if (!this->
visit(RHS))
1773 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
1778 if (!this->
visit(RHS))
1780 if (!this->emitSetLocal(RHST, RHSOffset, E))
1787 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1788 unsigned ElemIndex,
unsigned Offset,
1789 const Expr *E) ->
bool {
1791 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
1793 return this->emitArrayElemPop(classifyComplexElementType(E->
getType()),
1796 if (ElemIndex == 0 || !LoadZero)
1803 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1806 if (!this->emitGetLocal(
PT_Ptr, ResultOffset, E))
1813 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1816 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1819 if (!this->emitAddf(getFPOptions(E), E))
1822 if (!this->emitAdd(ResultElemT, E))
1827 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1830 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1833 if (!this->emitSubf(getFPOptions(E), E))
1836 if (!this->emitSub(ResultElemT, E))
1841 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1844 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1848 if (!this->emitMulf(getFPOptions(E), E))
1851 if (!this->emitMul(ResultElemT, E))
1856 assert(!RHSIsComplex);
1857 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1860 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1864 if (!this->emitDivf(getFPOptions(E), E))
1867 if (!this->emitDiv(ResultElemT, E))
1878 if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))
1881 if (!this->emitPop(ResultElemT, E))
1886 return this->emitPopPtr(E);
1889 return this->emitFinishInit(E);
1892template <
class Emitter>
1897 "Comma op should be handled in VisitBinaryOperator");
1901 LHSType = AT->getValueType();
1904 RHSType = AT->getValueType();
1918 if (!this->emitGetPtrLocal(*LocalIndex, E))
1927 PrimType ElemT = this->classifyVectorElementType(LHSType);
1928 PrimType RHSElemT = this->classifyVectorElementType(RHSType);
1932 assert(
Ctx.getASTContext().hasSameUnqualifiedType(
1935 if (!this->
visit(LHS))
1937 if (!this->
visit(RHS))
1939 if (!this->emitCopyArray(ElemT, 0, 0, VecTy->getNumElements(), E))
1942 return this->emitPopPtr(E);
1947 unsigned LHSOffset =
1949 if (!this->
visit(LHS))
1951 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
1955 unsigned RHSOffset =
1957 if (!this->
visit(RHS))
1959 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
1971 if (NeedIntPromot) {
1973 Ctx.getASTContext().getPromotedIntegerType(
Ctx.getASTContext().BoolTy);
1978 auto getElem = [=](
unsigned Offset,
PrimType ElemT,
unsigned Index) {
1979 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
1981 if (!this->emitArrayElemPop(ElemT, Index, E))
1984 if (!this->emitPrimCast(ElemT,
PT_Bool,
Ctx.getASTContext().BoolTy, E))
1986 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(), E))
1988 }
else if (NeedIntPromot) {
1989 if (!this->emitPrimCast(ElemT, PromotT, PromotTy, E))
1995#define EMIT_ARITH_OP(OP) \
1997 if (ElemT == PT_Float) { \
1998 if (!this->emit##OP##f(getFPOptions(E), E)) \
2001 if (!this->emit##OP(ElemT, E)) \
2007 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
2008 if (!getElem(LHSOffset, ElemT, I))
2010 if (!getElem(RHSOffset, RHSElemT, I))
2022 if (!this->emitRem(ElemT, E))
2026 if (!this->emitBitAnd(OpT, E))
2030 if (!this->emitBitOr(OpT, E))
2034 if (!this->emitBitXor(OpT, E))
2038 if (!this->emitShl(OpT, RHSElemT, E))
2042 if (!this->emitShr(OpT, RHSElemT, E))
2046 if (!this->emitEQ(ElemT, E))
2050 if (!this->emitNE(ElemT, E))
2054 if (!this->emitLE(ElemT, E))
2058 if (!this->emitLT(ElemT, E))
2062 if (!this->emitGE(ElemT, E))
2066 if (!this->emitGT(ElemT, E))
2071 if (!this->emitBitAnd(ResultElemT, E))
2076 if (!this->emitBitOr(ResultElemT, E))
2080 return this->emitInvalid(E);
2089 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(), E))
2091 if (!this->emitNeg(ResultElemT, E))
2097 if (NeedIntPromot &&
2098 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(), E))
2102 if (!this->emitInitElem(ResultElemT, I, E))
2111template <
class Emitter>
2121 auto LHSSemaInt = LHSSema.toOpaqueInt();
2123 auto RHSSemaInt = RHSSema.toOpaqueInt();
2125 if (!this->
visit(LHS))
2133 if (!this->
visit(RHS))
2142 auto ConvertResult = [&](
bool R) ->
bool {
2146 auto CommonSema = LHSSema.getCommonSemantics(RHSSema).toOpaqueInt();
2147 if (ResultSema != CommonSema)
2148 return this->emitCastFixedPoint(ResultSema, E);
2152 auto MaybeCastToBool = [&](
bool Result) {
2157 return this->emitPop(
T, E);
2159 return this->emitCast(
PT_Bool,
T, E);
2165 return MaybeCastToBool(this->emitEQFixedPoint(E));
2167 return MaybeCastToBool(this->emitNEFixedPoint(E));
2169 return MaybeCastToBool(this->emitLTFixedPoint(E));
2171 return MaybeCastToBool(this->emitLEFixedPoint(E));
2173 return MaybeCastToBool(this->emitGTFixedPoint(E));
2175 return MaybeCastToBool(this->emitGEFixedPoint(E));
2177 return ConvertResult(this->emitAddFixedPoint(E));
2179 return ConvertResult(this->emitSubFixedPoint(E));
2181 return ConvertResult(this->emitMulFixedPoint(E));
2183 return ConvertResult(this->emitDivFixedPoint(E));
2185 return ConvertResult(this->emitShiftFixedPoint(
true, E));
2187 return ConvertResult(this->emitShiftFixedPoint(
false, E));
2190 return this->emitInvalid(E);
2193 llvm_unreachable(
"unhandled binop opcode");
2196template <
class Emitter>
2205 if (!this->
visit(SubExpr))
2207 if (!this->emitNegFixedPoint(E))
2210 return this->emitPopFixedPoint(E);
2216 llvm_unreachable(
"Unhandled unary opcode");
2219template <
class Emitter>
2228 return this->visitZeroInitializer(*
T, QT, E);
2241 return this->visitZeroRecordInitializer(R, E);
2248 return this->visitZeroArrayInitializer(QT, E);
2252 QualType ElemQT = ComplexTy->getElementType();
2254 for (
unsigned I = 0; I < 2; ++I) {
2255 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2257 if (!this->emitInitElem(ElemT, I, E))
2264 unsigned NumVecElements = VecT->getNumElements();
2265 QualType ElemQT = VecT->getElementType();
2268 for (
unsigned I = 0; I < NumVecElements; ++I) {
2269 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2271 if (!this->emitInitElem(ElemT, I, E))
2278 unsigned NumElems = MT->getNumElementsFlattened();
2279 QualType ElemQT = MT->getElementType();
2282 for (
unsigned I = 0; I != NumElems; ++I) {
2283 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2285 if (!this->emitInitElem(ElemT, I, E))
2294template <
class Emitter>
2307 for (
const Expr *SubExpr : {LHS, RHS}) {
2308 if (!this->
visit(SubExpr)) {
2315 if (SubExpr ==
Base &&
Base->getType()->isPointerType()) {
2316 if (!this->emitExpandPtr(E))
2327 return this->emitError(E);
2330 if (!this->emitFlip(
PT_Ptr, *IndexT, E))
2334 if (!this->emitArrayElemPtrPop(*IndexT, E))
2337 return this->emitPopPtr(E);
2343 return this->emitLoadPop(*
T, E);
2346template <
class Emitter>
2348 const Expr *ArrayFiller,
const Expr *E) {
2353 QT = AT->getValueType();
2356 if (
Inits.size() == 0)
2358 return this->emitInvalid(E);
2371 if (
Inits.size() == 0)
2372 return this->visitZeroInitializer(*
T, QT, E);
2373 assert(
Inits.size() == 1);
2387 if (!this->emitGetPtrLocal(*LocalIndex, E))
2402 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
2408 if (
DefaultInit && !this->emitStartFieldInit(FieldToInit->Offset,
Init))
2417 bool BitField = FieldToInit->isBitField();
2419 return this->emitInitBitFieldActivate(
T, FieldToInit->Offset,
2420 FieldToInit->bitWidth(), E);
2422 return this->emitInitBitField(
T, FieldToInit->Offset,
2423 FieldToInit->bitWidth(), E);
2425 return this->emitInitFieldActivate(
T, FieldToInit->Offset, E);
2426 return this->emitInitField(
T, FieldToInit->Offset, E);
2429 auto initCompositeField = [=](
const Record::Field *FieldToInit,
2437 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
2440 if (
Activate && !this->emitActivate(E))
2443 if (!this->emitStartInit(
Init))
2450 if (
Inits.size() == 0) {
2451 if (!this->visitZeroRecordInitializer(R, E))
2456 if (
const auto *ILE = dyn_cast<InitListExpr>(E))
2457 FToInit = ILE->getInitializedFieldInUnion();
2461 const Record::Field *FieldToInit = R->getField(FToInit);
2463 if (!initPrimitiveField(FieldToInit,
Init, *
T,
true))
2466 if (!initCompositeField(FieldToInit,
Init,
true))
2470 return this->emitFinishInit(E);
2473 assert(!R->isUnion());
2474 for (
unsigned BI = 0; BI != R->getNumBases(); ++BI) {
2476 const Record::Base *B = R->getBase(BI);
2479 if (!this->emitGetPtrBase(B->Offset,
Init))
2485 unsigned FieldIndex = 0;
2486 for (
unsigned FI = R->getNumBases(); FI !=
Inits.size();) {
2487 const Record::Field *FieldToInit = R->getField(FieldIndex);
2488 if (FieldToInit->isUnnamedBitField()) {
2503 if (!initPrimitiveField(FieldToInit,
Init, *
T))
2505 }
else if (!initCompositeField(FieldToInit,
Init)) {
2513 assert(R->getNumVirtualBases() == 0);
2515 return this->emitFinishInit(E);
2520 Ctx.getASTContext().getAsConstantArrayType(QT);
2525 !this->emitCheckArrayDestSize(NumElems, E))
2528 if (
Inits.size() == 1 && QT ==
Inits[0]->getType())
2532 unsigned ElementIndex = 0;
2534 if (
const auto *EmbedS =
2535 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
2543 if (!this->emitCastIntegralFloating(
classifyPrim(IL), Sem,
2544 getFPOptions(E), E))
2550 return this->emitInitElem(TargetT, ElemIndex, IL);
2552 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
2568 for (; ElementIndex != NumElems; ++ElementIndex) {
2574 return this->emitFinishInit(E);
2578 unsigned NumInits =
Inits.size();
2583 QualType ElemQT = ComplexTy->getElementType();
2585 if (NumInits == 0) {
2587 for (
unsigned I = 0; I < 2; ++I) {
2588 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2590 if (!this->emitInitElem(ElemT, I, E))
2593 }
else if (NumInits == 2) {
2594 unsigned InitIndex = 0;
2599 if (!this->emitInitElem(ElemT, InitIndex, E))
2608 unsigned NumVecElements = VecT->getNumElements();
2609 assert(NumVecElements >=
Inits.size());
2611 QualType ElemQT = VecT->getElementType();
2615 unsigned InitIndex = 0;
2622 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
2623 if (!this->emitCopyArray(ElemT, 0, InitIndex,
2624 InitVecT->getNumElements(), E))
2626 InitIndex += InitVecT->getNumElements();
2628 if (!this->emitInitElem(ElemT, InitIndex, E))
2634 assert(InitIndex <= NumVecElements);
2637 for (; InitIndex != NumVecElements; ++InitIndex) {
2638 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2640 if (!this->emitInitElem(ElemT, InitIndex, E))
2647 unsigned NumElems = MT->getNumElementsFlattened();
2648 assert(
Inits.size() == NumElems);
2650 QualType ElemQT = MT->getElementType();
2656 for (
unsigned I = 0; I != NumElems; ++I) {
2659 if (!this->emitInitElem(ElemT, I, E))
2670template <
class Emitter>
2677 return this->emitInitElem(*InitT, ElemIndex,
Init);
2683 if (!this->emitConstUint32(ElemIndex,
Init))
2685 if (!this->emitArrayElemPtrUint32(
Init))
2690template <
class Emitter>
2693 bool Activate,
bool IsOperatorCall) {
2695 llvm::BitVector NonNullArgs;
2696 if (FuncDecl && FuncDecl->
hasAttr<NonNullAttr>())
2699 bool ExplicitMemberFn =
false;
2700 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl))
2701 ExplicitMemberFn = MD->isExplicitObjectMemberFunction();
2703 unsigned ArgIndex = 0;
2704 for (
const Expr *Arg : Args) {
2706 if (!this->
visit(Arg))
2714 unsigned DeclIndex = ArgIndex - IsOperatorCall + ExplicitMemberFn;
2715 if (DeclIndex < FuncDecl->getNumParams())
2716 Source = FuncDecl->
getParamDecl(ArgIndex - IsOperatorCall +
2725 if (!this->emitGetPtrLocal(*LocalIndex, Arg))
2733 if (!this->emitActivate(Arg))
2737 if (!NonNullArgs.empty() && NonNullArgs[ArgIndex]) {
2740 if (!this->emitCheckNonNullArg(ArgT, Arg))
2751template <
class Emitter>
2756template <
class Emitter>
2762template <
class Emitter>
2768template <
class Emitter>
2788 if (!this->emitGetPtrLocal(*LocalIndex, E))
2794template <
class Emitter>
2796 auto It = E->
begin();
2797 return this->
visit(*It);
2801 UnaryExprOrTypeTrait Kind) {
2806 T = Ref->getPointeeType();
2808 if (
T.getQualifiers().hasUnaligned())
2811 bool AlignOfReturnsPreferred =
2816 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2822template <
class Emitter>
2826 UnaryExprOrTypeTrait Kind = E->
getKind();
2829 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2835 ArgType = Ref->getPointeeType();
2841 if (
ArgType->isDependentType() || !
ArgType->isConstantSizeType())
2842 return this->emitInvalid(E);
2844 if (Kind == UETT_SizeOf)
2853 return this->emitConst(Size.getQuantity(), E);
2856 if (Kind == UETT_CountOf) {
2862 if (
const auto *CAT =
2866 return this->emitConst(CAT->getSize(), E);
2876 if (VAT->getElementType()->isArrayType()) {
2877 std::optional<APSInt> Res =
2879 ? VAT->getSizeExpr()->getIntegerConstantExpr(ASTCtx)
2884 return this->emitConst(*Res, E);
2889 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2909 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2912 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
2922 return this->emitConst(Size.getQuantity(), E);
2925 if (Kind == UETT_VectorElements) {
2930 return this->emitConst(VT->getNumElements(), E);
2932 return this->emitSizelessVectorElementSize(E);
2935 if (Kind == UETT_VecStep) {
2937 unsigned N = VT->getNumElements();
2944 return this->emitConst(N, E);
2946 return this->emitConst(1, E);
2949 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2958 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2960 return this->emitInvalid(E);
2962 return this->emitConst(
2971template <
class Emitter>
2980 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
2985 if (VD->getInit() && !VD->getInit()->isValueDependent())
2986 VD->evaluateValue();
2987 if (
auto GlobalIndex =
P.getGlobal(VD)) {
2988 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2990 if (
Member->getType()->isReferenceType())
2991 return this->emitLoadPopPtr(E);
3000 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
Member);
3001 MD && !MD->isStatic()) {
3005 if (!this->
discard(Base) && !this->emitSideEffect(E))
3020 const Record::Field *F = R->getField(FD);
3024 const auto maybeLoadValue = [&]() ->
bool {
3028 return this->emitLoadPop(*
T, E);
3033 if (F->Decl->getType()->isReferenceType())
3034 return this->emitGetFieldPop(
PT_Ptr, F->Offset, E) && maybeLoadValue();
3035 return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue();
3038template <
class Emitter>
3048template <
class Emitter>
3058 return this->emitCheckArraySize(Size, E);
3064 if (!this->
visit(Common))
3066 return this->emitCopyArray(*SubExprT, 0, 0, Size, E);
3080 for (
size_t I = 0; I != Size; ++I) {
3092template <
class Emitter>
3107 return this->emitGetLocal(SubExprT, It->second, E);
3110 if (!this->
visit(SourceExpr))
3117 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
3126 return this->emitGetLocal(SubExprT, LocalIndex, E);
3130template <
class Emitter>
3143 bool IsBcpCall =
false;
3144 if (
const auto *CE = dyn_cast<CallExpr>(
Condition->IgnoreParenCasts());
3145 CE && CE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) {
3149 LabelTy LabelEnd = this->getLabel();
3150 LabelTy LabelFalse = this->getLabel();
3153 if (!this->emitPushIgnoreDiags(E))
3161 if (this->checkingForUndefinedBehavior()) {
3164 if (!this->
discard(FalseExpr))
3178 if (!this->jumpFalse(LabelFalse, E))
3183 if (!this->jump(LabelEnd, E))
3185 this->emitLabel(LabelFalse);
3189 this->fallthrough(LabelEnd);
3190 this->emitLabel(LabelEnd);
3193 return this->emitPopIgnoreDiags(E);
3197template <
class Emitter>
3203 return this->emitGetStringPtr(E, E);
3207 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
3208 assert(CAT &&
"a string literal that's not a constant array?");
3213 unsigned N = std::min(ArraySize, E->
getLength());
3216 for (
unsigned I = 0; I != N; ++I) {
3219 if (CharWidth == 1) {
3220 this->emitConstSint8(CodeUnit, E);
3221 this->emitInitElemSint8(I, E);
3222 }
else if (CharWidth == 2) {
3223 this->emitConstUint16(CodeUnit, E);
3224 this->emitInitElemUint16(I, E);
3225 }
else if (CharWidth == 4) {
3226 this->emitConstUint32(CodeUnit, E);
3227 this->emitInitElemUint32(I, E);
3229 llvm_unreachable(
"unsupported character width");
3234 for (
unsigned I = N; I != ArraySize; ++I) {
3235 if (CharWidth == 1) {
3236 this->emitConstSint8(0, E);
3237 this->emitInitElemSint8(I, E);
3238 }
else if (CharWidth == 2) {
3239 this->emitConstUint16(0, E);
3240 this->emitInitElemUint16(I, E);
3241 }
else if (CharWidth == 4) {
3242 this->emitConstUint32(0, E);
3243 this->emitInitElemUint32(I, E);
3245 llvm_unreachable(
"unsupported character width");
3252template <
class Emitter>
3256 return this->emitDummyPtr(E, E);
3259template <
class Emitter>
3261 auto &A =
Ctx.getASTContext();
3270template <
class Emitter>
3278 auto &A =
Ctx.getASTContext();
3282 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
3283 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
3289 return this->emitGetStringPtr(SL, E);
3292template <
class Emitter>
3296 return this->emitConst(E->
getValue(), E);
3299template <
class Emitter>
3321 if (!this->emitLoad(LHST, E))
3324 if (!this->emitPrimCast(LHST,
classifyPrim(LHSComputationType),
3325 LHSComputationType, E))
3337 unsigned TempOffset =
3339 if (!this->emitSetLocal(*RT, TempOffset, E))
3345 if (!this->emitLoad(LHST, E))
3349 if (!this->emitPrimCast(LHST,
classifyPrim(LHSComputationType),
3350 LHSComputationType, E))
3354 if (!this->emitGetLocal(*RT, TempOffset, E))
3360 if (!this->emitAddf(getFPOptions(E), E))
3364 if (!this->emitSubf(getFPOptions(E), E))
3368 if (!this->emitMulf(getFPOptions(E), E))
3372 if (!this->emitDivf(getFPOptions(E), E))
3383 return this->emitStorePop(LHST, E);
3384 return this->emitStore(LHST, E);
3387template <
class Emitter>
3396 if (Op != BO_AddAssign && Op != BO_SubAssign)
3405 if (!this->emitLoad(*
LT, LHS))
3411 if (Op == BO_AddAssign) {
3412 if (!this->emitAddOffset(*RT, E))
3415 if (!this->emitSubOffset(*RT, E))
3420 return this->emitStorePopPtr(E);
3421 return this->emitStorePtr(E);
3424template <
class Emitter>
3437 if (!
Ctx.getLangOpts().CPlusPlus14)
3438 return this->
visit(RHS) && this->
visit(LHS) && this->emitError(E);
3440 if (!
LT || !RT || !ResultT || !LHSComputationT)
3457 if (!this->emitLoad(*
LT, E))
3459 if (
LT != LHSComputationT &&
3460 !this->emitIntegralCast(*
LT, *LHSComputationT,
3474 unsigned TempOffset =
3477 if (!this->emitSetLocal(*RT, TempOffset, E))
3484 if (!this->emitLoad(*
LT, E))
3486 if (
LT != LHSComputationT &&
3487 !this->emitIntegralCast(*
LT, *LHSComputationT,
3492 if (!this->emitGetLocal(*RT, TempOffset, E))
3499 if (!this->emitAdd(*LHSComputationT, E))
3503 if (!this->emitSub(*LHSComputationT, E))
3507 if (!this->emitMul(*LHSComputationT, E))
3511 if (!this->emitDiv(*LHSComputationT, E))
3515 if (!this->emitRem(*LHSComputationT, E))
3519 if (!this->emitShl(*LHSComputationT, *RT, E))
3523 if (!this->emitShr(*LHSComputationT, *RT, E))
3527 if (!this->emitBitAnd(*LHSComputationT, E))
3531 if (!this->emitBitXor(*LHSComputationT, E))
3535 if (!this->emitBitOr(*LHSComputationT, E))
3539 llvm_unreachable(
"Unimplemented compound assign operator");
3543 if (ResultT != LHSComputationT &&
3544 !this->emitIntegralCast(*LHSComputationT, *ResultT, E->
getType(), E))
3550 return this->emitStoreBitFieldPop(*ResultT, E);
3551 return this->emitStorePop(*ResultT, E);
3554 return this->emitStoreBitField(*ResultT, E);
3555 return this->emitStore(*ResultT, E);
3558template <
class Emitter>
3566template <
class Emitter>
3581 if (!
Ctx.getLangOpts().CPlusPlus11)
3588 for (
const Expr *LHS : CommaLHSs) {
3603 if (this->constantFolding())
3614 if (!this->
visit(Inner))
3619 if (!this->emitInitGlobalTemp(*InnerT, *GlobalIndex, TempDecl, E))
3622 if (!this->emitInitGlobal(*InnerT, *GlobalIndex, E))
3625 return this->emitGetPtrGlobal(*GlobalIndex, E);
3628 if (!this->checkLiteralType(Inner))
3631 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3637 return this->emitInitGlobalTempComp(TempDecl, E);
3650 unsigned LocalIndex =
3652 if (!this->VarScope->LocalsAlwaysEnabled &&
3653 !this->emitEnableLocal(LocalIndex, E))
3656 if (!this->
visit(Inner))
3658 if (!this->emitSetLocal(*InnerT, LocalIndex, E))
3661 return this->emitGetPtrLocal(LocalIndex, E);
3664 if (!this->checkLiteralType(Inner))
3671 if (!this->VarScope->LocalsAlwaysEnabled &&
3672 !this->emitEnableLocal(*LocalIndex, E))
3675 if (!this->emitGetPtrLocal(*LocalIndex, E))
3682template <
class Emitter>
3693 if (!this->
visit(SubExpr))
3697 return this->emitPopPtr(E);
3701template <
class Emitter>
3722 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3727 if (
P.isGlobalInitialized(*GlobalIndex))
3733 return this->emitInitGlobal(*
T, *GlobalIndex, E);
3745 unsigned LocalIndex;
3749 LocalIndex = *MaybeIndex;
3753 if (!this->emitGetPtrLocal(LocalIndex, E))
3757 return this->
visit(
Init) && this->emitInit(*
T, E);
3761template <
class Emitter>
3772 Ctx.getASTContext().CompCategories.getInfoForType(E->
getType());
3776 if (!R || R->getNumFields() == 0)
3778 const Record::Field *Field = R->getField(0
U);
3783 return this->emitInitField(*Field->T, Field->Offset, E);
3790template <
class Emitter>
3794 return this->emitConst(E->
getValue(), E);
3797template <
class Emitter>
3810 for (
const Record::Field &F : R->fields()) {
3812 if (!
Init ||
Init->containsErrors())
3820 if (!this->emitInitField(*
T, F.Offset, E))
3823 if (!this->emitGetPtrField(F.Offset, E))
3834template <
class Emitter>
3840 return this->emitGetStringPtr(E, E);
3844template <
class Emitter>
3849 return this->emitInvalid(E);
3852template <
class Emitter>
3866 if (!this->emitInvalidCast(
CastKind,
false, E))
3874 bool Fatal = (ToT != FromT);
3881template <
class Emitter>
3883 if (!
Ctx.getLangOpts().CPlusPlus20) {
3904 if (!this->emitDynamicCast(DestType.
getTypePtr(),
3909 return this->emitPopPtr(E);
3913template <
class Emitter>
3919 return this->emitConstBool(E->
getValue(), E);
3922template <
class Emitter>
3927 if (
T->isRecordType()) {
3941 if (!this->emitGetPtrLocal(*LocalIndex, E))
3949 T->castAsCXXRecordDecl()))
3959 if (!this->visitZeroRecordInitializer(R, E))
3970 if (!this->emitDefaultInit(Ctor, E))
3973 return this->emitPopPtr(E);
3981 assert(
Ctx.getASTContext().hasSameUnqualifiedType(E->
getType(),
3983 if (
const auto *ME = dyn_cast<MaterializeTemporaryExpr>(SrcObj)) {
3984 if (!this->emitCheckFunctionDecl(Ctor, E))
3995 assert(
Func->hasThisPointer());
3996 assert(!
Func->hasRVO());
4000 if (!this->emitDupPtr(E))
4004 for (
const auto *Arg : E->
arguments()) {
4005 if (!this->
visit(Arg))
4009 if (
Func->isVariadic()) {
4010 uint32_t VarArgSize = 0;
4011 unsigned NumParams =
Func->getNumWrittenParams();
4012 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I) {
4016 if (!this->emitCallVar(
Func, VarArgSize, E))
4019 if (!this->emitCall(
Func, 0, E)) {
4024 (void)this->emitPopPtr(E);
4030 return this->emitPopPtr(E);
4034 if (
T->isArrayType()) {
4039 if (!this->emitDupPtr(E))
4043 initArrayDimension = [&](
QualType T) ->
bool {
4044 if (!
T->isArrayType()) {
4046 for (
const auto *Arg : E->
arguments()) {
4047 if (!this->
visit(Arg))
4051 return this->emitCall(
Func, 0, E);
4055 Ctx.getASTContext().getAsConstantArrayType(
T);
4061 return this->emitCheckArraySize(NumElems, E);
4062 for (uint64_t I = 0; I != NumElems; ++I) {
4063 if (!this->emitConstUint64(I, E))
4065 if (!this->emitArrayElemPtrUint64(E))
4067 if (!initArrayDimension(ElemTy))
4070 return this->emitPopPtr(E);
4073 return initArrayDimension(E->
getType());
4079template <
class Emitter>
4089 assert(Val.
isInt());
4091 return this->emitConst(I, E);
4098 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
4099 return this->
visit(LValueExpr);
4114 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4118 const APValue &
V = UGCD->getValue();
4119 for (
unsigned I = 0, N = R->getNumFields(); I != N; ++I) {
4120 const Record::Field *F = R->getField(I);
4121 const APValue &FieldValue =
V.getStructField(I);
4125 if (!this->emitInitField(*F->T, F->Offset, E))
4133template <
class Emitter>
4139 for (
unsigned I = 0; I != N; ++I) {
4146 if (!this->
discard(ArrayIndexExpr))
4152 if (!this->
visit(ArrayIndexExpr))
4154 if (!this->emitCastAPToOffsetIndex(IndexT, E))
4158 if (!this->
visit(ArrayIndexExpr))
4162 if (!this->emitCast(IndexT,
PT_Sint64, E))
4172 return this->emitOffsetOf(
T, E, E);
4175template <
class Emitter>
4184 return this->visitZeroInitializer(*
T, Ty, E);
4191 if (!this->emitGetPtrLocal(*LocalIndex, E))
4199 ElemQT = CT->getElementType();
4202 NumElems = VT->getNumElements();
4203 ElemQT = VT->getElementType();
4209 for (
unsigned I = 0; I != NumElems; ++I) {
4210 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
4212 if (!this->emitInitElem(ElemT, I, E))
4221template <
class Emitter>
4226template <
class Emitter>
4232template <
class Emitter>
4237template <
class Emitter>
4242 return this->emitConst(E->
getValue(), E);
4245template <
class Emitter>
4267 unsigned ParamIndex = 0;
4271 if (!this->emitGetParam(PT, ParamIndex, E))
4276 return this->emitCall(F, 0, E);
4281template <
class Emitter>
4289 const Expr *PlacementDest =
nullptr;
4290 bool IsNoThrow =
false;
4295 if (PlacementArgs != 0) {
4304 if (PlacementArgs == 1) {
4306 if (OperatorNew->isReservedGlobalPlacementOperator()) {
4307 if (!this->emitCheckPlacementNew(E, E))
4309 PlacementDest = Arg1;
4313 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
4320 return this->emitInvalidNewDeleteExpr(E, E);
4324 return this->emitInvalid(E);
4326 }
else if (!OperatorNew
4327 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4328 return this->emitInvalidNewDeleteExpr(E, E);
4331 if (!PlacementDest) {
4336 Desc =
P.createDescriptor(E, *ElemT);
4338 Desc =
P.createDescriptor(E, ElementType.getTypePtr(),
false,
4345 std::optional<const Expr *> ArraySizeExpr = E->
getArraySize();
4349 const Expr *Stripped = *ArraySizeExpr;
4350 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
4351 Stripped = ICE->getSubExpr())
4352 if (ICE->getCastKind() != CK_NoOp &&
4353 ICE->getCastKind() != CK_IntegralCast)
4361 if (!this->
visit(Stripped))
4363 if (!this->emitSetLocal(
SizeT, ArrayLen, E))
4366 if (PlacementDest) {
4367 if (!this->
visit(PlacementDest))
4369 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
4371 if (!this->emitCheckNewTypeMismatchArray(
SizeT, E, E))
4374 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
4379 if (!this->emitAllocN(
SizeT, *ElemT, E, IsNoThrow, E))
4383 if (!this->emitAllocCN(
SizeT, Desc, IsNoThrow, E))
4390 size_t StaticInitElems = 0;
4391 const Expr *DynamicInit =
nullptr;
4395 Ctx.getASTContext().getAsConstantArrayType(InitType)) {
4396 StaticInitElems = CAT->getZExtSize();
4401 if (
const auto *ILE = dyn_cast<InitListExpr>(
Init)) {
4402 if (ILE->hasArrayFiller())
4403 DynamicInit = ILE->getArrayFiller();
4422 const Function *CtorFunc =
nullptr;
4423 if (
const auto *CE = dyn_cast<CXXConstructExpr>(
Init)) {
4427 }
else if (!DynamicInit && !ElemT)
4430 LabelTy EndLabel = this->getLabel();
4431 LabelTy StartLabel = this->getLabel();
4436 if (!this->emitDupPtr(E))
4438 if (!this->emitIsNonNullPtr(E))
4440 if (!this->jumpFalse(EndLabel, E))
4447 if (!this->emitConst(StaticInitElems,
SizeT, E))
4449 if (!this->emitSetLocal(
SizeT, Iter, E))
4452 this->fallthrough(StartLabel);
4453 this->emitLabel(StartLabel);
4455 if (!this->emitGetLocal(
SizeT, Iter, E))
4457 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
4459 if (!this->emitLT(
SizeT, E))
4461 if (!this->jumpFalse(EndLabel, E))
4465 if (!this->emitGetLocal(
SizeT, Iter, E))
4467 if (!this->emitArrayElemPtr(
SizeT, E))
4470 if (isa_and_nonnull<ImplicitValueInitExpr>(DynamicInit) &&
4475 if (!this->visitZeroInitializer(*InitT, ElemType, E))
4477 if (!this->emitStorePop(*InitT, E))
4481 if (!this->visitZeroArrayInitializer(ElemType, E))
4484 }
else if (DynamicInit) {
4486 if (!this->
visit(DynamicInit))
4488 if (!this->emitStorePop(*InitT, E))
4495 if (!this->visitZeroInitializer(
4499 if (!this->emitStorePop(*ElemT, E))
4503 if (!this->emitCall(CtorFunc, 0, E))
4508 if (!this->emitGetPtrLocal(Iter, E))
4510 if (!this->emitIncPop(
SizeT,
false, E))
4513 if (!this->jump(StartLabel, E))
4516 this->fallthrough(EndLabel);
4517 this->emitLabel(EndLabel);
4521 if (PlacementDest) {
4522 if (!this->
visit(PlacementDest))
4524 if (!this->emitCheckNewTypeMismatch(E, E))
4529 if (!this->emitAlloc(Desc, E))
4538 if (!this->emitInit(*ElemT, E))
4549 return this->emitPopPtr(E);
4554template <
class Emitter>
4560 if (!OperatorDelete->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4561 return this->emitInvalidNewDeleteExpr(E, E);
4570template <
class Emitter>
4576 if (
const Function *F =
Ctx.getOrCreateObjCBlock(E))
4581 return this->emitGetFnPtr(
Func, E);
4584template <
class Emitter>
4591 auto canonType = [](
const Type *
T) {
4592 return T->getCanonicalTypeUnqualified().getTypePtr();
4600 return this->emitGetTypeid(
4604 return this->emitGetTypeid(
4613 if (!
Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(E))
4619 if (!this->emitGetTypeidPtr(TypeInfoType, E))
4622 return this->emitPopPtr(E);
4626template <
class Emitter>
4630 return this->emitDummyPtr(E, E);
4631 return this->emitError(E);
4634template <
class Emitter>
4637 return this->emitDummyPtr(E, E);
4638 return this->emitError(E);
4641template <
class Emitter>
4648 assert(
false &&
"null reflection can't be constructed from parsing a "
4649 "reflection operand");
4657 assert(
false &&
"unknown or unimplemented reflection entities");
4661template <
class Emitter>
4663 assert(
Ctx.getLangOpts().CPlusPlus);
4664 return this->emitConstBool(E->
getValue(), E);
4667template <
class Emitter>
4679 return this->emitDummyPtr(GuidDecl, E);
4684 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4693 assert(
V.isStruct());
4694 assert(
V.getStructNumBases() == 0);
4698 return this->emitFinishInit(E);
4701template <
class Emitter>
4711template <
class Emitter>
4720template <
class Emitter>
4726template <
class Emitter>
4730 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
4734 if (OVE->isUnique())
4750template <
class Emitter>
4755template <
class Emitter>
4757 return this->emitError(E);
4760template <
class Emitter>
4766 return this->emitDummyPtr(E, E);
4769template <
class Emitter>
4770bool Compiler<Emitter>::emitVectorConversion(
const Expr *Src,
const Expr *E) {
4775 QualType ElemType = VT->getElementType();
4776 PrimType ElemT = classifyPrim(ElemType);
4778 PrimType SrcElemT = classifyVectorElementType(SrcType);
4784 if (!this->emitGetPtrLocal(*LocalIndex, E))
4788 unsigned SrcOffset =
4789 this->allocateLocalPrimitive(Src,
PT_Ptr,
true);
4790 if (!this->visit(Src))
4792 if (!this->emitSetLocal(
PT_Ptr, SrcOffset, E))
4795 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
4796 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
4798 if (!this->emitArrayElemPop(SrcElemT, I, E))
4802 if (SrcElemT != ElemT) {
4803 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
4805 }
else if (ElemType->isFloatingType() && SrcType != ElemType) {
4806 const auto *TargetSemantics = &Ctx.getFloatSemantics(ElemType);
4810 if (!this->emitInitElem(ElemT, I, E))
4816template <
class Emitter>
4818 return emitVectorConversion(E->
getSrcExpr(), E);
4821template <
class Emitter>
4825 return this->emitInvalid(E);
4834 assert(NumOutputElems > 0);
4840 if (!this->emitGetPtrLocal(*LocalIndex, E))
4845 unsigned VectorOffsets[2];
4846 for (
unsigned I = 0; I != 2; ++I) {
4849 if (!this->
visit(Vecs[I]))
4851 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I], E))
4854 for (
unsigned I = 0; I != NumOutputElems; ++I) {
4856 assert(ShuffleIndex >= -1);
4857 if (ShuffleIndex == -1)
4858 return this->emitInvalidShuffleVectorIndex(I, E);
4860 assert(ShuffleIndex < (NumInputElems * 2));
4861 if (!this->emitGetLocal(
PT_Ptr,
4862 VectorOffsets[ShuffleIndex >= NumInputElems], E))
4864 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
4865 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
4868 if (!this->emitInitElem(ElemT, I, E))
4873 return this->emitPopPtr(E);
4878template <
class Emitter>
4883 Base->getType()->isVectorType() ||
4889 if (Indices.size() == 1) {
4894 if (!this->emitConstUint32(Indices[0], E))
4896 return this->emitArrayElemPtrPop(
PT_Uint32, E);
4906 if (!this->emitSetLocal(
PT_Ptr, BaseOffset, E))
4914 if (!this->emitGetPtrLocal(*ResultIndex, E))
4922 uint32_t DstIndex = 0;
4923 for (uint32_t I : Indices) {
4924 if (!this->emitGetLocal(
PT_Ptr, BaseOffset, E))
4926 if (!this->emitArrayElemPop(ElemT, I, E))
4928 if (!this->emitInitElem(ElemT, DstIndex, E))
4938template <
class Emitter>
4942 return this->
discard(SubExpr) && this->emitInvalid(E);
4948 return this->emitDummyPtr(E, E);
4951template <
class Emitter>
4956 Ctx.getASTContext().getAsConstantArrayType(SubExpr->
getType());
4965 if (!this->emitGetPtrLocal(*LocalIndex, E))
4969 if (!this->
visit(SubExpr))
4971 if (!this->emitConstUint8(0, E))
4973 if (!this->emitArrayElemPtrPopUint8(E))
4975 if (!this->emitInitFieldPtr(R->getField(0u)->Offset, E))
4978 PrimType SecondFieldT = *R->getField(1u)->T;
4980 if (!this->emitConst(
ArrayType->getSize(), SecondFieldT, E))
4982 if (!this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E))
4985 return this->emitPopPtr(E);
4988 assert(SecondFieldT ==
PT_Ptr);
4990 if (!this->emitGetFieldPtr(R->getField(0u)->Offset, E))
4992 if (!this->emitExpandPtr(E))
4996 if (!this->emitArrayElemPtrPop(
PT_Uint64, E))
4999 if (!this->emitInitFieldPtr(R->getField(1u)->Offset, E))
5002 return this->emitPopPtr(E);
5006template <
class Emitter>
5021 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
5025 return this->emitUnsupported(E);
5034 return this->
Visit(E);
5041 return this->
Visit(E);
5045 if (
const auto *PE = dyn_cast<ParenExpr>(E))
5048 if (
const auto *CE = dyn_cast<CastExpr>(E);
5050 (CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp))
5057 if (
const auto *PE = dyn_cast<ParenExpr>(E))
5060 if (
const auto *CE = dyn_cast<CastExpr>(E);
5061 CE && (CE->getCastKind() == CK_DerivedToBase ||
5062 CE->getCastKind() == CK_UncheckedDerivedToBase ||
5063 CE->getCastKind() == CK_NoOp))
5083 if (!this->emitGetPtrLocal(*LocalIndex, E))
5093 return this->
Visit(E);
5096template <
class Emitter>
5102 return this->
Visit(E) && this->emitFinishInit(E);
5105template <
class Emitter>
5111 return this->
Visit(E) && this->emitFinishInitPop(E);
5117 return this->
Visit(E);
5128 if (!this->
visit(E))
5130 return this->emitComplexBoolCast(E);
5135 if (!this->
visit(E))
5143 return this->emitIsNonNullPtr(E);
5147 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
5150 return this->emitCast(*
T,
PT_Bool, E);
5153template <
class Emitter>
5157 QT = AT->getValueType();
5161 return this->emitZeroBool(E);
5163 return this->emitZeroSint8(E);
5165 return this->emitZeroUint8(E);
5167 return this->emitZeroSint16(E);
5169 return this->emitZeroUint16(E);
5171 return this->emitZeroSint32(E);
5173 return this->emitZeroUint32(E);
5175 return this->emitZeroSint64(E);
5177 return this->emitZeroUint64(E);
5179 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
5181 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
5183 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
5186 return this->emitNullMemberPtr(0,
nullptr, E);
5188 APFloat F = APFloat::getZero(Ctx.getFloatSemantics(QT));
5189 return this->emitFloat(F, E);
5192 auto Sem = Ctx.getASTContext().getFixedPointSemantics(QT);
5198 llvm_unreachable(
"unknown primitive type");
5201template <
class Emitter>
5202bool Compiler<Emitter>::visitZeroRecordInitializer(
const Record *R,
5204 bool IsCompleteClass) {
5208 for (
const Record::Field &Field :
R->fields()) {
5209 if (Field.isUnnamedBitField())
5216 if (!this->visitZeroInitializer(
T, QT, E))
5219 if (!this->emitInitFieldActivate(
T, Field.Offset, E))
5223 if (!this->emitInitField(
T, Field.Offset, E))
5228 if (!this->emitGetPtrField(Field.Offset, E))
5235 if (!this->visitZeroInitializer(
T, ET, E))
5237 if (!this->emitInitElem(
T, I, E))
5242 if (!this->visitZeroArrayInitializer(D->
getType(), E))
5245 if (!this->visitZeroRecordInitializer(D->
ElemRecord, E))
5253 if (!this->emitFinishInitActivatePop(E))
5257 if (!this->emitFinishInitPop(E))
5261 for (
const Record::Base &B :
R->bases()) {
5262 if (!this->emitGetPtrBase(B.Offset, E))
5264 if (!this->visitZeroRecordInitializer(B.R, E,
false))
5266 if (!this->emitFinishInitPop(E))
5270 if (IsCompleteClass) {
5271 for (
const Record::Base &B :
R->virtual_bases()) {
5274 if (!this->visitZeroRecordInitializer(B.R, E,
false))
5276 if (!this->emitFinishInitPop(E))
5284template <
class Emitter>
5285bool Compiler<Emitter>::visitZeroArrayInitializer(
QualType T,
const Expr *E) {
5286 assert(
T->isArrayType() ||
T->isAnyComplexType() ||
T->isVectorType());
5287 const ArrayType *AT =
T->getAsArrayTypeUnsafe();
5292 for (
size_t I = 0; I != NumElems; ++I) {
5293 if (!this->visitZeroInitializer(*ElemT, ElemType, E))
5295 if (!this->emitInitElem(*ElemT, I, E))
5301 const Record *
R = getRecord(ElemType);
5305 for (
size_t I = 0; I != NumElems; ++I) {
5306 if (!this->emitConstUint32(I, E))
5308 if (!this->emitArrayElemPtr(
PT_Uint32, E))
5310 if (!this->visitZeroRecordInitializer(R, E))
5312 if (!this->emitPopPtr(E))
5318 for (
size_t I = 0; I != NumElems; ++I) {
5319 if (!this->emitConstUint32(I, E))
5321 if (!this->emitArrayElemPtr(
PT_Uint32, E))
5323 if (!this->visitZeroArrayInitializer(ElemType, E))
5325 if (!this->emitPopPtr(E))
5334template <
class Emitter>
5335bool Compiler<Emitter>::visitAssignment(
const Expr *LHS,
const Expr *RHS,
5337 if (!canClassify(E->
getType()))
5342 if (!this->visit(LHS))
5344 if (!this->visit(RHS))
5347 if (!this->visit(RHS))
5349 if (!this->visit(LHS))
5357 if (!Ctx.getLangOpts().CPlusPlus && !this->emitInvalid(E))
5361 bool Activates = refersToUnion(LHS);
5364 if (NeedsFlip && !this->emitFlip(
PT_Ptr, RHT, E))
5367 if (DiscardResult) {
5368 if (BitField && Activates)
5369 return this->emitStoreBitFieldActivatePop(RHT, E);
5371 return this->emitStoreBitFieldPop(RHT, E);
5373 return this->emitStoreActivatePop(RHT, E);
5375 return this->emitStorePop(RHT, E);
5378 auto maybeLoad = [&](
bool Result) ->
bool {
5384 return this->emitLoadPop(RHT, E);
5388 if (BitField && Activates)
5389 return maybeLoad(this->emitStoreBitFieldActivate(RHT, E));
5391 return maybeLoad(this->emitStoreBitField(RHT, E));
5393 return maybeLoad(this->emitStoreActivate(RHT, E));
5395 return maybeLoad(this->emitStore(RHT, E));
5398template <
class Emitter>
5399template <
typename T>
5403 return this->emitConstSint8(
Value, Info);
5405 return this->emitConstUint8(
Value, Info);
5407 return this->emitConstSint16(
Value, Info);
5409 return this->emitConstUint16(
Value, Info);
5411 return this->emitConstSint32(
Value, Info);
5413 return this->emitConstUint32(
Value, Info);
5415 return this->emitConstSint64(
Value, Info);
5417 return this->emitConstUint64(
Value, Info);
5419 return this->emitConstBool(
Value, Info);
5427 llvm_unreachable(
"Invalid integral type");
5430 llvm_unreachable(
"unknown primitive type");
5433template <
class Emitter>
5434template <
typename T>
5435bool Compiler<Emitter>::emitConst(
T Value,
const Expr *E) {
5436 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
5439template <
class Emitter>
5443 return this->emitConstIntAPS(
Value, Info);
5445 return this->emitConstIntAP(
Value, Info);
5447 if (
Value.isSigned())
5448 return this->emitConst(
Value.getSExtValue(), Ty, Info);
5449 return this->emitConst(
Value.getZExtValue(), Ty, Info);
5452template <
class Emitter>
5456 return this->emitConstIntAPS(
Value, Info);
5458 return this->emitConstIntAP(
Value, Info);
5461 return this->emitConst(
Value.getSExtValue(), Ty, Info);
5462 return this->emitConst(
Value.getZExtValue(), Ty, Info);
5465template <
class Emitter>
5466bool Compiler<Emitter>::emitConst(
const APSInt &
Value,
const Expr *E) {
5467 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
5470template <
class Emitter>
5484 return Local.Offset;
5487template <
class Emitter>
5492 bool IsTemporary =
false;
5496 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
5497 Init = VarD->getInit();
5499 if (
const auto *E = Src.
asExpr()) {
5509 return std::nullopt;
5515 return Local.Offset;
5518template <
class Emitter>
5527 return std::nullopt;
5537 return Local.Offset;
5540template <
class Emitter>
5542 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
5543 return PT->getPointeeType()->getAsCanonical<RecordType>();
5549 return getRecord(RecordTy->getDecl()->getDefinitionOrSelf());
5553template <
class Emitter>
5555 return P.getOrCreateRecord(RD);
5558template <
class Emitter>
5560 return Ctx.getOrCreateFunction(FD);
5563template <
class Emitter>
5569 auto maybeDestroyLocals = [&]() ->
bool {
5570 if (DestroyToplevelScope)
5571 return RootScope.
destroyLocals() && this->emitCheckAllocations(E);
5572 return this->emitCheckAllocations(E);
5579 return this->emitRetVoid(E) && maybeDestroyLocals();
5587 return this->emitRet(*
T, E) && maybeDestroyLocals();
5595 if (!this->emitGetPtrLocal(*LocalOffset, E))
5603 return this->emitRetValue(E) && maybeDestroyLocals();
5606 return maybeDestroyLocals() &&
false;
5609template <
class Emitter>
5611 bool DestroyToplevelScope) {
5615 return this->
visitExpr(E, DestroyToplevelScope);
5618template <
class Emitter>
5630 if (
auto GlobalIndex =
P.getGlobal(VD)) {
5631 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
5645template <
class Emitter>
5647 bool ConstantContext) {
5650 if (!ConstantContext) {
5665 auto GlobalIndex =
P.getGlobal(VD);
5666 assert(GlobalIndex);
5668 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
5671 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
5679 if (!this->emitGetRefLocal(
Local->second.Offset, VD))
5681 }
else if (!this->emitGetLocal(*VarT,
Local->second.Offset, VD))
5684 if (!this->emitGetPtrLocal(
Local->second.Offset, VD))
5694 auto GlobalIndex =
P.getGlobal(VD);
5695 assert(GlobalIndex);
5696 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
5705 return VDScope.
destroyLocals() && this->emitCheckAllocations(VD);
5708template <
class Emitter>
5719 if (!this->isActive())
5724 if (
Init &&
Init->isValueDependent())
5728 auto checkDecl = [&]() ->
bool {
5730 return !NeedsOp || this->emitCheckDecl(VD, VD);
5737 if (!
P.getGlobal(*GlobalIndex)->isInitialized())
5740 if (
P.isGlobalInitialized(*GlobalIndex))
5744 }
else if ((GlobalIndex =
5759 return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
5762 if (!this->emitGetPtrGlobal(*GlobalIndex,
Init))
5765 if (!this->emitStartInit(
Init))
5771 if (!this->emitEndInit(
Init))
5774 return this->emitFinishInitGlobal(
Init);
5784 if (!
Init ||
Init->getType()->isVoidType())
5793 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
5805 if (!this->emitCheckRefInit(
Init))
5809 return this->emitSetLocal(*VarT, Offset, VD);
5817 if (!this->emitGetPtrLocal(*Offset,
Init))
5825template <
class Emitter>
5848 if (!this->emitGetPtrLocal(
Local.Offset, VD))
5854 return this->emitDestructionPop(D, VD);
5863 if (
const auto *P = dyn_cast<ParmVarDecl>(E->
getDecl()))
5887template <
class Emitter>
5902 unsigned ParamIndex = 0;
5909 const Expr *Arg = Args[ParamIndex];
5910 const ParmVarDecl *Param = Callee->getParamDecl(ParamIndex);
5912 unsigned ArgOffset =
5914 if (!this->
visit(Arg))
5916 if (!this->emitSetLocal(*ParamT, ArgOffset, Arg))
5922 if (!this->emitGetPtrLocal(*ArgOffset, Arg))
5934 if (
This->getType()->isPointerType()) {
5937 }
else if (
const auto *DRE = dyn_cast<DeclRefExpr>(
This)) {
5944 if (!this->emitGetPtrLocal(*ArgOffset,
This))
5966template <
class Emitter>
5972 return this->emitConst(Val.
getInt(), ValType, Info);
5974 return this->emitFloat(Val.
getFloat(), Info);
5978 if (!this->emitGetMemberPtr(MemberDecl, Info))
5984 if (!this->emitCopyMemberPtrPath(PathEntry, IsDerived, Info))
5990 return this->emitNullMemberPtr(0,
nullptr, Info);
5995 return this->emitNull(ValType, 0,
nullptr, Info);
5999 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>()) {
6002 GlobalIndex &&
P.isGlobalInitialized(*GlobalIndex)) {
6003 if (!this->emitGetPtrGlobal(*GlobalIndex, Info))
6006 if (!this->
visit(BaseExpr))
6009 EntryType = BaseExpr->getType();
6010 }
else if (
const auto *VD =
Base.dyn_cast<
const ValueDecl *>()) {
6013 EntryType = VD->getType();
6018 ->getCanonicalTypeUnqualified()
6020 EntryType =
Base.getTypeInfoType();
6021 if (!this->emitGetTypeid(OperandType, EntryType.
getTypePtr(), Info))
6029 ?
Ctx.getASTContext().getPointerType(E->
getType())
6032 if (!this->emitConstUint64(Offset, Info))
6034 if (!this->emitGetIntPtrUint64(PtrType.
getTypePtr(), Info))
6044 uint64_t Index = Entry.getAsArrayIndex();
6047 if (!this->emitConst(Index,
PT_Uint64, Info))
6049 if (!this->emitArrayElemPtrPop(
PT_Uint64, Info))
6051 EntryType = ElemType;
6058 const Decl *BaseOrMember = Entry.getAsBaseOrMember().getPointer();
6059 if (
const auto *FD = dyn_cast<FieldDecl>(BaseOrMember)) {
6061 if (!this->emitGetPtrFieldPop(EntryOffset, Info))
6063 EntryType = FD->getType();
6067 if (!this->emitGetPtrBasePop(B->Offset,
false, Info))
6072 if (!this->emitGetPtrVirtBasePop(
Base, Info))
6075 EntryType =
Ctx.getASTContext().getCanonicalTagType(
Base);
6090 uint32_t BitWidth =
Ctx.getBitWidth(E->
getType());
6092 ? this->emitCastPointerIntegralAP(BitWidth, Info)
6093 : this->emitCastPointerIntegralAPS(BitWidth, Info);
6095 return this->emitCastPointerIntegral(ValType, Info);
6101template <
class Emitter>
6104 bool IsCompleteClass) {
6110 if (IsCompleteClass)
6117 const Record::Base *RB = R->getBase(I);
6118 QualType BaseType =
Ctx.getASTContext().getCanonicalTagType(RB->Decl);
6120 if (!this->emitGetPtrBase(RB->Offset, Info))
6125 if (!this->emitFinishInitPop(Info))
6133 const Record::Field *RF = R->getField(I);
6134 QualType FieldType = RF->Decl->getType();
6139 if (!this->emitInitField(*PT, RF->Offset, Info))
6142 if (!this->emitGetPtrField(RF->Offset, Info))
6146 if (!this->emitFinishInitPop(Info))
6152 if (IsCompleteClass) {
6157 const Record::Base *RB = R->getVirtualBase(I);
6158 QualType BaseType =
Ctx.getASTContext().getCanonicalTagType(RB->Decl);
6166 if (!this->emitFinishInitPop(Info))
6182 const Record::Field *RF = R->getField(UnionField);
6183 QualType FieldType = RF->Decl->getType();
6188 if (RF->isBitField())
6189 return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(),
6191 return this->emitInitFieldActivate(*PT, RF->Offset, Info);
6194 if (!this->emitGetPtrField(RF->Offset, Info))
6196 if (!this->emitActivate(Info))
6200 return this->emitPopPtr(Info);
6204 const auto *ArrType =
T->getAsArrayTypeUnsafe();
6205 QualType ElemType = ArrType->getElementType();
6208 for (
unsigned A = 0, AN = Val.
getArraySize(); A != AN; ++A) {
6209 const APValue &Elem = A >= InitializedElems
6218 if (!this->emitInitElem(*ElemT, A, Info))
6221 if (!this->emitConstUint32(A, Info))
6223 if (!this->emitArrayElemPtrUint32(Info))
6227 if (!this->emitPopPtr(Info))
6234 assert(
T->isComplexType());
6237 if (!this->emitInitElemFloat(0, Info))
6241 if (!this->emitInitElemFloat(1, Info))
6246 assert(
T->isComplexIntegerType());
6250 if (!this->emitInitElem(IntT, 0, Info))
6254 if (!this->emitInitElem(IntT, 1, Info))
6259 assert(
T->isVectorType());
6267 if (!this->emitInitElem(ElemT, I, Info))
6277template <
class Emitter>
6279 if (
P.getGlobal(VD))
6283 P.createGlobal(VD,
nullptr,
false,
6286 llvm_unreachable(
"Why didn't that work?");
6290 "registerRedecl should only be called with primitive values");
6295 return this->emitInitGlobal(
T, *GlobalIndex, {});
6298template <
class Emitter>
6300 unsigned BuiltinID) {
6306 if (!
Ctx.getASTContext().BuiltinInfo.isConstantEvaluated(BuiltinID))
6307 return this->emitInvalid(E);
6316 if (BuiltinID == Builtin::BI__builtin_constant_p) {
6321 return this->emitConst(0, E);
6324 if (!this->emitStartSpeculation(E))
6326 LabelTy EndLabel = this->getLabel();
6327 if (!this->speculate(E, EndLabel))
6329 if (!this->emitEndSpeculation(E))
6331 this->fallthrough(EndLabel);
6339 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6340 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
6341 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
6342 BuiltinID == Builtin::BI__builtin_function_start) {
6345 return this->emitDummyPtr(E, E);
6356 if (!this->emitGetPtrLocal(*LocalIndex, E))
6361 switch (BuiltinID) {
6362 case Builtin::BI__builtin_object_size:
6363 case Builtin::BI__builtin_dynamic_object_size: {
6367 if (!this->
visit(Arg0))
6378 case Builtin::BI__assume:
6379 case Builtin::BI__builtin_assume:
6382 case Builtin::BI__atomic_is_lock_free:
6383 case Builtin::BI__atomic_always_lock_free: {
6394 for (
const auto *Arg : E->
arguments()) {
6395 if (!this->
visit(Arg))
6401 if (!this->emitCallBI(E, BuiltinID, E))
6420template <
class Emitter>
6441 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(FuncDecl);
6442 DD && DD->isTrivial()) {
6444 if (!this->
visit(MemberCall->getImplicitObjectArgument()))
6446 return this->emitCheckDestruction(E) && this->emitEndLifetime(E) &&
6447 this->emitPopPtr(E);
6452 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
6453 MD && MD->getParent()->isInvalidDecl())
6458 bool ActivateLHS =
false;
6466 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
6467 OCE && OCE->isAssignmentOp()) {
6468 const CXXRecordDecl *LHSRecord = Args[0]->getType()->getAsCXXRecordDecl();
6471 if (
const auto *MCE = dyn_cast<CXXMemberCallExpr>(E))
6472 if (!this->
visit(MCE->getImplicitObjectArgument()))
6479 if (!this->emitTrivialCopy(ActivateLHS,
Func, E))
6497 if (!this->emitGetPtrLocal(*LocalIndex, E))
6505 if (!this->emitGetPtrLocal(*LocalIndex, E))
6509 if (!this->emitDupPtr(E))
6514 const Expr *ReversedArgs[2];
6515 bool IsAssignmentOperatorCall =
false;
6516 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
6517 OCE && OCE->isAssignmentOp()) {
6521 assert(Args.size() == 2);
6522 const CXXRecordDecl *LHSRecord = Args[0]->getType()->getAsCXXRecordDecl();
6524 IsAssignmentOperatorCall =
true;
6525 ReversedArgs[0] = Args[1];
6526 ReversedArgs[1] = Args[0];
6527 Args = ReversedArgs;
6534 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
6535 MD && MD->isStatic()) {
6539 Args = Args.drop_front();
6543 bool Devirtualized =
false;
6546 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
6554 if (!this->
visit(Callee))
6556 if (!this->emitSetLocal(
PT_MemberPtr, *CalleeOffset, E))
6558 if (!this->emitGetLocal(
PT_MemberPtr, *CalleeOffset, E))
6560 if (!this->emitGetMemberPtrBase(E))
6563 const auto *InstancePtr = MC->getImplicitObjectArgument();
6570 Stripped->getType()->getPointeeType()->castAsCXXRecordDecl());
6571 Devirtualized =
true;
6572 if (!this->
visit(Stripped))
6575 if (!this->
visit(InstancePtr))
6579 if (!this->
visit(InstancePtr))
6583 }
else if (
const auto *PD =
6584 dyn_cast<CXXPseudoDestructorExpr>(E->
getCallee())) {
6585 if (!this->emitCheckPseudoDtor(E))
6593 return this->emitPseudoDtor(E);
6594 }
else if (!FuncDecl) {
6598 if (!this->
visit(Callee))
6600 if (!this->emitSetLocal(
PT_Ptr, *CalleeOffset, E))
6609 if (IsAssignmentOperatorCall) {
6610 assert(Args.size() == 2);
6613 if (!this->emitFlip(Arg2T, Arg1T, E))
6627 assert(HasRVO ==
Func->hasRVO());
6629 bool HasQualifier =
false;
6630 if (
const auto *ME = dyn_cast<MemberExpr>(E->
getCallee()))
6631 HasQualifier = ME->hasQualifier();
6633 bool IsVirtual =
false;
6634 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
6635 IsVirtual = !Devirtualized && MD->isVirtual();
6640 if (IsVirtual && !HasQualifier) {
6641 uint32_t VarArgSize = 0;
6642 unsigned NumParams =
6643 Func->getNumWrittenParams() +
6645 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
6648 if (!this->emitCallVirt(
Func, VarArgSize, E))
6650 }
else if (
Func->isVariadic()) {
6651 uint32_t VarArgSize = 0;
6652 unsigned NumParams =
6653 Func->getNumWrittenParams() +
6655 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
6657 if (!this->emitCallVar(
Func, VarArgSize, E))
6660 if (!this->emitCall(
Func, 0, E))
6669 uint32_t ArgSize = 0;
6670 for (
unsigned I = 0, N = E->
getNumArgs(); I != N; ++I)
6676 if (!this->emitGetLocal(
PT_MemberPtr, *CalleeOffset, E))
6678 if (!this->emitGetMemberPtrDecl(E))
6681 if (!this->emitGetLocal(
PT_Ptr, *CalleeOffset, E))
6684 if (!this->emitCallPtr(ArgSize, E, E))
6695template <
class Emitter>
6702template <
class Emitter>
6709template <
class Emitter>
6714 return this->emitConstBool(E->
getValue(), E);
6717template <
class Emitter>
6723 uint64_t Val =
Ctx.getASTContext().getTargetNullPointerValue(E->
getType());
6724 return this->emitNullPtr(Val,
nullptr, E);
6727template <
class Emitter>
6735 return this->emitZero(
T, E);
6738template <
class Emitter>
6743 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
6744 if (this->LambdaThisCapture.Offset > 0) {
6745 if (this->LambdaThisCapture.IsPtr)
6746 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
6747 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
6756 return this->emitThis(E);
6771 unsigned StartIndex = 0;
6772 unsigned EndIndex = 0;
6774 for (StartIndex =
InitStack.size() - 1; StartIndex > 0; --StartIndex) {
6776 EndIndex = StartIndex;
6783 for (; StartIndex > 0; --StartIndex) {
6794 if (StartIndex == 0 && EndIndex == 0)
6805 assert(StartIndex <= EndIndex);
6808 for (
unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
6820 case Stmt::CompoundStmtClass:
6822 case Stmt::DeclStmtClass:
6824 case Stmt::ReturnStmtClass:
6826 case Stmt::IfStmtClass:
6828 case Stmt::WhileStmtClass:
6830 case Stmt::DoStmtClass:
6832 case Stmt::ForStmtClass:
6834 case Stmt::CXXForRangeStmtClass:
6836 case Stmt::BreakStmtClass:
6838 case Stmt::ContinueStmtClass:
6840 case Stmt::SwitchStmtClass:
6842 case Stmt::CaseStmtClass:
6844 case Stmt::DefaultStmtClass:
6846 case Stmt::AttributedStmtClass:
6848 case Stmt::CXXTryStmtClass:
6850 case Stmt::NullStmtClass:
6853 case Stmt::GCCAsmStmtClass:
6854 case Stmt::MSAsmStmtClass:
6855 case Stmt::GotoStmtClass:
6856 return this->emitInvalid(S);
6857 case Stmt::LabelStmtClass:
6859 case Stmt::CXXExpansionStmtInstantiationClass:
6863 if (
const auto *E = dyn_cast<Expr>(S))
6870template <
class Emitter>
6873 for (
const auto *InnerStmt : S->
body())
6876 return Scope.destroyLocals();
6879template <
class Emitter>
6880bool Compiler<Emitter>::maybeEmitDeferredVarInit(
const VarDecl *VD) {
6881 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
6882 for (
auto *BD : DD->flat_bindings())
6883 if (
auto *KD = BD->getHoldingVar();
6884 KD && !this->visitVarDecl(KD, KD->getInit()))
6898template <
class Emitter>
bool Compiler<Emitter>::refersToUnion(
const Expr *E) {
6900 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
6901 if (
const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6908 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6913 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E);
6914 ICE && (ICE->getCastKind() == CK_NoOp ||
6915 ICE->getCastKind() == CK_DerivedToBase ||
6916 ICE->getCastKind() == CK_UncheckedDerivedToBase)) {
6917 E = ICE->getSubExpr();
6921 if (
const auto *
This = dyn_cast<CXXThisExpr>(E)) {
6922 const auto *ThisRecord =
6923 This->getType()->getPointeeType()->getAsRecordDecl();
6924 if (!ThisRecord->isUnion())
6927 if (
const auto *Ctor =
6928 dyn_cast_if_present<CXXConstructorDecl>(CompilingFunction))
6929 return Ctor->getParent() == ThisRecord;
6938template <
class Emitter>
6940 bool EvaluateConditionDecl) {
6941 for (
const auto *D : DS->
decls()) {
6946 if (
const auto *ESD = dyn_cast<CXXExpansionStmtDecl>(D)) {
6947 assert(ESD->getInstantiations() &&
"not expanded?");
6948 if (!this->
visitStmt(ESD->getInstantiations()))
6953 const auto *VD = dyn_cast<VarDecl>(D);
6960 if (EvaluateConditionDecl && !this->maybeEmitDeferredVarInit(VD))
6967template <
class Emitter>
6970 return this->emitUnsupported(RS);
6976 if (!this->
visit(RE))
6982 if (RE->getType()->isVoidType()) {
6983 if (!this->
visit(RE))
6986 if (RE->containsErrors())
6991 if (!this->emitRVOPtr(RE))
6997 return this->emitRetVoid(RS);
7003 return this->emitRetVoid(RS);
7009 auto visitChildStmt = [&](
const Stmt *S) ->
bool {
7016 if (
auto *CondInit = IS->
getInit()) {
7032 return visitChildStmt(IS->
getThen());
7034 return visitChildStmt(Else);
7040 if (!this->emitIsConstantContext(IS))
7043 if (!this->emitIsConstantContext(IS))
7045 if (!this->emitInv(IS))
7059 LabelTy LabelElse = this->getLabel();
7060 LabelTy LabelEnd = this->getLabel();
7061 if (!this->jumpFalse(LabelElse, IS))
7063 if (!visitChildStmt(IS->
getThen()))
7065 if (!this->jump(LabelEnd, IS))
7067 this->emitLabel(LabelElse);
7068 if (!visitChildStmt(Else))
7070 this->emitLabel(LabelEnd);
7072 LabelTy LabelEnd = this->getLabel();
7073 if (!this->jumpFalse(LabelEnd, IS))
7075 if (!visitChildStmt(IS->
getThen()))
7077 this->emitLabel(LabelEnd);
7086template <
class Emitter>
7091 LabelTy CondLabel = this->getLabel();
7092 LabelTy EndLabel = this->getLabel();
7096 this->fallthrough(CondLabel);
7097 this->emitLabel(CondLabel);
7113 if (!this->jumpFalse(EndLabel, S))
7123 if (!this->jump(CondLabel, S))
7125 this->fallthrough(EndLabel);
7126 this->emitLabel(EndLabel);
7135 LabelTy StartLabel = this->getLabel();
7136 LabelTy EndLabel = this->getLabel();
7137 LabelTy CondLabel = this->getLabel();
7141 this->fallthrough(StartLabel);
7142 this->emitLabel(StartLabel);
7148 this->fallthrough(CondLabel);
7149 this->emitLabel(CondLabel);
7156 if (!this->jumpTrue(StartLabel, S))
7159 this->fallthrough(EndLabel);
7160 this->emitLabel(EndLabel);
7164template <
class Emitter>
7172 LabelTy EndLabel = this->getLabel();
7173 LabelTy CondLabel = this->getLabel();
7174 LabelTy IncLabel = this->getLabel();
7181 this->fallthrough(CondLabel);
7182 this->emitLabel(CondLabel);
7194 if (!this->jumpFalse(EndLabel, S))
7203 this->fallthrough(IncLabel);
7204 this->emitLabel(IncLabel);
7210 if (!this->jump(CondLabel, S))
7214 this->emitLabel(EndLabel);
7220template <
class Emitter>
7230 LabelTy EndLabel = this->getLabel();
7231 LabelTy CondLabel = this->getLabel();
7232 LabelTy IncLabel = this->getLabel();
7248 this->fallthrough(CondLabel);
7249 this->emitLabel(CondLabel);
7252 if (!this->jumpFalse(EndLabel, S))
7263 this->fallthrough(IncLabel);
7264 this->emitLabel(IncLabel);
7271 if (!this->jump(CondLabel, S))
7274 this->fallthrough(EndLabel);
7275 this->emitLabel(EndLabel);
7279template <
class Emitter>
7282 return this->emitInvalidTargetLabel(
false, S);
7290 if (LI.BreakLabel) {
7291 TargetLabel = *LI.BreakLabel;
7292 BreakScope = LI.BreakOrContinueScope;
7301 return this->emitInvalidTargetLabel(
false, S);
7304 if (LI.Name == TargetLoop) {
7305 TargetLabel = *LI.BreakLabel;
7306 BreakScope = LI.BreakOrContinueScope;
7317 C =
C->getParent()) {
7318 if (!
C->destroyLocals())
7322 return this->jump(*TargetLabel, S);
7325template <
class Emitter>
7328 return this->emitInvalidTargetLabel(
true, S);
7335 if (LI.ContinueLabel) {
7336 TargetLabel = *LI.ContinueLabel;
7337 ContinueScope = LI.BreakOrContinueScope;
7346 return this->emitInvalidTargetLabel(
true, S);
7349 if (LI.Name == TargetLoop) {
7350 TargetLabel = *LI.ContinueLabel;
7351 ContinueScope = LI.BreakOrContinueScope;
7361 C =
C->getParent()) {
7362 if (!
C->destroyLocals())
7366 return this->jump(*TargetLabel, S);
7369template <
class Emitter>
7379 LabelTy EndLabel = this->getLabel();
7384 if (
const auto *CondInit = S->
getInit())
7393 if (!this->
visit(Cond))
7395 if (!this->emitSetLocal(CondT, CondVar, S))
7405 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
7408 if (CS->caseStmtIsGNURange()) {
7409 LabelTy EndOfRangeCheck = this->getLabel();
7410 const Expr *Low = CS->getLHS();
7411 const Expr *High = CS->getRHS();
7415 if (!this->emitGetLocal(CondT, CondVar, CS))
7417 if (!this->
visit(Low))
7420 if (!this->emitGE(
LT, S))
7422 if (!this->jumpFalse(EndOfRangeCheck, S))
7425 if (!this->emitGetLocal(CondT, CondVar, CS))
7427 if (!this->
visit(High))
7430 if (!this->emitLE(HT, S))
7434 this->emitLabel(EndOfRangeCheck);
7439 if (
Value->isValueDependent())
7444 if (!this->emitGetLocal(CondT, CondVar, CS))
7450 if (!this->emitEQ(ValueT, S))
7455 assert(!DefaultLabel);
7456 DefaultLabel = this->getLabel();
7463 if (!this->jump(*DefaultLabel, S))
7466 if (!this->jump(EndLabel, S))
7474 this->fallthrough(EndLabel);
7475 this->emitLabel(EndLabel);
7480template <
class Emitter>
7488 return this->emitUnsupported(S);
7493template <
class Emitter>
7500 if (LI.DefaultLabel) {
7501 DefaultLabel = *LI.DefaultLabel;
7506 this->emitLabel(DefaultLabel);
7510template <
class Emitter>
7517 if (IsMSVCConstexprAttr && !this->emitPushMSVCCE(S))
7520 if (this->
Ctx.getLangOpts().CXXAssumptions &&
7521 !this->Ctx.getLangOpts().MSVCCompat) {
7523 auto *AA = dyn_cast<CXXAssumeAttr>(A);
7529 const Expr *Assumption = AA->getAssumption();
7540 if (!this->emitAssume(Assumption))
7549 if (IsMSVCConstexprAttr)
7550 return this->emitPopMSVCCE(S);
7554template <
class Emitter>
7567template <
class Emitter>
7577 LabelTy EndLabel = this->getLabel();
7579 LabelTy ContinueLabel = this->getLabel();
7584 this->emitLabel(ContinueLabel);
7587 this->emitLabel(EndLabel);
7592template <
class Emitter>
7593bool Compiler<Emitter>::emitLambdaStaticInvokerBody(
const CXXMethodDecl *MD) {
7600 assert(ClosureClass->
captures().empty());
7604 "A generic lambda's static-invoker function must be a "
7605 "template specialization");
7609 llvm::FoldingSetInsertToken InsertToken;
7610 const FunctionDecl *CorrespondingCallOpSpecialization =
7612 assert(CorrespondingCallOpSpecialization);
7613 LambdaCallOp = CorrespondingCallOpSpecialization;
7617 assert(ClosureClass->
captures().empty());
7618 const Function *
Func = this->getFunction(LambdaCallOp);
7621 assert(
Func->hasThisPointer());
7624 if (
Func->hasRVO()) {
7625 if (!this->emitRVOPtr(MD))
7633 if (!this->emitNullPtr(0,
nullptr, MD))
7638 auto It = this->Params.find(PVD);
7639 assert(It != this->Params.end());
7643 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
7644 if (!this->emitGetParam(ParamType, It->second.Index, MD))
7648 if (!this->emitCall(
Func, 0, LambdaCallOp))
7653 return this->emitRet(*ReturnType, MD);
7656 return this->emitRetVoid(MD);
7659template <
class Emitter>
7660bool Compiler<Emitter>::checkLiteralType(
const Expr *E) {
7661 if (Ctx.getLangOpts().CPlusPlus23)
7671 const Expr *InitExpr =
Init->getInit();
7673 if (!
Init->isWritten() && !
Init->isInClassMemberInitializer() &&
7677 if (
const auto *CE = dyn_cast<CXXConstructExpr>(InitExpr)) {
7687template <
class Emitter>
7689 assert(!ReturnType);
7692 if (!this->emitStartThisLifetime1(Ctor))
7695 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
7696 const Expr *InitExpr,
7699 if (InitExpr->getType().isNull())
7703 if (
Activate && !this->emitActivateThisField(FieldOffset, InitExpr))
7706 if (!this->visit(InitExpr))
7709 if (F->isBitField())
7710 return this->emitInitThisBitField(*
T, FieldOffset, F->bitWidth(),
7712 return this->emitInitThisField(*
T, FieldOffset, InitExpr);
7717 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
7720 if (
Activate && !this->emitActivate(InitExpr))
7723 return this->visitInitializerPop(InitExpr);
7727 const Record *
R = this->getRecord(RD);
7730 bool IsUnion =
R->isUnion();
7740 if (!this->emitThis(Ctor))
7743 if (!this->emitGetParam(
PT_Ptr, 0, Ctor))
7746 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
7747 this->emitRetVoid(Ctor);
7750 unsigned FieldInits = 0;
7753 if (
R->getNumVirtualBases() > 0) {
7754 if (!this->emitThis(Ctor))
7756 LabelTy AfterVirtBasesLabel = this->getLabel();
7759 if (!this->emitIsBaseClass({}))
7761 if (!this->jumpTrue(AfterVirtBasesLabel, {}))
7764 for (
const auto *
Init : Ctor->
inits()) {
7765 LocalScope<Emitter> VirtLocalScope(
this);
7768 const auto *BaseDecl =
Base->castAsCXXRecordDecl();
7769 assert(
R->findVirtualBase(BaseDecl));
7770 if (!this->emitGetPtrThisVirtBase(BaseDecl, Ctor))
7772 if (!this->visitInitializerPop(
Init->getInit()))
7777 this->fallthrough(AfterVirtBasesLabel);
7778 this->emitLabel(AfterVirtBasesLabel);
7780 if (!this->emitPopPtr(Ctor))
7784 for (
const auto *
Init : Ctor->
inits()) {
7788 const Expr *InitExpr =
Init->getInit();
7790 const Record::Field *F =
R->getField(
Member);
7794 if (!emitFieldInitializer(F, F->Offset, InitExpr, IsUnion))
7798 const auto *BaseDecl =
Base->castAsCXXRecordDecl();
7800 if (
Init->isBaseVirtual()) {
7806 const Record::Base *B =
R->getBase(BaseDecl);
7808 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
7812 if (!this->visitInitializerPop(InitExpr))
7817 unsigned ChainSize = IFD->getChainingSize();
7818 assert(ChainSize >= 2);
7820 unsigned NestedFieldOffset = 0;
7821 const Record::Field *NestedField =
nullptr;
7822 for (
unsigned I = 0; I != ChainSize; ++I) {
7824 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
7825 assert(FieldRecord);
7827 NestedField = FieldRecord->
getField(FD);
7828 assert(NestedField);
7829 IsUnion = IsUnion || FieldRecord->
isUnion();
7831 NestedFieldOffset += NestedField->Offset;
7834 if (I != ChainSize - 1)
7837 assert(NestedField);
7840 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
7845 unsigned InitFieldOffset = 0;
7846 for (
const NamedDecl *ND : IFD->chain().drop_back()) {
7848 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
7849 assert(FieldRecord);
7850 NestedField = FieldRecord->
getField(FD);
7851 InitFieldOffset += NestedField->Offset;
7852 assert(NestedField);
7853 if (!this->emitGetPtrThisField(InitFieldOffset, InitExpr))
7855 if (!this->emitFinishInitPop(InitExpr))
7859 InitStack.pop_back_n(ChainSize - 1);
7862 assert(
Init->isDelegatingInitializer());
7863 if (!this->emitThis(InitExpr))
7865 if (!this->visitInitializerPop(
Init->getInit()))
7869 if (!
Scope.destroyLocals())
7873 if (FieldInits !=
R->getNumFields()) {
7874 assert(FieldInits < R->getNumFields());
7876 if (!this->emitStartThisLifetime(Ctor))
7883 if (
const auto *CS = dyn_cast<CompoundStmt>(Body)) {
7884 if (!CS->body_empty() && !this->emitCtorCheck(
SourceInfo{}))
7891 if (!visitStmt(Body))
7898template <
class Emitter>
7901 const Record *
R = this->getRecord(RD);
7905 if (!
Dtor->isTrivial() &&
Dtor->getBody()) {
7906 if (!this->visitStmt(
Dtor->getBody()))
7910 if (!this->emitThis(
Dtor))
7913 if (!this->emitCheckDestruction(
Dtor))
7917 if (!
R->isUnion()) {
7921 for (
const Record::Field &Field : llvm::reverse(
R->fields())) {
7925 if (!this->emitGetPtrField(Field.Offset,
SourceInfo{}))
7927 if (!this->emitDestructionPop(D,
SourceInfo{}))
7932 for (
const Record::Base &
Base : llvm::reverse(
R->bases())) {
7933 if (
Base.R->hasTrivialDtor())
7937 if (!this->emitRecordDestructionPop(
Base.R, {}))
7941 if (
R->getNumVirtualBases() > 0) {
7942 LabelTy EndLabel = this->getLabel();
7944 if (!this->emitIsBaseClass({}))
7946 if (!this->jumpTrue(EndLabel, {}))
7949 for (
const Record::Base &
Base : llvm::reverse(
R->virtual_bases())) {
7950 if (
Base.R->hasTrivialDtor())
7955 if (!this->emitRecordDestructionPop(
Base.R, {}))
7959 this->fallthrough(EndLabel);
7960 this->emitLabel(EndLabel);
7963 if (!this->emitMarkDestroyed(
Dtor))
7966 return this->emitPopPtr(
Dtor) && this->emitRetVoid(
Dtor);
7969template <
class Emitter>
7970bool Compiler<Emitter>::compileUnionAssignmentOperator(
7972 if (!this->emitThis(MD))
7975 if (!this->emitGetParam(
PT_Ptr, 0, MD))
7978 return this->emitMemcpy(MD) && this->emitRet(
PT_Ptr, MD);
7981template <
class Emitter>
7991 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
7992 return this->compileConstructor(Ctor);
7993 if (
const auto *
Dtor = dyn_cast<CXXDestructorDecl>(F))
7994 return this->compileDestructor(
Dtor);
7997 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
8002 return this->compileUnionAssignmentOperator(MD);
8005 return this->emitLambdaStaticInvokerBody(MD);
8009 if (
const auto *Body = F->
getBody())
8023 return FD->getBitWidthValue();
8026template <
class Emitter>
8042 if (!
Ctx.getLangOpts().CPlusPlus14)
8043 return this->emitInvalid(E);
8045 return this->emitError(E);
8047 if (!this->
visit(SubExpr))
8051 if (!this->emitIncPtr(E))
8058 return DiscardResult ? this->emitIncfPop(getFPOptions(E), E)
8059 : this->emitIncf(getFPOptions(E), E);
8071 if (!
Ctx.getLangOpts().CPlusPlus14)
8072 return this->emitInvalid(E);
8074 return this->emitError(E);
8076 if (!this->
visit(SubExpr))
8080 if (!this->emitDecPtr(E))
8087 return DiscardResult ? this->emitDecfPop(getFPOptions(E), E)
8088 : this->emitDecf(getFPOptions(E), E);
8101 if (!
Ctx.getLangOpts().CPlusPlus14)
8102 return this->emitInvalid(E);
8104 return this->emitError(E);
8106 if (!this->
visit(SubExpr))
8110 if (!this->emitLoadPtr(E))
8112 if (!this->emitConstUint8(1, E))
8114 if (!this->emitAddOffsetUint8(E))
8116 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
8122 return this->emitIncfPop(getFPOptions(E), E);
8132 const auto &TargetSemantics =
Ctx.getFloatSemantics(E->
getType());
8133 if (!this->emitLoadFloat(E))
8135 APFloat F(TargetSemantics, 1);
8136 if (!this->emitFloat(F, E))
8139 if (!this->emitAddf(getFPOptions(E), E))
8141 if (!this->emitStoreFloat(E))
8153 return E->
isGLValue() || this->emitLoadPop(*
T, E);
8156 if (!
Ctx.getLangOpts().CPlusPlus14)
8157 return this->emitInvalid(E);
8159 return this->emitError(E);
8161 if (!this->
visit(SubExpr))
8165 if (!this->emitLoadPtr(E))
8167 if (!this->emitConstUint8(1, E))
8169 if (!this->emitSubOffsetUint8(E))
8171 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
8177 return this->emitDecfPop(getFPOptions(E), E);
8187 const auto &TargetSemantics =
Ctx.getFloatSemantics(E->
getType());
8188 if (!this->emitLoadFloat(E))
8190 APFloat F(TargetSemantics, 1);
8191 if (!this->emitFloat(F, E))
8194 if (!this->emitSubf(getFPOptions(E), E))
8196 if (!this->emitStoreFloat(E))
8208 return E->
isGLValue() || this->emitLoadPop(*
T, E);
8212 return this->emitError(E);
8215 return this->
discard(SubExpr);
8220 if (!this->emitInv(E))
8224 return this->emitCast(
PT_Bool, ET, E);
8228 return this->emitError(E);
8230 if (!this->
visit(SubExpr))
8235 return this->emitError(E);
8237 if (!this->
visit(SubExpr))
8253 if (!
Ctx.getLangOpts().CPlusPlus) {
8256 if (
const auto *Deref = dyn_cast<UnaryOperator>(
Sub);
8257 Deref && Deref->getOpcode() == UO_Deref) {
8259 return this->
discard(Deref->getSubExpr());
8260 return this->
visit(Deref->getSubExpr()) && this->emitAddrOf(E);
8265 return this->
discard(SubExpr);
8266 return this->
delegate(SubExpr) && this->emitAddrOf(E);
8269 return this->
discard(SubExpr);
8271 if (!this->
visit(SubExpr))
8278 return this->emitNarrowPtr(E);
8283 return this->emitError(E);
8285 if (!this->
visit(SubExpr))
8299 : this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
8304 assert(
false &&
"Unhandled opcode");
8310template <
class Emitter>
8316 return this->
discard(SubExpr);
8319 auto prepareResult = [=]() ->
bool {
8324 return this->emitGetPtrLocal(*LocalIndex, E);
8331 unsigned SubExprOffset = ~0u;
8332 auto createTemp = [=, &SubExprOffset]() ->
bool {
8335 if (!this->
visit(SubExpr))
8337 return this->emitSetLocal(
PT_Ptr, SubExprOffset, E);
8341 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
8342 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
8344 return this->emitArrayElemPop(ElemT, Index, E);
8349 if (!prepareResult())
8353 for (
unsigned I = 0; I != 2; ++I) {
8354 if (!getElem(SubExprOffset, I))
8356 if (!this->emitNeg(ElemT, E))
8358 if (!this->emitInitElem(ElemT, I, E))
8369 if (!this->
visit(SubExpr))
8371 if (!this->emitComplexBoolCast(SubExpr))
8373 if (!this->emitInv(E))
8376 return this->emitCast(
PT_Bool, ET, E);
8380 return this->emitComplexReal(SubExpr);
8383 if (!this->
visit(SubExpr))
8387 if (!this->emitConstUint8(1, E))
8389 return this->emitArrayElemPtrPopUint8(E);
8400 if (!this->emitArrayElem(ElemT, 1, E))
8402 if (!this->emitNeg(ElemT, E))
8404 if (!this->emitInitElem(ElemT, 1, E))
8412 return this->emitInvalid(E);
8418template <
class Emitter>
8424 return this->
discard(SubExpr);
8427 if (UnaryOp == UO_Extension)
8430 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
8431 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
8432 return this->emitInvalid(E);
8435 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
8442 if (!this->emitGetPtrLocal(*LocalIndex, E))
8447 unsigned SubExprOffset =
8449 if (!this->
visit(SubExpr))
8451 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, E))
8456 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
8457 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
8459 return this->emitArrayElemPop(ElemT, Index, E);
8464 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8465 if (!getElem(SubExprOffset, I))
8467 if (!this->emitNeg(ElemT, E))
8469 if (!this->emitInitElem(ElemT, I, E))
8484 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8485 if (!getElem(SubExprOffset, I))
8488 if (!this->emitPrimCast(ElemT,
PT_Bool,
Ctx.getASTContext().BoolTy, E))
8490 if (!this->emitInv(E))
8492 if (!this->emitPrimCast(
PT_Bool, ElemT, VecTy->getElementType(), E))
8494 if (!this->emitNeg(ElemT, E))
8496 if (ElemT != ResultVecElemT &&
8497 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy, E))
8499 if (!this->emitInitElem(ResultVecElemT, I, E))
8505 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
8506 if (!getElem(SubExprOffset, I))
8509 if (!this->emitInv(E))
8512 if (!this->emitComp(ElemT, E))
8515 if (!this->emitInitElem(ElemT, I, E))
8520 llvm_unreachable(
"Unsupported unary operators should be handled up front");
8525template <
class Emitter>
8527 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
8530 return this->emitConst(ECD->getInitVal(), E);
8532 if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
8536 return F && this->emitGetFnPtr(F, E);
8538 if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
8539 TPOD = TPOD->getFirstDecl();
8543 return this->emitGetPtrGlobal(*GlobalIndex, E);
8549 return this->emitInitGlobal(*
T, *Index, E);
8552 if (!this->emitGetPtrGlobal(*Index, E))
8556 return this->emitFinishInit(E);
8568 auto maybePopPtr = [&]() ->
bool {
8570 return this->emitPopPtr(E);
8577 if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
8581 if (
Ctx.getLangOpts().CPlusPlus && !
Ctx.getLangOpts().CPlusPlus11 &&
8586 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
8587 if (IsReference || !It->second.IsPtr)
8588 return this->emitGetParam(
classifyPrim(E), It->second.Index, E);
8590 return this->emitGetPtrParam(It->second.Index, E);
8593 if (!
Ctx.getLangOpts().CPlusPlus23 && IsReference && !
Locals.contains(D))
8600 const unsigned Offset = It->second.Offset;
8603 return this->emitGetRefLocal(Offset, E) && maybePopPtr();
8605 return this->emitGetPtrLocal(Offset, E) && maybePopPtr();
8608 if (
auto GlobalIndex =
P.getGlobal(D)) {
8610 if (!
Ctx.getLangOpts().CPlusPlus11)
8611 return this->emitGetGlobal(
classifyPrim(E), *GlobalIndex, E);
8612 if (!
Ctx.getLangOpts().CPlusPlus23)
8613 return this->emitGetGlobalUnchecked(
classifyPrim(E), *GlobalIndex, E);
8615 return this->emitGetRefGlobal(*GlobalIndex, E) && maybePopPtr();
8618 return this->emitGetPtrGlobal(*GlobalIndex, E) && maybePopPtr();
8622 auto revisit = [&](
const VarDecl *VD,
8623 bool IsConstexprUnknown =
true) ->
bool {
8625 IsConstexprUnknown);
8626 if constexpr (std::is_same_v<Emitter, EvalEmitter>) {
8632 if constexpr (std::is_same_v<Emitter, EvalEmitter>) {
8633 if (!this->emitPopCC(E))
8637 if (VarState.notCreated())
8645 if constexpr (!std::is_same_v<Emitter, EvalEmitter>) {
8647 if (
auto It = this->LambdaCaptures.find(D);
8648 It != this->LambdaCaptures.end()) {
8649 auto [Offset, IsPtr] = It->second;
8652 return this->emitGetThisFieldPtr(Offset, E) && maybePopPtr();
8653 return this->emitGetPtrThisField(Offset, E) && maybePopPtr();
8657 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E);
8658 DRE && DRE->refersToEnclosingVariableOrCapture()) {
8659 if (
const auto *VD = dyn_cast<VarDecl>(D); VD && VD->
isInitCapture())
8663 if (
const auto *BD = dyn_cast<BindingDecl>(D))
8664 return this->
delegate(BD->getBinding());
8670 return this->emitDummyPtr(D, E);
8675 const auto *VD = dyn_cast<VarDecl>(D);
8677 return this->emitError(E);
8680 if (!
Ctx.getLangOpts().CPlusPlus) {
8684 return revisit(VD,
false);
8688 return this->emitDummyPtr(D, E);
8692 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
8693 if (
T.isConstant(
Ctx.getASTContext()))
8695 return T->isReferenceType();
8699 typeShouldBeVisited(DeclType)) {
8701 Init && !
Init->isValueDependent()) {
8706 (void)
Init->EvaluateAsInitializer(
Ctx.getASTContext(), VD,
Result,
true);
8719 bool IsConstexprUnknown = !DeclType.
isConstant(
Ctx.getASTContext()) &&
8724 return revisit(VD, IsConstexprUnknown);
8725 }
else if (
Ctx.getLangOpts().CPlusPlus23 && IsReference)
8726 return revisit(VD,
true);
8735 return this->emitDummyPtr(
8739template <
class Emitter>
8745template <
class Emitter>
8755 if (!
C->destroyLocals())
8761template <
class Emitter>
8762unsigned Compiler<Emitter>::collectBaseOffset(
const QualType BaseType,
8765 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
8767 return Ty->castAsCXXRecordDecl();
8769 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
8770 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
8772 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
8776template <
class Emitter>
8783 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
8788 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
8789 getFPOptions(E), E);
8791 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
8792 getFPOptions(E), E);
8796 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
8801 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
8803 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
8807 return FromT != ToT ? this->emitCast(FromT, ToT, E) :
true;
8811 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
8812 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E);
8819template <
class Emitter>
8822 assert(FromT != ToT);
8825 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
8827 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
8829 return this->emitCast(FromT, ToT, E);
8833template <
class Emitter>
8834bool Compiler<Emitter>::emitComplexReal(
const Expr *SubExpr) {
8838 return this->
discard(SubExpr);
8840 if (!this->visit(SubExpr))
8843 if (!this->emitConstUint8(0, SubExpr))
8845 return this->emitArrayElemPtrPopUint8(SubExpr);
8849 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
8853template <
class Emitter>
8854bool Compiler<Emitter>::emitComplexBoolCast(
const Expr *E) {
8855 assert(!DiscardResult);
8859 if (!this->emitArrayElem(ElemT, 0, E))
8862 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(E), E))
8865 if (!this->emitCast(ElemT,
PT_Bool, E))
8870 LabelTy LabelTrue = this->getLabel();
8871 if (!this->jumpTrue(LabelTrue, E))
8874 if (!this->emitArrayElemPop(ElemT, 1, E))
8877 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(E), E))
8880 if (!this->emitCast(ElemT,
PT_Bool, E))
8884 LabelTy EndLabel = this->getLabel();
8885 this->jump(EndLabel, E);
8887 this->emitLabel(LabelTrue);
8888 if (!this->emitPopPtr(E))
8890 if (!this->emitConstBool(
true, E))
8893 this->fallthrough(EndLabel);
8894 this->emitLabel(EndLabel);
8899template <
class Emitter>
8900bool Compiler<Emitter>::emitComplexComparison(
const Expr *LHS,
const Expr *RHS,
8911 LHSIsComplex =
true;
8912 ElemT = classifyComplexElementType(LHS->
getType());
8913 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true);
8914 if (!this->visit(LHS))
8916 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
8919 LHSIsComplex =
false;
8921 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true);
8922 if (!this->visit(LHS))
8924 if (!this->emitSetLocal(LHST, LHSOffset, E))
8931 RHSIsComplex =
true;
8932 ElemT = classifyComplexElementType(RHS->
getType());
8933 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true);
8934 if (!this->visit(RHS))
8936 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
8939 RHSIsComplex =
false;
8941 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true);
8942 if (!this->visit(RHS))
8944 if (!this->emitSetLocal(RHST, RHSOffset, E))
8948 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
8949 bool IsComplex) ->
bool {
8951 if (!this->emitGetLocal(
PT_Ptr, LocalOffset, E))
8953 return this->emitArrayElemPop(ElemT, Index, E);
8955 return this->emitGetLocal(ElemT, LocalOffset, E);
8958 for (
unsigned I = 0; I != 2; ++I) {
8960 if (!getElem(LHSOffset, I, LHSIsComplex))
8962 if (!getElem(RHSOffset, I, RHSIsComplex))
8965 if (!this->emitEQ(ElemT, E))
8968 if (!this->emitCastBoolUint8(E))
8973 if (!this->emitAddUint8(E))
8975 if (!this->emitConstUint8(2, E))
8979 if (!this->emitEQUint8(E))
8982 if (!this->emitNEUint8(E))
8989 return this->emitCast(
PT_Bool, ResT, E);
8996template <
class Emitter>
8997bool Compiler<Emitter>::emitRecordDestructionPop(
const Record *R,
9000 assert(!
R->hasTrivialDtor());
9003 const Function *DtorFunc = getFunction(
Dtor);
9006 assert(DtorFunc->hasThisPointer());
9007 assert(DtorFunc->getNumParams() == 1);
9008 return this->emitCall(DtorFunc, 0, Loc);
9013template <
class Emitter>
9014bool Compiler<Emitter>::emitDestructionPop(
const Descriptor *Desc,
9026 return this->emitPopPtr(Loc);
9028 for (ssize_t I = N - 1; I >= 1; --I) {
9029 if (!this->emitConstUint64(I, Loc))
9031 if (!this->emitArrayElemPtrUint64(Loc))
9033 if (!this->emitDestructionPop(ElemDesc, Loc))
9037 if (!this->emitConstUint64(0, Loc))
9039 if (!this->emitArrayElemPtrPopUint64(Loc))
9041 return this->emitDestructionPop(ElemDesc, Loc);
9046 return this->emitRecordDestructionPop(Desc->
ElemRecord, Loc);
9051template <
class Emitter>
9052bool Compiler<Emitter>::emitDummyPtr(
DeclOrExpr D,
const Expr *E,
bool CU) {
9053 assert(!DiscardResult &&
"Should've been checked before");
9054 return this->emitGetOpaquePtr(D, CU, E);
9057template <
class Emitter>
9060 return this->emitConstFloat(
Floating(F), Info);
9062 APInt I = F.bitcastToAPInt();
9063 return this->emitConstFloat(
9065 llvm::APFloatBase::SemanticsToEnum(F.getSemantics())),
9076template <
class Emitter>
9077bool Compiler<Emitter>::emitBuiltinBitCast(
const CastExpr *E) {
9090 if (!this->emitGetPtrLocal(*LocalIndex, E))
9100 if (!this->visit(SubExpr))
9102 }
else if (
OptPrimType FromT = classify(SubExpr)) {
9103 unsigned TempOffset =
9104 allocateLocalPrimitive(SubExpr, *FromT,
true);
9105 if (!this->visit(SubExpr))
9107 if (!this->emitSetLocal(*FromT, TempOffset, E))
9109 if (!this->emitGetPtrLocal(TempOffset, E))
9116 if (!this->emitBitCast(E))
9118 return DiscardResult ? this->emitPopPtr(E) :
true;
9122 const llvm::fltSemantics *TargetSemantics =
nullptr;
9124 TargetSemantics = &Ctx.getFloatSemantics(ToType);
9130 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
9132 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->
isStdByteType(),
9133 ResultBitWidth, TargetSemantics,
9138 return this->emitPop(*ToT, E);
9147template <
class Emitter>
9148bool Compiler<Emitter>::emitHLSLAggregateSplat(
PrimType SrcT,
9153 unsigned NumElems = 0;
9156 NumElems = VT->getNumElements();
9157 ElemType = VT->getElementType();
9159 NumElems = MT->getNumElementsFlattened();
9160 ElemType = MT->getElementType();
9163 PrimType ElemT = classifyPrim(ElemType);
9164 for (
unsigned I = 0; I != NumElems; ++I) {
9165 if (!this->emitGetLocal(SrcT, SrcOffset, E))
9167 if (!this->emitPrimCast(SrcT, ElemT, ElemType, E))
9169 if (!this->emitInitElem(ElemT, I, E))
9179 QualType ArrElemType = CAT->getElementType();
9180 unsigned ArrSize = CAT->getZExtSize();
9183 for (
unsigned I = 0; I != ArrSize; ++I) {
9184 if (!this->emitGetLocal(SrcT, SrcOffset, E))
9186 if (!this->emitPrimCast(SrcT, *ElemT, ArrElemType, E))
9188 if (!this->emitInitElem(*ElemT, I, E))
9192 for (
unsigned I = 0; I != ArrSize; ++I) {
9193 if (!this->emitConstUint32(I, E))
9195 if (!this->emitArrayElemPtrUint32(E))
9197 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, ArrElemType, E))
9199 if (!this->emitFinishInitPop(E))
9209 const Record *
R = getRecord(DestType);
9213 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
9215 const Record::Base *B =
R->getBase(BS.getType());
9217 if (!this->emitGetPtrBase(B->Offset, E))
9219 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, BS.getType(), E))
9221 if (!this->emitFinishInitPop(E))
9226 for (
const Record::Field &F :
R->fields()) {
9227 if (F.isUnnamedBitField())
9230 QualType FieldType = F.Decl->getType();
9232 if (!this->emitGetLocal(SrcT, SrcOffset, E))
9234 if (!this->emitPrimCast(SrcT, *FieldT, FieldType, E))
9236 if (F.isBitField()) {
9237 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
9240 if (!this->emitInitField(*FieldT, F.Offset, E))
9244 if (!this->emitGetPtrField(F.Offset, E))
9246 if (!emitHLSLAggregateSplat(SrcT, SrcOffset, FieldType, E))
9248 if (!this->emitPopPtr(E))
9261template <
class Emitter>
9262unsigned Compiler<Emitter>::countHLSLFlatElements(
QualType Ty) {
9265 return VT->getNumElements();
9267 return MT->getNumElementsFlattened();
9271 return CAT->getZExtSize() * countHLSLFlatElements(CAT->getElementType());
9275 const Record *
R = getRecord(Ty);
9279 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
9281 Count += countHLSLFlatElements(BS.getType());
9283 for (
const Record::Field &F :
R->fields()) {
9284 if (F.isUnnamedBitField())
9286 Count += countHLSLFlatElements(F.Decl->getType());
9291 if (canClassify(Ty))
9300template <
class Emitter>
9301bool Compiler<Emitter>::emitHLSLFlattenAggregate(
9302 QualType SrcType,
unsigned SrcOffset,
9307 auto saveToLocal = [&](
PrimType T) ->
bool {
9308 unsigned Offset = allocateLocalPrimitive(E,
T,
true);
9309 if (!this->emitSetLocal(
T, Offset, E))
9311 Elements.push_back({Offset,
T});
9317 unsigned Offset = allocateLocalPrimitive(E,
PT_Ptr,
true);
9318 if (!this->emitSetLocal(
PT_Ptr, Offset, E))
9319 return std::nullopt;
9324 unsigned NumElems = 0;
9327 NumElems = VT->getNumElements();
9328 ElemType = VT->getElementType();
9330 NumElems = MT->getNumElementsFlattened();
9331 ElemType = MT->getElementType();
9334 PrimType ElemT = classifyPrim(ElemType);
9335 for (
unsigned I = 0; I != NumElems && Elements.size() < MaxElements; ++I) {
9336 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9338 if (!this->emitArrayElemPop(ElemT, I, E))
9340 if (!saveToLocal(ElemT))
9350 QualType ArrElemType = CAT->getElementType();
9351 unsigned ArrSize = CAT->getZExtSize();
9354 for (
unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
9355 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9357 if (!this->emitArrayElemPop(*ElemT, I, E))
9359 if (!saveToLocal(*ElemT))
9363 for (
unsigned I = 0; I != ArrSize && Elements.size() < MaxElements; ++I) {
9364 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9366 if (!this->emitConstUint32(I, E))
9368 if (!this->emitArrayElemPtrPopUint32(E))
9373 if (!emitHLSLFlattenAggregate(ArrElemType, *ElemPtrOffset, Elements,
9384 const Record *
R = getRecord(SrcType);
9388 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
9390 if (Elements.size() >= MaxElements)
9392 const Record::Base *B =
R->getBase(BS.getType());
9394 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9396 if (!this->emitGetPtrBasePop(B->Offset,
false, E))
9401 if (!emitHLSLFlattenAggregate(BS.getType(), *BasePtrOffset, Elements,
9407 for (
const Record::Field &F :
R->fields()) {
9408 if (Elements.size() >= MaxElements)
9410 if (F.isUnnamedBitField())
9413 QualType FieldType = F.Decl->getType();
9414 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
9416 if (!this->emitGetPtrFieldPop(F.Offset, E))
9420 if (!this->emitLoadPop(*FieldT, E))
9422 if (!saveToLocal(*FieldT))
9426 if (!FieldPtrOffset)
9428 if (!emitHLSLFlattenAggregate(FieldType, *FieldPtrOffset, Elements,
9444template <
class Emitter>
9445bool Compiler<Emitter>::emitHLSLConstructAggregate(
9451 const auto &Src = Elements[ElemIdx++];
9452 if (!this->emitGetLocal(Src.Type, Src.LocalOffset, E))
9454 return this->emitPrimCast(Src.Type, DestT, DestQT, E);
9458 unsigned NumElems = 0;
9461 NumElems = VT->getNumElements();
9462 ElemType = VT->getElementType();
9464 NumElems = MT->getNumElementsFlattened();
9465 ElemType = MT->getElementType();
9468 PrimType DestElemT = classifyPrim(ElemType);
9469 for (
unsigned I = 0; I != NumElems; ++I) {
9470 if (!loadAndCast(DestElemT, ElemType))
9472 if (!this->emitInitElem(DestElemT, I, E))
9482 QualType ArrElemType = CAT->getElementType();
9483 unsigned ArrSize = CAT->getZExtSize();
9486 for (
unsigned I = 0; I != ArrSize; ++I) {
9487 if (!loadAndCast(*ElemT, ArrElemType))
9489 if (!this->emitInitElem(*ElemT, I, E))
9493 for (
unsigned I = 0; I != ArrSize; ++I) {
9494 if (!this->emitConstUint32(I, E))
9496 if (!this->emitArrayElemPtrUint32(E))
9498 if (!emitHLSLConstructAggregate(ArrElemType, Elements, ElemIdx, E))
9500 if (!this->emitFinishInitPop(E))
9510 const Record *
R = getRecord(DestType);
9514 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(
R->getDecl())) {
9516 const Record::Base *B =
R->getBase(BS.getType());
9518 if (!this->emitGetPtrBase(B->Offset, E))
9520 if (!emitHLSLConstructAggregate(BS.getType(), Elements, ElemIdx, E))
9522 if (!this->emitFinishInitPop(E))
9527 for (
const Record::Field &F :
R->fields()) {
9528 if (F.isUnnamedBitField())
9531 QualType FieldType = F.Decl->getType();
9533 if (!loadAndCast(*FieldT, FieldType))
9535 if (F.isBitField()) {
9536 if (!this->emitInitBitField(*FieldT, F.Offset, F.bitWidth(), E))
9539 if (!this->emitInitField(*FieldT, F.Offset, E))
9543 if (!this->emitGetPtrField(F.Offset, E))
9545 if (!emitHLSLConstructAggregate(FieldType, Elements, ElemIdx, E))
9547 if (!this->emitPopPtr(E))
static bool visitAPValue(const APValue &Value, llvm::function_ref< bool(const APValue &)> Visitor)
static bool emit(llvm::SmallVectorImpl< std::byte > &Code, const T &Val)
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)
static CharUnits alignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
#define EMIT_ARITH_OP(OP)
static const Expr * stripDerivedToBaseCasts(const Expr *E)
static bool isTrivialMemoryOperation(const CXXMethodDecl *MD)
static const Expr * stripCheckedDerivedToBaseCasts(const Expr *E)
static bool hasTrivialDefaultCtorParent(const FieldDecl *FD)
static bool initNeedsOverridenLoc(const CXXCtorInitializer *Init)
const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. This ignores some c...
bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
unsigned ConvertBuiltinIDToX86BuiltinID(const ASTContext &Ctx, unsigned BuiltinOp)
Convert a builtin ID to the canonical x86 builtin ID the constant evaluators dispatch on in their x86...
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
APSInt & getComplexIntImag()
unsigned getStructNumFields() const
bool isComplexInt() const
APValue & getStructVirtualBase(unsigned i)
bool isMemberPointerToDerivedMember() const
unsigned getArrayInitializedElts() const
unsigned getStructNumBases() const
unsigned getStructNumVirtualBases() const
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
CharUnits & getLValueOffset()
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
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
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
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 isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
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.
Represents a C++26 reflect expression [expr.reflect].
ReflectionKind getKind() const
const void * getOpaqueValue() const
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
This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits One()
Construct a CharUnits quantity of one.
unsigned getValue() const
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
CompoundLiteralExpr - [C99 6.5.2.5].
const Expr * getInitializer() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Represents the specialization of a concept - evaluates to a prvalue of type bool.
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
Represents the canonical version of C arrays with a specified constant size.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
An expression that occurs in a constant context and the result of evaluating the expression.
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
ContinueStmt - This represents a continue.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInvalidDecl() const
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
bool isAnyOperatorNew() const
InitListExpr * getUpdater() const
DoStmt - This represents a 'do/while' stmt.
virtual bool TraverseStmt(MaybeConst< Stmt > *S)
Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...
const Expr * getBase() const
Represents a reference to emded data.
ChildElementIter< false > begin()
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool isValueDependent() const
Determines whether the value of this expression depends on.
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
An expression trait intrinsic.
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
Represents a member of a struct/union/class.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
DeclStmt * getConditionVariableDeclStmt()
If this ForStmt has a condition variable, return the faux DeclStmt associated with the creation of th...
const Expr * getSubExpr() const
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
bool isDefaulted() const
Whether this function is defaulted.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
Expr * getResultExpr()
Return the result expression of this controlling expression.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
bool isNegatedConsteval() const
DeclStmt * getConditionVariableDeclStmt()
If this IfStmt has a condition variable, return the faux DeclStmt associated with the creation of tha...
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
Describes an C or C++ initializer list.
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
ArrayRef< Expr * > inits() const
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompatibleWith(ClangABI Version) const
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
const Stmt * getNamedLoopOrSwitch() const
If this is a named break/continue, get the loop or switch statement that this targets.
APValue & getAsAPValue() const
Get the value of this MSGuidDecl as an APValue.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
LifetimeExtendedTemporaryDecl * getLifetimeExtendedTemporaryDecl()
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a C++ namespace alias.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
ObjCEncodeExpr, used for @encode in Objective-C.
QualType getEncodedType() const
SourceLocation getAtLoc() const
bool isExpressibleAsConstantInitializer() const
ObjCStringLiteral, used for Objective-C string literals i.e.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
unsigned getNumComponents() const
Helper class for OffsetOfExpr.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
@ Array
An index into an array.
Kind getKind() const
Determine what kind of offsetof node this is.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
ParenExpr - This represents a parenthesized expression, e.g.
const Expr * getSubExpr() const
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
[C99 6.4.2.2] - A predefined identifier such as func.
StringLiteral * getFunctionName()
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
bool isConstant(const ASTContext &Ctx) const
bool isConstQualified() const
Determine whether this type is const-qualified.
Represents a struct/union/class.
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Base for LValueReferenceType and RValueReferenceType.
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
bool isSatisfied() const
Whether or not the requires clause is satisfied.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
SourceLocation getLocation() const
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Represents an expression that computes the length of a parameter pack.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Represents a C++11 static_assert declaration.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
CompoundStmt * getSubStmt()
bool Visit(PTR(Stmt) S, ParamTys... P)
Stmt - This represents one statement.
StmtClass getStmtClass() const
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
uint32_t getCodeUnit(size_t I) const
Return the code unit at the given position.
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, ArrayRef< SourceLocation > Locs)
This is the "fully general" constructor that allows representation of strings formed from one or more...
unsigned getCharByteWidth() const
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Expr * getReplacement() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
DeclStmt * getConditionVariableDeclStmt()
If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Symbolic representation of typeid(T) for some type T.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
bool getBoolValue() const
bool isStoredAsComparisonResult() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
The base class of the type hierarchy.
bool isBooleanType() const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isConstantMatrixType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isAtomicType() const
EnumDecl * castAsEnumDecl() const
bool isStdByteType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isPointerOrReferenceType() const
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasBooleanRepresentation() const
Determine whether this type has a boolean representation – i.e., it is a boolean type,...
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represents C++ using-directive.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
bool isStaticDataMember() const
Determines whether this is a static data member.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
const Expr * getInit() const
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
DeclStmt * getConditionVariableDeclStmt()
If this WhileStmt has a condition variable, return the faux DeclStmt associated with the creation of ...
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
ArrayIndexScope(Compiler< Emitter > *Ctx, uint64_t Index)
A memory block, either on the stack or in the heap.
void invokeDtor()
Invokes the Destructor.
Compilation context for expressions.
llvm::SmallVector< InitLink > InitStack
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E)
bool VisitCXXDeleteExpr(const CXXDeleteExpr *E)
bool VisitOffsetOfExpr(const OffsetOfExpr *E)
bool visitContinueStmt(const ContinueStmt *S)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init, OptPrimType InitT)
Pointer to the array(not the element!) must be on the stack when calling this.
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E)
bool visitInitializerPop(const Expr *E)
Similar, but will also pop the pointer.
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
PrimType classifyPrim(QualType Ty) const
Classifies a known primitive type.
bool VisitTypeTraitExpr(const TypeTraitExpr *E)
bool VisitLambdaExpr(const LambdaExpr *E)
bool VisitMemberExpr(const MemberExpr *E)
llvm::DenseMap< const OpaqueValueExpr *, unsigned > OpaqueExprs
OpaqueValueExpr to location mapping.
bool VisitBinaryOperator(const BinaryOperator *E)
bool visitCXXExpansionStmtInstantiation(const CXXExpansionStmtInstantiation *S)
template for (auto x : {1, 2}) {}
bool visitAttributedStmt(const AttributedStmt *S)
bool VisitPackIndexingExpr(const PackIndexingExpr *E)
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
bool VisitCallExpr(const CallExpr *E)
std::optional< uint64_t > ArrayIndex
Current argument index. Needed to emit ArrayInitIndexExpr.
bool VisitPseudoObjectExpr(const PseudoObjectExpr *E)
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E)
bool visitAPValueInitializer(const APValue &Val, SourceInfo Info, QualType T, bool IsCompleteClass=true)
const Function * getFunction(const FunctionDecl *FD)
Returns a function for the given FunctionDecl.
bool VisitFixedPointBinOp(const BinaryOperator *E)
bool VisitCastExpr(const CastExpr *E)
bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E)
bool VisitFixedPointUnaryOperator(const UnaryOperator *E)
bool VisitComplexUnaryOperator(const UnaryOperator *E)
llvm::DenseMap< const SwitchCase *, LabelTy > CaseMap
bool VisitBlockExpr(const BlockExpr *E)
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
bool VisitLogicalBinOp(const BinaryOperator *E)
bool visitCompoundStmt(const CompoundStmt *S)
Context & Ctx
Current compilation context.
const VarDecl * InitializingDecl
bool visitDeclRef(const ValueDecl *D, const Expr *E)
Visit the given decl as if we have a reference to it.
bool visitBreakStmt(const BreakStmt *S)
bool visitExpr(const Expr *E, bool DestroyToplevelScope) override
bool visitForStmt(const ForStmt *S)
bool VisitDeclRefExpr(const DeclRefExpr *E)
bool VisitOpaqueValueExpr(const OpaqueValueExpr *E)
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E)
bool visitAPValue(const APValue &Val, PrimType ValType, SourceInfo Info)
Visit an APValue.
bool VisitStmtExpr(const StmtExpr *E)
bool VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *E)
bool VisitFixedPointLiteral(const FixedPointLiteral *E)
const FunctionDecl * CompilingFunction
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
VarCreationState visitVarDecl(const VarDecl *VD, const Expr *Init, bool Toplevel=false)
Creates and initializes a variable from the given decl.
VariableScope< Emitter > * VarScope
Current scope.
bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init, bool ConstantContext) override
Toplevel visitDeclAndReturn().
bool VisitCXXNewExpr(const CXXNewExpr *E)
bool VisitCompoundAssignOperator(const CompoundAssignOperator *E)
bool visit(const Expr *E) override
Evaluates an expression and places the result on the stack.
bool delegate(const Expr *E)
Just pass evaluation on to E.
bool visitLValueExpr(const Expr *E, bool DestroyToplevelScope) override
bool discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
CaseMap CaseLabels
Switch case mapping.
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
bool VisitCXXReflectExpr(const CXXReflectExpr *E)
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 registerRedecl(const VarDecl *VD, const APValue &V)
bool emitCleanup()
Emits scope cleanup instructions.
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E)
bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E)
bool visitInitializer(const Expr *E)
Compiles an initializer.
bool visitDtorCall(const VarDecl *VD, const APValue &Value) override
const Expr * SourceLocDefaultExpr
DefaultInit- or DefaultArgExpr, needed for SourceLocExpr.
bool VisitObjCArrayLiteral(const ObjCArrayLiteral *E)
UnsignedOrNone OptLabelTy
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E)
bool VisitPointerArithBinOp(const BinaryOperator *E)
Perform addition/subtraction of a pointer and an integer or subtraction of two pointers.
bool visitCallArgs(ArrayRef< const Expr * > Args, const FunctionDecl *FuncDecl, bool Activate, bool IsOperatorCall)
bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E)
bool visitDefaultStmt(const DefaultStmt *S)
bool VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
bool visitWithSubstitutions(const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This, const Expr *Condition) override
Evaluate the Condition as if it was in the body of Callee.
typename Emitter::LabelTy LabelTy
VarCreationState visitDecl(const VarDecl *VD)
bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E)
bool visitStmt(const Stmt *S)
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
bool VisitVectorUnaryOperator(const UnaryOperator *E)
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
bool VisitDesignatedInitUpdateExpr(const DesignatedInitUpdateExpr *E)
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
bool VisitRecoveryExpr(const RecoveryExpr *E)
bool VisitRequiresExpr(const RequiresExpr *E)
bool Initializing
Flag inidicating if we're initializing an already created variable.
bool visitReturnStmt(const ReturnStmt *RS)
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitChooseExpr(const ChooseExpr *E)
bool visitFunc(const FunctionDecl *F) override
bool visitCXXForRangeStmt(const CXXForRangeStmt *S)
bool visitCaseStmt(const CaseStmt *S)
bool VisitComplexBinOp(const BinaryOperator *E)
llvm::DenseMap< const ValueDecl *, Scope::Local > Locals
Variable to storage mapping.
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
bool VisitCXXTypeidExpr(const CXXTypeidExpr *E)
UnsignedOrNone allocateTemporary(const Expr *E)
bool VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinID)
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
OptPrimType ReturnType
Type of the expression returned by the function.
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
OptPrimType classify(const Expr *E) const
llvm::SmallVector< LabelInfo > LabelInfoStack
Stack of label information for loops and switch statements.
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
bool visitDoStmt(const DoStmt *S)
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitInitListExpr(const InitListExpr *E)
bool VisitVectorBinOp(const BinaryOperator *E)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
bool DiscardResult
Flag indicating if return value is to be discarded.
bool VisitEmbedExpr(const EmbedExpr *E)
UnsignedOrNone allocateLocal(DeclOrExpr Decl, QualType Ty=QualType(), ScopeKind=ScopeKind::Block)
Allocates a space storing a local given its type.
bool VisitConvertVectorExpr(const ConvertVectorExpr *E)
bool VisitCXXThisExpr(const CXXThisExpr *E)
bool VisitConstantExpr(const ConstantExpr *E)
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool visitSwitchStmt(const SwitchStmt *S)
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E)
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool visitAsLValue(const Expr *E)
unsigned allocateLocalPrimitive(DeclOrExpr Decl, PrimType Ty, bool IsConst, bool IsVolatile=false, ScopeKind SC=ScopeKind::Block)
Creates a local primitive value.
bool visitWhileStmt(const WhileStmt *S)
bool visitIfStmt(const IfStmt *IS)
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
bool canClassify(const Expr *E) const
bool VisitFloatingLiteral(const FloatingLiteral *E)
Program & P
Program to link to.
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
bool VariablesAreConstexprUnknown
bool VisitGNUNullExpr(const GNUNullExpr *E)
bool VisitImaginaryLiteral(const ImaginaryLiteral *E)
bool VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E)
bool visitCXXTryStmt(const CXXTryStmt *S)
static bool isUnevaluatedBuiltin(unsigned ID)
Unevaluated builtins don't get their arguments put on the stack automatically.
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Scope used to handle temporaries in toplevel variable declarations.
DeclScope(Compiler< Emitter > *Ctx, const VarDecl *VD)
Wrapper around fixed point types.
static FixedPoint zero(llvm::FixedPointSemantics Sem)
If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY.
bool hasThisPointer() const
bool hasRVO() const
Checks if the first argument is a RVO pointer.
InitLinkScope(Compiler< Emitter > *Ctx, InitLink &&Link)
Compiler< Emitter > * Ctx
InitStackScope(Compiler< Emitter > *Ctx, bool Active)
When generating code for e.g.
LocOverrideScope(Compiler< Emitter > *Ctx, SourceInfo NewValue, bool Enabled=true)
Generic scope for local variables.
UnsignedOrNone Idx
Index of the scope in the chain.
~LocalScope() override
Emit a Destroy op for this scope.
bool destroyLocals(const Expr *E=nullptr) override
Explicit destruction of local variables.
bool emitDestructors(const Expr *E=nullptr) override
void removeIfStoredOpaqueValue(const Scope::Local &Local)
void addLocal(Scope::Local Local) override
void removeStoredOpaqueValues()
LocalScope(Compiler< Emitter > *Ctx, ScopeKind Kind=ScopeKind::Block)
Sets the context for break/continue statements.
typename Compiler< Emitter >::LabelTy LabelTy
typename Compiler< Emitter >::OptLabelTy OptLabelTy
typename Compiler< Emitter >::LabelInfo LabelInfo
LoopScope(Compiler< Emitter > *Ctx, const Stmt *Name, LabelTy BreakLabel, LabelTy ContinueLabel)
PrimType value_or(PrimType PT) const
Scope used to handle initialization methods.
OptionScope(Compiler< Emitter > *Ctx, bool NewDiscardResult, bool NewInitializing, bool NewToLValue)
Root constructor, compiling or discarding primitives.
Context to manage declaration lifetimes.
Structure/Class descriptor.
bool isUnion() const
Checks if the record is a union.
const Field * getField(unsigned I) const
const Base * getBaseOrNull(const RecordDecl *RD) const
bool hasTrivialDtor() const
Returns true for anonymous unions and records with no destructor or for those with a trivial destruct...
const Base * findVirtualBase(const RecordDecl *RD) const
Returns a virtual base descriptor.
Describes the statement/declaration an opcode was generated from.
const Expr * asExpr() const
SourceLocScope(Compiler< Emitter > *Ctx, const Expr *DefaultExpr)
typename Compiler< Emitter >::LabelTy LabelTy
typename Compiler< Emitter >::OptLabelTy OptLabelTy
typename Compiler< Emitter >::LabelInfo LabelInfo
typename Compiler< Emitter >::CaseMap CaseMap
SwitchScope(Compiler< Emitter > *Ctx, const Stmt *Name, CaseMap &&CaseLabels, LabelTy BreakLabel, OptLabelTy DefaultLabel)
Scope chain managing the variable lifetimes.
void addForScopeKind(const Scope::Local &Local, ScopeKind Kind)
Like addExtended, but adds to the nearest scope of the given kind.
bool LocalsAlwaysEnabled
Whether locals added to this scope are enabled by default.
Compiler< Emitter > * Ctx
Compiler instance.
virtual bool emitDestructors(const Expr *E=nullptr)
VariableScope(Compiler< Emitter > *Ctx, ScopeKind Kind=ScopeKind::Block)
virtual bool destroyLocals(const Expr *E=nullptr)
virtual void addLocal(Scope::Local Local)
VariableScope * Parent
Link to the parent scope.
ScopeKind getKind() const
VariableScope * getParent() const
uint16_t getPointerAuthTypeDiscriminator(CodeGenModule &CGM, QualType FunctionType)
Return a type discriminator for the given function type.
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)
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)
static bool exceedsArraySizeLimit(const LangOptions &LangOpts, uint64_t NumElems)
Whether the CheckArraySize op rejects an array with NumElems elements.
bool Init(InterpState &S, CodePtr OpPC)
bool DefaultInit(InterpState &S, CodePtr OpPC, const CXXConstructorDecl *Ctor)
bool Mul(InterpState &S, CodePtr OpPC)
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
bool Inc(InterpState &S, CodePtr OpPC, bool CanOverflow)
1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...
bool Add(InterpState &S, CodePtr OpPC)
llvm::BitVector collectNonNullArgs(const FunctionDecl *F, ArrayRef< const Expr * > Args)
constexpr bool isIntegerType(PrimType T)
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
bool hasSpecificAttr(const Container &container)
@ Success
Annotation was successful.
@ Link
'link' clause, allowed on 'declare' construct.
DynamicRecursiveASTVisitorBase< true > ConstDynamicRecursiveASTVisitor
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
@ Result
The result type of a method or function.
OptionalUnsigned< unsigned > UnsignedOrNone
const FunctionProtoType * T
U cast(CodeGen::Address addr)
int const char * function
llvm::APSInt getIntValue() const
Get the constant integer value used by this variable to represent the comparison category result type...
EvalResult is a struct with detailed info about an evaluated expression.
const ValueDecl * asValueDecl() const
const Expr * asExpr() const
Describes a memory block created by an allocation site.
unsigned getNumElems() const
Returns the number of elements stored in the block.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
QualType getElemQualType() const
bool hasTrivialDtor() const
Whether variables of this descriptor need their destructor called or not.
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
const Descriptor *const ElemDesc
Descriptor of the array element.
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
PrimType getPrimType() const
bool isRecord() const
Checks if the descriptor is of a record.
const Record *const ElemRecord
Pointer to the record, if block contains records.
bool isArray() const
Checks if the descriptor is of an array.
Descriptor used for global variables.
GlobalInitState InitState
static InitLink InitList()
static InitLink Elem(unsigned Index)
bool emit(Compiler< Emitter > *Ctx, const Expr *E) const
static InitLink Field(unsigned Offset)
static InitLink Base(unsigned Offset)
static InitLink Decl(const ValueDecl *D)
static InitLink Temp(unsigned Offset)
Information about a local's storage.
State encapsulating if a the variable creation has been successful, unsuccessful, or no variable has ...
static VarCreationState NotCreated()