19#include "llvm/Support/SaveAndRestore.h"
30 if (
const auto *CE = dyn_cast_if_present<ConstantExpr>(E);
31 CE && CE->hasAPValueResult() &&
33 return CE->getResultAsAPSInt().getBoolValue();
44 OldInitializingDecl(
Ctx->InitializingDecl) {
45 Ctx->InitializingDecl = VD;
50 this->
Ctx->InitializingDecl = OldInitializingDecl;
51 this->
Ctx->InitStack.pop_back();
64 bool NewInitializing,
bool NewToLValue)
65 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
66 OldInitializing(Ctx->
Initializing), OldToLValue(Ctx->ToLValue) {
67 Ctx->DiscardResult = NewDiscardResult;
68 Ctx->Initializing = NewInitializing;
69 Ctx->ToLValue = NewToLValue;
73 Ctx->DiscardResult = OldDiscardResult;
74 Ctx->Initializing = OldInitializing;
75 Ctx->ToLValue = OldToLValue;
82 bool OldDiscardResult;
87template <
class Emitter>
91 return Ctx->emitThis(E);
94 return Ctx->emitGetPtrFieldPop(
Offset, E);
96 return Ctx->emitGetPtrLocal(
Offset, E);
100 if (!Ctx->emitConstUint32(
Offset, E))
102 return Ctx->emitArrayElemPtrPopUint32(E);
104 return Ctx->emitRVOPtr(E);
108 llvm_unreachable(
"Unhandled InitLink kind");
124 for (
const LabelInfo &LI : Ctx->LabelInfoStack)
125 assert(LI.Name != Name);
128 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel, ContinueLabel,
149 : Ctx(Ctx), OldCaseLabels(
std::move(this->Ctx->CaseLabels)) {
151 for (
const LabelInfo &LI : Ctx->LabelInfoStack)
152 assert(LI.Name != Name);
155 this->Ctx->CaseLabels = std::move(CaseLabels);
156 this->Ctx->LabelInfoStack.emplace_back(Name, BreakLabel,
158 DefaultLabel, Ctx->VarScope);
162 this->Ctx->CaseLabels = std::move(OldCaseLabels);
163 this->Ctx->LabelInfoStack.pop_back();
168 CaseMap OldCaseLabels;
174 Ctx->InStmtExpr =
true;
192 : Ctx(Ctx), OldFlag(Ctx->LocOverride), Enabled(Enabled) {
195 Ctx->LocOverride = NewValue;
200 Ctx->LocOverride = OldFlag;
205 std::optional<SourceInfo> OldFlag;
212template <
class Emitter>
220 case CK_LValueToRValue: {
231 if (
const auto *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
237 if (
auto GlobalIndex =
P.getGlobal(D))
238 return this->emitGetGlobal(*SubExprT, *GlobalIndex, CE);
239 }
else if (
auto It =
Locals.find(D); It !=
Locals.end()) {
240 return this->emitGetLocal(*SubExprT, It->second.Offset, CE);
241 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
242 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
243 return this->emitGetParam(*SubExprT, It->second.Offset, CE);
255 if (!this->emitGetPtrLocal(*LocalIndex, CE))
259 if (!this->
visit(SubExpr))
263 return this->emitLoadPop(*SubExprT, CE);
268 return this->emitMemcpy(CE);
271 case CK_DerivedToBaseMemberPointer: {
280 ->getMostRecentCXXRecordDecl();
282 const CXXRecordDecl *ToDecl = B->getType()->getAsCXXRecordDecl();
283 unsigned DerivedOffset =
Ctx.collectBaseOffset(ToDecl, CurDecl);
285 if (!this->emitCastMemberPtrBasePop(DerivedOffset, ToDecl, CE))
293 case CK_BaseToDerivedMemberPointer: {
302 ->getMostRecentCXXRecordDecl();
306 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
308 PathI != PathE; ++PathI) {
309 const CXXRecordDecl *ToDecl = (*PathI)->getType()->getAsCXXRecordDecl();
310 unsigned DerivedOffset =
Ctx.collectBaseOffset(CurDecl, ToDecl);
312 if (!this->emitCastMemberPtrDerivedPop(-DerivedOffset, ToDecl, CE))
319 ->getMostRecentCXXRecordDecl();
320 assert(ToDecl != CurDecl);
321 unsigned DerivedOffset =
Ctx.collectBaseOffset(CurDecl, ToDecl);
323 if (!this->emitCastMemberPtrDerivedPop(-DerivedOffset, ToDecl, CE))
329 case CK_UncheckedDerivedToBase:
330 case CK_DerivedToBase: {
335 if (
const auto *PT = dyn_cast<PointerType>(Ty))
336 return PT->getPointeeType()->getAsCXXRecordDecl();
337 return Ty->getAsCXXRecordDecl();
344 if (B->isVirtual()) {
345 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))
347 CurType = B->getType();
349 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
350 if (!this->emitGetPtrBasePop(
353 CurType = B->getType();
360 case CK_BaseToDerived: {
363 unsigned DerivedOffset =
369 return this->emitGetPtrDerivedPop(DerivedOffset,
374 case CK_FloatingCast: {
379 if (!this->
visit(SubExpr))
381 const auto *TargetSemantics = &
Ctx.getFloatSemantics(CE->
getType());
385 case CK_IntegralToFloating: {
388 if (!this->
visit(SubExpr))
390 const auto *TargetSemantics = &
Ctx.getFloatSemantics(CE->
getType());
391 return this->emitCastIntegralFloating(
392 classifyPrim(SubExpr), TargetSemantics, getFPOptions(CE), CE);
395 case CK_FloatingToBoolean: {
399 if (
const auto *FL = dyn_cast<FloatingLiteral>(SubExpr))
400 return this->emitConstBool(FL->getValue().isNonZero(), CE);
401 if (!this->
visit(SubExpr))
403 return this->emitCastFloatingIntegralBool(getFPOptions(CE), CE);
406 case CK_FloatingToIntegral: {
409 if (!this->
visit(SubExpr))
413 return this->emitCastFloatingIntegralAP(
Ctx.getBitWidth(CE->
getType()),
414 getFPOptions(CE), CE);
416 return this->emitCastFloatingIntegralAPS(
Ctx.getBitWidth(CE->
getType()),
417 getFPOptions(CE), CE);
419 return this->emitCastFloatingIntegral(ToT, getFPOptions(CE), CE);
422 case CK_NullToPointer:
423 case CK_NullToMemberPointer: {
428 if (!PointeeType.
isNull()) {
430 Desc =
P.createDescriptor(SubExpr, *T);
432 Desc =
P.createDescriptor(SubExpr, PointeeType.
getTypePtr(),
436 uint64_t Val =
Ctx.getASTContext().getTargetNullPointerValue(CE->
getType());
440 case CK_PointerToIntegral: {
441 if (!this->
visit(SubExpr))
447 if (!this->emitDecayPtr(FromT,
PT_Ptr, CE))
453 return this->emitCastPointerIntegralAP(
Ctx.getBitWidth(CE->
getType()),
456 return this->emitCastPointerIntegralAPS(
Ctx.getBitWidth(CE->
getType()),
458 return this->emitCastPointerIntegral(T, CE);
461 case CK_ArrayToPointerDecay: {
462 if (!this->
visit(SubExpr))
464 return this->emitArrayDecay(CE);
467 case CK_IntegralToPointer: {
469 assert(IntType->isIntegralOrEnumerationType());
470 if (!this->
visit(SubExpr))
478 Desc =
P.createDescriptor(SubExpr, *T);
485 if (!this->emitGetIntPtr(T, Desc, CE))
493 return this->emitDecayPtr(
PT_Ptr, DestPtrT, CE);
496 case CK_AtomicToNonAtomic:
497 case CK_ConstructorConversion:
498 case CK_FunctionToPointerDecay:
499 case CK_NonAtomicToAtomic:
501 case CK_UserDefinedConversion:
502 case CK_AddressSpaceConversion:
503 case CK_CPointerToObjCPointerCast:
520 return this->emitBuiltinBitCast(CE);
535 if (!this->
visit(SubExpr))
543 return this->emitFnPtrCast(CE);
550 if (!this->
visit(SubExpr))
552 return this->emitDecayPtr(*FromT, *ToT, CE);
554 case CK_IntegralToBoolean:
555 case CK_FixedPointToBoolean: {
561 if (
const auto *IL = dyn_cast<IntegerLiteral>(SubExpr))
562 return this->emitConst(IL->getValue(), CE);
563 if (!this->
visit(SubExpr))
568 case CK_BooleanToSignedIntegral:
569 case CK_IntegralCast: {
576 if (
const auto *IL = dyn_cast<IntegerLiteral>(SubExpr)) {
581 if (!this->emitConst(IL->getValue(), SubExpr))
584 if (!this->
visit(SubExpr))
592 if (!ED->isFixed()) {
593 if (!this->emitCheckEnumValue(*FromT, ED, CE))
599 if (!this->emitCastAP(*FromT,
Ctx.getBitWidth(CE->
getType()), CE))
602 if (!this->emitCastAPS(*FromT,
Ctx.getBitWidth(CE->
getType()), CE))
607 if (!this->emitCast(*FromT, *ToT, CE))
610 if (CE->
getCastKind() == CK_BooleanToSignedIntegral)
611 return this->emitNeg(*ToT, CE);
615 case CK_PointerToBoolean:
616 case CK_MemberPointerToBoolean: {
619 if (!this->
visit(SubExpr))
621 return this->emitIsNonNull(PtrT, CE);
624 case CK_IntegralComplexToBoolean:
625 case CK_FloatingComplexToBoolean: {
626 if (!this->
visit(SubExpr))
628 return this->emitComplexBoolCast(SubExpr);
631 case CK_IntegralComplexToReal:
632 case CK_FloatingComplexToReal:
633 return this->emitComplexReal(SubExpr);
635 case CK_IntegralRealToComplex:
636 case CK_FloatingRealToComplex: {
643 if (!this->emitGetPtrLocal(*LocalIndex, CE))
652 if (!this->visitZeroInitializer(T, SubExpr->
getType(), SubExpr))
654 return this->emitInitElem(T, 1, SubExpr);
657 case CK_IntegralComplexCast:
658 case CK_FloatingComplexCast:
659 case CK_IntegralComplexToFloatingComplex:
660 case CK_FloatingComplexToIntegralComplex: {
667 if (!this->emitGetPtrLocal(*LocalIndex, CE))
674 unsigned SubExprOffset =
676 if (!this->
visit(SubExpr))
678 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, CE))
686 for (
unsigned I = 0; I != 2; ++I) {
687 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, CE))
689 if (!this->emitArrayElemPop(SourceElemT, I, CE))
693 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
697 if (!this->emitInitElem(DestElemT, I, CE))
703 case CK_VectorSplat: {
712 if (!this->emitGetPtrLocal(*LocalIndex, CE))
718 unsigned ElemOffset =
722 if (!this->
visit(SubExpr))
727 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
730 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
731 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
733 if (!this->emitInitElem(ElemT, I, CE))
740 case CK_HLSLVectorTruncation: {
745 if (!this->
visit(SubExpr))
747 return this->emitArrayElemPop(*ResultT, 0, CE);
756 if (!this->emitGetPtrLocal(*LocalIndex, CE))
761 if (!this->
visit(SubExpr))
763 return this->emitCopyArray(classifyVectorElementType(CE->
getType()), 0, 0,
767 case CK_IntegralToFixedPoint: {
768 if (!this->
visit(SubExpr))
772 Ctx.getASTContext().getFixedPointSemantics(CE->
getType()).toOpaqueInt();
776 case CK_FloatingToFixedPoint: {
777 if (!this->
visit(SubExpr))
781 Ctx.getASTContext().getFixedPointSemantics(CE->
getType()).toOpaqueInt();
782 return this->emitCastFloatingFixedPoint(Sem, CE);
784 case CK_FixedPointToFloating: {
785 if (!this->
visit(SubExpr))
787 const auto *TargetSemantics = &
Ctx.getFloatSemantics(CE->
getType());
788 return this->emitCastFixedPointFloating(TargetSemantics, CE);
790 case CK_FixedPointToIntegral: {
791 if (!this->
visit(SubExpr))
795 case CK_FixedPointCast: {
796 if (!this->
visit(SubExpr))
799 Ctx.getASTContext().getFixedPointSemantics(CE->
getType()).toOpaqueInt();
800 return this->emitCastFixedPoint(Sem, CE);
811 case CK_LValueBitCast:
814 case CK_HLSLArrayRValue: {
821 if (!this->emitGetPtrLocal(*LocalIndex, CE))
824 if (!this->
visit(SubExpr))
826 return this->emitMemcpy(CE);
829 case CK_HLSLMatrixTruncation: {
834 if (!this->
visit(SubExpr))
836 return this->emitArrayElemPop(*ResultT, 0, CE);
845 if (!this->emitGetPtrLocal(*LocalIndex, CE))
850 if (!this->
visit(SubExpr))
852 return this->emitCopyArray(classifyMatrixElementType(SubExpr->
getType()), 0,
856 case CK_HLSLAggregateSplatCast: {
867 NumElems = VT->getNumElements();
868 DestElemType = VT->getElementType();
870 NumElems = MT->getNumElementsFlattened();
871 DestElemType = MT->getElementType();
881 if (!this->emitGetPtrLocal(*LocalIndex, CE))
889 if (!this->
visit(SubExpr))
891 if (SrcElemT != DestElemT) {
892 if (!this->emitPrimCast(SrcElemT, DestElemT, DestElemType, CE))
895 if (!this->emitSetLocal(DestElemT, SrcOffset, CE))
898 for (
unsigned I = 0; I != NumElems; ++I) {
899 if (!this->emitGetLocal(DestElemT, SrcOffset, CE))
901 if (!this->emitInitElem(DestElemT, I, CE))
907 case CK_HLSLElementwiseCast: {
920 const auto *SrcCAT = SrcAT ? dyn_cast<ConstantArrayType>(SrcAT) :
nullptr;
926 const auto *DestCAT =
927 DestAT ? dyn_cast<ConstantArrayType>(DestAT) :
nullptr;
930 if (!SrcVT && !SrcMT && !SrcCAT)
932 if (!DestVT && !DestMT && !DestCAT && !DestPT)
935 unsigned SrcNumElems;
938 SrcNumElems = SrcVT->getNumElements();
941 SrcNumElems = SrcMT->getNumElementsFlattened();
944 SrcNumElems = SrcCAT->getZExtSize();
950 if (!this->
visit(SubExpr))
952 if (!this->emitArrayElemPop(SrcElemT, 0, CE))
954 if (SrcElemT != *DestPT) {
955 if (!this->emitPrimCast(SrcElemT, *DestPT, DestType, CE))
961 unsigned DestNumElems;
965 DestNumElems = DestVT->getNumElements();
966 DestElemType = DestVT->getElementType();
968 DestNumElems = DestMT->getNumElementsFlattened();
970 }
else if (DestCAT) {
971 DestNumElems = DestCAT->getZExtSize();
972 DestElemType = DestCAT->getElementType();
980 if (!this->emitGetPtrLocal(*LocalIndex, CE))
986 if (!this->
visit(SubExpr))
988 if (!this->emitSetLocal(
PT_Ptr, SrcOffset, CE))
991 unsigned NumElems = std::min(SrcNumElems, DestNumElems);
992 for (
unsigned I = 0; I != NumElems; ++I) {
993 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, CE))
995 if (!this->emitArrayElemPop(SrcElemT, I, CE))
997 if (SrcElemT != DestElemT) {
998 if (!this->emitPrimCast(SrcElemT, DestElemT, DestElemType, CE))
1001 if (!this->emitInitElem(DestElemT, I, CE))
1008 return this->emitInvalid(CE);
1010 llvm_unreachable(
"Unhandled clang::CastKind enum");
1013template <
class Emitter>
1015 return this->emitBuiltinBitCast(E);
1018template <
class Emitter>
1023 return this->emitConst(
LE->getValue(),
LE);
1026template <
class Emitter>
1032 return this->emitFloat(F, E);
1035template <
class Emitter>
1045 if (!this->emitGetPtrLocal(*LocalIndex, E))
1052 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
1054 if (!this->emitInitElem(SubExprT, 0, SubExpr))
1059template <
class Emitter>
1067 auto Sem =
Ctx.getASTContext().getFixedPointSemantics(E->
getType());
1072template <
class Emitter>
1077template <
class Emitter>
1104 return this->emitComplexComparison(LHS, RHS, BO);
1109 if (!this->
visit(LHS))
1112 if (!this->
visit(RHS))
1115 if (!this->emitToMemberPtr(BO))
1121 if (!this->emitCastMemberPtrPtr(BO))
1138 Ctx.getASTContext().CompCategories.lookupInfoForType(BO->
getType());
1144 if (!this->emitGetPtrLocal(*ResultIndex, BO))
1151 return this->emitCMP3(*
LT, CmpInfo, BO);
1154 if (!
LT || !RT || !T)
1164 return this->visitAssignment(LHS, RHS, BO);
1171 auto MaybeCastToBool = [
this, T, BO](
bool Result) {
1175 return this->emitPopBool(BO);
1177 return this->emitCast(
PT_Bool, *T, BO);
1181 auto Discard = [
this, T, BO](
bool Result) {
1189 return MaybeCastToBool(this->emitEQ(*
LT, BO));
1191 return MaybeCastToBool(this->emitNE(*
LT, BO));
1193 return MaybeCastToBool(this->emitLT(*
LT, BO));
1195 return MaybeCastToBool(this->emitLE(*
LT, BO));
1197 return MaybeCastToBool(this->emitGT(*
LT, BO));
1199 return MaybeCastToBool(this->emitGE(*
LT, BO));
1202 return Discard(this->emitSubf(getFPOptions(BO), BO));
1203 return Discard(this->emitSub(*T, BO));
1206 return Discard(this->emitAddf(getFPOptions(BO), BO));
1207 return Discard(this->emitAdd(*T, BO));
1210 return Discard(this->emitMulf(getFPOptions(BO), BO));
1211 return Discard(this->emitMul(*T, BO));
1213 return Discard(this->emitRem(*T, BO));
1216 return Discard(this->emitDivf(getFPOptions(BO), BO));
1217 return Discard(this->emitDiv(*T, BO));
1219 return Discard(this->emitBitAnd(*T, BO));
1221 return Discard(this->emitBitOr(*T, BO));
1223 return Discard(this->emitShl(*
LT, *RT, BO));
1225 return Discard(this->emitShr(*
LT, *RT, BO));
1227 return Discard(this->emitBitXor(*T, BO));
1230 llvm_unreachable(
"Already handled earlier");
1235 llvm_unreachable(
"Unhandled binary op");
1240template <
class Emitter>
1246 if ((Op != BO_Add && Op != BO_Sub) ||
1257 auto visitAsPointer = [&](
const Expr *E,
PrimType T) ->
bool {
1258 if (!this->
visit(E))
1261 return this->emitDecayPtr(T,
PT_Ptr, E);
1270 if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *
LT))
1278 ElemTypeSize =
Ctx.getASTContext().getTypeSizeInChars(ElemType);
1281 if (!this->emitSubPtr(IntT, ElemTypeSize.
isZero(), E))
1288 if (!visitAsPointer(RHS, *RT))
1290 if (!this->
visit(LHS))
1294 if (!visitAsPointer(LHS, *
LT))
1296 if (!this->
visit(RHS))
1307 if (!this->emitAddOffset(OffsetType, E))
1311 if (!this->emitSubOffset(OffsetType, E))
1328template <
class Emitter>
1338 LabelTy LabelTrue = this->getLabel();
1339 LabelTy LabelEnd = this->getLabel();
1343 if (!this->jumpTrue(LabelTrue))
1348 if (!this->jump(LabelEnd))
1351 this->emitLabel(LabelTrue);
1352 this->emitConstBool(
true, E);
1353 this->fallthrough(LabelEnd);
1354 this->emitLabel(LabelEnd);
1357 assert(Op == BO_LAnd);
1360 LabelTy LabelFalse = this->getLabel();
1361 LabelTy LabelEnd = this->getLabel();
1365 if (!this->jumpFalse(LabelFalse))
1370 if (!this->jump(LabelEnd))
1373 this->emitLabel(LabelFalse);
1374 this->emitConstBool(
false, E);
1375 this->fallthrough(LabelEnd);
1376 this->emitLabel(LabelEnd);
1380 return this->emitPopBool(E);
1385 return this->emitCast(
PT_Bool, *T, E);
1389template <
class Emitter>
1396 if (!this->emitGetPtrLocal(*LocalIndex, E))
1405 PrimType ResultElemT = this->classifyComplexElementType(E->
getType());
1406 unsigned ResultOffset = ~0u;
1412 if (!this->emitDupPtr(E))
1414 if (!this->emitSetLocal(
PT_Ptr, ResultOffset, E))
1419 LHSType = AT->getValueType();
1422 RHSType = AT->getValueType();
1431 if (Op == BO_Mul && LHSIsComplex && RHSIsComplex) {
1436 if (!this->
visit(LHS))
1438 if (!this->
visit(RHS))
1440 if (!this->emitMulc(ElemT, E))
1443 return this->emitPopPtr(E);
1447 if (Op == BO_Div && RHSIsComplex) {
1454 if (!LHSIsComplex) {
1459 LHSOffset = *LocalIndex;
1461 if (!this->emitGetPtrLocal(LHSOffset, E))
1464 if (!this->
visit(LHS))
1467 if (!this->emitInitElem(ElemT, 0, E))
1470 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1472 if (!this->emitInitElem(ElemT, 1, E))
1475 if (!this->
visit(LHS))
1479 if (!this->
visit(RHS))
1481 if (!this->emitDivc(ElemT, E))
1484 return this->emitPopPtr(E);
1491 if (!this->
visit(LHS))
1493 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
1498 if (!this->
visit(LHS))
1500 if (!this->emitSetLocal(LHST, LHSOffset, E))
1508 if (!this->
visit(RHS))
1510 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
1515 if (!this->
visit(RHS))
1517 if (!this->emitSetLocal(RHST, RHSOffset, E))
1524 auto loadComplexValue = [
this](
bool IsComplex,
bool LoadZero,
1525 unsigned ElemIndex,
unsigned Offset,
1526 const Expr *E) ->
bool {
1528 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
1530 return this->emitArrayElemPop(classifyComplexElementType(E->
getType()),
1533 if (ElemIndex == 0 || !LoadZero)
1540 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
1543 if (!this->emitGetLocal(
PT_Ptr, ResultOffset, E))
1550 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1553 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1556 if (!this->emitAddf(getFPOptions(E), E))
1559 if (!this->emitAdd(ResultElemT, E))
1564 if (!loadComplexValue(LHSIsComplex,
true, ElemIndex, LHSOffset, LHS))
1567 if (!loadComplexValue(RHSIsComplex,
true, ElemIndex, RHSOffset, RHS))
1570 if (!this->emitSubf(getFPOptions(E), E))
1573 if (!this->emitSub(ResultElemT, E))
1578 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1581 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1585 if (!this->emitMulf(getFPOptions(E), E))
1588 if (!this->emitMul(ResultElemT, E))
1593 assert(!RHSIsComplex);
1594 if (!loadComplexValue(LHSIsComplex,
false, ElemIndex, LHSOffset, LHS))
1597 if (!loadComplexValue(RHSIsComplex,
false, ElemIndex, RHSOffset, RHS))
1601 if (!this->emitDivf(getFPOptions(E), E))
1604 if (!this->emitDiv(ResultElemT, E))
1615 if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))
1618 if (!this->emitPop(ResultElemT, E))
1623 return this->emitPopPtr(E);
1629template <
class Emitter>
1634 "Comma op should be handled in VisitBinaryOperator");
1648 if (!this->emitGetPtrLocal(*LocalIndex, E))
1662 assert(
Ctx.getASTContext().hasSameUnqualifiedType(
1665 if (!this->
visit(LHS))
1667 if (!this->
visit(RHS))
1669 if (!this->emitCopyArray(ElemT, 0, 0, VecTy->getNumElements(), E))
1672 return this->emitPopPtr(E);
1677 unsigned LHSOffset =
1679 if (!this->
visit(LHS))
1681 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
1685 unsigned RHSOffset =
1687 if (!this->
visit(RHS))
1689 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
1701 if (NeedIntPromot) {
1703 Ctx.getASTContext().getPromotedIntegerType(
Ctx.getASTContext().BoolTy);
1708 auto getElem = [=](
unsigned Offset,
PrimType ElemT,
unsigned Index) {
1709 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
1711 if (!this->emitArrayElemPop(ElemT, Index, E))
1714 if (!this->emitPrimCast(ElemT,
PT_Bool,
Ctx.getASTContext().BoolTy, E))
1716 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(), E))
1718 }
else if (NeedIntPromot) {
1719 if (!this->emitPrimCast(ElemT, PromotT, PromotTy, E))
1725#define EMIT_ARITH_OP(OP) \
1727 if (ElemT == PT_Float) { \
1728 if (!this->emit##OP##f(getFPOptions(E), E)) \
1731 if (!this->emit##OP(ElemT, E)) \
1737 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
1738 if (!getElem(LHSOffset, ElemT, I))
1740 if (!getElem(RHSOffset, RHSElemT, I))
1752 if (!this->emitRem(ElemT, E))
1756 if (!this->emitBitAnd(OpT, E))
1760 if (!this->emitBitOr(OpT, E))
1764 if (!this->emitBitXor(OpT, E))
1768 if (!this->emitShl(OpT, RHSElemT, E))
1772 if (!this->emitShr(OpT, RHSElemT, E))
1776 if (!this->emitEQ(ElemT, E))
1780 if (!this->emitNE(ElemT, E))
1784 if (!this->emitLE(ElemT, E))
1788 if (!this->emitLT(ElemT, E))
1792 if (!this->emitGE(ElemT, E))
1796 if (!this->emitGT(ElemT, E))
1801 if (!this->emitBitAnd(ResultElemT, E))
1806 if (!this->emitBitOr(ResultElemT, E))
1810 return this->emitInvalid(E);
1819 if (!this->emitPrimCast(
PT_Bool, ResultElemT, VecTy->getElementType(), E))
1821 if (!this->emitNeg(ResultElemT, E))
1827 if (NeedIntPromot &&
1828 !this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(), E))
1832 if (!this->emitInitElem(ResultElemT, I, E))
1841template <
class Emitter>
1851 auto LHSSemaInt = LHSSema.toOpaqueInt();
1853 auto RHSSemaInt = RHSSema.toOpaqueInt();
1855 if (!this->
visit(LHS))
1863 if (!this->
visit(RHS))
1872 auto ConvertResult = [&](
bool R) ->
bool {
1876 auto CommonSema = LHSSema.getCommonSemantics(RHSSema).toOpaqueInt();
1877 if (ResultSema != CommonSema)
1878 return this->emitCastFixedPoint(ResultSema, E);
1882 auto MaybeCastToBool = [&](
bool Result) {
1887 return this->emitPop(T, E);
1889 return this->emitCast(
PT_Bool, T, E);
1895 return MaybeCastToBool(this->emitEQFixedPoint(E));
1897 return MaybeCastToBool(this->emitNEFixedPoint(E));
1899 return MaybeCastToBool(this->emitLTFixedPoint(E));
1901 return MaybeCastToBool(this->emitLEFixedPoint(E));
1903 return MaybeCastToBool(this->emitGTFixedPoint(E));
1905 return MaybeCastToBool(this->emitGEFixedPoint(E));
1907 return ConvertResult(this->emitAddFixedPoint(E));
1909 return ConvertResult(this->emitSubFixedPoint(E));
1911 return ConvertResult(this->emitMulFixedPoint(E));
1913 return ConvertResult(this->emitDivFixedPoint(E));
1915 return ConvertResult(this->emitShiftFixedPoint(
true, E));
1917 return ConvertResult(this->emitShiftFixedPoint(
false, E));
1920 return this->emitInvalid(E);
1923 llvm_unreachable(
"unhandled binop opcode");
1926template <
class Emitter>
1935 if (!this->
visit(SubExpr))
1937 return this->emitNegFixedPoint(E);
1942 llvm_unreachable(
"Unhandled unary opcode");
1945template <
class Emitter>
1954 return this->visitZeroInitializer(*T, QT, E);
1962 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1963 CXXRD && CXXRD->getNumVBases() > 0) {
1973 return this->visitZeroRecordInitializer(R, E);
1980 return this->visitZeroArrayInitializer(QT, E);
1984 QualType ElemQT = ComplexTy->getElementType();
1986 for (
unsigned I = 0; I < 2; ++I) {
1987 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1989 if (!this->emitInitElem(ElemT, I, E))
1996 unsigned NumVecElements = VecT->getNumElements();
1997 QualType ElemQT = VecT->getElementType();
2000 for (
unsigned I = 0; I < NumVecElements; ++I) {
2001 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2003 if (!this->emitInitElem(ElemT, I, E))
2010 unsigned NumElems = MT->getNumElementsFlattened();
2011 QualType ElemQT = MT->getElementType();
2014 for (
unsigned I = 0; I != NumElems; ++I) {
2015 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2017 if (!this->emitInitElem(ElemT, I, E))
2026template <
class Emitter>
2039 for (
const Expr *SubExpr : {LHS, RHS}) {
2040 if (!this->
visit(SubExpr)) {
2047 if (SubExpr ==
Base &&
Base->getType()->isPointerType()) {
2048 if (!this->emitExpandPtr(E))
2059 return this->emitError(E);
2062 if (!this->emitFlip(
PT_Ptr, *IndexT, E))
2066 if (!this->emitArrayElemPtrPop(*IndexT, E))
2069 return this->emitPopPtr(E);
2075 return this->emitLoadPop(*T, E);
2078template <
class Emitter>
2080 const Expr *ArrayFiller,
const Expr *E) {
2085 QT = AT->getValueType();
2088 if (
Inits.size() == 0)
2090 return this->emitInvalid(E);
2105 if (
Inits.size() == 0)
2106 return this->visitZeroInitializer(*T, QT, E);
2107 assert(
Inits.size() == 1);
2120 auto initPrimitiveField = [=](
const Record::Field *FieldToInit,
2127 bool BitField = FieldToInit->isBitField();
2129 return this->emitInitBitFieldActivate(T, FieldToInit, E);
2131 return this->emitInitBitField(T, FieldToInit, E);
2133 return this->emitInitFieldActivate(T, FieldToInit->Offset, E);
2134 return this->emitInitField(T, FieldToInit->Offset, E);
2137 auto initCompositeField = [=](
const Record::Field *FieldToInit,
2145 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
2148 if (
Activate && !this->emitActivate(E))
2153 return this->emitPopPtr(E);
2157 if (
Inits.size() == 0) {
2158 if (!this->visitZeroRecordInitializer(R, E))
2163 if (
const auto *ILE = dyn_cast<InitListExpr>(E))
2164 FToInit = ILE->getInitializedFieldInUnion();
2168 const Record::Field *FieldToInit = R->
getField(FToInit);
2170 if (!initPrimitiveField(FieldToInit,
Init, *T,
true))
2173 if (!initCompositeField(FieldToInit,
Init,
true))
2177 return this->emitFinishInit(E);
2181 unsigned InitIndex = 0;
2184 while (InitIndex < R->getNumFields() &&
2189 const Record::Field *FieldToInit = R->
getField(InitIndex);
2190 if (!initPrimitiveField(FieldToInit,
Init, *T))
2195 if (
const Record::Base *B = R->
getBase(
Init->getType())) {
2196 if (!this->emitGetPtrBase(B->Offset,
Init))
2202 if (!this->emitFinishInitPop(E))
2207 const Record::Field *FieldToInit = R->
getField(InitIndex);
2208 if (!initCompositeField(FieldToInit,
Init))
2214 return this->emitFinishInit(E);
2218 if (
Inits.size() == 1 && QT ==
Inits[0]->getType())
2222 Ctx.getASTContext().getAsConstantArrayType(QT);
2225 if (!this->emitCheckArraySize(NumElems, E))
2229 unsigned ElementIndex = 0;
2231 if (
const auto *EmbedS =
2232 dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
2240 if (!this->emitCastIntegralFloating(
classifyPrim(IL), Sem,
2241 getFPOptions(E), E))
2247 return this->emitInitElem(TargetT, ElemIndex, IL);
2249 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
2261 for (; ElementIndex != NumElems; ++ElementIndex) {
2267 return this->emitFinishInit(E);
2271 unsigned NumInits =
Inits.size();
2276 QualType ElemQT = ComplexTy->getElementType();
2278 if (NumInits == 0) {
2280 for (
unsigned I = 0; I < 2; ++I) {
2281 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2283 if (!this->emitInitElem(ElemT, I, E))
2286 }
else if (NumInits == 2) {
2287 unsigned InitIndex = 0;
2292 if (!this->emitInitElem(ElemT, InitIndex, E))
2301 unsigned NumVecElements = VecT->getNumElements();
2302 assert(NumVecElements >=
Inits.size());
2304 QualType ElemQT = VecT->getElementType();
2308 unsigned InitIndex = 0;
2315 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
2316 if (!this->emitCopyArray(ElemT, 0, InitIndex,
2317 InitVecT->getNumElements(), E))
2319 InitIndex += InitVecT->getNumElements();
2321 if (!this->emitInitElem(ElemT, InitIndex, E))
2327 assert(InitIndex <= NumVecElements);
2330 for (; InitIndex != NumVecElements; ++InitIndex) {
2331 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2333 if (!this->emitInitElem(ElemT, InitIndex, E))
2340 unsigned NumElems = MT->getNumElementsFlattened();
2341 assert(
Inits.size() == NumElems);
2343 QualType ElemQT = MT->getElementType();
2349 for (
unsigned I = 0; I != NumElems; ++I) {
2352 if (!this->emitInitElem(ElemT, I, E))
2363template <
class Emitter>
2370 return this->emitInitElem(*InitT, ElemIndex,
Init);
2376 if (!this->emitConstUint32(ElemIndex,
Init))
2378 if (!this->emitArrayElemPtrUint32(
Init))
2382 return this->emitFinishInitPop(
Init);
2385template <
class Emitter>
2388 bool Activate,
bool IsOperatorCall) {
2390 llvm::BitVector NonNullArgs;
2391 if (FuncDecl && FuncDecl->
hasAttr<NonNullAttr>())
2394 bool ExplicitMemberFn =
false;
2395 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl))
2396 ExplicitMemberFn = MD->isExplicitObjectMemberFunction();
2398 unsigned ArgIndex = 0;
2399 for (
const Expr *Arg : Args) {
2401 if (!this->
visit(Arg))
2409 unsigned DeclIndex = ArgIndex - IsOperatorCall + ExplicitMemberFn;
2410 if (DeclIndex < FuncDecl->getNumParams())
2411 Source = FuncDecl->
getParamDecl(ArgIndex - IsOperatorCall +
2420 if (!this->emitGetPtrLocal(*LocalIndex, Arg))
2428 if (!this->emitActivate(Arg))
2432 if (!NonNullArgs.empty() && NonNullArgs[ArgIndex]) {
2435 if (!this->emitCheckNonNullArg(ArgT, Arg))
2446template <
class Emitter>
2451template <
class Emitter>
2457template <
class Emitter>
2463template <
class Emitter>
2479template <
class Emitter>
2481 auto It = E->
begin();
2482 return this->
visit(*It);
2487 bool AlignOfReturnsPreferred =
2488 ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
2494 T = Ref->getPointeeType();
2496 if (T.getQualifiers().hasUnaligned())
2502 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
2508template <
class Emitter>
2515 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
2521 ArgType = Ref->getPointeeType();
2527 if (
ArgType->isDependentType() || !
ArgType->isConstantSizeType())
2528 return this->emitInvalid(E);
2530 if (Kind == UETT_SizeOf)
2539 return this->emitConst(Size.getQuantity(), E);
2542 if (Kind == UETT_CountOf) {
2548 if (
const auto *CAT =
2552 return this->emitConst(CAT->getSize(), E);
2562 if (VAT->getElementType()->isArrayType()) {
2563 std::optional<APSInt> Res =
2565 ? VAT->getSizeExpr()->getIntegerConstantExpr(ASTCtx)
2570 return this->emitConst(*Res, E);
2575 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
2595 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
2598 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
2608 return this->emitConst(Size.getQuantity(), E);
2611 if (Kind == UETT_VectorElements) {
2616 return this->emitConst(VT->getNumElements(), E);
2618 return this->emitSizelessVectorElementSize(E);
2621 if (Kind == UETT_VecStep) {
2623 unsigned N = VT->getNumElements();
2630 return this->emitConst(N, E);
2632 return this->emitConst(1, E);
2635 if (Kind == UETT_OpenMPRequiredSimdAlign) {
2642 if (Kind == UETT_PtrAuthTypeDiscriminator) {
2644 return this->emitInvalid(E);
2646 return this->emitConst(
2647 const_cast<ASTContext &
>(ASTCtx).getPointerAuthTypeDiscriminator(
2655template <
class Emitter>
2666 const auto maybeLoadValue = [&]() ->
bool {
2670 return this->emitLoadPop(*T, E);
2674 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
2678 if (
auto GlobalIndex =
P.getGlobal(VD))
2679 return this->emitGetPtrGlobal(*GlobalIndex, E) && maybeLoadValue();
2684 if (!this->
discard(Base) && !this->emitSideEffect(E))
2699 const Record::Field *F = R->
getField(FD);
2701 if (F->Decl->getType()->isReferenceType())
2702 return this->emitGetFieldPop(
PT_Ptr, F->Offset, E) && maybeLoadValue();
2703 return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue();
2706template <
class Emitter>
2715template <
class Emitter>
2734 for (
size_t I = 0; I != Size; ++I) {
2746template <
class Emitter>
2757 return this->emitGetLocal(SubExprT, It->second, E);
2759 if (!this->
visit(SourceExpr))
2766 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
2772 if (!this->emitGetLocal(SubExprT, LocalIndex, E))
2782template <
class Emitter>
2805 bool IsBcpCall =
false;
2806 if (
const auto *CE = dyn_cast<CallExpr>(
Condition->IgnoreParenCasts());
2807 CE && CE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) {
2811 LabelTy LabelEnd = this->getLabel();
2812 LabelTy LabelFalse = this->getLabel();
2815 if (!this->emitStartSpeculation(E))
2823 if (this->checkingForUndefinedBehavior()) {
2826 if (!this->
discard(FalseExpr))
2832 if (!this->jumpFalse(LabelFalse))
2837 if (!this->jump(LabelEnd))
2839 this->emitLabel(LabelFalse);
2843 this->fallthrough(LabelEnd);
2844 this->emitLabel(LabelEnd);
2847 return this->emitEndSpeculation(E);
2851template <
class Emitter>
2857 unsigned StringIndex =
P.createGlobalString(E);
2858 return this->emitGetPtrGlobal(StringIndex, E);
2863 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
2864 assert(CAT &&
"a string literal that's not a constant array?");
2869 unsigned N = std::min(ArraySize, E->
getLength());
2872 for (
unsigned I = 0; I != N; ++I) {
2875 if (CharWidth == 1) {
2876 this->emitConstSint8(CodeUnit, E);
2877 this->emitInitElemSint8(I, E);
2878 }
else if (CharWidth == 2) {
2879 this->emitConstUint16(CodeUnit, E);
2880 this->emitInitElemUint16(I, E);
2881 }
else if (CharWidth == 4) {
2882 this->emitConstUint32(CodeUnit, E);
2883 this->emitInitElemUint32(I, E);
2885 llvm_unreachable(
"unsupported character width");
2890 for (
unsigned I = N; I != ArraySize; ++I) {
2891 if (CharWidth == 1) {
2892 this->emitConstSint8(0, E);
2893 this->emitInitElemSint8(I, E);
2894 }
else if (CharWidth == 2) {
2895 this->emitConstUint16(0, E);
2896 this->emitInitElemUint16(I, E);
2897 }
else if (CharWidth == 4) {
2898 this->emitConstUint32(0, E);
2899 this->emitInitElemUint32(I, E);
2901 llvm_unreachable(
"unsupported character width");
2908template <
class Emitter>
2912 return this->emitDummyPtr(E, E);
2915template <
class Emitter>
2917 auto &A =
Ctx.getASTContext();
2926template <
class Emitter>
2934 auto &A =
Ctx.getASTContext();
2938 APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
2939 QualType ArrayTy = A.getConstantArrayType(CharTy, Size,
nullptr,
2946 unsigned StringIndex =
P.createGlobalString(SL);
2947 return this->emitGetPtrGlobal(StringIndex, E);
2950template <
class Emitter>
2954 return this->emitConst(E->
getValue(), E);
2957template <
class Emitter>
2983 if (!this->emitSetLocal(*RT, TempOffset, E))
2989 if (!this->emitLoad(LHST, E))
2993 if (!this->emitPrimCast(LHST,
classifyPrim(LHSComputationType),
2994 LHSComputationType, E))
2998 if (!this->emitGetLocal(*RT, TempOffset, E))
3003 if (!this->emitAddf(getFPOptions(E), E))
3007 if (!this->emitSubf(getFPOptions(E), E))
3011 if (!this->emitMulf(getFPOptions(E), E))
3015 if (!this->emitDivf(getFPOptions(E), E))
3026 return this->emitStorePop(LHST, E);
3027 return this->emitStore(LHST, E);
3030template <
class Emitter>
3039 if (Op != BO_AddAssign && Op != BO_SubAssign)
3048 if (!this->emitLoad(*
LT, LHS))
3054 if (Op == BO_AddAssign) {
3055 if (!this->emitAddOffset(*RT, E))
3058 if (!this->emitSubOffset(*RT, E))
3063 return this->emitStorePopPtr(E);
3064 return this->emitStorePtr(E);
3067template <
class Emitter>
3080 if (!
Ctx.getLangOpts().CPlusPlus14)
3081 return this->
visit(RHS) && this->
visit(LHS) && this->emitError(E);
3083 if (!
LT || !RT || !ResultT || !LHSComputationT)
3108 if (!this->emitSetLocal(*RT, TempOffset, E))
3115 if (!this->emitLoad(*
LT, E))
3117 if (
LT != LHSComputationT &&
3123 if (!this->emitGetLocal(*RT, TempOffset, E))
3129 if (!this->emitAdd(*LHSComputationT, E))
3133 if (!this->emitSub(*LHSComputationT, E))
3137 if (!this->emitMul(*LHSComputationT, E))
3141 if (!this->emitDiv(*LHSComputationT, E))
3145 if (!this->emitRem(*LHSComputationT, E))
3149 if (!this->emitShl(*LHSComputationT, *RT, E))
3153 if (!this->emitShr(*LHSComputationT, *RT, E))
3157 if (!this->emitBitAnd(*LHSComputationT, E))
3161 if (!this->emitBitXor(*LHSComputationT, E))
3165 if (!this->emitBitOr(*LHSComputationT, E))
3169 llvm_unreachable(
"Unimplemented compound assign operator");
3173 if (ResultT != LHSComputationT &&
3174 !this->emitIntegralCast(*LHSComputationT, *ResultT, E->
getType(), E))
3180 return this->emitStoreBitFieldPop(*ResultT, E);
3181 return this->emitStorePop(*ResultT, E);
3184 return this->emitStoreBitField(*ResultT, E);
3185 return this->emitStore(*ResultT, E);
3188template <
class Emitter>
3196template <
class Emitter>
3208 return this->
discard(SubExpr);
3223 if (!this->
visit(SubExpr))
3225 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl, E))
3227 return this->emitGetPtrGlobal(*GlobalIndex, E);
3230 if (!this->checkLiteralType(SubExpr))
3233 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3237 return this->emitInitGlobalTempComp(TempDecl, E);
3248 unsigned LocalIndex =
3250 if (!this->VarScope->LocalsAlwaysEnabled &&
3251 !this->emitEnableLocal(LocalIndex, E))
3254 if (!this->
visit(SubExpr))
3256 if (!this->emitSetLocal(*SubExprT, LocalIndex, E))
3259 return this->emitGetPtrLocal(LocalIndex, E);
3262 if (!this->checkLiteralType(SubExpr))
3270 if (!this->VarScope->LocalsAlwaysEnabled &&
3271 !this->emitEnableLocal(*LocalIndex, E))
3274 if (!this->emitGetPtrLocal(*LocalIndex, E))
3281template <
class Emitter>
3292 if (!this->
visit(SubExpr))
3296 return this->emitPopPtr(E);
3300template <
class Emitter>
3321 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3326 if (
P.isGlobalInitialized(*GlobalIndex))
3332 return this->emitInitGlobal(*T, *GlobalIndex, E);
3344 unsigned LocalIndex;
3348 LocalIndex = *MaybeIndex;
3352 if (!this->emitGetPtrLocal(LocalIndex, E))
3356 return this->
visit(
Init) && this->emitInit(*T, E);
3360template <
class Emitter>
3373template <
class Emitter>
3377 return this->emitConst(E->
getValue(), E);
3380template <
class Emitter>
3393 for (
const Record::Field &F : R->
fields()) {
3395 if (!
Init ||
Init->containsErrors())
3403 if (!this->emitInitField(*T, F.Offset, E))
3406 if (!this->emitGetPtrField(F.Offset, E))
3412 if (!this->emitPopPtr(E))
3420template <
class Emitter>
3427 return this->emitGetPtrGlobal(StringIndex, E);
3433template <
class Emitter>
3438 return this->emitInvalid(E);
3441template <
class Emitter>
3467 if (PointeeToT && PointeeFromT) {
3485 bool Fatal = (ToT != FromT);
3492template <
class Emitter>
3495 if (!
Ctx.getLangOpts().CPlusPlus20) {
3503template <
class Emitter>
3509 return this->emitConstBool(E->
getValue(), E);
3512template <
class Emitter>
3517 if (T->isRecordType()) {
3531 if (!this->emitGetPtrLocal(*LocalIndex, E))
3539 T->getAsCXXRecordDecl()))
3549 if (!this->visitZeroRecordInitializer(R, E))
3561 assert(
Ctx.getASTContext().hasSameUnqualifiedType(E->
getType(),
3563 if (
const auto *ME = dyn_cast<MaterializeTemporaryExpr>(SrcObj)) {
3564 if (!this->emitCheckFunctionDecl(Ctor, E))
3575 assert(
Func->hasThisPointer());
3576 assert(!
Func->hasRVO());
3580 if (!this->emitDupPtr(E))
3584 for (
const auto *Arg : E->
arguments()) {
3585 if (!this->
visit(Arg))
3589 if (
Func->isVariadic()) {
3590 uint32_t VarArgSize = 0;
3591 unsigned NumParams =
Func->getNumWrittenParams();
3592 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I) {
3596 if (!this->emitCallVar(
Func, VarArgSize, E))
3599 if (!this->emitCall(
Func, 0, E)) {
3604 (void)this->emitPopPtr(E);
3610 return this->emitPopPtr(E);
3611 return this->emitFinishInit(E);
3614 if (T->isArrayType()) {
3619 if (!this->emitDupPtr(E))
3623 initArrayDimension = [&](
QualType T) ->
bool {
3624 if (!T->isArrayType()) {
3626 for (
const auto *Arg : E->
arguments()) {
3627 if (!this->
visit(Arg))
3631 return this->emitCall(
Func, 0, E);
3635 Ctx.getASTContext().getAsConstantArrayType(T);
3640 for (
size_t I = 0; I != NumElems; ++I) {
3641 if (!this->emitConstUint64(I, E))
3643 if (!this->emitArrayElemPtrUint64(E))
3645 if (!initArrayDimension(ElemTy))
3648 return this->emitPopPtr(E);
3651 return initArrayDimension(E->
getType());
3657template <
class Emitter>
3667 assert(Val.
isInt());
3669 return this->emitConst(I, E);
3676 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
3677 return this->
visit(LValueExpr);
3692 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
3696 const APValue &
V = UGCD->getValue();
3697 for (
unsigned I = 0, N = R->
getNumFields(); I != N; ++I) {
3698 const Record::Field *F = R->
getField(I);
3699 const APValue &FieldValue =
V.getStructField(I);
3705 if (!this->emitInitField(FieldT, F->Offset, E))
3713template <
class Emitter>
3719 for (
unsigned I = 0; I != N; ++I) {
3726 if (!this->
discard(ArrayIndexExpr))
3731 if (!this->
visit(ArrayIndexExpr))
3735 if (!this->emitCast(IndexT,
PT_Sint64, E))
3745 return this->emitOffsetOf(T, E, E);
3748template <
class Emitter>
3757 return this->visitZeroInitializer(*T, Ty, E);
3764 if (!this->emitGetPtrLocal(*LocalIndex, E))
3769 QualType ElemQT = CT->getElementType();
3772 for (
unsigned I = 0; I != 2; ++I) {
3773 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
3775 if (!this->emitInitElem(ElemT, I, E))
3787 if (!this->emitGetPtrLocal(*LocalIndex, E))
3792 QualType ElemQT = VT->getElementType();
3795 for (
unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
3796 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
3798 if (!this->emitInitElem(ElemT, I, E))
3807template <
class Emitter>
3812template <
class Emitter>
3818template <
class Emitter>
3823template <
class Emitter>
3828 return this->emitConst(E->
getValue(), E);
3831template <
class Emitter>
3836 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
3854 if (!this->emitGetParam(PT, Offset, E))
3859 return this->emitCall(F, 0, E);
3864template <
class Emitter>
3872 const Expr *PlacementDest =
nullptr;
3873 bool IsNoThrow =
false;
3878 if (PlacementArgs != 0) {
3887 if (PlacementArgs == 1) {
3895 if (!this->emitInvalidNewDeleteExpr(E, E))
3900 if (OperatorNew->isReservedGlobalPlacementOperator())
3901 PlacementDest = Arg1;
3905 return this->emitInvalid(E);
3907 }
else if (!OperatorNew
3908 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
3909 return this->emitInvalidNewDeleteExpr(E, E);
3912 if (!PlacementDest) {
3917 Desc =
P.createDescriptor(E, *ElemT,
nullptr,
3920 Desc =
P.createDescriptor(
3923 false,
false,
false,
3929 std::optional<const Expr *> ArraySizeExpr = E->
getArraySize();
3933 const Expr *Stripped = *ArraySizeExpr;
3934 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
3935 Stripped = ICE->getSubExpr())
3936 if (ICE->getCastKind() != CK_NoOp &&
3937 ICE->getCastKind() != CK_IntegralCast)
3945 if (!this->
visit(Stripped))
3947 if (!this->emitSetLocal(
SizeT, ArrayLen, E))
3950 if (PlacementDest) {
3951 if (!this->
visit(PlacementDest))
3953 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
3955 if (!this->emitCheckNewTypeMismatchArray(
SizeT, E, E))
3958 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
3963 if (!this->emitAllocN(
SizeT, *ElemT, E, IsNoThrow, E))
3967 if (!this->emitAllocCN(
SizeT, Desc, IsNoThrow, E))
3974 size_t StaticInitElems = 0;
3975 const Expr *DynamicInit =
nullptr;
3979 Ctx.getASTContext().getAsConstantArrayType(InitType)) {
3980 StaticInitElems = CAT->getZExtSize();
3985 if (
const auto *ILE = dyn_cast<InitListExpr>(
Init)) {
3986 if (ILE->hasArrayFiller())
3987 DynamicInit = ILE->getArrayFiller();
4006 const Function *CtorFunc =
nullptr;
4007 if (
const auto *CE = dyn_cast<CXXConstructExpr>(
Init)) {
4011 }
else if (!DynamicInit && !ElemT)
4014 LabelTy EndLabel = this->getLabel();
4015 LabelTy StartLabel = this->getLabel();
4020 if (!this->emitDupPtr(E))
4022 if (!this->emitNullPtr(0,
nullptr, E))
4024 if (!this->emitEQPtr(E))
4026 if (!this->jumpTrue(EndLabel))
4033 if (!this->emitConst(StaticInitElems,
SizeT, E))
4035 if (!this->emitSetLocal(
SizeT, Iter, E))
4038 this->fallthrough(StartLabel);
4039 this->emitLabel(StartLabel);
4041 if (!this->emitGetLocal(
SizeT, Iter, E))
4043 if (!this->emitGetLocal(
SizeT, ArrayLen, E))
4045 if (!this->emitLT(
SizeT, E))
4047 if (!this->jumpFalse(EndLabel))
4051 if (!this->emitGetLocal(
SizeT, Iter, E))
4053 if (!this->emitArrayElemPtr(
SizeT, E))
4056 if (isa_and_nonnull<ImplicitValueInitExpr>(DynamicInit) &&
4061 if (!this->visitZeroInitializer(InitT, ElemType, E))
4063 if (!this->emitStorePop(InitT, E))
4065 }
else if (DynamicInit) {
4067 if (!this->
visit(DynamicInit))
4069 if (!this->emitStorePop(*InitT, E))
4074 if (!this->emitPopPtr(E))
4078 if (!this->visitZeroInitializer(
4082 if (!this->emitStorePop(*ElemT, E))
4086 if (!this->emitCall(CtorFunc, 0, E))
4091 if (!this->emitGetPtrLocal(Iter, E))
4093 if (!this->emitIncPop(
SizeT,
false, E))
4096 if (!this->jump(StartLabel))
4099 this->fallthrough(EndLabel);
4100 this->emitLabel(EndLabel);
4104 if (PlacementDest) {
4105 if (!this->
visit(PlacementDest))
4107 if (!this->emitCheckNewTypeMismatch(E, E))
4112 if (!this->emitAlloc(Desc, E))
4121 if (!this->emitInit(*ElemT, E))
4132 return this->emitPopPtr(E);
4137template <
class Emitter>
4143 if (!OperatorDelete->isUsableAsGlobalAllocationFunctionInConstantEvaluation())
4144 return this->emitInvalidNewDeleteExpr(E, E);
4153template <
class Emitter>
4159 if (
const Function *F =
Ctx.getOrCreateObjCBlock(E))
4164 return this->emitGetFnPtr(
Func, E);
4167template <
class Emitter>
4171 auto canonType = [](
const Type *T) {
4172 return T->getCanonicalTypeUnqualified().getTypePtr();
4180 return this->emitGetTypeid(
4184 return this->emitGetTypeid(
4193 if (!
Ctx.getLangOpts().CPlusPlus20 && !this->emitDiagTypeid(E))
4199 if (!this->emitGetTypeidPtr(TypeInfoType, E))
4202 return this->emitPopPtr(E);
4206template <
class Emitter>
4208 assert(
Ctx.getLangOpts().CPlusPlus);
4209 return this->emitConstBool(E->
getValue(), E);
4212template <
class Emitter>
4224 return this->emitDummyPtr(GuidDecl, E);
4229 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
4238 assert(
V.isStruct());
4239 assert(
V.getStructNumBases() == 0);
4243 return this->emitFinishInit(E);
4246template <
class Emitter>
4256template <
class Emitter>
4265template <
class Emitter>
4271template <
class Emitter>
4275 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
4279 if (OVE->isUnique())
4295template <
class Emitter>
4300template <
class Emitter>
4302 return this->emitError(E);
4305template <
class Emitter>
4311 return this->emitDummyPtr(E, E);
4314template <
class Emitter>
4318 QualType ElemType = VT->getElementType();
4322 PrimType SrcElemT = classifyVectorElementType(SrcType);
4324 unsigned SrcOffset =
4326 if (!this->
visit(Src))
4328 if (!this->emitSetLocal(
PT_Ptr, SrcOffset, E))
4331 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
4332 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
4334 if (!this->emitArrayElemPop(SrcElemT, I, E))
4338 if (SrcElemT != ElemT) {
4339 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
4341 }
else if (ElemType->isFloatingType() && SrcType != ElemType) {
4342 const auto *TargetSemantics = &
Ctx.getFloatSemantics(ElemType);
4346 if (!this->emitInitElem(ElemT, I, E))
4353template <
class Emitter>
4357 return this->emitInvalid(E);
4366 assert(NumOutputElems > 0);
4372 if (!this->emitGetPtrLocal(*LocalIndex, E))
4377 unsigned VectorOffsets[2];
4378 for (
unsigned I = 0; I != 2; ++I) {
4381 if (!this->
visit(Vecs[I]))
4383 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I], E))
4386 for (
unsigned I = 0; I != NumOutputElems; ++I) {
4388 assert(ShuffleIndex >= -1);
4389 if (ShuffleIndex == -1)
4390 return this->emitInvalidShuffleVectorIndex(I, E);
4392 assert(ShuffleIndex < (NumInputElems * 2));
4393 if (!this->emitGetLocal(
PT_Ptr,
4394 VectorOffsets[ShuffleIndex >= NumInputElems], E))
4396 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
4397 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
4400 if (!this->emitInitElem(ElemT, I, E))
4405 return this->emitPopPtr(E);
4410template <
class Emitter>
4415 Base->getType()->isVectorType() ||
4421 if (Indices.size() == 1) {
4426 if (!this->emitConstUint32(Indices[0], E))
4428 return this->emitArrayElemPtrPop(
PT_Uint32, E);
4438 if (!this->emitSetLocal(
PT_Ptr, BaseOffset, E))
4446 if (!this->emitGetPtrLocal(*ResultIndex, E))
4454 uint32_t DstIndex = 0;
4455 for (uint32_t I : Indices) {
4456 if (!this->emitGetLocal(
PT_Ptr, BaseOffset, E))
4458 if (!this->emitArrayElemPop(ElemT, I, E))
4460 if (!this->emitInitElem(ElemT, DstIndex, E))
4470template <
class Emitter>
4474 return this->
discard(SubExpr) && this->emitInvalid(E);
4480 return this->emitDummyPtr(E, E);
4483template <
class Emitter>
4488 Ctx.getASTContext().getAsConstantArrayType(SubExpr->
getType());
4493 if (!this->
visit(SubExpr))
4495 if (!this->emitConstUint8(0, E))
4497 if (!this->emitArrayElemPtrPopUint8(E))
4504 if (!this->emitConst(
ArrayType->getSize(), SecondFieldT, E))
4506 return this->emitInitField(SecondFieldT, R->
getField(1u)->
Offset, E);
4508 assert(SecondFieldT ==
PT_Ptr);
4512 if (!this->emitExpandPtr(E))
4516 if (!this->emitArrayElemPtrPop(
PT_Uint64, E))
4521template <
class Emitter>
4536 if (
const Expr *ResultExpr = dyn_cast<Expr>(S))
4538 return this->emitUnsupported(E);
4547 return this->
Visit(E);
4554 return this->
Visit(E);
4558 if (
const auto *PE = dyn_cast<ParenExpr>(E))
4561 if (
const auto *CE = dyn_cast<CastExpr>(E);
4563 (CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp))
4570 if (
const auto *PE = dyn_cast<ParenExpr>(E))
4573 if (
const auto *CE = dyn_cast<CastExpr>(E);
4574 CE && (CE->getCastKind() == CK_DerivedToBase ||
4575 CE->getCastKind() == CK_UncheckedDerivedToBase ||
4576 CE->getCastKind() == CK_NoOp))
4596 if (!this->emitGetPtrLocal(*LocalIndex, E))
4606 return this->
Visit(E);
4609template <
class Emitter>
4615 return this->
Visit(E);
4621 return this->
Visit(E);
4629 if (!this->
visit(E))
4631 return this->emitComplexBoolCast(E);
4636 if (!this->
visit(E))
4644 return this->emitIsNonNullPtr(E);
4648 return this->emitCastFloatingIntegralBool(getFPOptions(E), E);
4651 return this->emitCast(*T,
PT_Bool, E);
4654template <
class Emitter>
4658 QT = AT->getValueType();
4662 return this->emitZeroBool(E);
4664 return this->emitZeroSint8(E);
4666 return this->emitZeroUint8(E);
4668 return this->emitZeroSint16(E);
4670 return this->emitZeroUint16(E);
4672 return this->emitZeroSint32(E);
4674 return this->emitZeroUint32(E);
4676 return this->emitZeroSint64(E);
4678 return this->emitZeroUint64(E);
4680 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
4682 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
4684 return this->emitNullPtr(Ctx.getASTContext().getTargetNullPointerValue(QT),
4687 return this->emitNullMemberPtr(0,
nullptr, E);
4689 APFloat F = APFloat::getZero(Ctx.getFloatSemantics(QT));
4690 return this->emitFloat(F, E);
4693 auto Sem = Ctx.getASTContext().getFixedPointSemantics(E->
getType());
4697 llvm_unreachable(
"unknown primitive type");
4700template <
class Emitter>
4701bool Compiler<Emitter>::visitZeroRecordInitializer(
const Record *R,
4706 for (
const Record::Field &Field : R->
fields()) {
4707 if (Field.isUnnamedBitField())
4714 if (!this->visitZeroInitializer(T, QT, E))
4717 if (!this->emitInitFieldActivate(T, Field.Offset, E))
4721 if (!this->emitInitField(T, Field.Offset, E))
4726 if (!this->emitGetPtrField(Field.Offset, E))
4732 for (uint32_t I = 0, N = D->
getNumElems(); I != N; ++I) {
4733 if (!this->visitZeroInitializer(T, ET, E))
4735 if (!this->emitInitElem(T, I, E))
4740 if (!this->visitZeroArrayInitializer(D->
getType(), E))
4743 if (!this->visitZeroRecordInitializer(D->
ElemRecord, E))
4751 if (!this->emitFinishInitActivatePop(E))
4755 if (!this->emitFinishInitPop(E))
4759 for (
const Record::Base &B : R->
bases()) {
4760 if (!this->emitGetPtrBase(B.Offset, E))
4762 if (!this->visitZeroRecordInitializer(B.R, E))
4764 if (!this->emitFinishInitPop(E))
4773template <
class Emitter>
4774bool Compiler<Emitter>::visitZeroArrayInitializer(
QualType T,
const Expr *E) {
4775 assert(T->isArrayType() || T->isAnyComplexType() || T->isVectorType());
4781 for (
size_t I = 0; I != NumElems; ++I) {
4782 if (!this->visitZeroInitializer(*ElemT, ElemType, E))
4784 if (!this->emitInitElem(*ElemT, I, E))
4790 const Record *R = getRecord(ElemType);
4794 for (
size_t I = 0; I != NumElems; ++I) {
4795 if (!this->emitConstUint32(I, E))
4797 if (!this->emitArrayElemPtr(
PT_Uint32, E))
4799 if (!this->visitZeroRecordInitializer(R, E))
4801 if (!this->emitPopPtr(E))
4807 for (
size_t I = 0; I != NumElems; ++I) {
4808 if (!this->emitConstUint32(I, E))
4810 if (!this->emitArrayElemPtr(
PT_Uint32, E))
4812 if (!this->visitZeroArrayInitializer(ElemType, E))
4814 if (!this->emitPopPtr(E))
4823template <
class Emitter>
4824bool Compiler<Emitter>::visitAssignment(
const Expr *LHS,
const Expr *RHS,
4826 if (!canClassify(E->
getType()))
4829 if (!this->visit(RHS))
4831 if (!this->visit(LHS))
4838 if (!Ctx.getLangOpts().CPlusPlus && !this->emitInvalid(E))
4842 bool Activates = refersToUnion(LHS);
4845 if (!this->emitFlip(
PT_Ptr, RHT, E))
4848 if (DiscardResult) {
4849 if (BitField && Activates)
4850 return this->emitStoreBitFieldActivatePop(RHT, E);
4852 return this->emitStoreBitFieldPop(RHT, E);
4854 return this->emitStoreActivatePop(RHT, E);
4856 return this->emitStorePop(RHT, E);
4859 auto maybeLoad = [&](
bool Result) ->
bool {
4865 return this->emitLoadPop(RHT, E);
4869 if (BitField && Activates)
4870 return maybeLoad(this->emitStoreBitFieldActivate(RHT, E));
4872 return maybeLoad(this->emitStoreBitField(RHT, E));
4874 return maybeLoad(this->emitStoreActivate(RHT, E));
4876 return maybeLoad(this->emitStore(RHT, E));
4879template <
class Emitter>
4880template <
typename T>
4884 return this->emitConstSint8(
Value, E);
4886 return this->emitConstUint8(
Value, E);
4888 return this->emitConstSint16(
Value, E);
4890 return this->emitConstUint16(
Value, E);
4892 return this->emitConstSint32(
Value, E);
4894 return this->emitConstUint32(
Value, E);
4896 return this->emitConstSint64(
Value, E);
4898 return this->emitConstUint64(
Value, E);
4900 return this->emitConstBool(
Value, E);
4907 llvm_unreachable(
"Invalid integral type");
4910 llvm_unreachable(
"unknown primitive type");
4913template <
class Emitter>
4914template <
typename T>
4915bool Compiler<Emitter>::emitConst(T
Value,
const Expr *E) {
4916 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
4919template <
class Emitter>
4923 return this->emitConstIntAPS(
Value, E);
4925 return this->emitConstIntAP(
Value, E);
4927 if (
Value.isSigned())
4928 return this->emitConst(
Value.getSExtValue(), Ty, E);
4929 return this->emitConst(
Value.getZExtValue(), Ty, E);
4932template <
class Emitter>
4936 return this->emitConstIntAPS(
Value, E);
4938 return this->emitConstIntAP(
Value, E);
4941 return this->emitConst(
Value.getSExtValue(), Ty, E);
4942 return this->emitConst(
Value.getZExtValue(), Ty, E);
4945template <
class Emitter>
4946bool Compiler<Emitter>::emitConst(
const APSInt &
Value,
const Expr *E) {
4947 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
4950template <
class Emitter>
4955 bool IsConstexprUnknown) {
4964 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
4965 Locals.insert({VD, Local});
4966 VarScope->addForScopeKind(Local, SC);
4967 return Local.Offset;
4970template <
class Emitter>
4973 bool IsConstexprUnknown) {
4976 bool IsTemporary =
false;
4977 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
4980 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
4981 Init = VarD->getInit();
4983 if (
auto *E = Src.dyn_cast<
const Expr *>()) {
4994 return std::nullopt;
4999 Locals.insert({Key, Local});
5000 VarScope->addForScopeKind(Local, SC);
5001 return Local.Offset;
5004template <
class Emitter>
5014 return std::nullopt;
5024 return Local.Offset;
5027template <
class Emitter>
5029 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
5030 return PT->getPointeeType()->getAsCanonical<RecordType>();
5036 return getRecord(RecordTy->getDecl()->getDefinitionOrSelf());
5040template <
class Emitter>
5042 return P.getOrCreateRecord(RD);
5045template <
class Emitter>
5047 return Ctx.getOrCreateFunction(FD);
5050template <
class Emitter>
5055 if (!DestroyToplevelScope) {
5056 if (!this->emitCheckAllocations(E))
5060 auto maybeDestroyLocals = [&]() ->
bool {
5061 if (DestroyToplevelScope)
5062 return RootScope.
destroyLocals() && this->emitCheckAllocations(E);
5063 return this->emitCheckAllocations(E);
5070 return this->emitRetVoid(E) && maybeDestroyLocals();
5078 return this->emitRet(*T, E) && maybeDestroyLocals();
5086 if (!this->emitGetPtrLocal(*LocalOffset, E))
5092 if (!this->emitFinishInit(E))
5097 return this->emitRetValue(E) && maybeDestroyLocals();
5100 return maybeDestroyLocals() && this->emitCheckAllocations(E) &&
false;
5103template <
class Emitter>
5105 bool IsConstexprUnknown) {
5108 IsConstexprUnknown);
5117 if (
auto GlobalIndex =
P.getGlobal(VD)) {
5118 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
5132template <
class Emitter>
5134 bool ConstantContext) {
5137 if (!ConstantContext) {
5151 auto GlobalIndex =
P.getGlobal(VD);
5152 assert(GlobalIndex);
5154 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
5157 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
5161 auto Local =
Locals.find(VD);
5162 assert(Local !=
Locals.end());
5164 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
5167 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
5177 auto GlobalIndex =
P.getGlobal(VD);
5178 assert(GlobalIndex);
5179 Block *GlobalBlock =
P.getGlobal(*GlobalIndex);
5188 return VDScope.
destroyLocals() && this->emitCheckAllocations(VD);
5191template <
class Emitter>
5194 bool Toplevel,
bool IsConstexprUnknown) {
5201 if (!this->isActive())
5206 if (
Init &&
Init->isValueDependent())
5210 auto checkDecl = [&]() ->
bool {
5212 return !NeedsOp || this->emitCheckDecl(VD, VD);
5220 if (!
P.getGlobal(*GlobalIndex)->isInitialized())
5223 if (
P.isGlobalInitialized(*GlobalIndex))
5227 }
else if ((GlobalIndex =
P.createGlobal(VD,
Init))) {
5241 return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
5244 if (!this->emitGetPtrGlobal(*GlobalIndex,
Init))
5250 return this->emitFinishInitGlobal(
Init);
5259 IsConstexprUnknown);
5270 return this->emitSetLocal(*VarT, Offset, VD) &&
Scope.destroyLocals();
5274 return this->emitSetLocal(*VarT, Offset, VD);
5282 if (!this->emitGetPtrLocal(*Offset,
Init))
5288 return this->emitFinishInitPop(
Init);
5293template <
class Emitter>
5298 return this->emitConst(Val.
getInt(), ValType, E);
5301 return this->emitFloat(F, E);
5306 return this->emitNull(ValType, 0,
nullptr, E);
5308 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
5309 return this->
visit(BaseExpr);
5314 return this->emitGetMemberPtr(MemberDecl, E);
5315 return this->emitNullMemberPtr(0,
nullptr, E);
5321template <
class Emitter>
5329 const Record::Field *RF = R->
getField(I);
5330 QualType FieldType = RF->Decl->getType();
5335 if (!this->emitInitField(*PT, RF->Offset, E))
5338 if (!this->emitGetPtrField(RF->Offset, E))
5342 if (!this->emitPopPtr(E))
5355 const Record::Field *RF = R->
getField(UnionField);
5356 QualType FieldType = RF->Decl->getType();
5361 if (RF->isBitField())
5362 return this->emitInitBitFieldActivate(*PT, RF, E);
5363 return this->emitInitFieldActivate(*PT, RF->Offset, E);
5366 if (!this->emitGetPtrField(RF->Offset, E))
5368 if (!this->emitActivate(E))
5372 return this->emitPopPtr(E);
5375 const auto *ArrType = T->getAsArrayTypeUnsafe();
5376 QualType ElemType = ArrType->getElementType();
5377 for (
unsigned A = 0, AN = Val.
getArraySize(); A != AN; ++A) {
5382 if (!this->emitInitElem(*ElemT, A, E))
5385 if (!this->emitConstUint32(A, E))
5387 if (!this->emitArrayElemPtrUint32(E))
5391 if (!this->emitPopPtr(E))
5402template <
class Emitter>
5404 unsigned BuiltinID) {
5405 if (BuiltinID == Builtin::BI__builtin_constant_p) {
5410 return this->emitConst(0, E);
5413 if (!this->emitStartSpeculation(E))
5415 LabelTy EndLabel = this->getLabel();
5416 if (!this->speculate(E, EndLabel))
5418 this->fallthrough(EndLabel);
5419 if (!this->emitEndSpeculation(E))
5428 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
5429 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString ||
5430 BuiltinID == Builtin::BI__builtin_ptrauth_sign_constant ||
5431 BuiltinID == Builtin::BI__builtin_function_start) {
5434 return this->emitDummyPtr(E, E);
5445 if (!this->emitGetPtrLocal(*LocalIndex, E))
5450 switch (BuiltinID) {
5451 case Builtin::BI__builtin_object_size:
5452 case Builtin::BI__builtin_dynamic_object_size: {
5456 if (!this->
visit(Arg0))
5467 case Builtin::BI__assume:
5468 case Builtin::BI__builtin_assume:
5471 case Builtin::BI__atomic_is_lock_free:
5472 case Builtin::BI__atomic_always_lock_free: {
5483 for (
const auto *Arg : E->
arguments()) {
5484 if (!this->
visit(Arg))
5490 if (!this->emitCallBI(E, BuiltinID, E))
5499template <
class Emitter>
5518 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(FuncDecl);
5519 DD && DD->isTrivial()) {
5521 if (!this->
visit(MemberCall->getImplicitObjectArgument()))
5523 return this->emitCheckDestruction(E) && this->emitEndLifetime(E) &&
5524 this->emitPopPtr(E);
5532 bool HasRVO = !
ReturnType->isVoidType() && !T;
5540 if (!this->emitGetPtrLocal(*LocalIndex, E))
5548 if (!this->emitGetPtrLocal(*LocalIndex, E))
5552 if (!this->emitDupPtr(E))
5559 bool IsAssignmentOperatorCall =
false;
5560 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
5561 OCE && OCE->isAssignmentOp()) {
5565 assert(Args.size() == 2);
5566 IsAssignmentOperatorCall =
true;
5567 std::reverse(Args.begin(), Args.end());
5573 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
5574 MD && MD->isStatic()) {
5578 Args.erase(Args.begin());
5582 bool Devirtualized =
false;
5585 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
5593 if (!this->
visit(Callee))
5595 if (!this->emitSetLocal(
PT_MemberPtr, *CalleeOffset, E))
5597 if (!this->emitGetLocal(
PT_MemberPtr, *CalleeOffset, E))
5599 if (!this->emitGetMemberPtrBase(E))
5602 const auto *InstancePtr = MC->getImplicitObjectArgument();
5609 Stripped->getType()->getPointeeType()->getAsCXXRecordDecl());
5610 Devirtualized =
true;
5611 if (!this->
visit(Stripped))
5614 if (!this->
visit(InstancePtr))
5618 if (!this->
visit(InstancePtr))
5622 }
else if (
const auto *PD =
5623 dyn_cast<CXXPseudoDestructorExpr>(E->
getCallee())) {
5624 if (!this->emitCheckPseudoDtor(E))
5632 return this->emitEndLifetimePop(E);
5633 }
else if (!FuncDecl) {
5637 if (!this->
visit(Callee))
5639 if (!this->emitSetLocal(
PT_Ptr, *CalleeOffset, E))
5643 if (!this->
visitCallArgs(Args, FuncDecl, IsAssignmentOperatorCall,
5648 if (IsAssignmentOperatorCall) {
5649 assert(Args.size() == 2);
5652 if (!this->emitFlip(Arg2T, Arg1T, E))
5666 assert(HasRVO ==
Func->hasRVO());
5668 bool HasQualifier =
false;
5669 if (
const auto *ME = dyn_cast<MemberExpr>(E->
getCallee()))
5670 HasQualifier = ME->hasQualifier();
5672 bool IsVirtual =
false;
5673 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
5674 IsVirtual = !Devirtualized && MD->isVirtual();
5679 if (IsVirtual && !HasQualifier) {
5680 uint32_t VarArgSize = 0;
5681 unsigned NumParams =
5683 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
5686 if (!this->emitCallVirt(
Func, VarArgSize, E))
5688 }
else if (
Func->isVariadic()) {
5689 uint32_t VarArgSize = 0;
5690 unsigned NumParams =
5692 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
5694 if (!this->emitCallVar(
Func, VarArgSize, E))
5697 if (!this->emitCall(
Func, 0, E))
5706 uint32_t ArgSize = 0;
5707 for (
unsigned I = 0, N = E->
getNumArgs(); I != N; ++I)
5713 if (!this->emitGetLocal(
PT_MemberPtr, *CalleeOffset, E))
5715 if (!this->emitGetMemberPtrDecl(E))
5718 if (!this->emitGetLocal(
PT_Ptr, *CalleeOffset, E))
5721 if (!this->emitCallPtr(ArgSize, E, E))
5732template <
class Emitter>
5739template <
class Emitter>
5746template <
class Emitter>
5751 return this->emitConstBool(E->
getValue(), E);
5754template <
class Emitter>
5760 uint64_t Val =
Ctx.getASTContext().getTargetNullPointerValue(E->
getType());
5761 return this->emitNullPtr(Val,
nullptr, E);
5764template <
class Emitter>
5772 return this->emitZero(T, E);
5775template <
class Emitter>
5780 if (this->LambdaThisCapture.Offset > 0) {
5781 if (this->LambdaThisCapture.IsPtr)
5782 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
5783 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
5791 return this->emitThis(E);
5806 unsigned StartIndex = 0;
5807 unsigned EndIndex = 0;
5809 for (StartIndex =
InitStack.size() - 1; StartIndex > 0; --StartIndex) {
5811 EndIndex = StartIndex;
5818 for (; StartIndex > 0; --StartIndex) {
5828 if (StartIndex == 0 && EndIndex == 0)
5831 assert(StartIndex < EndIndex);
5834 for (
unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
5846 case Stmt::CompoundStmtClass:
5848 case Stmt::DeclStmtClass:
5850 case Stmt::ReturnStmtClass:
5852 case Stmt::IfStmtClass:
5854 case Stmt::WhileStmtClass:
5856 case Stmt::DoStmtClass:
5858 case Stmt::ForStmtClass:
5860 case Stmt::CXXForRangeStmtClass:
5862 case Stmt::BreakStmtClass:
5864 case Stmt::ContinueStmtClass:
5866 case Stmt::SwitchStmtClass:
5868 case Stmt::CaseStmtClass:
5870 case Stmt::DefaultStmtClass:
5872 case Stmt::AttributedStmtClass:
5874 case Stmt::CXXTryStmtClass:
5876 case Stmt::NullStmtClass:
5879 case Stmt::GCCAsmStmtClass:
5880 case Stmt::MSAsmStmtClass:
5881 case Stmt::GotoStmtClass:
5882 return this->emitInvalid(S);
5883 case Stmt::LabelStmtClass:
5886 if (
const auto *E = dyn_cast<Expr>(S))
5893template <
class Emitter>
5896 for (
const auto *InnerStmt : S->
body())
5899 return Scope.destroyLocals();
5902template <
class Emitter>
5903bool Compiler<Emitter>::maybeEmitDeferredVarInit(
const VarDecl *VD) {
5904 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5905 for (
auto *BD : DD->flat_bindings())
5906 if (
auto *KD = BD->getHoldingVar();
5907 KD && !this->visitVarDecl(KD, KD->getInit()))
5921template <
class Emitter>
bool Compiler<Emitter>::refersToUnion(
const Expr *E) {
5923 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
5924 if (
const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
5931 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
5936 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E);
5937 ICE && (ICE->getCastKind() == CK_NoOp ||
5938 ICE->getCastKind() == CK_DerivedToBase ||
5939 ICE->getCastKind() == CK_UncheckedDerivedToBase)) {
5940 E = ICE->getSubExpr();
5944 if (
const auto *
This = dyn_cast<CXXThisExpr>(E)) {
5945 const auto *ThisRecord =
5946 This->getType()->getPointeeType()->getAsRecordDecl();
5947 if (!ThisRecord->isUnion())
5950 if (
const auto *Ctor =
5951 dyn_cast_if_present<CXXConstructorDecl>(CompilingFunction))
5952 return Ctor->getParent() == ThisRecord;
5961template <
class Emitter>
5963 bool EvaluateConditionDecl) {
5964 for (
const auto *D : DS->
decls()) {
5969 const auto *VD = dyn_cast<VarDecl>(D);
5976 if (EvaluateConditionDecl && !this->maybeEmitDeferredVarInit(VD))
5983template <
class Emitter>
5986 return this->emitUnsupported(RS);
5992 if (!this->
visit(RE))
5998 if (RE->getType()->isVoidType()) {
5999 if (!this->
visit(RE))
6002 if (RE->containsErrors())
6007 if (!this->emitRVOPtr(RE))
6011 if (!this->emitPopPtr(RE))
6015 return this->emitRetVoid(RS);
6021 return this->emitRetVoid(RS);
6027 auto visitChildStmt = [&](
const Stmt *S) ->
bool {
6034 if (
auto *CondInit = IS->
getInit()) {
6050 return visitChildStmt(IS->
getThen());
6052 return visitChildStmt(Else);
6058 if (!this->emitIsConstantContext(IS))
6061 if (!this->emitIsConstantContext(IS))
6063 if (!this->emitInv(IS))
6077 LabelTy LabelElse = this->getLabel();
6078 LabelTy LabelEnd = this->getLabel();
6079 if (!this->jumpFalse(LabelElse))
6081 if (!visitChildStmt(IS->
getThen()))
6083 if (!this->jump(LabelEnd))
6085 this->emitLabel(LabelElse);
6086 if (!visitChildStmt(Else))
6088 this->emitLabel(LabelEnd);
6090 LabelTy LabelEnd = this->getLabel();
6091 if (!this->jumpFalse(LabelEnd))
6093 if (!visitChildStmt(IS->
getThen()))
6095 this->emitLabel(LabelEnd);
6104template <
class Emitter>
6109 LabelTy CondLabel = this->getLabel();
6110 LabelTy EndLabel = this->getLabel();
6114 this->fallthrough(CondLabel);
6115 this->emitLabel(CondLabel);
6129 if (!this->jumpFalse(EndLabel))
6138 if (!this->jump(CondLabel))
6140 this->fallthrough(EndLabel);
6141 this->emitLabel(EndLabel);
6149 LabelTy StartLabel = this->getLabel();
6150 LabelTy EndLabel = this->getLabel();
6151 LabelTy CondLabel = this->getLabel();
6155 this->fallthrough(StartLabel);
6156 this->emitLabel(StartLabel);
6162 this->fallthrough(CondLabel);
6163 this->emitLabel(CondLabel);
6170 if (!this->jumpTrue(StartLabel))
6173 this->fallthrough(EndLabel);
6174 this->emitLabel(EndLabel);
6178template <
class Emitter>
6186 LabelTy EndLabel = this->getLabel();
6187 LabelTy CondLabel = this->getLabel();
6188 LabelTy IncLabel = this->getLabel();
6195 this->fallthrough(CondLabel);
6196 this->emitLabel(CondLabel);
6208 if (!this->jumpFalse(EndLabel))
6217 this->fallthrough(IncLabel);
6218 this->emitLabel(IncLabel);
6224 if (!this->jump(CondLabel))
6228 this->emitLabel(EndLabel);
6234template <
class Emitter>
6244 LabelTy EndLabel = this->getLabel();
6245 LabelTy CondLabel = this->getLabel();
6246 LabelTy IncLabel = this->getLabel();
6261 this->fallthrough(CondLabel);
6262 this->emitLabel(CondLabel);
6265 if (!this->jumpFalse(EndLabel))
6276 this->fallthrough(IncLabel);
6277 this->emitLabel(IncLabel);
6282 if (!this->jump(CondLabel))
6285 this->fallthrough(EndLabel);
6286 this->emitLabel(EndLabel);
6290template <
class Emitter>
6301 if (LI.BreakLabel) {
6302 TargetLabel = *LI.BreakLabel;
6303 BreakScope = LI.BreakOrContinueScope;
6309 if (LI.Name == TargetLoop) {
6310 TargetLabel = *LI.BreakLabel;
6311 BreakScope = LI.BreakOrContinueScope;
6322 C =
C->getParent()) {
6323 if (!
C->destroyLocals())
6327 return this->jump(*TargetLabel);
6330template <
class Emitter>
6341 if (LI.ContinueLabel) {
6342 TargetLabel = *LI.ContinueLabel;
6343 ContinueScope = LI.BreakOrContinueScope;
6349 if (LI.Name == TargetLoop) {
6350 TargetLabel = *LI.ContinueLabel;
6351 ContinueScope = LI.BreakOrContinueScope;
6356 assert(TargetLabel);
6359 C =
C->getParent()) {
6360 if (!
C->destroyLocals())
6364 return this->jump(*TargetLabel);
6367template <
class Emitter>
6370 if (
Cond->containsErrors())
6376 LabelTy EndLabel = this->getLabel();
6381 if (
const auto *CondInit = S->
getInit())
6392 if (!this->emitSetLocal(CondT, CondVar, S))
6402 if (
const auto *CS = dyn_cast<CaseStmt>(SC)) {
6405 if (CS->caseStmtIsGNURange()) {
6406 LabelTy EndOfRangeCheck = this->getLabel();
6407 const Expr *Low = CS->getLHS();
6408 const Expr *High = CS->getRHS();
6412 if (!this->emitGetLocal(CondT, CondVar, CS))
6414 if (!this->
visit(Low))
6417 if (!this->emitGE(
LT, S))
6419 if (!this->jumpFalse(EndOfRangeCheck))
6422 if (!this->emitGetLocal(CondT, CondVar, CS))
6424 if (!this->
visit(High))
6427 if (!this->emitLE(HT, S))
6431 this->emitLabel(EndOfRangeCheck);
6436 if (
Value->isValueDependent())
6441 if (!this->emitGetLocal(CondT, CondVar, CS))
6447 if (!this->emitEQ(ValueT, S))
6452 assert(!DefaultLabel);
6453 DefaultLabel = this->getLabel();
6460 if (!this->jump(*DefaultLabel))
6463 if (!this->jump(EndLabel))
6471 this->fallthrough(EndLabel);
6472 this->emitLabel(EndLabel);
6477template <
class Emitter>
6484template <
class Emitter>
6491 if (LI.DefaultLabel) {
6492 DefaultLabel = *LI.DefaultLabel;
6497 this->emitLabel(DefaultLabel);
6501template <
class Emitter>
6508 if (IsMSVCConstexprAttr && !this->emitPushMSVCCE(S))
6511 if (this->
Ctx.getLangOpts().CXXAssumptions &&
6512 !this->Ctx.getLangOpts().MSVCCompat) {
6514 auto *AA = dyn_cast<CXXAssumeAttr>(A);
6520 const Expr *Assumption = AA->getAssumption();
6531 if (!this->emitAssume(Assumption))
6540 if (IsMSVCConstexprAttr)
6541 return this->emitPopMSVCCE(S);
6545template <
class Emitter>
6551template <
class Emitter>
6552bool Compiler<Emitter>::emitLambdaStaticInvokerBody(
const CXXMethodDecl *MD) {
6559 assert(ClosureClass->
captures().empty());
6563 "A generic lambda's static-invoker function must be a "
6564 "template specialization");
6568 void *InsertPos =
nullptr;
6569 const FunctionDecl *CorrespondingCallOpSpecialization =
6571 assert(CorrespondingCallOpSpecialization);
6572 LambdaCallOp = CorrespondingCallOpSpecialization;
6576 assert(ClosureClass->
captures().empty());
6577 const Function *
Func = this->getFunction(LambdaCallOp);
6580 assert(
Func->hasThisPointer());
6583 if (
Func->hasRVO()) {
6584 if (!this->emitRVOPtr(MD))
6592 if (!this->emitNullPtr(0,
nullptr, MD))
6597 auto It = this->Params.find(PVD);
6598 assert(It != this->Params.end());
6602 PrimType ParamType = this->classify(PVD->getType()).value_or(
PT_Ptr);
6603 if (!this->emitGetParam(ParamType, It->second.Offset, MD))
6607 if (!this->emitCall(
Func, 0, LambdaCallOp))
6612 return this->emitRet(*ReturnType, MD);
6615 return this->emitRetVoid(MD);
6618template <
class Emitter>
6619bool Compiler<Emitter>::checkLiteralType(
const Expr *E) {
6620 if (Ctx.getLangOpts().CPlusPlus23)
6630 const Expr *InitExpr =
Init->getInit();
6632 if (!
Init->isWritten() && !
Init->isInClassMemberInitializer() &&
6636 if (
const auto *CE = dyn_cast<CXXConstructExpr>(InitExpr)) {
6646template <
class Emitter>
6648 assert(!ReturnType);
6650 auto emitFieldInitializer = [&](
const Record::Field *F,
unsigned FieldOffset,
6651 const Expr *InitExpr,
6654 if (InitExpr->getType().isNull())
6658 if (
Activate && !this->emitActivateThisField(FieldOffset, InitExpr))
6661 if (!this->visit(InitExpr))
6664 bool BitField = F->isBitField();
6666 return this->emitInitThisBitField(*T, F, FieldOffset, InitExpr);
6667 return this->emitInitThisField(*T, FieldOffset, InitExpr);
6672 if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
6675 if (
Activate && !this->emitActivate(InitExpr))
6678 if (!this->visitInitializer(InitExpr))
6681 return this->emitFinishInitPop(InitExpr);
6685 const Record *R = this->getRecord(RD);
6694 return this->emitRetVoid(Ctor);
6697 if (!this->emitThis(Ctor))
6706 return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
6707 this->emitRetVoid(Ctor);
6711 for (
const auto *
Init : Ctor->
inits()) {
6715 const Expr *InitExpr =
Init->getInit();
6721 if (!emitFieldInitializer(F, F->Offset, InitExpr, IsUnion))
6724 const auto *BaseDecl =
Base->getAsCXXRecordDecl();
6727 if (
Init->isBaseVirtual()) {
6729 if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
6735 const Record::Base *B = R->
getBase(BaseDecl);
6737 if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
6741 if (IsUnion && !this->emitActivate(InitExpr))
6744 if (!this->visitInitializer(InitExpr))
6746 if (!this->emitFinishInitPop(InitExpr))
6751 assert(IFD->getChainingSize() >= 2);
6753 unsigned NestedFieldOffset = 0;
6754 const Record::Field *NestedField =
nullptr;
6755 for (
const NamedDecl *ND : IFD->chain()) {
6757 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
6758 assert(FieldRecord);
6760 NestedField = FieldRecord->
getField(FD);
6761 assert(NestedField);
6762 IsUnion = IsUnion || FieldRecord->
isUnion();
6764 NestedFieldOffset += NestedField->Offset;
6766 assert(NestedField);
6768 unsigned FirstLinkOffset =
6772 if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
6777 unsigned InitFieldOffset = 0;
6778 for (
const NamedDecl *ND : IFD->chain().drop_back()) {
6780 const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent());
6781 assert(FieldRecord);
6782 NestedField = FieldRecord->
getField(FD);
6783 InitFieldOffset += NestedField->Offset;
6784 assert(NestedField);
6785 if (!this->emitGetPtrThisField(InitFieldOffset, InitExpr))
6787 if (!this->emitFinishInitPop(InitExpr))
6792 assert(
Init->isDelegatingInitializer());
6793 if (!this->emitThis(InitExpr))
6795 if (!this->visitInitializer(
Init->getInit()))
6797 if (!this->emitPopPtr(InitExpr))
6801 if (!
Scope.destroyLocals())
6808 if (
const auto *CS = dyn_cast<CompoundStmt>(Body)) {
6809 if (!CS->body_empty() && !this->emitCtorCheck(
SourceInfo{}))
6816 if (!visitStmt(Body))
6823template <
class Emitter>
6826 const Record *R = this->getRecord(RD);
6831 if (!this->visitStmt(Dtor->
getBody()))
6835 if (!this->emitThis(Dtor))
6838 if (!this->emitCheckDestruction(Dtor))
6846 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
6850 if (!this->emitGetPtrField(Field.Offset,
SourceInfo{}))
6852 if (!this->emitDestructionPop(D,
SourceInfo{}))
6857 for (
const Record::Base &
Base : llvm::reverse(R->
bases())) {
6858 if (
Base.R->hasTrivialDtor())
6862 if (!this->emitRecordDestructionPop(
Base.R, {}))
6867 return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
6870template <
class Emitter>
6871bool Compiler<Emitter>::compileUnionAssignmentOperator(
6873 if (!this->emitThis(MD))
6882 return this->emitMemcpy(MD) && this->emitRet(
PT_Ptr, MD);
6885template <
class Emitter>
6892 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
6893 return this->compileConstructor(Ctor);
6894 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(F))
6895 return this->compileDestructor(Dtor);
6898 if (
const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
6903 return this->compileUnionAssignmentOperator(MD);
6906 return this->emitLambdaStaticInvokerBody(MD);
6910 if (
const auto *Body = F->
getBody())
6924 return FD->getBitWidthValue();
6927template <
class Emitter>
6940 if (!
Ctx.getLangOpts().CPlusPlus14)
6941 return this->emitInvalid(E);
6943 return this->emitError(E);
6945 if (!this->
visit(SubExpr))
6949 if (!this->emitIncPtr(E))
6956 return DiscardResult ? this->emitIncfPop(getFPOptions(E), E)
6957 : this->emitIncf(getFPOptions(E), E);
6969 if (!
Ctx.getLangOpts().CPlusPlus14)
6970 return this->emitInvalid(E);
6972 return this->emitError(E);
6974 if (!this->
visit(SubExpr))
6978 if (!this->emitDecPtr(E))
6985 return DiscardResult ? this->emitDecfPop(getFPOptions(E), E)
6986 : this->emitDecf(getFPOptions(E), E);
6999 if (!
Ctx.getLangOpts().CPlusPlus14)
7000 return this->emitInvalid(E);
7002 return this->emitError(E);
7004 if (!this->
visit(SubExpr))
7008 if (!this->emitLoadPtr(E))
7010 if (!this->emitConstUint8(1, E))
7012 if (!this->emitAddOffsetUint8(E))
7014 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7020 return this->emitIncfPop(getFPOptions(E), E);
7030 const auto &TargetSemantics =
Ctx.getFloatSemantics(E->
getType());
7031 if (!this->emitLoadFloat(E))
7033 APFloat F(TargetSemantics, 1);
7034 if (!this->emitFloat(F, E))
7037 if (!this->emitAddf(getFPOptions(E), E))
7039 if (!this->emitStoreFloat(E))
7051 return E->
isGLValue() || this->emitLoadPop(*T, E);
7054 if (!
Ctx.getLangOpts().CPlusPlus14)
7055 return this->emitInvalid(E);
7057 return this->emitError(E);
7059 if (!this->
visit(SubExpr))
7063 if (!this->emitLoadPtr(E))
7065 if (!this->emitConstUint8(1, E))
7067 if (!this->emitSubOffsetUint8(E))
7069 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
7075 return this->emitDecfPop(getFPOptions(E), E);
7085 const auto &TargetSemantics =
Ctx.getFloatSemantics(E->
getType());
7086 if (!this->emitLoadFloat(E))
7088 APFloat F(TargetSemantics, 1);
7089 if (!this->emitFloat(F, E))
7092 if (!this->emitSubf(getFPOptions(E), E))
7094 if (!this->emitStoreFloat(E))
7106 return E->
isGLValue() || this->emitLoadPop(*T, E);
7110 return this->emitError(E);
7113 return this->
discard(SubExpr);
7118 if (!this->emitInv(E))
7122 return this->emitCast(
PT_Bool, ET, E);
7126 return this->emitError(E);
7128 if (!this->
visit(SubExpr))
7130 return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
7133 return this->emitError(E);
7135 if (!this->
visit(SubExpr))
7150 return this->
discard(SubExpr);
7152 if (!this->
visit(SubExpr))
7159 return this->emitNarrowPtr(E);
7164 return this->emitError(E);
7166 if (!this->
visit(SubExpr))
7168 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
7180 : this->visitZeroInitializer(*T, SubExpr->
getType(), SubExpr);
7185 assert(
false &&
"Unhandled opcode");
7191template <
class Emitter>
7197 return this->
discard(SubExpr);
7200 auto prepareResult = [=]() ->
bool {
7205 return this->emitGetPtrLocal(*LocalIndex, E);
7212 unsigned SubExprOffset = ~0u;
7213 auto createTemp = [=, &SubExprOffset]() ->
bool {
7216 if (!this->
visit(SubExpr))
7218 return this->emitSetLocal(
PT_Ptr, SubExprOffset, E);
7222 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
7223 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
7225 return this->emitArrayElemPop(ElemT, Index, E);
7230 if (!prepareResult())
7234 for (
unsigned I = 0; I != 2; ++I) {
7235 if (!getElem(SubExprOffset, I))
7237 if (!this->emitNeg(ElemT, E))
7239 if (!this->emitInitElem(ElemT, I, E))
7250 if (!this->
visit(SubExpr))
7252 if (!this->emitComplexBoolCast(SubExpr))
7254 if (!this->emitInv(E))
7257 return this->emitCast(
PT_Bool, ET, E);
7261 return this->emitComplexReal(SubExpr);
7264 if (!this->
visit(SubExpr))
7268 if (!this->emitConstUint8(1, E))
7270 return this->emitArrayElemPtrPopUint8(E);
7281 if (!this->emitArrayElem(ElemT, 1, E))
7283 if (!this->emitNeg(ElemT, E))
7285 if (!this->emitInitElem(ElemT, 1, E))
7293 return this->emitInvalid(E);
7299template <
class Emitter>
7305 return this->
discard(SubExpr);
7308 if (UnaryOp == UO_Extension)
7311 if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
7312 UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
7313 return this->emitInvalid(E);
7316 if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
7323 if (!this->emitGetPtrLocal(*LocalIndex, E))
7328 unsigned SubExprOffset =
7330 if (!this->
visit(SubExpr))
7332 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, E))
7337 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
7338 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
7340 return this->emitArrayElemPop(ElemT, Index, E);
7345 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
7346 if (!getElem(SubExprOffset, I))
7348 if (!this->emitNeg(ElemT, E))
7350 if (!this->emitInitElem(ElemT, I, E))
7365 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
7366 if (!getElem(SubExprOffset, I))
7369 if (!this->emitPrimCast(ElemT,
PT_Bool,
Ctx.getASTContext().BoolTy, E))
7371 if (!this->emitInv(E))
7373 if (!this->emitPrimCast(
PT_Bool, ElemT, VecTy->getElementType(), E))
7375 if (!this->emitNeg(ElemT, E))
7377 if (ElemT != ResultVecElemT &&
7378 !this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy, E))
7380 if (!this->emitInitElem(ResultVecElemT, I, E))
7386 for (
unsigned I = 0; I != VecTy->getNumElements(); ++I) {
7387 if (!getElem(SubExprOffset, I))
7390 if (!this->emitInv(E))
7393 if (!this->emitComp(ElemT, E))
7396 if (!this->emitInitElem(ElemT, I, E))
7401 llvm_unreachable(
"Unsupported unary operators should be handled up front");
7406template <
class Emitter>
7411 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(D))
7412 return this->emitConst(ECD->getInitVal(), E);
7413 if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
7415 return F && this->emitGetFnPtr(F, E);
7417 if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
7419 if (!this->emitGetPtrGlobal(*Index, E))
7424 return this->emitInitGlobal(*T, *Index, E);
7428 return this->emitFinishInit(E);
7443 if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
7444 if (
Ctx.getLangOpts().CPlusPlus && !
Ctx.getLangOpts().CPlusPlus11 &&
7449 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
7450 if (IsReference || !It->second.IsPtr)
7451 return this->emitGetParam(
classifyPrim(E), It->second.Offset, E);
7453 return this->emitGetPtrParam(It->second.Offset, E);
7456 if (!
Ctx.getLangOpts().CPlusPlus23 && IsReference)
7462 const unsigned Offset = It->second.Offset;
7465 return this->emitGetPtrLocal(Offset, E);
7468 if (
auto GlobalIndex =
P.getGlobal(D)) {
7470 if (!
Ctx.getLangOpts().CPlusPlus11)
7471 return this->emitGetGlobal(
classifyPrim(E), *GlobalIndex, E);
7472 return this->emitGetGlobalUnchecked(
classifyPrim(E), *GlobalIndex, E);
7475 return this->emitGetPtrGlobal(*GlobalIndex, E);
7479 auto revisit = [&](
const VarDecl *VD) ->
bool {
7482 auto VarState = this->
visitDecl(VD,
true);
7484 if (!this->emitPopCC(E))
7487 if (VarState.notCreated())
7496 if (
auto It = this->LambdaCaptures.find(D);
7497 It != this->LambdaCaptures.end()) {
7498 auto [Offset, IsPtr] = It->second;
7501 return this->emitGetThisFieldPtr(Offset, E);
7502 return this->emitGetPtrThisField(Offset, E);
7505 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E);
7506 DRE && DRE->refersToEnclosingVariableOrCapture()) {
7507 if (
const auto *VD = dyn_cast<VarDecl>(D); VD && VD->
isInitCapture())
7511 if (
const auto *BD = dyn_cast<BindingDecl>(D))
7512 return this->
visit(BD->getBinding());
7516 return this->emitDummyPtr(D, E);
7520 const auto *VD = dyn_cast<VarDecl>(D);
7522 return this->emitError(E);
7525 if (!
Ctx.getLangOpts().CPlusPlus) {
7529 return this->emitDummyPtr(D, E);
7533 const auto typeShouldBeVisited = [&](
QualType T) ->
bool {
7534 if (T.isConstant(
Ctx.getASTContext()))
7536 return T->isReferenceType();
7540 typeShouldBeVisited(DeclType)) {
7542 Init && !
Init->isValueDependent()) {
7548 (void)
Init->EvaluateAsInitializer(
V,
Ctx.getASTContext(), VD, Notes,
7573 return this->emitDummyPtr(D, E);
7576template <
class Emitter>
7584 if (!
C->destroyLocals())
7590template <
class Emitter>
7591unsigned Compiler<Emitter>::collectBaseOffset(
const QualType BaseType,
7594 if (
const auto *R = Ty->getPointeeCXXRecordDecl())
7596 return Ty->getAsCXXRecordDecl();
7598 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
7599 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
7601 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
7605template <
class Emitter>
7612 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
7617 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT),
7618 getFPOptions(E), E);
7620 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT),
7621 getFPOptions(E), E);
7625 return this->emitCastFloatingIntegral(ToT, getFPOptions(E), E);
7630 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
7632 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
7636 return FromT != ToT ? this->emitCast(FromT, ToT, E) :
true;
7640 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
7641 return this->emitCastIntegralFloating(FromT, ToSem, getFPOptions(E), E);
7648template <
class Emitter>
7651 assert(FromT != ToT);
7654 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
7656 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
7658 return this->emitCast(FromT, ToT, E);
7662template <
class Emitter>
7663bool Compiler<Emitter>::emitComplexReal(
const Expr *SubExpr) {
7667 return this->
discard(SubExpr);
7669 if (!this->visit(SubExpr))
7672 if (!this->emitConstUint8(0, SubExpr))
7674 return this->emitArrayElemPtrPopUint8(SubExpr);
7678 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
7682template <
class Emitter>
7683bool Compiler<Emitter>::emitComplexBoolCast(
const Expr *E) {
7684 assert(!DiscardResult);
7688 if (!this->emitArrayElem(ElemT, 0, E))
7691 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(E), E))
7694 if (!this->emitCast(ElemT,
PT_Bool, E))
7699 LabelTy LabelTrue = this->getLabel();
7700 if (!this->jumpTrue(LabelTrue))
7703 if (!this->emitArrayElemPop(ElemT, 1, E))
7706 if (!this->emitCastFloatingIntegral(
PT_Bool, getFPOptions(E), E))
7709 if (!this->emitCast(ElemT,
PT_Bool, E))
7713 LabelTy EndLabel = this->getLabel();
7714 this->jump(EndLabel);
7716 this->emitLabel(LabelTrue);
7717 if (!this->emitPopPtr(E))
7719 if (!this->emitConstBool(
true, E))
7722 this->fallthrough(EndLabel);
7723 this->emitLabel(EndLabel);
7728template <
class Emitter>
7729bool Compiler<Emitter>::emitComplexComparison(
const Expr *LHS,
const Expr *RHS,
7740 LHSIsComplex =
true;
7741 ElemT = classifyComplexElementType(LHS->
getType());
7742 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true);
7743 if (!this->visit(LHS))
7745 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
7748 LHSIsComplex =
false;
7750 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true);
7751 if (!this->visit(LHS))
7753 if (!this->emitSetLocal(LHST, LHSOffset, E))
7760 RHSIsComplex =
true;
7761 ElemT = classifyComplexElementType(RHS->
getType());
7762 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true);
7763 if (!this->visit(RHS))
7765 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
7768 RHSIsComplex =
false;
7770 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true);
7771 if (!this->visit(RHS))
7773 if (!this->emitSetLocal(RHST, RHSOffset, E))
7777 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
7778 bool IsComplex) ->
bool {
7780 if (!this->emitGetLocal(
PT_Ptr, LocalOffset, E))
7782 return this->emitArrayElemPop(ElemT, Index, E);
7784 return this->emitGetLocal(ElemT, LocalOffset, E);
7787 for (
unsigned I = 0; I != 2; ++I) {
7789 if (!getElem(LHSOffset, I, LHSIsComplex))
7791 if (!getElem(RHSOffset, I, RHSIsComplex))
7794 if (!this->emitEQ(ElemT, E))
7797 if (!this->emitCastBoolUint8(E))
7802 if (!this->emitAddUint8(E))
7804 if (!this->emitConstUint8(2, E))
7808 if (!this->emitEQUint8(E))
7811 if (!this->emitNEUint8(E))
7818 return this->emitCast(
PT_Bool, ResT, E);
7825template <
class Emitter>
7826bool Compiler<Emitter>::emitRecordDestructionPop(
const Record *R,
7832 const Function *DtorFunc = getFunction(Dtor);
7835 assert(DtorFunc->hasThisPointer());
7836 assert(DtorFunc->getNumParams() == 1);
7837 return this->emitCall(DtorFunc, 0, Loc);
7842template <
class Emitter>
7843bool Compiler<Emitter>::emitDestructionPop(
const Descriptor *Desc,
7855 return this->emitPopPtr(Loc);
7857 for (ssize_t I = N - 1; I >= 1; --I) {
7858 if (!this->emitConstUint64(I, Loc))
7860 if (!this->emitArrayElemPtrUint64(Loc))
7862 if (!this->emitDestructionPop(ElemDesc, Loc))
7866 if (!this->emitConstUint64(0, Loc))
7868 if (!this->emitArrayElemPtrPopUint64(Loc))
7870 return this->emitDestructionPop(ElemDesc, Loc);
7875 return this->emitRecordDestructionPop(Desc->
ElemRecord, Loc);
7880template <
class Emitter>
7881bool Compiler<Emitter>::emitDummyPtr(
const DeclTy &D,
const Expr *E) {
7882 assert(!DiscardResult &&
"Should've been checked before");
7883 unsigned DummyID = P.getOrCreateDummy(D);
7885 if (!this->emitGetPtrGlobal(DummyID, E))
7893 return this->emitDecayPtr(
PT_Ptr, PT, E);
7899template <
class Emitter>
7900bool Compiler<Emitter>::emitFloat(
const APFloat &F,
const Expr *E) {
7902 return this->emitConstFloat(
Floating(F), E);
7904 APInt I = F.bitcastToAPInt();
7905 return this->emitConstFloat(
7906 Floating(
const_cast<uint64_t *
>(I.getRawData()),
7907 llvm::APFloatBase::SemanticsToEnum(F.getSemantics())),
7918template <
class Emitter>
7919bool Compiler<Emitter>::emitBuiltinBitCast(
const CastExpr *E) {
7932 if (!this->emitGetPtrLocal(*LocalIndex, E))
7942 if (!this->visit(SubExpr))
7944 }
else if (
OptPrimType FromT = classify(SubExpr)) {
7945 unsigned TempOffset =
7946 allocateLocalPrimitive(SubExpr, *FromT,
true);
7947 if (!this->visit(SubExpr))
7949 if (!this->emitSetLocal(*FromT, TempOffset, E))
7951 if (!this->emitGetPtrLocal(TempOffset, E))
7958 if (!this->emitBitCast(E))
7960 return DiscardResult ? this->emitPopPtr(E) :
true;
7964 const llvm::fltSemantics *TargetSemantics =
nullptr;
7966 TargetSemantics = &Ctx.getFloatSemantics(ToType);
7972 uint32_t ResultBitWidth = std::max(Ctx.getBitWidth(ToType), 8u);
7974 if (!this->emitBitCastPrim(*ToT, ToTypeIsUChar || ToType->
isStdByteType(),
7975 ResultBitWidth, TargetSemantics,
7980 return this->emitPop(*ToT, E);
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static void emitCleanup(CIRGenFunction &cgf, cir::CleanupScopeOp cleanupScope, EHScopeStack::Cleanup *cleanup, EHScopeStack::Cleanup::Flags flags)
static uint32_t getBitWidth(const Expr *E)
#define EMIT_ARITH_OP(OP)
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
static const Expr * stripDerivedToBaseCasts(const Expr *E)
static const Expr * stripCheckedDerivedToBaseCasts(const Expr *E)
static bool hasTrivialDefaultCtorParent(const FieldDecl *FD)
static bool initNeedsOverridenLoc(const CXXCtorInitializer *Init)
a trap message and trap category.
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
ArrayRef< LValuePathEntry > getLValuePath() const
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
unsigned getStructNumFields() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
bool isMemberPointer() const
unsigned getArraySize() const
@ None
There is no such object (it's outside its lifetime).
bool isNullPointer() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
const LangOptions & getLangOpts() const
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const VariableArrayType * getAsVariableArrayType(QualType T) const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
AddrLabelExpr - The GNU address of label extension, representing &&label.
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Represents a loop initializing the elements of an array.
llvm::APInt getArraySize() const
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
uint64_t getValue() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Attr - This represents one attribute.
Represents an attribute applied to a statement.
ArrayRef< const Attr * > getAttrs() const
Represents a C++ declaration that introduces decls from somewhere else.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
static bool isShiftOp(Opcode Opc)
static bool isCommaOp(Opcode Opc)
static Opcode getOpForCompoundAssignment(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
static bool isAssignmentOp(Opcode Opc)
static bool isCompoundAssignmentOp(Opcode Opc)
static bool isBitwiseOp(Opcode Opc)
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
BreakStmt - This represents a break.
Represents a C++2a __builtin_bit_cast(T, v) expression.
Represents a base class of a C++ class.
Represents binding an expression to a temporary.
const Expr * getSubExpr() const
A boolean literal, per ([C++ lex.bool] Boolean literals).
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Expr * getArg(unsigned Arg)
Return the specified argument.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
Represents a C++ base or member initializer.
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Expr * getExpr()
Get the initialization expression that will be used.
Represents a delete expression for memory deallocation and destructor calls, e.g.
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a C++ destructor within a class.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
DeclStmt * getBeginStmt()
DeclStmt * getLoopVarStmt()
DeclStmt * getRangeStmt()
Represents a call to an inherited base class constructor from an inheriting constructor.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
QualType getAllocatedType() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Expr * getPlacementArg(unsigned I)
unsigned getNumPlacementArgs() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a list-initialization with parenthesis.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
capture_const_range captures() const
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
A rewritten comparison expression that was originally written using operator syntax.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
An expression "T()" which creates an rvalue of a non-class type T.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Represents the this expression in C++.
A C++ throw-expression (C++ [except.throw]).
const Expr * getSubExpr() const
CXXTryStmt - A C++ try block, including all handlers.
CompoundStmt * getTryBlock()
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
bool isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
MSGuidDecl * getGuidDecl() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Expr ** getArgs()
Retrieve the call arguments.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
unsigned getValue() const
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
CompoundLiteralExpr - [C99 6.5.2.5].
const Expr * getInitializer() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Represents the specialization of a concept - evaluates to a prvalue of type bool.
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
Represents the canonical version of C arrays with a specified constant size.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
ContinueStmt - This represents a continue.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInvalidDecl() const
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
bool isAnyOperatorNew() const
DoStmt - This represents a 'do/while' stmt.
const Expr * getBase() const
Represents a reference to emded data.
ChildElementIter< false > begin()
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool isValueDependent() const
Determines whether the value of this expression depends on.
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
An expression trait intrinsic.
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
Represents a member of a struct/union/class.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
DeclStmt * getConditionVariableDeclStmt()
If this ForStmt has a condition variable, return the faux DeclStmt associated with the creation of th...
const Expr * getSubExpr() const
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
bool isDefaulted() const
Whether this function is defaulted.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
Expr * getResultExpr()
Return the result expression of this controlling expression.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
bool isNegatedConsteval() const
DeclStmt * getConditionVariableDeclStmt()
If this IfStmt has a condition variable, return the faux DeclStmt associated with the creation of tha...
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
Describes an C or C++ initializer list.
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
ArrayRef< Expr * > inits()
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
const Stmt * getNamedLoopOrSwitch() const
If this is a named break/continue, get the loop or switch statement that this targets.
APValue & getAsAPValue() const
Get the value of this MSGuidDecl as an APValue.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
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.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
bool isExpressibleAsConstantInitializer() const
ObjCEncodeExpr, used for @encode in Objective-C.
QualType getEncodedType() const
SourceLocation getAtLoc() const
ObjCStringLiteral, used for Objective-C string literals i.e.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
unsigned getNumComponents() const
Helper class for OffsetOfExpr.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
@ Array
An index into an array.
Kind getKind() const
Determine what kind of offsetof node this is.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
ParenExpr - This represents a parenthesized expression, e.g.
const Expr * getSubExpr() const
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
[C99 6.4.2.2] - A predefined identifier such as func.
StringLiteral * getFunctionName()
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
bool isConstant(const ASTContext &Ctx) const
bool isConstQualified() const
Determine whether this type is const-qualified.
Represents a struct/union/class.
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Base for LValueReferenceType and RValueReferenceType.
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
bool isSatisfied() const
Whether or not the requires clause is satisfied.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
SourceLocation getLocation() const
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Represents an expression that computes the length of a parameter pack.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Represents a C++11 static_assert declaration.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
CompoundStmt * getSubStmt()
bool Visit(PTR(Stmt) S, ParamTys... P)
Stmt - This represents one statement.
StmtClass getStmtClass() const
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, ArrayRef< SourceLocation > Locs)
This is the "fully general" constructor that allows representation of strings formed from one or more...
uint32_t getCodeUnit(size_t i) const
unsigned getCharByteWidth() const
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Expr * getReplacement() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
DeclStmt * getConditionVariableDeclStmt()
If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
The base class of the type hierarchy.
bool isBooleanType() const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isConstantMatrixType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isAtomicType() const
EnumDecl * castAsEnumDecl() const
bool isStdByteType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isPointerOrReferenceType() const
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represents C++ using-directive.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool isStaticDataMember() const
Determines whether this is a static data member.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
const Expr * getInit() const
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
DeclStmt * getConditionVariableDeclStmt()
If this WhileStmt has a condition variable, return the faux DeclStmt associated with the creation of ...
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
A memory block, either on the stack or in the heap.
void invokeDtor()
Invokes the Destructor.
Compilation context for expressions.
llvm::SmallVector< InitLink > InitStack
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E)
bool VisitCXXDeleteExpr(const CXXDeleteExpr *E)
bool VisitOffsetOfExpr(const OffsetOfExpr *E)
bool visitContinueStmt(const ContinueStmt *S)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init, OptPrimType InitT)
Pointer to the array(not the element!) must be on the stack when calling this.
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E)
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
PrimType classifyPrim(QualType Ty) const
Classifies a known primitive type.
bool VisitTypeTraitExpr(const TypeTraitExpr *E)
bool VisitLambdaExpr(const LambdaExpr *E)
bool VisitMemberExpr(const MemberExpr *E)
llvm::DenseMap< const OpaqueValueExpr *, unsigned > OpaqueExprs
OpaqueValueExpr to location mapping.
bool VisitBinaryOperator(const BinaryOperator *E)
bool visitAttributedStmt(const AttributedStmt *S)
bool VisitPackIndexingExpr(const PackIndexingExpr *E)
VarCreationState visitDecl(const VarDecl *VD, bool IsConstexprUnknown=false)
bool visitAPValueInitializer(const APValue &Val, const Expr *E, QualType T)
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
bool VisitCallExpr(const CallExpr *E)
std::optional< uint64_t > ArrayIndex
Current argument index. Needed to emit ArrayInitIndexExpr.
bool VisitPseudoObjectExpr(const PseudoObjectExpr *E)
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E)
const Function * getFunction(const FunctionDecl *FD)
Returns a function for the given FunctionDecl.
bool VisitFixedPointBinOp(const BinaryOperator *E)
bool VisitCastExpr(const CastExpr *E)
bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E)
bool VisitFixedPointUnaryOperator(const UnaryOperator *E)
bool VisitComplexUnaryOperator(const UnaryOperator *E)
llvm::DenseMap< const SwitchCase *, LabelTy > CaseMap
bool VisitBlockExpr(const BlockExpr *E)
bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E)
Visit an APValue.
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
bool VisitLogicalBinOp(const BinaryOperator *E)
bool visitCompoundStmt(const CompoundStmt *S)
Context & Ctx
Current compilation context.
bool visitDeclRef(const ValueDecl *D, const Expr *E)
Visit the given decl as if we have a reference to it.
bool visitBreakStmt(const BreakStmt *S)
bool visitExpr(const Expr *E, bool DestroyToplevelScope) override
bool visitForStmt(const ForStmt *S)
bool VisitDeclRefExpr(const DeclRefExpr *E)
bool VisitOpaqueValueExpr(const OpaqueValueExpr *E)
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E)
bool VisitStmtExpr(const StmtExpr *E)
bool VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *E)
bool VisitFixedPointLiteral(const FixedPointLiteral *E)
const FunctionDecl * CompilingFunction
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
VariableScope< Emitter > * VarScope
Current scope.
bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init, bool ConstantContext) override
Toplevel visitDeclAndReturn().
bool VisitCXXNewExpr(const CXXNewExpr *E)
const ValueDecl * InitializingDecl
bool VisitCompoundAssignOperator(const CompoundAssignOperator *E)
bool visit(const Expr *E) override
Evaluates an expression and places the result on the stack.
bool delegate(const Expr *E)
Just pass evaluation on to E.
bool discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
CaseMap CaseLabels
Switch case mapping.
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsVolatile=false, ScopeKind SC=ScopeKind::Block, bool IsConstexprUnknown=false)
Creates a local primitive value.
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
const RecordType * getRecordTy(QualType Ty)
Returns a record type from a record or pointer type.
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E)
bool visitInitList(ArrayRef< const Expr * > Inits, const Expr *ArrayFiller, const Expr *E)
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E)
bool VisitPredefinedExpr(const PredefinedExpr *E)
bool VisitSourceLocExpr(const SourceLocExpr *E)
bool visitDeclStmt(const DeclStmt *DS, bool EvaluateConditionDecl=false)
bool emitCleanup()
Emits scope cleanup instructions.
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E)
bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E)
bool visitInitializer(const Expr *E)
Compiles an initializer.
const Expr * SourceLocDefaultExpr
DefaultInit- or DefaultArgExpr, needed for SourceLocExpr.
UnsignedOrNone OptLabelTy
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E)
bool VisitPointerArithBinOp(const BinaryOperator *E)
Perform addition/subtraction of a pointer and an integer or subtraction of two pointers.
bool visitCallArgs(ArrayRef< const Expr * > Args, const FunctionDecl *FuncDecl, bool Activate, bool IsOperatorCall)
bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E)
bool visitDefaultStmt(const DefaultStmt *S)
typename Emitter::LabelTy LabelTy
bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E)
bool visitStmt(const Stmt *S)
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
bool VisitVectorUnaryOperator(const UnaryOperator *E)
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
VarCreationState visitVarDecl(const VarDecl *VD, const Expr *Init, bool Toplevel=false, bool IsConstexprUnknown=false)
Creates and initializes a variable from the given decl.
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
bool VisitRecoveryExpr(const RecoveryExpr *E)
bool VisitRequiresExpr(const RequiresExpr *E)
bool Initializing
Flag inidicating if we're initializing an already created variable.
bool visitReturnStmt(const ReturnStmt *RS)
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitChooseExpr(const ChooseExpr *E)
bool visitFunc(const FunctionDecl *F) override
bool visitCXXForRangeStmt(const CXXForRangeStmt *S)
bool visitCaseStmt(const CaseStmt *S)
bool VisitComplexBinOp(const BinaryOperator *E)
llvm::DenseMap< const ValueDecl *, Scope::Local > Locals
Variable to storage mapping.
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
bool VisitCXXTypeidExpr(const CXXTypeidExpr *E)
UnsignedOrNone allocateTemporary(const Expr *E)
bool VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinID)
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
OptPrimType ReturnType
Type of the expression returned by the function.
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
OptPrimType classify(const Expr *E) const
llvm::SmallVector< LabelInfo > LabelInfoStack
Stack of label information for loops and switch statements.
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
bool visitDoStmt(const DoStmt *S)
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitInitListExpr(const InitListExpr *E)
bool VisitVectorBinOp(const BinaryOperator *E)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitParenExpr(const ParenExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
bool DiscardResult
Flag indicating if return value is to be discarded.
bool VisitEmbedExpr(const EmbedExpr *E)
bool VisitConvertVectorExpr(const ConvertVectorExpr *E)
bool VisitCXXThisExpr(const CXXThisExpr *E)
bool VisitConstantExpr(const ConstantExpr *E)
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool visitSwitchStmt(const SwitchStmt *S)
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E)
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool visitAsLValue(const Expr *E)
bool visitWhileStmt(const WhileStmt *S)
bool visitIfStmt(const IfStmt *IS)
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
bool canClassify(const Expr *E) const
bool VisitFloatingLiteral(const FloatingLiteral *E)
Program & P
Program to link to.
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
bool VisitGNUNullExpr(const GNUNullExpr *E)
UnsignedOrNone allocateLocal(DeclTy &&Decl, QualType Ty=QualType(), ScopeKind=ScopeKind::Block, bool IsConstexprUnknown=false)
Allocates a space storing a local given its type.
bool VisitImaginaryLiteral(const ImaginaryLiteral *E)
bool VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E)
bool visitCXXTryStmt(const CXXTryStmt *S)
static bool isUnevaluatedBuiltin(unsigned ID)
Unevaluated builtins don't get their arguments put on the stack automatically.
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Scope used to handle temporaries in toplevel variable declarations.
DeclScope(Compiler< Emitter > *Ctx, const ValueDecl *VD)
Wrapper around fixed point types.
static FixedPoint zero(llvm::FixedPointSemantics Sem)
If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY.
bool hasThisPointer() const
bool hasRVO() const
Checks if the first argument is a RVO pointer.
When generating code for e.g.
LocOverrideScope(Compiler< Emitter > *Ctx, SourceInfo NewValue, bool Enabled=true)
Generic scope for local variables.
bool destroyLocals(const Expr *E=nullptr) override
Explicit destruction of local variables.
LocalScope(Compiler< Emitter > *Ctx, ScopeKind Kind=ScopeKind::Block)
Sets the context for break/continue statements.
typename Compiler< Emitter >::LabelTy LabelTy
typename Compiler< Emitter >::OptLabelTy OptLabelTy
typename Compiler< Emitter >::LabelInfo LabelInfo
LoopScope(Compiler< Emitter > *Ctx, const Stmt *Name, LabelTy BreakLabel, LabelTy ContinueLabel)
PrimType value_or(PrimType PT) const
Scope used to handle initialization methods.
OptionScope(Compiler< Emitter > *Ctx, bool NewDiscardResult, bool NewInitializing, bool NewToLValue)
Root constructor, compiling or discarding primitives.
Context to manage declaration lifetimes.
Structure/Class descriptor.
bool isUnion() const
Checks if the record is a union.
const Field * getField(unsigned I) const
const CXXDestructorDecl * getDestructor() const
Returns the destructor of the record, if any.
const Base * getBase(unsigned I) const
bool hasTrivialDtor() const
Returns true for anonymous unions and records with no destructor or for those with a trivial destruct...
const Base * getVirtualBase(unsigned I) const
llvm::iterator_range< const_base_iter > bases() const
unsigned getNumFields() const
llvm::iterator_range< const_field_iter > fields() const
Describes the statement/declaration an opcode was generated from.
StmtExprScope(Compiler< Emitter > *Ctx)
typename Compiler< Emitter >::LabelTy LabelTy
typename Compiler< Emitter >::OptLabelTy OptLabelTy
typename Compiler< Emitter >::LabelInfo LabelInfo
typename Compiler< Emitter >::CaseMap CaseMap
SwitchScope(Compiler< Emitter > *Ctx, const Stmt *Name, CaseMap &&CaseLabels, LabelTy BreakLabel, OptLabelTy DefaultLabel)
Scope chain managing the variable lifetimes.
Compiler< Emitter > * Ctx
Compiler instance.
virtual void addLocal(Scope::Local Local)
VariableScope * getParent() const
bool Sub(InterpState &S, CodePtr OpPC)
bool LT(InterpState &S, CodePtr OpPC)
static llvm::RoundingMode getRoundingMode(FPOptions FPO)
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
constexpr bool isSignedType(PrimType T)
bool Div(InterpState &S, CodePtr OpPC)
1) Pops the RHS from the stack.
static bool Activate(InterpState &S, CodePtr OpPC)
constexpr bool isPtrType(PrimType T)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool InitScope(InterpState &S, CodePtr OpPC, uint32_t I)
static void discard(InterpStack &Stk, PrimType T)
bool LE(InterpState &S, CodePtr OpPC)
PrimType
Enumeration of the primitive types of the VM.
static std::optional< bool > getBoolValue(const Expr *E)
bool Init(InterpState &S, CodePtr OpPC)
bool Mul(InterpState &S, CodePtr OpPC)
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
bool Inc(InterpState &S, CodePtr OpPC, bool CanOverflow)
1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...
bool Add(InterpState &S, CodePtr OpPC)
llvm::BitVector collectNonNullArgs(const FunctionDecl *F, ArrayRef< const Expr * > Args)
constexpr bool isIntegralType(PrimType T)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
bool hasSpecificAttr(const Container &container)
@ Success
Annotation was successful.
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
@ Result
The result type of a method or function.
U cast(CodeGen::Address addr)
int const char * function
Describes a memory block created by an allocation site.
unsigned getNumElems() const
Returns the number of elements stored in the block.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
QualType getElemQualType() const
bool hasTrivialDtor() const
Whether variables of this descriptor need their destructor called or not.
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
const Descriptor *const ElemDesc
Descriptor of the array element.
static constexpr MetadataSize InlineDescMD
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
bool isRecord() const
Checks if the descriptor is of a record.
const Record *const ElemRecord
Pointer to the record, if block contains records.
bool isArray() const
Checks if the descriptor is of an array.
Descriptor used for global variables.
GlobalInitState InitState
static InitLink InitList()
static InitLink Elem(unsigned Index)
bool emit(Compiler< Emitter > *Ctx, const Expr *E) const
static InitLink Field(unsigned Offset)
static InitLink Decl(const ValueDecl *D)
static InitLink Temp(unsigned Offset)
bool isUnnamedBitField() const
Information about a local's storage.
State encapsulating if a the variable creation has been successful, unsuccessful, or no variable has ...
static VarCreationState NotCreated()