27#include "llvm/Support/ErrorHandling.h"
37 llvm::DenseMap<const CXXRecordDecl *, cir::GlobalOp> vtables;
40 CIRGenItaniumCXXABI(CIRGenModule &cgm) : CIRGenCXXABI(cgm) {
45 AddedStructorArgs getImplicitConstructorArgs(CIRGenFunction &cgf,
46 const CXXConstructorDecl *d,
49 bool delegating)
override;
51 bool needsVTTParameter(clang::GlobalDecl gd)
override;
53 AddedStructorArgCounts
54 buildStructorSignature(GlobalDecl gd,
55 llvm::SmallVectorImpl<CanQualType> &argTys)
override;
57 void emitInstanceFunctionProlog(SourceLocation loc,
58 CIRGenFunction &cgf)
override;
60 void addImplicitStructorParams(CIRGenFunction &cgf, QualType &resTy,
61 FunctionArgList ¶ms)
override;
63 const CXXDestructorDecl *dd,
66 bool delegating)
override;
67 void emitCXXConstructors(
const clang::CXXConstructorDecl *d)
override;
68 void emitCXXDestructors(
const clang::CXXDestructorDecl *d)
override;
69 void emitCXXStructor(clang::GlobalDecl gd)
override;
71 void emitDestructorCall(CIRGenFunction &cgf,
const CXXDestructorDecl *dd,
73 bool delegating, Address thisAddr,
74 QualType thisTy)
override;
75 void registerGlobalDtor(
const VarDecl *vd, cir::FuncOp dtor,
76 mlir::Value addr)
override;
77 void emitVirtualObjectDelete(CIRGenFunction &cgf,
const CXXDeleteExpr *de,
78 Address ptr, QualType elementType,
79 const CXXDestructorDecl *dtor)
override;
81 void emitRethrow(CIRGenFunction &cgf,
bool isNoReturn)
override;
82 void emitThrow(CIRGenFunction &cgf,
const CXXThrowExpr *e)
override;
84 bool useThunkForDtorVariant(
const CXXDestructorDecl *dtor,
92 bool isVirtualOffsetNeededForVTableField(CIRGenFunction &cgf,
93 CIRGenFunction::VPtr vptr)
override;
95 cir::GlobalOp getAddrOfVTable(
const CXXRecordDecl *rd,
96 CharUnits vptrOffset)
override;
97 CIRGenCallee getVirtualFunctionPointer(CIRGenFunction &cgf,
98 clang::GlobalDecl gd, Address thisAddr,
100 SourceLocation loc)
override;
101 mlir::Value emitVirtualDestructorCall(CIRGenFunction &cgf,
102 const CXXDestructorDecl *dtor,
104 DeleteOrMemberCallExpr e)
override;
105 mlir::Value getVTableAddressPoint(BaseSubobject base,
106 const CXXRecordDecl *vtableClass)
override;
107 mlir::Value getVTableAddressPointInStructorWithVTT(
108 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
109 const CXXRecordDecl *nearestVBase);
111 mlir::Value getVTableAddressPointInStructor(
112 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
113 clang::BaseSubobject base,
114 const clang::CXXRecordDecl *nearestVBase)
override;
115 void emitVTableDefinitions(CIRGenVTables &cgvt,
116 const CXXRecordDecl *rd)
override;
117 void emitVirtualInheritanceTables(
const CXXRecordDecl *rd)
override;
119 mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc,
120 QualType ty)
override;
122 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *vtableClass)
override {
126 size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *,
127 FunctionArgList &args)
const override {
128 assert(!args.empty() &&
"expected the arglist to not be empty!");
129 return args.size() - 1;
132 void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc)
override;
135 getVirtualBaseClassOffset(mlir::Location loc, CIRGenFunction &cgf,
136 Address thisAddr,
const CXXRecordDecl *classDecl,
137 const CXXRecordDecl *baseClassDecl)
override;
144 mlir::Value emitDynamicCast(CIRGenFunction &cgf, mlir::Location loc,
145 QualType srcRecordTy, QualType destRecordTy,
146 cir::PointerType destCIRTy,
bool isRefCast,
147 Address src)
override;
149 Address initializeArrayCookie(CIRGenFunction &cgf, Address newPtr,
150 mlir::Value numElements,
const CXXNewExpr *e,
151 QualType elementType)
override;
154 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
159 virtual bool shouldRTTIBeUnique()
const {
return true; }
163 enum RTTIUniquenessKind {
181 classifyRTTIUniqueness(QualType canTy, cir::GlobalLinkageKind linkage)
const;
186void CIRGenItaniumCXXABI::emitInstanceFunctionProlog(
SourceLocation loc,
191 "emitInstanceFunctionProlog: Naked");
196 setCXXABIThisValue(cgf, loadIncomingCXXThis(cgf));
199 if (getStructorImplicitParamDecl(cgf)) {
203 setStructorImplicitParamValue(cgf, val);
214 if (hasThisReturn(cgf.
curGD)) {
216 "emitInstanceFunctionProlog: hasThisReturn");
220CIRGenCXXABI::AddedStructorArgCounts
221CIRGenItaniumCXXABI::buildStructorSignature(
222 GlobalDecl gd, llvm::SmallVectorImpl<CanQualType> &argTys) {
233 argTys.insert(argTys.begin() + 1,
236 return AddedStructorArgCounts::withPrefix(1);
239 return AddedStructorArgCounts{};
244enum class StructorCIRGen { Emit, RAUW, Alias, COMDAT };
250 return StructorCIRGen::Emit;
255 return StructorCIRGen::Emit;
258 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(md)) {
268 return StructorCIRGen::RAUW;
272 return StructorCIRGen::RAUW;
278 return StructorCIRGen::COMDAT;
279 return StructorCIRGen::Emit;
282 return StructorCIRGen::Alias;
292 auto globalValue = dyn_cast_or_null<cir::CIRGlobalValueInterface>(
294 if (globalValue && !globalValue.isDeclaration())
297 auto entry = cast_or_null<cir::FuncOp>(cgm.
getGlobalValue(mangledName));
306void CIRGenItaniumCXXABI::emitCXXStructor(GlobalDecl gd) {
309 const auto *cd = dyn_cast<CXXConstructorDecl>(md);
313 GlobalDecl baseDecl =
317 if (cirGenType == StructorCIRGen::Alias ||
318 cirGenType == StructorCIRGen::COMDAT) {
323 if (cirGenType == StructorCIRGen::RAUW) {
336void CIRGenItaniumCXXABI::addImplicitStructorParams(CIRGenFunction &cgf,
338 FunctionArgList ¶ms) {
343 if (needsVTTParameter(cgf.
curGD)) {
350 astContext,
nullptr, md->getLocation(),
351 &astContext.
Idents.
get(
"vtt"), t, ImplicitParamKind::CXXVTT);
352 params.insert(params.begin() + 1, vttDecl);
353 getStructorImplicitParamDecl(cgf) = vttDecl;
357void CIRGenItaniumCXXABI::emitCXXConstructors(
const CXXConstructorDecl *d) {
373void CIRGenItaniumCXXABI::emitCXXDestructors(
const CXXDestructorDecl *d) {
389CIRGenCXXABI::AddedStructorArgs CIRGenItaniumCXXABI::getImplicitConstructorArgs(
391 bool forVirtualBase,
bool delegating) {
392 if (!needsVTTParameter(GlobalDecl(d,
type)))
393 return AddedStructorArgs{};
403 return AddedStructorArgs::withPrefix({{vtt, vttTy}});
409bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
413 if (!md->getParent()->getNumVBases())
427void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt,
428 const CXXRecordDecl *rd) {
429 cir::GlobalOp vtable = getAddrOfVTable(rd, CharUnits());
430 if (vtable.hasInitializer())
436 mlir::Attribute rtti =
447 vtable.setLinkage(linkage);
450 vtable.setComdat(
true);
465 "emitVTableDefinitions: __fundamental_type_info");
468 [[maybe_unused]]
auto vtableAsGlobalValue =
469 dyn_cast<cir::CIRGlobalValueInterface>(*vtable);
470 assert(vtableAsGlobalValue &&
"VTable must support CIRGlobalValueInterface");
480 "emitVTableDefinitions: WholeProgramVTables");
489mlir::Value CIRGenItaniumCXXABI::emitVirtualDestructorCall(
490 CIRGenFunction &cgf,
const CXXDestructorDecl *dtor,
CXXDtorType dtorType,
491 Address thisAddr, DeleteOrMemberCallExpr
expr) {
492 auto *
callExpr = dyn_cast<const CXXMemberCallExpr *>(
expr);
493 auto *delExpr = dyn_cast<const CXXDeleteExpr *>(
expr);
494 assert((
callExpr !=
nullptr) ^ (delExpr !=
nullptr));
498 GlobalDecl globalDecl(dtor, dtorType);
499 const CIRGenFunctionInfo *fnInfo =
508 thisTy,
nullptr, QualType(),
nullptr);
512void CIRGenItaniumCXXABI::emitVirtualInheritanceTables(
513 const CXXRecordDecl *rd) {
520class CIRGenItaniumRTTIBuilder {
522 const CIRGenItaniumCXXABI &cxxABI;
525 SmallVector<mlir::Attribute, 16> fields;
528 cir::GlobalOp getAddrOfTypeName(mlir::Location loc, QualType ty,
529 cir::GlobalLinkageKind linkage);
532 mlir::Attribute getAddrOfExternalRTTIDescriptor(mlir::Location loc,
536 void buildVTablePointer(mlir::Location loc,
const Type *ty);
540 void buildSIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
545 void buildVMIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
548 CIRGenItaniumRTTIBuilder(
const CIRGenItaniumCXXABI &abi, CIRGenModule &cgm)
549 : cgm(cgm), cxxABI(abi) {}
553 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty);
556 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty,
557 cir::GlobalLinkageKind linkage,
558 mlir::SymbolTable::Visibility visibility);
577 PTI_Incomplete = 0x8,
581 PTI_ContainingClassIncomplete = 0x10,
593 VMI_NonDiamondRepeat = 0x1,
596 VMI_DiamondShaped = 0x2
611static bool typeInfoIsInStandardLibrary(
const BuiltinType *ty) {
627 case BuiltinType::WasmExternRef:
628 case BuiltinType::HLSLResource:
629 llvm_unreachable(
"NYI");
630 case BuiltinType::Void:
631 case BuiltinType::NullPtr:
632 case BuiltinType::Bool:
633 case BuiltinType::WChar_S:
634 case BuiltinType::WChar_U:
635 case BuiltinType::Char_U:
636 case BuiltinType::Char_S:
637 case BuiltinType::UChar:
638 case BuiltinType::SChar:
639 case BuiltinType::Short:
640 case BuiltinType::UShort:
641 case BuiltinType::Int:
642 case BuiltinType::UInt:
643 case BuiltinType::Long:
644 case BuiltinType::ULong:
645 case BuiltinType::LongLong:
646 case BuiltinType::ULongLong:
647 case BuiltinType::Half:
648 case BuiltinType::Float:
649 case BuiltinType::Double:
650 case BuiltinType::LongDouble:
651 case BuiltinType::Float16:
652 case BuiltinType::Float128:
653 case BuiltinType::Ibm128:
654 case BuiltinType::Char8:
655 case BuiltinType::Char16:
656 case BuiltinType::Char32:
657 case BuiltinType::Int128:
658 case BuiltinType::UInt128:
661#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
662 case BuiltinType::Id:
663#include "clang/Basic/OpenCLImageTypes.def"
664#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
665#include "clang/Basic/OpenCLExtensionTypes.def"
666 case BuiltinType::OCLSampler:
667 case BuiltinType::OCLEvent:
668 case BuiltinType::OCLClkEvent:
669 case BuiltinType::OCLQueue:
670 case BuiltinType::OCLReserveID:
671#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
672#include "clang/Basic/AArch64ACLETypes.def"
673#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
674#include "clang/Basic/PPCTypes.def"
675#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
676#include "clang/Basic/RISCVVTypes.def"
677#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
678#include "clang/Basic/AMDGPUTypes.def"
679 case BuiltinType::ShortAccum:
680 case BuiltinType::Accum:
681 case BuiltinType::LongAccum:
682 case BuiltinType::UShortAccum:
683 case BuiltinType::UAccum:
684 case BuiltinType::ULongAccum:
685 case BuiltinType::ShortFract:
686 case BuiltinType::Fract:
687 case BuiltinType::LongFract:
688 case BuiltinType::UShortFract:
689 case BuiltinType::UFract:
690 case BuiltinType::ULongFract:
691 case BuiltinType::SatShortAccum:
692 case BuiltinType::SatAccum:
693 case BuiltinType::SatLongAccum:
694 case BuiltinType::SatUShortAccum:
695 case BuiltinType::SatUAccum:
696 case BuiltinType::SatULongAccum:
697 case BuiltinType::SatShortFract:
698 case BuiltinType::SatFract:
699 case BuiltinType::SatLongFract:
700 case BuiltinType::SatUShortFract:
701 case BuiltinType::SatUFract:
702 case BuiltinType::SatULongFract:
703 case BuiltinType::BFloat16:
706 case BuiltinType::Dependent:
707#define BUILTIN_TYPE(Id, SingletonId)
708#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
709#include "clang/AST/BuiltinTypes.def"
710 llvm_unreachable(
"asking for RRTI for a placeholder type!");
712 case BuiltinType::ObjCId:
713 case BuiltinType::ObjCClass:
714 case BuiltinType::ObjCSel:
715 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
718 llvm_unreachable(
"Invalid BuiltinType Kind!");
721static bool typeInfoIsInStandardLibrary(
const PointerType *pointerTy) {
723 const auto *builtinTy = dyn_cast<BuiltinType>(pointeeTy);
734 return typeInfoIsInStandardLibrary(builtinTy);
739static bool isStandardLibraryRttiDescriptor(QualType ty) {
741 if (
const auto *builtinTy = dyn_cast<BuiltinType>(ty))
742 return typeInfoIsInStandardLibrary(builtinTy);
746 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
747 return typeInfoIsInStandardLibrary(pointerTy);
756static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
764 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
777 bool isDLLImport = rd->
hasAttr<DLLImportAttr>();
787 return !isDLLImport || cgm.
getTriple().isWindowsItaniumEnvironment();
800 llvm::SmallPtrSet<const CXXRecordDecl *, 16> nonVirtualBases;
801 llvm::SmallPtrSet<const CXXRecordDecl *, 16> virtualBases;
806static unsigned computeVmiClassTypeInfoFlags(
const CXXBaseSpecifier *base,
814 if (!bases.virtualBases.insert(baseDecl).second) {
817 flags |= VMI_DiamondShaped;
819 if (bases.nonVirtualBases.count(baseDecl))
820 flags |= VMI_NonDiamondRepeat;
824 if (!bases.nonVirtualBases.insert(baseDecl).second) {
827 flags |= VMI_NonDiamondRepeat;
829 if (bases.virtualBases.count(baseDecl))
830 flags |= VMI_NonDiamondRepeat;
835 for (
const auto &bs : baseDecl->bases())
836 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
841static unsigned computeVmiClassTypeInfoFlags(
const CXXRecordDecl *rd) {
846 for (
const auto &bs : rd->
bases())
847 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
856static bool canUseSingleInheritance(
const CXXRecordDecl *rd) {
874 return baseDecl->isEmpty() ||
879static bool isIncompleteClassType(
const RecordType *recordTy) {
880 return !recordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
894static bool containsIncompleteClassType(QualType ty) {
895 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
896 if (isIncompleteClassType(recordTy))
900 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
903 if (
const auto *memberPointerTy = dyn_cast<MemberPointerType>(ty)) {
905 if (!memberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
908 return containsIncompleteClassType(memberPointerTy->getPointeeType());
914const char *vTableClassNameForType(
const CIRGenModule &cgm,
const Type *ty) {
916 static const char *
const classTypeInfo =
917 "_ZTVN10__cxxabiv117__class_type_infoE";
919 static const char *
const siClassTypeInfo =
920 "_ZTVN10__cxxabiv120__si_class_type_infoE";
922 static const char *
const vmiClassTypeInfo =
923 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
926#define TYPE(Class, Base)
927#define ABSTRACT_TYPE(Class, Base)
928#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
929#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
930#define DEPENDENT_TYPE(Class, Base) case Type::Class:
931#include "clang/AST/TypeNodes.inc"
932 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
934 case Type::LValueReference:
935 case Type::RValueReference:
936 llvm_unreachable(
"References shouldn't get here");
939 case Type::DeducedTemplateSpecialization:
940 llvm_unreachable(
"Undeduced type shouldn't get here");
943 llvm_unreachable(
"Pipe types shouldn't get here");
945 case Type::ArrayParameter:
946 llvm_unreachable(
"Array Parameter types should not get here.");
952 case Type::ExtVector:
953 case Type::ConstantMatrix:
957 case Type::BlockPointer:
958 return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
959 case Type::ConstantArray:
960 case Type::IncompleteArray:
961 case Type::VariableArray:
962 cgm.
errorNYI(
"VTableClassNameForType: __array_type_info");
965 case Type::FunctionNoProto:
966 case Type::FunctionProto:
967 cgm.
errorNYI(
"VTableClassNameForType: __function_type_info");
971 return "_ZTVN10__cxxabiv116__enum_type_infoE";
975 ->getDefinitionOrSelf();
978 return classTypeInfo;
981 if (canUseSingleInheritance(rd)) {
982 return siClassTypeInfo;
985 return vmiClassTypeInfo;
988 case Type::ObjCObject:
989 cgm.
errorNYI(
"VTableClassNameForType: ObjCObject");
992 case Type::ObjCInterface:
993 cgm.
errorNYI(
"VTableClassNameForType: ObjCInterface");
996 case Type::ObjCObjectPointer:
998 cgm.
errorNYI(
"VTableClassNameForType: __pointer_type_info");
1001 case Type::MemberPointer:
1002 cgm.
errorNYI(
"VTableClassNameForType: __pointer_to_member_type_info");
1005 case Type::HLSLAttributedResource:
1006 case Type::HLSLInlineSpirv:
1007 llvm_unreachable(
"HLSL doesn't support virtual functions");
1026 if (containsIncompleteClassType(ty))
1027 return cir::GlobalLinkageKind::InternalLinkage;
1031 llvm_unreachable(
"Linkage hasn't been computed!");
1036 return cir::GlobalLinkageKind::InternalLinkage;
1044 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1046 if (
const RecordType *record = dyn_cast<RecordType>(ty)) {
1050 return cir::GlobalLinkageKind::WeakODRLinkage;
1052 if (cgm.
getTriple().isWindowsItaniumEnvironment())
1053 if (rd->
hasAttr<DLLImportAttr>() &&
1054 shouldUseExternalRttiDescriptor(cgm, ty))
1055 return cir::GlobalLinkageKind::ExternalLinkage;
1061 .isWindowsGNUEnvironment())
1065 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1068 llvm_unreachable(
"Invalid linkage!");
1072CIRGenItaniumRTTIBuilder::getAddrOfTypeName(mlir::Location loc, QualType ty,
1073 cir::GlobalLinkageKind linkage) {
1075 SmallString<256>
name;
1076 llvm::raw_svector_ostream
out(name);
1082 mlir::Attribute init = builder.
getString(
1095 loc, name, initStr.getType(), linkage, align);
1101CIRGenItaniumRTTIBuilder::getAddrOfExternalRTTIDescriptor(mlir::Location loc,
1104 SmallString<256>
name;
1105 llvm::raw_svector_ostream
out(name);
1110 cir::GlobalOp gv = dyn_cast_or_null<cir::GlobalOp>(
1111 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1126 cgm.
errorNYI(
"getAddrOfExternalRTTIDescriptor: hasPS4DLLImportExport");
1133void CIRGenItaniumRTTIBuilder::buildVTablePointer(mlir::Location loc,
1136 const char *vTableName = vTableClassNameForType(cgm, ty);
1140 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1147 loc, vTableName, vtableGlobalTy, cir::GlobalLinkageKind::ExternalLinkage,
1151 mlir::Attribute field{};
1153 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1155 SmallVector<mlir::Attribute, 4> offsets{
1157 auto indices = mlir::ArrayAttr::get(builder.getContext(), offsets);
1162 assert(field &&
"expected attribute");
1163 fields.push_back(field);
1168void CIRGenItaniumRTTIBuilder::buildSIClassTypeInfo(mlir::Location loc,
1169 const CXXRecordDecl *rd) {
1173 mlir::Attribute baseTypeInfo =
1174 CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1176 fields.push_back(baseTypeInfo);
1182void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc,
1183 const CXXRecordDecl *rd) {
1184 mlir::Type unsignedIntLTy =
1191 unsigned flags = computeVmiClassTypeInfoFlags(rd);
1192 fields.push_back(cir::IntAttr::get(unsignedIntLTy, flags));
1197 fields.push_back(cir::IntAttr::get(unsignedIntLTy, rd->
getNumBases()));
1230 mlir::Type offsetFlagsLTy = cgm.
convertType(offsetFlagsTy);
1232 for (
const CXXBaseSpecifier &base : rd->
bases()) {
1234 fields.push_back(CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1235 .buildTypeInfo(loc, base.
getType()));
1249 const ASTRecordLayout &layout =
1258 offsetFlags |= BCTI_Virtual;
1260 offsetFlags |= BCTI_Public;
1262 fields.push_back(cir::IntAttr::get(offsetFlagsLTy, offsetFlags));
1266mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(mlir::Location loc,
1272 SmallString<256>
name;
1273 llvm::raw_svector_ostream
out(name);
1276 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1277 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1279 if (oldGV && !oldGV.isDeclaration()) {
1280 assert(!oldGV.hasAvailableExternallyLinkage() &&
1281 "available_externally typeinfos not yet implemented");
1287 if (isStandardLibraryRttiDescriptor(ty) ||
1288 shouldUseExternalRttiDescriptor(cgm, ty))
1289 return getAddrOfExternalRTTIDescriptor(loc, ty);
1299 mlir::SymbolTable::Visibility symVisibility;
1302 symVisibility = mlir::SymbolTable::Visibility::Public;
1303 else if (cxxABI.classifyRTTIUniqueness(ty, linkage) ==
1304 CIRGenItaniumCXXABI::RUK_NonUniqueHidden) {
1306 "buildTypeInfo: classifyRTTIUniqueness == RUK_NonUniqueHidden");
1311 return buildTypeInfo(loc, ty, linkage, symVisibility);
1314mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
1315 mlir::Location loc, QualType ty, cir::GlobalLinkageKind linkage,
1316 mlir::SymbolTable::Visibility visibility) {
1325 cir::GlobalOp typeName = getAddrOfTypeName(loc, ty, linkage);
1326 mlir::Attribute typeNameField;
1330 CIRGenItaniumCXXABI::RTTIUniquenessKind rttiUniqueness =
1331 cxxABI.classifyRTTIUniqueness(ty, linkage);
1332 if (rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique) {
1336 "buildTypeInfo: rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique");
1342 fields.push_back(typeNameField);
1345#define TYPE(Class, Base)
1346#define ABSTRACT_TYPE(Class, Base)
1347#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1348#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1349#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1350#include "clang/AST/TypeNodes.inc"
1351 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1356 case Type::ExtVector:
1357 case Type::ConstantMatrix:
1359 case Type::BlockPointer:
1364 case Type::LValueReference:
1365 case Type::RValueReference:
1366 llvm_unreachable(
"References shouldn't get here");
1369 case Type::DeducedTemplateSpecialization:
1370 llvm_unreachable(
"Undeduced type shouldn't get here");
1378 case Type::ConstantArray:
1379 case Type::IncompleteArray:
1380 case Type::VariableArray:
1381 case Type::ArrayParameter:
1386 case Type::FunctionNoProto:
1387 case Type::FunctionProto:
1397 case Type::Record: {
1399 ->getDefinitionOrSelf();
1405 if (canUseSingleInheritance(rd)) {
1406 buildSIClassTypeInfo(loc, rd);
1408 buildVMIClassTypeInfo(loc, rd);
1414 case Type::ObjCObject:
1415 case Type::ObjCInterface:
1416 cgm.
errorNYI(
"buildTypeInfo: ObjCObject & ObjCInterface");
1419 case Type::ObjCObjectPointer:
1420 cgm.
errorNYI(
"buildTypeInfo: ObjCObjectPointer");
1424 cgm.
errorNYI(
"buildTypeInfo: Pointer");
1427 case Type::MemberPointer:
1428 cgm.
errorNYI(
"buildTypeInfo: MemberPointer");
1435 case Type::HLSLAttributedResource:
1436 case Type::HLSLInlineSpirv:
1437 llvm_unreachable(
"HLSL doesn't support RTTI");
1441 cir::TypeInfoAttr init = builder.
getTypeInfo(builder.getArrayAttr(fields));
1443 SmallString<256>
name;
1444 llvm::raw_svector_ostream
out(name);
1448 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1449 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1458 cgm.
errorNYI(
"buildTypeInfo: target hasPS4DLLImportExport");
1465 gv.setName(oldGV.getName());
1466 if (!oldGV->use_empty()) {
1467 cgm.
errorNYI(
"buildTypeInfo: old GV !use_empty");
1475 cgm.
errorNYI(
"buildTypeInfo: supportsCOMDAT & isWeakForLinker");
1481 gv.setAlignmentAttr(cgm.
getSize(align));
1498 mlir::SymbolTable::setSymbolVisibility(typeName, visibility);
1503 mlir::SymbolTable::setSymbolVisibility(gv, visibility);
1512mlir::Attribute CIRGenItaniumCXXABI::getAddrOfRTTIDescriptor(mlir::Location loc,
1514 return CIRGenItaniumRTTIBuilder(*
this, cgm).buildTypeInfo(loc, ty);
1519CIRGenItaniumCXXABI::RTTIUniquenessKind
1520CIRGenItaniumCXXABI::classifyRTTIUniqueness(
1521 QualType canTy, cir::GlobalLinkageKind linkage)
const {
1522 if (shouldRTTIBeUnique())
1526 if (linkage != cir::GlobalLinkageKind::LinkOnceODRLinkage &&
1527 linkage != cir::GlobalLinkageKind::WeakODRLinkage)
1535 if (linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage)
1536 return RUK_NonUniqueHidden;
1541 assert(linkage == cir::GlobalLinkageKind::WeakODRLinkage);
1542 return RUK_NonUniqueVisible;
1545void CIRGenItaniumCXXABI::emitDestructorCall(
1547 bool forVirtualBase,
bool delegating, Address thisAddr, QualType thisTy) {
1548 GlobalDecl gd(dd,
type);
1554 CIRGenCallee callee =
1561void CIRGenItaniumCXXABI::registerGlobalDtor(
const VarDecl *vd,
1582mlir::Value CIRGenItaniumCXXABI::getCXXDestructorImplicitParam(
1584 bool forVirtualBase,
bool delegating) {
1585 GlobalDecl gd(dd,
type);
1593 mlir::Value exceptionPtr = {},
1594 mlir::FlatSymbolRefAttr typeInfo = {},
1595 mlir::FlatSymbolRefAttr dtor = {}) {
1596 mlir::Block *currentBlock = builder.getInsertionBlock();
1597 mlir::Region *region = currentBlock->getParent();
1599 if (currentBlock->empty()) {
1600 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1601 cir::UnreachableOp::create(builder, loc);
1603 mlir::Block *throwBlock = builder.createBlock(region);
1605 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1606 cir::UnreachableOp::create(builder, loc);
1608 builder.setInsertionPointToEnd(currentBlock);
1609 cir::BrOp::create(builder, loc, throwBlock);
1612 (void)builder.createBlock(region);
1615void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf,
bool isNoReturn) {
1619 assert(cgf.
currSrcLoc &&
"expected source location");
1623 cgm.
errorNYI(
"emitRethrow with isNoReturn false");
1627void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf,
1628 const CXXThrowExpr *e) {
1636 cir::PointerType throwTy =
1643 mlir::TypedValue<cir::PointerType> exceptionPtr =
1644 cir::AllocExceptionOp::create(builder, subExprLoc, throwTy,
1645 builder.getI64IntegerAttr(typeSize))
1653 auto typeInfo = mlir::cast<cir::GlobalViewAttr>(
1656 assert(!typeInfo.getIndices() &&
"expected no indirection");
1665 if (
const RecordType *recordTy = clangThrowType->
getAs<RecordType>()) {
1668 if (!rec->hasTrivialDestructor()) {
1669 cgm.
errorNYI(
"emitThrow: non-trivial destructor");
1681 case TargetCXXABI::GenericItanium:
1682 case TargetCXXABI::GenericAArch64:
1683 return new CIRGenItaniumCXXABI(cgm);
1685 case TargetCXXABI::AppleARM64:
1689 return new CIRGenItaniumCXXABI(cgm);
1692 llvm_unreachable(
"bad or NYI ABI kind");
1696cir::GlobalOp CIRGenItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *rd,
1698 assert(vptrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1699 cir::GlobalOp &vtable = vtables[rd];
1707 llvm::raw_svector_ostream
out(name);
1708 getMangleContext().mangleCXXVTable(rd,
out);
1723 cir::GlobalLinkageKind::ExternalLinkage,
1737 "getAddrOfVTable: PS4 DLL import/export");
1743CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer(
1747 mlir::Location loc = cgf.
getLoc(srcLoc);
1750 mlir::Value vtable = cgf.
getVTablePtr(loc, thisAddr, methodDecl->getParent());
1753 mlir::Value vfunc{};
1755 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: emitVTableTypeCheckedLoad");
1759 mlir::Value vfuncLoad;
1762 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: isRelativeLayout");
1764 auto vtableSlotPtr = cir::VTableGetVirtualFnAddrOp::create(
1765 builder, loc, builder.
getPointerTo(tyPtr), vtable, vtableIndex);
1778 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: strictVTablePointers");
1783 CIRGenCallee callee(gd, vfunc.getDefiningOp());
1787mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1788 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
1789 const CXXRecordDecl *nearestVBase) {
1791 needsVTTParameter(cgf.
curGD) &&
"This class doesn't have VTT");
1802 virtualPointerIndex);
1804 auto vptrType = cir::VPtrType::get(cgf.
getBuilder().getContext());
1810CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject base,
1811 const CXXRecordDecl *vtableClass) {
1812 cir::GlobalOp vtable = getAddrOfVTable(vtableClass, CharUnits());
1816 VTableLayout::AddressPointLocation addressPoint =
1822 auto vtablePtrTy = cir::VPtrType::get(builder.getContext());
1824 return cir::VTableAddrPointOp::create(
1826 mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()),
1827 cir::AddressPointAttr::get(cgm.
getBuilder().getContext(),
1832mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor(
1833 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
1834 clang::BaseSubobject base,
const clang::CXXRecordDecl *nearestVBase) {
1837 needsVTTParameter(cgf.
curGD)) {
1838 return getVTableAddressPointInStructorWithVTT(cgf, vtableClass, base,
1841 return getVTableAddressPoint(base, vtableClass);
1844bool CIRGenItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1845 CIRGenFunction &cgf, CIRGenFunction::VPtr vptr) {
1848 return needsVTTParameter(cgf.
curGD);
1851mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(
1852 mlir::Location loc, CIRGenFunction &cgf, Address thisAddr,
1853 const CXXRecordDecl *classDecl,
const CXXRecordDecl *baseClassDecl) {
1855 mlir::Value vtablePtr = cgf.
getVTablePtr(loc, thisAddr, classDecl);
1857 CharUnits vbaseOffsetOffset =
1860 mlir::Value offsetVal =
1862 auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.
uInt8PtrTy,
1863 vtableBytePtr, offsetVal);
1865 mlir::Value vbaseOffset;
1868 cgm.
errorNYI(loc,
"getVirtualBaseClassOffset: relative layout");
1884 cir::FuncType fnTy =
1894 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
1898void CIRGenItaniumCXXABI::emitBadCastCall(CIRGenFunction &cgf,
1899 mlir::Location loc) {
1912 if (!dst->isDerivedFrom(src, paths))
1915 unsigned numPublicPaths = 0;
1928 if (pathElement.Base->isVirtual())
1931 if (numPublicPaths > 1)
1938 pathElement.Base->getType()->getAsCXXRecordDecl());
1943 if (numPublicPaths == 0)
1947 if (numPublicPaths > 1)
1975 {voidPtrTy, rttiPtrTy, rttiPtrTy, ptrDiffTy}, voidPtrTy);
1981 bool vtableUsesRelativeLayout =
1984 loc, src.
getPointer(), vtableUsesRelativeLayout);
1992 cir::PointerType destCIRTy,
1993 bool isRefCast,
Address src) {
2003 std::optional<CharUnits> offset;
2013 pathElement.Base->getType()->getAsCXXRecordDecl();
2014 if (pathElement.Base->isVirtual()) {
2028 offset = pathOffset;
2029 }
else if (offset != pathOffset) {
2045 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2047 mlir::Region *currentRegion = builder.getBlock()->getParent();
2052 builder.createBlock(currentRegion, currentRegion->end());
2055 return nullPtrValue;
2063 mlir::Value expectedVPtr =
2064 abi.getVTableAddressPoint(
BaseSubobject(srcDecl, *offset), destDecl);
2068 mlir::Type vptrTy = expectedVPtr.getType();
2072 mlir::Value srcVPtr = builder.
createLoad(loc, srcVPtrPtr);
2077 mlir::Value success =
2078 builder.
createCompare(loc, cir::CmpOpKind::eq, srcVPtr, expectedVPtr);
2080 auto emitCastResult = [&] {
2081 if (offset->isZero())
2088 mlir::Value strideToApply =
2091 mlir::Value resultU8Ptr = cir::PtrStrideOp::create(builder, loc, u8PtrTy,
2092 srcU8Ptr, strideToApply);
2097 mlir::Value failed = builder.
createNot(success);
2098 cir::IfOp::create(builder, loc, failed,
false,
2099 [&](mlir::OpBuilder &, mlir::Location) {
2102 return emitCastResult();
2105 return cir::TernaryOp::create(
2106 builder, loc, success,
2107 [&](mlir::OpBuilder &, mlir::Location) {
2108 auto result = emitCastResult();
2111 [&](mlir::OpBuilder &, mlir::Location) {
2112 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2122 auto srcRtti = mlir::cast<cir::GlobalViewAttr>(
2124 auto destRtti = mlir::cast<cir::GlobalViewAttr>(
2129 auto runtimeFuncRef = mlir::FlatSymbolRefAttr::get(runtimeFuncOp);
2130 auto badCastFuncRef = mlir::FlatSymbolRefAttr::get(badCastFuncOp);
2137 auto offsetHintAttr = cir::IntAttr::get(ptrdiffTy, offsetHint.
getQuantity());
2139 return cir::DynamicCastInfoAttr::get(srcRtti, destRtti, runtimeFuncRef,
2140 badCastFuncRef, offsetHintAttr);
2143mlir::Value CIRGenItaniumCXXABI::emitDynamicCast(CIRGenFunction &cgf,
2145 QualType srcRecordTy,
2146 QualType destRecordTy,
2147 cir::PointerType destCIRTy,
2148 bool isRefCast, Address src) {
2149 bool isCastToVoid = destRecordTy.
isNull();
2150 assert((!isCastToVoid || !isRefCast) &&
"cannot cast to void reference");
2163 return cir::TernaryOp::create(
2164 builder, loc, srcPtrIsNull,
2165 [&](mlir::OpBuilder, mlir::Location) {
2167 loc, builder.
getNullPtr(destCIRTy, loc).getResult());
2169 [&](mlir::OpBuilder &, mlir::Location) {
2171 *
this, cgf, loc, srcRecordTy, destRecordTy, destCIRTy,
2179 destCIRTy, isRefCast, src);
2182 cir::DynamicCastInfoAttr castInfo =
2185 isRefCast, castInfo);
2190void CIRGenItaniumCXXABI::emitVirtualObjectDelete(
2191 CIRGenFunction &cgf,
const CXXDeleteExpr *delExpr, Address ptr,
2192 QualType elementType,
const CXXDestructorDecl *dtor) {
2194 if (useGlobalDelete) {
2196 "emitVirtualObjectDelete: global delete");
2200 emitVirtualDestructorCall(cgf, dtor, dtorType, ptr, delExpr);
2205CharUnits CIRGenItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2213Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf,
2215 mlir::Value numElements,
2216 const CXXNewExpr *e,
2217 QualType elementType) {
2218 assert(requiresArrayCookie(e));
2230 CharUnits cookieSize =
2232 assert(cookieSize == getArrayCookieSizeImpl(elementType));
2235 mlir::Value baseBytePtr =
2239 CharUnits cookieOffset = cookieSize - sizeSize;
2240 mlir::Value cookiePtrValue = baseBytePtr;
2241 if (!cookieOffset.
isZero()) {
2250 Address cookiePtr(cookiePtrValue, u8PtrTy, cookiePtrAlignment);
2253 Address numElementsPtr =
2259 mlir::Value dataOffset =
2262 mlir::Value dataPtr =
2264 mlir::Value finalPtr =
2267 return Address(finalPtr, newPtr.
getElementType(), finalAlignment);
static void emitConstructorDestructorAlias(CIRGenModule &cgm, GlobalDecl aliasDecl, GlobalDecl targetDecl)
static CharUnits computeOffsetHint(ASTContext &astContext, const CXXRecordDecl *src, const CXXRecordDecl *dst)
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 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)
Defines the clang::Expr interface and subclasses for C++ expressions.
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)
mlir::Value createNot(mlir::Value value)
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)
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
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.
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::Value emitRawPointer() const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
cir::IntType getUInt64Ty()
cir::TypeInfoAttr getTypeInfo(mlir::ArrayAttr fieldsAttr)
cir::ConstantOp getSInt64(uint64_t c, mlir::Location loc)
cir::PointerType getUInt8PtrTy()
mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy, std::optional< size_t > size)
Get a cir::ConstArrayAttr for a string literal.
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)
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
mlir::Value createVTTAddrPoint(mlir::Location loc, mlir::Type retTy, mlir::Value addr, uint64_t offset)
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::MemOrderAttr order={})
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={})
void emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
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)
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::ArrayAttr={}, bool isLocal=false, bool assumeConvergent=false)
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)
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.
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
const cir::CIRDataLayout getDataLayout() const
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::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)
mlir::ModuleOp getModule() const
bool supportsCOMDAT() const
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
static cir::GlobalOp createGlobalOp(CIRGenModule &cgm, mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::Operation *insertPoint=nullptr)
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...
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
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.
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()
const CXXBaseSpecifier * base_class_const_iterator
Iterator that traverses the base classes of a class.
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)
CharUnits - 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
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
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, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
uint64_t getMethodVTableIndex(GlobalDecl GD)
Locate a virtual function in the vtable.
bool isRelativeLayout() const
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
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getCanonicalType() const
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
const T * getAs() const
Member-template getAs<specific type>'.
AddressPointLocation getAddressPoint(BaseSubobject Base) const
TLSKind getTLSKind() 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.
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.
The JSON file list parser is used to communicate input to InstallAPI.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
@ 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.
@ Type
The name was classified as a type.
U cast(CodeGen::Address addr)
@ DefaultVisibility
Objects with "default" visibility are seen by the dynamic linker and act like normal objects.
static bool addressSpace()
static bool opGlobalUnnamedAddr()
static bool vtableEmitMetadata()
static bool emitTypeMetadataCodeForVCall()
static bool opFuncReadOnly()
static bool setDLLStorageClass()
static bool hiddenVisibility()
static bool opFuncNoUnwind()
static bool cxxabiAppleARM64CXXABI()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool isTrivialCtorOrDtor()
static bool opFuncCallingConv()
static bool opFuncWillReturn()
static bool protectedVisibility()
static bool deferredVtables()
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.
unsigned AddressPointIndex