28#include "llvm/Support/ErrorHandling.h"
38 llvm::DenseMap<const CXXRecordDecl *, cir::GlobalOp> vtables;
41 CIRGenItaniumCXXABI(CIRGenModule &cgm) : CIRGenCXXABI(cgm) {
46 AddedStructorArgs getImplicitConstructorArgs(CIRGenFunction &cgf,
47 const CXXConstructorDecl *d,
50 bool delegating)
override;
52 bool needsVTTParameter(clang::GlobalDecl gd)
override;
54 AddedStructorArgCounts
55 buildStructorSignature(GlobalDecl gd,
56 llvm::SmallVectorImpl<CanQualType> &argTys)
override;
58 void emitInstanceFunctionProlog(SourceLocation loc,
59 CIRGenFunction &cgf)
override;
61 void addImplicitStructorParams(CIRGenFunction &cgf, QualType &resTy,
62 FunctionArgList ¶ms)
override;
64 const CXXDestructorDecl *dd,
67 bool delegating)
override;
68 void emitCXXConstructors(
const clang::CXXConstructorDecl *d)
override;
69 void emitCXXDestructors(
const clang::CXXDestructorDecl *d)
override;
70 void emitCXXStructor(clang::GlobalDecl gd)
override;
72 void emitDestructorCall(CIRGenFunction &cgf,
const CXXDestructorDecl *dd,
74 bool delegating, Address thisAddr,
75 QualType thisTy)
override;
76 void registerGlobalDtor(
const VarDecl *vd, cir::FuncOp dtor,
77 mlir::Value addr)
override;
78 void emitVirtualObjectDelete(CIRGenFunction &cgf,
const CXXDeleteExpr *de,
79 Address ptr, QualType elementType,
80 const CXXDestructorDecl *dtor)
override;
82 void emitRethrow(CIRGenFunction &cgf,
bool isNoReturn)
override;
83 void emitThrow(CIRGenFunction &cgf,
const CXXThrowExpr *e)
override;
85 bool useThunkForDtorVariant(
const CXXDestructorDecl *dtor,
93 bool isVirtualOffsetNeededForVTableField(CIRGenFunction &cgf,
94 CIRGenFunction::VPtr vptr)
override;
96 cir::GlobalOp getAddrOfVTable(
const CXXRecordDecl *rd,
97 CharUnits vptrOffset)
override;
98 CIRGenCallee getVirtualFunctionPointer(CIRGenFunction &cgf,
99 clang::GlobalDecl gd, Address thisAddr,
101 SourceLocation loc)
override;
102 mlir::Value emitVirtualDestructorCall(CIRGenFunction &cgf,
103 const CXXDestructorDecl *dtor,
105 DeleteOrMemberCallExpr e)
override;
107 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
108 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
110 mlir::Value getVTableAddressPoint(BaseSubobject base,
111 const CXXRecordDecl *vtableClass)
override;
112 mlir::Value getVTableAddressPointInStructorWithVTT(
113 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
114 const CXXRecordDecl *nearestVBase);
116 mlir::Value getVTableAddressPointInStructor(
117 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
118 clang::BaseSubobject base,
119 const clang::CXXRecordDecl *nearestVBase)
override;
120 void emitVTableDefinitions(CIRGenVTables &cgvt,
121 const CXXRecordDecl *rd)
override;
122 void emitVirtualInheritanceTables(
const CXXRecordDecl *rd)
override;
124 void setThunkLinkage(cir::FuncOp thunk,
bool forVTable, GlobalDecl gd,
125 bool returnAdjustment)
override {
126 if (forVTable && !thunk.hasLocalLinkage())
127 thunk.setLinkage(cir::GlobalLinkageKind::AvailableExternallyLinkage);
132 bool exportThunk()
override {
return true; }
134 mlir::Value performThisAdjustment(CIRGenFunction &cgf, Address thisAddr,
135 const CXXRecordDecl *unadjustedClass,
136 const ThunkInfo &ti)
override;
139 const CXXRecordDecl *unadjustedClass,
140 const ReturnAdjustment &ra)
override;
142 bool shouldTypeidBeNullChecked(QualType srcTy)
override;
143 mlir::Value emitTypeid(CIRGenFunction &cgf, QualType SrcRecordTy,
144 Address thisPtr, mlir::Type StdTypeInfoPtrTy)
override;
145 void emitBadTypeidCall(CIRGenFunction &cgf, mlir::Location loc)
override;
147 mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc,
148 QualType ty)
override;
150 StringRef getPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
151 StringRef getDeletedVirtualCallName()
override {
152 return "__cxa_deleted_virtual";
156 getAddrOfCXXCatchHandlerType(mlir::Location loc, QualType ty,
157 QualType catchHandlerType)
override {
158 auto rtti = dyn_cast<cir::GlobalViewAttr>(getAddrOfRTTIDescriptor(loc, ty));
159 assert(rtti &&
"expected GlobalViewAttr");
160 return CatchTypeInfo{rtti, 0};
163 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *vtableClass)
override {
167 size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *,
168 FunctionArgList &args)
const override {
169 assert(!args.empty() &&
"expected the arglist to not be empty!");
170 return args.size() - 1;
173 void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc)
override;
176 getVirtualBaseClassOffset(mlir::Location loc, CIRGenFunction &cgf,
177 Address thisAddr,
const CXXRecordDecl *classDecl,
178 const CXXRecordDecl *baseClassDecl)
override;
185 mlir::Value emitDynamicCast(CIRGenFunction &cgf, mlir::Location loc,
186 QualType srcRecordTy, QualType destRecordTy,
187 cir::PointerType destCIRTy,
bool isRefCast,
188 Address src)
override;
190 cir::MethodAttr buildVirtualMethodAttr(cir::MethodType methodTy,
191 const CXXMethodDecl *md)
override;
193 Address initializeArrayCookie(CIRGenFunction &cgf, Address newPtr,
194 mlir::Value numElements,
const CXXNewExpr *e,
195 QualType elementType)
override;
197 bool isZeroInitializable(
const MemberPointerType *MPT)
override;
200 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
205 virtual bool shouldRTTIBeUnique()
const {
return true; }
209 enum RTTIUniquenessKind {
227 classifyRTTIUniqueness(QualType canTy, cir::GlobalLinkageKind linkage)
const;
230 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *rd)
const;
231 bool isVTableHidden(
const CXXRecordDecl *rd)
const;
236void CIRGenItaniumCXXABI::emitInstanceFunctionProlog(
SourceLocation loc,
241 "emitInstanceFunctionProlog: Naked");
246 setCXXABIThisValue(cgf, loadIncomingCXXThis(cgf));
249 if (getStructorImplicitParamDecl(cgf)) {
253 setStructorImplicitParamValue(cgf, val);
264 if (hasThisReturn(cgf.
curGD)) {
266 "emitInstanceFunctionProlog: hasThisReturn");
270CIRGenCXXABI::AddedStructorArgCounts
271CIRGenItaniumCXXABI::buildStructorSignature(
272 GlobalDecl gd, llvm::SmallVectorImpl<CanQualType> &argTys) {
283 argTys.insert(argTys.begin() + 1,
286 return AddedStructorArgCounts::withPrefix(1);
289 return AddedStructorArgCounts{};
294enum class StructorCIRGen { Emit, RAUW, Alias, COMDAT };
300 return StructorCIRGen::Emit;
305 return StructorCIRGen::Emit;
308 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(md)) {
318 return StructorCIRGen::RAUW;
322 return StructorCIRGen::RAUW;
328 return StructorCIRGen::COMDAT;
329 return StructorCIRGen::Emit;
332 return StructorCIRGen::Alias;
342 auto globalValue = dyn_cast_or_null<cir::CIRGlobalValueInterface>(
344 if (globalValue && !globalValue.isDeclaration())
347 auto entry = cast_or_null<cir::FuncOp>(cgm.
getGlobalValue(mangledName));
356void CIRGenItaniumCXXABI::emitCXXStructor(GlobalDecl gd) {
359 const auto *cd = dyn_cast<CXXConstructorDecl>(md);
363 GlobalDecl baseDecl =
367 if (cirGenType == StructorCIRGen::Alias ||
368 cirGenType == StructorCIRGen::COMDAT) {
373 if (cirGenType == StructorCIRGen::RAUW) {
386void CIRGenItaniumCXXABI::addImplicitStructorParams(CIRGenFunction &cgf,
388 FunctionArgList ¶ms) {
393 if (needsVTTParameter(cgf.
curGD)) {
400 astContext,
nullptr, md->getLocation(),
401 &astContext.
Idents.
get(
"vtt"), t, ImplicitParamKind::CXXVTT);
402 params.insert(params.begin() + 1, vttDecl);
403 getStructorImplicitParamDecl(cgf) = vttDecl;
407void CIRGenItaniumCXXABI::emitCXXConstructors(
const CXXConstructorDecl *d) {
423void CIRGenItaniumCXXABI::emitCXXDestructors(
const CXXDestructorDecl *d) {
439CIRGenCXXABI::AddedStructorArgs CIRGenItaniumCXXABI::getImplicitConstructorArgs(
441 bool forVirtualBase,
bool delegating) {
442 if (!needsVTTParameter(GlobalDecl(d,
type)))
443 return AddedStructorArgs{};
453 return AddedStructorArgs::withPrefix({{vtt, vttTy}});
459bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
463 if (!md->getParent()->getNumVBases())
477void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt,
478 const CXXRecordDecl *rd) {
479 cir::GlobalOp vtable = getAddrOfVTable(rd, CharUnits());
480 if (vtable.hasInitializer())
486 mlir::Attribute rtti =
497 vtable.setLinkage(linkage);
500 vtable.setComdat(
true);
515 "emitVTableDefinitions: __fundamental_type_info");
518 [[maybe_unused]]
auto vtableAsGlobalValue =
519 dyn_cast<cir::CIRGlobalValueInterface>(*vtable);
520 assert(vtableAsGlobalValue &&
"VTable must support CIRGlobalValueInterface");
530 "emitVTableDefinitions: WholeProgramVTables");
539mlir::Value CIRGenItaniumCXXABI::emitVirtualDestructorCall(
540 CIRGenFunction &cgf,
const CXXDestructorDecl *dtor,
CXXDtorType dtorType,
541 Address thisAddr, DeleteOrMemberCallExpr
expr) {
542 auto *
callExpr = dyn_cast<const CXXMemberCallExpr *>(
expr);
543 auto *delExpr = dyn_cast<const CXXDeleteExpr *>(
expr);
544 assert((
callExpr !=
nullptr) ^ (delExpr !=
nullptr));
548 GlobalDecl globalDecl(dtor, dtorType);
549 const CIRGenFunctionInfo *fnInfo =
558 thisTy,
nullptr, QualType(),
nullptr);
562void CIRGenItaniumCXXABI::emitVirtualInheritanceTables(
563 const CXXRecordDecl *rd) {
570class CIRGenItaniumRTTIBuilder {
572 const CIRGenItaniumCXXABI &cxxABI;
575 SmallVector<mlir::Attribute, 16> fields;
578 cir::GlobalOp getAddrOfTypeName(mlir::Location loc, QualType ty,
579 cir::GlobalLinkageKind linkage);
582 mlir::Attribute getAddrOfExternalRTTIDescriptor(mlir::Location loc,
586 void buildVTablePointer(mlir::Location loc,
const Type *ty);
590 void buildSIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
595 void buildVMIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
599 void buildPointerTypeInfo(mlir::Location loc, QualType ty);
606 void buildPointerToMemberTypeInfo(mlir::Location loc,
607 const MemberPointerType *ty);
610 CIRGenItaniumRTTIBuilder(
const CIRGenItaniumCXXABI &abi, CIRGenModule &cgm)
611 : cgm(cgm), cxxABI(abi) {}
615 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty);
618 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty,
619 cir::GlobalLinkageKind linkage,
620 mlir::SymbolTable::Visibility visibility);
639 PTI_Incomplete = 0x8,
643 PTI_ContainingClassIncomplete = 0x10,
655 VMI_NonDiamondRepeat = 0x1,
658 VMI_DiamondShaped = 0x2
673static bool typeInfoIsInStandardLibrary(
const BuiltinType *ty) {
689 case BuiltinType::WasmExternRef:
690 case BuiltinType::HLSLResource:
691 llvm_unreachable(
"NYI");
692 case BuiltinType::Void:
693 case BuiltinType::NullPtr:
694 case BuiltinType::Bool:
695 case BuiltinType::WChar_S:
696 case BuiltinType::WChar_U:
697 case BuiltinType::Char_U:
698 case BuiltinType::Char_S:
699 case BuiltinType::UChar:
700 case BuiltinType::SChar:
701 case BuiltinType::Short:
702 case BuiltinType::UShort:
703 case BuiltinType::Int:
704 case BuiltinType::UInt:
705 case BuiltinType::Long:
706 case BuiltinType::ULong:
707 case BuiltinType::LongLong:
708 case BuiltinType::ULongLong:
709 case BuiltinType::Half:
710 case BuiltinType::Float:
711 case BuiltinType::Double:
712 case BuiltinType::LongDouble:
713 case BuiltinType::Float16:
714 case BuiltinType::Float128:
715 case BuiltinType::Ibm128:
716 case BuiltinType::Char8:
717 case BuiltinType::Char16:
718 case BuiltinType::Char32:
719 case BuiltinType::Int128:
720 case BuiltinType::UInt128:
723#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
724 case BuiltinType::Id:
725#include "clang/Basic/OpenCLImageTypes.def"
726#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
727#include "clang/Basic/OpenCLExtensionTypes.def"
728 case BuiltinType::OCLSampler:
729 case BuiltinType::OCLEvent:
730 case BuiltinType::OCLClkEvent:
731 case BuiltinType::OCLQueue:
732 case BuiltinType::OCLReserveID:
733#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
734#include "clang/Basic/AArch64ACLETypes.def"
735#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
736#include "clang/Basic/PPCTypes.def"
737#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
738#include "clang/Basic/RISCVVTypes.def"
739#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
740#include "clang/Basic/AMDGPUTypes.def"
741 case BuiltinType::ShortAccum:
742 case BuiltinType::Accum:
743 case BuiltinType::LongAccum:
744 case BuiltinType::UShortAccum:
745 case BuiltinType::UAccum:
746 case BuiltinType::ULongAccum:
747 case BuiltinType::ShortFract:
748 case BuiltinType::Fract:
749 case BuiltinType::LongFract:
750 case BuiltinType::UShortFract:
751 case BuiltinType::UFract:
752 case BuiltinType::ULongFract:
753 case BuiltinType::SatShortAccum:
754 case BuiltinType::SatAccum:
755 case BuiltinType::SatLongAccum:
756 case BuiltinType::SatUShortAccum:
757 case BuiltinType::SatUAccum:
758 case BuiltinType::SatULongAccum:
759 case BuiltinType::SatShortFract:
760 case BuiltinType::SatFract:
761 case BuiltinType::SatLongFract:
762 case BuiltinType::SatUShortFract:
763 case BuiltinType::SatUFract:
764 case BuiltinType::SatULongFract:
765 case BuiltinType::BFloat16:
768 case BuiltinType::Dependent:
769#define BUILTIN_TYPE(Id, SingletonId)
770#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
771#include "clang/AST/BuiltinTypes.def"
772 llvm_unreachable(
"asking for RRTI for a placeholder type!");
774 case BuiltinType::ObjCId:
775 case BuiltinType::ObjCClass:
776 case BuiltinType::ObjCSel:
777 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
780 llvm_unreachable(
"Invalid BuiltinType Kind!");
783static bool typeInfoIsInStandardLibrary(
const PointerType *pointerTy) {
785 const auto *builtinTy = dyn_cast<BuiltinType>(pointeeTy);
796 return typeInfoIsInStandardLibrary(builtinTy);
801static bool isStandardLibraryRttiDescriptor(QualType ty) {
803 if (
const auto *builtinTy = dyn_cast<BuiltinType>(ty))
804 return typeInfoIsInStandardLibrary(builtinTy);
808 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
809 return typeInfoIsInStandardLibrary(pointerTy);
818static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
826 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
839 bool isDLLImport = rd->
hasAttr<DLLImportAttr>();
849 return !isDLLImport || cgm.
getTriple().isWindowsItaniumEnvironment();
862 llvm::SmallPtrSet<const CXXRecordDecl *, 16> nonVirtualBases;
863 llvm::SmallPtrSet<const CXXRecordDecl *, 16> virtualBases;
868static unsigned computeVmiClassTypeInfoFlags(
const CXXBaseSpecifier *base,
876 if (!bases.virtualBases.insert(baseDecl).second) {
879 flags |= VMI_DiamondShaped;
881 if (bases.nonVirtualBases.count(baseDecl))
882 flags |= VMI_NonDiamondRepeat;
886 if (!bases.nonVirtualBases.insert(baseDecl).second) {
889 flags |= VMI_NonDiamondRepeat;
891 if (bases.virtualBases.count(baseDecl))
892 flags |= VMI_NonDiamondRepeat;
897 for (
const auto &bs : baseDecl->bases())
898 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
903static unsigned computeVmiClassTypeInfoFlags(
const CXXRecordDecl *rd) {
908 for (
const auto &bs : rd->
bases())
909 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
918static bool canUseSingleInheritance(
const CXXRecordDecl *rd) {
936 return baseDecl->isEmpty() ||
941static bool isIncompleteClassType(
const RecordType *recordTy) {
942 return !recordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
956static bool containsIncompleteClassType(QualType ty) {
957 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
958 if (isIncompleteClassType(recordTy))
962 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
965 if (
const auto *memberPointerTy = dyn_cast<MemberPointerType>(ty)) {
967 if (!memberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
970 return containsIncompleteClassType(memberPointerTy->getPointeeType());
982 flags |= PTI_Volatile;
984 flags |= PTI_Restrict;
988 if (containsIncompleteClassType(ty))
989 flags |= PTI_Incomplete;
991 if (
const auto *proto = ty->
getAs<FunctionProtoType>()) {
992 if (proto->isNothrow()) {
993 flags |= PTI_Noexcept;
1001const char *vTableClassNameForType(
const CIRGenModule &cgm,
const Type *ty) {
1003 static const char *
const classTypeInfo =
1004 "_ZTVN10__cxxabiv117__class_type_infoE";
1006 static const char *
const siClassTypeInfo =
1007 "_ZTVN10__cxxabiv120__si_class_type_infoE";
1009 static const char *
const vmiClassTypeInfo =
1010 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
1013#define TYPE(Class, Base)
1014#define ABSTRACT_TYPE(Class, Base)
1015#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1016#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1017#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1018#include "clang/AST/TypeNodes.inc"
1019 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1021 case Type::LValueReference:
1022 case Type::RValueReference:
1023 llvm_unreachable(
"References shouldn't get here");
1026 case Type::DeducedTemplateSpecialization:
1027 llvm_unreachable(
"Undeduced type shouldn't get here");
1030 llvm_unreachable(
"Pipe types shouldn't get here");
1032 case Type::ArrayParameter:
1033 llvm_unreachable(
"Array Parameter types should not get here.");
1037 case Type::OverflowBehavior:
1040 case Type::ExtVector:
1041 case Type::ConstantMatrix:
1045 case Type::BlockPointer:
1046 return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
1047 case Type::ConstantArray:
1048 case Type::IncompleteArray:
1049 case Type::VariableArray:
1051 return "_ZTVN10__cxxabiv117__array_type_infoE";
1053 case Type::FunctionNoProto:
1054 case Type::FunctionProto:
1056 return "_ZTVN10__cxxabiv120__function_type_infoE";
1059 return "_ZTVN10__cxxabiv116__enum_type_infoE";
1061 case Type::Record: {
1063 ->getDefinitionOrSelf();
1066 return classTypeInfo;
1069 if (canUseSingleInheritance(rd)) {
1070 return siClassTypeInfo;
1073 return vmiClassTypeInfo;
1076 case Type::ObjCObject:
1077 cgm.
errorNYI(
"VTableClassNameForType: ObjCObject");
1080 case Type::ObjCInterface:
1081 cgm.
errorNYI(
"VTableClassNameForType: ObjCInterface");
1084 case Type::ObjCObjectPointer:
1087 return "_ZTVN10__cxxabiv119__pointer_type_infoE";
1089 case Type::MemberPointer:
1091 return "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
1093 case Type::HLSLAttributedResource:
1094 case Type::HLSLInlineSpirv:
1095 llvm_unreachable(
"HLSL doesn't support virtual functions");
1114 if (containsIncompleteClassType(ty))
1115 return cir::GlobalLinkageKind::InternalLinkage;
1119 llvm_unreachable(
"Linkage hasn't been computed!");
1124 return cir::GlobalLinkageKind::InternalLinkage;
1132 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1134 if (
const RecordType *record = dyn_cast<RecordType>(ty)) {
1138 return cir::GlobalLinkageKind::WeakODRLinkage;
1140 if (cgm.
getTriple().isWindowsItaniumEnvironment())
1141 if (rd->
hasAttr<DLLImportAttr>() &&
1142 shouldUseExternalRttiDescriptor(cgm, ty))
1143 return cir::GlobalLinkageKind::ExternalLinkage;
1149 .isWindowsGNUEnvironment())
1153 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1156 llvm_unreachable(
"Invalid linkage!");
1160CIRGenItaniumRTTIBuilder::getAddrOfTypeName(mlir::Location loc, QualType ty,
1161 cir::GlobalLinkageKind linkage) {
1163 SmallString<256>
name;
1164 llvm::raw_svector_ostream
out(name);
1170 mlir::Attribute init = builder.
getString(
1183 loc, name, initStr.getType(), linkage, align);
1189CIRGenItaniumRTTIBuilder::getAddrOfExternalRTTIDescriptor(mlir::Location loc,
1192 SmallString<256>
name;
1193 llvm::raw_svector_ostream
out(name);
1198 cir::GlobalOp gv = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
1213 cgm.
errorNYI(
"getAddrOfExternalRTTIDescriptor: hasPS4DLLImportExport");
1220void CIRGenItaniumRTTIBuilder::buildVTablePointer(mlir::Location loc,
1223 const char *vTableName = vTableClassNameForType(cgm, ty);
1227 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1234 loc, vTableName, vtableGlobalTy, cir::GlobalLinkageKind::ExternalLinkage,
1238 mlir::Attribute field{};
1240 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1242 SmallVector<mlir::Attribute, 4> offsets{
1244 auto indices = mlir::ArrayAttr::get(builder.getContext(), offsets);
1249 assert(field &&
"expected attribute");
1250 fields.push_back(field);
1255void CIRGenItaniumRTTIBuilder::buildSIClassTypeInfo(mlir::Location loc,
1256 const CXXRecordDecl *rd) {
1260 mlir::Attribute baseTypeInfo =
1261 CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1263 fields.push_back(baseTypeInfo);
1269void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc,
1270 const CXXRecordDecl *rd) {
1271 mlir::Type unsignedIntLTy =
1278 unsigned flags = computeVmiClassTypeInfoFlags(rd);
1279 fields.push_back(cir::IntAttr::get(unsignedIntLTy, flags));
1284 fields.push_back(cir::IntAttr::get(unsignedIntLTy, rd->
getNumBases()));
1317 mlir::Type offsetFlagsLTy = cgm.
convertType(offsetFlagsTy);
1319 for (
const CXXBaseSpecifier &base : rd->
bases()) {
1321 fields.push_back(CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1322 .buildTypeInfo(loc, base.
getType()));
1336 const ASTRecordLayout &layout =
1345 offsetFlags |= BCTI_Virtual;
1347 offsetFlags |= BCTI_Public;
1349 fields.push_back(cir::IntAttr::get(offsetFlagsLTy, offsetFlags));
1353void CIRGenItaniumRTTIBuilder::buildPointerTypeInfo(mlir::Location loc,
1377 mlir::Attribute flagsAttr = cir::IntAttr::get(unsignedIntTy, flags);
1378 fields.push_back(flagsAttr);
1380 mlir::Attribute pointeeTypeInfo =
1381 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, ty);
1382 fields.push_back(pointeeTypeInfo);
1385void CIRGenItaniumRTTIBuilder::buildPointerToMemberTypeInfo(
1386 mlir::Location loc,
const MemberPointerType *ty) {
1401 flags |= PTI_ContainingClassIncomplete;
1404 mlir::Attribute flagsAttr = cir::IntAttr::get(unsignedIntTy, flags);
1405 fields.push_back(flagsAttr);
1407 mlir::Attribute pointeeTypeInfo =
1408 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, pointeeTy);
1409 fields.push_back(pointeeTypeInfo);
1412 mlir::Attribute classTypeInfo =
1413 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, contextTy);
1414 fields.push_back(classTypeInfo);
1417mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(mlir::Location loc,
1423 SmallString<256>
name;
1424 llvm::raw_svector_ostream
out(name);
1427 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
1429 if (oldGV && !oldGV.isDeclaration()) {
1430 assert(!oldGV.hasAvailableExternallyLinkage() &&
1431 "available_externally typeinfos not yet implemented");
1437 if (isStandardLibraryRttiDescriptor(ty) ||
1438 shouldUseExternalRttiDescriptor(cgm, ty))
1439 return getAddrOfExternalRTTIDescriptor(loc, ty);
1449 mlir::SymbolTable::Visibility symVisibility;
1452 symVisibility = mlir::SymbolTable::Visibility::Public;
1453 else if (cxxABI.classifyRTTIUniqueness(ty, linkage) ==
1454 CIRGenItaniumCXXABI::RUK_NonUniqueHidden) {
1456 "buildTypeInfo: classifyRTTIUniqueness == RUK_NonUniqueHidden");
1461 return buildTypeInfo(loc, ty, linkage, symVisibility);
1464mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
1465 mlir::Location loc, QualType ty, cir::GlobalLinkageKind linkage,
1466 mlir::SymbolTable::Visibility visibility) {
1475 cir::GlobalOp typeName = getAddrOfTypeName(loc, ty, linkage);
1476 mlir::Attribute typeNameField;
1480 CIRGenItaniumCXXABI::RTTIUniquenessKind rttiUniqueness =
1481 cxxABI.classifyRTTIUniqueness(ty, linkage);
1482 if (rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique) {
1486 "buildTypeInfo: rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique");
1492 fields.push_back(typeNameField);
1495#define TYPE(Class, Base)
1496#define ABSTRACT_TYPE(Class, Base)
1497#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1498#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1499#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1500#include "clang/AST/TypeNodes.inc"
1501 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1506 case Type::ExtVector:
1507 case Type::ConstantMatrix:
1509 case Type::BlockPointer:
1514 case Type::LValueReference:
1515 case Type::RValueReference:
1516 llvm_unreachable(
"References shouldn't get here");
1519 case Type::DeducedTemplateSpecialization:
1520 llvm_unreachable(
"Undeduced type shouldn't get here");
1528 case Type::OverflowBehavior:
1531 case Type::ConstantArray:
1532 case Type::IncompleteArray:
1533 case Type::VariableArray:
1534 case Type::ArrayParameter:
1539 case Type::FunctionNoProto:
1540 case Type::FunctionProto:
1550 case Type::Record: {
1552 ->getDefinitionOrSelf();
1558 if (canUseSingleInheritance(rd)) {
1559 buildSIClassTypeInfo(loc, rd);
1561 buildVMIClassTypeInfo(loc, rd);
1567 case Type::ObjCObject:
1568 case Type::ObjCInterface:
1569 cgm.
errorNYI(
"buildTypeInfo: ObjCObject & ObjCInterface");
1572 case Type::ObjCObjectPointer:
1573 cgm.
errorNYI(
"buildTypeInfo: ObjCObjectPointer");
1581 case Type::MemberPointer:
1589 case Type::HLSLAttributedResource:
1590 case Type::HLSLInlineSpirv:
1591 llvm_unreachable(
"HLSL doesn't support RTTI");
1595 cir::TypeInfoAttr init = builder.
getTypeInfo(builder.getArrayAttr(fields));
1597 SmallString<256>
name;
1598 llvm::raw_svector_ostream
out(name);
1602 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
1607 gv.setLinkage(linkage);
1612 cgm.
errorNYI(
"buildTypeInfo: target hasPS4DLLImportExport");
1619 gv.setName(oldGV.getName());
1620 if (!oldGV->use_empty()) {
1621 cgm.
errorNYI(
"buildTypeInfo: old GV !use_empty");
1633 gv.setAlignmentAttr(cgm.
getSize(align));
1650 mlir::SymbolTable::setSymbolVisibility(typeName, visibility);
1655 mlir::SymbolTable::setSymbolVisibility(gv, visibility);
1664bool CIRGenItaniumCXXABI::shouldTypeidBeNullChecked(QualType srcTy) {
1668void CIRGenItaniumCXXABI::emitBadTypeidCall(CIRGenFunction &cgf,
1669 mlir::Location loc) {
1671 cir::FuncType fnTy =
1673 mlir::NamedAttrList attrs;
1674 attrs.set(cir::CIRDialect::getNoReturnAttrName(),
1680 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
1683mlir::Value CIRGenItaniumCXXABI::emitTypeid(CIRGenFunction &cgf, QualType srcTy,
1685 mlir::Type typeInfoPtrTy) {
1687 mlir::Location loc = cgm.
getLoc(classDecl->getSourceRange());
1688 mlir::Value vptr = cgf.
getVTablePtr(loc, thisPtr, classDecl);
1696 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1698 vtbl = cir::VTableGetTypeInfoOp::create(
1706mlir::Attribute CIRGenItaniumCXXABI::getAddrOfRTTIDescriptor(mlir::Location loc,
1708 return CIRGenItaniumRTTIBuilder(*
this, cgm).buildTypeInfo(loc, ty);
1713CIRGenItaniumCXXABI::RTTIUniquenessKind
1714CIRGenItaniumCXXABI::classifyRTTIUniqueness(
1715 QualType canTy, cir::GlobalLinkageKind linkage)
const {
1716 if (shouldRTTIBeUnique())
1720 if (linkage != cir::GlobalLinkageKind::LinkOnceODRLinkage &&
1721 linkage != cir::GlobalLinkageKind::WeakODRLinkage)
1729 if (linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage)
1730 return RUK_NonUniqueHidden;
1735 assert(linkage == cir::GlobalLinkageKind::WeakODRLinkage);
1736 return RUK_NonUniqueVisible;
1739void CIRGenItaniumCXXABI::emitDestructorCall(
1741 bool forVirtualBase,
bool delegating, Address thisAddr, QualType thisTy) {
1742 GlobalDecl gd(dd,
type);
1748 CIRGenCallee callee =
1755void CIRGenItaniumCXXABI::registerGlobalDtor(
const VarDecl *vd,
1771mlir::Value CIRGenItaniumCXXABI::getCXXDestructorImplicitParam(
1773 bool forVirtualBase,
bool delegating) {
1774 GlobalDecl gd(dd,
type);
1782 mlir::Value exceptionPtr = {},
1783 mlir::FlatSymbolRefAttr typeInfo = {},
1784 mlir::FlatSymbolRefAttr dtor = {}) {
1785 mlir::Block *currentBlock = builder.getInsertionBlock();
1786 mlir::Region *region = currentBlock->getParent();
1788 if (currentBlock->empty()) {
1789 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1790 cir::UnreachableOp::create(builder, loc);
1792 mlir::Block *throwBlock = builder.createBlock(region);
1794 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1795 cir::UnreachableOp::create(builder, loc);
1797 builder.setInsertionPointToEnd(currentBlock);
1798 cir::BrOp::create(builder, loc, throwBlock);
1801 (void)builder.createBlock(region);
1804void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf,
bool isNoReturn) {
1808 assert(cgf.
currSrcLoc &&
"expected source location");
1812 cgm.
errorNYI(
"emitRethrow with isNoReturn false");
1816void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf,
1817 const CXXThrowExpr *e) {
1825 cir::PointerType throwTy =
1832 mlir::TypedValue<cir::PointerType> exceptionPtr =
1833 cir::AllocExceptionOp::create(builder, subExprLoc, throwTy,
1834 builder.getI64IntegerAttr(typeSize))
1842 auto typeInfo = mlir::cast<cir::GlobalViewAttr>(
1845 assert(!typeInfo.getIndices() &&
"expected no indirection");
1855 mlir::FlatSymbolRefAttr dtor{};
1856 if (cxxrd && !cxxrd->hasTrivialDestructor()) {
1861 CXXDestructorDecl *dtorD = cxxrd->getDestructor();
1862 dtor = mlir::FlatSymbolRefAttr::get(
1874 case TargetCXXABI::GenericItanium:
1875 case TargetCXXABI::GenericAArch64:
1876 case TargetCXXABI::GenericARM:
1877 return new CIRGenItaniumCXXABI(cgm);
1879 case TargetCXXABI::AppleARM64:
1883 return new CIRGenItaniumCXXABI(cgm);
1886 llvm_unreachable(
"bad or NYI ABI kind");
1890cir::GlobalOp CIRGenItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *rd,
1892 assert(vptrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1893 cir::GlobalOp &vtable = vtables[rd];
1901 llvm::raw_svector_ostream
out(name);
1902 getMangleContext().mangleCXXVTable(rd,
out);
1911 unsigned ptrAlign = cgm.
getLangOpts().RelativeCXXABIVTables
1917 cir::GlobalLinkageKind::ExternalLinkage,
1931 "getAddrOfVTable: PS4 DLL import/export");
1937CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer(
1941 mlir::Location loc = cgf.
getLoc(srcLoc);
1944 mlir::Value vtable = cgf.
getVTablePtr(loc, thisAddr, methodDecl->getParent());
1947 mlir::Value vfunc{};
1949 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: emitVTableTypeCheckedLoad");
1953 mlir::Value vfuncLoad;
1956 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: isRelativeLayout");
1958 auto vtableSlotPtr = cir::VTableGetVirtualFnAddrOp::create(
1959 builder, loc, builder.
getPointerTo(tyPtr), vtable, vtableIndex);
1972 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: strictVTablePointers");
1977 CIRGenCallee callee(gd, vfunc.getDefiningOp());
1981mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1982 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
1983 const CXXRecordDecl *nearestVBase) {
1985 needsVTTParameter(cgf.
curGD) &&
"This class doesn't have VTT");
1996 virtualPointerIndex);
1998 auto vptrType = cir::VPtrType::get(cgf.
getBuilder().getContext());
2004CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject base,
2005 const CXXRecordDecl *vtableClass) {
2006 cir::GlobalOp vtable = getAddrOfVTable(vtableClass, CharUnits());
2010 VTableLayout::AddressPointLocation addressPoint =
2016 auto vtablePtrTy = cir::VPtrType::get(builder.getContext());
2018 return cir::VTableAddrPointOp::create(
2020 mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()),
2021 cir::AddressPointAttr::get(cgm.
getBuilder().getContext(),
2026mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor(
2027 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
2028 clang::BaseSubobject base,
const clang::CXXRecordDecl *nearestVBase) {
2031 needsVTTParameter(cgf.
curGD)) {
2032 return getVTableAddressPointInStructorWithVTT(cgf, vtableClass, base,
2035 return getVTableAddressPoint(base, vtableClass);
2038bool CIRGenItaniumCXXABI::isVirtualOffsetNeededForVTableField(
2039 CIRGenFunction &cgf, CIRGenFunction::VPtr vptr) {
2042 return needsVTTParameter(cgf.
curGD);
2045mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(
2046 mlir::Location loc, CIRGenFunction &cgf, Address thisAddr,
2047 const CXXRecordDecl *classDecl,
const CXXRecordDecl *baseClassDecl) {
2049 mlir::Value vtablePtr = cgf.
getVTablePtr(loc, thisAddr, classDecl);
2051 CharUnits vbaseOffsetOffset =
2054 mlir::Value offsetVal =
2056 auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.
uInt8PtrTy,
2057 vtableBytePtr, offsetVal);
2059 mlir::Value vbaseOffset;
2062 cgm.
errorNYI(loc,
"getVirtualBaseClassOffset: relative layout");
2078 cir::FuncType fnTy =
2088 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
2092void CIRGenItaniumCXXABI::emitBadCastCall(CIRGenFunction &cgf,
2093 mlir::Location loc) {
2109 unsigned numPublicPaths = 0;
2122 if (pathElement.Base->isVirtual())
2125 if (numPublicPaths > 1)
2132 pathElement.Base->getType()->getAsCXXRecordDecl());
2137 if (numPublicPaths == 0)
2141 if (numPublicPaths > 1)
2168 {voidPtrTy, rttiPtrTy, rttiPtrTy, ptrDiffTy}, voidPtrTy);
2170 fn->setAttr(cir::CIRDialect::getNoThrowAttrName(),
2171 mlir::UnitAttr::get(cgf.
getBuilder().getContext()));
2177 bool vtableUsesRelativeLayout = cgf.
cgm.
getLangOpts().RelativeCXXABIVTables;
2179 loc, src.
getPointer(), vtableUsesRelativeLayout);
2187 cir::PointerType destCIRTy,
2188 bool isRefCast,
Address src) {
2198 std::optional<CharUnits> offset;
2208 pathElement.Base->getType()->getAsCXXRecordDecl();
2209 if (pathElement.Base->isVirtual()) {
2223 offset = pathOffset;
2224 }
else if (offset != pathOffset) {
2240 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2242 mlir::Region *currentRegion = builder.getBlock()->getParent();
2247 builder.createBlock(currentRegion, currentRegion->end());
2250 return nullPtrValue;
2258 mlir::Value expectedVPtr =
2263 mlir::Type vptrTy = expectedVPtr.getType();
2267 mlir::Value srcVPtr = builder.
createLoad(loc, srcVPtrPtr);
2272 mlir::Value success =
2273 builder.
createCompare(loc, cir::CmpOpKind::eq, srcVPtr, expectedVPtr);
2275 auto emitCastResult = [&] {
2276 if (offset->isZero())
2283 mlir::Value strideToApply =
2286 mlir::Value resultU8Ptr = cir::PtrStrideOp::create(builder, loc, u8PtrTy,
2287 srcU8Ptr, strideToApply);
2292 mlir::Value failed = builder.
createNot(success);
2293 cir::IfOp::create(builder, loc, failed,
false,
2294 [&](mlir::OpBuilder &, mlir::Location) {
2297 return emitCastResult();
2300 return cir::TernaryOp::create(
2301 builder, loc, success,
2302 [&](mlir::OpBuilder &, mlir::Location) {
2303 auto result = emitCastResult();
2306 [&](mlir::OpBuilder &, mlir::Location) {
2307 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2317 auto srcRtti = mlir::cast<cir::GlobalViewAttr>(
2319 auto destRtti = mlir::cast<cir::GlobalViewAttr>(
2324 auto runtimeFuncRef = mlir::FlatSymbolRefAttr::get(runtimeFuncOp);
2325 auto badCastFuncRef = mlir::FlatSymbolRefAttr::get(badCastFuncOp);
2332 auto offsetHintAttr = cir::IntAttr::get(ptrdiffTy, offsetHint.
getQuantity());
2334 return cir::DynamicCastInfoAttr::get(srcRtti, destRtti, runtimeFuncRef,
2335 badCastFuncRef, offsetHintAttr);
2338mlir::Value CIRGenItaniumCXXABI::emitDynamicCast(CIRGenFunction &cgf,
2340 QualType srcRecordTy,
2341 QualType destRecordTy,
2342 cir::PointerType destCIRTy,
2343 bool isRefCast, Address src) {
2344 bool isCastToVoid = destRecordTy.
isNull();
2345 assert((!isCastToVoid || !isRefCast) &&
"cannot cast to void reference");
2358 return cir::TernaryOp::create(
2359 builder, loc, srcPtrIsNull,
2360 [&](mlir::OpBuilder, mlir::Location) {
2362 loc, builder.
getNullPtr(destCIRTy, loc).getResult());
2364 [&](mlir::OpBuilder &, mlir::Location) {
2366 *
this, cgf, loc, srcRecordTy, destRecordTy, destCIRTy,
2374 destCIRTy, isRefCast, src);
2377 cir::DynamicCastInfoAttr castInfo =
2380 isRefCast, castInfo);
2384CIRGenItaniumCXXABI::buildVirtualMethodAttr(cir::MethodType methodTy,
2385 const CXXMethodDecl *md) {
2386 assert(md->
isVirtual() &&
"only deal with virtual member functions");
2392 vtableOffset = index * 4;
2397 vtableOffset = index * pointerWidth.
getQuantity();
2400 return cir::MethodAttr::get(methodTy, vtableOffset);
2404void CIRGenItaniumCXXABI::emitVirtualObjectDelete(
2405 CIRGenFunction &cgf,
const CXXDeleteExpr *delExpr, Address ptr,
2406 QualType elementType,
const CXXDestructorDecl *dtor) {
2408 if (useGlobalDelete) {
2410 "emitVirtualObjectDelete: global delete");
2414 emitVirtualDestructorCall(cgf, dtor, dtorType, ptr, delExpr);
2419CharUnits CIRGenItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2427Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf,
2429 mlir::Value numElements,
2430 const CXXNewExpr *e,
2431 QualType elementType) {
2432 assert(requiresArrayCookie(e));
2444 CharUnits cookieSize =
2446 assert(cookieSize == getArrayCookieSizeImpl(elementType));
2450 mlir::Value baseBytePtr =
2454 CharUnits cookieOffset = cookieSize - sizeSize;
2455 mlir::Value cookiePtrValue = baseBytePtr;
2456 if (!cookieOffset.
isZero()) {
2465 Address cookiePtr(cookiePtrValue, u8Ty, cookiePtrAlignment);
2474 mlir::Value dataOffset =
2477 mlir::Value dataPtr =
2479 mlir::Value finalPtr =
2485bool CIRGenItaniumCXXABI::hasAnyUnusedVirtualInlineFunction(
2486 const CXXRecordDecl *rd)
const {
2489 for (
const auto &vtableComponent : vtableLayout.vtable_components()) {
2491 if (!vtableComponent.isUsedFunctionPointerKind())
2494 const CXXMethodDecl *method = vtableComponent.getFunctionDecl();
2496 const bool isInlined =
2502 vtableComponent.getGlobalDecl(
false));
2503 auto entry = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
2509 if (!entry || entry.isDeclaration())
2515bool CIRGenItaniumCXXABI::isVTableHidden(
const CXXRecordDecl *rd)
const {
2518 for (
const auto &vtableComponent : vtableLayout.vtable_components()) {
2519 if (vtableComponent.isRTTIKind()) {
2520 const CXXRecordDecl *rttiDecl = vtableComponent.getRTTIDecl();
2521 if (rttiDecl->
getVisibility() == Visibility::HiddenVisibility)
2523 }
else if (vtableComponent.isUsedFunctionPointerKind()) {
2524 const CXXMethodDecl *method = vtableComponent.getFunctionDecl();
2525 if (method->
getVisibility() == Visibility::HiddenVisibility &&
2533bool CIRGenItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2534 const CXXRecordDecl *rd)
const {
2542 if (isVTableHidden(rd))
2562 if (hasAnyUnusedVirtualInlineFunction(rd))
2570 for (
const auto &
b : rd->
bases()) {
2571 auto *brd =
b.getType()->getAsCXXRecordDecl();
2572 assert(brd &&
"no class for base specifier");
2573 if (
b.isVirtual() || !brd->isDynamicClass())
2575 if (!canSpeculativelyEmitVTableAsBaseClass(brd))
2583bool CIRGenItaniumCXXABI::canSpeculativelyEmitVTable(
2584 const CXXRecordDecl *rd)
const {
2585 if (!canSpeculativelyEmitVTableAsBaseClass(rd))
2593 for (
const auto &
b : rd->
vbases()) {
2594 auto *brd =
b.getType()->getAsCXXRecordDecl();
2595 assert(brd &&
"no class for base specifier");
2596 if (!brd->isDynamicClass())
2598 if (!canSpeculativelyEmitVTableAsBaseClass(brd))
2608 int64_t nonVirtualAdjustment,
2609 int64_t virtualAdjustment,
2610 bool isReturnAdjustment) {
2611 if (!nonVirtualAdjustment && !virtualAdjustment)
2615 mlir::Location loc = builder.getUnknownLoc();
2620 if (nonVirtualAdjustment && !isReturnAdjustment) {
2621 cir::ConstantOp offsetConst = builder.
getSInt64(nonVirtualAdjustment, loc);
2622 v = cir::PtrStrideOp::create(builder, loc, i8PtrTy, v, offsetConst);
2626 mlir::Value resultPtr;
2627 if (virtualAdjustment) {
2633 mlir::Value offsetPtr =
2634 cir::PtrStrideOp::create(builder, loc, i8PtrTy, vtablePtr,
2635 builder.
getSInt64(virtualAdjustment, loc));
2638 cgf.
cgm.
errorNYI(
"virtual adjustment for relative layout vtables");
2644 resultPtr = cir::PtrStrideOp::create(builder, loc, i8PtrTy, v, offset);
2651 if (nonVirtualAdjustment && isReturnAdjustment) {
2652 cir::ConstantOp offsetConst = builder.
getSInt64(nonVirtualAdjustment, loc);
2654 cir::PtrStrideOp::create(builder, loc, i8PtrTy, resultPtr, offsetConst);
2661mlir::Value CIRGenItaniumCXXABI::performThisAdjustment(
2662 CIRGenFunction &cgf, Address thisAddr,
const CXXRecordDecl *unadjustedClass,
2663 const ThunkInfo &ti) {
2670mlir::Value CIRGenItaniumCXXABI::performReturnAdjustment(
2671 CIRGenFunction &cgf, Address ret,
const CXXRecordDecl *unadjustedClass,
2672 const ReturnAdjustment &ra) {
2678bool CIRGenItaniumCXXABI::isZeroInitializable(
const MemberPointerType *mpt) {
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 performTypeAdjustment(CIRGenFunction &cgf, Address initialPtr, const CXXRecordDecl *unadjustedClass, int64_t nonVirtualAdjustment, int64_t virtualAdjustment, bool isReturnAdjustment)
static mlir::Value emitExactDynamicCast(CIRGenItaniumCXXABI &abi, CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy, cir::PointerType destCIRTy, bool isRefCast, Address src)
static void emitCallToBadCast(CIRGenFunction &cgf, mlir::Location loc)
static cir::FuncOp getItaniumDynamicCastFn(CIRGenFunction &cgf)
static StructorCIRGen getCIRGenToUse(CIRGenModule &cgm, const CXXMethodDecl *md)
static cir::FuncOp getBadCastFn(CIRGenFunction &cgf)
static RValue performReturnAdjustment(CIRGenFunction &cgf, QualType resultType, RValue rv, const ThunkInfo &thunk)
static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type)
Compute the flags for a __pbase_type_info, and remove the corresponding pieces from Type.
Defines the clang::Expr interface and subclasses for C++ expressions.
static QualType getPointeeType(const MemRegion *R)
C Language Family Type Representation.
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
mlir::Value createPtrIsNull(mlir::Value ptr)
cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base, mlir::Value stride)
cir::PointerType getPointerTo(mlir::Type ty)
cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc)
mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy)
mlir::Value getSignedInt(mlir::Location loc, int64_t val, unsigned numBits)
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)
cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind, mlir::Value lhs, mlir::Value rhs)
mlir::Value createNot(mlir::Location loc, mlir::Value value)
cir::PointerType getVoidPtrTy(clang::LangAS langAS=clang::LangAS::Default)
cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value={})
Create a yield operation.
llvm::Align getABITypeAlign(mlir::Type ty) const
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 getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const
Get a function type and produce the equivalent function type with the specified exception specificati...
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CharUnits getExnObjectAlignment() const
Return the alignment (in bytes) of the thrown exception object.
CharUnits getPreferredTypeAlignInChars(QualType T) const
Return the PreferredAlignment of a (complete) type T, in characters.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
CanQualType getCanonicalTagType(const TagDecl *TD) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
mlir::Value getPointer() const
mlir::Type getElementType() const
clang::CharUnits getAlignment() const
mlir::Type getType() const
mlir::Value emitRawPointer() const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
cir::IntType getUInt64Ty()
cir::IntType getUInt8Ty()
cir::TypeInfoAttr getTypeInfo(mlir::ArrayAttr fieldsAttr)
cir::ConstantOp getSInt64(uint64_t c, mlir::Location loc)
cir::PointerType getUInt8PtrTy()
cir::LoadOp 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::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy, std::optional< size_t > size, bool ensureNullTerm=true)
Get a cir::ConstArrayAttr for a string literal.
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
mlir::Value createVTTAddrPoint(mlir::Location loc, mlir::Type retTy, mlir::Value addr, uint64_t offset)
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()
mlir::Value emitRuntimeCall(mlir::Location loc, cir::FuncOp callee, llvm::ArrayRef< mlir::Value > args={}, mlir::NamedAttrList attrs={})
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.
static cir::GlobalOp createGlobalOp(CIRGenModule &cgm, mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::ptr::MemorySpaceAttrInterface addrSpace={}, mlir::Operation *insertPoint=nullptr)
llvm::StringRef getMangledName(clang::GlobalDecl gd)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
clang::ASTContext & getASTContext() const
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
mlir::Type convertType(clang::QualType type)
mlir::IntegerAttr getSize(CharUnits size)
CIRGenBuilderTy & getBuilder()
ItaniumVTableContext & getItaniumVTableContext()
void setGVProperties(mlir::Operation *op, const NamedDecl *d) const
Set visibility, dllimport/dllexport and dso_local.
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
const clang::TargetInfo & getTarget() const
const llvm::Triple & getTriple() const
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
cir::GlobalOp createOrReplaceCXXRuntimeVariable(mlir::Location loc, llvm::StringRef name, mlir::Type ty, cir::GlobalLinkageKind linkage, clang::CharUnits alignment)
Will return a global variable of the given type.
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::NamedAttrList extraAttrs={}, bool isLocal=false, bool assumeConvergent=false)
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
const cir::CIRDataLayout getDataLayout() const
void eraseGlobalSymbol(mlir::Operation *op)
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
const clang::CodeGenOptions & getCodeGenOpts() const
const clang::LangOptions & getLangOpts() const
void addDeferredVTable(const CXXRecordDecl *rd)
cir::FuncOp codegenCXXStructor(clang::GlobalDecl gd)
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
mlir::Operation * getGlobalValue(llvm::StringRef ref)
bool supportsCOMDAT() const
mlir::MLIRContext & getMLIRContext()
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
CIRGenCXXABI & getCXXABI() const
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
CIRGenVTables & getVTables()
cir::GlobalLinkageKind getVTableLinkage(const CXXRecordDecl *rd)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
cir::RecordType getVTableType(const clang::VTableLayout &layout)
Returns the type of a vtable with the given layout.
void createVTableInitializer(cir::GlobalOp &vtable, const clang::VTableLayout &layout, mlir::Attribute rtti, bool vtableHasLocalLinkage)
Add vtable components for the given vtable layout to the given global initializer.
void emitVTTDefinition(cir::GlobalOp vttOp, cir::GlobalLinkageKind linkage, const CXXRecordDecl *rd)
Emit the definition of the given vtable.
cir::GlobalOp getAddrOfVTT(const CXXRecordDecl *rd)
Get the address of the VTT for the given record decl.
bool isVTableExternal(const clang::CXXRecordDecl *rd)
At this point in the translation unit, does it appear that can we rely on the vtable being defined el...
uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *rd, BaseSubobject base)
Return the index in the VTT where the virtual pointer for the given subobject is located.
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
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.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
SourceRange getSourceRange() const
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
const CXXBaseSpecifier * base_class_const_iterator
Iterator that traverses the base classes of a class.
base_class_range vbases()
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
bool hasDefinition() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
const Expr * getSubExpr() const
static CanQual< Type > CreateUnsafe(QualType Other)
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 One()
One - Construct a CharUnits quantity of one.
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()
bool shouldEmitInExternalSource() const
Whether the definition of the declaration should be emitted in external sources.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
FunctionDecl * getDefinition()
Get the definition for this declaration.
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
GlobalDecl - represents a global declaration.
GlobalDecl getWithCtorType(CXXCtorType Type)
CXXCtorType getCtorType() const
GlobalDecl getWithDtorType(CXXDtorType Type)
CXXDtorType getDtorType() const
const Decl * getDecl() const
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
uint64_t getMethodVTableIndex(GlobalDecl GD)
Locate a virtual function in the vtable.
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)
Return the offset in chars (relative to the vtable address point) where the offset of the virtual bas...
virtual void mangleCXXRTTI(QualType T, raw_ostream &)=0
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
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
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isConstQualified() const
Determine whether this type is const-qualified.
Encodes a location in the source.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool hasConstructorVariants() const
Does this ABI have different entrypoints for complete-object and base-subobject constructors?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
virtual bool hasPS4DLLImportExport() const
uint64_t getPointerAlign(LangAS AddrSpace) const
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
unsigned getLongWidth() const
getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' for this target,...
SourceLocation getBeginLoc() const LLVM_READONLY
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
CXXRecordDecl * castAsCXXRecordDecl() const
Visibility getVisibility() const
Determine the visibility of this type.
Linkage getLinkage() const
Determine the linkage of this type.
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
AddressPointLocation getAddressPoint(BaseSubobject Base) const
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.
@ Address
A pointer to a ValueDecl.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
@ 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)
@ EST_None
no exception specification
@ 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 cxxabiAppleARM64CXXABI()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool pointerAuthentication()
static bool opFuncCallingConv()
static bool opFuncWillReturn()
static bool protectedVisibility()
static bool cxxabiUseARMGuardVarABI()
static bool cxxabiUseARMMethodPtrABI()
static bool setDSOLocal()
static bool vtableRelativeLayout()
const clang::CXXRecordDecl * nearestVBase
clang::CharUnits getPointerAlign() const
clang::CharUnits getSizeSize() const
cir::PointerType uInt8PtrTy
Represents an element in a path from a derived class to a base class.
union clang::ReturnAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
ThisAdjustment This
The this pointer adjustment.
unsigned AddressPointIndex
struct clang::ReturnAdjustment::VirtualAdjustment::@103031170252120233124322035264172076254313213024 Itanium
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
struct clang::ThisAdjustment::VirtualAdjustment::@106065375072164260365214033034320247050276346205 Itanium
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset.