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 void emitCXXConstructors(
const clang::CXXConstructorDecl *d)
override;
64 void emitCXXDestructors(
const clang::CXXDestructorDecl *d)
override;
65 void emitCXXStructor(clang::GlobalDecl gd)
override;
67 void emitDestructorCall(CIRGenFunction &cgf,
const CXXDestructorDecl *dd,
69 bool delegating, Address thisAddr,
70 QualType thisTy)
override;
72 void emitRethrow(CIRGenFunction &cgf,
bool isNoReturn)
override;
74 bool useThunkForDtorVariant(
const CXXDestructorDecl *dtor,
82 bool isVirtualOffsetNeededForVTableField(CIRGenFunction &cgf,
83 CIRGenFunction::VPtr vptr)
override;
85 cir::GlobalOp getAddrOfVTable(
const CXXRecordDecl *rd,
86 CharUnits vptrOffset)
override;
87 CIRGenCallee getVirtualFunctionPointer(CIRGenFunction &cgf,
88 clang::GlobalDecl gd, Address thisAddr,
90 SourceLocation loc)
override;
92 mlir::Value getVTableAddressPoint(BaseSubobject base,
93 const CXXRecordDecl *vtableClass)
override;
94 mlir::Value getVTableAddressPointInStructorWithVTT(
95 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
96 const CXXRecordDecl *nearestVBase);
98 mlir::Value getVTableAddressPointInStructor(
99 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
100 clang::BaseSubobject base,
101 const clang::CXXRecordDecl *nearestVBase)
override;
102 void emitVTableDefinitions(CIRGenVTables &cgvt,
103 const CXXRecordDecl *rd)
override;
104 void emitVirtualInheritanceTables(
const CXXRecordDecl *rd)
override;
106 mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc,
107 QualType ty)
override;
109 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *vtableClass)
override {
114 getVirtualBaseClassOffset(mlir::Location loc, CIRGenFunction &cgf,
115 Address thisAddr,
const CXXRecordDecl *classDecl,
116 const CXXRecordDecl *baseClassDecl)
override;
122 virtual bool shouldRTTIBeUnique()
const {
return true; }
126 enum RTTIUniquenessKind {
144 classifyRTTIUniqueness(QualType canTy, cir::GlobalLinkageKind linkage)
const;
149void CIRGenItaniumCXXABI::emitInstanceFunctionProlog(
SourceLocation loc,
154 "emitInstanceFunctionProlog: Naked");
159 setCXXABIThisValue(cgf, loadIncomingCXXThis(cgf));
162 if (getStructorImplicitParamDecl(cgf)) {
166 setStructorImplicitParamValue(cgf, val);
177 if (hasThisReturn(cgf.
curGD)) {
179 "emitInstanceFunctionProlog: hasThisReturn");
183CIRGenCXXABI::AddedStructorArgCounts
184CIRGenItaniumCXXABI::buildStructorSignature(
185 GlobalDecl gd, llvm::SmallVectorImpl<CanQualType> &argTys) {
186 clang::ASTContext &astContext = cgm.getASTContext();
196 argTys.insert(argTys.begin() + 1,
199 return AddedStructorArgCounts::withPrefix(1);
202 return AddedStructorArgCounts{};
207enum class StructorCIRGen { Emit, RAUW, Alias, COMDAT };
213 return StructorCIRGen::Emit;
218 return StructorCIRGen::Emit;
221 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(md)) {
231 return StructorCIRGen::RAUW;
235 return StructorCIRGen::RAUW;
241 return StructorCIRGen::COMDAT;
242 return StructorCIRGen::Emit;
245 return StructorCIRGen::Alias;
255 auto globalValue = dyn_cast_or_null<cir::CIRGlobalValueInterface>(
257 if (globalValue && !globalValue.isDeclaration())
260 auto entry = cast_or_null<cir::FuncOp>(cgm.
getGlobalValue(mangledName));
269void CIRGenItaniumCXXABI::emitCXXStructor(GlobalDecl gd) {
272 const auto *cd = dyn_cast<CXXConstructorDecl>(md);
276 GlobalDecl baseDecl =
280 if (cirGenType == StructorCIRGen::Alias ||
281 cirGenType == StructorCIRGen::COMDAT) {
286 if (cirGenType == StructorCIRGen::RAUW) {
287 StringRef mangledName = cgm.getMangledName(gd);
288 mlir::Operation *aliasee = cgm.getAddrOfGlobal(baseDecl);
289 cgm.addReplacement(mangledName, aliasee);
294 auto fn = cgm.codegenCXXStructor(gd);
296 cgm.maybeSetTrivialComdat(*md, fn);
299void CIRGenItaniumCXXABI::addImplicitStructorParams(CIRGenFunction &cgf,
301 FunctionArgList ¶ms) {
306 if (needsVTTParameter(cgf.
curGD)) {
307 ASTContext &astContext = cgm.getASTContext();
313 astContext,
nullptr, md->getLocation(),
314 &astContext.
Idents.
get(
"vtt"), t, ImplicitParamKind::CXXVTT);
315 params.insert(params.begin() + 1, vttDecl);
316 getStructorImplicitParamDecl(cgf) = vttDecl;
320void CIRGenItaniumCXXABI::emitCXXConstructors(
const CXXConstructorDecl *d) {
322 assert(cgm.getTarget().getCXXABI().hasConstructorVariants());
326 cgm.emitGlobal(GlobalDecl(d,
Ctor_Base));
336void CIRGenItaniumCXXABI::emitCXXDestructors(
const CXXDestructorDecl *d) {
339 cgm.emitGlobal(GlobalDecl(d,
Dtor_Base));
352CIRGenCXXABI::AddedStructorArgs CIRGenItaniumCXXABI::getImplicitConstructorArgs(
354 bool forVirtualBase,
bool delegating) {
355 if (!needsVTTParameter(GlobalDecl(d,
type)))
356 return AddedStructorArgs{};
364 cgm.getASTContext().getPointerType(cgm.getASTContext().VoidPtrTy);
366 return AddedStructorArgs::withPrefix({{vtt, vttTy}});
372bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
376 if (!md->getParent()->getNumVBases())
390void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt,
391 const CXXRecordDecl *rd) {
392 cir::GlobalOp vtable = getAddrOfVTable(rd, CharUnits());
393 if (vtable.hasInitializer())
396 ItaniumVTableContext &vtContext = cgm.getItaniumVTableContext();
398 cir::GlobalLinkageKind linkage = cgm.getVTableLinkage(rd);
399 mlir::Attribute rtti =
400 cgm.getAddrOfRTTIDescriptor(cgm.getLoc(rd->
getBeginLoc()),
401 cgm.getASTContext().getCanonicalTagType(rd));
410 vtable.setLinkage(linkage);
413 vtable.setComdat(
true);
416 cgm.setGVProperties(vtable, rd);
428 "emitVTableDefinitions: __fundamental_type_info");
431 auto vtableAsGlobalValue = dyn_cast<cir::CIRGlobalValueInterface>(*vtable);
432 assert(vtableAsGlobalValue &&
"VTable must support CIRGlobalValueInterface");
440 if (cgm.getCodeGenOpts().WholeProgramVTables) {
442 "emitVTableDefinitions: WholeProgramVTables");
451void CIRGenItaniumCXXABI::emitVirtualInheritanceTables(
452 const CXXRecordDecl *rd) {
453 CIRGenVTables &vtables = cgm.getVTables();
459class CIRGenItaniumRTTIBuilder {
461 const CIRGenItaniumCXXABI &cxxABI;
464 SmallVector<mlir::Attribute, 16> fields;
467 cir::GlobalOp getAddrOfTypeName(mlir::Location loc, QualType ty,
468 cir::GlobalLinkageKind linkage);
471 mlir::Attribute getAddrOfExternalRTTIDescriptor(mlir::Location loc,
475 void buildVTablePointer(mlir::Location loc,
const Type *ty);
479 void buildSIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
484 void buildVMIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
487 CIRGenItaniumRTTIBuilder(
const CIRGenItaniumCXXABI &abi, CIRGenModule &cgm)
488 : cgm(cgm), cxxABI(abi) {}
492 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty);
495 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty,
496 cir::GlobalLinkageKind linkage,
497 mlir::SymbolTable::Visibility visibility);
516 PTI_Incomplete = 0x8,
520 PTI_ContainingClassIncomplete = 0x10,
532 VMI_NonDiamondRepeat = 0x1,
535 VMI_DiamondShaped = 0x2
550static bool typeInfoIsInStandardLibrary(
const BuiltinType *ty) {
566 case BuiltinType::WasmExternRef:
567 case BuiltinType::HLSLResource:
568 llvm_unreachable(
"NYI");
569 case BuiltinType::Void:
570 case BuiltinType::NullPtr:
571 case BuiltinType::Bool:
572 case BuiltinType::WChar_S:
573 case BuiltinType::WChar_U:
574 case BuiltinType::Char_U:
575 case BuiltinType::Char_S:
576 case BuiltinType::UChar:
577 case BuiltinType::SChar:
578 case BuiltinType::Short:
579 case BuiltinType::UShort:
580 case BuiltinType::Int:
581 case BuiltinType::UInt:
582 case BuiltinType::Long:
583 case BuiltinType::ULong:
584 case BuiltinType::LongLong:
585 case BuiltinType::ULongLong:
586 case BuiltinType::Half:
587 case BuiltinType::Float:
588 case BuiltinType::Double:
589 case BuiltinType::LongDouble:
590 case BuiltinType::Float16:
591 case BuiltinType::Float128:
592 case BuiltinType::Ibm128:
593 case BuiltinType::Char8:
594 case BuiltinType::Char16:
595 case BuiltinType::Char32:
596 case BuiltinType::Int128:
597 case BuiltinType::UInt128:
600#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
601 case BuiltinType::Id:
602#include "clang/Basic/OpenCLImageTypes.def"
603#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
604#include "clang/Basic/OpenCLExtensionTypes.def"
605 case BuiltinType::OCLSampler:
606 case BuiltinType::OCLEvent:
607 case BuiltinType::OCLClkEvent:
608 case BuiltinType::OCLQueue:
609 case BuiltinType::OCLReserveID:
610#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
611#include "clang/Basic/AArch64ACLETypes.def"
612#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
613#include "clang/Basic/PPCTypes.def"
614#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
615#include "clang/Basic/RISCVVTypes.def"
616#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
617#include "clang/Basic/AMDGPUTypes.def"
618 case BuiltinType::ShortAccum:
619 case BuiltinType::Accum:
620 case BuiltinType::LongAccum:
621 case BuiltinType::UShortAccum:
622 case BuiltinType::UAccum:
623 case BuiltinType::ULongAccum:
624 case BuiltinType::ShortFract:
625 case BuiltinType::Fract:
626 case BuiltinType::LongFract:
627 case BuiltinType::UShortFract:
628 case BuiltinType::UFract:
629 case BuiltinType::ULongFract:
630 case BuiltinType::SatShortAccum:
631 case BuiltinType::SatAccum:
632 case BuiltinType::SatLongAccum:
633 case BuiltinType::SatUShortAccum:
634 case BuiltinType::SatUAccum:
635 case BuiltinType::SatULongAccum:
636 case BuiltinType::SatShortFract:
637 case BuiltinType::SatFract:
638 case BuiltinType::SatLongFract:
639 case BuiltinType::SatUShortFract:
640 case BuiltinType::SatUFract:
641 case BuiltinType::SatULongFract:
642 case BuiltinType::BFloat16:
645 case BuiltinType::Dependent:
646#define BUILTIN_TYPE(Id, SingletonId)
647#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
648#include "clang/AST/BuiltinTypes.def"
649 llvm_unreachable(
"asking for RRTI for a placeholder type!");
651 case BuiltinType::ObjCId:
652 case BuiltinType::ObjCClass:
653 case BuiltinType::ObjCSel:
654 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
657 llvm_unreachable(
"Invalid BuiltinType Kind!");
660static bool typeInfoIsInStandardLibrary(
const PointerType *pointerTy) {
662 const auto *builtinTy = dyn_cast<BuiltinType>(pointeeTy);
673 return typeInfoIsInStandardLibrary(builtinTy);
678static bool isStandardLibraryRttiDescriptor(QualType ty) {
680 if (
const auto *builtinTy = dyn_cast<BuiltinType>(ty))
681 return typeInfoIsInStandardLibrary(builtinTy);
685 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
686 return typeInfoIsInStandardLibrary(pointerTy);
695static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
703 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
704 const CXXRecordDecl *rd =
716 bool isDLLImport = rd->
hasAttr<DLLImportAttr>();
726 return !isDLLImport || cgm.
getTriple().isWindowsItaniumEnvironment();
739 llvm::SmallPtrSet<const CXXRecordDecl *, 16> nonVirtualBases;
740 llvm::SmallPtrSet<const CXXRecordDecl *, 16> virtualBases;
745static unsigned computeVmiClassTypeInfoFlags(
const CXXBaseSpecifier *base,
753 if (!bases.virtualBases.insert(baseDecl).second) {
756 flags |= VMI_DiamondShaped;
758 if (bases.nonVirtualBases.count(baseDecl))
759 flags |= VMI_NonDiamondRepeat;
763 if (!bases.nonVirtualBases.insert(baseDecl).second) {
766 flags |= VMI_NonDiamondRepeat;
768 if (bases.virtualBases.count(baseDecl))
769 flags |= VMI_NonDiamondRepeat;
774 for (
const auto &bs : baseDecl->bases())
775 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
780static unsigned computeVmiClassTypeInfoFlags(
const CXXRecordDecl *rd) {
785 for (
const auto &bs : rd->
bases())
786 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
795static bool canUseSingleInheritance(
const CXXRecordDecl *rd) {
813 return baseDecl->isEmpty() ||
818static bool isIncompleteClassType(
const RecordType *recordTy) {
819 return !recordTy->getOriginalDecl()
820 ->getDefinitionOrSelf()
821 ->isCompleteDefinition();
835static bool containsIncompleteClassType(QualType ty) {
836 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
837 if (isIncompleteClassType(recordTy))
841 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
844 if (
const auto *memberPointerTy = dyn_cast<MemberPointerType>(ty)) {
846 if (!memberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
849 return containsIncompleteClassType(memberPointerTy->getPointeeType());
855const char *vTableClassNameForType(
const CIRGenModule &cgm,
const Type *ty) {
857 static const char *
const classTypeInfo =
858 "_ZTVN10__cxxabiv117__class_type_infoE";
860 static const char *
const siClassTypeInfo =
861 "_ZTVN10__cxxabiv120__si_class_type_infoE";
863 static const char *
const vmiClassTypeInfo =
864 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
867#define TYPE(Class, Base)
868#define ABSTRACT_TYPE(Class, Base)
869#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
870#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
871#define DEPENDENT_TYPE(Class, Base) case Type::Class:
872#include "clang/AST/TypeNodes.inc"
873 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
875 case Type::LValueReference:
876 case Type::RValueReference:
877 llvm_unreachable(
"References shouldn't get here");
880 case Type::DeducedTemplateSpecialization:
881 llvm_unreachable(
"Undeduced type shouldn't get here");
884 llvm_unreachable(
"Pipe types shouldn't get here");
886 case Type::ArrayParameter:
887 llvm_unreachable(
"Array Parameter types should not get here.");
893 case Type::ExtVector:
894 case Type::ConstantMatrix:
898 case Type::BlockPointer:
899 cgm.
errorNYI(
"VTableClassNameForType: __fundamental_type_info");
901 case Type::ConstantArray:
902 case Type::IncompleteArray:
903 case Type::VariableArray:
904 cgm.
errorNYI(
"VTableClassNameForType: __array_type_info");
907 case Type::FunctionNoProto:
908 case Type::FunctionProto:
909 cgm.
errorNYI(
"VTableClassNameForType: __function_type_info");
913 cgm.
errorNYI(
"VTableClassNameForType: Enum");
917 const CXXRecordDecl *rd =
919 ->getDefinitionOrSelf();
922 return classTypeInfo;
925 if (canUseSingleInheritance(rd)) {
926 return siClassTypeInfo;
929 return vmiClassTypeInfo;
932 case Type::ObjCObject:
933 cgm.
errorNYI(
"VTableClassNameForType: ObjCObject");
936 case Type::ObjCInterface:
937 cgm.
errorNYI(
"VTableClassNameForType: ObjCInterface");
940 case Type::ObjCObjectPointer:
942 cgm.
errorNYI(
"VTableClassNameForType: __pointer_type_info");
945 case Type::MemberPointer:
946 cgm.
errorNYI(
"VTableClassNameForType: __pointer_to_member_type_info");
949 case Type::HLSLAttributedResource:
950 case Type::HLSLInlineSpirv:
951 llvm_unreachable(
"HLSL doesn't support virtual functions");
970 if (containsIncompleteClassType(ty))
971 return cir::GlobalLinkageKind::InternalLinkage;
975 llvm_unreachable(
"Linkage hasn't been computed!");
980 return cir::GlobalLinkageKind::InternalLinkage;
988 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
990 if (
const RecordType *record = dyn_cast<RecordType>(ty)) {
994 return cir::GlobalLinkageKind::WeakODRLinkage;
996 if (cgm.
getTriple().isWindowsItaniumEnvironment())
997 if (rd->
hasAttr<DLLImportAttr>() &&
998 shouldUseExternalRttiDescriptor(cgm, ty))
999 return cir::GlobalLinkageKind::ExternalLinkage;
1005 .isWindowsGNUEnvironment())
1009 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1012 llvm_unreachable(
"Invalid linkage!");
1016CIRGenItaniumRTTIBuilder::getAddrOfTypeName(mlir::Location loc, QualType ty,
1017 cir::GlobalLinkageKind linkage) {
1019 SmallString<256>
name;
1020 llvm::raw_svector_ostream
out(name);
1026 mlir::Attribute init = builder.
getString(
1039 loc, name, initStr.getType(), linkage, align);
1045CIRGenItaniumRTTIBuilder::getAddrOfExternalRTTIDescriptor(mlir::Location loc,
1048 SmallString<256>
name;
1049 llvm::raw_svector_ostream
out(name);
1054 cir::GlobalOp gv = dyn_cast_or_null<cir::GlobalOp>(
1055 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1070 cgm.
errorNYI(
"getAddrOfExternalRTTIDescriptor: hasPS4DLLImportExport");
1077void CIRGenItaniumRTTIBuilder::buildVTablePointer(mlir::Location loc,
1080 const char *vTableName = vTableClassNameForType(cgm, ty);
1084 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1091 loc, vTableName, vtableGlobalTy, cir::GlobalLinkageKind::ExternalLinkage,
1095 mlir::Attribute field{};
1097 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1099 SmallVector<mlir::Attribute, 4> offsets{
1101 auto indices = mlir::ArrayAttr::get(builder.getContext(), offsets);
1106 assert(field &&
"expected attribute");
1107 fields.push_back(field);
1112void CIRGenItaniumRTTIBuilder::buildSIClassTypeInfo(mlir::Location loc,
1113 const CXXRecordDecl *rd) {
1117 mlir::Attribute baseTypeInfo =
1118 CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1120 fields.push_back(baseTypeInfo);
1126void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc,
1127 const CXXRecordDecl *rd) {
1128 mlir::Type unsignedIntLTy =
1135 unsigned flags = computeVmiClassTypeInfoFlags(rd);
1136 fields.push_back(cir::IntAttr::get(unsignedIntLTy, flags));
1141 fields.push_back(cir::IntAttr::get(unsignedIntLTy, rd->
getNumBases()));
1174 mlir::Type offsetFlagsLTy = cgm.
convertType(offsetFlagsTy);
1176 for (
const CXXBaseSpecifier &base : rd->
bases()) {
1178 fields.push_back(CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1179 .buildTypeInfo(loc, base.
getType()));
1193 const ASTRecordLayout &layout =
1202 offsetFlags |= BCTI_Virtual;
1204 offsetFlags |= BCTI_Public;
1206 fields.push_back(cir::IntAttr::get(offsetFlagsLTy, offsetFlags));
1210mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(mlir::Location loc,
1216 SmallString<256>
name;
1217 llvm::raw_svector_ostream
out(name);
1220 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1221 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1223 if (oldGV && !oldGV.isDeclaration()) {
1224 assert(!oldGV.hasAvailableExternallyLinkage() &&
1225 "available_externally typeinfos not yet implemented");
1231 if (isStandardLibraryRttiDescriptor(ty) ||
1232 shouldUseExternalRttiDescriptor(cgm, ty))
1233 return getAddrOfExternalRTTIDescriptor(loc, ty);
1243 mlir::SymbolTable::Visibility symVisibility;
1246 symVisibility = mlir::SymbolTable::Visibility::Public;
1247 else if (cxxABI.classifyRTTIUniqueness(ty, linkage) ==
1248 CIRGenItaniumCXXABI::RUK_NonUniqueHidden) {
1250 "buildTypeInfo: classifyRTTIUniqueness == RUK_NonUniqueHidden");
1255 return buildTypeInfo(loc, ty, linkage, symVisibility);
1258mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
1259 mlir::Location loc, QualType ty, cir::GlobalLinkageKind linkage,
1260 mlir::SymbolTable::Visibility visibility) {
1269 cir::GlobalOp typeName = getAddrOfTypeName(loc, ty, linkage);
1270 mlir::Attribute typeNameField;
1274 CIRGenItaniumCXXABI::RTTIUniquenessKind rttiUniqueness =
1275 cxxABI.classifyRTTIUniqueness(ty, linkage);
1276 if (rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique) {
1280 "buildTypeInfo: rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique");
1286 fields.push_back(typeNameField);
1289#define TYPE(Class, Base)
1290#define ABSTRACT_TYPE(Class, Base)
1291#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1292#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1293#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1294#include "clang/AST/TypeNodes.inc"
1295 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1300 case Type::ExtVector:
1301 case Type::ConstantMatrix:
1303 case Type::BlockPointer:
1308 case Type::LValueReference:
1309 case Type::RValueReference:
1310 llvm_unreachable(
"References shouldn't get here");
1313 case Type::DeducedTemplateSpecialization:
1314 llvm_unreachable(
"Undeduced type shouldn't get here");
1322 case Type::ConstantArray:
1323 case Type::IncompleteArray:
1324 case Type::VariableArray:
1325 case Type::ArrayParameter:
1330 case Type::FunctionNoProto:
1331 case Type::FunctionProto:
1341 case Type::Record: {
1344 ->getDefinitionOrSelf();
1350 if (canUseSingleInheritance(rd)) {
1351 buildSIClassTypeInfo(loc, rd);
1353 buildVMIClassTypeInfo(loc, rd);
1359 case Type::ObjCObject:
1360 case Type::ObjCInterface:
1361 cgm.
errorNYI(
"buildTypeInfo: ObjCObject & ObjCInterface");
1364 case Type::ObjCObjectPointer:
1365 cgm.
errorNYI(
"buildTypeInfo: ObjCObjectPointer");
1369 cgm.
errorNYI(
"buildTypeInfo: Pointer");
1372 case Type::MemberPointer:
1373 cgm.
errorNYI(
"buildTypeInfo: MemberPointer");
1380 case Type::HLSLAttributedResource:
1381 case Type::HLSLInlineSpirv:
1382 llvm_unreachable(
"HLSL doesn't support RTTI");
1386 cir::TypeInfoAttr init = builder.
getTypeInfo(builder.getArrayAttr(fields));
1388 SmallString<256>
name;
1389 llvm::raw_svector_ostream
out(name);
1393 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1394 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1403 cgm.
errorNYI(
"buildTypeInfo: target hasPS4DLLImportExport");
1410 gv.setName(oldGV.getName());
1411 if (!oldGV->use_empty()) {
1412 cgm.
errorNYI(
"buildTypeInfo: old GV !use_empty");
1420 cgm.
errorNYI(
"buildTypeInfo: supportsCOMDAT & isWeakForLinker");
1426 gv.setAlignmentAttr(cgm.
getSize(align));
1443 mlir::SymbolTable::setSymbolVisibility(typeName, visibility);
1448 mlir::SymbolTable::setSymbolVisibility(gv, visibility);
1457mlir::Attribute CIRGenItaniumCXXABI::getAddrOfRTTIDescriptor(mlir::Location loc,
1459 return CIRGenItaniumRTTIBuilder(*
this, cgm).buildTypeInfo(loc, ty);
1464CIRGenItaniumCXXABI::RTTIUniquenessKind
1465CIRGenItaniumCXXABI::classifyRTTIUniqueness(
1466 QualType canTy, cir::GlobalLinkageKind linkage)
const {
1467 if (shouldRTTIBeUnique())
1471 if (linkage != cir::GlobalLinkageKind::LinkOnceODRLinkage &&
1472 linkage != cir::GlobalLinkageKind::WeakODRLinkage)
1480 if (linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage)
1481 return RUK_NonUniqueHidden;
1486 assert(linkage == cir::GlobalLinkageKind::WeakODRLinkage);
1487 return RUK_NonUniqueVisible;
1490void CIRGenItaniumCXXABI::emitDestructorCall(
1492 bool forVirtualBase,
bool delegating, Address thisAddr, QualType thisTy) {
1493 GlobalDecl gd(dd,
type);
1494 if (needsVTTParameter(gd)) {
1498 mlir::Value vtt =
nullptr;
1502 CIRGenCallee callee =
1513 mlir::Value exceptionPtr = {},
1514 mlir::FlatSymbolRefAttr typeInfo = {},
1515 mlir::FlatSymbolRefAttr dtor = {}) {
1516 mlir::Block *currentBlock = builder.getInsertionBlock();
1517 mlir::Region *region = currentBlock->getParent();
1519 if (currentBlock->empty()) {
1520 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1521 cir::UnreachableOp::create(builder, loc);
1523 mlir::Block *throwBlock = builder.createBlock(region);
1525 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1526 cir::UnreachableOp::create(builder, loc);
1528 builder.setInsertionPointToEnd(currentBlock);
1529 cir::BrOp::create(builder, loc, throwBlock);
1532 (void)builder.createBlock(region);
1535void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf,
bool isNoReturn) {
1539 assert(cgf.
currSrcLoc &&
"expected source location");
1543 cgm.
errorNYI(
"emitRethrow with isNoReturn false");
1549 case TargetCXXABI::GenericItanium:
1550 case TargetCXXABI::GenericAArch64:
1551 return new CIRGenItaniumCXXABI(cgm);
1553 case TargetCXXABI::AppleARM64:
1557 return new CIRGenItaniumCXXABI(cgm);
1560 llvm_unreachable(
"bad or NYI ABI kind");
1564cir::GlobalOp CIRGenItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *rd,
1566 assert(vptrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1567 cir::GlobalOp &vtable = vtables[rd];
1575 llvm::raw_svector_ostream
out(name);
1576 getMangleContext().mangleCXXVTable(rd,
out);
1591 cir::GlobalLinkageKind::ExternalLinkage,
1605 "getAddrOfVTable: PS4 DLL import/export");
1611CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer(
1615 mlir::Location loc = cgf.
getLoc(srcLoc);
1618 mlir::Value vtable = cgf.
getVTablePtr(loc, thisAddr, methodDecl->getParent());
1621 mlir::Value vfunc{};
1623 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: emitVTableTypeCheckedLoad");
1627 mlir::Value vfuncLoad;
1630 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: isRelativeLayout");
1632 auto vtableSlotPtr = cir::VTableGetVirtualFnAddrOp::create(
1633 builder, loc, builder.
getPointerTo(tyPtr), vtable, vtableIndex);
1646 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: strictVTablePointers");
1651 CIRGenCallee callee(gd, vfunc.getDefiningOp());
1655mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1656 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
1657 const CXXRecordDecl *nearestVBase) {
1659 needsVTTParameter(cgf.
curGD) &&
"This class doesn't have VTT");
1670 virtualPointerIndex);
1672 auto vptrType = cir::VPtrType::get(cgf.
getBuilder().getContext());
1678CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject base,
1679 const CXXRecordDecl *vtableClass) {
1680 cir::GlobalOp vtable = getAddrOfVTable(vtableClass, CharUnits());
1684 VTableLayout::AddressPointLocation addressPoint =
1690 auto vtablePtrTy = cir::VPtrType::get(builder.getContext());
1692 return builder.create<cir::VTableAddrPointOp>(
1694 mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()),
1695 cir::AddressPointAttr::get(cgm.
getBuilder().getContext(),
1700mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor(
1701 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
1702 clang::BaseSubobject base,
const clang::CXXRecordDecl *nearestVBase) {
1705 needsVTTParameter(cgf.
curGD)) {
1706 return getVTableAddressPointInStructorWithVTT(cgf, vtableClass, base,
1709 return getVTableAddressPoint(base, vtableClass);
1712bool CIRGenItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1713 CIRGenFunction &cgf, CIRGenFunction::VPtr vptr) {
1716 return needsVTTParameter(cgf.
curGD);
1719mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(
1720 mlir::Location loc, CIRGenFunction &cgf, Address thisAddr,
1721 const CXXRecordDecl *classDecl,
const CXXRecordDecl *baseClassDecl) {
1723 mlir::Value vtablePtr = cgf.
getVTablePtr(loc, thisAddr, classDecl);
1725 CharUnits vbaseOffsetOffset =
1728 mlir::Value offsetVal =
1730 auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.
UInt8PtrTy,
1731 vtableBytePtr, offsetVal);
1733 mlir::Value vbaseOffset;
1736 cgm.
errorNYI(loc,
"getVirtualBaseClassOffset: relative layout");
static void emitConstructorDestructorAlias(CIRGenModule &cgm, GlobalDecl aliasDecl, GlobalDecl targetDecl)
static void insertThrowAndSplit(mlir::OpBuilder &builder, mlir::Location loc, mlir::Value exceptionPtr={}, mlir::FlatSymbolRefAttr typeInfo={}, mlir::FlatSymbolRefAttr dtor={})
static 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 StructorCIRGen getCIRGenToUse(CIRGenModule &cgm, const CXXMethodDecl *md)
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.
cir::PointerType getPointerTo(mlir::Type ty)
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)
llvm::Align getABITypeAlign(mlir::Type ty) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
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.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
mlir::Value getPointer() const
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)
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)
Implements C++ ABI-specific code generation functions.
clang::MangleContext & getMangleContext()
Gets the mangle context.
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
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.
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()
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.
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)
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.
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.
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.
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.
Represents a C++ struct/union/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.
static CanQual< Type > CreateUnsafe(QualType Other)
CharUnits - This is an opaque type for sizes expressed in character units.
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.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
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.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getCanonicalType() const
Encodes a location in the source.
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
AddressPointLocation getAddressPoint(BaseSubobject Base) const
static bool isLocalLinkage(GlobalLinkageKind linkage)
static LLVM_ATTRIBUTE_UNUSED bool isDiscardableIfUnused(GlobalLinkageKind linkage)
Whether the definition of this global may be discarded if it is not used in its compilation unit.
static LLVM_ATTRIBUTE_UNUSED bool isValidLinkage(GlobalLinkageKind gl)
static LLVM_ATTRIBUTE_UNUSED bool isWeakForLinker(GlobalLinkageKind linkage)
Whether the definition of this global may be replaced at link time.
CIRGenCXXABI * CreateCIRGenItaniumCXXABI(CIRGenModule &cgm)
Creates and Itanium-family ABI.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
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 setDLLStorageClass()
static bool hiddenVisibility()
static bool cxxabiAppleARM64CXXABI()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
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
cir::PointerType UInt8PtrTy
unsigned AddressPointIndex