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:
179 return this->emitNull(classifyPrim(CE->
getType()), CE);
181 case CK_PointerToIntegral: {
183 return this->discard(SubExpr);
185 if (!this->visit(SubExpr))
189 return this->emitCastPointerIntegral(T, CE);
192 case CK_ArrayToPointerDecay: {
193 if (!this->visit(SubExpr))
195 if (!this->emitArrayDecay(CE))
198 return this->emitPopPtr(CE);
202 case CK_AtomicToNonAtomic:
203 case CK_ConstructorConversion:
204 case CK_FunctionToPointerDecay:
205 case CK_NonAtomicToAtomic:
207 case CK_UserDefinedConversion:
208 return this->delegate(SubExpr);
212 if (!this->discard(SubExpr))
214 return this->emitInvalidCast(CastKind::Reinterpret, CE);
216 return this->delegate(SubExpr);
218 case CK_IntegralToBoolean:
219 case CK_IntegralCast: {
221 return this->discard(SubExpr);
222 std::optional<PrimType> FromT = classify(SubExpr->
getType());
223 std::optional<PrimType> ToT = classify(CE->
getType());
228 if (!this->visit(SubExpr))
232 return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->
getType()), CE);
234 return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->
getType()), CE);
238 return this->emitCast(*FromT, *ToT, CE);
241 case CK_PointerToBoolean: {
245 if (!this->visit(SubExpr))
248 if (!this->emitNull(PtrT, CE))
251 return this->emitNE(PtrT, CE);
254 case CK_IntegralComplexToBoolean:
255 case CK_FloatingComplexToBoolean: {
257 return this->discard(SubExpr);
258 if (!this->visit(SubExpr))
260 return this->emitComplexBoolCast(SubExpr);
263 case CK_IntegralComplexToReal:
264 case CK_FloatingComplexToReal:
265 return this->emitComplexReal(SubExpr);
267 case CK_IntegralRealToComplex:
268 case CK_FloatingRealToComplex: {
272 std::optional<unsigned> LocalIndex =
273 allocateLocal(CE,
true);
276 if (!this->emitGetPtrLocal(*LocalIndex, CE))
281 if (!this->visitArrayElemInit(0, SubExpr))
285 if (!this->visitZeroInitializer(T, SubExpr->
getType(), SubExpr))
287 return this->emitInitElem(T, 1, SubExpr);
290 case CK_IntegralComplexCast:
291 case CK_FloatingComplexCast:
292 case CK_IntegralComplexToFloatingComplex:
293 case CK_FloatingComplexToIntegralComplex: {
297 return this->discard(SubExpr);
300 std::optional<unsigned> LocalIndex =
301 allocateLocal(CE,
true);
304 if (!this->emitGetPtrLocal(*LocalIndex, CE))
311 unsigned SubExprOffset = allocateLocalPrimitive(
312 SubExpr,
PT_Ptr,
true,
false);
313 if (!this->visit(SubExpr))
315 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, CE))
321 PrimType DestElemT = classifyPrim(DestElemType);
323 for (
unsigned I = 0; I != 2; ++I) {
324 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, CE))
326 if (!this->emitArrayElemPop(SourceElemT, I, CE))
330 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
334 if (!this->emitInitElem(DestElemT, I, CE))
341 return discard(SubExpr);
344 return this->emitInvalid(CE);
346 llvm_unreachable(
"Unhandled clang::CastKind enum");
349template <
class Emitter>
354 return this->emitConst(
LE->getValue(),
LE);
357template <
class Emitter>
362 return this->emitConstFloat(E->
getValue(), E);
365template <
class Emitter>
373 std::optional<unsigned> LocalIndex = allocateLocal(E,
false);
376 if (!this->emitGetPtrLocal(*LocalIndex, E))
383 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
385 if (!this->emitInitElem(SubExprT, 0, SubExpr))
387 return this->visitArrayElemInit(1, SubExpr);
390template <
class Emitter>
395template <
class Emitter>
399 return this->VisitLogicalBinOp(BO);
407 if (!this->discard(LHS))
410 return this->discard(RHS);
412 return this->delegate(RHS);
416 return this->VisitComplexBinOp(BO);
420 return this->emitComplexComparison(LHS, RHS, BO);
423 return this->visit(RHS);
426 std::optional<PrimType>
LT = classify(LHS->
getType());
427 std::optional<PrimType> RT = classify(RHS->
getType());
428 std::optional<PrimType> T = classify(BO->
getType());
437 Ctx.getASTContext().CompCategories.lookupInfoForType(BO->
getType());
442 std::optional<unsigned> ResultIndex = this->allocateLocal(BO,
false);
443 if (!this->emitGetPtrLocal(*ResultIndex, BO))
447 if (!visit(LHS) || !visit(RHS))
450 return this->emitCMP3(*
LT, CmpInfo, BO);
453 if (!
LT || !RT || !T)
459 return this->VisitPointerArithBinOp(BO);
462 if (!visit(LHS) || !visit(RHS))
467 auto MaybeCastToBool = [
this, T, BO](
bool Result) {
471 return this->emitPop(*T, BO);
473 return this->emitCast(
PT_Bool, *T, BO);
477 auto Discard = [
this, T, BO](
bool Result) {
480 return DiscardResult ? this->emitPop(*T, BO) :
true;
485 return MaybeCastToBool(this->emitEQ(*
LT, BO));
487 return MaybeCastToBool(this->emitNE(*
LT, BO));
489 return MaybeCastToBool(this->emitLT(*
LT, BO));
491 return MaybeCastToBool(this->emitLE(*
LT, BO));
493 return MaybeCastToBool(this->emitGT(*
LT, BO));
495 return MaybeCastToBool(this->emitGE(*
LT, BO));
498 return Discard(this->emitSubf(getRoundingMode(BO), BO));
499 return Discard(this->emitSub(*T, BO));
502 return Discard(this->emitAddf(getRoundingMode(BO), BO));
503 return Discard(this->emitAdd(*T, BO));
506 return Discard(this->emitMulf(getRoundingMode(BO), BO));
507 return Discard(this->emitMul(*T, BO));
509 return Discard(this->emitRem(*T, BO));
512 return Discard(this->emitDivf(getRoundingMode(BO), BO));
513 return Discard(this->emitDiv(*T, BO));
517 : this->emitStorePop(*T, BO);
519 if (!this->emitStoreBitField(*T, BO))
522 if (!this->emitStore(*T, BO))
528 return this->emitLoadPop(*T, BO);
531 return Discard(this->emitBitAnd(*T, BO));
533 return Discard(this->emitBitOr(*T, BO));
535 return Discard(this->emitShl(*
LT, *RT, BO));
537 return Discard(this->emitShr(*
LT, *RT, BO));
539 return Discard(this->emitBitXor(*T, BO));
542 llvm_unreachable(
"Already handled earlier");
547 llvm_unreachable(
"Unhandled binary op");
552template <
class Emitter>
558 if ((Op != BO_Add && Op != BO_Sub) ||
562 std::optional<PrimType>
LT = classify(LHS);
563 std::optional<PrimType> RT = classify(RHS);
573 if (!visit(RHS) || !visit(LHS))
576 return this->emitSubPtr(classifyPrim(E->
getType()), E);
581 if (!visit(RHS) || !visit(LHS))
585 if (!visit(LHS) || !visit(RHS))
593 return this->emitAddOffset(OffsetType, E);
594 else if (Op == BO_Sub)
595 return this->emitSubOffset(OffsetType, E);
600template <
class Emitter>
606 std::optional<PrimType> T = classify(E->
getType());
610 LabelTy LabelTrue = this->getLabel();
611 LabelTy LabelEnd = this->getLabel();
613 if (!this->visitBool(LHS))
615 if (!this->jumpTrue(LabelTrue))
618 if (!this->visitBool(RHS))
620 if (!this->jump(LabelEnd))
623 this->emitLabel(LabelTrue);
624 this->emitConstBool(
true, E);
625 this->fallthrough(LabelEnd);
626 this->emitLabel(LabelEnd);
629 assert(Op == BO_LAnd);
632 LabelTy LabelFalse = this->getLabel();
633 LabelTy LabelEnd = this->getLabel();
635 if (!this->visitBool(LHS))
637 if (!this->jumpFalse(LabelFalse))
640 if (!this->visitBool(RHS))
642 if (!this->jump(LabelEnd))
645 this->emitLabel(LabelFalse);
646 this->emitConstBool(
false, E);
647 this->fallthrough(LabelEnd);
648 this->emitLabel(LabelEnd);
652 return this->emitPopBool(E);
657 return this->emitCast(
PT_Bool, *T, E);
661template <
class Emitter>
665 std::optional<unsigned> LocalIndex = allocateLocal(E,
false);
668 if (!this->emitGetPtrLocal(*LocalIndex, E))
678 unsigned ResultOffset = ~0u;
680 ResultOffset = this->allocateLocalPrimitive(E,
PT_Ptr,
true,
false);
683 if (!this->DiscardResult) {
684 if (!this->emitDupPtr(E))
686 if (!this->emitSetLocal(
PT_Ptr, ResultOffset, E))
691 LHSType = AT->getValueType();
694 RHSType = AT->getValueType();
701 LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
702 if (!this->visit(LHS))
704 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
707 LHSIsComplex =
false;
708 PrimType LHST = classifyPrim(LHSType);
709 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
710 if (!this->visit(LHS))
712 if (!this->emitSetLocal(LHST, LHSOffset, E))
721 RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
722 if (!this->visit(RHS))
724 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
727 RHSIsComplex =
false;
728 PrimType RHST = classifyPrim(RHSType);
729 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
730 if (!this->visit(RHS))
732 if (!this->emitSetLocal(RHST, RHSOffset, E))
739 auto loadComplexValue = [
this](
bool IsComplex,
unsigned ElemIndex,
740 unsigned Offset,
const Expr *E) ->
bool {
742 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
744 return this->emitArrayElemPop(classifyComplexElementType(E->
getType()),
748 return this->emitGetLocal(classifyPrim(E->
getType()), Offset, E);
749 return this->visitZeroInitializer(classifyPrim(E->
getType()), E->
getType(),
755 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
757 if (!this->DiscardResult) {
758 if (!this->emitGetLocal(
PT_Ptr, ResultOffset, E))
762 if (!loadComplexValue(LHSIsComplex, ElemIndex, LHSOffset, LHS))
765 if (!loadComplexValue(RHSIsComplex, ElemIndex, RHSOffset, RHS))
772 if (!this->emitAddf(getRoundingMode(E), E))
775 if (!this->emitAdd(ResultElemT, E))
781 if (!this->emitSubf(getRoundingMode(E), E))
784 if (!this->emitSub(ResultElemT, E))
793 if (!this->DiscardResult) {
795 if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))
798 if (!this->emitPop(ResultElemT, E))
805template <
class Emitter>
809 if (std::optional<PrimType> T = classify(QT))
810 return this->visitZeroInitializer(*T, QT, E);
821 const auto *CAT = cast<ConstantArrayType>(AT);
822 size_t NumElems = CAT->getZExtSize();
823 PrimType ElemT = classifyPrim(CAT->getElementType());
825 for (
size_t I = 0; I != NumElems; ++I) {
826 if (!this->visitZeroInitializer(ElemT, CAT->getElementType(), E))
828 if (!this->emitInitElem(ElemT, I, E))
836 assert(Initializing);
838 PrimType ElemT = classifyPrim(ElemQT);
839 for (
unsigned I = 0; I < 2; ++I) {
840 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
842 if (!this->emitInitElem(ElemT, I, E))
851template <
class Emitter>
858 return this->discard(
Base) && this->discard(Index);
862 if (!this->visit(
Base))
865 if (!this->visit(Index))
868 PrimType IndexT = classifyPrim(Index->getType());
869 return this->emitArrayElemPtrPop(IndexT, E);
872template <
class Emitter>
878 if (Inits.size() == 1 && E->
getType() == Inits[0]->getType()) {
879 return this->visitInitializer(Inits[0]);
882 unsigned InitIndex = 0;
884 if (!this->emitDupPtr(E))
887 if (std::optional<PrimType> T = classify(
Init)) {
888 const Record::Field *FieldToInit = R->
getField(InitIndex);
889 if (!this->visit(
Init))
892 if (FieldToInit->isBitField()) {
893 if (!this->emitInitBitField(*T, FieldToInit, E))
896 if (!this->emitInitField(*T, FieldToInit->Offset, E))
900 if (!this->emitPopPtr(E))
905 if (
const Record::Base *B = R->
getBase(
Init->getType())) {
906 if (!this->emitGetPtrBasePop(B->Offset,
Init))
909 if (!this->visitInitializer(
Init))
912 if (!this->emitFinishInitPop(E))
917 const Record::Field *FieldToInit = R->
getField(InitIndex);
920 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
923 if (!this->visitInitializer(
Init))
926 if (!this->emitPopPtr(E))
937template <
class Emitter>
940 if (std::optional<PrimType> T = classify(
Init->getType())) {
942 if (!this->visit(
Init))
944 return this->emitInitElem(*T, ElemIndex,
Init);
949 if (!this->emitConstUint32(ElemIndex,
Init))
951 if (!this->emitArrayElemPtrUint32(
Init))
953 if (!this->visitInitializer(
Init))
955 return this->emitFinishInitPop(
Init);
958template <
class Emitter>
963 if (!this->discard(
Init))
970 if (std::optional<PrimType> T = classify(E->
getType())) {
971 assert(!DiscardResult);
973 return this->visitZeroInitializer(*T, E->
getType(), E);
975 return this->delegate(E->
inits()[0]);
980 return this->visitInitList(E->
inits(), E);
983 unsigned ElementIndex = 0;
985 if (!this->visitArrayElemInit(ElementIndex,
Init))
994 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
997 for (; ElementIndex != NumElems; ++ElementIndex) {
998 if (!this->visitArrayElemInit(ElementIndex, Filler))
1010 return this->delegate(E->
inits()[0]);
1013 PrimType ElemT = classifyPrim(ElemQT);
1014 if (NumInits == 0) {
1016 for (
unsigned I = 0; I < 2; ++I) {
1017 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1019 if (!this->emitInitElem(ElemT, I, E))
1022 }
else if (NumInits == 2) {
1023 unsigned InitIndex = 0;
1025 if (!this->visit(
Init))
1028 if (!this->emitInitElem(ElemT, InitIndex, E))
1039template <
class Emitter>
1042 if (DiscardResult) {
1044 if (!this->discard(
Init))
1054template <
class Emitter>
1060template <
class Emitter>
1062 std::optional<PrimType> T = classify(E->
getType());
1078 bool AlignOfReturnsPreferred =
1079 ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
1090 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
1096template <
class Emitter>
1100 const ASTContext &ASTCtx = Ctx.getASTContext();
1102 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
1117 if (Kind == UETT_SizeOf)
1126 return this->emitConst(Size.getQuantity(), E);
1129 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
1146 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
1149 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
1159 return this->emitConst(Size.getQuantity(), E);
1165template <
class Emitter>
1171 return this->discard(
Base);
1174 if (!this->delegate(
Base))
1177 if (!this->visit(
Base))
1184 if (
const auto *FD = dyn_cast<FieldDecl>(
Member)) {
1186 const Record *R = getRecord(RD);
1187 const Record::Field *F = R->
getField(FD);
1189 if (F->Decl->getType()->isReferenceType())
1190 return this->emitGetFieldPop(
PT_Ptr, F->Offset, E);
1191 return this->emitGetPtrField(F->Offset, E);
1197template <
class Emitter>
1204 return this->emitConst(*ArrayIndex, E);
1207template <
class Emitter>
1210 assert(Initializing);
1211 assert(!DiscardResult);
1226 for (
size_t I = 0; I != Size; ++I) {
1230 if (!this->visitArrayElemInit(I, SubExpr))
1236template <
class Emitter>
1243 return this->visitInitializer(SourceExpr);
1246 if (
auto It = OpaqueExprs.find(E); It != OpaqueExprs.end())
1247 return this->emitGetLocal(SubExprT, It->second, E);
1249 if (!this->visit(SourceExpr))
1255 unsigned LocalIndex = allocateLocalPrimitive(E, SubExprT,
true);
1256 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
1261 if (!DiscardResult) {
1262 if (!this->emitGetLocal(SubExprT, LocalIndex, E))
1267 OpaqueExprs.insert({E, LocalIndex});
1272template <
class Emitter>
1279 LabelTy LabelEnd = this->getLabel();
1280 LabelTy LabelFalse = this->getLabel();
1285 if (!this->jumpFalse(LabelFalse))
1288 if (!this->delegate(TrueExpr))
1290 if (!this->jump(LabelEnd))
1293 this->emitLabel(LabelFalse);
1295 if (!this->delegate(FalseExpr))
1298 this->fallthrough(LabelEnd);
1299 this->emitLabel(LabelEnd);
1304template <
class Emitter>
1309 if (!Initializing) {
1310 unsigned StringIndex =
P.createGlobalString(E);
1311 return this->emitGetPtrGlobal(StringIndex, E);
1316 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
1317 assert(CAT &&
"a string literal that's not a constant array?");
1322 unsigned N = std::min(ArraySize, E->
getLength());
1325 for (
unsigned I = 0; I != N; ++I) {
1328 if (CharWidth == 1) {
1329 this->emitConstSint8(CodeUnit, E);
1330 this->emitInitElemSint8(I, E);
1331 }
else if (CharWidth == 2) {
1332 this->emitConstUint16(CodeUnit, E);
1333 this->emitInitElemUint16(I, E);
1334 }
else if (CharWidth == 4) {
1335 this->emitConstUint32(CodeUnit, E);
1336 this->emitInitElemUint32(I, E);
1338 llvm_unreachable(
"unsupported character width");
1343 for (
unsigned I = N; I != ArraySize; ++I) {
1344 if (CharWidth == 1) {
1345 this->emitConstSint8(0, E);
1346 this->emitInitElemSint8(I, E);
1347 }
else if (CharWidth == 2) {
1348 this->emitConstUint16(0, E);
1349 this->emitInitElemUint16(I, E);
1350 }
else if (CharWidth == 4) {
1351 this->emitConstUint32(0, E);
1352 this->emitInitElemUint32(I, E);
1354 llvm_unreachable(
"unsupported character width");
1361template <
class Emitter>
1366 return this->emitConst(E->
getValue(), E);
1369template <
class Emitter>
1378 std::optional<PrimType>
LT = classify(LHSComputationType);
1379 std::optional<PrimType> RT = classify(ResultType);
1386 PrimType LHST = classifyPrim(LHSType);
1394 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT,
true);
1395 if (!this->emitSetLocal(*RT, TempOffset, E))
1401 if (!this->emitLoad(LHST, E))
1405 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
1406 LHSComputationType, E))
1410 if (!this->emitGetLocal(*RT, TempOffset, E))
1413 llvm::RoundingMode RM = getRoundingMode(E);
1416 if (!this->emitAddf(RM, E))
1420 if (!this->emitSubf(RM, E))
1424 if (!this->emitMulf(RM, E))
1428 if (!this->emitDivf(RM, E))
1435 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->
getType(), E))
1439 return this->emitStorePop(LHST, E);
1440 return this->emitStore(LHST, E);
1443template <
class Emitter>
1449 std::optional<PrimType>
LT = classify(LHS->
getType());
1450 std::optional<PrimType> RT = classify(RHS->
getType());
1452 if (Op != BO_AddAssign && Op != BO_SubAssign)
1461 if (!this->emitLoad(*
LT, LHS))
1467 if (Op == BO_AddAssign) {
1468 if (!this->emitAddOffset(*RT, E))
1471 if (!this->emitSubOffset(*RT, E))
1476 return this->emitStorePopPtr(E);
1477 return this->emitStorePtr(E);
1480template <
class Emitter>
1486 std::optional<PrimType> LHSComputationT =
1488 std::optional<PrimType>
LT = classify(LHS->
getType());
1489 std::optional<PrimType> RT = classify(RHS->
getType());
1490 std::optional<PrimType> ResultT = classify(E->
getType());
1492 if (!
LT || !RT || !ResultT || !LHSComputationT)
1499 return VisitFloatCompoundAssignOperator(E);
1502 return VisitPointerCompoundAssignOperator(E);
1515 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT,
true);
1517 if (!this->emitSetLocal(*RT, TempOffset, E))
1524 if (!this->emitLoad(*
LT, E))
1526 if (*
LT != *LHSComputationT) {
1527 if (!this->emitCast(*
LT, *LHSComputationT, E))
1532 if (!this->emitGetLocal(*RT, TempOffset, E))
1538 if (!this->emitAdd(*LHSComputationT, E))
1542 if (!this->emitSub(*LHSComputationT, E))
1546 if (!this->emitMul(*LHSComputationT, E))
1550 if (!this->emitDiv(*LHSComputationT, E))
1554 if (!this->emitRem(*LHSComputationT, E))
1558 if (!this->emitShl(*LHSComputationT, *RT, E))
1562 if (!this->emitShr(*LHSComputationT, *RT, E))
1566 if (!this->emitBitAnd(*LHSComputationT, E))
1570 if (!this->emitBitXor(*LHSComputationT, E))
1574 if (!this->emitBitOr(*LHSComputationT, E))
1578 llvm_unreachable(
"Unimplemented compound assign operator");
1582 if (*ResultT != *LHSComputationT) {
1583 if (!this->emitCast(*LHSComputationT, *ResultT, E))
1588 if (DiscardResult) {
1590 return this->emitStoreBitFieldPop(*ResultT, E);
1591 return this->emitStorePop(*ResultT, E);
1594 return this->emitStoreBitField(*ResultT, E);
1595 return this->emitStore(*ResultT, E);
1598template <
class Emitter>
1603 assert(E->
getNumObjects() == 0 &&
"TODO: Implement cleanups");
1605 return this->delegate(SubExpr);
1608template <
class Emitter>
1615 return this->visitInitializer(SubExpr);
1620 return this->discard(SubExpr);
1624 std::optional<PrimType> SubExprT = classify(SubExpr);
1627 std::optional<unsigned> GlobalIndex =
P.createGlobal(E);
1637 if (!this->visit(SubExpr))
1640 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl, E))
1643 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex, E))
1646 return this->emitGetPtrGlobal(*GlobalIndex, E);
1650 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1652 if (!this->visitInitializer(SubExpr))
1655 return this->emitInitGlobalTempComp(TempDecl, E);
1661 unsigned LocalIndex = allocateLocalPrimitive(
1662 SubExpr, *SubExprT,
true,
true);
1663 if (!this->visit(SubExpr))
1665 if (!this->emitSetLocal(*SubExprT, LocalIndex, E))
1667 return this->emitGetPtrLocal(LocalIndex, E);
1671 if (std::optional<unsigned> LocalIndex =
1672 allocateLocal(Inner,
true)) {
1673 if (!this->emitGetPtrLocal(*LocalIndex, E))
1675 return this->visitInitializer(SubExpr);
1681template <
class Emitter>
1687template <
class Emitter>
1693 return this->visitInitializer(
Init);
1696 std::optional<PrimType> T = classify(E->
getType());
1700 return this->delegate(
Init);
1702 if (std::optional<unsigned> GlobalIndex =
P.createGlobal(E)) {
1703 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1707 if (!this->visit(
Init))
1709 return this->emitInitGlobal(*T, *GlobalIndex, E);
1712 return this->visitInitializer(
Init);
1721 return this->delegate(
Init);
1723 unsigned LocalIndex;
1726 LocalIndex = this->allocateLocalPrimitive(
Init, *T,
false,
false);
1727 else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(
Init))
1728 LocalIndex = *MaybeIndex;
1732 if (!this->emitGetPtrLocal(LocalIndex, E))
1736 if (!this->visit(
Init)) {
1739 return this->emitInit(*T, E);
1741 if (!this->visitInitializer(
Init))
1746 return this->emitPopPtr(E);
1753template <
class Emitter>
1758 return this->emitConstBool(E->
getValue(), E);
1759 return this->emitConst(E->
getValue(), E);
1762template <
class Emitter>
1767 return this->emitConst(E->
getValue(), E);
1770template <
class Emitter>
1775 assert(Initializing);
1781 for (
const Record::Field &F : R->
fields()) {
1788 if (std::optional<PrimType> T = classify(
Init)) {
1789 if (!this->visit(
Init))
1792 if (!this->emitSetField(*T, F.Offset, E))
1795 if (!this->emitDupPtr(E))
1798 if (!this->emitGetPtrField(F.Offset, E))
1801 if (!this->visitInitializer(
Init))
1804 if (!this->emitPopPtr(E))
1812template <
class Emitter>
1820template <
class Emitter>
1825 return this->emitInvalid(E);
1828template <
class Emitter>
1834 return this->emitInvalidCast(CastKind::Reinterpret, E);
1837template <
class Emitter>
1843 return this->emitConstBool(E->
getValue(), E);
1846template <
class Emitter>
1850 assert(!classify(T));
1858 return this->visitZeroRecordInitializer(R, E);
1866 assert(
Func->hasThisPointer());
1867 assert(!
Func->hasRVO());
1871 if (DiscardResult) {
1872 assert(!Initializing);
1873 std::optional<unsigned> LocalIndex =
1874 allocateLocal(E,
true);
1879 if (!this->emitGetPtrLocal(*LocalIndex, E))
1885 if (!this->emitDupPtr(E))
1889 for (
const auto *Arg : E->
arguments()) {
1890 if (!this->visit(Arg))
1894 if (
Func->isVariadic()) {
1895 uint32_t VarArgSize = 0;
1896 unsigned NumParams =
Func->getNumWrittenParams();
1897 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I) {
1901 if (!this->emitCallVar(
Func, VarArgSize, E))
1904 if (!this->emitCall(
Func, 0, E))
1909 if (DiscardResult) {
1910 if (!this->emitRecordDestruction(getRecord(E->
getType())))
1912 if (!this->emitPopPtr(E))
1920 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
1929 for (
size_t I = 0; I != NumElems; ++I) {
1930 if (!this->emitConstUint64(I, E))
1932 if (!this->emitArrayElemPtrUint64(E))
1936 for (
const auto *Arg : E->
arguments()) {
1937 if (!this->visit(Arg))
1941 if (!this->emitCall(
Func, 0, E))
1950template <
class Emitter>
1960 assert(Val.
isInt());
1962 return this->emitConst(I, E);
1969 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
1970 return this->visit(LValueExpr);
1979 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
1981 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(UGCD);
1985 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1989 const APValue &
V = UGCD->getValue();
1990 for (
unsigned I = 0, N = R->
getNumFields(); I != N; ++I) {
1991 const Record::Field *F = R->
getField(I);
1992 const APValue &FieldValue =
V.getStructField(I);
1994 PrimType FieldT = classifyPrim(F->Decl->getType());
1996 if (!this->visitAPValue(FieldValue, FieldT, E))
1998 if (!this->emitInitField(FieldT, F->Offset, E))
2006template <
class Emitter>
2012 for (
unsigned I = 0; I != N; ++I) {
2018 if (DiscardResult) {
2019 if (!this->discard(ArrayIndexExpr))
2024 if (!this->visit(ArrayIndexExpr))
2028 if (!this->emitCast(IndexT,
PT_Sint64, E))
2038 return this->emitOffsetOf(T, E, E);
2041template <
class Emitter>
2049 if (std::optional<PrimType> T = classify(Ty))
2050 return this->visitZeroInitializer(*T, Ty, E);
2053 if (!Initializing) {
2054 std::optional<unsigned> LocalIndex = allocateLocal(E,
false);
2057 if (!this->emitGetPtrLocal(*LocalIndex, E))
2063 PrimType ElemT = classifyPrim(ElemQT);
2065 for (
unsigned I = 0; I != 2; ++I) {
2066 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2068 if (!this->emitInitElem(ElemT, I, E))
2074template <
class Emitter>
2079template <
class Emitter>
2085template <
class Emitter>
2090template <
class Emitter>
2096 return this->emitConst(E->
getValue(), E);
2099template <
class Emitter>
2104 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
2105 const Function *F = this->getFunction(Ctor);
2122 if (!this->emitGetParam(PT, Offset, E))
2127 return this->emitCall(F, 0, E);
2130template <
class Emitter>
2133 assert(Ctx.getLangOpts().CPlusPlus);
2134 return this->emitConstBool(E->
getValue(), E);
2137template <
class Emitter>
2141 assert(!Initializing);
2143 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(E->
getGuidDecl());
2146 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2156 assert(
V.isStruct());
2157 assert(
V.getStructNumBases() == 0);
2159 for (
unsigned I = 0, N =
V.getStructNumFields(); I != N; ++I) {
2160 const APValue &F =
V.getStructField(I);
2161 const Record::Field *RF = R->
getField(I);
2164 PrimType T = classifyPrim(RF->Decl->getType());
2165 if (!this->visitAPValue(F, T, E))
2167 if (!this->emitInitField(T, RF->Offset, E))
2170 assert(RF->Desc->isPrimitiveArray());
2171 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
2172 PrimType ElemT = classifyPrim(ArrType->getElementType());
2175 if (!this->emitDupPtr(E))
2177 if (!this->emitGetPtrField(RF->Offset, E))
2180 for (
unsigned A = 0, AN = F.
getArraySize(); A != AN; ++A) {
2183 if (!this->emitInitElem(ElemT, A, E))
2187 if (!this->emitPopPtr(E))
2190 assert(
false &&
"I don't think this should be possible");
2194 return this->emitFinishInit(E);
2197template <
class Emitter>
2203template <
class Emitter>
2210template <
class Emitter>
2216template <
class Emitter>
2221 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
2225 if (OVE->isUnique())
2228 if (!this->discard(OVE))
2231 if (!this->delegate(SemE))
2234 if (!this->discard(SemE))
2241template <
class Emitter>
2253 return this->Visit(E);
2256template <
class Emitter>
2259 return this->emitError(E);
2264 return this->Visit(E);
2269 return this->emitError(E);
2272 return this->discard(E);
2277 std::optional<unsigned> LocalIndex = allocateLocal(E,
true);
2281 if (!this->emitGetPtrLocal(*LocalIndex, E))
2283 return this->visitInitializer(E);
2290 return this->Visit(E);
2293template <
class Emitter>
2295 assert(!classify(E->
getType()));
2298 return this->emitError(E);
2302 return this->Visit(E);
2305template <
class Emitter>
2307 std::optional<PrimType> T = classify(E->
getType());
2311 if (!this->visit(E))
2313 return this->emitComplexBoolCast(E);
2318 if (!this->visit(E))
2326 if (!this->emitNull(*T, E))
2328 return this->emitNE(*T, E);
2333 return this->emitCastFloatingIntegralBool(E);
2336 return this->emitCast(*T,
PT_Bool, E);
2339template <
class Emitter>
2344 return this->emitZeroBool(E);
2346 return this->emitZeroSint8(E);
2348 return this->emitZeroUint8(E);
2350 return this->emitZeroSint16(E);
2352 return this->emitZeroUint16(E);
2354 return this->emitZeroSint32(E);
2356 return this->emitZeroUint32(E);
2358 return this->emitZeroSint64(E);
2360 return this->emitZeroUint64(E);
2362 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
2364 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
2366 return this->emitNullPtr(E);
2368 return this->emitNullFnPtr(E);
2370 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E);
2373 llvm_unreachable(
"unknown primitive type");
2376template <
class Emitter>
2382 for (
const Record::Field &Field : R->
fields()) {
2387 if (!this->visitZeroInitializer(T, QT, E))
2389 if (!this->emitInitField(T,
Field.Offset, E))
2395 if (!this->emitDupPtr(E))
2397 if (!this->emitGetPtrField(
Field.Offset, E))
2403 for (uint32_t I = 0, N = D->
getNumElems(); I != N; ++I) {
2404 if (!this->visitZeroInitializer(T, ET, E))
2406 if (!this->emitInitElem(T, I, E))
2412 for (uint32_t I = 0, N = D->
getNumElems(); I != N; ++I) {
2413 if (!this->emitConstUint32(I, E))
2415 if (!this->emitArrayElemPtr(
PT_Uint32, E))
2417 if (!this->visitZeroRecordInitializer(ElemRecord, E))
2419 if (!this->emitPopPtr(E))
2423 if (!this->visitZeroRecordInitializer(D->
ElemRecord, E))
2429 if (!this->emitPopPtr(E))
2433 for (
const Record::Base &B : R->
bases()) {
2434 if (!this->emitGetPtrBase(B.Offset, E))
2436 if (!this->visitZeroRecordInitializer(B.R, E))
2438 if (!this->emitFinishInitPop(E))
2447template <
class Emitter>
2448template <
typename T>
2452 return this->emitConstSint8(
Value, E);
2454 return this->emitConstUint8(
Value, E);
2456 return this->emitConstSint16(
Value, E);
2458 return this->emitConstUint16(
Value, E);
2460 return this->emitConstSint32(
Value, E);
2462 return this->emitConstUint32(
Value, E);
2464 return this->emitConstSint64(
Value, E);
2466 return this->emitConstUint64(
Value, E);
2468 return this->emitConstBool(
Value, E);
2474 llvm_unreachable(
"Invalid integral type");
2477 llvm_unreachable(
"unknown primitive type");
2480template <
class Emitter>
2481template <
typename T>
2483 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
2486template <
class Emitter>
2490 return this->emitConstIntAPS(
Value, E);
2492 return this->emitConstIntAP(
Value, E);
2494 if (
Value.isSigned())
2495 return this->emitConst(
Value.getSExtValue(), Ty, E);
2496 return this->emitConst(
Value.getZExtValue(), Ty, E);
2499template <
class Emitter>
2501 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
2504template <
class Emitter>
2510 if (
const auto *VD =
2511 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
2512 assert(!
P.getGlobal(VD));
2513 assert(!Locals.contains(VD));
2520 Src.is<
const Expr *>());
2522 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
2523 Locals.insert({VD, Local});
2524 VarScope->add(Local, IsExtended);
2525 return Local.Offset;
2528template <
class Emitter>
2529std::optional<unsigned>
2532 if ([[maybe_unused]]
const auto *VD =
2533 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
2534 assert(!
P.getGlobal(VD));
2535 assert(!Locals.contains(VD));
2541 bool IsTemporary =
false;
2542 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
2546 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
2547 Init = VarD->getInit();
2549 if (
auto *E = Src.dyn_cast<
const Expr *>()) {
2556 IsTemporary,
false,
Init);
2558 return std::nullopt;
2562 Locals.insert({Key, Local});
2563 VarScope->add(Local, IsExtended);
2564 return Local.Offset;
2567template <
class Emitter>
2569 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
2574template <
class Emitter>
2576 if (
const auto *RecordTy = getRecordTy(Ty))
2577 return getRecord(RecordTy->getDecl());
2581template <
class Emitter>
2583 return P.getOrCreateRecord(RD);
2586template <
class Emitter>
2588 return Ctx.getOrCreateFunction(FD);
2591template <
class Emitter>
2598 return this->emitRetVoid(E);
2602 if (std::optional<PrimType> T = classify(E)) {
2605 return this->emitRet(*T, E);
2611 if (std::optional<unsigned> LocalOffset = this->allocateLocal(E)) {
2612 if (!this->emitGetPtrLocal(*LocalOffset, E))
2615 if (!visitInitializer(E))
2618 if (!this->emitFinishInit(E))
2632template <
class Emitter>
2634 assert(!VD->
isInvalidDecl() &&
"Trying to constant evaluate an invalid decl");
2638 if (std::optional<unsigned> Index =
P.getGlobal(VD);
2639 Index && !
P.getPtrGlobal(*Index).isInitialized())
2643 if (!this->visitVarDecl(VD))
2646 std::optional<PrimType> VarT = classify(VD->
getType());
2649 auto GlobalIndex =
P.getGlobal(VD);
2650 assert(GlobalIndex);
2652 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
2655 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
2659 auto Local = Locals.find(VD);
2660 assert(Local != Locals.end());
2662 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
2665 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
2672 return this->emitRet(*VarT, VD);
2675 return this->emitRet(
PT_Ptr, VD);
2678template <
class Emitter>
2685 std::optional<PrimType> VarT = classify(VD->
getType());
2689 if (
P.getGlobal(VD))
2692 std::optional<unsigned> GlobalIndex =
P.createGlobal(VD,
Init);
2701 if (!this->visit(
Init))
2703 return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
2705 return this->visitGlobalInitializer(
Init, *GlobalIndex);
2711 unsigned Offset = this->allocateLocalPrimitive(
2716 if (!this->visit(
Init))
2719 return this->emitSetLocal(*VarT, Offset, VD);
2722 if (std::optional<unsigned> Offset = this->allocateLocal(VD))
2723 return !
Init || this->visitLocalInitializer(
Init, *Offset);
2732template <
class Emitter>
2735 assert(!DiscardResult);
2737 return this->emitConst(Val.
getInt(), ValType, E);
2741 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
2742 return this->visit(BaseExpr);
2748template <
class Emitter>
2755 std::optional<PrimType> ReturnT = classify(E);
2758 if (!Initializing && !ReturnT && !ReturnType->
isVoidType()) {
2759 std::optional<unsigned> LocalIndex = allocateLocal(E,
false);
2762 if (!this->emitGetPtrLocal(*LocalIndex, E))
2766 if (!
Func->isUnevaluatedBuiltin()) {
2768 for (
const auto *Arg : E->
arguments()) {
2769 if (!this->visit(Arg))
2774 if (!this->emitCallBI(
Func, E, E))
2777 if (DiscardResult && !ReturnType->
isVoidType()) {
2779 return this->emitPop(*ReturnT, E);
2785template <
class Emitter>
2788 return VisitBuiltinCallExpr(E);
2791 std::optional<PrimType> T = classify(ReturnType);
2792 bool HasRVO = !ReturnType->
isVoidType() && !T;
2796 if (DiscardResult) {
2800 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
2801 if (!this->emitGetPtrLocal(*LocalIndex, E))
2807 if (!Initializing) {
2808 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
2809 if (!this->emitGetPtrLocal(*LocalIndex, E))
2813 if (!this->emitDupPtr(E))
2822 if (isa<CXXOperatorCallExpr>(E)) {
2823 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
2824 MD && MD->isStatic()) {
2825 if (!this->discard(E->
getArg(0)))
2827 Args = Args.drop_front();
2832 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
2833 if (!this->visit(MC->getImplicitObjectArgument()))
2839 unsigned ArgIndex = 0;
2840 for (
const auto *Arg : Args) {
2841 if (!this->visit(Arg))
2845 if (FuncDecl && NonNullArgs[ArgIndex]) {
2848 if (!this->emitCheckNonNullArg(ArgT, Arg))
2859 assert(HasRVO ==
Func->hasRVO());
2861 bool HasQualifier =
false;
2862 if (
const auto *ME = dyn_cast<MemberExpr>(E->
getCallee()))
2863 HasQualifier = ME->hasQualifier();
2865 bool IsVirtual =
false;
2866 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
2867 IsVirtual = MD->isVirtual();
2872 if (IsVirtual && !HasQualifier) {
2873 uint32_t VarArgSize = 0;
2874 unsigned NumParams =
Func->getNumWrittenParams();
2875 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
2878 if (!this->emitCallVirt(
Func, VarArgSize, E))
2880 }
else if (
Func->isVariadic()) {
2881 uint32_t VarArgSize = 0;
2882 unsigned NumParams =
2883 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(E);
2884 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
2886 if (!this->emitCallVar(
Func, VarArgSize, E))
2889 if (!this->emitCall(
Func, 0, E))
2898 uint32_t ArgSize = 0;
2899 for (
unsigned I = 0, N = E->
getNumArgs(); I != N; ++I)
2905 if (!this->emitCallPtr(ArgSize, E, E))
2910 if (DiscardResult && !ReturnType->
isVoidType() && T)
2911 return this->emitPop(*T, E);
2916template <
class Emitter>
2920 return this->delegate(E->
getExpr());
2923template <
class Emitter>
2929 if (std::optional<PrimType> T = classify(E->
getExpr()))
2930 return this->visit(SubExpr);
2932 assert(Initializing);
2933 return this->visitInitializer(SubExpr);
2936template <
class Emitter>
2942 return this->emitConstBool(E->
getValue(), E);
2945template <
class Emitter>
2951 return this->emitNullPtr(E);
2954template <
class Emitter>
2962 return this->emitZero(T, E);
2965template <
class Emitter>
2970 if (this->LambdaThisCapture.Offset > 0) {
2971 if (this->LambdaThisCapture.IsPtr)
2972 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
2973 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
2976 return this->emitThis(E);
2979template <
class Emitter>
2983 return this->VisitComplexUnaryOperator(E);
2984 std::optional<PrimType> T = classify(SubExpr->
getType());
2988 if (!this->visit(SubExpr))
2992 if (!this->emitIncPtr(E))
2995 return DiscardResult ? this->emitPopPtr(E) :
true;
2999 return DiscardResult ? this->emitIncfPop(getRoundingMode(E), E)
3000 : this->emitIncf(getRoundingMode(E), E);
3003 return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E);
3006 if (!this->visit(SubExpr))
3010 if (!this->emitDecPtr(E))
3013 return DiscardResult ? this->emitPopPtr(E) :
true;
3017 return DiscardResult ? this->emitDecfPop(getRoundingMode(E), E)
3018 : this->emitDecf(getRoundingMode(E), E);
3021 return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E);
3024 if (!this->visit(SubExpr))
3028 if (!this->emitLoadPtr(E))
3030 if (!this->emitConstUint8(1, E))
3032 if (!this->emitAddOffsetUint8(E))
3034 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
3038 if (DiscardResult) {
3040 return this->emitIncfPop(getRoundingMode(E), E);
3041 return this->emitIncPop(*T, E);
3045 const auto &TargetSemantics = Ctx.getFloatSemantics(E->
getType());
3046 if (!this->emitLoadFloat(E))
3048 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
3050 if (!this->emitAddf(getRoundingMode(E), E))
3052 return this->emitStoreFloat(E);
3054 if (!this->emitLoad(*T, E))
3056 if (!this->emitConst(1, E))
3058 if (!this->emitAdd(*T, E))
3060 return this->emitStore(*T, E);
3063 if (!this->visit(SubExpr))
3067 if (!this->emitLoadPtr(E))
3069 if (!this->emitConstUint8(1, E))
3071 if (!this->emitSubOffsetUint8(E))
3073 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
3077 if (DiscardResult) {
3079 return this->emitDecfPop(getRoundingMode(E), E);
3080 return this->emitDecPop(*T, E);
3084 const auto &TargetSemantics = Ctx.getFloatSemantics(E->
getType());
3085 if (!this->emitLoadFloat(E))
3087 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
3089 if (!this->emitSubf(getRoundingMode(E), E))
3091 return this->emitStoreFloat(E);
3093 if (!this->emitLoad(*T, E))
3095 if (!this->emitConst(1, E))
3097 if (!this->emitSub(*T, E))
3099 return this->emitStore(*T, E);
3103 return this->discard(SubExpr);
3105 if (!this->visitBool(SubExpr))
3108 if (!this->emitInvBool(E))
3112 return this->emitCast(
PT_Bool, ET, E);
3115 if (!this->visit(SubExpr))
3117 return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
3119 if (!this->visit(SubExpr))
3121 return DiscardResult ? this->emitPop(*T, E) :
true;
3124 return this->delegate(SubExpr);
3127 return this->discard(SubExpr);
3128 return this->visit(SubExpr);
3130 if (!this->visit(SubExpr))
3132 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
3135 return this->delegate(SubExpr);
3138 if (!this->discard(SubExpr))
3140 return this->visitZeroInitializer(*T, SubExpr->
getType(), SubExpr);
3143 return this->delegate(SubExpr);
3145 assert(
false &&
"Unhandled opcode");
3151template <
class Emitter>
3158 return this->discard(SubExpr);
3160 std::optional<PrimType> ResT = classify(E);
3161 auto prepareResult = [=]() ->
bool {
3162 if (!ResT && !Initializing) {
3163 std::optional<unsigned> LocalIndex =
3164 allocateLocal(SubExpr,
false);
3167 return this->emitGetPtrLocal(*LocalIndex, E);
3174 unsigned SubExprOffset = ~0u;
3175 auto createTemp = [=, &SubExprOffset]() ->
bool {
3176 SubExprOffset = this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
3177 if (!this->visit(SubExpr))
3179 return this->emitSetLocal(
PT_Ptr, SubExprOffset, E);
3183 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
3184 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
3186 return this->emitArrayElemPop(ElemT, Index, E);
3191 if (!prepareResult())
3195 for (
unsigned I = 0; I != 2; ++I) {
3196 if (!getElem(SubExprOffset, I))
3198 if (!this->emitNeg(ElemT, E))
3200 if (!this->emitInitElem(ElemT, I, E))
3208 return this->delegate(SubExpr);
3211 if (!this->visit(SubExpr))
3213 if (!this->emitComplexBoolCast(SubExpr))
3215 if (!this->emitInvBool(E))
3218 return this->emitCast(
PT_Bool, ET, E);
3222 return this->emitComplexReal(SubExpr);
3225 if (!this->visit(SubExpr))
3229 if (!this->emitConstUint8(1, E))
3231 return this->emitArrayElemPtrPopUint8(E);
3236 return this->emitArrayElemPop(classifyPrim(E->
getType()), 1, E);
3239 return this->emitInvalid(E);
3245template <
class Emitter>
3252 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
3253 return this->emitConst(ECD->getInitVal(), E);
3254 }
else if (
const auto *BD = dyn_cast<BindingDecl>(D)) {
3255 return this->visit(BD->getBinding());
3256 }
else if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
3257 const Function *F = getFunction(FuncDecl);
3258 return F && this->emitGetFnPtr(F, E);
3259 }
else if (isa<TemplateParamObjectDecl>(D)) {
3260 if (std::optional<unsigned> Index =
P.getOrCreateGlobal(D))
3261 return this->emitGetPtrGlobal(*Index, E);
3272 if (
auto It = Locals.find(D); It != Locals.end()) {
3273 const unsigned Offset = It->second.Offset;
3275 return this->emitGetLocal(
PT_Ptr, Offset, E);
3276 return this->emitGetPtrLocal(Offset, E);
3277 }
else if (
auto GlobalIndex =
P.getGlobal(D)) {
3279 return this->emitGetGlobalPtr(*GlobalIndex, E);
3281 return this->emitGetPtrGlobal(*GlobalIndex, E);
3282 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
3283 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
3284 if (IsReference || !It->second.IsPtr)
3285 return this->emitGetParamPtr(It->second.Offset, E);
3287 return this->emitGetPtrParam(It->second.Offset, E);
3292 if (
auto It = this->LambdaCaptures.find(D);
3293 It != this->LambdaCaptures.end()) {
3294 auto [Offset, IsPtr] = It->second;
3297 return this->emitGetThisFieldPtr(Offset, E);
3298 return this->emitGetPtrThisField(Offset, E);
3303 if (Ctx.getLangOpts().CPlusPlus) {
3304 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
3306 if ((VD->isLocalVarDecl() || VD->isStaticDataMember()) &&
3307 VD->getType().isConstQualified()) {
3308 if (!this->visitVarDecl(VD))
3311 return this->VisitDeclRefExpr(E);
3315 if (
const auto *VD = dyn_cast<VarDecl>(D);
3316 VD && VD->getAnyInitializer() && VD->getType().isConstQualified()) {
3317 if (!this->visitVarDecl(VD))
3320 return this->VisitDeclRefExpr(E);
3324 if (std::optional<unsigned> I =
P.getOrCreateDummy(D))
3325 return this->emitGetPtrGlobal(*I, E);
3327 return this->emitInvalidDeclRef(E, E);
3330template <
class Emitter>
3333 C->emitDestruction();
3336template <
class Emitter>
3341 assert(DerivedType);
3342 const auto *FinalDecl = cast<CXXRecordDecl>(BaseType->
getDecl());
3344 const Record *CurRecord = getRecord(CurDecl);
3345 assert(CurDecl && FinalDecl);
3347 unsigned OffsetSum = 0;
3351 for (
const Record::Base &B : CurRecord->
bases()) {
3352 const auto *BaseDecl = cast<CXXRecordDecl>(B.Decl);
3354 if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) {
3355 OffsetSum += B.Offset;
3361 if (CurDecl == FinalDecl)
3365 assert(OffsetSum > 0);
3370template <
class Emitter>
3377 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
3378 return this->emitCastFP(ToSem, getRoundingMode(E), E);
3383 return this->emitCastFloatingIntegral(ToT, E);
3389 return FromT != ToT ? this->emitCast(FromT, ToT, E) :
true;
3393 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
3394 return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(E),
3403template <
class Emitter>
3408 return this->discard(SubExpr);
3410 if (!this->visit(SubExpr))
3413 if (!this->emitConstUint8(0, SubExpr))
3415 return this->emitArrayElemPtrPopUint8(SubExpr);
3419 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
3423template <
class Emitter>
3425 assert(!DiscardResult);
3429 if (!this->emitArrayElem(ElemT, 0, E))
3432 if (!this->emitCastFloatingIntegral(
PT_Bool, E))
3435 if (!this->emitCast(ElemT,
PT_Bool, E))
3440 LabelTy LabelTrue = this->getLabel();
3441 if (!this->jumpTrue(LabelTrue))
3444 if (!this->emitArrayElemPop(ElemT, 1, E))
3447 if (!this->emitCastFloatingIntegral(
PT_Bool, E))
3450 if (!this->emitCast(ElemT,
PT_Bool, E))
3454 LabelTy EndLabel = this->getLabel();
3455 this->jump(EndLabel);
3457 this->emitLabel(LabelTrue);
3458 if (!this->emitPopPtr(E))
3460 if (!this->emitConstBool(
true, E))
3463 this->fallthrough(EndLabel);
3464 this->emitLabel(EndLabel);
3469template <
class Emitter>
3474 assert(!Initializing);
3475 assert(!DiscardResult);
3481 LHSIsComplex =
true;
3482 ElemT = classifyComplexElementType(LHS->
getType());
3483 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true,
3485 if (!this->visit(LHS))
3487 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
3490 LHSIsComplex =
false;
3492 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
3493 if (!this->visit(LHS))
3495 if (!this->emitSetLocal(LHST, LHSOffset, E))
3502 RHSIsComplex =
true;
3503 ElemT = classifyComplexElementType(RHS->
getType());
3504 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true,
3506 if (!this->visit(RHS))
3508 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
3511 RHSIsComplex =
false;
3513 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
3514 if (!this->visit(RHS))
3516 if (!this->emitSetLocal(RHST, RHSOffset, E))
3520 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
3521 bool IsComplex) ->
bool {
3523 if (!this->emitGetLocal(
PT_Ptr, LocalOffset, E))
3525 return this->emitArrayElemPop(ElemT, Index, E);
3527 return this->emitGetLocal(ElemT, LocalOffset, E);
3530 for (
unsigned I = 0; I != 2; ++I) {
3532 if (!getElem(LHSOffset, I, LHSIsComplex))
3534 if (!getElem(RHSOffset, I, RHSIsComplex))
3537 if (!this->emitEQ(ElemT, E))
3540 if (!this->emitCastBoolUint8(E))
3545 if (!this->emitAddUint8(E))
3547 if (!this->emitConstUint8(2, E))
3551 if (!this->emitEQUint8(E))
3554 if (!this->emitNEUint8(E))
3561 return this->emitCast(
PT_Bool, ResT, E);
3568template <
class Emitter>
3572 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
3579 if (!this->emitDestruction(D))
3592 const Function *DtorFunc = getFunction(Dtor);
3599 if (!this->emitCall(DtorFunc, 0,
SourceInfo{}))
3603 for (
const Record::Base &
Base : llvm::reverse(R->
bases())) {
3606 if (!this->emitRecordDestruction(
Base.R))
3618template <
class Emitter>
3642 for (ssize_t I = Desc->
getNumElems() - 1; I >= 0; --I) {
3645 if (!this->emitArrayElemPtrUint64(
SourceInfo{}))
3647 if (!this->emitDestruction(ElemDesc))
3656 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.
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 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 isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
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
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 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.
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.