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#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
742#include "clang/Basic/SPIRVTypes.def"
743 case BuiltinType::ShortAccum:
744 case BuiltinType::Accum:
745 case BuiltinType::LongAccum:
746 case BuiltinType::UShortAccum:
747 case BuiltinType::UAccum:
748 case BuiltinType::ULongAccum:
749 case BuiltinType::ShortFract:
750 case BuiltinType::Fract:
751 case BuiltinType::LongFract:
752 case BuiltinType::UShortFract:
753 case BuiltinType::UFract:
754 case BuiltinType::ULongFract:
755 case BuiltinType::SatShortAccum:
756 case BuiltinType::SatAccum:
757 case BuiltinType::SatLongAccum:
758 case BuiltinType::SatUShortAccum:
759 case BuiltinType::SatUAccum:
760 case BuiltinType::SatULongAccum:
761 case BuiltinType::SatShortFract:
762 case BuiltinType::SatFract:
763 case BuiltinType::SatLongFract:
764 case BuiltinType::SatUShortFract:
765 case BuiltinType::SatUFract:
766 case BuiltinType::SatULongFract:
767 case BuiltinType::BFloat16:
770 case BuiltinType::Dependent:
771#define BUILTIN_TYPE(Id, SingletonId)
772#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
773#include "clang/AST/BuiltinTypes.def"
774 llvm_unreachable(
"asking for RRTI for a placeholder type!");
776 case BuiltinType::ObjCId:
777 case BuiltinType::ObjCClass:
778 case BuiltinType::ObjCSel:
779 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
782 llvm_unreachable(
"Invalid BuiltinType Kind!");
785static bool typeInfoIsInStandardLibrary(
const PointerType *pointerTy) {
787 const auto *builtinTy = dyn_cast<BuiltinType>(pointeeTy);
798 return typeInfoIsInStandardLibrary(builtinTy);
803static bool isStandardLibraryRttiDescriptor(QualType ty) {
805 if (
const auto *builtinTy = dyn_cast<BuiltinType>(ty))
806 return typeInfoIsInStandardLibrary(builtinTy);
810 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
811 return typeInfoIsInStandardLibrary(pointerTy);
820static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
828 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
841 bool isDLLImport = rd->
hasAttr<DLLImportAttr>();
851 return !isDLLImport || cgm.
getTriple().isWindowsItaniumEnvironment();
864 llvm::SmallPtrSet<const CXXRecordDecl *, 16> nonVirtualBases;
865 llvm::SmallPtrSet<const CXXRecordDecl *, 16> virtualBases;
870static unsigned computeVmiClassTypeInfoFlags(
const CXXBaseSpecifier *base,
878 if (!bases.virtualBases.insert(baseDecl).second) {
881 flags |= VMI_DiamondShaped;
883 if (bases.nonVirtualBases.count(baseDecl))
884 flags |= VMI_NonDiamondRepeat;
888 if (!bases.nonVirtualBases.insert(baseDecl).second) {
891 flags |= VMI_NonDiamondRepeat;
893 if (bases.virtualBases.count(baseDecl))
894 flags |= VMI_NonDiamondRepeat;
899 for (
const auto &bs : baseDecl->bases())
900 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
905static unsigned computeVmiClassTypeInfoFlags(
const CXXRecordDecl *rd) {
910 for (
const auto &bs : rd->
bases())
911 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
920static bool canUseSingleInheritance(
const CXXRecordDecl *rd) {
938 return baseDecl->isEmpty() ||
943static bool isIncompleteClassType(
const RecordType *recordTy) {
944 return !recordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
958static bool containsIncompleteClassType(QualType ty) {
959 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
960 if (isIncompleteClassType(recordTy))
964 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
967 if (
const auto *memberPointerTy = dyn_cast<MemberPointerType>(ty)) {
969 if (!memberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
972 return containsIncompleteClassType(memberPointerTy->getPointeeType());
984 flags |= PTI_Volatile;
986 flags |= PTI_Restrict;
990 if (containsIncompleteClassType(ty))
991 flags |= PTI_Incomplete;
993 if (
const auto *proto = ty->
getAs<FunctionProtoType>()) {
994 if (proto->isNothrow()) {
995 flags |= PTI_Noexcept;
1003const char *vTableClassNameForType(
const CIRGenModule &cgm,
const Type *ty) {
1005 static const char *
const classTypeInfo =
1006 "_ZTVN10__cxxabiv117__class_type_infoE";
1008 static const char *
const siClassTypeInfo =
1009 "_ZTVN10__cxxabiv120__si_class_type_infoE";
1011 static const char *
const vmiClassTypeInfo =
1012 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
1015#define TYPE(Class, Base)
1016#define ABSTRACT_TYPE(Class, Base)
1017#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1018#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1019#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1020#include "clang/AST/TypeNodes.inc"
1021 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1023 case Type::LValueReference:
1024 case Type::RValueReference:
1025 llvm_unreachable(
"References shouldn't get here");
1028 case Type::DeducedTemplateSpecialization:
1029 llvm_unreachable(
"Undeduced type shouldn't get here");
1032 llvm_unreachable(
"Pipe types shouldn't get here");
1034 case Type::ArrayParameter:
1035 llvm_unreachable(
"Array Parameter types should not get here.");
1039 case Type::OverflowBehavior:
1042 case Type::ExtVector:
1043 case Type::ConstantMatrix:
1047 case Type::BlockPointer:
1048 return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
1049 case Type::ConstantArray:
1050 case Type::IncompleteArray:
1051 case Type::VariableArray:
1053 return "_ZTVN10__cxxabiv117__array_type_infoE";
1055 case Type::FunctionNoProto:
1056 case Type::FunctionProto:
1058 return "_ZTVN10__cxxabiv120__function_type_infoE";
1061 return "_ZTVN10__cxxabiv116__enum_type_infoE";
1063 case Type::Record: {
1065 ->getDefinitionOrSelf();
1068 return classTypeInfo;
1071 if (canUseSingleInheritance(rd)) {
1072 return siClassTypeInfo;
1075 return vmiClassTypeInfo;
1078 case Type::ObjCObject:
1079 cgm.
errorNYI(
"VTableClassNameForType: ObjCObject");
1082 case Type::ObjCInterface:
1083 cgm.
errorNYI(
"VTableClassNameForType: ObjCInterface");
1086 case Type::ObjCObjectPointer:
1089 return "_ZTVN10__cxxabiv119__pointer_type_infoE";
1091 case Type::MemberPointer:
1093 return "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
1095 case Type::HLSLAttributedResource:
1096 case Type::HLSLInlineSpirv:
1097 llvm_unreachable(
"HLSL doesn't support virtual functions");
1116 if (containsIncompleteClassType(ty))
1117 return cir::GlobalLinkageKind::InternalLinkage;
1121 llvm_unreachable(
"Linkage hasn't been computed!");
1126 return cir::GlobalLinkageKind::InternalLinkage;
1134 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1136 if (
const RecordType *record = dyn_cast<RecordType>(ty)) {
1140 return cir::GlobalLinkageKind::WeakODRLinkage;
1142 if (cgm.
getTriple().isWindowsItaniumEnvironment())
1143 if (rd->
hasAttr<DLLImportAttr>() &&
1144 shouldUseExternalRttiDescriptor(cgm, ty))
1145 return cir::GlobalLinkageKind::ExternalLinkage;
1151 .isWindowsGNUEnvironment())
1155 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1158 llvm_unreachable(
"Invalid linkage!");
1162CIRGenItaniumRTTIBuilder::getAddrOfTypeName(mlir::Location loc, QualType ty,
1163 cir::GlobalLinkageKind linkage) {
1165 SmallString<256>
name;
1166 llvm::raw_svector_ostream
out(name);
1172 mlir::Attribute init = builder.
getString(
1185 loc, name, initStr.getType(), linkage, align);
1191CIRGenItaniumRTTIBuilder::getAddrOfExternalRTTIDescriptor(mlir::Location loc,
1194 SmallString<256>
name;
1195 llvm::raw_svector_ostream
out(name);
1200 cir::GlobalOp gv = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
1215 cgm.
errorNYI(
"getAddrOfExternalRTTIDescriptor: hasPS4DLLImportExport");
1222void CIRGenItaniumRTTIBuilder::buildVTablePointer(mlir::Location loc,
1225 const char *vTableName = vTableClassNameForType(cgm, ty);
1229 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1236 loc, vTableName, vtableGlobalTy, cir::GlobalLinkageKind::ExternalLinkage,
1242 vTable.setConstant(
false);
1245 mlir::Attribute field{};
1247 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1249 SmallVector<mlir::Attribute, 4> offsets{
1251 auto indices = mlir::ArrayAttr::get(builder.getContext(), offsets);
1256 assert(field &&
"expected attribute");
1257 fields.push_back(field);
1262void CIRGenItaniumRTTIBuilder::buildSIClassTypeInfo(mlir::Location loc,
1263 const CXXRecordDecl *rd) {
1267 mlir::Attribute baseTypeInfo =
1268 CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1270 fields.push_back(baseTypeInfo);
1276void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc,
1277 const CXXRecordDecl *rd) {
1278 mlir::Type unsignedIntLTy =
1285 unsigned flags = computeVmiClassTypeInfoFlags(rd);
1286 fields.push_back(cir::IntAttr::get(unsignedIntLTy, flags));
1291 fields.push_back(cir::IntAttr::get(unsignedIntLTy, rd->
getNumBases()));
1324 mlir::Type offsetFlagsLTy = cgm.
convertType(offsetFlagsTy);
1326 for (
const CXXBaseSpecifier &base : rd->
bases()) {
1328 fields.push_back(CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1329 .buildTypeInfo(loc, base.
getType()));
1343 const ASTRecordLayout &layout =
1352 offsetFlags |= BCTI_Virtual;
1354 offsetFlags |= BCTI_Public;
1356 fields.push_back(cir::IntAttr::get(offsetFlagsLTy, offsetFlags));
1360void CIRGenItaniumRTTIBuilder::buildPointerTypeInfo(mlir::Location loc,
1384 mlir::Attribute flagsAttr = cir::IntAttr::get(unsignedIntTy, flags);
1385 fields.push_back(flagsAttr);
1387 mlir::Attribute pointeeTypeInfo =
1388 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, ty);
1389 fields.push_back(pointeeTypeInfo);
1392void CIRGenItaniumRTTIBuilder::buildPointerToMemberTypeInfo(
1393 mlir::Location loc,
const MemberPointerType *ty) {
1408 flags |= PTI_ContainingClassIncomplete;
1411 mlir::Attribute flagsAttr = cir::IntAttr::get(unsignedIntTy, flags);
1412 fields.push_back(flagsAttr);
1414 mlir::Attribute pointeeTypeInfo =
1415 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, pointeeTy);
1416 fields.push_back(pointeeTypeInfo);
1419 mlir::Attribute classTypeInfo =
1420 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, contextTy);
1421 fields.push_back(classTypeInfo);
1424mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(mlir::Location loc,
1430 SmallString<256>
name;
1431 llvm::raw_svector_ostream
out(name);
1434 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
1436 if (oldGV && !oldGV.isDeclaration()) {
1437 assert(!oldGV.hasAvailableExternallyLinkage() &&
1438 "available_externally typeinfos not yet implemented");
1444 if (isStandardLibraryRttiDescriptor(ty) ||
1445 shouldUseExternalRttiDescriptor(cgm, ty))
1446 return getAddrOfExternalRTTIDescriptor(loc, ty);
1456 mlir::SymbolTable::Visibility symVisibility;
1459 symVisibility = mlir::SymbolTable::Visibility::Public;
1460 else if (cxxABI.classifyRTTIUniqueness(ty, linkage) ==
1461 CIRGenItaniumCXXABI::RUK_NonUniqueHidden) {
1463 "buildTypeInfo: classifyRTTIUniqueness == RUK_NonUniqueHidden");
1468 return buildTypeInfo(loc, ty, linkage, symVisibility);
1471mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
1472 mlir::Location loc, QualType ty, cir::GlobalLinkageKind linkage,
1473 mlir::SymbolTable::Visibility visibility) {
1482 cir::GlobalOp typeName = getAddrOfTypeName(loc, ty, linkage);
1483 mlir::Attribute typeNameField;
1487 CIRGenItaniumCXXABI::RTTIUniquenessKind rttiUniqueness =
1488 cxxABI.classifyRTTIUniqueness(ty, linkage);
1489 if (rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique) {
1493 "buildTypeInfo: rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique");
1499 fields.push_back(typeNameField);
1502#define TYPE(Class, Base)
1503#define ABSTRACT_TYPE(Class, Base)
1504#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1505#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1506#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1507#include "clang/AST/TypeNodes.inc"
1508 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1513 case Type::ExtVector:
1514 case Type::ConstantMatrix:
1516 case Type::BlockPointer:
1521 case Type::LValueReference:
1522 case Type::RValueReference:
1523 llvm_unreachable(
"References shouldn't get here");
1526 case Type::DeducedTemplateSpecialization:
1527 llvm_unreachable(
"Undeduced type shouldn't get here");
1535 case Type::OverflowBehavior:
1538 case Type::ConstantArray:
1539 case Type::IncompleteArray:
1540 case Type::VariableArray:
1541 case Type::ArrayParameter:
1546 case Type::FunctionNoProto:
1547 case Type::FunctionProto:
1557 case Type::Record: {
1559 ->getDefinitionOrSelf();
1565 if (canUseSingleInheritance(rd)) {
1566 buildSIClassTypeInfo(loc, rd);
1568 buildVMIClassTypeInfo(loc, rd);
1574 case Type::ObjCObject:
1575 case Type::ObjCInterface:
1576 cgm.
errorNYI(
"buildTypeInfo: ObjCObject & ObjCInterface");
1579 case Type::ObjCObjectPointer:
1580 cgm.
errorNYI(
"buildTypeInfo: ObjCObjectPointer");
1588 case Type::MemberPointer:
1596 case Type::HLSLAttributedResource:
1597 case Type::HLSLInlineSpirv:
1598 llvm_unreachable(
"HLSL doesn't support RTTI");
1602 cir::TypeInfoAttr init = builder.
getTypeInfo(builder.getArrayAttr(fields));
1604 SmallString<256>
name;
1605 llvm::raw_svector_ostream
out(name);
1609 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
1613 gv.setLinkage(linkage);
1618 cgm.
errorNYI(
"buildTypeInfo: target hasPS4DLLImportExport");
1625 gv.setName(oldGV.getName());
1626 if (!oldGV->use_empty()) {
1627 cgm.
errorNYI(
"buildTypeInfo: old GV !use_empty");
1639 gv.setAlignmentAttr(cgm.
getSize(align));
1656 mlir::SymbolTable::setSymbolVisibility(typeName, visibility);
1661 mlir::SymbolTable::setSymbolVisibility(gv, visibility);
1670bool CIRGenItaniumCXXABI::shouldTypeidBeNullChecked(QualType srcTy) {
1674void CIRGenItaniumCXXABI::emitBadTypeidCall(CIRGenFunction &cgf,
1675 mlir::Location loc) {
1677 cir::FuncType fnTy =
1679 mlir::NamedAttrList attrs;
1680 attrs.set(cir::CIRDialect::getNoReturnAttrName(),
1686 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
1689mlir::Value CIRGenItaniumCXXABI::emitTypeid(CIRGenFunction &cgf, QualType srcTy,
1691 mlir::Type typeInfoPtrTy) {
1693 mlir::Location loc = cgm.
getLoc(classDecl->getSourceRange());
1694 mlir::Value vptr = cgf.
getVTablePtr(loc, thisPtr, classDecl);
1702 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1704 vtbl = cir::VTableGetTypeInfoOp::create(
1712mlir::Attribute CIRGenItaniumCXXABI::getAddrOfRTTIDescriptor(mlir::Location loc,
1714 return CIRGenItaniumRTTIBuilder(*
this, cgm).buildTypeInfo(loc, ty);
1719CIRGenItaniumCXXABI::RTTIUniquenessKind
1720CIRGenItaniumCXXABI::classifyRTTIUniqueness(
1721 QualType canTy, cir::GlobalLinkageKind linkage)
const {
1722 if (shouldRTTIBeUnique())
1726 if (linkage != cir::GlobalLinkageKind::LinkOnceODRLinkage &&
1727 linkage != cir::GlobalLinkageKind::WeakODRLinkage)
1735 if (linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage)
1736 return RUK_NonUniqueHidden;
1741 assert(linkage == cir::GlobalLinkageKind::WeakODRLinkage);
1742 return RUK_NonUniqueVisible;
1745void CIRGenItaniumCXXABI::emitDestructorCall(
1747 bool forVirtualBase,
bool delegating, Address thisAddr, QualType thisTy) {
1748 GlobalDecl gd(dd,
type);
1754 CIRGenCallee callee =
1761void CIRGenItaniumCXXABI::registerGlobalDtor(
const VarDecl *vd,
1777mlir::Value CIRGenItaniumCXXABI::getCXXDestructorImplicitParam(
1779 bool forVirtualBase,
bool delegating) {
1780 GlobalDecl gd(dd,
type);
1788 mlir::Value exceptionPtr = {},
1789 mlir::FlatSymbolRefAttr typeInfo = {},
1790 mlir::FlatSymbolRefAttr dtor = {}) {
1791 mlir::Block *currentBlock = builder.getInsertionBlock();
1792 mlir::Region *region = currentBlock->getParent();
1794 if (currentBlock->empty()) {
1795 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1796 cir::UnreachableOp::create(builder, loc);
1798 mlir::Block *throwBlock = builder.createBlock(region);
1800 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1801 cir::UnreachableOp::create(builder, loc);
1803 builder.setInsertionPointToEnd(currentBlock);
1804 cir::BrOp::create(builder, loc, throwBlock);
1807 (void)builder.createBlock(region);
1810void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf,
bool isNoReturn) {
1814 assert(cgf.
currSrcLoc &&
"expected source location");
1818 cgm.
errorNYI(
"emitRethrow with isNoReturn false");
1822void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf,
1823 const CXXThrowExpr *e) {
1831 cir::PointerType throwTy =
1838 mlir::TypedValue<cir::PointerType> exceptionPtr =
1839 cir::AllocExceptionOp::create(builder, subExprLoc, throwTy,
1840 builder.getI64IntegerAttr(typeSize))
1848 auto typeInfo = mlir::cast<cir::GlobalViewAttr>(
1851 assert(!typeInfo.getIndices() &&
"expected no indirection");
1861 mlir::FlatSymbolRefAttr dtor{};
1862 if (cxxrd && !cxxrd->hasTrivialDestructor()) {
1867 CXXDestructorDecl *dtorD = cxxrd->getDestructor();
1868 dtor = mlir::FlatSymbolRefAttr::get(
1880 case TargetCXXABI::GenericItanium:
1881 case TargetCXXABI::GenericAArch64:
1882 case TargetCXXABI::GenericARM:
1883 return new CIRGenItaniumCXXABI(cgm);
1885 case TargetCXXABI::AppleARM64:
1889 return new CIRGenItaniumCXXABI(cgm);
1892 llvm_unreachable(
"bad or NYI ABI kind");
1896cir::GlobalOp CIRGenItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *rd,
1898 assert(vptrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1899 cir::GlobalOp &vtable = vtables[rd];
1907 llvm::raw_svector_ostream
out(name);
1908 getMangleContext().mangleCXXVTable(rd,
out);
1917 unsigned ptrAlign = cgm.
getLangOpts().RelativeCXXABIVTables
1923 cir::GlobalLinkageKind::ExternalLinkage,
1937 "getAddrOfVTable: PS4 DLL import/export");
1943CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer(
1947 mlir::Location loc = cgf.
getLoc(srcLoc);
1950 mlir::Value vtable = cgf.
getVTablePtr(loc, thisAddr, methodDecl->getParent());
1953 mlir::Value vfunc{};
1955 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: emitVTableTypeCheckedLoad");
1959 mlir::Value vfuncLoad;
1962 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: isRelativeLayout");
1964 auto vtableSlotPtr = cir::VTableGetVirtualFnAddrOp::create(
1965 builder, loc, builder.
getPointerTo(tyPtr), vtable, vtableIndex);
1978 if (
auto loadOp = vfuncLoad.getDefiningOp<cir::LoadOp>())
1979 loadOp.setInvariant(
true);
1984 CIRGenCallee callee(gd, vfunc.getDefiningOp());
1988mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1989 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
1990 const CXXRecordDecl *nearestVBase) {
1992 needsVTTParameter(cgf.
curGD) &&
"This class doesn't have VTT");
2003 virtualPointerIndex);
2005 auto vptrType = cir::VPtrType::get(cgf.
getBuilder().getContext());
2011CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject base,
2012 const CXXRecordDecl *vtableClass) {
2013 cir::GlobalOp vtable = getAddrOfVTable(vtableClass, CharUnits());
2017 VTableLayout::AddressPointLocation addressPoint =
2023 auto vtablePtrTy = cir::VPtrType::get(builder.getContext());
2025 return cir::VTableAddrPointOp::create(
2027 mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()),
2028 cir::AddressPointAttr::get(cgm.
getBuilder().getContext(),
2033mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor(
2034 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
2035 clang::BaseSubobject base,
const clang::CXXRecordDecl *nearestVBase) {
2038 needsVTTParameter(cgf.
curGD)) {
2039 return getVTableAddressPointInStructorWithVTT(cgf, vtableClass, base,
2042 return getVTableAddressPoint(base, vtableClass);
2045bool CIRGenItaniumCXXABI::isVirtualOffsetNeededForVTableField(
2046 CIRGenFunction &cgf, CIRGenFunction::VPtr vptr) {
2049 return needsVTTParameter(cgf.
curGD);
2052mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(
2053 mlir::Location loc, CIRGenFunction &cgf, Address thisAddr,
2054 const CXXRecordDecl *classDecl,
const CXXRecordDecl *baseClassDecl) {
2056 mlir::Value vtablePtr = cgf.
getVTablePtr(loc, thisAddr, classDecl);
2058 CharUnits vbaseOffsetOffset =
2061 mlir::Value offsetVal =
2063 auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.
uInt8PtrTy,
2064 vtableBytePtr, offsetVal);
2066 mlir::Value vbaseOffset;
2069 cgm.
errorNYI(loc,
"getVirtualBaseClassOffset: relative layout");
2085 cir::FuncType fnTy =
2094 mlir::NamedAttrList attrs;
2095 attrs.set(cir::CIRDialect::getNoReturnAttrName(),
2099 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
2103void CIRGenItaniumCXXABI::emitBadCastCall(CIRGenFunction &cgf,
2104 mlir::Location loc) {
2120 unsigned numPublicPaths = 0;
2133 if (pathElement.Base->isVirtual())
2136 if (numPublicPaths > 1)
2143 pathElement.Base->getType()->getAsCXXRecordDecl());
2148 if (numPublicPaths == 0)
2152 if (numPublicPaths > 1)
2179 {voidPtrTy, rttiPtrTy, rttiPtrTy, ptrDiffTy}, voidPtrTy);
2181 fn->setAttr(cir::CIRDialect::getNoThrowAttrName(),
2182 mlir::UnitAttr::get(cgf.
getBuilder().getContext()));
2188 bool vtableUsesRelativeLayout = cgf.
cgm.
getLangOpts().RelativeCXXABIVTables;
2190 loc, src.
getPointer(), vtableUsesRelativeLayout);
2198 cir::PointerType destCIRTy,
2199 bool isRefCast,
Address src) {
2209 std::optional<CharUnits> offset;
2219 pathElement.Base->getType()->getAsCXXRecordDecl();
2220 if (pathElement.Base->isVirtual()) {
2234 offset = pathOffset;
2235 }
else if (offset != pathOffset) {
2251 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2253 mlir::Region *currentRegion = builder.getBlock()->getParent();
2258 builder.createBlock(currentRegion, currentRegion->end());
2261 return nullPtrValue;
2269 mlir::Value expectedVPtr =
2274 mlir::Type vptrTy = expectedVPtr.getType();
2278 mlir::Value srcVPtr = builder.
createLoad(loc, srcVPtrPtr);
2283 mlir::Value success =
2284 builder.
createCompare(loc, cir::CmpOpKind::eq, srcVPtr, expectedVPtr);
2286 auto emitCastResult = [&] {
2287 if (offset->isZero())
2294 mlir::Value strideToApply =
2297 mlir::Value resultU8Ptr = cir::PtrStrideOp::create(builder, loc, u8PtrTy,
2298 srcU8Ptr, strideToApply);
2303 mlir::Value failed = builder.
createNot(success);
2304 cir::IfOp::create(builder, loc, failed,
false,
2305 [&](mlir::OpBuilder &, mlir::Location) {
2308 return emitCastResult();
2311 return cir::TernaryOp::create(
2312 builder, loc, success,
2313 [&](mlir::OpBuilder &, mlir::Location) {
2314 auto result = emitCastResult();
2317 [&](mlir::OpBuilder &, mlir::Location) {
2318 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2328 auto srcRtti = mlir::cast<cir::GlobalViewAttr>(
2330 auto destRtti = mlir::cast<cir::GlobalViewAttr>(
2335 auto runtimeFuncRef = mlir::FlatSymbolRefAttr::get(runtimeFuncOp);
2336 auto badCastFuncRef = mlir::FlatSymbolRefAttr::get(badCastFuncOp);
2343 auto offsetHintAttr = cir::IntAttr::get(ptrdiffTy, offsetHint.
getQuantity());
2345 return cir::DynamicCastInfoAttr::get(srcRtti, destRtti, runtimeFuncRef,
2346 badCastFuncRef, offsetHintAttr);
2349mlir::Value CIRGenItaniumCXXABI::emitDynamicCast(CIRGenFunction &cgf,
2351 QualType srcRecordTy,
2352 QualType destRecordTy,
2353 cir::PointerType destCIRTy,
2354 bool isRefCast, Address src) {
2355 bool isCastToVoid = destRecordTy.
isNull();
2356 assert((!isCastToVoid || !isRefCast) &&
"cannot cast to void reference");
2369 return cir::TernaryOp::create(
2370 builder, loc, srcPtrIsNull,
2371 [&](mlir::OpBuilder, mlir::Location) {
2373 loc, builder.
getNullPtr(destCIRTy, loc).getResult());
2375 [&](mlir::OpBuilder &, mlir::Location) {
2377 *
this, cgf, loc, srcRecordTy, destRecordTy, destCIRTy,
2385 destCIRTy, isRefCast, src);
2388 cir::DynamicCastInfoAttr castInfo =
2391 isRefCast, castInfo);
2395CIRGenItaniumCXXABI::buildVirtualMethodAttr(cir::MethodType methodTy,
2396 const CXXMethodDecl *md) {
2397 assert(md->
isVirtual() &&
"only deal with virtual member functions");
2403 vtableOffset = index * 4;
2408 vtableOffset = index * pointerWidth.
getQuantity();
2411 return cir::MethodAttr::get(methodTy, vtableOffset);
2415void CIRGenItaniumCXXABI::emitVirtualObjectDelete(
2416 CIRGenFunction &cgf,
const CXXDeleteExpr *delExpr, Address ptr,
2417 QualType elementType,
const CXXDestructorDecl *dtor) {
2419 if (useGlobalDelete) {
2421 "emitVirtualObjectDelete: global delete");
2425 emitVirtualDestructorCall(cgf, dtor, dtorType, ptr, delExpr);
2430CharUnits CIRGenItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2438Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf,
2440 mlir::Value numElements,
2441 const CXXNewExpr *e,
2442 QualType elementType) {
2443 assert(requiresArrayCookie(e));
2455 CharUnits cookieSize =
2457 assert(cookieSize == getArrayCookieSizeImpl(elementType));
2461 mlir::Value baseBytePtr =
2465 CharUnits cookieOffset = cookieSize - sizeSize;
2466 mlir::Value cookiePtrValue = baseBytePtr;
2467 if (!cookieOffset.
isZero()) {
2476 Address cookiePtr(cookiePtrValue, u8Ty, cookiePtrAlignment);
2485 mlir::Value dataOffset =
2488 mlir::Value dataPtr =
2490 mlir::Value finalPtr =
2496bool CIRGenItaniumCXXABI::hasAnyUnusedVirtualInlineFunction(
2497 const CXXRecordDecl *rd)
const {
2500 for (
const auto &vtableComponent : vtableLayout.vtable_components()) {
2502 if (!vtableComponent.isUsedFunctionPointerKind())
2505 const CXXMethodDecl *method = vtableComponent.getFunctionDecl();
2507 const bool isInlined =
2513 vtableComponent.getGlobalDecl(
false));
2514 auto entry = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
2520 if (!entry || entry.isDeclaration())
2526bool CIRGenItaniumCXXABI::isVTableHidden(
const CXXRecordDecl *rd)
const {
2529 for (
const auto &vtableComponent : vtableLayout.vtable_components()) {
2530 if (vtableComponent.isRTTIKind()) {
2531 const CXXRecordDecl *rttiDecl = vtableComponent.getRTTIDecl();
2532 if (rttiDecl->
getVisibility() == Visibility::HiddenVisibility)
2534 }
else if (vtableComponent.isUsedFunctionPointerKind()) {
2535 const CXXMethodDecl *method = vtableComponent.getFunctionDecl();
2536 if (method->
getVisibility() == Visibility::HiddenVisibility &&
2544bool CIRGenItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2545 const CXXRecordDecl *rd)
const {
2553 if (isVTableHidden(rd))
2573 if (hasAnyUnusedVirtualInlineFunction(rd))
2581 for (
const auto &b : rd->
bases()) {
2582 auto *brd = b.getType()->getAsCXXRecordDecl();
2583 assert(brd &&
"no class for base specifier");
2584 if (b.isVirtual() || !brd->isDynamicClass())
2586 if (!canSpeculativelyEmitVTableAsBaseClass(brd))
2594bool CIRGenItaniumCXXABI::canSpeculativelyEmitVTable(
2595 const CXXRecordDecl *rd)
const {
2596 if (!canSpeculativelyEmitVTableAsBaseClass(rd))
2604 for (
const auto &b : rd->
vbases()) {
2605 auto *brd = b.getType()->getAsCXXRecordDecl();
2606 assert(brd &&
"no class for base specifier");
2607 if (!brd->isDynamicClass())
2609 if (!canSpeculativelyEmitVTableAsBaseClass(brd))
2619 int64_t nonVirtualAdjustment,
2620 int64_t virtualAdjustment,
2621 bool isReturnAdjustment) {
2622 if (!nonVirtualAdjustment && !virtualAdjustment)
2626 mlir::Location loc = builder.getUnknownLoc();
2631 if (nonVirtualAdjustment && !isReturnAdjustment) {
2632 cir::ConstantOp offsetConst = builder.
getSInt64(nonVirtualAdjustment, loc);
2633 v = cir::PtrStrideOp::create(builder, loc, i8PtrTy, v, offsetConst);
2637 mlir::Value resultPtr;
2638 if (virtualAdjustment) {
2644 mlir::Value offsetPtr =
2645 cir::PtrStrideOp::create(builder, loc, i8PtrTy, vtablePtr,
2646 builder.
getSInt64(virtualAdjustment, loc));
2649 cgf.
cgm.
errorNYI(
"virtual adjustment for relative layout vtables");
2655 resultPtr = cir::PtrStrideOp::create(builder, loc, i8PtrTy, v, offset);
2662 if (nonVirtualAdjustment && isReturnAdjustment) {
2663 cir::ConstantOp offsetConst = builder.
getSInt64(nonVirtualAdjustment, loc);
2665 cir::PtrStrideOp::create(builder, loc, i8PtrTy, resultPtr, offsetConst);
2672mlir::Value CIRGenItaniumCXXABI::performThisAdjustment(
2673 CIRGenFunction &cgf, Address thisAddr,
const CXXRecordDecl *unadjustedClass,
2674 const ThunkInfo &ti) {
2681mlir::Value CIRGenItaniumCXXABI::performReturnAdjustment(
2682 CIRGenFunction &cgf, Address ret,
const CXXRecordDecl *unadjustedClass,
2683 const ReturnAdjustment &ra) {
2689bool 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 createLoad(mlir::Location loc, Address addr, bool isVolatile=false, bool isNontemporal=false)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, bool isNontemporal=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
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)
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)
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.
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
cir::GlobalOp createGlobalOp(mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::ptr::MemorySpaceAttrInterface addrSpace={}, mlir::Operation *insertPoint=nullptr)
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.
Top level wrappers for InstallAPI frontend operations.
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.