50 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
51 OldInitializing(Ctx->Initializing) {
57 Ctx->DiscardResult = OldDiscardResult;
58 Ctx->Initializing = OldInitializing;
65 bool OldDiscardResult;
72template <
class Emitter>
77 case CK_LValueToRValue: {
79 return this->discard(SubExpr);
81 std::optional<PrimType> SubExprT = classify(SubExpr->
getType());
83 if (!Initializing && !SubExprT) {
84 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
87 if (!this->emitGetPtrLocal(*LocalIndex, CE))
91 if (!this->visit(SubExpr))
95 return this->emitLoadPop(*SubExprT, CE);
100 return this->emitMemcpy(CE);
103 case CK_UncheckedDerivedToBase:
104 case CK_DerivedToBase: {
105 if (!this->visit(SubExpr))
109 if (
const auto *PT = dyn_cast<PointerType>(Ty))
110 return PT->getPointeeType()->getAsCXXRecordDecl();
111 return Ty->getAsCXXRecordDecl();
118 if (B->isVirtual()) {
119 if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))
121 CurType = B->getType();
123 unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
124 if (!this->emitGetPtrBasePop(DerivedOffset, CE))
126 CurType = B->getType();
133 case CK_BaseToDerived: {
134 if (!this->visit(SubExpr))
137 unsigned DerivedOffset =
140 return this->emitGetPtrDerivedPop(DerivedOffset, CE);
143 case CK_FloatingCast: {
145 return this->discard(SubExpr);
146 if (!this->visit(SubExpr))
148 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
149 return this->emitCastFP(TargetSemantics, getRoundingMode(CE), CE);
152 case CK_IntegralToFloating: {
154 return this->discard(SubExpr);
155 std::optional<PrimType> FromT = classify(SubExpr->
getType());
159 if (!this->visit(SubExpr))
162 const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->
getType());
163 llvm::RoundingMode RM = getRoundingMode(CE);
164 return this->emitCastIntegralFloating(*FromT, TargetSemantics, RM, CE);
167 case CK_FloatingToBoolean:
168 case CK_FloatingToIntegral: {
170 return this->discard(SubExpr);
172 std::optional<PrimType> ToT = classify(CE->
getType());
177 if (!this->visit(SubExpr))
181 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->
getType()),
184 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->
getType()),
187 return this->emitCastFloatingIntegral(*ToT, CE);
190 case CK_NullToPointer: {
196 if (!PointeeType.
isNull()) {
197 if (std::optional<PrimType>
T = classify(PointeeType))
198 Desc =
P.createDescriptor(SubExpr, *
T);
200 return this->emitNull(classifyPrim(CE->
getType()), Desc, CE);
203 case CK_PointerToIntegral: {
205 return this->discard(SubExpr);
207 if (!this->visit(SubExpr))
213 if (!this->emitDecayPtr(FromT,
PT_Ptr, CE))
219 return this->emitCastPointerIntegralAP(Ctx.getBitWidth(CE->
getType()),
222 return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(CE->
getType()),
224 return this->emitCastPointerIntegral(
T, CE);
227 case CK_ArrayToPointerDecay: {
228 if (!this->visit(SubExpr))
230 if (!this->emitArrayDecay(CE))
233 return this->emitPopPtr(CE);
237 case CK_IntegralToPointer: {
240 if (!this->visit(SubExpr))
246 return this->emitPop(
T, CE);
253 Desc =
P.createDescriptor(SubExpr, *
T);
261 if (!this->emitGetIntPtr(
T, Desc, CE))
264 PrimType DestPtrT = classifyPrim(PtrType);
269 return this->emitDecayPtr(
PT_Ptr, DestPtrT, CE);
272 case CK_AtomicToNonAtomic:
273 case CK_ConstructorConversion:
274 case CK_FunctionToPointerDecay:
275 case CK_NonAtomicToAtomic:
277 case CK_UserDefinedConversion:
278 return this->delegate(SubExpr);
283 if (!this->discard(SubExpr))
285 return this->emitInvalidCast(CastKind::Reinterpret, CE);
289 return this->discard(SubExpr);
291 std::optional<PrimType> FromT = classify(SubExpr->
getType());
292 std::optional<PrimType> ToT = classify(CE->
getType());
299 return this->delegate(SubExpr);
301 if (!this->visit(SubExpr))
303 return this->emitDecayPtr(*FromT, *ToT, CE);
306 case CK_IntegralToBoolean:
307 case CK_IntegralCast: {
309 return this->discard(SubExpr);
310 std::optional<PrimType> FromT = classify(SubExpr->
getType());
311 std::optional<PrimType> ToT = classify(CE->
getType());
316 if (!this->visit(SubExpr))
320 return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->
getType()), CE);
322 return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->
getType()), CE);
326 return this->emitCast(*FromT, *ToT, CE);
329 case CK_PointerToBoolean: {
333 if (!this->visit(SubExpr))
336 if (!this->emitNull(PtrT,
nullptr, CE))
339 return this->emitNE(PtrT, CE);
342 case CK_IntegralComplexToBoolean:
343 case CK_FloatingComplexToBoolean: {
345 return this->discard(SubExpr);
346 if (!this->visit(SubExpr))
348 return this->emitComplexBoolCast(SubExpr);
351 case CK_IntegralComplexToReal:
352 case CK_FloatingComplexToReal:
353 return this->emitComplexReal(SubExpr);
355 case CK_IntegralRealToComplex:
356 case CK_FloatingRealToComplex: {
360 std::optional<unsigned> LocalIndex = allocateLocal(CE);
363 if (!this->emitGetPtrLocal(*LocalIndex, CE))
368 if (!this->visitArrayElemInit(0, SubExpr))
372 if (!this->visitZeroInitializer(
T, SubExpr->
getType(), SubExpr))
374 return this->emitInitElem(
T, 1, SubExpr);
377 case CK_IntegralComplexCast:
378 case CK_FloatingComplexCast:
379 case CK_IntegralComplexToFloatingComplex:
380 case CK_FloatingComplexToIntegralComplex: {
384 return this->discard(SubExpr);
387 std::optional<unsigned> LocalIndex = allocateLocal(CE);
390 if (!this->emitGetPtrLocal(*LocalIndex, CE))
397 unsigned SubExprOffset = allocateLocalPrimitive(
398 SubExpr,
PT_Ptr,
true,
false);
399 if (!this->visit(SubExpr))
401 if (!this->emitSetLocal(
PT_Ptr, SubExprOffset, CE))
407 PrimType DestElemT = classifyPrim(DestElemType);
409 for (
unsigned I = 0; I != 2; ++I) {
410 if (!this->emitGetLocal(
PT_Ptr, SubExprOffset, CE))
412 if (!this->emitArrayElemPop(SourceElemT, I, CE))
416 if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE))
420 if (!this->emitInitElem(DestElemT, I, CE))
426 case CK_VectorSplat: {
427 assert(!classify(CE->
getType()));
428 assert(classify(SubExpr->
getType()));
432 return this->discard(SubExpr);
434 assert(Initializing);
436 PrimType ElemT = classifyPrim(SubExpr);
437 unsigned ElemOffset = allocateLocalPrimitive(
438 SubExpr, ElemT,
true,
false);
440 if (!this->visit(SubExpr))
442 if (!this->emitSetLocal(ElemT, ElemOffset, CE))
445 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
446 if (!this->emitGetLocal(ElemT, ElemOffset, CE))
448 if (!this->emitInitElem(ElemT, I, CE))
456 return discard(SubExpr);
459 return this->emitInvalid(CE);
461 llvm_unreachable(
"Unhandled clang::CastKind enum");
464template <
class Emitter>
469 return this->emitConst(
LE->getValue(),
LE);
472template <
class Emitter>
477 return this->emitConstFloat(E->
getValue(), E);
480template <
class Emitter>
488 std::optional<unsigned> LocalIndex = allocateLocal(E);
491 if (!this->emitGetPtrLocal(*LocalIndex, E))
498 if (!this->visitZeroInitializer(SubExprT, SubExpr->
getType(), SubExpr))
500 if (!this->emitInitElem(SubExprT, 0, SubExpr))
502 return this->visitArrayElemInit(1, SubExpr);
505template <
class Emitter>
510template <
class Emitter>
514 return this->VisitLogicalBinOp(BO);
522 if (!this->discard(LHS))
525 return this->discard(RHS);
527 return this->delegate(RHS);
531 return this->VisitComplexBinOp(BO);
535 return this->emitComplexComparison(LHS, RHS, BO);
538 return this->visit(RHS);
541 std::optional<PrimType>
LT = classify(LHS->
getType());
542 std::optional<PrimType> RT = classify(RHS->
getType());
543 std::optional<PrimType>
T = classify(BO->
getType());
552 Ctx.getASTContext().CompCategories.lookupInfoForType(BO->
getType());
557 std::optional<unsigned> ResultIndex = this->allocateLocal(BO);
558 if (!this->emitGetPtrLocal(*ResultIndex, BO))
562 if (!visit(LHS) || !visit(RHS))
565 return this->emitCMP3(*
LT, CmpInfo, BO);
568 if (!
LT || !RT || !
T)
574 return this->VisitPointerArithBinOp(BO);
577 if (!visit(LHS) || !visit(RHS))
582 auto MaybeCastToBool = [
this,
T, BO](
bool Result) {
586 return this->emitPop(*
T, BO);
588 return this->emitCast(
PT_Bool, *
T, BO);
592 auto Discard = [
this,
T, BO](
bool Result) {
595 return DiscardResult ? this->emitPop(*
T, BO) :
true;
600 return MaybeCastToBool(this->emitEQ(*
LT, BO));
602 return MaybeCastToBool(this->emitNE(*
LT, BO));
604 return MaybeCastToBool(this->emitLT(*
LT, BO));
606 return MaybeCastToBool(this->emitLE(*
LT, BO));
608 return MaybeCastToBool(this->emitGT(*
LT, BO));
610 return MaybeCastToBool(this->emitGE(*
LT, BO));
613 return Discard(this->emitSubf(getRoundingMode(BO), BO));
614 return Discard(this->emitSub(*
T, BO));
617 return Discard(this->emitAddf(getRoundingMode(BO), BO));
618 return Discard(this->emitAdd(*
T, BO));
621 return Discard(this->emitMulf(getRoundingMode(BO), BO));
622 return Discard(this->emitMul(*
T, BO));
624 return Discard(this->emitRem(*
T, BO));
627 return Discard(this->emitDivf(getRoundingMode(BO), BO));
628 return Discard(this->emitDiv(*
T, BO));
632 : this->emitStorePop(*
T, BO);
634 if (!this->emitStoreBitField(*
T, BO))
637 if (!this->emitStore(*
T, BO))
643 return this->emitLoadPop(*
T, BO);
646 return Discard(this->emitBitAnd(*
T, BO));
648 return Discard(this->emitBitOr(*
T, BO));
650 return Discard(this->emitShl(*
LT, *RT, BO));
652 return Discard(this->emitShr(*
LT, *RT, BO));
654 return Discard(this->emitBitXor(*
T, BO));
657 llvm_unreachable(
"Already handled earlier");
662 llvm_unreachable(
"Unhandled binary op");
667template <
class Emitter>
673 if ((Op != BO_Add && Op != BO_Sub) ||
677 std::optional<PrimType>
LT = classify(LHS);
678 std::optional<PrimType> RT = classify(RHS);
688 if (!visit(RHS) || !visit(LHS))
691 return this->emitSubPtr(classifyPrim(E->
getType()), E);
696 if (!visit(RHS) || !visit(LHS))
700 if (!visit(LHS) || !visit(RHS))
708 return this->emitAddOffset(OffsetType, E);
709 else if (Op == BO_Sub)
710 return this->emitSubOffset(OffsetType, E);
715template <
class Emitter>
721 std::optional<PrimType>
T = classify(E->
getType());
725 LabelTy LabelTrue = this->getLabel();
726 LabelTy LabelEnd = this->getLabel();
728 if (!this->visitBool(LHS))
730 if (!this->jumpTrue(LabelTrue))
733 if (!this->visitBool(RHS))
735 if (!this->jump(LabelEnd))
738 this->emitLabel(LabelTrue);
739 this->emitConstBool(
true, E);
740 this->fallthrough(LabelEnd);
741 this->emitLabel(LabelEnd);
744 assert(Op == BO_LAnd);
747 LabelTy LabelFalse = this->getLabel();
748 LabelTy LabelEnd = this->getLabel();
750 if (!this->visitBool(LHS))
752 if (!this->jumpFalse(LabelFalse))
755 if (!this->visitBool(RHS))
757 if (!this->jump(LabelEnd))
760 this->emitLabel(LabelFalse);
761 this->emitConstBool(
false, E);
762 this->fallthrough(LabelEnd);
763 this->emitLabel(LabelEnd);
767 return this->emitPopBool(E);
772 return this->emitCast(
PT_Bool, *
T, E);
776template <
class Emitter>
780 std::optional<unsigned> LocalIndex = allocateLocal(E);
783 if (!this->emitGetPtrLocal(*LocalIndex, E))
793 unsigned ResultOffset = ~0u;
795 ResultOffset = this->allocateLocalPrimitive(E,
PT_Ptr,
true,
false);
798 if (!this->DiscardResult) {
799 if (!this->emitDupPtr(E))
801 if (!this->emitSetLocal(
PT_Ptr, ResultOffset, E))
806 LHSType = AT->getValueType();
809 RHSType = AT->getValueType();
816 LHSOffset = this->allocateLocalPrimitive(LHS,
PT_Ptr,
true,
false);
817 if (!this->visit(LHS))
819 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
822 LHSIsComplex =
false;
823 PrimType LHST = classifyPrim(LHSType);
824 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
825 if (!this->visit(LHS))
827 if (!this->emitSetLocal(LHST, LHSOffset, E))
836 RHSOffset = this->allocateLocalPrimitive(RHS,
PT_Ptr,
true,
false);
837 if (!this->visit(RHS))
839 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
842 RHSIsComplex =
false;
843 PrimType RHST = classifyPrim(RHSType);
844 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
845 if (!this->visit(RHS))
847 if (!this->emitSetLocal(RHST, RHSOffset, E))
854 auto loadComplexValue = [
this](
bool IsComplex,
unsigned ElemIndex,
855 unsigned Offset,
const Expr *E) ->
bool {
857 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
859 return this->emitArrayElemPop(classifyComplexElementType(E->
getType()),
863 return this->emitGetLocal(classifyPrim(E->
getType()), Offset, E);
864 return this->visitZeroInitializer(classifyPrim(E->
getType()), E->
getType(),
870 for (
unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
872 if (!this->DiscardResult) {
873 if (!this->emitGetLocal(
PT_Ptr, ResultOffset, E))
877 if (!loadComplexValue(LHSIsComplex, ElemIndex, LHSOffset, LHS))
880 if (!loadComplexValue(RHSIsComplex, ElemIndex, RHSOffset, RHS))
887 if (!this->emitAddf(getRoundingMode(E), E))
890 if (!this->emitAdd(ResultElemT, E))
896 if (!this->emitSubf(getRoundingMode(E), E))
899 if (!this->emitSub(ResultElemT, E))
908 if (!this->DiscardResult) {
910 if (!this->emitInitElemPop(ResultElemT, ElemIndex, E))
913 if (!this->emitPop(ResultElemT, E))
920template <
class Emitter>
924 if (std::optional<PrimType>
T = classify(QT))
925 return this->visitZeroInitializer(*
T, QT, E);
939 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
940 CXXRD && CXXRD->getNumVBases() > 0) {
945 const Record *R = getRecord(QT);
949 assert(Initializing);
950 return this->visitZeroRecordInitializer(R, E);
959 const auto *CAT = cast<ConstantArrayType>(AT);
960 size_t NumElems = CAT->getZExtSize();
961 PrimType ElemT = classifyPrim(CAT->getElementType());
963 for (
size_t I = 0; I != NumElems; ++I) {
964 if (!this->visitZeroInitializer(ElemT, CAT->getElementType(), E))
966 if (!this->emitInitElem(ElemT, I, E))
974 assert(Initializing);
975 QualType ElemQT = ComplexTy->getElementType();
976 PrimType ElemT = classifyPrim(ElemQT);
977 for (
unsigned I = 0; I < 2; ++I) {
978 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
980 if (!this->emitInitElem(ElemT, I, E))
987 unsigned NumVecElements = VecT->getNumElements();
988 QualType ElemQT = VecT->getElementType();
989 PrimType ElemT = classifyPrim(ElemQT);
991 for (
unsigned I = 0; I < NumVecElements; ++I) {
992 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
994 if (!this->emitInitElem(ElemT, I, E))
1003template <
class Emitter>
1010 return this->discard(
Base) && this->discard(Index);
1014 if (!this->visit(
Base))
1017 if (!this->visit(Index))
1020 PrimType IndexT = classifyPrim(Index->getType());
1021 return this->emitArrayElemPtrPop(IndexT, E);
1024template <
class Emitter>
1026 const Expr *ArrayFiller,
1029 return this->emitInvalid(E);
1032 if (DiscardResult) {
1034 if (!this->discard(
Init))
1041 if (std::optional<PrimType>
T = classify(E->
getType())) {
1042 assert(!DiscardResult);
1043 if (Inits.size() == 0)
1044 return this->visitZeroInitializer(*
T, E->
getType(), E);
1045 assert(Inits.size() == 1);
1046 return this->delegate(Inits[0]);
1053 if (Inits.size() == 1 && E->
getType() == Inits[0]->getType()) {
1054 return this->visitInitializer(Inits[0]);
1057 unsigned InitIndex = 0;
1060 while (InitIndex < R->getNumFields() &&
1064 if (!this->emitDupPtr(E))
1067 if (std::optional<PrimType>
T = classify(
Init)) {
1068 const Record::Field *FieldToInit = R->
getField(InitIndex);
1069 if (!this->visit(
Init))
1072 if (FieldToInit->isBitField()) {
1073 if (!this->emitInitBitField(*
T, FieldToInit, E))
1076 if (!this->emitInitField(*
T, FieldToInit->Offset, E))
1080 if (!this->emitPopPtr(E))
1085 if (
const Record::Base *B = R->
getBase(
Init->getType())) {
1086 if (!this->emitGetPtrBasePop(B->Offset,
Init))
1089 if (!this->visitInitializer(
Init))
1092 if (!this->emitFinishInitPop(E))
1097 const Record::Field *FieldToInit = R->
getField(InitIndex);
1100 if (!this->emitGetPtrField(FieldToInit->Offset,
Init))
1103 if (!this->visitInitializer(
Init))
1106 if (!this->emitPopPtr(E))
1116 unsigned ElementIndex = 0;
1118 if (!this->visitArrayElemInit(ElementIndex,
Init))
1127 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
1130 for (; ElementIndex != NumElems; ++ElementIndex) {
1131 if (!this->visitArrayElemInit(ElementIndex, ArrayFiller))
1140 unsigned NumInits = Inits.size();
1143 return this->delegate(Inits[0]);
1145 QualType ElemQT = ComplexTy->getElementType();
1146 PrimType ElemT = classifyPrim(ElemQT);
1147 if (NumInits == 0) {
1149 for (
unsigned I = 0; I < 2; ++I) {
1150 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1152 if (!this->emitInitElem(ElemT, I, E))
1155 }
else if (NumInits == 2) {
1156 unsigned InitIndex = 0;
1158 if (!this->visit(
Init))
1161 if (!this->emitInitElem(ElemT, InitIndex, E))
1170 unsigned NumVecElements = VecT->getNumElements();
1171 assert(NumVecElements >= Inits.size());
1173 QualType ElemQT = VecT->getElementType();
1174 PrimType ElemT = classifyPrim(ElemQT);
1177 unsigned InitIndex = 0;
1179 if (!this->visit(
Init))
1184 if (
const auto *InitVecT =
Init->getType()->getAs<
VectorType>()) {
1185 if (!this->emitCopyArray(ElemT, 0, InitIndex, InitVecT->getNumElements(), E))
1187 InitIndex += InitVecT->getNumElements();
1189 if (!this->emitInitElem(ElemT, InitIndex, E))
1195 assert(InitIndex <= NumVecElements);
1198 for (; InitIndex != NumVecElements; ++InitIndex) {
1199 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1201 if (!this->emitInitElem(ElemT, InitIndex, E))
1212template <
class Emitter>
1215 if (std::optional<PrimType>
T = classify(
Init->getType())) {
1217 if (!this->visit(
Init))
1219 return this->emitInitElem(*
T, ElemIndex,
Init);
1224 if (!this->emitConstUint32(ElemIndex,
Init))
1226 if (!this->emitArrayElemPtrUint32(
Init))
1228 if (!this->visitInitializer(
Init))
1230 return this->emitFinishInitPop(
Init);
1233template <
class Emitter>
1238template <
class Emitter>
1244template <
class Emitter>
1250template <
class Emitter>
1252 std::optional<PrimType>
T = classify(E->
getType());
1268 bool AlignOfReturnsPreferred =
1269 ASTCtx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
1277 if (
T.getQualifiers().hasUnaligned())
1283 if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
1289template <
class Emitter>
1293 const ASTContext &ASTCtx = Ctx.getASTContext();
1295 if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
1310 if (Kind == UETT_SizeOf)
1319 return this->emitConst(Size.getQuantity(), E);
1322 if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
1339 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
1342 else if (
const auto *ME = dyn_cast<MemberExpr>(Arg))
1352 return this->emitConst(Size.getQuantity(), E);
1355 if (Kind == UETT_VectorElements) {
1357 return this->emitConst(VT->getNumElements(), E);
1364 if (Kind == UETT_VecStep) {
1366 unsigned N = VT->getNumElements();
1373 return this->emitConst(N, E);
1375 return this->emitConst(1, E);
1381template <
class Emitter>
1388 return this->discard(
Base);
1392 const auto maybeLoadValue = [&]() ->
bool {
1395 if (std::optional<PrimType>
T = classify(E))
1396 return this->emitLoadPop(*
T, E);
1400 if (
const auto *VD = dyn_cast<VarDecl>(
Member)) {
1404 if (
auto GlobalIndex =
P.getGlobal(VD))
1405 return this->emitGetPtrGlobal(*GlobalIndex, E) && maybeLoadValue();
1410 if (!this->delegate(
Base))
1413 if (!this->visit(
Base))
1418 if (
const auto *FD = dyn_cast<FieldDecl>(
Member)) {
1420 const Record *R = getRecord(RD);
1423 const Record::Field *F = R->
getField(FD);
1425 if (F->Decl->getType()->isReferenceType())
1426 return this->emitGetFieldPop(
PT_Ptr, F->Offset, E) && maybeLoadValue();
1427 return this->emitGetPtrField(F->Offset, E) && maybeLoadValue();
1433template <
class Emitter>
1440 return this->emitConst(*ArrayIndex, E);
1443template <
class Emitter>
1446 assert(Initializing);
1447 assert(!DiscardResult);
1462 for (
size_t I = 0; I != Size; ++I) {
1466 if (!this->visitArrayElemInit(I, SubExpr))
1472template <
class Emitter>
1479 return this->visitInitializer(SourceExpr);
1482 if (
auto It = OpaqueExprs.find(E); It != OpaqueExprs.end())
1483 return this->emitGetLocal(SubExprT, It->second, E);
1485 if (!this->visit(SourceExpr))
1491 unsigned LocalIndex = allocateLocalPrimitive(E, SubExprT,
true);
1492 if (!this->emitSetLocal(SubExprT, LocalIndex, E))
1497 if (!DiscardResult) {
1498 if (!this->emitGetLocal(SubExprT, LocalIndex, E))
1503 OpaqueExprs.insert({E, LocalIndex});
1508template <
class Emitter>
1515 LabelTy LabelEnd = this->getLabel();
1516 LabelTy LabelFalse = this->getLabel();
1521 if (!this->jumpFalse(LabelFalse))
1524 if (!this->delegate(TrueExpr))
1526 if (!this->jump(LabelEnd))
1529 this->emitLabel(LabelFalse);
1531 if (!this->delegate(FalseExpr))
1534 this->fallthrough(LabelEnd);
1535 this->emitLabel(LabelEnd);
1540template <
class Emitter>
1545 if (!Initializing) {
1546 unsigned StringIndex =
P.createGlobalString(E);
1547 return this->emitGetPtrGlobal(StringIndex, E);
1552 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
1553 assert(CAT &&
"a string literal that's not a constant array?");
1558 unsigned N = std::min(ArraySize, E->
getLength());
1561 for (
unsigned I = 0; I != N; ++I) {
1564 if (CharWidth == 1) {
1565 this->emitConstSint8(CodeUnit, E);
1566 this->emitInitElemSint8(I, E);
1567 }
else if (CharWidth == 2) {
1568 this->emitConstUint16(CodeUnit, E);
1569 this->emitInitElemUint16(I, E);
1570 }
else if (CharWidth == 4) {
1571 this->emitConstUint32(CodeUnit, E);
1572 this->emitInitElemUint32(I, E);
1574 llvm_unreachable(
"unsupported character width");
1579 for (
unsigned I = N; I != ArraySize; ++I) {
1580 if (CharWidth == 1) {
1581 this->emitConstSint8(0, E);
1582 this->emitInitElemSint8(I, E);
1583 }
else if (CharWidth == 2) {
1584 this->emitConstUint16(0, E);
1585 this->emitInitElemUint16(I, E);
1586 }
else if (CharWidth == 4) {
1587 this->emitConstUint32(0, E);
1588 this->emitInitElemUint32(I, E);
1590 llvm_unreachable(
"unsupported character width");
1597template <
class Emitter>
1602 return this->emitConst(E->
getValue(), E);
1605template <
class Emitter>
1614 std::optional<PrimType>
LT = classify(LHSComputationType);
1615 std::optional<PrimType> RT = classify(ResultType);
1622 PrimType LHST = classifyPrim(LHSType);
1630 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT,
true);
1631 if (!this->emitSetLocal(*RT, TempOffset, E))
1637 if (!this->emitLoad(LHST, E))
1641 if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
1642 LHSComputationType, E))
1646 if (!this->emitGetLocal(*RT, TempOffset, E))
1649 llvm::RoundingMode RM = getRoundingMode(E);
1652 if (!this->emitAddf(RM, E))
1656 if (!this->emitSubf(RM, E))
1660 if (!this->emitMulf(RM, E))
1664 if (!this->emitDivf(RM, E))
1671 if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->
getType(), E))
1675 return this->emitStorePop(LHST, E);
1676 return this->emitStore(LHST, E);
1679template <
class Emitter>
1685 std::optional<PrimType>
LT = classify(LHS->
getType());
1686 std::optional<PrimType> RT = classify(RHS->
getType());
1688 if (Op != BO_AddAssign && Op != BO_SubAssign)
1697 if (!this->emitLoad(*
LT, LHS))
1703 if (Op == BO_AddAssign) {
1704 if (!this->emitAddOffset(*RT, E))
1707 if (!this->emitSubOffset(*RT, E))
1712 return this->emitStorePopPtr(E);
1713 return this->emitStorePtr(E);
1716template <
class Emitter>
1722 std::optional<PrimType> LHSComputationT =
1724 std::optional<PrimType>
LT = classify(LHS->
getType());
1725 std::optional<PrimType> RT = classify(RHS->
getType());
1726 std::optional<PrimType> ResultT = classify(E->
getType());
1728 if (!
LT || !RT || !ResultT || !LHSComputationT)
1735 return VisitFloatCompoundAssignOperator(E);
1738 return VisitPointerCompoundAssignOperator(E);
1751 unsigned TempOffset = this->allocateLocalPrimitive(E, *RT,
true);
1753 if (!this->emitSetLocal(*RT, TempOffset, E))
1760 if (!this->emitLoad(*
LT, E))
1762 if (
LT != LHSComputationT) {
1763 if (!this->emitCast(*
LT, *LHSComputationT, E))
1768 if (!this->emitGetLocal(*RT, TempOffset, E))
1774 if (!this->emitAdd(*LHSComputationT, E))
1778 if (!this->emitSub(*LHSComputationT, E))
1782 if (!this->emitMul(*LHSComputationT, E))
1786 if (!this->emitDiv(*LHSComputationT, E))
1790 if (!this->emitRem(*LHSComputationT, E))
1794 if (!this->emitShl(*LHSComputationT, *RT, E))
1798 if (!this->emitShr(*LHSComputationT, *RT, E))
1802 if (!this->emitBitAnd(*LHSComputationT, E))
1806 if (!this->emitBitXor(*LHSComputationT, E))
1810 if (!this->emitBitOr(*LHSComputationT, E))
1814 llvm_unreachable(
"Unimplemented compound assign operator");
1818 if (ResultT != LHSComputationT) {
1819 if (!this->emitCast(*LHSComputationT, *ResultT, E))
1824 if (DiscardResult) {
1826 return this->emitStoreBitFieldPop(*ResultT, E);
1827 return this->emitStorePop(*ResultT, E);
1830 return this->emitStoreBitField(*ResultT, E);
1831 return this->emitStore(*ResultT, E);
1834template <
class Emitter>
1840 assert(E->
getNumObjects() == 0 &&
"TODO: Implement cleanups");
1845template <
class Emitter>
1852 return this->visitInitializer(SubExpr);
1857 return this->discard(SubExpr);
1861 std::optional<PrimType> SubExprT = classify(SubExpr);
1864 std::optional<unsigned> GlobalIndex =
P.createGlobal(E);
1874 if (!this->visit(SubExpr))
1877 if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl, E))
1880 if (!this->emitInitGlobal(*SubExprT, *GlobalIndex, E))
1883 return this->emitGetPtrGlobal(*GlobalIndex, E);
1887 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1889 if (!this->visitInitializer(SubExpr))
1892 return this->emitInitGlobalTempComp(TempDecl, E);
1898 unsigned LocalIndex = allocateLocalPrimitive(
1899 SubExpr, *SubExprT,
true,
true);
1900 if (!this->visit(SubExpr))
1902 if (!this->emitSetLocal(*SubExprT, LocalIndex, E))
1904 return this->emitGetPtrLocal(LocalIndex, E);
1907 if (std::optional<unsigned> LocalIndex =
1909 if (!this->emitGetPtrLocal(*LocalIndex, E))
1911 return this->visitInitializer(SubExpr);
1917template <
class Emitter>
1923template <
class Emitter>
1929 return this->visitInitializer(
Init) && this->emitFinishInit(E);
1932 std::optional<PrimType>
T = classify(E->
getType());
1936 return this->delegate(
Init);
1938 if (std::optional<unsigned> GlobalIndex =
P.createGlobal(E)) {
1939 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1943 if (!this->visit(
Init))
1945 return this->emitInitGlobal(*
T, *GlobalIndex, E);
1948 return this->visitInitializer(
Init) && this->emitFinishInit(E);
1957 return this->delegate(
Init);
1959 unsigned LocalIndex;
1962 LocalIndex = this->allocateLocalPrimitive(
Init, *
T,
false,
false);
1963 else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(
Init))
1964 LocalIndex = *MaybeIndex;
1968 if (!this->emitGetPtrLocal(LocalIndex, E))
1972 if (!this->visit(
Init)) {
1975 return this->emitInit(*
T, E);
1977 if (!this->visitInitializer(
Init) || !this->emitFinishInit(E))
1982 return this->emitPopPtr(E);
1989template <
class Emitter>
1994 return this->emitConstBool(E->
getValue(), E);
1995 return this->emitConst(E->
getValue(), E);
1998template <
class Emitter>
2003 return this->emitConst(E->
getValue(), E);
2006template <
class Emitter>
2011 assert(Initializing);
2017 for (
const Record::Field &F : R->
fields()) {
2024 if (std::optional<PrimType>
T = classify(
Init)) {
2025 if (!this->visit(
Init))
2028 if (!this->emitInitField(*
T, F.Offset, E))
2031 if (!this->emitDupPtr(E))
2034 if (!this->emitGetPtrField(F.Offset, E))
2037 if (!this->visitInitializer(
Init))
2040 if (!this->emitPopPtr(E))
2048template <
class Emitter>
2056template <
class Emitter>
2061 return this->emitInvalid(E);
2064template <
class Emitter>
2070 return this->emitInvalidCast(CastKind::Reinterpret, E);
2073template <
class Emitter>
2079 return this->emitConstBool(E->
getValue(), E);
2082template <
class Emitter>
2086 assert(!classify(
T));
2095 if (!this->visitZeroRecordInitializer(R, E))
2108 assert(
Func->hasThisPointer());
2109 assert(!
Func->hasRVO());
2113 if (DiscardResult) {
2114 assert(!Initializing);
2115 std::optional<unsigned> LocalIndex = allocateLocal(E);
2120 if (!this->emitGetPtrLocal(*LocalIndex, E))
2126 if (!this->emitDupPtr(E))
2130 for (
const auto *Arg : E->
arguments()) {
2131 if (!this->visit(Arg))
2135 if (
Func->isVariadic()) {
2136 uint32_t VarArgSize = 0;
2137 unsigned NumParams =
Func->getNumWrittenParams();
2138 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I) {
2142 if (!this->emitCallVar(
Func, VarArgSize, E))
2145 if (!this->emitCall(
Func, 0, E))
2150 if (DiscardResult) {
2151 if (!this->emitRecordDestruction(getRecord(E->
getType())))
2153 if (!this->emitPopPtr(E))
2161 Ctx.getASTContext().getAsConstantArrayType(E->
getType());
2172 for (
size_t I = 0; I != NumElems; ++I) {
2173 if (!this->emitConstUint64(I, E))
2175 if (!this->emitArrayElemPtrUint64(E))
2179 for (
const auto *Arg : E->
arguments()) {
2180 if (!this->visit(Arg))
2184 if (!this->emitCall(
Func, 0, E))
2193template <
class Emitter>
2203 assert(Val.
isInt());
2205 return this->emitConst(I, E);
2212 if (
const Expr *LValueExpr =
Base.dyn_cast<
const Expr *>())
2213 return this->visit(LValueExpr);
2222 auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
2224 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(UGCD);
2228 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2232 const APValue &
V = UGCD->getValue();
2233 for (
unsigned I = 0, N = R->
getNumFields(); I != N; ++I) {
2234 const Record::Field *F = R->
getField(I);
2235 const APValue &FieldValue =
V.getStructField(I);
2237 PrimType FieldT = classifyPrim(F->Decl->getType());
2239 if (!this->visitAPValue(FieldValue, FieldT, E))
2241 if (!this->emitInitField(FieldT, F->Offset, E))
2249template <
class Emitter>
2255 for (
unsigned I = 0; I != N; ++I) {
2261 if (DiscardResult) {
2262 if (!this->discard(ArrayIndexExpr))
2267 if (!this->visit(ArrayIndexExpr))
2271 if (!this->emitCast(IndexT,
PT_Sint64, E))
2281 return this->emitOffsetOf(
T, E, E);
2284template <
class Emitter>
2292 if (std::optional<PrimType>
T = classify(Ty))
2293 return this->visitZeroInitializer(*
T, Ty, E);
2296 if (!Initializing) {
2297 std::optional<unsigned> LocalIndex = allocateLocal(E);
2300 if (!this->emitGetPtrLocal(*LocalIndex, E))
2305 QualType ElemQT = CT->getElementType();
2306 PrimType ElemT = classifyPrim(ElemQT);
2308 for (
unsigned I = 0; I != 2; ++I) {
2309 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2311 if (!this->emitInitElem(ElemT, I, E))
2319 if (!Initializing) {
2320 std::optional<unsigned> LocalIndex = allocateLocal(E);
2323 if (!this->emitGetPtrLocal(*LocalIndex, E))
2328 QualType ElemQT = VT->getElementType();
2329 PrimType ElemT = classifyPrim(ElemQT);
2331 for (
unsigned I = 0, N = VT->getNumElements(); I != N; ++I) {
2332 if (!this->visitZeroInitializer(ElemT, ElemQT, E))
2334 if (!this->emitInitElem(ElemT, I, E))
2343template <
class Emitter>
2348template <
class Emitter>
2354template <
class Emitter>
2359template <
class Emitter>
2365 return this->emitConst(E->
getValue(), E);
2368template <
class Emitter>
2373 "Trivial CXXInheritedCtorInitExpr, implement. (possible?)");
2374 const Function *F = this->getFunction(Ctor);
2391 if (!this->emitGetParam(PT, Offset, E))
2396 return this->emitCall(F, 0, E);
2399template <
class Emitter>
2402 assert(Ctx.getLangOpts().CPlusPlus);
2403 return this->emitConstBool(E->
getValue(), E);
2406template <
class Emitter>
2410 assert(!Initializing);
2412 std::optional<unsigned> GlobalIndex =
P.getOrCreateGlobal(E->
getGuidDecl());
2415 if (!this->emitGetPtrGlobal(*GlobalIndex, E))
2418 assert(this->getRecord(E->
getType()));
2424 assert(
V.isStruct());
2425 assert(
V.getStructNumBases() == 0);
2426 if (!this->visitAPValueInitializer(
V, E))
2429 return this->emitFinishInit(E);
2432template <
class Emitter>
2440template <
class Emitter>
2449template <
class Emitter>
2455template <
class Emitter>
2460 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
2464 if (OVE->isUnique())
2467 if (!this->discard(OVE))
2470 if (!this->delegate(SemE))
2473 if (!this->discard(SemE))
2480template <
class Emitter>
2486template <
class Emitter>
2488 return this->emitError(E);
2491template <
class Emitter>
2495 unsigned Offset = allocateLocalPrimitive(
2498 return this->emitGetLocal(
PT_Ptr, Offset, E);
2501template <
class Emitter>
2504 assert(Initializing);
2506 QualType ElemType = VT->getElementType();
2507 PrimType ElemT = classifyPrim(ElemType);
2512 unsigned SrcOffset = this->allocateLocalPrimitive(Src,
PT_Ptr,
true,
false);
2513 if (!this->visit(Src))
2515 if (!this->emitSetLocal(
PT_Ptr, SrcOffset, E))
2518 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
2519 if (!this->emitGetLocal(
PT_Ptr, SrcOffset, E))
2521 if (!this->emitArrayElemPop(SrcElemT, I, E))
2523 if (SrcElemT != ElemT) {
2524 if (!this->emitPrimCast(SrcElemT, ElemT, ElemType, E))
2527 if (!this->emitInitElem(ElemT, I, E))
2534template <
class Emitter>
2537 assert(Initializing);
2541 assert(Vecs[0]->getType() == Vecs[1]->getType());
2547 assert(NumOutputElems > 0);
2550 unsigned VectorOffsets[2];
2551 for (
unsigned I = 0; I != 2; ++I) {
2552 VectorOffsets[I] = this->allocateLocalPrimitive(
2553 Vecs[I],
PT_Ptr,
true,
false);
2554 if (!this->visit(Vecs[I]))
2556 if (!this->emitSetLocal(
PT_Ptr, VectorOffsets[I], E))
2559 for (
unsigned I = 0; I != NumOutputElems; ++I) {
2561 if (ShuffleIndex == -1)
2562 return this->emitInvalid(E);
2564 assert(ShuffleIndex < (NumInputElems * 2));
2565 if (!this->emitGetLocal(
PT_Ptr,
2566 VectorOffsets[ShuffleIndex >= NumInputElems], E))
2568 unsigned InputVectorIndex = ShuffleIndex.getZExtValue() % NumInputElems;
2569 if (!this->emitArrayElemPop(ElemT, InputVectorIndex, E))
2572 if (!this->emitInitElem(ElemT, I, E))
2582 return this->Visit(E);
2585template <
class Emitter>
2590 return this->Visit(E);
2595 return this->discard(E);
2600 std::optional<unsigned> LocalIndex = allocateLocal(E);
2604 if (!this->emitGetPtrLocal(*LocalIndex, E))
2606 return this->visitInitializer(E);
2613 return this->Visit(E);
2616template <
class Emitter>
2618 assert(!classify(E->
getType()));
2621 return this->emitError(E);
2625 return this->Visit(E);
2628template <
class Emitter>
2630 std::optional<PrimType>
T = classify(E->
getType());
2634 if (!this->visit(E))
2636 return this->emitComplexBoolCast(E);
2641 if (!this->visit(E))
2649 if (!this->emitNull(*
T,
nullptr, E))
2651 return this->emitNE(*
T, E);
2656 return this->emitCastFloatingIntegralBool(E);
2659 return this->emitCast(*
T,
PT_Bool, E);
2662template <
class Emitter>
2667 return this->emitZeroBool(E);
2669 return this->emitZeroSint8(E);
2671 return this->emitZeroUint8(E);
2673 return this->emitZeroSint16(E);
2675 return this->emitZeroUint16(E);
2677 return this->emitZeroSint32(E);
2679 return this->emitZeroUint32(E);
2681 return this->emitZeroSint64(E);
2683 return this->emitZeroUint64(E);
2685 return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
2687 return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
2689 return this->emitNullPtr(
nullptr, E);
2691 return this->emitNullFnPtr(
nullptr, E);
2693 return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E);
2696 llvm_unreachable(
"unknown primitive type");
2699template <
class Emitter>
2705 for (
const Record::Field &Field : R->
fields()) {
2710 if (!this->visitZeroInitializer(
T, QT, E))
2712 if (!this->emitInitField(
T,
Field.Offset, E))
2718 if (!this->emitDupPtr(E))
2720 if (!this->emitGetPtrField(
Field.Offset, E))
2726 for (uint32_t I = 0, N = D->
getNumElems(); I != N; ++I) {
2727 if (!this->visitZeroInitializer(
T, ET, E))
2729 if (!this->emitInitElem(
T, I, E))
2735 for (uint32_t I = 0, N = D->
getNumElems(); I != N; ++I) {
2736 if (!this->emitConstUint32(I, E))
2738 if (!this->emitArrayElemPtr(
PT_Uint32, E))
2740 if (!this->visitZeroRecordInitializer(ElemRecord, E))
2742 if (!this->emitPopPtr(E))
2746 if (!this->visitZeroRecordInitializer(D->
ElemRecord, E))
2752 if (!this->emitPopPtr(E))
2756 for (
const Record::Base &B : R->
bases()) {
2757 if (!this->emitGetPtrBase(B.Offset, E))
2759 if (!this->visitZeroRecordInitializer(B.R, E))
2761 if (!this->emitFinishInitPop(E))
2770template <
class Emitter>
2771template <
typename T>
2775 return this->emitConstSint8(
Value, E);
2777 return this->emitConstUint8(
Value, E);
2779 return this->emitConstSint16(
Value, E);
2781 return this->emitConstUint16(
Value, E);
2783 return this->emitConstSint32(
Value, E);
2785 return this->emitConstUint32(
Value, E);
2787 return this->emitConstSint64(
Value, E);
2789 return this->emitConstUint64(
Value, E);
2791 return this->emitConstBool(
Value, E);
2797 llvm_unreachable(
"Invalid integral type");
2800 llvm_unreachable(
"unknown primitive type");
2803template <
class Emitter>
2804template <
typename T>
2806 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
2809template <
class Emitter>
2813 return this->emitConstIntAPS(
Value, E);
2815 return this->emitConstIntAP(
Value, E);
2817 if (
Value.isSigned())
2818 return this->emitConst(
Value.getSExtValue(), Ty, E);
2819 return this->emitConst(
Value.getZExtValue(), Ty, E);
2822template <
class Emitter>
2824 return this->emitConst(
Value, classifyPrim(E->
getType()), E);
2827template <
class Emitter>
2833 if (
const auto *VD =
2834 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
2835 assert(!
P.getGlobal(VD));
2836 assert(!Locals.contains(VD));
2844 Src.is<
const Expr *>());
2846 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>()))
2847 Locals.insert({VD, Local});
2848 VarScope->add(Local, IsExtended);
2849 return Local.Offset;
2852template <
class Emitter>
2853std::optional<unsigned>
2857 if ([[maybe_unused]]
const auto *VD =
2858 dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
2859 assert(!
P.getGlobal(VD));
2860 assert(!Locals.contains(VD));
2866 bool IsTemporary =
false;
2867 if (
auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
2871 if (
const auto *VarD = dyn_cast<VarDecl>(VD))
2872 Init = VarD->getInit();
2874 if (
auto *E = Src.dyn_cast<
const Expr *>()) {
2881 IsTemporary,
false,
Init);
2883 return std::nullopt;
2887 Locals.insert({Key, Local});
2889 VarScope->addExtended(Local, ExtendingDecl);
2891 VarScope->add(Local,
false);
2892 return Local.Offset;
2895template <
class Emitter>
2897 if (
const PointerType *PT = dyn_cast<PointerType>(Ty))
2902template <
class Emitter>
2904 if (
const auto *RecordTy = getRecordTy(Ty))
2905 return getRecord(RecordTy->getDecl());
2909template <
class Emitter>
2911 return P.getOrCreateRecord(RD);
2914template <
class Emitter>
2916 return Ctx.getOrCreateFunction(FD);
2919template <
class Emitter>
2930 if (std::optional<PrimType>
T = classify(E)) {
2939 if (std::optional<unsigned> LocalOffset = this->allocateLocal(E)) {
2940 if (!this->emitGetPtrLocal(*LocalOffset, E))
2943 if (!visitInitializer(E))
2946 if (!this->emitFinishInit(E))
2961template <
class Emitter>
2963 assert(!VD->
isInvalidDecl() &&
"Trying to constant evaluate an invalid decl");
2967 if (std::optional<unsigned> Index =
P.getGlobal(VD);
2968 Index && !
P.getPtrGlobal(*Index).isInitialized())
2972 if (!this->visitVarDecl(VD))
2975 std::optional<PrimType> VarT = classify(VD->
getType());
2978 auto GlobalIndex =
P.getGlobal(VD);
2979 assert(GlobalIndex);
2981 if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
2984 if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
2988 auto Local = Locals.find(VD);
2989 assert(Local != Locals.end());
2991 if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
2994 if (!this->emitGetPtrLocal(Local->second.Offset, VD))
3001 return this->emitRet(*VarT, VD);
3004 return this->emitRet(
PT_Ptr, VD);
3007template <
class Emitter>
3014 std::optional<PrimType> VarT = classify(VD->
getType());
3017 auto initGlobal = [&](
unsigned GlobalIndex) ->
bool {
3022 if (!this->visit(
Init))
3024 return this->emitInitGlobal(*VarT, GlobalIndex, VD);
3026 return this->visitGlobalInitializer(
Init, GlobalIndex);
3030 if (std::optional<unsigned> GlobalIndex =
P.getGlobal(VD)) {
3031 if (
P.getPtrGlobal(*GlobalIndex).isInitialized())
3036 return Init && initGlobal(*GlobalIndex);
3039 std::optional<unsigned> GlobalIndex =
P.createGlobal(VD,
Init);
3044 return !
Init || initGlobal(*GlobalIndex);
3048 unsigned Offset = this->allocateLocalPrimitive(
3053 if (!this->visit(
Init))
3056 return this->emitSetLocal(*VarT, Offset, VD);
3059 if (std::optional<unsigned> Offset = this->allocateLocal(VD))
3060 return !
Init || this->visitLocalInitializer(
Init, *Offset);
3070template <
class Emitter>
3073 assert(!DiscardResult);
3075 return this->emitConst(Val.
getInt(), ValType, E);
3079 if (
const Expr *BaseExpr =
Base.dyn_cast<
const Expr *>())
3080 return this->visit(BaseExpr);
3086template <
class Emitter>
3095 const Record::Field *RF = R->
getField(I);
3098 PrimType T = classifyPrim(RF->Decl->getType());
3099 if (!this->visitAPValue(F,
T, E))
3101 if (!this->emitInitField(
T, RF->Offset, E))
3104 assert(RF->Desc->isPrimitiveArray());
3105 const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
3106 PrimType ElemT = classifyPrim(ArrType->getElementType());
3109 if (!this->emitDupPtr(E))
3111 if (!this->emitGetPtrField(RF->Offset, E))
3114 for (
unsigned A = 0, AN = F.
getArraySize(); A != AN; ++A) {
3117 if (!this->emitInitElem(ElemT, A, E))
3121 if (!this->emitPopPtr(E))
3124 assert(
false &&
"I don't think this should be possible");
3134template <
class Emitter>
3141 std::optional<PrimType> ReturnT = classify(E);
3144 if (!Initializing && !ReturnT && !ReturnType->
isVoidType()) {
3145 std::optional<unsigned> LocalIndex = allocateLocal(E);
3148 if (!this->emitGetPtrLocal(*LocalIndex, E))
3152 if (!
Func->isUnevaluatedBuiltin()) {
3154 for (
const auto *Arg : E->
arguments()) {
3155 if (!this->visit(Arg))
3160 if (!this->emitCallBI(
Func, E, E))
3163 if (DiscardResult && !ReturnType->
isVoidType()) {
3165 return this->emitPop(*ReturnT, E);
3171template <
class Emitter>
3174 return VisitBuiltinCallExpr(E);
3177 std::optional<PrimType>
T = classify(ReturnType);
3182 if (DiscardResult) {
3186 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
3187 if (!this->emitGetPtrLocal(*LocalIndex, E))
3193 if (!Initializing) {
3194 if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
3195 if (!this->emitGetPtrLocal(*LocalIndex, E))
3199 if (!this->emitDupPtr(E))
3208 if (isa<CXXOperatorCallExpr>(E)) {
3209 if (
const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl);
3210 MD && MD->isStatic()) {
3211 if (!this->discard(E->
getArg(0)))
3213 Args = Args.drop_front();
3218 if (
const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
3219 if (!this->visit(MC->getImplicitObjectArgument()))
3225 unsigned ArgIndex = 0;
3226 for (
const auto *Arg : Args) {
3227 if (!this->visit(Arg))
3231 if (FuncDecl && NonNullArgs[ArgIndex]) {
3234 if (!this->emitCheckNonNullArg(ArgT, Arg))
3245 assert(HasRVO ==
Func->hasRVO());
3247 bool HasQualifier =
false;
3248 if (
const auto *ME = dyn_cast<MemberExpr>(E->
getCallee()))
3249 HasQualifier = ME->hasQualifier();
3251 bool IsVirtual =
false;
3252 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
3253 IsVirtual = MD->isVirtual();
3258 if (IsVirtual && !HasQualifier) {
3259 uint32_t VarArgSize = 0;
3260 unsigned NumParams =
Func->getNumWrittenParams();
3261 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
3264 if (!this->emitCallVirt(
Func, VarArgSize, E))
3266 }
else if (
Func->isVariadic()) {
3267 uint32_t VarArgSize = 0;
3268 unsigned NumParams =
3269 Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(E);
3270 for (
unsigned I = NumParams, N = E->
getNumArgs(); I != N; ++I)
3272 if (!this->emitCallVar(
Func, VarArgSize, E))
3275 if (!this->emitCall(
Func, 0, E))
3284 uint32_t ArgSize = 0;
3285 for (
unsigned I = 0, N = E->
getNumArgs(); I != N; ++I)
3291 if (!this->emitCallPtr(ArgSize, E, E))
3296 if (DiscardResult && !ReturnType->
isVoidType() &&
T)
3297 return this->emitPop(*
T, E);
3302template <
class Emitter>
3306 return this->delegate(E->
getExpr());
3309template <
class Emitter>
3315 if (std::optional<PrimType>
T = classify(E->
getExpr()))
3316 return this->visit(SubExpr);
3318 assert(Initializing);
3319 return this->visitInitializer(SubExpr);
3322template <
class Emitter>
3328 return this->emitConstBool(E->
getValue(), E);
3331template <
class Emitter>
3337 return this->emitNullPtr(
nullptr, E);
3340template <
class Emitter>
3348 return this->emitZero(
T, E);
3351template <
class Emitter>
3356 if (this->LambdaThisCapture.Offset > 0) {
3357 if (this->LambdaThisCapture.IsPtr)
3358 return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
3359 return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
3362 return this->emitThis(E);
3365template <
class Emitter>
3369 return this->VisitComplexUnaryOperator(E);
3370 std::optional<PrimType>
T = classify(SubExpr->
getType());
3374 if (!this->visit(SubExpr))
3378 if (!this->emitIncPtr(E))
3381 return DiscardResult ? this->emitPopPtr(E) :
true;
3385 return DiscardResult ? this->emitIncfPop(getRoundingMode(E), E)
3386 : this->emitIncf(getRoundingMode(E), E);
3389 return DiscardResult ? this->emitIncPop(*
T, E) : this->emitInc(*
T, E);
3392 if (!this->visit(SubExpr))
3396 if (!this->emitDecPtr(E))
3399 return DiscardResult ? this->emitPopPtr(E) :
true;
3403 return DiscardResult ? this->emitDecfPop(getRoundingMode(E), E)
3404 : this->emitDecf(getRoundingMode(E), E);
3407 return DiscardResult ? this->emitDecPop(*
T, E) : this->emitDec(*
T, E);
3410 if (!this->visit(SubExpr))
3414 if (!this->emitLoadPtr(E))
3416 if (!this->emitConstUint8(1, E))
3418 if (!this->emitAddOffsetUint8(E))
3420 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
3424 if (DiscardResult) {
3426 return this->emitIncfPop(getRoundingMode(E), E);
3427 return this->emitIncPop(*
T, E);
3431 const auto &TargetSemantics = Ctx.getFloatSemantics(E->
getType());
3432 if (!this->emitLoadFloat(E))
3434 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
3436 if (!this->emitAddf(getRoundingMode(E), E))
3438 if (!this->emitStoreFloat(E))
3442 if (!this->emitLoad(*
T, E))
3444 if (!this->emitConst(1, E))
3446 if (!this->emitAdd(*
T, E))
3448 if (!this->emitStore(*
T, E))
3451 return E->
isGLValue() || this->emitLoadPop(*
T, E);
3454 if (!this->visit(SubExpr))
3458 if (!this->emitLoadPtr(E))
3460 if (!this->emitConstUint8(1, E))
3462 if (!this->emitSubOffsetUint8(E))
3464 return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
3468 if (DiscardResult) {
3470 return this->emitDecfPop(getRoundingMode(E), E);
3471 return this->emitDecPop(*
T, E);
3475 const auto &TargetSemantics = Ctx.getFloatSemantics(E->
getType());
3476 if (!this->emitLoadFloat(E))
3478 if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
3480 if (!this->emitSubf(getRoundingMode(E), E))
3482 if (!this->emitStoreFloat(E))
3486 if (!this->emitLoad(*
T, E))
3488 if (!this->emitConst(1, E))
3490 if (!this->emitSub(*
T, E))
3492 if (!this->emitStore(*
T, E))
3495 return E->
isGLValue() || this->emitLoadPop(*
T, E);
3499 return this->discard(SubExpr);
3501 if (!this->visitBool(SubExpr))
3504 if (!this->emitInvBool(E))
3508 return this->emitCast(
PT_Bool, ET, E);
3511 if (!this->visit(SubExpr))
3513 return DiscardResult ? this->emitPop(*
T, E) : this->emitNeg(*
T, E);
3515 if (!this->visit(SubExpr))
3517 return DiscardResult ? this->emitPop(*
T, E) :
true;
3520 return this->delegate(SubExpr);
3523 return this->discard(SubExpr);
3524 return this->visit(SubExpr);
3526 if (!this->visit(SubExpr))
3528 return DiscardResult ? this->emitPop(*
T, E) : this->emitComp(*
T, E);
3531 return this->delegate(SubExpr);
3534 if (!this->discard(SubExpr))
3536 return this->visitZeroInitializer(*
T, SubExpr->
getType(), SubExpr);
3539 return this->delegate(SubExpr);
3541 assert(
false &&
"Unhandled opcode");
3547template <
class Emitter>
3554 return this->discard(SubExpr);
3556 std::optional<PrimType> ResT = classify(E);
3557 auto prepareResult = [=]() ->
bool {
3558 if (!ResT && !Initializing) {
3559 std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
3562 return this->emitGetPtrLocal(*LocalIndex, E);
3569 unsigned SubExprOffset = ~0u;
3570 auto createTemp = [=, &SubExprOffset]() ->
bool {
3571 SubExprOffset = this->allocateLocalPrimitive(SubExpr,
PT_Ptr,
true,
false);
3572 if (!this->visit(SubExpr))
3574 return this->emitSetLocal(
PT_Ptr, SubExprOffset, E);
3578 auto getElem = [=](
unsigned Offset,
unsigned Index) ->
bool {
3579 if (!this->emitGetLocal(
PT_Ptr, Offset, E))
3581 return this->emitArrayElemPop(ElemT, Index, E);
3586 if (!prepareResult())
3590 for (
unsigned I = 0; I != 2; ++I) {
3591 if (!getElem(SubExprOffset, I))
3593 if (!this->emitNeg(ElemT, E))
3595 if (!this->emitInitElem(ElemT, I, E))
3603 return this->delegate(SubExpr);
3606 if (!this->visit(SubExpr))
3608 if (!this->emitComplexBoolCast(SubExpr))
3610 if (!this->emitInvBool(E))
3613 return this->emitCast(
PT_Bool, ET, E);
3617 return this->emitComplexReal(SubExpr);
3620 if (!this->visit(SubExpr))
3624 if (!this->emitConstUint8(1, E))
3626 return this->emitArrayElemPtrPopUint8(E);
3631 return this->emitArrayElemPop(classifyPrim(E->
getType()), 1, E);
3634 return this->emitInvalid(E);
3640template <
class Emitter>
3647 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
3648 return this->emitConst(ECD->getInitVal(), E);
3649 }
else if (
const auto *BD = dyn_cast<BindingDecl>(D)) {
3650 return this->visit(BD->getBinding());
3651 }
else if (
const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
3652 const Function *F = getFunction(FuncDecl);
3653 return F && this->emitGetFnPtr(F, E);
3654 }
else if (
const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(D)) {
3655 if (std::optional<unsigned> Index =
P.getOrCreateGlobal(D)) {
3656 if (!this->emitGetPtrGlobal(*Index, E))
3658 if (std::optional<PrimType>
T = classify(E->
getType())) {
3659 if (!this->visitAPValue(TPOD->getValue(), *
T, E))
3661 return this->emitInitGlobal(*
T, *Index, E);
3663 return this->visitAPValueInitializer(TPOD->getValue(), E);
3675 if (
auto It = Locals.find(D); It != Locals.end()) {
3676 const unsigned Offset = It->second.Offset;
3678 return this->emitGetLocal(
PT_Ptr, Offset, E);
3679 return this->emitGetPtrLocal(Offset, E);
3680 }
else if (
auto GlobalIndex =
P.getGlobal(D)) {
3682 return this->emitGetGlobalPtr(*GlobalIndex, E);
3684 return this->emitGetPtrGlobal(*GlobalIndex, E);
3685 }
else if (
const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
3686 if (
auto It = this->Params.find(PVD); It != this->Params.end()) {
3687 if (IsReference || !It->second.IsPtr)
3688 return this->emitGetParamPtr(It->second.Offset, E);
3690 return this->emitGetPtrParam(It->second.Offset, E);
3695 if (
auto It = this->LambdaCaptures.find(D);
3696 It != this->LambdaCaptures.end()) {
3697 auto [Offset, IsPtr] = It->second;
3700 return this->emitGetThisFieldPtr(Offset, E);
3701 return this->emitGetPtrThisField(Offset, E);
3706 if (Ctx.getLangOpts().CPlusPlus) {
3707 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
3709 if ((VD->isLocalVarDecl() || VD->isStaticDataMember()) &&
3710 VD->getType().isConstQualified()) {
3711 if (!this->visitVarDecl(VD))
3714 return this->VisitDeclRefExpr(E);
3718 if (
const auto *VD = dyn_cast<VarDecl>(D);
3719 VD && VD->getAnyInitializer() && VD->getType().isConstQualified()) {
3720 if (!this->visitVarDecl(VD))
3723 return this->VisitDeclRefExpr(E);
3727 if (std::optional<unsigned> I =
P.getOrCreateDummy(D))
3728 return this->emitGetPtrGlobal(*I, E);
3730 return this->emitInvalidDeclRef(E, E);
3733template <
class Emitter>
3736 C->emitDestruction();
3739template <
class Emitter>
3744 if (
const auto *PT = dyn_cast<PointerType>(Ty))
3745 return PT->getPointeeType()->getAsCXXRecordDecl();
3746 return Ty->getAsCXXRecordDecl();
3748 const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
3749 const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);
3751 return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
3755template <
class Emitter>
3762 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
3763 return this->emitCastFP(ToSem, getRoundingMode(E), E);
3767 return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(ToQT), E);
3769 return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(ToQT), E);
3773 return this->emitCastFloatingIntegral(ToT, E);
3778 return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
3780 return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
3784 return FromT != ToT ? this->emitCast(FromT, ToT, E) :
true;
3788 const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
3789 return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(E),
3798template <
class Emitter>
3803 return this->discard(SubExpr);
3805 if (!this->visit(SubExpr))
3808 if (!this->emitConstUint8(0, SubExpr))
3810 return this->emitArrayElemPtrPopUint8(SubExpr);
3814 return this->emitArrayElemPop(classifyComplexElementType(SubExpr->
getType()),
3818template <
class Emitter>
3820 assert(!DiscardResult);
3824 if (!this->emitArrayElem(ElemT, 0, E))
3827 if (!this->emitCastFloatingIntegral(
PT_Bool, E))
3830 if (!this->emitCast(ElemT,
PT_Bool, E))
3835 LabelTy LabelTrue = this->getLabel();
3836 if (!this->jumpTrue(LabelTrue))
3839 if (!this->emitArrayElemPop(ElemT, 1, E))
3842 if (!this->emitCastFloatingIntegral(
PT_Bool, E))
3845 if (!this->emitCast(ElemT,
PT_Bool, E))
3849 LabelTy EndLabel = this->getLabel();
3850 this->jump(EndLabel);
3852 this->emitLabel(LabelTrue);
3853 if (!this->emitPopPtr(E))
3855 if (!this->emitConstBool(
true, E))
3858 this->fallthrough(EndLabel);
3859 this->emitLabel(EndLabel);
3864template <
class Emitter>
3869 assert(!Initializing);
3870 assert(!DiscardResult);
3876 LHSIsComplex =
true;
3877 ElemT = classifyComplexElementType(LHS->
getType());
3878 LHSOffset = allocateLocalPrimitive(LHS,
PT_Ptr,
true,
3880 if (!this->visit(LHS))
3882 if (!this->emitSetLocal(
PT_Ptr, LHSOffset, E))
3885 LHSIsComplex =
false;
3887 LHSOffset = this->allocateLocalPrimitive(LHS, LHST,
true,
false);
3888 if (!this->visit(LHS))
3890 if (!this->emitSetLocal(LHST, LHSOffset, E))
3897 RHSIsComplex =
true;
3898 ElemT = classifyComplexElementType(RHS->
getType());
3899 RHSOffset = allocateLocalPrimitive(RHS,
PT_Ptr,
true,
3901 if (!this->visit(RHS))
3903 if (!this->emitSetLocal(
PT_Ptr, RHSOffset, E))
3906 RHSIsComplex =
false;
3908 RHSOffset = this->allocateLocalPrimitive(RHS, RHST,
true,
false);
3909 if (!this->visit(RHS))
3911 if (!this->emitSetLocal(RHST, RHSOffset, E))
3915 auto getElem = [&](
unsigned LocalOffset,
unsigned Index,
3916 bool IsComplex) ->
bool {
3918 if (!this->emitGetLocal(
PT_Ptr, LocalOffset, E))
3920 return this->emitArrayElemPop(ElemT, Index, E);
3922 return this->emitGetLocal(ElemT, LocalOffset, E);
3925 for (
unsigned I = 0; I != 2; ++I) {
3927 if (!getElem(LHSOffset, I, LHSIsComplex))
3929 if (!getElem(RHSOffset, I, RHSIsComplex))
3932 if (!this->emitEQ(ElemT, E))
3935 if (!this->emitCastBoolUint8(E))
3940 if (!this->emitAddUint8(E))
3942 if (!this->emitConstUint8(2, E))
3946 if (!this->emitEQUint8(E))
3949 if (!this->emitNEUint8(E))
3956 return this->emitCast(
PT_Bool, ResT, E);
3963template <
class Emitter>
3967 for (
const Record::Field &Field : llvm::reverse(R->
fields())) {
3974 if (!this->emitDestruction(D))
3987 const Function *DtorFunc = getFunction(Dtor);
3994 if (!this->emitCall(DtorFunc, 0,
SourceInfo{}))
3998 for (
const Record::Base &
Base : llvm::reverse(R->
bases())) {
4001 if (!this->emitRecordDestruction(
Base.R))
4013template <
class Emitter>
4037 for (ssize_t I = Desc->
getNumElems() - 1; I >= 0; --I) {
4040 if (!this->emitArrayElemPtrUint64(
SourceInfo{}))
4042 if (!this->emitDestruction(ElemDesc))
4051 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
APValue & getStructField(unsigned i)
unsigned getStructNumFields() 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...
AddrLabelExpr - The GNU address of label extension, representing &&label.
LabelDecl * getLabel() const
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 a base class of a C++ class.
Represents binding an expression to a temporary.
const Expr * getSubExpr() const
A boolean literal, per ([C++ lex.bool] Boolean literals).
Represents a call to a C++ constructor.
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()
Represents a C++ struct/union/class.
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
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
CharUnits - This is an opaque type for sizes expressed in character units.
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
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
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.
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.
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
LifetimeExtendedTemporaryDecl * getLifetimeExtendedTemporaryDecl()
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
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...
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Base for LValueReferenceType and RValueReferenceType.
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
bool isSatisfied() const
Whether or not the requires clause is satisfied.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
Represents an expression that computes the length of a parameter pack.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
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 isVoidPointerType() 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).
const T * castAs() const
Member-template castAs<specific type>.
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.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
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.
unsigned getNumElements() const
QualType getElementType() const
Scope for storage declared in a compound statement.
Compilation context for expressions.
bool visitExpr(const Expr *E) override
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
std::optional< unsigned > allocateLocal(DeclTy &&Decl, const ValueDecl *ExtendingDecl=nullptr)
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 VisitConvertVectorExpr(const ConvertVectorExpr *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 VisitShuffleVectorExpr(const ShuffleVectorExpr *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 visitAPValueInitializer(const APValue &Val, const Expr *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 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 visitInitList(ArrayRef< const Expr * > Inits, const Expr *ArrayFiller, const Expr *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)
bool VisitRecoveryExpr(const RecoveryExpr *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.
DeclScope(ByteCodeExprGen< Emitter > *Ctx, const ValueDecl *VD)
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.
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.
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.