30#include "llvm/ADT/SmallString.h"
31#include "llvm/Support/ErrorHandling.h"
32#include "llvm/Support/raw_ostream.h"
42 llvm::DenseMap<const CXXRecordDecl *, cir::GlobalOp> vtables;
45 CIRGenItaniumCXXABI(CIRGenModule &cgm) : CIRGenCXXABI(cgm) {
50 AddedStructorArgs getImplicitConstructorArgs(CIRGenFunction &cgf,
51 const CXXConstructorDecl *d,
54 bool delegating)
override;
56 bool needsVTTParameter(clang::GlobalDecl gd)
override;
58 AddedStructorArgCounts
59 buildStructorSignature(GlobalDecl gd,
60 llvm::SmallVectorImpl<CanQualType> &argTys)
override;
62 void emitInstanceFunctionProlog(SourceLocation loc,
63 CIRGenFunction &cgf)
override;
65 void addImplicitStructorParams(CIRGenFunction &cgf, QualType &resTy,
66 FunctionArgList ¶ms)
override;
68 const CXXDestructorDecl *dd,
71 bool delegating)
override;
72 void emitCXXConstructors(
const clang::CXXConstructorDecl *d)
override;
73 void emitCXXDestructors(
const clang::CXXDestructorDecl *d)
override;
74 void emitCXXStructor(clang::GlobalDecl gd)
override;
76 void emitDestructorCall(CIRGenFunction &cgf,
const CXXDestructorDecl *dd,
78 bool delegating, Address thisAddr,
79 QualType thisTy)
override;
80 void registerGlobalDtor(
const VarDecl *vd, cir::FuncOp dtor,
81 mlir::Value addr)
override;
82 void emitVirtualObjectDelete(CIRGenFunction &cgf,
const CXXDeleteExpr *de,
83 Address ptr, QualType elementType,
84 const CXXDestructorDecl *dtor)
override;
86 void emitRethrow(CIRGenFunction &cgf,
bool isNoReturn)
override;
87 void emitThrow(CIRGenFunction &cgf,
const CXXThrowExpr *e)
override;
89 bool useThunkForDtorVariant(
const CXXDestructorDecl *dtor,
97 bool isVirtualOffsetNeededForVTableField(CIRGenFunction &cgf,
98 CIRGenFunction::VPtr vptr)
override;
100 cir::GlobalOp getAddrOfVTable(
const CXXRecordDecl *rd,
101 CharUnits vptrOffset)
override;
102 CIRGenCallee getVirtualFunctionPointer(CIRGenFunction &cgf,
103 clang::GlobalDecl gd, Address thisAddr,
105 SourceLocation loc)
override;
106 mlir::Value emitVirtualDestructorCall(CIRGenFunction &cgf,
107 const CXXDestructorDecl *dtor,
109 DeleteOrMemberCallExpr e)
override;
111 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
112 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
114 mlir::Value getVTableAddressPoint(BaseSubobject base,
115 const CXXRecordDecl *vtableClass)
override;
117 getVTableAddressPointAttr(BaseSubobject base,
118 const CXXRecordDecl *vtableClass)
override;
119 mlir::Value getVTableAddressPointInStructorWithVTT(
120 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
121 const CXXRecordDecl *nearestVBase);
123 mlir::Value getVTableAddressPointInStructor(
124 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
125 clang::BaseSubobject base,
126 const clang::CXXRecordDecl *nearestVBase)
override;
127 void emitVTableDefinitions(CIRGenVTables &cgvt,
128 const CXXRecordDecl *rd)
override;
129 void emitVirtualInheritanceTables(
const CXXRecordDecl *rd)
override;
131 void setThunkLinkage(cir::FuncOp thunk,
bool forVTable, GlobalDecl gd,
132 bool returnAdjustment)
override {
133 if (forVTable && !thunk.hasLocalLinkage())
134 thunk.setLinkage(cir::GlobalLinkageKind::AvailableExternallyLinkage);
139 bool exportThunk()
override {
return true; }
141 mlir::Value performThisAdjustment(CIRGenFunction &cgf, Address thisAddr,
142 const CXXRecordDecl *unadjustedClass,
143 const ThunkInfo &ti)
override;
146 const CXXRecordDecl *unadjustedClass,
147 const ReturnAdjustment &ra)
override;
149 bool shouldTypeidBeNullChecked(QualType srcTy)
override;
150 mlir::Value emitTypeid(CIRGenFunction &cgf, QualType SrcRecordTy,
151 Address thisPtr, mlir::Type StdTypeInfoPtrTy)
override;
152 void emitBadTypeidCall(CIRGenFunction &cgf, mlir::Location loc)
override;
154 mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc,
155 QualType ty)
override;
157 StringRef getPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
158 StringRef getDeletedVirtualCallName()
override {
159 return "__cxa_deleted_virtual";
163 getAddrOfCXXCatchHandlerType(mlir::Location loc, QualType ty,
164 QualType catchHandlerType)
override {
165 auto rtti = dyn_cast<cir::GlobalViewAttr>(getAddrOfRTTIDescriptor(loc, ty));
166 assert(rtti &&
"expected GlobalViewAttr");
167 return CatchTypeInfo{rtti, 0};
170 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *vtableClass)
override {
174 size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *,
175 FunctionArgList &args)
const override {
176 assert(!args.empty() &&
"expected the arglist to not be empty!");
177 return args.size() - 1;
180 void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc)
override;
183 getVirtualBaseClassOffset(mlir::Location loc, CIRGenFunction &cgf,
184 Address thisAddr,
const CXXRecordDecl *classDecl,
185 const CXXRecordDecl *baseClassDecl)
override;
192 mlir::Value emitDynamicCast(CIRGenFunction &cgf, mlir::Location loc,
193 QualType srcRecordTy, QualType destRecordTy,
194 cir::PointerType destCIRTy,
bool isRefCast,
195 Address src)
override;
197 cir::MethodAttr buildVirtualMethodAttr(cir::MethodType methodTy,
198 const CXXMethodDecl *md)
override;
200 Address initializeArrayCookie(CIRGenFunction &cgf, Address newPtr,
201 mlir::Value numElements,
const CXXNewExpr *e,
202 QualType elementType)
override;
204 bool isZeroInitializable(
const MemberPointerType *MPT)
override;
207 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
212 virtual bool shouldRTTIBeUnique()
const {
return true; }
216 enum RTTIUniquenessKind {
234 classifyRTTIUniqueness(QualType canTy, cir::GlobalLinkageKind linkage)
const;
237 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *rd)
const;
238 bool isVTableHidden(
const CXXRecordDecl *rd)
const;
243void CIRGenItaniumCXXABI::emitInstanceFunctionProlog(
SourceLocation loc,
248 "emitInstanceFunctionProlog: Naked");
253 setCXXABIThisValue(cgf, loadIncomingCXXThis(cgf));
256 if (getStructorImplicitParamDecl(cgf)) {
260 setStructorImplicitParamValue(cgf, val);
271 if (hasThisReturn(cgf.
curGD)) {
273 "emitInstanceFunctionProlog: hasThisReturn");
277CIRGenCXXABI::AddedStructorArgCounts
278CIRGenItaniumCXXABI::buildStructorSignature(
279 GlobalDecl gd, llvm::SmallVectorImpl<CanQualType> &argTys) {
290 argTys.insert(argTys.begin() + 1,
293 return AddedStructorArgCounts::withPrefix(1);
296 return AddedStructorArgCounts{};
301enum class StructorCIRGen { Emit, RAUW, Alias, COMDAT };
307 return StructorCIRGen::Emit;
312 return StructorCIRGen::Emit;
315 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(md)) {
325 return StructorCIRGen::RAUW;
329 return StructorCIRGen::RAUW;
335 return StructorCIRGen::COMDAT;
336 return StructorCIRGen::Emit;
339 return StructorCIRGen::Alias;
349 auto globalValue = dyn_cast_or_null<cir::CIRGlobalValueInterface>(
351 if (globalValue && !globalValue.isDeclaration())
354 auto entry = cast_or_null<cir::FuncOp>(cgm.
getGlobalValue(mangledName));
363void CIRGenItaniumCXXABI::emitCXXStructor(GlobalDecl gd) {
366 const auto *cd = dyn_cast<CXXConstructorDecl>(md);
371 GlobalDecl baseDecl =
375 if (cirGenType == StructorCIRGen::Alias ||
376 cirGenType == StructorCIRGen::COMDAT) {
381 if (cirGenType == StructorCIRGen::RAUW) {
391 if (cirGenType == StructorCIRGen::COMDAT) {
392 llvm::SmallString<256> comdatKey;
393 llvm::raw_svector_ostream
out(comdatKey);
394 ItaniumMangleContext &mangler =
400 fn.setComdat(llvm::StringRef(comdatKey));
406void CIRGenItaniumCXXABI::addImplicitStructorParams(CIRGenFunction &cgf,
408 FunctionArgList ¶ms) {
413 if (needsVTTParameter(cgf.
curGD)) {
420 astContext,
nullptr, md->getLocation(),
421 &astContext.
Idents.
get(
"vtt"), t, ImplicitParamKind::CXXVTT);
422 params.insert(params.begin() + 1, vttDecl);
423 getStructorImplicitParamDecl(cgf) = vttDecl;
427void CIRGenItaniumCXXABI::emitCXXConstructors(
const CXXConstructorDecl *d) {
443void CIRGenItaniumCXXABI::emitCXXDestructors(
const CXXDestructorDecl *d) {
459CIRGenCXXABI::AddedStructorArgs CIRGenItaniumCXXABI::getImplicitConstructorArgs(
461 bool forVirtualBase,
bool delegating) {
462 if (!needsVTTParameter(GlobalDecl(d,
type)))
463 return AddedStructorArgs{};
473 return AddedStructorArgs::withPrefix({{vtt, vttTy}});
479bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
483 if (!md->getParent()->getNumVBases())
497void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt,
498 const CXXRecordDecl *rd) {
499 cir::GlobalOp vtable = getAddrOfVTable(rd, CharUnits());
500 if (vtable.hasInitializer())
506 mlir::Attribute rtti =
517 vtable.setLinkage(linkage);
520 vtable.setSelfComdat();
535 "emitVTableDefinitions: __fundamental_type_info");
538 [[maybe_unused]]
auto vtableAsGlobalValue =
539 dyn_cast<cir::CIRGlobalValueInterface>(*vtable);
540 assert(vtableAsGlobalValue &&
"VTable must support CIRGlobalValueInterface");
550 "emitVTableDefinitions: WholeProgramVTables");
559mlir::Value CIRGenItaniumCXXABI::emitVirtualDestructorCall(
560 CIRGenFunction &cgf,
const CXXDestructorDecl *dtor,
CXXDtorType dtorType,
561 Address thisAddr, DeleteOrMemberCallExpr
expr) {
562 auto *
callExpr = dyn_cast<const CXXMemberCallExpr *>(
expr);
563 auto *delExpr = dyn_cast<const CXXDeleteExpr *>(
expr);
564 assert((
callExpr !=
nullptr) ^ (delExpr !=
nullptr));
568 GlobalDecl globalDecl(dtor, dtorType);
569 const CIRGenFunctionInfo *fnInfo =
578 thisTy,
nullptr, QualType(),
nullptr);
582void CIRGenItaniumCXXABI::emitVirtualInheritanceTables(
583 const CXXRecordDecl *rd) {
590class CIRGenItaniumRTTIBuilder {
592 const CIRGenItaniumCXXABI &cxxABI;
595 SmallVector<mlir::Attribute, 16> fields;
598 cir::GlobalOp getAddrOfTypeName(mlir::Location loc, QualType ty,
599 cir::GlobalLinkageKind linkage);
602 mlir::Attribute getAddrOfExternalRTTIDescriptor(mlir::Location loc,
606 void buildVTablePointer(mlir::Location loc,
const Type *ty);
610 void buildSIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
615 void buildVMIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
619 void buildPointerTypeInfo(mlir::Location loc, QualType ty);
626 void buildPointerToMemberTypeInfo(mlir::Location loc,
627 const MemberPointerType *ty);
630 CIRGenItaniumRTTIBuilder(
const CIRGenItaniumCXXABI &abi, CIRGenModule &cgm)
631 : cgm(cgm), cxxABI(abi) {}
635 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty);
638 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty,
639 cir::GlobalLinkageKind linkage,
640 mlir::SymbolTable::Visibility visibility);
647static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
655 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
668 bool isDLLImport = rd->
hasAttr<DLLImportAttr>();
678 return !isDLLImport || cgm.
getTriple().isWindowsItaniumEnvironment();
688const char *vTableClassNameForType(
const CIRGenModule &cgm,
const Type *ty) {
690 static const char *
const classTypeInfo =
691 "_ZTVN10__cxxabiv117__class_type_infoE";
693 static const char *
const siClassTypeInfo =
694 "_ZTVN10__cxxabiv120__si_class_type_infoE";
696 static const char *
const vmiClassTypeInfo =
697 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
700#define TYPE(Class, Base)
701#define ABSTRACT_TYPE(Class, Base)
702#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
703#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
704#define DEPENDENT_TYPE(Class, Base) case Type::Class:
705#include "clang/AST/TypeNodes.inc"
706 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
708 case Type::LValueReference:
709 case Type::RValueReference:
710 llvm_unreachable(
"References shouldn't get here");
713 case Type::DeducedTemplateSpecialization:
714 llvm_unreachable(
"Undeduced type shouldn't get here");
717 llvm_unreachable(
"Pipe types shouldn't get here");
719 case Type::ArrayParameter:
720 llvm_unreachable(
"Array Parameter types should not get here.");
724 case Type::OverflowBehavior:
727 case Type::ExtVector:
728 case Type::ConstantMatrix:
732 case Type::BlockPointer:
733 return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
734 case Type::ConstantArray:
735 case Type::IncompleteArray:
736 case Type::VariableArray:
738 return "_ZTVN10__cxxabiv117__array_type_infoE";
740 case Type::FunctionNoProto:
741 case Type::FunctionProto:
743 return "_ZTVN10__cxxabiv120__function_type_infoE";
746 return "_ZTVN10__cxxabiv116__enum_type_infoE";
750 ->getDefinitionOrSelf();
753 return classTypeInfo;
757 return siClassTypeInfo;
760 return vmiClassTypeInfo;
763 case Type::ObjCObject:
764 cgm.
errorNYI(
"VTableClassNameForType: ObjCObject");
767 case Type::ObjCInterface:
768 cgm.
errorNYI(
"VTableClassNameForType: ObjCInterface");
771 case Type::ObjCObjectPointer:
774 return "_ZTVN10__cxxabiv119__pointer_type_infoE";
776 case Type::MemberPointer:
778 return "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
780 case Type::HLSLAttributedResource:
781 case Type::HLSLInlineSpirv:
782 llvm_unreachable(
"HLSL doesn't support virtual functions");
802 return cir::GlobalLinkageKind::InternalLinkage;
806 llvm_unreachable(
"Linkage hasn't been computed!");
811 return cir::GlobalLinkageKind::InternalLinkage;
819 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
821 if (
const RecordType *record = dyn_cast<RecordType>(ty)) {
825 return cir::GlobalLinkageKind::WeakODRLinkage;
827 if (cgm.
getTriple().isWindowsItaniumEnvironment())
828 if (rd->
hasAttr<DLLImportAttr>() &&
829 shouldUseExternalRttiDescriptor(cgm, ty))
830 return cir::GlobalLinkageKind::ExternalLinkage;
836 .isWindowsGNUEnvironment())
840 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
843 llvm_unreachable(
"Invalid linkage!");
847CIRGenItaniumRTTIBuilder::getAddrOfTypeName(mlir::Location loc, QualType ty,
848 cir::GlobalLinkageKind linkage) {
850 SmallString<256>
name;
851 llvm::raw_svector_ostream
out(name);
857 mlir::Attribute init = builder.
getString(
870 loc, name, initStr.getType(), linkage, align);
876CIRGenItaniumRTTIBuilder::getAddrOfExternalRTTIDescriptor(mlir::Location loc,
879 SmallString<256>
name;
880 llvm::raw_svector_ostream
out(name);
885 cir::GlobalOp gv = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
900 cgm.
errorNYI(
"getAddrOfExternalRTTIDescriptor: hasPS4DLLImportExport");
907void CIRGenItaniumRTTIBuilder::buildVTablePointer(mlir::Location loc,
910 const char *vTableName = vTableClassNameForType(cgm, ty);
914 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
921 loc, vTableName, vtableGlobalTy, cir::GlobalLinkageKind::ExternalLinkage,
927 vTable.setConstant(
false);
930 mlir::Attribute field{};
932 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
934 SmallVector<mlir::Attribute, 4> offsets{
936 auto indices = mlir::ArrayAttr::get(builder.getContext(), offsets);
941 assert(field &&
"expected attribute");
942 fields.push_back(field);
947void CIRGenItaniumRTTIBuilder::buildSIClassTypeInfo(mlir::Location loc,
948 const CXXRecordDecl *rd) {
952 mlir::Attribute baseTypeInfo =
953 CIRGenItaniumRTTIBuilder(cxxABI, cgm)
955 fields.push_back(baseTypeInfo);
961void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc,
962 const CXXRecordDecl *rd) {
963 mlir::Type unsignedIntLTy =
971 fields.push_back(cir::IntAttr::get(unsignedIntLTy, flags));
976 fields.push_back(cir::IntAttr::get(unsignedIntLTy, rd->
getNumBases()));
1009 mlir::Type offsetFlagsLTy = cgm.
convertType(offsetFlagsTy);
1011 for (
const CXXBaseSpecifier &base : rd->
bases()) {
1013 fields.push_back(CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1014 .buildTypeInfo(loc, base.getType()));
1016 CXXRecordDecl *baseDecl = base.getType()->castAsCXXRecordDecl();
1024 if (base.isVirtual())
1028 const ASTRecordLayout &layout =
1036 if (base.isVirtual())
1038 if (base.getAccessSpecifier() ==
AS_public)
1041 fields.push_back(cir::IntAttr::get(offsetFlagsLTy, offsetFlags));
1045void CIRGenItaniumRTTIBuilder::buildPointerTypeInfo(mlir::Location loc,
1066 const unsigned int flags =
1070 mlir::Attribute flagsAttr = cir::IntAttr::get(unsignedIntTy, flags);
1071 fields.push_back(flagsAttr);
1073 mlir::Attribute pointeeTypeInfo =
1074 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, ty);
1075 fields.push_back(pointeeTypeInfo);
1078void CIRGenItaniumRTTIBuilder::buildPointerToMemberTypeInfo(
1079 mlir::Location loc,
const MemberPointerType *ty) {
1098 mlir::Attribute flagsAttr = cir::IntAttr::get(unsignedIntTy, flags);
1099 fields.push_back(flagsAttr);
1101 mlir::Attribute pointeeTypeInfo =
1102 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, pointeeTy);
1103 fields.push_back(pointeeTypeInfo);
1106 mlir::Attribute classTypeInfo =
1107 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, contextTy);
1108 fields.push_back(classTypeInfo);
1111mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(mlir::Location loc,
1117 SmallString<256>
name;
1118 llvm::raw_svector_ostream
out(name);
1121 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
1123 if (oldGV && !oldGV.isDeclaration()) {
1124 assert(!oldGV.hasAvailableExternallyLinkage() &&
1125 "available_externally typeinfos not yet implemented");
1132 shouldUseExternalRttiDescriptor(cgm, ty))
1133 return getAddrOfExternalRTTIDescriptor(loc, ty);
1143 mlir::SymbolTable::Visibility symVisibility;
1146 symVisibility = mlir::SymbolTable::Visibility::Public;
1147 else if (cxxABI.classifyRTTIUniqueness(ty, linkage) ==
1148 CIRGenItaniumCXXABI::RUK_NonUniqueHidden) {
1150 "buildTypeInfo: classifyRTTIUniqueness == RUK_NonUniqueHidden");
1155 return buildTypeInfo(loc, ty, linkage, symVisibility);
1158mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
1159 mlir::Location loc, QualType ty, cir::GlobalLinkageKind linkage,
1160 mlir::SymbolTable::Visibility visibility) {
1169 cir::GlobalOp typeName = getAddrOfTypeName(loc, ty, linkage);
1170 mlir::Attribute typeNameField;
1174 CIRGenItaniumCXXABI::RTTIUniquenessKind rttiUniqueness =
1175 cxxABI.classifyRTTIUniqueness(ty, linkage);
1176 if (rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique) {
1180 "buildTypeInfo: rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique");
1186 fields.push_back(typeNameField);
1189#define TYPE(Class, Base)
1190#define ABSTRACT_TYPE(Class, Base)
1191#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1192#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1193#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1194#include "clang/AST/TypeNodes.inc"
1195 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1200 case Type::ExtVector:
1201 case Type::ConstantMatrix:
1203 case Type::BlockPointer:
1208 case Type::LValueReference:
1209 case Type::RValueReference:
1210 llvm_unreachable(
"References shouldn't get here");
1213 case Type::DeducedTemplateSpecialization:
1214 llvm_unreachable(
"Undeduced type shouldn't get here");
1222 case Type::OverflowBehavior:
1225 case Type::ConstantArray:
1226 case Type::IncompleteArray:
1227 case Type::VariableArray:
1228 case Type::ArrayParameter:
1233 case Type::FunctionNoProto:
1234 case Type::FunctionProto:
1244 case Type::Record: {
1246 ->getDefinitionOrSelf();
1253 buildSIClassTypeInfo(loc, rd);
1255 buildVMIClassTypeInfo(loc, rd);
1261 case Type::ObjCObject:
1262 case Type::ObjCInterface:
1263 cgm.
errorNYI(
"buildTypeInfo: ObjCObject & ObjCInterface");
1266 case Type::ObjCObjectPointer:
1267 cgm.
errorNYI(
"buildTypeInfo: ObjCObjectPointer");
1275 case Type::MemberPointer:
1283 case Type::HLSLAttributedResource:
1284 case Type::HLSLInlineSpirv:
1285 llvm_unreachable(
"HLSL doesn't support RTTI");
1289 cir::TypeInfoAttr init = builder.
getTypeInfo(builder.getArrayAttr(fields));
1291 SmallString<256>
name;
1292 llvm::raw_svector_ostream
out(name);
1296 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
1300 gv.setLinkage(linkage);
1305 cgm.
errorNYI(
"buildTypeInfo: target hasPS4DLLImportExport");
1312 gv.setName(oldGV.getName());
1313 if (!oldGV->use_empty()) {
1314 cgm.
errorNYI(
"buildTypeInfo: old GV !use_empty");
1326 gv.setAlignmentAttr(cgm.
getSize(align));
1343 mlir::SymbolTable::setSymbolVisibility(typeName, visibility);
1348 mlir::SymbolTable::setSymbolVisibility(gv, visibility);
1357bool CIRGenItaniumCXXABI::shouldTypeidBeNullChecked(QualType srcTy) {
1361void CIRGenItaniumCXXABI::emitBadTypeidCall(CIRGenFunction &cgf,
1362 mlir::Location loc) {
1364 cir::FuncType fnTy =
1366 mlir::NamedAttrList attrs;
1367 attrs.set(cir::CIRDialect::getNoReturnAttrName(),
1373 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
1376mlir::Value CIRGenItaniumCXXABI::emitTypeid(CIRGenFunction &cgf, QualType srcTy,
1378 mlir::Type typeInfoPtrTy) {
1380 mlir::Location loc = cgm.
getLoc(classDecl->getSourceRange());
1381 mlir::Value vptr = cgf.
getVTablePtr(loc, thisPtr, classDecl);
1389 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1391 vtbl = cir::VTableGetTypeInfoOp::create(
1399mlir::Attribute CIRGenItaniumCXXABI::getAddrOfRTTIDescriptor(mlir::Location loc,
1401 return CIRGenItaniumRTTIBuilder(*
this, cgm).buildTypeInfo(loc, ty);
1406CIRGenItaniumCXXABI::RTTIUniquenessKind
1407CIRGenItaniumCXXABI::classifyRTTIUniqueness(
1408 QualType canTy, cir::GlobalLinkageKind linkage)
const {
1409 if (shouldRTTIBeUnique())
1413 if (linkage != cir::GlobalLinkageKind::LinkOnceODRLinkage &&
1414 linkage != cir::GlobalLinkageKind::WeakODRLinkage)
1422 if (linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage)
1423 return RUK_NonUniqueHidden;
1428 assert(linkage == cir::GlobalLinkageKind::WeakODRLinkage);
1429 return RUK_NonUniqueVisible;
1432void CIRGenItaniumCXXABI::emitDestructorCall(
1434 bool forVirtualBase,
bool delegating, Address thisAddr, QualType thisTy) {
1435 GlobalDecl gd(dd,
type);
1441 CIRGenCallee callee =
1448void CIRGenItaniumCXXABI::registerGlobalDtor(
const VarDecl *vd,
1464mlir::Value CIRGenItaniumCXXABI::getCXXDestructorImplicitParam(
1466 bool forVirtualBase,
bool delegating) {
1467 GlobalDecl gd(dd,
type);
1475 mlir::Value exceptionPtr = {},
1476 mlir::FlatSymbolRefAttr typeInfo = {},
1477 mlir::FlatSymbolRefAttr dtor = {}) {
1478 mlir::Block *currentBlock = builder.getInsertionBlock();
1479 mlir::Region *region = currentBlock->getParent();
1481 if (currentBlock->empty()) {
1482 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1483 cir::UnreachableOp::create(builder, loc);
1485 mlir::Block *throwBlock = builder.createBlock(region);
1487 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1488 cir::UnreachableOp::create(builder, loc);
1490 builder.setInsertionPointToEnd(currentBlock);
1491 cir::BrOp::create(builder, loc, throwBlock);
1494 (void)builder.createBlock(region);
1497void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf,
bool isNoReturn) {
1501 assert(cgf.
currSrcLoc &&
"expected source location");
1505 cgm.
errorNYI(
"emitRethrow with isNoReturn false");
1509void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf,
1510 const CXXThrowExpr *e) {
1518 cir::PointerType throwTy =
1525 mlir::TypedValue<cir::PointerType> exceptionPtr =
1526 cir::AllocExceptionOp::create(builder, subExprLoc, throwTy,
1527 builder.getI64IntegerAttr(typeSize))
1535 auto typeInfo = mlir::cast<cir::GlobalViewAttr>(
1538 assert(!typeInfo.getIndices() &&
"expected no indirection");
1548 mlir::FlatSymbolRefAttr dtor{};
1549 if (cxxrd && !cxxrd->hasTrivialDestructor()) {
1554 CXXDestructorDecl *dtorD = cxxrd->getDestructor();
1555 dtor = mlir::FlatSymbolRefAttr::get(
1567 case TargetCXXABI::GenericItanium:
1568 case TargetCXXABI::GenericAArch64:
1569 case TargetCXXABI::GenericARM:
1570 return new CIRGenItaniumCXXABI(cgm);
1572 case TargetCXXABI::AppleARM64:
1576 return new CIRGenItaniumCXXABI(cgm);
1579 llvm_unreachable(
"bad or NYI ABI kind");
1583cir::GlobalOp CIRGenItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *rd,
1585 assert(vptrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1586 cir::GlobalOp &vtable = vtables[rd];
1594 llvm::raw_svector_ostream
out(name);
1595 getMangleContext().mangleCXXVTable(rd,
out);
1604 unsigned ptrAlign = cgm.
getLangOpts().RelativeCXXABIVTables
1610 cir::GlobalLinkageKind::ExternalLinkage,
1624 "getAddrOfVTable: PS4 DLL import/export");
1630CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer(
1634 mlir::Location loc = cgf.
getLoc(srcLoc);
1637 mlir::Value vtable = cgf.
getVTablePtr(loc, thisAddr, methodDecl->getParent());
1640 mlir::Value vfunc{};
1642 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: emitVTableTypeCheckedLoad");
1646 mlir::Value vfuncLoad;
1649 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: isRelativeLayout");
1651 auto vtableSlotPtr = cir::VTableGetVirtualFnAddrOp::create(
1652 builder, loc, builder.
getPointerTo(tyPtr), vtable, vtableIndex);
1665 if (
auto loadOp = vfuncLoad.getDefiningOp<cir::LoadOp>())
1666 loadOp.setInvariant(
true);
1671 CIRGenCallee callee(gd, vfunc.getDefiningOp());
1675mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1676 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
1677 const CXXRecordDecl *nearestVBase) {
1679 needsVTTParameter(cgf.
curGD) &&
"This class doesn't have VTT");
1690 virtualPointerIndex);
1692 auto vptrType = cir::VPtrType::get(cgf.
getBuilder().getContext());
1698CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject base,
1699 const CXXRecordDecl *vtableClass) {
1700 cir::GlobalOp vtable = getAddrOfVTable(vtableClass, CharUnits());
1704 VTableLayout::AddressPointLocation addressPoint =
1710 auto vtablePtrTy = cir::VPtrType::get(builder.getContext());
1712 return cir::VTableAddrPointOp::create(
1714 mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()),
1715 cir::AddressPointAttr::get(cgm.
getBuilder().getContext(),
1720cir::GlobalViewAttr CIRGenItaniumCXXABI::getVTableAddressPointAttr(
1721 BaseSubobject base,
const CXXRecordDecl *vtableClass) {
1722 cir::GlobalOp vtable = getAddrOfVTable(vtableClass, CharUnits());
1726 VTableLayout::AddressPointLocation addressPoint =
1732 mlir::ArrayAttr indices = builder.getArrayAttr(
1733 {builder.getI32IntegerAttr(addressPoint.
VTableIndex),
1735 return cir::GlobalViewAttr::get(
1736 cir::VPtrType::get(builder.getContext()),
1737 mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()), indices,
1741mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor(
1742 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
1743 clang::BaseSubobject base,
const clang::CXXRecordDecl *nearestVBase) {
1746 needsVTTParameter(cgf.
curGD)) {
1747 return getVTableAddressPointInStructorWithVTT(cgf, vtableClass, base,
1750 return getVTableAddressPoint(base, vtableClass);
1753bool CIRGenItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1754 CIRGenFunction &cgf, CIRGenFunction::VPtr vptr) {
1757 return needsVTTParameter(cgf.
curGD);
1760mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(
1761 mlir::Location loc, CIRGenFunction &cgf, Address thisAddr,
1762 const CXXRecordDecl *classDecl,
const CXXRecordDecl *baseClassDecl) {
1764 mlir::Value vtablePtr = cgf.
getVTablePtr(loc, thisAddr, classDecl);
1766 CharUnits vbaseOffsetOffset =
1769 mlir::Value offsetVal =
1771 auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.
uInt8PtrTy,
1772 vtableBytePtr, offsetVal);
1774 mlir::Value vbaseOffset;
1777 cgm.
errorNYI(loc,
"getVirtualBaseClassOffset: relative layout");
1793 cir::FuncType fnTy =
1802 mlir::NamedAttrList attrs;
1803 attrs.set(cir::CIRDialect::getNoReturnAttrName(),
1807 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
1811void CIRGenItaniumCXXABI::emitBadCastCall(CIRGenFunction &cgf,
1812 mlir::Location loc) {
1835 {voidPtrTy, rttiPtrTy, rttiPtrTy, ptrDiffTy}, voidPtrTy);
1837 fn->setAttr(cir::CIRDialect::getNoThrowAttrName(),
1838 mlir::UnitAttr::get(cgf.
getBuilder().getContext()));
1844 bool vtableUsesRelativeLayout = cgf.
cgm.
getLangOpts().RelativeCXXABIVTables;
1846 loc, src.
getPointer(), vtableUsesRelativeLayout);
1854 cir::PointerType destCIRTy,
1855 bool isRefCast,
Address src) {
1865 std::optional<CharUnits> offset;
1875 pathElement.Base->getType()->getAsCXXRecordDecl();
1876 if (pathElement.Base->isVirtual()) {
1890 offset = pathOffset;
1891 }
else if (offset != pathOffset) {
1907 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
1909 mlir::Region *currentRegion = builder.getBlock()->getParent();
1914 builder.createBlock(currentRegion, currentRegion->end());
1917 return nullPtrValue;
1925 mlir::Value expectedVPtr =
1930 mlir::Type vptrTy = expectedVPtr.getType();
1934 mlir::Value srcVPtr = builder.
createLoad(loc, srcVPtrPtr);
1939 mlir::Value success =
1940 builder.
createCompare(loc, cir::CmpOpKind::eq, srcVPtr, expectedVPtr);
1942 auto emitCastResult = [&] {
1943 if (offset->isZero())
1950 mlir::Value strideToApply =
1953 mlir::Value resultU8Ptr = cir::PtrStrideOp::create(builder, loc, u8PtrTy,
1954 srcU8Ptr, strideToApply);
1959 mlir::Value failed = builder.
createNot(success);
1960 cir::IfOp::create(builder, loc, failed,
false,
1961 [&](mlir::OpBuilder &, mlir::Location) {
1964 return emitCastResult();
1967 return cir::TernaryOp::create(
1968 builder, loc, success,
1969 [&](mlir::OpBuilder &, mlir::Location) {
1970 auto result = emitCastResult();
1973 [&](mlir::OpBuilder &, mlir::Location) {
1974 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
1984 auto srcRtti = mlir::cast<cir::GlobalViewAttr>(
1986 auto destRtti = mlir::cast<cir::GlobalViewAttr>(
1991 auto runtimeFuncRef = mlir::FlatSymbolRefAttr::get(runtimeFuncOp);
1992 auto badCastFuncRef = mlir::FlatSymbolRefAttr::get(badCastFuncOp);
2000 auto offsetHintAttr = cir::IntAttr::get(ptrdiffTy, offsetHint.
getQuantity());
2002 return cir::DynamicCastInfoAttr::get(srcRtti, destRtti, runtimeFuncRef,
2003 badCastFuncRef, offsetHintAttr);
2006mlir::Value CIRGenItaniumCXXABI::emitDynamicCast(CIRGenFunction &cgf,
2008 QualType srcRecordTy,
2009 QualType destRecordTy,
2010 cir::PointerType destCIRTy,
2011 bool isRefCast, Address src) {
2012 bool isCastToVoid = destRecordTy.
isNull();
2013 assert((!isCastToVoid || !isRefCast) &&
"cannot cast to void reference");
2026 return cir::TernaryOp::create(
2027 builder, loc, srcPtrIsNull,
2028 [&](mlir::OpBuilder, mlir::Location) {
2030 loc, builder.
getNullPtr(destCIRTy, loc).getResult());
2032 [&](mlir::OpBuilder &, mlir::Location) {
2034 *
this, cgf, loc, srcRecordTy, destRecordTy, destCIRTy,
2042 destCIRTy, isRefCast, src);
2045 cir::DynamicCastInfoAttr castInfo =
2048 isRefCast, castInfo);
2052CIRGenItaniumCXXABI::buildVirtualMethodAttr(cir::MethodType methodTy,
2053 const CXXMethodDecl *md) {
2054 assert(md->
isVirtual() &&
"only deal with virtual member functions");
2060 vtableOffset = index * 4;
2065 vtableOffset = index * pointerWidth.
getQuantity();
2068 return cir::MethodAttr::get(methodTy, vtableOffset);
2072void CIRGenItaniumCXXABI::emitVirtualObjectDelete(
2073 CIRGenFunction &cgf,
const CXXDeleteExpr *delExpr, Address ptr,
2074 QualType elementType,
const CXXDestructorDecl *dtor) {
2076 if (useGlobalDelete) {
2078 "emitVirtualObjectDelete: global delete");
2082 emitVirtualDestructorCall(cgf, dtor, dtorType, ptr, delExpr);
2087CharUnits CIRGenItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2095Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf,
2097 mlir::Value numElements,
2098 const CXXNewExpr *e,
2099 QualType elementType) {
2100 assert(requiresArrayCookie(e));
2111 CharUnits cookieSize =
2113 assert(cookieSize == getArrayCookieSizeImpl(elementType));
2116 mlir::Value baseBytePtr =
2120 CharUnits cookieOffset = cookieSize - sizeSize;
2121 mlir::Value cookiePtrValue = baseBytePtr;
2122 if (!cookieOffset.
isZero()) {
2131 Address cookiePtr(cookiePtrValue, u8Ty, cookiePtrAlignment);
2140 mlir::Value dataOffset =
2143 mlir::Value dataPtr =
2145 mlir::Value finalPtr =
2151bool CIRGenItaniumCXXABI::hasAnyUnusedVirtualInlineFunction(
2152 const CXXRecordDecl *rd)
const {
2155 for (
const auto &vtableComponent : vtableLayout.vtable_components()) {
2157 if (!vtableComponent.isUsedFunctionPointerKind())
2160 const CXXMethodDecl *method = vtableComponent.getFunctionDecl();
2162 const bool isInlined =
2168 vtableComponent.getGlobalDecl(
false));
2169 auto entry = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
2175 if (!entry || entry.isDeclaration())
2181bool CIRGenItaniumCXXABI::isVTableHidden(
const CXXRecordDecl *rd)
const {
2184 for (
const auto &vtableComponent : vtableLayout.vtable_components()) {
2185 if (vtableComponent.isRTTIKind()) {
2186 const CXXRecordDecl *rttiDecl = vtableComponent.getRTTIDecl();
2187 if (rttiDecl->
getVisibility() == Visibility::HiddenVisibility)
2189 }
else if (vtableComponent.isUsedFunctionPointerKind()) {
2190 const CXXMethodDecl *method = vtableComponent.getFunctionDecl();
2191 if (method->
getVisibility() == Visibility::HiddenVisibility &&
2199bool CIRGenItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2200 const CXXRecordDecl *rd)
const {
2208 if (isVTableHidden(rd))
2228 if (hasAnyUnusedVirtualInlineFunction(rd))
2236 for (
const auto &b : rd->
bases()) {
2237 auto *brd = b.getType()->getAsCXXRecordDecl();
2238 assert(brd &&
"no class for base specifier");
2239 if (b.isVirtual() || !brd->isDynamicClass())
2241 if (!canSpeculativelyEmitVTableAsBaseClass(brd))
2249bool CIRGenItaniumCXXABI::canSpeculativelyEmitVTable(
2250 const CXXRecordDecl *rd)
const {
2251 if (!canSpeculativelyEmitVTableAsBaseClass(rd))
2259 for (
const auto &b : rd->
vbases()) {
2260 auto *brd = b.getType()->getAsCXXRecordDecl();
2261 assert(brd &&
"no class for base specifier");
2262 if (!brd->isDynamicClass())
2264 if (!canSpeculativelyEmitVTableAsBaseClass(brd))
2276 bool isReturnAdjustment) {
2277 if (!nonVirtualAdjustment && !virtualAdjustment)
2281 mlir::Location loc = builder.getUnknownLoc();
2282 cir::PointerType ui8DefaultASPtrTy = builder.
getUInt8PtrTy();
2285 auto i8PtrTy = mlir::cast<cir::PointerType>(v.getType());
2288 if (nonVirtualAdjustment && !isReturnAdjustment) {
2289 cir::ConstantOp offsetConst = builder.
getSInt64(nonVirtualAdjustment, loc);
2290 v = cir::PtrStrideOp::create(builder, loc, i8PtrTy, v, offsetConst);
2294 mlir::Value resultPtr;
2295 if (virtualAdjustment) {
2298 vtablePtr = builder.
createBitcast(vtablePtr, ui8DefaultASPtrTy);
2301 mlir::Value offsetPtr =
2302 cir::PtrStrideOp::create(builder, loc, ui8DefaultASPtrTy, vtablePtr,
2303 builder.
getSInt64(virtualAdjustment, loc));
2306 cgf.
cgm.
errorNYI(
"virtual adjustment for relative layout vtables");
2312 resultPtr = cir::PtrStrideOp::create(builder, loc, i8PtrTy, v, offset);
2319 if (nonVirtualAdjustment && isReturnAdjustment) {
2320 cir::ConstantOp offsetConst = builder.
getSInt64(nonVirtualAdjustment, loc);
2322 cir::PtrStrideOp::create(builder, loc, i8PtrTy, resultPtr, offsetConst);
2329mlir::Value CIRGenItaniumCXXABI::performThisAdjustment(
2330 CIRGenFunction &cgf, Address thisAddr,
const CXXRecordDecl *unadjustedClass,
2331 const ThunkInfo &ti) {
2338mlir::Value CIRGenItaniumCXXABI::performReturnAdjustment(
2339 CIRGenFunction &cgf, Address ret,
const CXXRecordDecl *unadjustedClass,
2340 const ReturnAdjustment &ra) {
2346bool CIRGenItaniumCXXABI::isZeroInitializable(
const MemberPointerType *mpt) {
static void emitConstructorDestructorAlias(CIRGenModule &cgm, GlobalDecl aliasDecl, GlobalDecl targetDecl)
static void insertThrowAndSplit(mlir::OpBuilder &builder, mlir::Location loc, mlir::Value exceptionPtr={}, mlir::FlatSymbolRefAttr typeInfo={}, mlir::FlatSymbolRefAttr dtor={})
static Address emitDynamicCastToVoid(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, Address src)
static cir::DynamicCastInfoAttr emitDynamicCastInfo(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy)
static cir::GlobalLinkageKind getTypeInfoLinkage(CIRGenModule &cgm, QualType ty)
Return the linkage that the type info and type info name constants should have for the given type.
static mlir::Value performTypeAdjustment(CIRGenFunction &cgf, Address initialPtr, const CXXRecordDecl *unadjustedClass, int64_t nonVirtualAdjustment, int64_t virtualAdjustment, bool isReturnAdjustment)
static mlir::Value emitExactDynamicCast(CIRGenItaniumCXXABI &abi, CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy, cir::PointerType destCIRTy, bool isRefCast, Address src)
static void emitCallToBadCast(CIRGenFunction &cgf, mlir::Location loc)
static cir::FuncOp getItaniumDynamicCastFn(CIRGenFunction &cgf)
static StructorCIRGen getCIRGenToUse(CIRGenModule &cgm, const CXXMethodDecl *md)
static cir::FuncOp getBadCastFn(CIRGenFunction &cgf)
static RValue performReturnAdjustment(CIRGenFunction &cgf, QualType resultType, RValue rv, const ThunkInfo &thunk)
Defines the clang::Expr interface and subclasses for C++ expressions.
static QualType getPointeeType(const MemRegion *R)
C Language Family Type Representation.
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
mlir::Value createPtrIsNull(mlir::Value ptr)
cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base, mlir::Value stride)
cir::PointerType getPointerTo(mlir::Type ty)
cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc)
mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy)
mlir::Value getSignedInt(mlir::Location loc, int64_t val, unsigned numBits)
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)
cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind, mlir::Value lhs, mlir::Value rhs)
mlir::Value createNot(mlir::Location loc, mlir::Value value)
cir::PointerType getVoidPtrTy(clang::LangAS langAS=clang::LangAS::Default)
cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value={})
Create a yield operation.
llvm::Align getABITypeAlign(mlir::Type ty) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CharUnits getExnObjectAlignment() const
Return the alignment (in bytes) of the thrown exception object.
CharUnits getPreferredTypeAlignInChars(QualType T) const
Return the PreferredAlignment of a (complete) type T, in characters.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
CanQualType getCanonicalTagType(const TagDecl *TD) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
mlir::Value getPointer() const
mlir::Type getElementType() const
clang::CharUnits getAlignment() const
mlir::Type getType() const
mlir::Value emitRawPointer() const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
cir::IntType getUInt64Ty()
cir::IntType getUInt8Ty()
cir::TypeInfoAttr getTypeInfo(mlir::ArrayAttr fieldsAttr)
cir::ConstantOp getSInt64(uint64_t c, mlir::Location loc)
cir::PointerType getUInt8PtrTy()
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false, bool isNontemporal=false)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, bool isNontemporal=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
cir::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty, mlir::Value ptr, llvm::MaybeAlign align)
cir::FuncType getFuncType(llvm::ArrayRef< mlir::Type > params, mlir::Type retTy, bool isVarArg=false)
mlir::Value createDynCastToVoid(mlir::Location loc, mlir::Value src, bool vtableUseRelativeLayout)
mlir::Value createDynCast(mlir::Location loc, mlir::Value src, cir::PointerType destType, bool isRefCast, cir::DynamicCastInfoAttr info)
mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy, std::optional< size_t > size, bool ensureNullTerm=true)
Get a cir::ConstArrayAttr for a string literal.
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
mlir::Value createVTTAddrPoint(mlir::Location loc, mlir::Type retTy, mlir::Value addr, uint64_t offset)
Implements C++ ABI-specific code generation functions.
clang::MangleContext & getMangleContext()
Gets the mangle context.
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
static CIRGenCallee forVirtual(const clang::CallExpr *ce, clang::GlobalDecl md, Address addr, cir::FuncType fTy)
mlir::Type convertType(clang::QualType t)
clang::GlobalDecl curGD
The GlobalDecl for the current function being compiled or the global variable currently being initial...
const clang::Decl * curFuncDecl
Address getAddrOfLocalVar(const clang::VarDecl *vd)
Return the address of a local variable.
void emitAnyExprToExn(const Expr *e, Address addr)
mlir::Value getVTTParameter(GlobalDecl gd, bool forVirtualBase, bool delegating)
Return the VTT parameter that should be passed to a base constructor/destructor with virtual bases.
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
mlir::Value loadCXXVTT()
Load the VTT parameter to base constructors/destructors have virtual bases.
mlir::Value getVTablePtr(mlir::Location loc, Address thisAddr, const clang::CXXRecordDecl *vtableClass)
Return the Value of the vtable pointer member pointed to by thisAddr.
bool shouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *rd)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
CIRGenBuilderTy & getBuilder()
mlir::Value emitRuntimeCall(mlir::Location loc, cir::FuncOp callee, llvm::ArrayRef< mlir::Value > args={}, mlir::NamedAttrList attrs={})
std::optional< SourceRange > currSrcLoc
Use to track source locations across nested visitor traversals.
void emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)
clang::ASTContext & getContext() const
This class organizes the cross-function state that is used while generating CIR code.
llvm::StringRef getMangledName(clang::GlobalDecl gd)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
clang::ASTContext & getASTContext() const
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
mlir::Type convertType(clang::QualType type)
mlir::IntegerAttr getSize(CharUnits size)
CIRGenBuilderTy & getBuilder()
ItaniumVTableContext & getItaniumVTableContext()
void setGVProperties(mlir::Operation *op, const NamedDecl *d) const
Set visibility, dllimport/dllexport and dso_local.
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
const clang::TargetInfo & getTarget() const
const llvm::Triple & getTriple() const
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
const cir::CIRDataLayout & getDataLayout() const
cir::GlobalOp createOrReplaceCXXRuntimeVariable(mlir::Location loc, llvm::StringRef name, mlir::Type ty, cir::GlobalLinkageKind linkage, clang::CharUnits alignment)
Will return a global variable of the given type.
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::NamedAttrList extraAttrs={}, bool isLocal=false, bool assumeConvergent=false)
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
void eraseGlobalSymbol(mlir::Operation *op)
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
const clang::CodeGenOptions & getCodeGenOpts() const
const clang::LangOptions & getLangOpts() const
cir::GlobalOp createGlobalOp(mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::ptr::MemorySpaceAttrInterface addrSpace={}, mlir::Operation *insertPoint=nullptr)
void addDeferredVTable(const CXXRecordDecl *rd)
cir::FuncOp codegenCXXStructor(clang::GlobalDecl gd)
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
mlir::Operation * getGlobalValue(llvm::StringRef ref)
bool supportsCOMDAT() const
mlir::MLIRContext & getMLIRContext()
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
CIRGenCXXABI & getCXXABI() const
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
CIRGenVTables & getVTables()
cir::GlobalLinkageKind getVTableLinkage(const CXXRecordDecl *rd)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
cir::RecordType getVTableType(const clang::VTableLayout &layout)
Returns the type of a vtable with the given layout.
void createVTableInitializer(cir::GlobalOp &vtable, const clang::VTableLayout &layout, mlir::Attribute rtti, bool vtableHasLocalLinkage)
Add vtable components for the given vtable layout to the given global initializer.
void emitVTTDefinition(cir::GlobalOp vttOp, cir::GlobalLinkageKind linkage, const CXXRecordDecl *rd)
Emit the definition of the given vtable.
cir::GlobalOp getAddrOfVTT(const CXXRecordDecl *rd)
Get the address of the VTT for the given record decl.
bool isVTableExternal(const clang::CXXRecordDecl *rd)
At this point in the translation unit, does it appear that can we rely on the vtable being defined el...
uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *rd, BaseSubobject base)
Return the index in the VTT where the virtual pointer for the given subobject is located.
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
QualType getType() const
Retrieves the type of the base class.
bool isGlobalDelete() const
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
SourceRange getSourceRange() const
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
base_class_range vbases()
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
bool hasDefinition() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
const Expr * getSubExpr() const
static CanQual< Type > CreateUnsafe(QualType Other)
This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
Test whether the quantity equals zero.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits One()
Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Construct a CharUnits quantity of zero.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
bool shouldEmitInExternalSource() const
Whether the definition of the declaration should be emitted in external sources.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
FunctionDecl * getDefinition()
Get the definition for this declaration.
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
GlobalDecl - represents a global declaration.
GlobalDecl getWithCtorType(CXXCtorType Type)
CXXCtorType getCtorType() const
GlobalDecl getWithDtorType(CXXDtorType Type)
CXXDtorType getDtorType() const
const Decl * getDecl() const
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D, raw_ostream &)=0
virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D, raw_ostream &)=0
uint64_t getMethodVTableIndex(GlobalDecl GD)
Locate a virtual function in the vtable.
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)
Return the offset in chars (relative to the vtable address point) where the offset of the virtual bas...
virtual void mangleCXXRTTI(QualType T, raw_ostream &)=0
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Encodes a location in the source.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool hasConstructorVariants() const
Does this ABI have different entrypoints for complete-object and base-subobject constructors?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
virtual bool hasPS4DLLImportExport() const
uint64_t getPointerAlign(LangAS AddrSpace) const
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
unsigned getLongWidth() const
getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' for this target,...
SourceLocation getBeginLoc() const LLVM_READONLY
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
CXXRecordDecl * castAsCXXRecordDecl() const
Visibility getVisibility() const
Determine the visibility of this type.
Linkage getLinkage() const
Determine the linkage of this type.
TypeClass getTypeClass() const
AddressPointLocation getAddressPoint(BaseSubobject Base) const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed?
static bool isLocalLinkage(GlobalLinkageKind linkage)
static bool isValidLinkage(GlobalLinkageKind gl)
static bool isWeakForLinker(GlobalLinkageKind linkage)
Whether the definition of this global may be replaced at link time.
static bool isDiscardableIfUnused(GlobalLinkageKind linkage)
Whether the definition of this global may be discarded if it is not used in its compilation unit.
CIRGenCXXABI * CreateCIRGenItaniumCXXABI(CIRGenModule &cgm)
Creates and Itanium-family ABI.
unsigned extractPBaseFlags(const ASTContext &Ctx, QualType &Type)
Compute the flags for a __pbase_type_info, and remove the corresponding pieces from Type.
bool containsIncompleteClassType(QualType Ty)
Returns whether the given type contains an incomplete class type.
bool canUseSingleInheritance(const CXXRecordDecl *RD)
Return whether the given record decl has a "single, public, non-virtual base at offset zero (i....
unsigned computeVMIClassTypeInfoFlags(const CXXRecordDecl *RD)
Compute the value of the flags member in abi::__vmi_class_type_info.
CharUnits computeOffsetHint(ASTContext &Ctx, const CXXRecordDecl *Src, const CXXRecordDecl *Dst)
Compute the src2dst_offset hint as described in the Itanium C++ ABI [2.9.7].
bool isStandardLibraryRTTIDescriptor(QualType Ty)
Returns whether the type information for the given type exists in the standard library.
@ BCTI_Virtual
BCTI_Virtual - Base class is virtual.
@ BCTI_Public
BCTI_Public - Base class is public.
@ PTI_ContainingClassIncomplete
PTI_ContainingClassIncomplete - Containing class is incomplete.
llvm::Value * getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating)
const internal::VariadicDynCastAllOfMatcher< Stmt, CallExpr > callExpr
Matches call expressions.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
@ Address
A pointer to a ValueDecl.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ VisibleNone
No linkage according to the standard, but is visible from other translation units because of types de...
@ None
No linkage, which means that the entity is unique and can only be referred to from within its scope.
@ UniqueExternal
External linkage within a unique namespace.
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ External
External linkage, which indicates that the entity can be referred to from other translation units.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
CXXDtorType
C++ destructor types.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
U cast(CodeGen::Address addr)
@ DefaultVisibility
Objects with "default" visibility are seen by the dynamic linker and act like normal objects.
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 int64_t
static bool addressSpace()
static bool opGlobalUnnamedAddr()
static bool vtableEmitMetadata()
static bool emitTypeMetadataCodeForVCall()
static bool opFuncReadOnly()
static bool setDLLStorageClass()
static bool hiddenVisibility()
static bool cxxabiAppleARM64CXXABI()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool pointerAuthentication()
static bool opFuncCallingConv()
static bool opFuncWillReturn()
static bool protectedVisibility()
static bool cxxabiUseARMGuardVarABI()
static bool cxxabiUseARMMethodPtrABI()
static bool setDSOLocal()
static bool vtableRelativeLayout()
const clang::CXXRecordDecl * nearestVBase
clang::CharUnits getPointerAlign() const
clang::CharUnits getSizeSize() const
cir::PointerType uInt8PtrTy
Represents an element in a path from a derived class to a base class.
union clang::ReturnAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
ThisAdjustment This
The this pointer adjustment.
unsigned AddressPointIndex
struct clang::ReturnAdjustment::VirtualAdjustment::@103031170252120233124322035264172076254313213024 Itanium
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
struct clang::ThisAdjustment::VirtualAdjustment::@106065375072164260365214033034320247050276346205 Itanium
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset.