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;
78 void emitRethrow(CIRGenFunction &cgf,
bool isNoReturn)
override;
79 void emitThrow(CIRGenFunction &cgf,
const CXXThrowExpr *e)
override;
81 bool useThunkForDtorVariant(
const CXXDestructorDecl *dtor,
89 bool isVirtualOffsetNeededForVTableField(CIRGenFunction &cgf,
90 CIRGenFunction::VPtr vptr)
override;
92 cir::GlobalOp getAddrOfVTable(
const CXXRecordDecl *rd,
93 CharUnits vptrOffset)
override;
94 CIRGenCallee getVirtualFunctionPointer(CIRGenFunction &cgf,
95 clang::GlobalDecl gd, Address thisAddr,
97 SourceLocation loc)
override;
98 mlir::Value emitVirtualDestructorCall(CIRGenFunction &cgf,
99 const CXXDestructorDecl *dtor,
101 DeleteOrMemberCallExpr e)
override;
102 mlir::Value getVTableAddressPoint(BaseSubobject base,
103 const CXXRecordDecl *vtableClass)
override;
104 mlir::Value getVTableAddressPointInStructorWithVTT(
105 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
106 const CXXRecordDecl *nearestVBase);
108 mlir::Value getVTableAddressPointInStructor(
109 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
110 clang::BaseSubobject base,
111 const clang::CXXRecordDecl *nearestVBase)
override;
112 void emitVTableDefinitions(CIRGenVTables &cgvt,
113 const CXXRecordDecl *rd)
override;
114 void emitVirtualInheritanceTables(
const CXXRecordDecl *rd)
override;
116 mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc,
117 QualType ty)
override;
119 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *vtableClass)
override {
124 getVirtualBaseClassOffset(mlir::Location loc, CIRGenFunction &cgf,
125 Address thisAddr,
const CXXRecordDecl *classDecl,
126 const CXXRecordDecl *baseClassDecl)
override;
133 mlir::Value emitDynamicCast(CIRGenFunction &cgf, mlir::Location loc,
134 QualType srcRecordTy, QualType destRecordTy,
135 cir::PointerType destCIRTy,
bool isRefCast,
136 Address src)
override;
142 virtual bool shouldRTTIBeUnique()
const {
return true; }
146 enum RTTIUniquenessKind {
164 classifyRTTIUniqueness(QualType canTy, cir::GlobalLinkageKind linkage)
const;
169void CIRGenItaniumCXXABI::emitInstanceFunctionProlog(
SourceLocation loc,
174 "emitInstanceFunctionProlog: Naked");
179 setCXXABIThisValue(cgf, loadIncomingCXXThis(cgf));
182 if (getStructorImplicitParamDecl(cgf)) {
186 setStructorImplicitParamValue(cgf, val);
197 if (hasThisReturn(cgf.
curGD)) {
199 "emitInstanceFunctionProlog: hasThisReturn");
203CIRGenCXXABI::AddedStructorArgCounts
204CIRGenItaniumCXXABI::buildStructorSignature(
205 GlobalDecl gd, llvm::SmallVectorImpl<CanQualType> &argTys) {
206 clang::ASTContext &astContext = cgm.getASTContext();
216 argTys.insert(argTys.begin() + 1,
219 return AddedStructorArgCounts::withPrefix(1);
222 return AddedStructorArgCounts{};
227enum class StructorCIRGen { Emit, RAUW, Alias, COMDAT };
233 return StructorCIRGen::Emit;
238 return StructorCIRGen::Emit;
241 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(md)) {
251 return StructorCIRGen::RAUW;
255 return StructorCIRGen::RAUW;
261 return StructorCIRGen::COMDAT;
262 return StructorCIRGen::Emit;
265 return StructorCIRGen::Alias;
275 auto globalValue = dyn_cast_or_null<cir::CIRGlobalValueInterface>(
277 if (globalValue && !globalValue.isDeclaration())
280 auto entry = cast_or_null<cir::FuncOp>(cgm.
getGlobalValue(mangledName));
289void CIRGenItaniumCXXABI::emitCXXStructor(GlobalDecl gd) {
292 const auto *cd = dyn_cast<CXXConstructorDecl>(md);
296 GlobalDecl baseDecl =
300 if (cirGenType == StructorCIRGen::Alias ||
301 cirGenType == StructorCIRGen::COMDAT) {
306 if (cirGenType == StructorCIRGen::RAUW) {
307 StringRef mangledName = cgm.getMangledName(gd);
308 mlir::Operation *aliasee = cgm.getAddrOfGlobal(baseDecl);
309 cgm.addReplacement(mangledName, aliasee);
314 auto fn = cgm.codegenCXXStructor(gd);
316 cgm.maybeSetTrivialComdat(*md, fn);
319void CIRGenItaniumCXXABI::addImplicitStructorParams(CIRGenFunction &cgf,
321 FunctionArgList ¶ms) {
326 if (needsVTTParameter(cgf.
curGD)) {
327 ASTContext &astContext = cgm.getASTContext();
333 astContext,
nullptr, md->getLocation(),
334 &astContext.
Idents.
get(
"vtt"), t, ImplicitParamKind::CXXVTT);
335 params.insert(params.begin() + 1, vttDecl);
336 getStructorImplicitParamDecl(cgf) = vttDecl;
340void CIRGenItaniumCXXABI::emitCXXConstructors(
const CXXConstructorDecl *d) {
342 assert(cgm.getTarget().getCXXABI().hasConstructorVariants());
346 cgm.emitGlobal(GlobalDecl(d,
Ctor_Base));
356void CIRGenItaniumCXXABI::emitCXXDestructors(
const CXXDestructorDecl *d) {
359 cgm.emitGlobal(GlobalDecl(d,
Dtor_Base));
372CIRGenCXXABI::AddedStructorArgs CIRGenItaniumCXXABI::getImplicitConstructorArgs(
374 bool forVirtualBase,
bool delegating) {
375 if (!needsVTTParameter(GlobalDecl(d,
type)))
376 return AddedStructorArgs{};
384 cgm.getASTContext().getPointerType(cgm.getASTContext().VoidPtrTy);
386 return AddedStructorArgs::withPrefix({{vtt, vttTy}});
392bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
396 if (!md->getParent()->getNumVBases())
410void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt,
411 const CXXRecordDecl *rd) {
412 cir::GlobalOp vtable = getAddrOfVTable(rd, CharUnits());
413 if (vtable.hasInitializer())
416 ItaniumVTableContext &vtContext = cgm.getItaniumVTableContext();
418 cir::GlobalLinkageKind linkage = cgm.getVTableLinkage(rd);
419 mlir::Attribute rtti =
420 cgm.getAddrOfRTTIDescriptor(cgm.getLoc(rd->
getBeginLoc()),
421 cgm.getASTContext().getCanonicalTagType(rd));
430 vtable.setLinkage(linkage);
433 vtable.setComdat(
true);
436 cgm.setGVProperties(vtable, rd);
448 "emitVTableDefinitions: __fundamental_type_info");
451 auto vtableAsGlobalValue = dyn_cast<cir::CIRGlobalValueInterface>(*vtable);
452 assert(vtableAsGlobalValue &&
"VTable must support CIRGlobalValueInterface");
460 if (cgm.getCodeGenOpts().WholeProgramVTables) {
462 "emitVTableDefinitions: WholeProgramVTables");
471mlir::Value CIRGenItaniumCXXABI::emitVirtualDestructorCall(
472 CIRGenFunction &cgf,
const CXXDestructorDecl *dtor,
CXXDtorType dtorType,
473 Address thisAddr, DeleteOrMemberCallExpr
expr) {
474 auto *
callExpr = dyn_cast<const CXXMemberCallExpr *>(
expr);
475 auto *delExpr = dyn_cast<const CXXDeleteExpr *>(
expr);
476 assert((
callExpr !=
nullptr) ^ (delExpr !=
nullptr));
480 GlobalDecl globalDecl(dtor, dtorType);
481 const CIRGenFunctionInfo *fnInfo =
482 &cgm.getTypes().arrangeCXXStructorDeclaration(globalDecl);
483 const cir::FuncType &fnTy = cgm.getTypes().getFunctionType(*fnInfo);
490 thisTy,
nullptr, QualType(),
nullptr);
494void CIRGenItaniumCXXABI::emitVirtualInheritanceTables(
495 const CXXRecordDecl *rd) {
496 CIRGenVTables &vtables = cgm.getVTables();
502class CIRGenItaniumRTTIBuilder {
504 const CIRGenItaniumCXXABI &cxxABI;
507 SmallVector<mlir::Attribute, 16> fields;
510 cir::GlobalOp getAddrOfTypeName(mlir::Location loc, QualType ty,
511 cir::GlobalLinkageKind linkage);
514 mlir::Attribute getAddrOfExternalRTTIDescriptor(mlir::Location loc,
518 void buildVTablePointer(mlir::Location loc,
const Type *ty);
522 void buildSIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
527 void buildVMIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
530 CIRGenItaniumRTTIBuilder(
const CIRGenItaniumCXXABI &abi, CIRGenModule &cgm)
531 : cgm(cgm), cxxABI(abi) {}
535 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty);
538 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty,
539 cir::GlobalLinkageKind linkage,
540 mlir::SymbolTable::Visibility visibility);
559 PTI_Incomplete = 0x8,
563 PTI_ContainingClassIncomplete = 0x10,
575 VMI_NonDiamondRepeat = 0x1,
578 VMI_DiamondShaped = 0x2
593static bool typeInfoIsInStandardLibrary(
const BuiltinType *ty) {
609 case BuiltinType::WasmExternRef:
610 case BuiltinType::HLSLResource:
611 llvm_unreachable(
"NYI");
612 case BuiltinType::Void:
613 case BuiltinType::NullPtr:
614 case BuiltinType::Bool:
615 case BuiltinType::WChar_S:
616 case BuiltinType::WChar_U:
617 case BuiltinType::Char_U:
618 case BuiltinType::Char_S:
619 case BuiltinType::UChar:
620 case BuiltinType::SChar:
621 case BuiltinType::Short:
622 case BuiltinType::UShort:
623 case BuiltinType::Int:
624 case BuiltinType::UInt:
625 case BuiltinType::Long:
626 case BuiltinType::ULong:
627 case BuiltinType::LongLong:
628 case BuiltinType::ULongLong:
629 case BuiltinType::Half:
630 case BuiltinType::Float:
631 case BuiltinType::Double:
632 case BuiltinType::LongDouble:
633 case BuiltinType::Float16:
634 case BuiltinType::Float128:
635 case BuiltinType::Ibm128:
636 case BuiltinType::Char8:
637 case BuiltinType::Char16:
638 case BuiltinType::Char32:
639 case BuiltinType::Int128:
640 case BuiltinType::UInt128:
643#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
644 case BuiltinType::Id:
645#include "clang/Basic/OpenCLImageTypes.def"
646#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
647#include "clang/Basic/OpenCLExtensionTypes.def"
648 case BuiltinType::OCLSampler:
649 case BuiltinType::OCLEvent:
650 case BuiltinType::OCLClkEvent:
651 case BuiltinType::OCLQueue:
652 case BuiltinType::OCLReserveID:
653#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
654#include "clang/Basic/AArch64ACLETypes.def"
655#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
656#include "clang/Basic/PPCTypes.def"
657#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
658#include "clang/Basic/RISCVVTypes.def"
659#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
660#include "clang/Basic/AMDGPUTypes.def"
661 case BuiltinType::ShortAccum:
662 case BuiltinType::Accum:
663 case BuiltinType::LongAccum:
664 case BuiltinType::UShortAccum:
665 case BuiltinType::UAccum:
666 case BuiltinType::ULongAccum:
667 case BuiltinType::ShortFract:
668 case BuiltinType::Fract:
669 case BuiltinType::LongFract:
670 case BuiltinType::UShortFract:
671 case BuiltinType::UFract:
672 case BuiltinType::ULongFract:
673 case BuiltinType::SatShortAccum:
674 case BuiltinType::SatAccum:
675 case BuiltinType::SatLongAccum:
676 case BuiltinType::SatUShortAccum:
677 case BuiltinType::SatUAccum:
678 case BuiltinType::SatULongAccum:
679 case BuiltinType::SatShortFract:
680 case BuiltinType::SatFract:
681 case BuiltinType::SatLongFract:
682 case BuiltinType::SatUShortFract:
683 case BuiltinType::SatUFract:
684 case BuiltinType::SatULongFract:
685 case BuiltinType::BFloat16:
688 case BuiltinType::Dependent:
689#define BUILTIN_TYPE(Id, SingletonId)
690#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
691#include "clang/AST/BuiltinTypes.def"
692 llvm_unreachable(
"asking for RRTI for a placeholder type!");
694 case BuiltinType::ObjCId:
695 case BuiltinType::ObjCClass:
696 case BuiltinType::ObjCSel:
697 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
700 llvm_unreachable(
"Invalid BuiltinType Kind!");
703static bool typeInfoIsInStandardLibrary(
const PointerType *pointerTy) {
705 const auto *builtinTy = dyn_cast<BuiltinType>(pointeeTy);
716 return typeInfoIsInStandardLibrary(builtinTy);
721static bool isStandardLibraryRttiDescriptor(QualType ty) {
723 if (
const auto *builtinTy = dyn_cast<BuiltinType>(ty))
724 return typeInfoIsInStandardLibrary(builtinTy);
728 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
729 return typeInfoIsInStandardLibrary(pointerTy);
738static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
746 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
759 bool isDLLImport = rd->
hasAttr<DLLImportAttr>();
769 return !isDLLImport || cgm.
getTriple().isWindowsItaniumEnvironment();
782 llvm::SmallPtrSet<const CXXRecordDecl *, 16> nonVirtualBases;
783 llvm::SmallPtrSet<const CXXRecordDecl *, 16> virtualBases;
788static unsigned computeVmiClassTypeInfoFlags(
const CXXBaseSpecifier *base,
796 if (!bases.virtualBases.insert(baseDecl).second) {
799 flags |= VMI_DiamondShaped;
801 if (bases.nonVirtualBases.count(baseDecl))
802 flags |= VMI_NonDiamondRepeat;
806 if (!bases.nonVirtualBases.insert(baseDecl).second) {
809 flags |= VMI_NonDiamondRepeat;
811 if (bases.virtualBases.count(baseDecl))
812 flags |= VMI_NonDiamondRepeat;
817 for (
const auto &bs : baseDecl->bases())
818 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
823static unsigned computeVmiClassTypeInfoFlags(
const CXXRecordDecl *rd) {
828 for (
const auto &bs : rd->
bases())
829 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
838static bool canUseSingleInheritance(
const CXXRecordDecl *rd) {
856 return baseDecl->isEmpty() ||
861static bool isIncompleteClassType(
const RecordType *recordTy) {
862 return !recordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
876static bool containsIncompleteClassType(QualType ty) {
877 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
878 if (isIncompleteClassType(recordTy))
882 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
885 if (
const auto *memberPointerTy = dyn_cast<MemberPointerType>(ty)) {
887 if (!memberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
890 return containsIncompleteClassType(memberPointerTy->getPointeeType());
896const char *vTableClassNameForType(
const CIRGenModule &cgm,
const Type *ty) {
898 static const char *
const classTypeInfo =
899 "_ZTVN10__cxxabiv117__class_type_infoE";
901 static const char *
const siClassTypeInfo =
902 "_ZTVN10__cxxabiv120__si_class_type_infoE";
904 static const char *
const vmiClassTypeInfo =
905 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
908#define TYPE(Class, Base)
909#define ABSTRACT_TYPE(Class, Base)
910#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
911#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
912#define DEPENDENT_TYPE(Class, Base) case Type::Class:
913#include "clang/AST/TypeNodes.inc"
914 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
916 case Type::LValueReference:
917 case Type::RValueReference:
918 llvm_unreachable(
"References shouldn't get here");
921 case Type::DeducedTemplateSpecialization:
922 llvm_unreachable(
"Undeduced type shouldn't get here");
925 llvm_unreachable(
"Pipe types shouldn't get here");
927 case Type::ArrayParameter:
928 llvm_unreachable(
"Array Parameter types should not get here.");
934 case Type::ExtVector:
935 case Type::ConstantMatrix:
939 case Type::BlockPointer:
940 return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
941 case Type::ConstantArray:
942 case Type::IncompleteArray:
943 case Type::VariableArray:
944 cgm.
errorNYI(
"VTableClassNameForType: __array_type_info");
947 case Type::FunctionNoProto:
948 case Type::FunctionProto:
949 cgm.
errorNYI(
"VTableClassNameForType: __function_type_info");
953 cgm.
errorNYI(
"VTableClassNameForType: Enum");
958 ->getDefinitionOrSelf();
961 return classTypeInfo;
964 if (canUseSingleInheritance(rd)) {
965 return siClassTypeInfo;
968 return vmiClassTypeInfo;
971 case Type::ObjCObject:
972 cgm.
errorNYI(
"VTableClassNameForType: ObjCObject");
975 case Type::ObjCInterface:
976 cgm.
errorNYI(
"VTableClassNameForType: ObjCInterface");
979 case Type::ObjCObjectPointer:
981 cgm.
errorNYI(
"VTableClassNameForType: __pointer_type_info");
984 case Type::MemberPointer:
985 cgm.
errorNYI(
"VTableClassNameForType: __pointer_to_member_type_info");
988 case Type::HLSLAttributedResource:
989 case Type::HLSLInlineSpirv:
990 llvm_unreachable(
"HLSL doesn't support virtual functions");
1009 if (containsIncompleteClassType(ty))
1010 return cir::GlobalLinkageKind::InternalLinkage;
1014 llvm_unreachable(
"Linkage hasn't been computed!");
1019 return cir::GlobalLinkageKind::InternalLinkage;
1027 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1029 if (
const RecordType *record = dyn_cast<RecordType>(ty)) {
1033 return cir::GlobalLinkageKind::WeakODRLinkage;
1035 if (cgm.
getTriple().isWindowsItaniumEnvironment())
1036 if (rd->
hasAttr<DLLImportAttr>() &&
1037 shouldUseExternalRttiDescriptor(cgm, ty))
1038 return cir::GlobalLinkageKind::ExternalLinkage;
1044 .isWindowsGNUEnvironment())
1048 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1051 llvm_unreachable(
"Invalid linkage!");
1055CIRGenItaniumRTTIBuilder::getAddrOfTypeName(mlir::Location loc, QualType ty,
1056 cir::GlobalLinkageKind linkage) {
1058 SmallString<256>
name;
1059 llvm::raw_svector_ostream
out(name);
1065 mlir::Attribute init = builder.
getString(
1078 loc, name, initStr.getType(), linkage, align);
1084CIRGenItaniumRTTIBuilder::getAddrOfExternalRTTIDescriptor(mlir::Location loc,
1087 SmallString<256>
name;
1088 llvm::raw_svector_ostream
out(name);
1093 cir::GlobalOp gv = dyn_cast_or_null<cir::GlobalOp>(
1094 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1109 cgm.
errorNYI(
"getAddrOfExternalRTTIDescriptor: hasPS4DLLImportExport");
1116void CIRGenItaniumRTTIBuilder::buildVTablePointer(mlir::Location loc,
1119 const char *vTableName = vTableClassNameForType(cgm, ty);
1123 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1130 loc, vTableName, vtableGlobalTy, cir::GlobalLinkageKind::ExternalLinkage,
1134 mlir::Attribute field{};
1136 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1138 SmallVector<mlir::Attribute, 4> offsets{
1140 auto indices = mlir::ArrayAttr::get(builder.getContext(), offsets);
1145 assert(field &&
"expected attribute");
1146 fields.push_back(field);
1151void CIRGenItaniumRTTIBuilder::buildSIClassTypeInfo(mlir::Location loc,
1152 const CXXRecordDecl *rd) {
1156 mlir::Attribute baseTypeInfo =
1157 CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1159 fields.push_back(baseTypeInfo);
1165void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc,
1166 const CXXRecordDecl *rd) {
1167 mlir::Type unsignedIntLTy =
1174 unsigned flags = computeVmiClassTypeInfoFlags(rd);
1175 fields.push_back(cir::IntAttr::get(unsignedIntLTy, flags));
1180 fields.push_back(cir::IntAttr::get(unsignedIntLTy, rd->
getNumBases()));
1213 mlir::Type offsetFlagsLTy = cgm.
convertType(offsetFlagsTy);
1215 for (
const CXXBaseSpecifier &base : rd->
bases()) {
1217 fields.push_back(CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1218 .buildTypeInfo(loc, base.
getType()));
1232 const ASTRecordLayout &layout =
1241 offsetFlags |= BCTI_Virtual;
1243 offsetFlags |= BCTI_Public;
1245 fields.push_back(cir::IntAttr::get(offsetFlagsLTy, offsetFlags));
1249mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(mlir::Location loc,
1255 SmallString<256>
name;
1256 llvm::raw_svector_ostream
out(name);
1259 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1260 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1262 if (oldGV && !oldGV.isDeclaration()) {
1263 assert(!oldGV.hasAvailableExternallyLinkage() &&
1264 "available_externally typeinfos not yet implemented");
1270 if (isStandardLibraryRttiDescriptor(ty) ||
1271 shouldUseExternalRttiDescriptor(cgm, ty))
1272 return getAddrOfExternalRTTIDescriptor(loc, ty);
1282 mlir::SymbolTable::Visibility symVisibility;
1285 symVisibility = mlir::SymbolTable::Visibility::Public;
1286 else if (cxxABI.classifyRTTIUniqueness(ty, linkage) ==
1287 CIRGenItaniumCXXABI::RUK_NonUniqueHidden) {
1289 "buildTypeInfo: classifyRTTIUniqueness == RUK_NonUniqueHidden");
1294 return buildTypeInfo(loc, ty, linkage, symVisibility);
1297mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
1298 mlir::Location loc, QualType ty, cir::GlobalLinkageKind linkage,
1299 mlir::SymbolTable::Visibility visibility) {
1308 cir::GlobalOp typeName = getAddrOfTypeName(loc, ty, linkage);
1309 mlir::Attribute typeNameField;
1313 CIRGenItaniumCXXABI::RTTIUniquenessKind rttiUniqueness =
1314 cxxABI.classifyRTTIUniqueness(ty, linkage);
1315 if (rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique) {
1319 "buildTypeInfo: rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique");
1325 fields.push_back(typeNameField);
1328#define TYPE(Class, Base)
1329#define ABSTRACT_TYPE(Class, Base)
1330#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1331#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1332#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1333#include "clang/AST/TypeNodes.inc"
1334 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1339 case Type::ExtVector:
1340 case Type::ConstantMatrix:
1342 case Type::BlockPointer:
1347 case Type::LValueReference:
1348 case Type::RValueReference:
1349 llvm_unreachable(
"References shouldn't get here");
1352 case Type::DeducedTemplateSpecialization:
1353 llvm_unreachable(
"Undeduced type shouldn't get here");
1361 case Type::ConstantArray:
1362 case Type::IncompleteArray:
1363 case Type::VariableArray:
1364 case Type::ArrayParameter:
1369 case Type::FunctionNoProto:
1370 case Type::FunctionProto:
1380 case Type::Record: {
1382 ->getDefinitionOrSelf();
1388 if (canUseSingleInheritance(rd)) {
1389 buildSIClassTypeInfo(loc, rd);
1391 buildVMIClassTypeInfo(loc, rd);
1397 case Type::ObjCObject:
1398 case Type::ObjCInterface:
1399 cgm.
errorNYI(
"buildTypeInfo: ObjCObject & ObjCInterface");
1402 case Type::ObjCObjectPointer:
1403 cgm.
errorNYI(
"buildTypeInfo: ObjCObjectPointer");
1407 cgm.
errorNYI(
"buildTypeInfo: Pointer");
1410 case Type::MemberPointer:
1411 cgm.
errorNYI(
"buildTypeInfo: MemberPointer");
1418 case Type::HLSLAttributedResource:
1419 case Type::HLSLInlineSpirv:
1420 llvm_unreachable(
"HLSL doesn't support RTTI");
1424 cir::TypeInfoAttr init = builder.
getTypeInfo(builder.getArrayAttr(fields));
1426 SmallString<256>
name;
1427 llvm::raw_svector_ostream
out(name);
1431 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1432 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1441 cgm.
errorNYI(
"buildTypeInfo: target hasPS4DLLImportExport");
1448 gv.setName(oldGV.getName());
1449 if (!oldGV->use_empty()) {
1450 cgm.
errorNYI(
"buildTypeInfo: old GV !use_empty");
1458 cgm.
errorNYI(
"buildTypeInfo: supportsCOMDAT & isWeakForLinker");
1464 gv.setAlignmentAttr(cgm.
getSize(align));
1481 mlir::SymbolTable::setSymbolVisibility(typeName, visibility);
1486 mlir::SymbolTable::setSymbolVisibility(gv, visibility);
1495mlir::Attribute CIRGenItaniumCXXABI::getAddrOfRTTIDescriptor(mlir::Location loc,
1497 return CIRGenItaniumRTTIBuilder(*
this, cgm).buildTypeInfo(loc, ty);
1502CIRGenItaniumCXXABI::RTTIUniquenessKind
1503CIRGenItaniumCXXABI::classifyRTTIUniqueness(
1504 QualType canTy, cir::GlobalLinkageKind linkage)
const {
1505 if (shouldRTTIBeUnique())
1509 if (linkage != cir::GlobalLinkageKind::LinkOnceODRLinkage &&
1510 linkage != cir::GlobalLinkageKind::WeakODRLinkage)
1518 if (linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage)
1519 return RUK_NonUniqueHidden;
1524 assert(linkage == cir::GlobalLinkageKind::WeakODRLinkage);
1525 return RUK_NonUniqueVisible;
1528void CIRGenItaniumCXXABI::emitDestructorCall(
1530 bool forVirtualBase,
bool delegating, Address thisAddr, QualType thisTy) {
1531 GlobalDecl gd(dd,
type);
1537 CIRGenCallee callee =
1544void CIRGenItaniumCXXABI::registerGlobalDtor(
const VarDecl *vd,
1565mlir::Value CIRGenItaniumCXXABI::getCXXDestructorImplicitParam(
1567 bool forVirtualBase,
bool delegating) {
1568 GlobalDecl gd(dd,
type);
1576 mlir::Value exceptionPtr = {},
1577 mlir::FlatSymbolRefAttr typeInfo = {},
1578 mlir::FlatSymbolRefAttr dtor = {}) {
1579 mlir::Block *currentBlock = builder.getInsertionBlock();
1580 mlir::Region *region = currentBlock->getParent();
1582 if (currentBlock->empty()) {
1583 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1584 cir::UnreachableOp::create(builder, loc);
1586 mlir::Block *throwBlock = builder.createBlock(region);
1588 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1589 cir::UnreachableOp::create(builder, loc);
1591 builder.setInsertionPointToEnd(currentBlock);
1592 cir::BrOp::create(builder, loc, throwBlock);
1595 (void)builder.createBlock(region);
1598void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf,
bool isNoReturn) {
1602 assert(cgf.
currSrcLoc &&
"expected source location");
1606 cgm.
errorNYI(
"emitRethrow with isNoReturn false");
1610void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf,
1611 const CXXThrowExpr *e) {
1619 cir::PointerType throwTy =
1626 mlir::TypedValue<cir::PointerType> exceptionPtr =
1627 cir::AllocExceptionOp::create(builder, subExprLoc, throwTy,
1628 builder.getI64IntegerAttr(typeSize))
1636 auto typeInfo = mlir::cast<cir::GlobalViewAttr>(
1639 assert(!typeInfo.getIndices() &&
"expected no indirection");
1648 if (
const RecordType *recordTy = clangThrowType->
getAs<RecordType>()) {
1651 if (!rec->hasTrivialDestructor()) {
1652 cgm.
errorNYI(
"emitThrow: non-trivial destructor");
1664 case TargetCXXABI::GenericItanium:
1665 case TargetCXXABI::GenericAArch64:
1666 return new CIRGenItaniumCXXABI(cgm);
1668 case TargetCXXABI::AppleARM64:
1672 return new CIRGenItaniumCXXABI(cgm);
1675 llvm_unreachable(
"bad or NYI ABI kind");
1679cir::GlobalOp CIRGenItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *rd,
1681 assert(vptrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1682 cir::GlobalOp &vtable = vtables[rd];
1690 llvm::raw_svector_ostream
out(name);
1691 getMangleContext().mangleCXXVTable(rd,
out);
1706 cir::GlobalLinkageKind::ExternalLinkage,
1720 "getAddrOfVTable: PS4 DLL import/export");
1726CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer(
1730 mlir::Location loc = cgf.
getLoc(srcLoc);
1733 mlir::Value vtable = cgf.
getVTablePtr(loc, thisAddr, methodDecl->getParent());
1736 mlir::Value vfunc{};
1738 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: emitVTableTypeCheckedLoad");
1742 mlir::Value vfuncLoad;
1745 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: isRelativeLayout");
1747 auto vtableSlotPtr = cir::VTableGetVirtualFnAddrOp::create(
1748 builder, loc, builder.
getPointerTo(tyPtr), vtable, vtableIndex);
1761 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: strictVTablePointers");
1766 CIRGenCallee callee(gd, vfunc.getDefiningOp());
1770mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1771 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
1772 const CXXRecordDecl *nearestVBase) {
1774 needsVTTParameter(cgf.
curGD) &&
"This class doesn't have VTT");
1785 virtualPointerIndex);
1787 auto vptrType = cir::VPtrType::get(cgf.
getBuilder().getContext());
1793CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject base,
1794 const CXXRecordDecl *vtableClass) {
1795 cir::GlobalOp vtable = getAddrOfVTable(vtableClass, CharUnits());
1799 VTableLayout::AddressPointLocation addressPoint =
1805 auto vtablePtrTy = cir::VPtrType::get(builder.getContext());
1807 return builder.create<cir::VTableAddrPointOp>(
1809 mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()),
1810 cir::AddressPointAttr::get(cgm.
getBuilder().getContext(),
1815mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor(
1816 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
1817 clang::BaseSubobject base,
const clang::CXXRecordDecl *nearestVBase) {
1820 needsVTTParameter(cgf.
curGD)) {
1821 return getVTableAddressPointInStructorWithVTT(cgf, vtableClass, base,
1824 return getVTableAddressPoint(base, vtableClass);
1827bool CIRGenItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1828 CIRGenFunction &cgf, CIRGenFunction::VPtr vptr) {
1831 return needsVTTParameter(cgf.
curGD);
1834mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(
1835 mlir::Location loc, CIRGenFunction &cgf, Address thisAddr,
1836 const CXXRecordDecl *classDecl,
const CXXRecordDecl *baseClassDecl) {
1838 mlir::Value vtablePtr = cgf.
getVTablePtr(loc, thisAddr, classDecl);
1840 CharUnits vbaseOffsetOffset =
1843 mlir::Value offsetVal =
1845 auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.
UInt8PtrTy,
1846 vtableBytePtr, offsetVal);
1848 mlir::Value vbaseOffset;
1851 cgm.
errorNYI(loc,
"getVirtualBaseClassOffset: relative layout");
1867 cir::FuncType fnTy =
1881 if (!dst->isDerivedFrom(src, paths))
1884 unsigned numPublicPaths = 0;
1897 if (pathElement.Base->isVirtual())
1900 if (numPublicPaths > 1)
1907 pathElement.Base->getType()->getAsCXXRecordDecl());
1912 if (numPublicPaths == 0)
1916 if (numPublicPaths > 1)
1944 {voidPtrTy, rttiPtrTy, rttiPtrTy, ptrDiffTy}, voidPtrTy);
1952 auto srcRtti = mlir::cast<cir::GlobalViewAttr>(
1954 auto destRtti = mlir::cast<cir::GlobalViewAttr>(
1959 auto runtimeFuncRef = mlir::FlatSymbolRefAttr::get(runtimeFuncOp);
1960 auto badCastFuncRef = mlir::FlatSymbolRefAttr::get(badCastFuncOp);
1967 auto offsetHintAttr = cir::IntAttr::get(ptrdiffTy, offsetHint.
getQuantity());
1969 return cir::DynamicCastInfoAttr::get(srcRtti, destRtti, runtimeFuncRef,
1970 badCastFuncRef, offsetHintAttr);
1973mlir::Value CIRGenItaniumCXXABI::emitDynamicCast(CIRGenFunction &cgf,
1975 QualType srcRecordTy,
1976 QualType destRecordTy,
1977 cir::PointerType destCIRTy,
1978 bool isRefCast, Address src) {
1979 bool isCastToVoid = destRecordTy.
isNull();
1980 assert((!isCastToVoid || !isRefCast) &&
"cannot cast to void reference");
1983 cgm.
errorNYI(loc,
"emitDynamicCastToVoid");
1991 cgm.
errorNYI(loc,
"emitExactDynamicCast");
1995 cir::DynamicCastInfoAttr castInfo =
1998 isRefCast, castInfo);
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 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 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.
cir::PointerType getPointerTo(mlir::Type ty)
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)
cir::PointerType getVoidPtrTy(clang::LangAS langAS=clang::LangAS::Default)
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 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.
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
mlir::Value getPointer() const
mlir::Value emitRawPointer() const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
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 createDynCast(mlir::Location loc, mlir::Value src, cir::PointerType destType, bool isRefCast, cir::DynamicCastInfoAttr info)
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())
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()
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.
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.
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.
const Expr * getSubExpr() const
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()
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 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.
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
cir::PointerType UInt8PtrTy
Represents an element in a path from a derived class to a base class.
unsigned AddressPointIndex