17#include "mlir/IR/Types.h"
19#include "llvm/ADT/SmallVector.h"
26 : cgm(cgm), vtContext(cgm.getASTContext().getVTableContext()) {}
34mlir::Type CIRGenVTables::getVTableComponentType() {
40 mlir::Type componentType = getVTableComponentType();
42 tys.push_back(cir::ArrayType::get(componentType, layout.
getVTableSize(i)));
68mlir::Attribute CIRGenVTables::getVTableComponent(
69 const VTableLayout &layout,
unsigned componentIndex, mlir::Attribute rtti,
70 unsigned &nextVTableThunkIndex,
unsigned vtableAddressPoint,
71 bool vtableHasLocalLinkage) {
80 cgm.
errorNYI(
"getVTableComponent: VCallOffset");
81 return mlir::Attribute();
83 cgm.
errorNYI(
"getVTableComponent: VBaseOffset");
84 return mlir::Attribute();
86 cgm.
errorNYI(
"getVTableComponent: CompleteDtorPointer");
87 return mlir::Attribute();
89 cgm.
errorNYI(
"getVTableComponent: DeletingDtorPointer");
90 return mlir::Attribute();
92 cgm.
errorNYI(
"getVTableComponent: UnusedFunctionPointer");
93 return mlir::Attribute();
100 assert((mlir::isa<cir::GlobalViewAttr>(rtti) ||
101 mlir::isa<cir::ConstPtrAttr>(rtti)) &&
102 "expected GlobalViewAttr or ConstPtrAttr");
111 if (cast<CXXMethodDecl>(gd.
getDecl())->isPureVirtual()) {
112 cgm.
errorNYI(
"getVTableComponent: CK_FunctionPointer: pure virtual");
113 return mlir::Attribute();
114 }
else if (cast<CXXMethodDecl>(gd.
getDecl())->isDeleted()) {
115 cgm.
errorNYI(
"getVTableComponent: CK_FunctionPointer: deleted virtual");
116 return mlir::Attribute();
117 }
else if (nextVTableThunkIndex < layout.
vtable_thunks().size() &&
120 cgm.
errorNYI(
"getVTableComponent: CK_FunctionPointer: thunk");
121 return mlir::Attribute();
128 return cir::GlobalViewAttr::get(
130 mlir::FlatSymbolRefAttr::get(fnPtr.getSymNameAttr()));
134 llvm_unreachable(
"Unexpected vtable component kind");
139 mlir::Attribute rtti,
140 bool vtableHasLocalLinkage) {
141 mlir::Type componentType = getVTableComponentType();
145 unsigned nextVTableThunkIndex = 0;
150 for (
auto [vtableIndex, addressPoint] : llvm::enumerate(addressPoints)) {
153 size_t vtableEnd = vtableStart + layout.
getVTableSize(vtableIndex);
155 components.reserve(vtableEnd - vtableStart);
156 for (
size_t componentIndex : llvm::seq(vtableStart, vtableEnd))
157 components.push_back(
158 getVTableComponent(layout, componentIndex, rtti, nextVTableThunkIndex,
159 addressPoint, vtableHasLocalLinkage));
161 auto arr = cir::ConstArrayAttr::get(
162 cir::ArrayType::get(componentType, components.size()),
163 mlir::ArrayAttr::get(mlirContext, components));
164 vtables.push_back(arr);
168 const auto members = mlir::ArrayAttr::get(mlirContext, vtables);
172 auto vtableAttr = cir::VTableAttr::get(record.getType(), record.getMembers());
183 return cir::GlobalLinkageKind::InternalLinkage;
188 if (keyFunction && !rd->
hasAttr<DLLImportAttr>()) {
193 keyFunction = cast<CXXMethodDecl>(def);
201 (def || codeGenOpts.OptimizationLevel > 0 ||
202 codeGenOpts.getDebugInfo() != llvm::codegenoptions::NoDebugInfo) &&
203 "Shouldn't query vtable linkage without key function, "
204 "optimizations, or debug info");
205 if (!def && codeGenOpts.OptimizationLevel > 0)
206 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
210 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
211 : cir::GlobalLinkageKind::InternalLinkage;
212 return cir::GlobalLinkageKind::ExternalLinkage;
215 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
218 return cir::GlobalLinkageKind::WeakODRLinkage;
221 llvm_unreachable(
"Should not have been asked to emit this");
226 return cir::GlobalLinkageKind::ExternalLinkage;
240 if (!thunkInfoVector)
mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value)
const CXXMethodDecl * getCurrentKeyFunction(const CXXRecordDecl *RD)
Get our current best idea for the key function of the given record decl, or nullptr if there isn't on...
const LangOptions & getLangOpts() const
cir::ConstRecordAttr getAnonConstRecord(mlir::ArrayAttr arrayAttr, bool packed=false, bool padded=false, mlir::Type ty={})
cir::PointerType getUInt8PtrTy()
cir::RecordType getAnonRecordTy(llvm::ArrayRef< mlir::Type > members, bool packed=false, bool padded=false)
Get a CIR anonymous record type.
virtual void emitVTableDefinitions(CIRGenVTables &cgvt, const CXXRecordDecl *rd)=0
Emits the VTable definitions required for the given record type.
This class organizes the cross-function state that is used while generating CIR code.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
CIRGenBuilderTy & getBuilder()
mlir::Type getVTableComponentType()
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
mlir::MLIRContext & getMLIRContext()
CIRGenCXXABI & getCXXABI() const
void emitVTable(const CXXRecordDecl *rd)
This is a callback from Sema to tell us that a particular vtable is required to be emitted in this tr...
cir::GlobalLinkageKind getVTableLinkage(const CXXRecordDecl *rd)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
cir::FuncType getFunctionTypeForVTable(clang::GlobalDecl gd)
Get the CIR function type for use in a vtable, given a CXXMethodDecl.
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 emitThunks(GlobalDecl gd)
Emit the associated thunks for the given global decl.
CIRGenVTables(CIRGenModule &cgm)
void generateClassData(const CXXRecordDecl *rd)
Generate all the class data required to be generated upon definition of a KeyFunction.
Represents a static or instance method of a struct/union/class.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Represents a C++ struct/union/class.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Represents a function declaration or definition.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template instantiation this function represents.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
GlobalDecl - represents a global declaration.
CXXDtorType getDtorType() const
const Decl * getDecl() const
bool isExternallyVisible() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Represents a single component in a vtable.
GlobalDecl getGlobalDecl() const
Kind getKind() const
Get the kind of this vtable component.
@ CK_DeletingDtorPointer
A pointer to the deleting destructor.
@ CK_UnusedFunctionPointer
An entry that is never used.
@ CK_CompleteDtorPointer
A pointer to the complete destructor.
CharUnits getOffsetToTop() const
virtual const ThunkInfoVectorTy * getThunkInfo(GlobalDecl GD)
const AddressPointsIndexMapTy & getAddressPointIndices() const
size_t getVTableOffset(size_t i) const
ArrayRef< VTableComponent > vtable_components() const
size_t getNumVTables() const
ArrayRef< VTableThunkTy > vtable_thunks() const
size_t getVTableSize(size_t i) const
The JSON file list parser is used to communicate input to InstallAPI.
@ Dtor_Base
Base object dtor.
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Diagnostic wrappers for TextAPI types for error reporting.
static bool cudaSupport()
static bool generateDebugInfo()
static bool vtableRelativeLayout()