54 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
55 OldInitializing(Ctx->Initializing) {
61 Ctx->DiscardResult = OldDiscardResult;
62 Ctx->Initializing = OldInitializing;
69 bool OldDiscardResult;
76template <
class Emitter>
81 case CK_LValueToRValue: {
83 return this->discard(SubExpr);
85 std::optional<PrimType> SubExprT = classify(SubExpr->
getType());
87 if (!Initializing && !SubExprT) {
88 std::optional<unsigned> LocalIndex =
89 allocateLocal(SubExpr,
false);
92 if (!this->emitGetPtrLocal(*LocalIndex, CE))
96 if (!this->visit(SubExpr))
100 return this->emitLoadPop(*SubExprT, CE);
105 return this->emitMemcpy(CE);
108 case CK_UncheckedDerivedToBase:
109 case CK_DerivedToBase: {
110 if (!this->visit(SubExpr))
113 unsigned DerivedOffset = collectBaseOffset(getRecordTy(CE->
getType()),
114 getRecordTy(SubExpr->
getType()));
116 return this->emitGetPtrBasePop(DerivedOffset, CE);
119 case CK_BaseToDerived: {
120 if (!this->visit(SubExpr))
123 unsigned DerivedOffset = collectBaseOffset(getRecordTy(SubExpr->
getType()),
126 return this->emitGetPtrDerivedPop(DerivedOffset, CE);
129 case CK_FloatingCast: {
131 return this->discard(SubExpr);
132 if (!this->visit(SubExpr))
134 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
135 return this->emitCastFP(TargetSemantics, getRoundingMode(CE), CE);
138 case CK_IntegralToFloating: {
140 return this->discard(SubExpr);
141 std::optional<PrimType> FromT = classify(SubExpr->
getType());
145 if (!this->visit(SubExpr))
148 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
149 llvm::RoundingMode RM = getRoundingMode(CE);
150 return this->emitCastIntegralFloating(*FromT, TargetSemantics, RM, CE);
153 case CK_FloatingToBoolean:
154 case CK_FloatingToIntegral: {
156 return this->discard(SubExpr);
158 std::optional<PrimType> ToT = classify(CE->
getType());
163 if (!this->visit(SubExpr))
167 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->
getType()),
170 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->
getType()),
173 return this->emitCastFloatingIntegral(*ToT, CE);
176 case CK_NullToPointer: {
182 if (!PointeeType.
isNull()) {
183 if (std::optional<PrimType>
T = classify(PointeeType))
184 Desc =
P.createDescriptor(SubExpr, *
T);
186 return this->emitNull(classifyPrim(CE->
getType()), Desc, CE);
189 case CK_PointerToIntegral: {
191 return this->discard(SubExpr);
193 if (!this->visit(SubExpr))
197 return this->emitCastPointerIntegral(
T, CE);
200 case CK_ArrayToPointerDecay: {
201 if (!this->visit(SubExpr))
203 if (!this->emitArrayDecay(CE))
206 return this->emitPopPtr(CE);
210 case CK_IntegralToPointer: {
213 if (!this->visit(SubExpr))
219 return this->emitPop(
T, CE);
226 Desc =
P.createDescriptor(SubExpr, *
T);
234 if (!this->emitGetIntPtr(
T, Desc, CE))
237 PrimType DestPtrT = classifyPrim(PtrType);
242 return this->emitDecayPtr(
PT_Ptr, DestPtrT, CE);
245 case CK_AtomicToNonAtomic:
246 case CK_ConstructorConversion:
247 case CK_FunctionToPointerDecay:
248 case CK_NonAtomicToAtomic:
250 case CK_UserDefinedConversion:
251 return this->delegate(SubExpr);
256 if (!this->discard(SubExpr))
258 return this->emitInvalidCast(CastKind::Reinterpret, CE);
262 return this->discard(SubExpr);
264 std::optional<PrimType> FromT = classify(SubExpr->
getType());
265 std::optional<PrimType> ToT = classify(CE->
getType());
272 return this->delegate(SubExpr);
274 if (!this->visit(SubExpr))
276 return this->emitDecayPtr(*FromT, *ToT, CE);
279 case CK_IntegralToBoolean:
280 case CK_IntegralCast: {
282 return this->discard(SubExpr);
283 std::optional<PrimType> FromT = classify(SubExpr->
getType());
284 std::optional<PrimType> ToT = classify(CE->
getType());
289 if (!this->visit(SubExpr))
293 return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->
getType()), CE);
295 return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->
getType()), CE);
299 return this->emitCast(*FromT, *ToT, CE);
302 case CK_PointerToBoolean: {
306 if (!this->visit(SubExpr))
309 if (!this->emitNull(PtrT,
nullptr, CE))
312 return this->emitNE(PtrT, CE);
315 case CK_IntegralComplexToBoolean:
316 case CK_FloatingComplexToBoolean: {
318 return this->discard(SubExpr);
319 if (!this->visit(SubExpr))
321 return this->emitComplexBoolCast(SubExpr);
324 case CK_IntegralComplexToReal:
325 case CK_FloatingComplexToReal:
326 return this->emitComplexReal(SubExpr);
328 case CK_IntegralRealToComplex:
329 case CK_FloatingRealToComplex: {
333 std::optional<unsigned> LocalIndex =
334 allocateLocal(CE,
true);
337 if (!this->emitGetPtrLocal(*LocalIndex, CE))
342 if (!this->visitArrayElemInit(0, SubExpr))
346 if (!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
348 return this->emitInitElem(
T, 1, SubExpr);
351 case CK_IntegralComplexCast:
352 case CK_FloatingComplexCast:
353 case CK_IntegralComplexToFloatingComplex:
354 case CK_FloatingComplexToIntegralComplex: {
358 return this->discard(SubExpr);
361 std::optional<unsigned> LocalIndex =
362 allocateLocal(CE,
true);
365 if (!this->emitGetPtrLocal(*LocalIndex, CE))
372 unsigned SubExprOffset = allocateLocalPrimitive(
373 SubExpr,
PT_Ptr,
true,
false);
374 if (!this->visit(SubExpr))
376 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, CE))
382 PrimType DestElemT = classifyPrim(DestElemType);
384 for (
unsigned I = 0; I != 2; ++I) {
385 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, CE))
387 if (!this->emitArrayElemPop(SourceElemT, I, CE))
391 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
395 if (!this->emitInitElem(DestElemT, I, CE))
401 case CK_VectorSplat: {
402 assert(!classify(CE->
getType()));
403 assert(classify(SubExpr->
getType()));
407 return this->discard(SubExpr);
409 assert(Initializing);
411 PrimType ElemT = classifyPrim(SubExpr);
412 unsigned ElemOffset = allocateLocalPrimitive(
413 SubExpr, ElemT,
true,
false);
415 if (!this->visit(SubExpr))
417 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
420 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
421 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
423 if (!this->emitInitElem(ElemT, I, CE))
431 return discard(SubExpr);
434 return this->emitInvalid(CE);
436 llvm_unreachable(
"Unhandled clang::CastKind enum");
439template <
class Emitter>
444 return this->emitConst(
LE->getValue(),
LE);
447template <
class Emitter>
452 return this->emitConstFloat(E->
getValue(), E);
455template <
class Emitter>
463 std::optional<unsigned> LocalIndex = allocateLocal(E,
false);
466 if (!this->emitGetPtrLocal(*LocalIndex, E))
473 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
475 if (!this->emitInitElem(SubExprT, 0, SubExpr))
477 return this->visitArrayElemInit(1, SubExpr);
480template <
class Emitter>
485template <
class Emitter>
489 return this->VisitLogicalBinOp(BO);
497 if (!this->discard(LHS))
500 return this->discard(RHS);
502 return this->delegate(RHS);
506 return this->VisitComplexBinOp(BO);
510 return this->emitComplexComparison(LHS, RHS, BO);
513 return this->visit(RHS);
516 std::optional<PrimType>
LT = classify(LHS->
getType());
517 std::optional<PrimType> RT = classify(RHS->
getType());
518 std::optional<PrimType>
T = classify(BO->
getType());
527 Ctx.getASTContext().CompCategories.lookupInfoForType(BO->
getType());
532 std::optional<unsigned> ResultIndex = this->allocateLocal(BO,
false);
533 if (!this->emitGetPtrLocal(*ResultIndex, BO))
537 if (!visit(LHS) || !visit(RHS))
540 return this->emitCMP3(*
LT, CmpInfo, BO);
543 if (!
LT || !RT || !
T)
549 return this->VisitPointerArithBinOp(BO);
552 if (!visit(LHS) || !visit(RHS))
557 auto MaybeCastToBool = [
this,
T, BO](
bool Result) {
561 return this->emitPop(*
T, BO);
563 return this->emitCast(
PT_Bool, *
T, BO);
567 auto Discard = [
this,
T, BO](
bool Result) {
570 return DiscardResult ? this->emitPop(*
T, BO) :
true;
575 return MaybeCastToBool(this->emitEQ(*
LT, BO));
577 return MaybeCastToBool(this->emitNE(*
LT, BO));
579 return MaybeCastToBool(this->emitLT(*
LT, BO));
581 return MaybeCastToBool(this->emitLE(*
LT, BO));
583 return MaybeCastToBool(this->emitGT(*
LT, BO));
585 return MaybeCastToBool(this->emitGE(*
LT, BO));
588 return Discard(this->emitSubf(getRoundingMode(BO), BO));
589 return Discard(this->emitSub(*
T, BO));
592 return Discard(this->emitAddf(getRoundingMode(BO), BO));
593 return Discard(this->emitAdd(*
T, BO));
596 return Discard(this->emitMulf(getRoundingMode(BO), BO));
597 return Discard(this->emitMul(*
T, BO));
599 return Discard(this->emitRem(*
T, BO));
602 return Discard(this->emitDivf(getRoundingMode(BO), BO));
603 return Discard(this->emitDiv(*
T, BO));
607 : this->emitStorePop(*
T, BO);
609 if (!this->emitStoreBitField(*
T, BO))
612 if (!this->emitStore(*
T, BO))
618 return this->emitLoadPop(*
T, BO);
621 return Discard(this->emitBitAnd(*
T, BO));
623 return Discard(this->emitBitOr(*
T, BO));
625 return Discard(this->emitShl(*
LT, *RT, BO));
627 return Discard(this->emitShr(*
LT, *RT, BO));
629 return Discard(this->emitBitXor(*
T, BO));
632 llvm_unreachable(
"Already handled earlier");
637 llvm_unreachable(
"Unhandled binary op");
642template <
class Emitter>
648 if ((Op != BO_Add && Op != BO_Sub) ||
652 std::optional<PrimType>
LT = classify(LHS);
653 std::optional<PrimType> RT = classify(RHS);
663 if (!visit(RHS) || !visit(LHS))
666 return this->emitSubPtr(classifyPrim(E->
getType()), E);
671 if (!visit(RHS) || !visit(LHS))
675 if (!visit(LHS) || !visit(RHS))
683 return this->emitAddOffset(OffsetType, E);
684 else if (Op == BO_Sub)
685 return this->emitSubOffset(OffsetType, E);
690template <
class Emitter>
696 std::optional<PrimType>
T = classify(E->
getType());
700 LabelTy LabelTrue = this->getLabel();
701 LabelTy LabelEnd = this->getLabel();
703 if (!this->visitBool(LHS))
705 if (!this->jumpTrue(LabelTrue))
708 if (!this->visitBool(RHS))
710 if (!this->jump(LabelEnd))
713 this->emitLabel(LabelTrue);
714 this->emitConstBool(
true, E);
715 this->fallthrough(LabelEnd);
716 this->emitLabel(LabelEnd);
719 assert(Op == BO_LAnd);
722 LabelTy LabelFalse = this->getLabel();
723 LabelTy LabelEnd = this->getLabel();
725 if (!this->visitBool(LHS))
727 if (!this->jumpFalse(LabelFalse))
730 if (!this->visitBool(RHS))
732 if (!this->jump(LabelEnd))
735 this->emitLabel(LabelFalse);
736 this->emitConstBool(
false, E);
737 this->fallthrough(LabelEnd);
738 this->emitLabel(LabelEnd);
742 return this->emitPopBool(E);
747 return this->emitCast(
PT_Bool, *
T, E);
751template <
class Emitter>
755 std::optional<unsigned> LocalIndex = allocateLocal(E,
false);
758 if (!this->emitGetPtrLocal(*LocalIndex, E))
768 unsigned ResultOffset = ~0u;
770 ResultOffset = this->allocateLocalPrimitive(E,
PT_Ptr,
true,
false);
773 if (!this->DiscardResult) {
774 if (!this->emitDupPtr(E))
776 if (!this->emitSetLocal(
PT_Ptr, ResultOffset, E))
781 LHSType = AT->getValueType();
784 RHSType = AT->getValueType();
791 LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
792 if (!this->visit(LHS))
794 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
797 LHSIsComplex =
false;
798 PrimType LHST = classifyPrim(LHSType);
799 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
800 if (!this->visit(LHS))
802 if (!this->emitSetLocal(LHST, LHSOffset, E))
811 RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
812 if (!this->visit(RHS))
814 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
817 RHSIsComplex =
false;
818 PrimType RHST = classifyPrim(RHSType);
819 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
820 if (!this->visit(RHS))
822 if (!this->emitSetLocal(RHST, RHSOffset, E))
829 auto loadComplexValue = [
this](
bool IsComplex,
unsigned ElemIndex,
830 unsigned Offset,
const Expr *E) ->
bool {
832 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
834 return this->emitArrayElemPop(classifyComplexElementType(E->
getType()),
838 return this->emitGetLocal(classifyPrim(E->
getType()), Offset, E);
839 return this->visitZeroInitializer(classifyPrim(E->
getType()), E->
getType(),
845 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
847 if (!this->DiscardResult) {
848 if (!this->emitGetLocal(
PT_Ptr, ResultOffset, E))
852 if (!loadComplexValue(LHSIsComplex, ElemIndex, LHSOffset, LHS))
855 if (!loadComplexValue(RHSIsComplex, ElemIndex, RHSOffset, RHS))
862 if (!this->emitAddf(getRoundingMode(E), E))
865 if (!this->emitAdd(ResultElemT, E))
871 if (!this->emitSubf(getRoundingMode(E), E))
874 if (!this->emitSub(ResultElemT, E))
883 if (!this->DiscardResult) {
885 if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))
888 if (!this->emitPop(ResultElemT, E))
895template <
class Emitter>
899 if (std::optional<PrimType>
T = classify(QT))
900 return this->visitZeroInitializer(*
T, QT, E);
911 const auto *CAT = cast<ConstantArrayType>(AT);
912 size_t NumElems = CAT->getZExtSize();
913 PrimType ElemT = classifyPrim(CAT->getElementType());
915 for (
size_t I = 0; I != NumElems; ++I) {
916 if (!this->visitZeroInitializer(ElemT, CAT->getElementType(), E))
918 if (!this->emitInitElem(ElemT, I, E))
926 assert(Initializing);
928 PrimType ElemT = classifyPrim(ElemQT);
929 for (
unsigned I = 0; I < 2; ++I) {
930 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
932 if (!this->emitInitElem(ElemT, I, E))
941template <
class Emitter>
948 return this->discard(
Base) && this->discard(Index);
952 if (!this->visit(
Base))
955 if (!this->visit(Index))
958 PrimType IndexT = classifyPrim(Index->getType());
959 return this->emitArrayElemPtrPop(IndexT, E);
962template <
class Emitter>
968 if (Inits.size() == 1 && E->
getType() == Inits[0]->getType()) {
969 return this->visitInitializer(Inits[0]);
972 unsigned InitIndex = 0;
975 while (InitIndex < R->getNumFields() &&
979 if (!this->emitDupPtr(E))
982 if (std::optional<PrimType>
T = classify(
Init)) {
983 const Record::Field *FieldToInit = R->
getField(InitIndex);
984 if (!this->visit(
Init))
987 if (FieldToInit->isBitField()) {
988 if (!this->emitInitBitField(*
T, FieldToInit, E))
991 if (!this->emitInitField(*
T, FieldToInit->Offset, E))
995 if (!this->emitPopPtr(E))
1000 if (
const Record::Base *B = R->
getBase(
Init->getType())) {
1001 if (!this->emitGetPtrBasePop(B->Offset,
Init))
1004 if (!this->visitInitializer(
Init))
1007 if (!this->emitFinishInitPop(E))
1012 const Record::Field *FieldToInit = R->
getField(InitIndex);
1015 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
1018 if (!this->visitInitializer(
Init))
1021 if (!this->emitPopPtr(E))
1032template <
class Emitter>
1035 if (std::optional<PrimType>
T = classify(
Init->getType())) {
1037 if (!this->visit(
Init))
1039 return this->emitInitElem(*
T, ElemIndex,
Init);
1044 if (!this->emitConstUint32(ElemIndex,
Init))
1046 if (!this->emitArrayElemPtrUint32(
Init))
1048 if (!this->visitInitializer(
Init))
1050 return this->emitFinishInitPop(
Init);
1053template <
class Emitter>
1056 if (DiscardResult) {
1058 if (!this->discard(
Init))
1065 if (std::optional<PrimType>
T = classify(E->
getType())) {
1066 assert(!DiscardResult);
1068 return this->visitZeroInitializer(*
T, E->
getType(), E);
1070 return this->delegate(E->
inits()[0]);
1075 return this->visitInitList(E->
inits(), E);
1078 unsigned ElementIndex = 0;
1080 if (!this->visitArrayElemInit(ElementIndex,
Init))
1089 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
1092 for (; ElementIndex != NumElems; ++ElementIndex) {
1093 if (!this->visitArrayElemInit(ElementIndex, Filler))
1105 return this->delegate(E->
inits()[0]);
1108 PrimType ElemT = classifyPrim(ElemQT);
1109 if (NumInits == 0) {
1111 for (
unsigned I = 0; I < 2; ++I) {
1112 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1114 if (!this->emitInitElem(ElemT, I, E))
1117 }
else if (NumInits == 2) {
1118 unsigned InitIndex = 0;
1120 if (!this->visit(
Init))
1123 if (!this->emitInitElem(ElemT, InitIndex, E))
1132 unsigned NumVecElements = VecT->getNumElements();
1135 QualType ElemQT = VecT->getElementType();
1136 PrimType ElemT = classifyPrim(ElemQT);
1139 unsigned InitIndex = 0;
1141 if (!this->visit(
Init))
1144 if (!this->emitInitElem(ElemT, InitIndex, E))
1150 for (; InitIndex != NumVecElements; ++InitIndex) {
1151 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1153 if (!this->emitInitElem(ElemT, InitIndex, E))
1162template <
class Emitter>
1165 if (DiscardResult) {
1167 if (!this->discard(
Init))
1177template <
class Emitter>
1183template <
class Emitter>
1185 std::optional<PrimType>
T = classify(E->
getType());
1201 bool AlignOfReturnsPreferred =
1202 ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
1210 if (
T.getQualifiers().hasUnaligned())
1216 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
1222template <
class Emitter>
1226 const ASTContext &ASTCtx = Ctx.getASTContext();
1228 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
1243 if (Kind == UETT_SizeOf)
1252 return this->emitConst(Size.getQuantity(), E);
1255 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
1272 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
1275 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
1285 return this->emitConst(Size.getQuantity(), E);
1288 if (Kind == UETT_VectorElements) {
1290 return this->emitConst(VT->getNumElements(), E);
1300template <
class Emitter>
1307 return this->discard(
Base);
1311 const auto maybeLoadValue = [&]() ->
bool {
1314 if (std::optional<PrimType>
T = classify(E))
1315 return this->emitLoadPop(*
T, E);
1319 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
1323 if (
auto GlobalIndex =
P.getGlobal(VD))
1324 return this->emitGetPtrGlobal(*GlobalIndex, E) && maybeLoadValue();
1329 if (!this->delegate(
Base))
1332 if (!this->visit(
Base))
1337 if (
const auto *FD = dyn_cast<FieldDecl>(
Member)) {
1339 const Record *R = getRecord(RD);
1340 const Record::Field *F = R->
getField(FD);
1342 if (F->Decl->getType()->isReferenceType())
1343 return this->emitGetFieldPop(
PT_Ptr, F->Offset, E) && maybeLoadValue();
1344 return this->emitGetPtrField(F->Offset, E) && maybeLoadValue();
1350template <
class Emitter>
1357 return this->emitConst(*ArrayIndex, E);
1360template <
class Emitter>
1363 assert(Initializing);
1364 assert(!DiscardResult);
1379 for (
size_t I = 0; I != Size; ++I) {
1383 if (!this->visitArrayElemInit(I, SubExpr))
1389template <
class Emitter>
1396 return this->visitInitializer(SourceExpr);
1399 if (
auto It = OpaqueExprs.find(E); It != OpaqueExprs.end())
1400 return this->emitGetLocal(SubExprT, It->second, E);
1402 if (!this->visit(SourceExpr))
1408 unsigned LocalIndex = allocateLocalPrimitive(E, SubExprT,
true);
1409 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
1414 if (!DiscardResult) {
1415 if (!this->emitGetLocal(SubExprT, LocalIndex, E))
1420 OpaqueExprs.insert({E, LocalIndex});
1425template <
class Emitter>
1432 LabelTy LabelEnd = this->getLabel();
1433 LabelTy LabelFalse = this->getLabel();
1438 if (!this->jumpFalse(LabelFalse))
1441 if (!this->delegate(TrueExpr))
1443 if (!this->jump(LabelEnd))
1446 this->emitLabel(LabelFalse);
1448 if (!this->delegate(FalseExpr))
1451 this->fallthrough(LabelEnd);
1452 this->emitLabel(LabelEnd);
1457template <
class Emitter>
1462 if (!Initializing) {
1463 unsigned StringIndex =
P.createGlobalString(E);
1464 return this->emitGetPtrGlobal(StringIndex, E);
1469 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
1470 assert(CAT &&
"a string literal that's not a constant array?");
1475 unsigned N = std::min(ArraySize, E->
getLength());
1478 for (
unsigned I = 0; I != N; ++I) {
1481 if (CharWidth == 1) {
1482 this->emitConstSint8(CodeUnit, E);
1483 this->emitInitElemSint8(I, E);
1484 }
else if (CharWidth == 2) {
1485 this->emitConstUint16(CodeUnit, E);
1486 this->emitInitElemUint16(I, E);
1487 }
else if (CharWidth == 4) {
1488 this->emitConstUint32(CodeUnit, E);
1489 this->emitInitElemUint32(I, E);
1491 llvm_unreachable(
"unsupported character width");
1496 for (
unsigned I = N; I != ArraySize; ++I) {
1497 if (CharWidth == 1) {
1498 this->emitConstSint8(0, E);
1499 this->emitInitElemSint8(I, E);
1500 }
else if (CharWidth == 2) {
1501 this->emitConstUint16(0, E);
1502 this->emitInitElemUint16(I, E);
1503 }
else if (CharWidth == 4) {
1504 this->emitConstUint32(0, E);
1505 this->emitInitElemUint32(I, E);
1507 llvm_unreachable(
"unsupported character width");
1514template <
class Emitter>
1519 return this->emitConst(E->
getValue(), E);
1522template <
class Emitter>
1531 std::optional<PrimType>
LT = classify(LHSComputationType);
1532 std::optional<PrimType> RT = classify(ResultType);
1539 PrimType LHST = classifyPrim(LHSType);
1547 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT,
true);
1548 if (!this->emitSetLocal(*RT, TempOffset, E))
1554 if (!this->emitLoad(LHST, E))
1558 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
1559 LHSComputationType, E))
1563 if (!this->emitGetLocal(*RT, TempOffset, E))
1566 llvm::RoundingMode RM = getRoundingMode(E);
1569 if (!this->emitAddf(RM, E))
1573 if (!this->emitSubf(RM, E))
1577 if (!this->emitMulf(RM, E))
1581 if (!this->emitDivf(RM, E))
1588 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->
getType(), E))
1592 return this->emitStorePop(LHST, E);
1593 return this->emitStore(LHST, E);
1596template <
class Emitter>
1602 std::optional<PrimType>
LT = classify(LHS->
getType());
1603 std::optional<PrimType> RT = classify(RHS->
getType());
1605 if (Op != BO_AddAssign && Op != BO_SubAssign)
1614 if (!this->emitLoad(*
LT, LHS))
1620 if (Op == BO_AddAssign) {
1621 if (!this->emitAddOffset(*RT, E))
1624 if (!this->emitSubOffset(*RT, E))
1629 return this->emitStorePopPtr(E);
1630 return this->emitStorePtr(E);
1633template <
class Emitter>
1639 std::optional<PrimType> LHSComputationT =
1641 std::optional<PrimType>
LT = classify(LHS->
getType());
1642 std::optional<PrimType> RT = classify(RHS->
getType());
1643 std::optional<PrimType> ResultT = classify(E->
getType());
1645 if (!
LT || !RT || !ResultT || !LHSComputationT)
1652 return VisitFloatCompoundAssignOperator(E);
1655 return VisitPointerCompoundAssignOperator(E);
1668 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT,
true);
1670 if (!this->emitSetLocal(*RT, TempOffset, E))
1677 if (!this->emitLoad(*
LT, E))
1679 if (
LT != LHSComputationT) {
1680 if (!this->emitCast(*
LT, *LHSComputationT, E))
1685 if (!this->emitGetLocal(*RT, TempOffset, E))
1691 if (!this->emitAdd(*LHSComputationT, E))
1695 if (!this->emitSub(*LHSComputationT, E))
1699 if (!this->emitMul(*LHSComputationT, E))
1703 if (!this->emitDiv(*LHSComputationT, E))
1707 if (!this->emitRem(*LHSComputationT, E))
1711 if (!this->emitShl(*LHSComputationT, *RT, E))
1715 if (!this->emitShr(*LHSComputationT, *RT, E))
1719 if (!this->emitBitAnd(*LHSComputationT, E))
1723 if (!this->emitBitXor(*LHSComputationT, E))
1727 if (!this->emitBitOr(*LHSComputationT, E))
1731 llvm_unreachable(
"Unimplemented compound assign operator");
1735 if (ResultT != LHSComputationT) {
1736 if (!this->emitCast(*LHSComputationT, *ResultT, E))
1741 if (DiscardResult) {
1743 return this->emitStoreBitFieldPop(*ResultT, E);
1744 return this->emitStorePop(*ResultT, E);
1747 return this->emitStoreBitField(*ResultT, E);
1748 return this->emitStore(*ResultT, E);
1751template <
class Emitter>
1756 assert(E->
getNumObjects() == 0 &&
"TODO: Implement cleanups");
1758 return this->delegate(SubExpr);
1761template <
class Emitter>
1768 return this->visitInitializer(SubExpr);
1773 return this->discard(SubExpr);
1777 std::optional<PrimType> SubExprT = classify(SubExpr);
1780 std::optional<unsigned> GlobalIndex =
P.createGlobal(E);
1790 if (!this->visit(SubExpr))
1793 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl, E))
1796 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex, E))
1799 return this->emitGetPtrGlobal(*GlobalIndex, E);
1803 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1805 if (!this->visitInitializer(SubExpr))
1808 return this->emitInitGlobalTempComp(TempDecl, E);
1814 unsigned LocalIndex = allocateLocalPrimitive(
1815 SubExpr, *SubExprT,
true,
true);
1816 if (!this->visit(SubExpr))
1818 if (!this->emitSetLocal(*SubExprT, LocalIndex, E))
1820 return this->emitGetPtrLocal(LocalIndex, E);
1824 if (std::optional<unsigned> LocalIndex =
1825 allocateLocal(Inner,
true)) {
1826 if (!this->emitGetPtrLocal(*LocalIndex, E))
1828 return this->visitInitializer(SubExpr);
1834template <
class Emitter>
1840template <
class Emitter>
1846 return this->visitInitializer(
Init) && this->emitFinishInit(E);
1849 std::optional<PrimType>
T = classify(E->
getType());
1853 return this->delegate(
Init);
1855 if (std::optional<unsigned> GlobalIndex =
P.createGlobal(E)) {
1856 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1860 if (!this->visit(
Init))
1862 return this->emitInitGlobal(*
T, *GlobalIndex, E);
1865 return this->visitInitializer(
Init) && this->emitFinishInit(E);
1874 return this->delegate(
Init);
1876 unsigned LocalIndex;
1879 LocalIndex = this->allocateLocalPrimitive(
Init, *
T,
false,
false);
1880 else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(
Init))
1881 LocalIndex = *MaybeIndex;
1885 if (!this->emitGetPtrLocal(LocalIndex, E))
1889 if (!this->visit(
Init)) {
1892 return this->emitInit(*
T, E);
1894 if (!this->visitInitializer(
Init) || !this->emitFinishInit(E))
1899 return this->emitPopPtr(E);
1906template <
class Emitter>
1911 return this->emitConstBool(E->
getValue(), E);
1912 return this->emitConst(E->
getValue(), E);
1915template <
class Emitter>
1920 return this->emitConst(E->
getValue(), E);
1923template <
class Emitter>
1928 assert(Initializing);
1934 for (
const Record::Field &F : R->
fields()) {
1941 if (std::optional<PrimType>
T = classify(
Init)) {
1942 if (!this->visit(
Init))
1945 if (!this->emitSetField(*
T, F.Offset, E))
1948 if (!this->emitDupPtr(E))
1951 if (!this->emitGetPtrField(F.Offset, E))
1954 if (!this->visitInitializer(
Init))
1957 if (!this->emitPopPtr(E))
1965template <
class Emitter>
1973template <
class Emitter>
1978 return this->emitInvalid(E);
1981template <
class Emitter>
1987 return this->emitInvalidCast(CastKind::Reinterpret, E);
1990template <
class Emitter>
1996 return this->emitConstBool(E->
getValue(), E);
1999template <
class Emitter>
2003 assert(!classify(
T));
2011 return this->visitZeroRecordInitializer(R, E);
2019 assert(
Func->hasThisPointer());
2020 assert(!
Func->hasRVO());
2024 if (DiscardResult) {
2025 assert(!Initializing);
2026 std::optional<unsigned> LocalIndex =
2027 allocateLocal(E,
true);
2032 if (!this->emitGetPtrLocal(*LocalIndex, E))
2038 if (!this->emitDupPtr(E))
2042 for (
const auto *Arg : E->
arguments()) {
2043 if (!this->visit(Arg))
2047 if (
Func->isVariadic()) {
2048 uint32_t VarArgSize = 0;
2049 unsigned NumParams =
Func->getNumWrittenParams();
2050 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I) {
2054 if (!this->emitCallVar(
Func, VarArgSize, E))
2057 if (!this->emitCall(
Func, 0, E))
2062 if (DiscardResult) {
2063 if (!this->emitRecordDestruction(getRecord(E->
getType())))
2065 if (!this->emitPopPtr(E))
2073 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
2082 for (
size_t I = 0; I != NumElems; ++I) {
2083 if (!this->emitConstUint64(I, E))
2085 if (!this->emitArrayElemPtrUint64(E))
2089 for (
const auto *Arg : E->
arguments()) {
2090 if (!this->visit(Arg))
2094 if (!this->emitCall(
Func, 0, E))
2103template <
class Emitter>
2113 assert(Val.
isInt());
2115 return this->emitConst(I, E);
2122 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
2123 return this->visit(LValueExpr);
2132 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
2134 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(UGCD);
2138 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2142 const APValue &
V = UGCD->getValue();
2143 for (
unsigned I = 0, N = R->
getNumFields(); I != N; ++I) {
2144 const Record::Field *F = R->
getField(I);
2145 const APValue &FieldValue =
V.getStructField(I);
2147 PrimType FieldT = classifyPrim(F->Decl->getType());
2149 if (!this->visitAPValue(FieldValue, FieldT, E))
2151 if (!this->emitInitField(FieldT, F->Offset, E))
2159template <
class Emitter>
2165 for (
unsigned I = 0; I != N; ++I) {
2171 if (DiscardResult) {
2172 if (!this->discard(ArrayIndexExpr))
2177 if (!this->visit(ArrayIndexExpr))
2181 if (!this->emitCast(IndexT,
PT_Sint64, E))
2191 return this->emitOffsetOf(
T, E, E);
2194template <
class Emitter>
2202 if (std::optional<PrimType>
T = classify(Ty))
2203 return this->visitZeroInitializer(*
T, Ty, E);
2206 if (!Initializing) {
2207 std::optional<unsigned> LocalIndex = allocateLocal(E,
false);
2210 if (!this->emitGetPtrLocal(*LocalIndex, E))
2216 PrimType ElemT = classifyPrim(ElemQT);
2218 for (
unsigned I = 0; I != 2; ++I) {
2219 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2221 if (!this->emitInitElem(ElemT, I, E))
2227template <
class Emitter>
2232template <
class Emitter>
2238template <
class Emitter>
2243template <
class Emitter>
2249 return this->emitConst(E->
getValue(), E);
2252template <
class Emitter>
2257 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
2258 const Function *F = this->getFunction(Ctor);
2275 if (!this->emitGetParam(PT, Offset, E))
2280 return this->emitCall(F, 0, E);
2283template <
class Emitter>
2286 assert(Ctx.getLangOpts().CPlusPlus);
2287 return this->emitConstBool(E->
getValue(), E);
2290template <
class Emitter>
2294 assert(!Initializing);
2296 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(E->
getGuidDecl());
2299 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2309 assert(
V.isStruct());
2310 assert(
V.getStructNumBases() == 0);
2312 for (
unsigned I = 0, N =
V.getStructNumFields(); I != N; ++I) {
2313 const APValue &F =
V.getStructField(I);
2314 const Record::Field *RF = R->
getField(I);
2317 PrimType T = classifyPrim(RF->Decl->getType());
2318 if (!this->visitAPValue(F,
T, E))
2320 if (!this->emitInitField(
T, RF->Offset, E))
2323 assert(RF->Desc->isPrimitiveArray());
2324 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
2325 PrimType ElemT = classifyPrim(ArrType->getElementType());
2328 if (!this->emitDupPtr(E))
2330 if (!this->emitGetPtrField(RF->Offset, E))
2333 for (
unsigned A = 0, AN = F.
getArraySize(); A != AN; ++A) {
2336 if (!this->emitInitElem(ElemT, A, E))
2340 if (!this->emitPopPtr(E))
2343 assert(
false &&
"I don't think this should be possible");
2347 return this->emitFinishInit(E);
2350template <
class Emitter>
2356template <
class Emitter>
2363template <
class Emitter>
2369template <
class Emitter>
2374 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
2378 if (OVE->isUnique())
2381 if (!this->discard(OVE))
2384 if (!this->delegate(SemE))
2387 if (!this->discard(SemE))
2394template <
class Emitter>
2406 return this->Visit(E);
2409template <
class Emitter>
2412 return this->emitError(E);
2417 return this->Visit(E);
2422 return this->emitError(E);
2425 return this->discard(E);
2430 std::optional<unsigned> LocalIndex = allocateLocal(E,
true);
2434 if (!this->emitGetPtrLocal(*LocalIndex, E))
2436 return this->visitInitializer(E);
2443 return this->Visit(E);
2446template <
class Emitter>
2448 assert(!classify(E->
getType()));
2451 return this->emitError(E);
2455 return this->Visit(E);
2458template <
class Emitter>
2460 std::optional<PrimType>
T = classify(E->
getType());
2464 if (!this->visit(E))
2466 return this->emitComplexBoolCast(E);
2471 if (!this->visit(E))
2479 if (!this->emitNull(*
T,
nullptr, E))
2481 return this->emitNE(*
T, E);
2486 return this->emitCastFloatingIntegralBool(E);
2489 return this->emitCast(*
T,
PT_Bool, E);
2492template <
class Emitter>
2497 return this->emitZeroBool(E);
2499 return this->emitZeroSint8(E);
2501 return this->emitZeroUint8(E);
2503 return this->emitZeroSint16(E);
2505 return this->emitZeroUint16(E);
2507 return this->emitZeroSint32(E);
2509 return this->emitZeroUint32(E);
2511 return this->emitZeroSint64(E);
2513 return this->emitZeroUint64(E);
2515 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
2517 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
2519 return this->emitNullPtr(
nullptr, E);
2521 return this->emitNullFnPtr(
nullptr, E);
2523 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E);
2526 llvm_unreachable(
"unknown primitive type");
2529template <
class Emitter>
2535 for (
const Record::Field &Field : R->
fields()) {
2540 if (!this->visitZeroInitializer(
T, QT, E))
2542 if (!this->emitInitField(
T,
Field.Offset, E))
2548 if (!this->emitDupPtr(E))
2550 if (!this->emitGetPtrField(
Field.Offset, E))
2556 for (uint32_t I = 0, N = D->
getNumElems(); I != N; ++I) {
2557 if (!this->visitZeroInitializer(
T, ET, E))
2559 if (!this->emitInitElem(
T, I, E))
2565 for (uint32_t I = 0, N = D->
getNumElems(); I != N; ++I) {
2566 if (!this->emitConstUint32(I, E))
2568 if (!this->emitArrayElemPtr(
PT_Uint32, E))
2570 if (!this->visitZeroRecordInitializer(ElemRecord, E))
2572 if (!this->emitPopPtr(E))
2576 if (!this->visitZeroRecordInitializer(D->
ElemRecord, E))
2582 if (!this->emitPopPtr(E))
2586 for (
const Record::Base &B : R->
bases()) {
2587 if (!this->emitGetPtrBase(B.Offset, E))
2589 if (!this->visitZeroRecordInitializer(B.R, E))
2591 if (!this->emitFinishInitPop(E))
2600template <
class Emitter>
2601template <
typename T>
2605 return this->emitConstSint8(
Value, E);
2607 return this->emitConstUint8(
Value, E);
2609 return this->emitConstSint16(
Value, E);
2611 return this->emitConstUint16(
Value, E);
2613 return this->emitConstSint32(
Value, E);
2615 return this->emitConstUint32(
Value, E);
2617 return this->emitConstSint64(
Value, E);
2619 return this->emitConstUint64(
Value, E);
2621 return this->emitConstBool(
Value, E);
2627 llvm_unreachable(
"Invalid integral type");
2630 llvm_unreachable(
"unknown primitive type");
2633template <
class Emitter>
2634template <
typename T>
2636 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
2639template <
class Emitter>
2643 return this->emitConstIntAPS(
Value, E);
2645 return this->emitConstIntAP(
Value, E);
2647 if (
Value.isSigned())
2648 return this->emitConst(
Value.getSExtValue(), Ty, E);
2649 return this->emitConst(
Value.getZExtValue(), Ty, E);
2652template <
class Emitter>
2654 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
2657template <
class Emitter>
2663 if (
const auto *VD =
2664 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
2665 assert(!
P.getGlobal(VD));
2666 assert(!Locals.contains(VD));
2674 Src.is<
const Expr *>());
2676 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
2677 Locals.insert({VD, Local});
2678 VarScope->add(Local, IsExtended);
2679 return Local.Offset;
2682template <
class Emitter>
2683std::optional<unsigned>
2686 if ([[maybe_unused]]
const auto *VD =
2687 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
2688 assert(!
P.getGlobal(VD));
2689 assert(!Locals.contains(VD));
2695 bool IsTemporary =
false;
2696 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
2700 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
2701 Init = VarD->getInit();
2703 if (
auto *E = Src.dyn_cast<
const Expr *>()) {
2710 IsTemporary,
false,
Init);
2712 return std::nullopt;
2716 Locals.insert({Key, Local});
2717 VarScope->add(Local, IsExtended);
2718 return Local.Offset;
2721template <
class Emitter>
2723 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
2728template <
class Emitter>
2730 if (
const auto *RecordTy = getRecordTy(Ty))
2731 return getRecord(RecordTy->getDecl());
2735template <
class Emitter>
2737 return P.getOrCreateRecord(RD);
2740template <
class Emitter>
2742 return Ctx.getOrCreateFunction(FD);
2745template <
class Emitter>
2752 return this->emitRetVoid(E);
2756 if (std::optional<PrimType>
T = classify(E)) {
2759 return this->emitRet(*
T, E);
2765 if (std::optional<unsigned> LocalOffset = this->allocateLocal(E)) {
2766 if (!this->emitGetPtrLocal(*LocalOffset, E))
2769 if (!visitInitializer(E))
2772 if (!this->emitFinishInit(E))
2786template <
class Emitter>
2788 assert(!VD->
isInvalidDecl() &&
"Trying to constant evaluate an invalid decl");
2792 if (std::optional<unsigned> Index =
P.getGlobal(VD);
2793 Index && !
P.getPtrGlobal(*Index).isInitialized())
2797 if (!this->visitVarDecl(VD))
2800 std::optional<PrimType> VarT = classify(VD->
getType());
2803 auto GlobalIndex =
P.getGlobal(VD);
2804 assert(GlobalIndex);
2806 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
2809 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
2813 auto Local = Locals.find(VD);
2814 assert(Local != Locals.end());
2816 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
2819 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
2826 return this->emitRet(*VarT, VD);
2829 return this->emitRet(
PT_Ptr, VD);
2832template <
class Emitter>
2839 std::optional<PrimType> VarT = classify(VD->
getType());
2842 auto initGlobal = [&](
unsigned GlobalIndex) ->
bool {
2847 if (!this->visit(
Init))
2849 return this->emitInitGlobal(*VarT, GlobalIndex, VD);
2851 return this->visitGlobalInitializer(
Init, GlobalIndex);
2855 if (std::optional<unsigned> GlobalIndex =
P.getGlobal(VD)) {
2856 if (
P.getPtrGlobal(*GlobalIndex).isInitialized())
2861 return Init && initGlobal(*GlobalIndex);
2864 std::optional<unsigned> GlobalIndex =
P.createGlobal(VD,
Init);
2869 return !
Init || initGlobal(*GlobalIndex);
2873 unsigned Offset = this->allocateLocalPrimitive(
2878 if (!this->visit(
Init))
2881 return this->emitSetLocal(*VarT, Offset, VD);
2884 if (std::optional<unsigned> Offset = this->allocateLocal(VD))
2885 return !
Init || this->visitLocalInitializer(
Init, *Offset);
2894template <
class Emitter>
2897 assert(!DiscardResult);
2899 return this->emitConst(Val.
getInt(), ValType, E);
2903 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
2904 return this->visit(BaseExpr);
2910template <
class Emitter>
2917 std::optional<PrimType> ReturnT = classify(E);
2920 if (!Initializing && !ReturnT && !ReturnType->
isVoidType()) {
2921 std::optional<unsigned> LocalIndex = allocateLocal(E,
false);
2924 if (!this->emitGetPtrLocal(*LocalIndex, E))
2928 if (!
Func->isUnevaluatedBuiltin()) {
2930 for (
const auto *Arg : E->
arguments()) {
2931 if (!this->visit(Arg))
2936 if (!this->emitCallBI(
Func, E, E))
2939 if (DiscardResult && !ReturnType->
isVoidType()) {
2941 return this->emitPop(*ReturnT, E);
2947template <
class Emitter>
2950 return VisitBuiltinCallExpr(E);
2953 std::optional<PrimType>
T = classify(ReturnType);
2958 if (DiscardResult) {
2962 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
2963 if (!this->emitGetPtrLocal(*LocalIndex, E))
2969 if (!Initializing) {
2970 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
2971 if (!this->emitGetPtrLocal(*LocalIndex, E))
2975 if (!this->emitDupPtr(E))
2984 if (isa<CXXOperatorCallExpr>(E)) {
2985 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
2986 MD && MD->isStatic()) {
2987 if (!this->discard(E->
getArg(0)))
2989 Args = Args.drop_front();
2994 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
2995 if (!this->visit(MC->getImplicitObjectArgument()))
3001 unsigned ArgIndex = 0;
3002 for (
const auto *Arg : Args) {
3003 if (!this->visit(Arg))
3007 if (FuncDecl && NonNullArgs[ArgIndex]) {
3010 if (!this->emitCheckNonNullArg(ArgT, Arg))
3021 assert(HasRVO ==
Func->hasRVO());
3023 bool HasQualifier =
false;
3024 if (
const auto *ME = dyn_cast<MemberExpr>(E->
getCallee()))
3025 HasQualifier = ME->hasQualifier();
3027 bool IsVirtual =
false;
3028 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
3029 IsVirtual = MD->isVirtual();
3034 if (IsVirtual && !HasQualifier) {
3035 uint32_t VarArgSize = 0;
3036 unsigned NumParams =
Func->getNumWrittenParams();
3037 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
3040 if (!this->emitCallVirt(
Func, VarArgSize, E))
3042 }
else if (
Func->isVariadic()) {
3043 uint32_t VarArgSize = 0;
3044 unsigned NumParams =
3045 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(E);
3046 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
3048 if (!this->emitCallVar(
Func, VarArgSize, E))
3051 if (!this->emitCall(
Func, 0, E))
3060 uint32_t ArgSize = 0;
3061 for (
unsigned I = 0, N = E->
getNumArgs(); I != N; ++I)
3067 if (!this->emitCallPtr(ArgSize, E, E))
3072 if (DiscardResult && !ReturnType->
isVoidType() &&
T)
3073 return this->emitPop(*
T, E);
3078template <
class Emitter>
3082 return this->delegate(E->
getExpr());
3085template <
class Emitter>
3091 if (std::optional<PrimType>
T = classify(E->
getExpr()))
3092 return this->visit(SubExpr);
3094 assert(Initializing);
3095 return this->visitInitializer(SubExpr);
3098template <
class Emitter>
3104 return this->emitConstBool(E->
getValue(), E);
3107template <
class Emitter>
3113 return this->emitNullPtr(
nullptr, E);
3116template <
class Emitter>
3124 return this->emitZero(
T, E);
3127template <
class Emitter>
3132 if (this->LambdaThisCapture.Offset > 0) {
3133 if (this->LambdaThisCapture.IsPtr)
3134 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
3135 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
3138 return this->emitThis(E);
3141template <
class Emitter>
3145 return this->VisitComplexUnaryOperator(E);
3146 std::optional<PrimType>
T = classify(SubExpr->
getType());
3150 if (!this->visit(SubExpr))
3154 if (!this->emitIncPtr(E))
3157 return DiscardResult ? this->emitPopPtr(E) :
true;
3161 return DiscardResult ? this->emitIncfPop(getRoundingMode(E), E)
3162 : this->emitIncf(getRoundingMode(E), E);
3165 return DiscardResult ? this->emitIncPop(*
T, E) : this->emitInc(*
T, E);
3168 if (!this->visit(SubExpr))
3172 if (!this->emitDecPtr(E))
3175 return DiscardResult ? this->emitPopPtr(E) :
true;
3179 return DiscardResult ? this->emitDecfPop(getRoundingMode(E), E)
3180 : this->emitDecf(getRoundingMode(E), E);
3183 return DiscardResult ? this->emitDecPop(*
T, E) : this->emitDec(*
T, E);
3186 if (!this->visit(SubExpr))
3190 if (!this->emitLoadPtr(E))
3192 if (!this->emitConstUint8(1, E))
3194 if (!this->emitAddOffsetUint8(E))
3196 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
3200 if (DiscardResult) {
3202 return this->emitIncfPop(getRoundingMode(E), E);
3203 return this->emitIncPop(*
T, E);
3207 const auto &TargetSemantics = Ctx.getFloatSemantics(E->
getType());
3208 if (!this->emitLoadFloat(E))
3210 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
3212 if (!this->emitAddf(getRoundingMode(E), E))
3214 if (!this->emitStoreFloat(E))
3218 if (!this->emitLoad(*
T, E))
3220 if (!this->emitConst(1, E))
3222 if (!this->emitAdd(*
T, E))
3224 if (!this->emitStore(*
T, E))
3227 return E->
isGLValue() || this->emitLoadPop(*
T, E);
3230 if (!this->visit(SubExpr))
3234 if (!this->emitLoadPtr(E))
3236 if (!this->emitConstUint8(1, E))
3238 if (!this->emitSubOffsetUint8(E))
3240 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
3244 if (DiscardResult) {
3246 return this->emitDecfPop(getRoundingMode(E), E);
3247 return this->emitDecPop(*
T, E);
3251 const auto &TargetSemantics = Ctx.getFloatSemantics(E->
getType());
3252 if (!this->emitLoadFloat(E))
3254 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
3256 if (!this->emitSubf(getRoundingMode(E), E))
3258 if (!this->emitStoreFloat(E))
3262 if (!this->emitLoad(*
T, E))
3264 if (!this->emitConst(1, E))
3266 if (!this->emitSub(*
T, E))
3268 if (!this->emitStore(*
T, E))
3271 return E->
isGLValue() || this->emitLoadPop(*
T, E);
3275 return this->discard(SubExpr);
3277 if (!this->visitBool(SubExpr))
3280 if (!this->emitInvBool(E))
3284 return this->emitCast(
PT_Bool, ET, E);
3287 if (!this->visit(SubExpr))
3289 return DiscardResult ? this->emitPop(*
T, E) : this->emitNeg(*
T, E);
3291 if (!this->visit(SubExpr))
3293 return DiscardResult ? this->emitPop(*
T, E) :
true;
3296 return this->delegate(SubExpr);
3299 return this->discard(SubExpr);
3300 return this->visit(SubExpr);
3302 if (!this->visit(SubExpr))
3304 return DiscardResult ? this->emitPop(*
T, E) : this->emitComp(*
T, E);
3307 return this->delegate(SubExpr);
3310 if (!this->discard(SubExpr))
3312 return this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
3315 return this->delegate(SubExpr);
3317 assert(
false &&
"Unhandled opcode");
3323template <
class Emitter>
3330 return this->discard(SubExpr);
3332 std::optional<PrimType> ResT = classify(E);
3333 auto prepareResult = [=]() ->
bool {
3334 if (!ResT && !Initializing) {
3335 std::optional<unsigned> LocalIndex =
3336 allocateLocal(SubExpr,
false);
3339 return this->emitGetPtrLocal(*LocalIndex, E);
3346 unsigned SubExprOffset = ~0u;
3347 auto createTemp = [=, &SubExprOffset]() ->
bool {
3348 SubExprOffset = this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
3349 if (!this->visit(SubExpr))
3351 return this->emitSetLocal(
PT_Ptr, SubExprOffset, E);
3355 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
3356 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
3358 return this->emitArrayElemPop(ElemT, Index, E);
3363 if (!prepareResult())
3367 for (
unsigned I = 0; I != 2; ++I) {
3368 if (!getElem(SubExprOffset, I))
3370 if (!this->emitNeg(ElemT, E))
3372 if (!this->emitInitElem(ElemT, I, E))
3380 return this->delegate(SubExpr);
3383 if (!this->visit(SubExpr))
3385 if (!this->emitComplexBoolCast(SubExpr))
3387 if (!this->emitInvBool(E))
3390 return this->emitCast(
PT_Bool, ET, E);
3394 return this->emitComplexReal(SubExpr);
3397 if (!this->visit(SubExpr))
3401 if (!this->emitConstUint8(1, E))
3403 return this->emitArrayElemPtrPopUint8(E);
3408 return this->emitArrayElemPop(classifyPrim(E->
getType()), 1, E);
3411 return this->emitInvalid(E);
3417template <
class Emitter>
3424 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
3425 return this->emitConst(ECD->getInitVal(), E);
3426 }
else if (
const auto *BD = dyn_cast<BindingDecl>(D)) {
3427 return this->visit(BD->getBinding());
3428 }
else if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
3429 const Function *F = getFunction(FuncDecl);
3430 return F && this->emitGetFnPtr(F, E);
3431 }
else if (isa<TemplateParamObjectDecl>(D)) {
3432 if (std::optional<unsigned> Index =
P.getOrCreateGlobal(D))
3433 return this->emitGetPtrGlobal(*Index, E);
3444 if (
auto It = Locals.find(D); It != Locals.end()) {
3445 const unsigned Offset = It->second.Offset;
3447 return this->emitGetLocal(
PT_Ptr, Offset, E);
3448 return this->emitGetPtrLocal(Offset, E);
3449 }
else if (
auto GlobalIndex =
P.getGlobal(D)) {
3451 return this->emitGetGlobalPtr(*GlobalIndex, E);
3453 return this->emitGetPtrGlobal(*GlobalIndex, E);
3454 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
3455 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
3456 if (IsReference || !It->second.IsPtr)
3457 return this->emitGetParamPtr(It->second.Offset, E);
3459 return this->emitGetPtrParam(It->second.Offset, E);
3464 if (
auto It = this->LambdaCaptures.find(D);
3465 It != this->LambdaCaptures.end()) {
3466 auto [Offset, IsPtr] = It->second;
3469 return this->emitGetThisFieldPtr(Offset, E);
3470 return this->emitGetPtrThisField(Offset, E);
3475 if (Ctx.getLangOpts().CPlusPlus) {
3476 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
3478 if ((VD->isLocalVarDecl() || VD->isStaticDataMember()) &&
3479 VD->getType().isConstQualified()) {
3480 if (!this->visitVarDecl(VD))
3483 return this->VisitDeclRefExpr(E);
3487 if (
const auto *VD = dyn_cast<VarDecl>(D);
3488 VD && VD->getAnyInitializer() && VD->getType().isConstQualified()) {
3489 if (!this->visitVarDecl(VD))
3492 return this->VisitDeclRefExpr(E);
3496 if (std::optional<unsigned> I =
P.getOrCreateDummy(D))
3497 return this->emitGetPtrGlobal(*I, E);
3499 return this->emitInvalidDeclRef(E, E);
3502template <
class Emitter>
3505 C->emitDestruction();
3508template <
class Emitter>
3513 assert(DerivedType);
3514 const auto *FinalDecl = cast<CXXRecordDecl>(BaseType->
getDecl());
3516 const Record *CurRecord = getRecord(CurDecl);
3517 assert(CurDecl && FinalDecl);
3519 unsigned OffsetSum = 0;
3523 for (
const Record::Base &B : CurRecord->
bases()) {
3524 const auto *BaseDecl = cast<CXXRecordDecl>(B.Decl);
3526 if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) {
3527 OffsetSum += B.Offset;
3533 if (CurDecl == FinalDecl)
3537 assert(OffsetSum > 0);
3542template <
class Emitter>
3549 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
3550 return this->emitCastFP(ToSem, getRoundingMode(E), E);
3555 return this->emitCastFloatingIntegral(ToT, E);
3561 return FromT != ToT ? this->emitCast(FromT, ToT, E) :
true;
3565 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
3566 return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(E),
3575template <
class Emitter>
3580 return this->discard(SubExpr);
3582 if (!this->visit(SubExpr))
3585 if (!this->emitConstUint8(0, SubExpr))
3587 return this->emitArrayElemPtrPopUint8(SubExpr);
3591 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
3595template <
class Emitter>
3597 assert(!DiscardResult);
3601 if (!this->emitArrayElem(ElemT, 0, E))
3604 if (!this->emitCastFloatingIntegral(
PT_Bool, E))
3607 if (!this->emitCast(ElemT,
PT_Bool, E))
3612 LabelTy LabelTrue = this->getLabel();
3613 if (!this->jumpTrue(LabelTrue))
3616 if (!this->emitArrayElemPop(ElemT, 1, E))
3619 if (!this->emitCastFloatingIntegral(
PT_Bool, E))
3622 if (!this->emitCast(ElemT,
PT_Bool, E))
3626 LabelTy EndLabel = this->getLabel();
3627 this->jump(EndLabel);
3629 this->emitLabel(LabelTrue);
3630 if (!this->emitPopPtr(E))
3632 if (!this->emitConstBool(
true, E))
3635 this->fallthrough(EndLabel);
3636 this->emitLabel(EndLabel);
3641template <
class Emitter>
3646 assert(!Initializing);
3647 assert(!DiscardResult);
3653 LHSIsComplex =
true;
3654 ElemT = classifyComplexElementType(LHS->
getType());
3655 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true,
3657 if (!this->visit(LHS))
3659 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
3662 LHSIsComplex =
false;
3664 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
3665 if (!this->visit(LHS))
3667 if (!this->emitSetLocal(LHST, LHSOffset, E))
3674 RHSIsComplex =
true;
3675 ElemT = classifyComplexElementType(RHS->
getType());
3676 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true,
3678 if (!this->visit(RHS))
3680 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
3683 RHSIsComplex =
false;
3685 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
3686 if (!this->visit(RHS))
3688 if (!this->emitSetLocal(RHST, RHSOffset, E))
3692 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
3693 bool IsComplex) ->
bool {
3695 if (!this->emitGetLocal(
PT_Ptr, LocalOffset, E))
3697 return this->emitArrayElemPop(ElemT, Index, E);
3699 return this->emitGetLocal(ElemT, LocalOffset, E);
3702 for (
unsigned I = 0; I != 2; ++I) {
3704 if (!getElem(LHSOffset, I, LHSIsComplex))
3706 if (!getElem(RHSOffset, I, RHSIsComplex))
3709 if (!this->emitEQ(ElemT, E))
3712 if (!this->emitCastBoolUint8(E))
3717 if (!this->emitAddUint8(E))
3719 if (!this->emitConstUint8(2, E))
3723 if (!this->emitEQUint8(E))
3726 if (!this->emitNEUint8(E))
3733 return this->emitCast(
PT_Bool, ResT, E);
3740template <
class Emitter>
3744 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
3751 if (!this->emitDestruction(D))
3764 const Function *DtorFunc = getFunction(Dtor);
3771 if (!this->emitCall(DtorFunc, 0,
SourceInfo{}))
3775 for (
const Record::Base &
Base : llvm::reverse(R->
bases())) {
3778 if (!this->emitRecordDestruction(
Base.R))
3790template <
class Emitter>
3814 for (ssize_t I = Desc->
getNumElems() - 1; I >= 0; --I) {
3817 if (!this->emitArrayElemPtrUint64(
SourceInfo{}))
3819 if (!this->emitDestruction(ElemDesc))
3828 return this->emitRecordDestruction(Desc->
ElemRecord);
ASTImporterLookupTable & LT
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, UnaryExprOrTypeTrait Kind)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
ArrayRef< LValuePathEntry > getLValuePath() const
unsigned getArraySize() const
@ None
There is no such object (it's outside its lifetime).
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
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.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
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 ?: operator.
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...
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.
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.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
static bool isCommaOp(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
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.
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.
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 C++ destructor within a class.
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 C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a list-initialization with parenthesis.
ArrayRef< Expr * > getInitExprs()
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 a value-initialized rvalue of type T, which is a non-class type.
Represents the this expression in C++.
A C++ throw-expression (C++ [except.throw]).
const Expr * getSubExpr() const
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.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
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.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
CharUnits - This is an opaque type for sizes expressed in character units.
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.
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
CompoundLiteralExpr - [C99 6.5.2.5].
const Expr * getInitializer() const
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
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
bool isInvalidDecl() const
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
unsigned getNumObjects() const
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 containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
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 refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
An expression trait intrinsic.
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
llvm::APFloat getValue() const
const Expr * getSubExpr() const
Represents a function declaration or definition.
ArrayRef< ParmVarDecl * > parameters() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
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.
GlobalDecl - represents a global declaration.
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.
Describes an C or C++ initializer list.
unsigned getNumInits() const
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-...
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.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
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.
@ Array
An index into an array.
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 parethesized expression, e.g.
const Expr * getSubExpr() const
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
[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 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 isConstQualified() const
Determine whether this type is const-qualified.
Represents a struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
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.
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...
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
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
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
bool isBooleanType() const
bool isIncompleteArrayType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool isReferenceType() 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 isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isAtomicType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isFunctionType() const
bool isVectorType() const
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.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
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
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
const Expr * getInit() const
Represents a GCC generic vector type.
Scope for storage declared in a compound statement.
Compilation context for expressions.
bool visitExpr(const Expr *E) override
std::optional< unsigned > allocateLocal(DeclTy &&Decl, bool IsExtended=false)
Allocates a space storing a local given its type.
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsExtended=false)
Creates a local primitive value.
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool VisitDeclRefExpr(const DeclRefExpr *E)
bool VisitExprWithCleanups(const ExprWithCleanups *E)
bool VisitPseudoObjectExpr(const PseudoObjectExpr *E)
bool VisitComplexBinOp(const BinaryOperator *E)
bool VisitCXXThrowExpr(const CXXThrowExpr *E)
bool VisitMemberExpr(const MemberExpr *E)
bool VisitOffsetOfExpr(const OffsetOfExpr *E)
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
bool discard(const Expr *E)
Evaluates an expression for side effects and discards the result.
bool visitDecl(const VarDecl *VD) override
Toplevel visitDecl().
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E)
bool visitInitializer(const Expr *E)
Compiles an initializer.
bool VisitParenExpr(const ParenExpr *E)
bool Initializing
Flag inidicating if we're initializing an already created variable.
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E)
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E)
bool VisitImaginaryLiteral(const ImaginaryLiteral *E)
bool VisitLambdaExpr(const LambdaExpr *E)
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E)
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
bool VisitComplexUnaryOperator(const UnaryOperator *E)
bool VisitRequiresExpr(const RequiresExpr *E)
bool VisitBuiltinCallExpr(const CallExpr *E)
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E)
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init)
Pointer to the array(not the element!) must be on the stack when calling this.
void emitCleanup()
Emits scope cleanup instructions.
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
bool visitBool(const Expr *E)
Visits an expression and converts it to a boolean.
bool VisitPredefinedExpr(const PredefinedExpr *E)
bool VisitBinaryOperator(const BinaryOperator *E)
bool VisitTypeTraitExpr(const TypeTraitExpr *E)
bool visit(const Expr *E)
Evaluates an expression and places the result on the stack.
bool VisitInitListExpr(const InitListExpr *E)
bool VisitFloatingLiteral(const FloatingLiteral *E)
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E)
bool VisitPackIndexingExpr(const PackIndexingExpr *E)
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E)
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E)
bool visitInitList(ArrayRef< const Expr * > Inits, const Expr *E)
bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E)
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
bool VisitUnaryOperator(const UnaryOperator *E)
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E)
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E)
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E)
bool DiscardResult
Flag indicating if return value is to be discarded.
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
const Function * getFunction(const FunctionDecl *FD)
bool VisitLogicalBinOp(const BinaryOperator *E)
bool visitVarDecl(const VarDecl *VD)
Creates and initializes a variable from the given decl.
bool VisitStringLiteral(const StringLiteral *E)
bool VisitCXXConstructExpr(const CXXConstructExpr *E)
bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E)
bool VisitGNUNullExpr(const GNUNullExpr *E)
Record * getRecord(QualType Ty)
Returns a record from a record or pointer type.
bool VisitSourceLocExpr(const SourceLocExpr *E)
bool VisitOpaqueValueExpr(const OpaqueValueExpr *E)
bool VisitCXXThisExpr(const CXXThisExpr *E)
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E)
typename Emitter::LabelTy LabelTy
bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E)
Visit an APValue.
bool VisitPointerArithBinOp(const BinaryOperator *E)
Perform addition/subtraction of a pointer and an integer or subtraction of two pointers.
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitCompoundAssignOperator(const CompoundAssignOperator *E)
bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E)
bool VisitCallExpr(const CallExpr *E)
const RecordType * getRecordTy(QualType Ty)
Returns a record type from a record or pointer type.
bool delegate(const Expr *E)
Just pass evaluation on to E.
bool VisitConstantExpr(const ConstantExpr *E)
bool VisitChooseExpr(const ChooseExpr *E)
bool VisitCastExpr(const CastExpr *E)
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E)
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
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.
void addExtended(const Scope::Local &Local) override
DeclScope(ByteCodeExprGen< Emitter > *Ctx, const ValueDecl *VD)
Expression scope which tracks potentially lifetime extended temporaries which are hoisted to the pare...
unsigned getNumParams() const
bool hasThisPointer() const
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Generic scope for local variables.
bool destroyLocals()
Explicit destruction of local variables.
Scope used to handle initialization methods.
OptionScope(ByteCodeExprGen< Emitter > *Ctx, bool NewDiscardResult, bool NewInitializing)
Root constructor, compiling or discarding primitives.
Context to manage declaration lifetimes.
Structure/Class descriptor.
unsigned getNumBases() const
const CXXDestructorDecl * getDestructor() const
Returns the destructor of the record, if any.
const Field * getField(const FieldDecl *FD) const
Returns a field.
llvm::iterator_range< const_base_iter > bases() const
unsigned getNumFields() const
llvm::iterator_range< const_field_iter > fields() const
const Base * getBase(const RecordDecl *FD) const
Returns a base descriptor.
Describes the statement/declaration an opcode was generated from.
Scope chain managing the variable lifetimes.
virtual void addLocal(const Scope::Local &Local)
ByteCodeExprGen< Emitter > * Ctx
ByteCodeExprGen instance.
constexpr bool isPtrType(PrimType T)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool LE(InterpState &S, CodePtr OpPC)
PrimType
Enumeration of the primitive types of the VM.
llvm::BitVector collectNonNullArgs(const FunctionDecl *F, const llvm::ArrayRef< const Expr * > &Args)
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
constexpr bool isIntegralType(PrimType T)
The JSON file list parser is used to communicate input to InstallAPI.
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
@ SD_Static
Static storage duration.
const FunctionProtoType * T
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 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.
Information about a local's storage.