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 void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc)
override;
129 getVirtualBaseClassOffset(mlir::Location loc, CIRGenFunction &cgf,
130 Address thisAddr,
const CXXRecordDecl *classDecl,
131 const CXXRecordDecl *baseClassDecl)
override;
138 mlir::Value emitDynamicCast(CIRGenFunction &cgf, mlir::Location loc,
139 QualType srcRecordTy, QualType destRecordTy,
140 cir::PointerType destCIRTy,
bool isRefCast,
141 Address src)
override;
143 Address initializeArrayCookie(CIRGenFunction &cgf, Address newPtr,
144 mlir::Value numElements,
const CXXNewExpr *e,
145 QualType elementType)
override;
148 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
153 virtual bool shouldRTTIBeUnique()
const {
return true; }
157 enum RTTIUniquenessKind {
175 classifyRTTIUniqueness(QualType canTy, cir::GlobalLinkageKind linkage)
const;
180void CIRGenItaniumCXXABI::emitInstanceFunctionProlog(
SourceLocation loc,
185 "emitInstanceFunctionProlog: Naked");
190 setCXXABIThisValue(cgf, loadIncomingCXXThis(cgf));
193 if (getStructorImplicitParamDecl(cgf)) {
197 setStructorImplicitParamValue(cgf, val);
208 if (hasThisReturn(cgf.
curGD)) {
210 "emitInstanceFunctionProlog: hasThisReturn");
214CIRGenCXXABI::AddedStructorArgCounts
215CIRGenItaniumCXXABI::buildStructorSignature(
216 GlobalDecl gd, llvm::SmallVectorImpl<CanQualType> &argTys) {
217 clang::ASTContext &astContext = cgm.getASTContext();
227 argTys.insert(argTys.begin() + 1,
230 return AddedStructorArgCounts::withPrefix(1);
233 return AddedStructorArgCounts{};
238enum class StructorCIRGen { Emit, RAUW, Alias, COMDAT };
244 return StructorCIRGen::Emit;
249 return StructorCIRGen::Emit;
252 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(md)) {
262 return StructorCIRGen::RAUW;
266 return StructorCIRGen::RAUW;
272 return StructorCIRGen::COMDAT;
273 return StructorCIRGen::Emit;
276 return StructorCIRGen::Alias;
286 auto globalValue = dyn_cast_or_null<cir::CIRGlobalValueInterface>(
288 if (globalValue && !globalValue.isDeclaration())
291 auto entry = cast_or_null<cir::FuncOp>(cgm.
getGlobalValue(mangledName));
300void CIRGenItaniumCXXABI::emitCXXStructor(GlobalDecl gd) {
303 const auto *cd = dyn_cast<CXXConstructorDecl>(md);
307 GlobalDecl baseDecl =
311 if (cirGenType == StructorCIRGen::Alias ||
312 cirGenType == StructorCIRGen::COMDAT) {
317 if (cirGenType == StructorCIRGen::RAUW) {
318 StringRef mangledName = cgm.getMangledName(gd);
319 mlir::Operation *aliasee = cgm.getAddrOfGlobal(baseDecl);
320 cgm.addReplacement(mangledName, aliasee);
325 auto fn = cgm.codegenCXXStructor(gd);
327 cgm.maybeSetTrivialComdat(*md, fn);
330void CIRGenItaniumCXXABI::addImplicitStructorParams(CIRGenFunction &cgf,
332 FunctionArgList ¶ms) {
337 if (needsVTTParameter(cgf.
curGD)) {
338 ASTContext &astContext = cgm.getASTContext();
344 astContext,
nullptr, md->getLocation(),
345 &astContext.
Idents.
get(
"vtt"), t, ImplicitParamKind::CXXVTT);
346 params.insert(params.begin() + 1, vttDecl);
347 getStructorImplicitParamDecl(cgf) = vttDecl;
351void CIRGenItaniumCXXABI::emitCXXConstructors(
const CXXConstructorDecl *d) {
353 assert(cgm.getTarget().getCXXABI().hasConstructorVariants());
357 cgm.emitGlobal(GlobalDecl(d,
Ctor_Base));
367void CIRGenItaniumCXXABI::emitCXXDestructors(
const CXXDestructorDecl *d) {
370 cgm.emitGlobal(GlobalDecl(d,
Dtor_Base));
383CIRGenCXXABI::AddedStructorArgs CIRGenItaniumCXXABI::getImplicitConstructorArgs(
385 bool forVirtualBase,
bool delegating) {
386 if (!needsVTTParameter(GlobalDecl(d,
type)))
387 return AddedStructorArgs{};
395 cgm.getASTContext().getPointerType(cgm.getASTContext().VoidPtrTy);
397 return AddedStructorArgs::withPrefix({{vtt, vttTy}});
403bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
407 if (!md->getParent()->getNumVBases())
421void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt,
422 const CXXRecordDecl *rd) {
423 cir::GlobalOp vtable = getAddrOfVTable(rd, CharUnits());
424 if (vtable.hasInitializer())
427 ItaniumVTableContext &vtContext = cgm.getItaniumVTableContext();
429 cir::GlobalLinkageKind linkage = cgm.getVTableLinkage(rd);
430 mlir::Attribute rtti =
431 cgm.getAddrOfRTTIDescriptor(cgm.getLoc(rd->
getBeginLoc()),
432 cgm.getASTContext().getCanonicalTagType(rd));
441 vtable.setLinkage(linkage);
444 vtable.setComdat(
true);
447 cgm.setGVProperties(vtable, rd);
459 "emitVTableDefinitions: __fundamental_type_info");
462 auto vtableAsGlobalValue = dyn_cast<cir::CIRGlobalValueInterface>(*vtable);
463 assert(vtableAsGlobalValue &&
"VTable must support CIRGlobalValueInterface");
471 if (cgm.getCodeGenOpts().WholeProgramVTables) {
473 "emitVTableDefinitions: WholeProgramVTables");
482mlir::Value CIRGenItaniumCXXABI::emitVirtualDestructorCall(
483 CIRGenFunction &cgf,
const CXXDestructorDecl *dtor,
CXXDtorType dtorType,
484 Address thisAddr, DeleteOrMemberCallExpr
expr) {
485 auto *
callExpr = dyn_cast<const CXXMemberCallExpr *>(
expr);
486 auto *delExpr = dyn_cast<const CXXDeleteExpr *>(
expr);
487 assert((
callExpr !=
nullptr) ^ (delExpr !=
nullptr));
491 GlobalDecl globalDecl(dtor, dtorType);
492 const CIRGenFunctionInfo *fnInfo =
493 &cgm.getTypes().arrangeCXXStructorDeclaration(globalDecl);
494 const cir::FuncType &fnTy = cgm.getTypes().getFunctionType(*fnInfo);
501 thisTy,
nullptr, QualType(),
nullptr);
505void CIRGenItaniumCXXABI::emitVirtualInheritanceTables(
506 const CXXRecordDecl *rd) {
507 CIRGenVTables &vtables = cgm.getVTables();
513class CIRGenItaniumRTTIBuilder {
515 const CIRGenItaniumCXXABI &cxxABI;
518 SmallVector<mlir::Attribute, 16> fields;
521 cir::GlobalOp getAddrOfTypeName(mlir::Location loc, QualType ty,
522 cir::GlobalLinkageKind linkage);
525 mlir::Attribute getAddrOfExternalRTTIDescriptor(mlir::Location loc,
529 void buildVTablePointer(mlir::Location loc,
const Type *ty);
533 void buildSIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
538 void buildVMIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
541 CIRGenItaniumRTTIBuilder(
const CIRGenItaniumCXXABI &abi, CIRGenModule &cgm)
542 : cgm(cgm), cxxABI(abi) {}
546 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty);
549 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty,
550 cir::GlobalLinkageKind linkage,
551 mlir::SymbolTable::Visibility visibility);
570 PTI_Incomplete = 0x8,
574 PTI_ContainingClassIncomplete = 0x10,
586 VMI_NonDiamondRepeat = 0x1,
589 VMI_DiamondShaped = 0x2
604static bool typeInfoIsInStandardLibrary(
const BuiltinType *ty) {
620 case BuiltinType::WasmExternRef:
621 case BuiltinType::HLSLResource:
622 llvm_unreachable(
"NYI");
623 case BuiltinType::Void:
624 case BuiltinType::NullPtr:
625 case BuiltinType::Bool:
626 case BuiltinType::WChar_S:
627 case BuiltinType::WChar_U:
628 case BuiltinType::Char_U:
629 case BuiltinType::Char_S:
630 case BuiltinType::UChar:
631 case BuiltinType::SChar:
632 case BuiltinType::Short:
633 case BuiltinType::UShort:
634 case BuiltinType::Int:
635 case BuiltinType::UInt:
636 case BuiltinType::Long:
637 case BuiltinType::ULong:
638 case BuiltinType::LongLong:
639 case BuiltinType::ULongLong:
640 case BuiltinType::Half:
641 case BuiltinType::Float:
642 case BuiltinType::Double:
643 case BuiltinType::LongDouble:
644 case BuiltinType::Float16:
645 case BuiltinType::Float128:
646 case BuiltinType::Ibm128:
647 case BuiltinType::Char8:
648 case BuiltinType::Char16:
649 case BuiltinType::Char32:
650 case BuiltinType::Int128:
651 case BuiltinType::UInt128:
654#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
655 case BuiltinType::Id:
656#include "clang/Basic/OpenCLImageTypes.def"
657#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
658#include "clang/Basic/OpenCLExtensionTypes.def"
659 case BuiltinType::OCLSampler:
660 case BuiltinType::OCLEvent:
661 case BuiltinType::OCLClkEvent:
662 case BuiltinType::OCLQueue:
663 case BuiltinType::OCLReserveID:
664#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
665#include "clang/Basic/AArch64ACLETypes.def"
666#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
667#include "clang/Basic/PPCTypes.def"
668#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
669#include "clang/Basic/RISCVVTypes.def"
670#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
671#include "clang/Basic/AMDGPUTypes.def"
672 case BuiltinType::ShortAccum:
673 case BuiltinType::Accum:
674 case BuiltinType::LongAccum:
675 case BuiltinType::UShortAccum:
676 case BuiltinType::UAccum:
677 case BuiltinType::ULongAccum:
678 case BuiltinType::ShortFract:
679 case BuiltinType::Fract:
680 case BuiltinType::LongFract:
681 case BuiltinType::UShortFract:
682 case BuiltinType::UFract:
683 case BuiltinType::ULongFract:
684 case BuiltinType::SatShortAccum:
685 case BuiltinType::SatAccum:
686 case BuiltinType::SatLongAccum:
687 case BuiltinType::SatUShortAccum:
688 case BuiltinType::SatUAccum:
689 case BuiltinType::SatULongAccum:
690 case BuiltinType::SatShortFract:
691 case BuiltinType::SatFract:
692 case BuiltinType::SatLongFract:
693 case BuiltinType::SatUShortFract:
694 case BuiltinType::SatUFract:
695 case BuiltinType::SatULongFract:
696 case BuiltinType::BFloat16:
699 case BuiltinType::Dependent:
700#define BUILTIN_TYPE(Id, SingletonId)
701#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
702#include "clang/AST/BuiltinTypes.def"
703 llvm_unreachable(
"asking for RRTI for a placeholder type!");
705 case BuiltinType::ObjCId:
706 case BuiltinType::ObjCClass:
707 case BuiltinType::ObjCSel:
708 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
711 llvm_unreachable(
"Invalid BuiltinType Kind!");
714static bool typeInfoIsInStandardLibrary(
const PointerType *pointerTy) {
716 const auto *builtinTy = dyn_cast<BuiltinType>(pointeeTy);
727 return typeInfoIsInStandardLibrary(builtinTy);
732static bool isStandardLibraryRttiDescriptor(QualType ty) {
734 if (
const auto *builtinTy = dyn_cast<BuiltinType>(ty))
735 return typeInfoIsInStandardLibrary(builtinTy);
739 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
740 return typeInfoIsInStandardLibrary(pointerTy);
749static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
757 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
770 bool isDLLImport = rd->
hasAttr<DLLImportAttr>();
780 return !isDLLImport || cgm.
getTriple().isWindowsItaniumEnvironment();
793 llvm::SmallPtrSet<const CXXRecordDecl *, 16> nonVirtualBases;
794 llvm::SmallPtrSet<const CXXRecordDecl *, 16> virtualBases;
799static unsigned computeVmiClassTypeInfoFlags(
const CXXBaseSpecifier *base,
807 if (!bases.virtualBases.insert(baseDecl).second) {
810 flags |= VMI_DiamondShaped;
812 if (bases.nonVirtualBases.count(baseDecl))
813 flags |= VMI_NonDiamondRepeat;
817 if (!bases.nonVirtualBases.insert(baseDecl).second) {
820 flags |= VMI_NonDiamondRepeat;
822 if (bases.virtualBases.count(baseDecl))
823 flags |= VMI_NonDiamondRepeat;
828 for (
const auto &bs : baseDecl->bases())
829 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
834static unsigned computeVmiClassTypeInfoFlags(
const CXXRecordDecl *rd) {
839 for (
const auto &bs : rd->
bases())
840 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
849static bool canUseSingleInheritance(
const CXXRecordDecl *rd) {
867 return baseDecl->isEmpty() ||
872static bool isIncompleteClassType(
const RecordType *recordTy) {
873 return !recordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
887static bool containsIncompleteClassType(QualType ty) {
888 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
889 if (isIncompleteClassType(recordTy))
893 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
896 if (
const auto *memberPointerTy = dyn_cast<MemberPointerType>(ty)) {
898 if (!memberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
901 return containsIncompleteClassType(memberPointerTy->getPointeeType());
907const char *vTableClassNameForType(
const CIRGenModule &cgm,
const Type *ty) {
909 static const char *
const classTypeInfo =
910 "_ZTVN10__cxxabiv117__class_type_infoE";
912 static const char *
const siClassTypeInfo =
913 "_ZTVN10__cxxabiv120__si_class_type_infoE";
915 static const char *
const vmiClassTypeInfo =
916 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
919#define TYPE(Class, Base)
920#define ABSTRACT_TYPE(Class, Base)
921#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
922#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
923#define DEPENDENT_TYPE(Class, Base) case Type::Class:
924#include "clang/AST/TypeNodes.inc"
925 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
927 case Type::LValueReference:
928 case Type::RValueReference:
929 llvm_unreachable(
"References shouldn't get here");
932 case Type::DeducedTemplateSpecialization:
933 llvm_unreachable(
"Undeduced type shouldn't get here");
936 llvm_unreachable(
"Pipe types shouldn't get here");
938 case Type::ArrayParameter:
939 llvm_unreachable(
"Array Parameter types should not get here.");
945 case Type::ExtVector:
946 case Type::ConstantMatrix:
950 case Type::BlockPointer:
951 return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
952 case Type::ConstantArray:
953 case Type::IncompleteArray:
954 case Type::VariableArray:
955 cgm.
errorNYI(
"VTableClassNameForType: __array_type_info");
958 case Type::FunctionNoProto:
959 case Type::FunctionProto:
960 cgm.
errorNYI(
"VTableClassNameForType: __function_type_info");
964 return "_ZTVN10__cxxabiv116__enum_type_infoE";
968 ->getDefinitionOrSelf();
971 return classTypeInfo;
974 if (canUseSingleInheritance(rd)) {
975 return siClassTypeInfo;
978 return vmiClassTypeInfo;
981 case Type::ObjCObject:
982 cgm.
errorNYI(
"VTableClassNameForType: ObjCObject");
985 case Type::ObjCInterface:
986 cgm.
errorNYI(
"VTableClassNameForType: ObjCInterface");
989 case Type::ObjCObjectPointer:
991 cgm.
errorNYI(
"VTableClassNameForType: __pointer_type_info");
994 case Type::MemberPointer:
995 cgm.
errorNYI(
"VTableClassNameForType: __pointer_to_member_type_info");
998 case Type::HLSLAttributedResource:
999 case Type::HLSLInlineSpirv:
1000 llvm_unreachable(
"HLSL doesn't support virtual functions");
1019 if (containsIncompleteClassType(ty))
1020 return cir::GlobalLinkageKind::InternalLinkage;
1024 llvm_unreachable(
"Linkage hasn't been computed!");
1029 return cir::GlobalLinkageKind::InternalLinkage;
1037 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1039 if (
const RecordType *record = dyn_cast<RecordType>(ty)) {
1043 return cir::GlobalLinkageKind::WeakODRLinkage;
1045 if (cgm.
getTriple().isWindowsItaniumEnvironment())
1046 if (rd->
hasAttr<DLLImportAttr>() &&
1047 shouldUseExternalRttiDescriptor(cgm, ty))
1048 return cir::GlobalLinkageKind::ExternalLinkage;
1054 .isWindowsGNUEnvironment())
1058 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1061 llvm_unreachable(
"Invalid linkage!");
1065CIRGenItaniumRTTIBuilder::getAddrOfTypeName(mlir::Location loc, QualType ty,
1066 cir::GlobalLinkageKind linkage) {
1068 SmallString<256>
name;
1069 llvm::raw_svector_ostream
out(name);
1075 mlir::Attribute init = builder.
getString(
1088 loc, name, initStr.getType(), linkage, align);
1094CIRGenItaniumRTTIBuilder::getAddrOfExternalRTTIDescriptor(mlir::Location loc,
1097 SmallString<256>
name;
1098 llvm::raw_svector_ostream
out(name);
1103 cir::GlobalOp gv = dyn_cast_or_null<cir::GlobalOp>(
1104 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1119 cgm.
errorNYI(
"getAddrOfExternalRTTIDescriptor: hasPS4DLLImportExport");
1126void CIRGenItaniumRTTIBuilder::buildVTablePointer(mlir::Location loc,
1129 const char *vTableName = vTableClassNameForType(cgm, ty);
1133 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1140 loc, vTableName, vtableGlobalTy, cir::GlobalLinkageKind::ExternalLinkage,
1144 mlir::Attribute field{};
1146 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1148 SmallVector<mlir::Attribute, 4> offsets{
1150 auto indices = mlir::ArrayAttr::get(builder.getContext(), offsets);
1155 assert(field &&
"expected attribute");
1156 fields.push_back(field);
1161void CIRGenItaniumRTTIBuilder::buildSIClassTypeInfo(mlir::Location loc,
1162 const CXXRecordDecl *rd) {
1166 mlir::Attribute baseTypeInfo =
1167 CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1169 fields.push_back(baseTypeInfo);
1175void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc,
1176 const CXXRecordDecl *rd) {
1177 mlir::Type unsignedIntLTy =
1184 unsigned flags = computeVmiClassTypeInfoFlags(rd);
1185 fields.push_back(cir::IntAttr::get(unsignedIntLTy, flags));
1190 fields.push_back(cir::IntAttr::get(unsignedIntLTy, rd->
getNumBases()));
1223 mlir::Type offsetFlagsLTy = cgm.
convertType(offsetFlagsTy);
1225 for (
const CXXBaseSpecifier &base : rd->
bases()) {
1227 fields.push_back(CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1228 .buildTypeInfo(loc, base.
getType()));
1242 const ASTRecordLayout &layout =
1251 offsetFlags |= BCTI_Virtual;
1253 offsetFlags |= BCTI_Public;
1255 fields.push_back(cir::IntAttr::get(offsetFlagsLTy, offsetFlags));
1259mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(mlir::Location loc,
1265 SmallString<256>
name;
1266 llvm::raw_svector_ostream
out(name);
1269 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1270 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1272 if (oldGV && !oldGV.isDeclaration()) {
1273 assert(!oldGV.hasAvailableExternallyLinkage() &&
1274 "available_externally typeinfos not yet implemented");
1280 if (isStandardLibraryRttiDescriptor(ty) ||
1281 shouldUseExternalRttiDescriptor(cgm, ty))
1282 return getAddrOfExternalRTTIDescriptor(loc, ty);
1292 mlir::SymbolTable::Visibility symVisibility;
1295 symVisibility = mlir::SymbolTable::Visibility::Public;
1296 else if (cxxABI.classifyRTTIUniqueness(ty, linkage) ==
1297 CIRGenItaniumCXXABI::RUK_NonUniqueHidden) {
1299 "buildTypeInfo: classifyRTTIUniqueness == RUK_NonUniqueHidden");
1304 return buildTypeInfo(loc, ty, linkage, symVisibility);
1307mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
1308 mlir::Location loc, QualType ty, cir::GlobalLinkageKind linkage,
1309 mlir::SymbolTable::Visibility visibility) {
1318 cir::GlobalOp typeName = getAddrOfTypeName(loc, ty, linkage);
1319 mlir::Attribute typeNameField;
1323 CIRGenItaniumCXXABI::RTTIUniquenessKind rttiUniqueness =
1324 cxxABI.classifyRTTIUniqueness(ty, linkage);
1325 if (rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique) {
1329 "buildTypeInfo: rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique");
1335 fields.push_back(typeNameField);
1338#define TYPE(Class, Base)
1339#define ABSTRACT_TYPE(Class, Base)
1340#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1341#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1342#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1343#include "clang/AST/TypeNodes.inc"
1344 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1349 case Type::ExtVector:
1350 case Type::ConstantMatrix:
1352 case Type::BlockPointer:
1357 case Type::LValueReference:
1358 case Type::RValueReference:
1359 llvm_unreachable(
"References shouldn't get here");
1362 case Type::DeducedTemplateSpecialization:
1363 llvm_unreachable(
"Undeduced type shouldn't get here");
1371 case Type::ConstantArray:
1372 case Type::IncompleteArray:
1373 case Type::VariableArray:
1374 case Type::ArrayParameter:
1379 case Type::FunctionNoProto:
1380 case Type::FunctionProto:
1390 case Type::Record: {
1392 ->getDefinitionOrSelf();
1398 if (canUseSingleInheritance(rd)) {
1399 buildSIClassTypeInfo(loc, rd);
1401 buildVMIClassTypeInfo(loc, rd);
1407 case Type::ObjCObject:
1408 case Type::ObjCInterface:
1409 cgm.
errorNYI(
"buildTypeInfo: ObjCObject & ObjCInterface");
1412 case Type::ObjCObjectPointer:
1413 cgm.
errorNYI(
"buildTypeInfo: ObjCObjectPointer");
1417 cgm.
errorNYI(
"buildTypeInfo: Pointer");
1420 case Type::MemberPointer:
1421 cgm.
errorNYI(
"buildTypeInfo: MemberPointer");
1428 case Type::HLSLAttributedResource:
1429 case Type::HLSLInlineSpirv:
1430 llvm_unreachable(
"HLSL doesn't support RTTI");
1434 cir::TypeInfoAttr init = builder.
getTypeInfo(builder.getArrayAttr(fields));
1436 SmallString<256>
name;
1437 llvm::raw_svector_ostream
out(name);
1441 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1442 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1451 cgm.
errorNYI(
"buildTypeInfo: target hasPS4DLLImportExport");
1458 gv.setName(oldGV.getName());
1459 if (!oldGV->use_empty()) {
1460 cgm.
errorNYI(
"buildTypeInfo: old GV !use_empty");
1468 cgm.
errorNYI(
"buildTypeInfo: supportsCOMDAT & isWeakForLinker");
1474 gv.setAlignmentAttr(cgm.
getSize(align));
1491 mlir::SymbolTable::setSymbolVisibility(typeName, visibility);
1496 mlir::SymbolTable::setSymbolVisibility(gv, visibility);
1505mlir::Attribute CIRGenItaniumCXXABI::getAddrOfRTTIDescriptor(mlir::Location loc,
1507 return CIRGenItaniumRTTIBuilder(*
this, cgm).buildTypeInfo(loc, ty);
1512CIRGenItaniumCXXABI::RTTIUniquenessKind
1513CIRGenItaniumCXXABI::classifyRTTIUniqueness(
1514 QualType canTy, cir::GlobalLinkageKind linkage)
const {
1515 if (shouldRTTIBeUnique())
1519 if (linkage != cir::GlobalLinkageKind::LinkOnceODRLinkage &&
1520 linkage != cir::GlobalLinkageKind::WeakODRLinkage)
1528 if (linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage)
1529 return RUK_NonUniqueHidden;
1534 assert(linkage == cir::GlobalLinkageKind::WeakODRLinkage);
1535 return RUK_NonUniqueVisible;
1538void CIRGenItaniumCXXABI::emitDestructorCall(
1540 bool forVirtualBase,
bool delegating, Address thisAddr, QualType thisTy) {
1541 GlobalDecl gd(dd,
type);
1547 CIRGenCallee callee =
1554void CIRGenItaniumCXXABI::registerGlobalDtor(
const VarDecl *vd,
1575mlir::Value CIRGenItaniumCXXABI::getCXXDestructorImplicitParam(
1577 bool forVirtualBase,
bool delegating) {
1578 GlobalDecl gd(dd,
type);
1586 mlir::Value exceptionPtr = {},
1587 mlir::FlatSymbolRefAttr typeInfo = {},
1588 mlir::FlatSymbolRefAttr dtor = {}) {
1589 mlir::Block *currentBlock = builder.getInsertionBlock();
1590 mlir::Region *region = currentBlock->getParent();
1592 if (currentBlock->empty()) {
1593 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1594 cir::UnreachableOp::create(builder, loc);
1596 mlir::Block *throwBlock = builder.createBlock(region);
1598 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1599 cir::UnreachableOp::create(builder, loc);
1601 builder.setInsertionPointToEnd(currentBlock);
1602 cir::BrOp::create(builder, loc, throwBlock);
1605 (void)builder.createBlock(region);
1608void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf,
bool isNoReturn) {
1612 assert(cgf.
currSrcLoc &&
"expected source location");
1616 cgm.
errorNYI(
"emitRethrow with isNoReturn false");
1620void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf,
1621 const CXXThrowExpr *e) {
1629 cir::PointerType throwTy =
1636 mlir::TypedValue<cir::PointerType> exceptionPtr =
1637 cir::AllocExceptionOp::create(builder, subExprLoc, throwTy,
1638 builder.getI64IntegerAttr(typeSize))
1646 auto typeInfo = mlir::cast<cir::GlobalViewAttr>(
1649 assert(!typeInfo.getIndices() &&
"expected no indirection");
1658 if (
const RecordType *recordTy = clangThrowType->
getAs<RecordType>()) {
1661 if (!rec->hasTrivialDestructor()) {
1662 cgm.
errorNYI(
"emitThrow: non-trivial destructor");
1674 case TargetCXXABI::GenericItanium:
1675 case TargetCXXABI::GenericAArch64:
1676 return new CIRGenItaniumCXXABI(cgm);
1678 case TargetCXXABI::AppleARM64:
1682 return new CIRGenItaniumCXXABI(cgm);
1685 llvm_unreachable(
"bad or NYI ABI kind");
1689cir::GlobalOp CIRGenItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *rd,
1691 assert(vptrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1692 cir::GlobalOp &vtable = vtables[rd];
1700 llvm::raw_svector_ostream
out(name);
1701 getMangleContext().mangleCXXVTable(rd,
out);
1716 cir::GlobalLinkageKind::ExternalLinkage,
1730 "getAddrOfVTable: PS4 DLL import/export");
1736CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer(
1740 mlir::Location loc = cgf.
getLoc(srcLoc);
1743 mlir::Value vtable = cgf.
getVTablePtr(loc, thisAddr, methodDecl->getParent());
1746 mlir::Value vfunc{};
1748 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: emitVTableTypeCheckedLoad");
1752 mlir::Value vfuncLoad;
1755 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: isRelativeLayout");
1757 auto vtableSlotPtr = cir::VTableGetVirtualFnAddrOp::create(
1758 builder, loc, builder.
getPointerTo(tyPtr), vtable, vtableIndex);
1771 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: strictVTablePointers");
1776 CIRGenCallee callee(gd, vfunc.getDefiningOp());
1780mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1781 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
1782 const CXXRecordDecl *nearestVBase) {
1784 needsVTTParameter(cgf.
curGD) &&
"This class doesn't have VTT");
1795 virtualPointerIndex);
1797 auto vptrType = cir::VPtrType::get(cgf.
getBuilder().getContext());
1803CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject base,
1804 const CXXRecordDecl *vtableClass) {
1805 cir::GlobalOp vtable = getAddrOfVTable(vtableClass, CharUnits());
1809 VTableLayout::AddressPointLocation addressPoint =
1815 auto vtablePtrTy = cir::VPtrType::get(builder.getContext());
1817 return cir::VTableAddrPointOp::create(
1819 mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()),
1820 cir::AddressPointAttr::get(cgm.
getBuilder().getContext(),
1825mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor(
1826 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
1827 clang::BaseSubobject base,
const clang::CXXRecordDecl *nearestVBase) {
1830 needsVTTParameter(cgf.
curGD)) {
1831 return getVTableAddressPointInStructorWithVTT(cgf, vtableClass, base,
1834 return getVTableAddressPoint(base, vtableClass);
1837bool CIRGenItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1838 CIRGenFunction &cgf, CIRGenFunction::VPtr vptr) {
1841 return needsVTTParameter(cgf.
curGD);
1844mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(
1845 mlir::Location loc, CIRGenFunction &cgf, Address thisAddr,
1846 const CXXRecordDecl *classDecl,
const CXXRecordDecl *baseClassDecl) {
1848 mlir::Value vtablePtr = cgf.
getVTablePtr(loc, thisAddr, classDecl);
1850 CharUnits vbaseOffsetOffset =
1853 mlir::Value offsetVal =
1855 auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.
uInt8PtrTy,
1856 vtableBytePtr, offsetVal);
1858 mlir::Value vbaseOffset;
1861 cgm.
errorNYI(loc,
"getVirtualBaseClassOffset: relative layout");
1877 cir::FuncType fnTy =
1887 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
1891void CIRGenItaniumCXXABI::emitBadCastCall(CIRGenFunction &cgf,
1892 mlir::Location loc) {
1905 if (!dst->isDerivedFrom(src, paths))
1908 unsigned numPublicPaths = 0;
1921 if (pathElement.Base->isVirtual())
1924 if (numPublicPaths > 1)
1931 pathElement.Base->getType()->getAsCXXRecordDecl());
1936 if (numPublicPaths == 0)
1940 if (numPublicPaths > 1)
1968 {voidPtrTy, rttiPtrTy, rttiPtrTy, ptrDiffTy}, voidPtrTy);
1974 bool vtableUsesRelativeLayout =
1977 loc, src.
getPointer(), vtableUsesRelativeLayout);
1985 cir::PointerType destCIRTy,
1986 bool isRefCast,
Address src) {
1996 std::optional<CharUnits> offset;
2006 pathElement.Base->getType()->getAsCXXRecordDecl();
2007 if (pathElement.Base->isVirtual()) {
2021 offset = pathOffset;
2022 }
else if (offset != pathOffset) {
2038 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2040 mlir::Region *currentRegion = builder.getBlock()->getParent();
2045 builder.createBlock(currentRegion, currentRegion->end());
2048 return nullPtrValue;
2056 mlir::Value expectedVPtr =
2057 abi.getVTableAddressPoint(
BaseSubobject(srcDecl, *offset), destDecl);
2061 mlir::Type vptrTy = expectedVPtr.getType();
2065 mlir::Value srcVPtr = builder.
createLoad(loc, srcVPtrPtr);
2070 mlir::Value success =
2071 builder.
createCompare(loc, cir::CmpOpKind::eq, srcVPtr, expectedVPtr);
2073 auto emitCastResult = [&] {
2074 if (offset->isZero())
2081 mlir::Value strideToApply =
2084 mlir::Value resultU8Ptr = cir::PtrStrideOp::create(builder, loc, u8PtrTy,
2085 srcU8Ptr, strideToApply);
2090 mlir::Value failed = builder.
createNot(success);
2091 cir::IfOp::create(builder, loc, failed,
false,
2092 [&](mlir::OpBuilder &, mlir::Location) {
2095 return emitCastResult();
2098 return cir::TernaryOp::create(
2099 builder, loc, success,
2100 [&](mlir::OpBuilder &, mlir::Location) {
2101 auto result = emitCastResult();
2104 [&](mlir::OpBuilder &, mlir::Location) {
2105 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2115 auto srcRtti = mlir::cast<cir::GlobalViewAttr>(
2117 auto destRtti = mlir::cast<cir::GlobalViewAttr>(
2122 auto runtimeFuncRef = mlir::FlatSymbolRefAttr::get(runtimeFuncOp);
2123 auto badCastFuncRef = mlir::FlatSymbolRefAttr::get(badCastFuncOp);
2130 auto offsetHintAttr = cir::IntAttr::get(ptrdiffTy, offsetHint.
getQuantity());
2132 return cir::DynamicCastInfoAttr::get(srcRtti, destRtti, runtimeFuncRef,
2133 badCastFuncRef, offsetHintAttr);
2136mlir::Value CIRGenItaniumCXXABI::emitDynamicCast(CIRGenFunction &cgf,
2138 QualType srcRecordTy,
2139 QualType destRecordTy,
2140 cir::PointerType destCIRTy,
2141 bool isRefCast, Address src) {
2142 bool isCastToVoid = destRecordTy.
isNull();
2143 assert((!isCastToVoid || !isRefCast) &&
"cannot cast to void reference");
2156 return cir::TernaryOp::create(
2157 builder, loc, srcPtrIsNull,
2158 [&](mlir::OpBuilder, mlir::Location) {
2160 loc, builder.
getNullPtr(destCIRTy, loc).getResult());
2162 [&](mlir::OpBuilder &, mlir::Location) {
2164 *
this, cgf, loc, srcRecordTy, destRecordTy, destCIRTy,
2172 destCIRTy, isRefCast, src);
2175 cir::DynamicCastInfoAttr castInfo =
2178 isRefCast, castInfo);
2183void CIRGenItaniumCXXABI::emitVirtualObjectDelete(
2184 CIRGenFunction &cgf,
const CXXDeleteExpr *delExpr, Address ptr,
2185 QualType elementType,
const CXXDestructorDecl *dtor) {
2187 if (useGlobalDelete) {
2189 "emitVirtualObjectDelete: global delete");
2193 emitVirtualDestructorCall(cgf, dtor, dtorType, ptr, delExpr);
2198CharUnits CIRGenItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2206Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf,
2208 mlir::Value numElements,
2209 const CXXNewExpr *e,
2210 QualType elementType) {
2211 assert(requiresArrayCookie(e));
2223 CharUnits cookieSize =
2225 assert(cookieSize == getArrayCookieSizeImpl(elementType));
2228 mlir::Value baseBytePtr =
2232 CharUnits cookieOffset = cookieSize - sizeSize;
2233 mlir::Value cookiePtrValue = baseBytePtr;
2234 if (!cookieOffset.
isZero()) {
2243 Address cookiePtr(cookiePtrValue, u8PtrTy, cookiePtrAlignment);
2246 Address numElementsPtr =
2252 mlir::Value dataOffset =
2255 mlir::Value dataPtr =
2257 mlir::Value finalPtr =
2260 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.
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)
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
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)
CIRGenCXXABI & getCXXABI() const
CIRGenVTables & getVTables()
cir::GlobalLinkageKind getVTableLinkage(const CXXRecordDecl *rd)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
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.
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
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