clang 22.0.0git
CIRGenVTables.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This contains code dealing with C++ code generation of virtual tables.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CIRGenVTables.h"
14
15#include "CIRGenCXXABI.h"
16#include "CIRGenModule.h"
17#include "mlir/IR/Types.h"
20#include "llvm/ADT/SmallVector.h"
21
22using namespace llvm;
23using namespace clang;
24using namespace clang::CIRGen;
25
27 : cgm(cgm), vtContext(cgm.getASTContext().getVTableContext()) {}
28
30 mlir::Type ptrTy = builder.getUInt8PtrTy();
32 return ptrTy;
33}
34
35mlir::Type CIRGenVTables::getVTableComponentType() {
36 return cgm.getVTableComponentType();
37}
38
39cir::RecordType CIRGenVTables::getVTableType(const VTableLayout &layout) {
41 mlir::Type componentType = getVTableComponentType();
42 for (unsigned i = 0, e = layout.getNumVTables(); i != e; ++i)
43 tys.push_back(cir::ArrayType::get(componentType, layout.getVTableSize(i)));
44
45 // FIXME(cir): should VTableLayout be encoded like we do for some
46 // AST nodes?
47 return cgm.getBuilder().getAnonRecordTy(tys, /*incomplete=*/false);
48}
49
50/// This is a callback from Sema to tell us that a particular vtable is
51/// required to be emitted in this translation unit.
52///
53/// This is only called for vtables that _must_ be emitted (mainly due to key
54/// functions). For weak vtables, CodeGen tracks when they are needed and
55/// emits them as-needed.
57 vtables.generateClassData(rd);
58}
59
62
63 if (rd->getNumVBases())
65
66 cgm.getCXXABI().emitVTableDefinitions(*this, rd);
67}
68
69mlir::Attribute CIRGenVTables::getVTableComponent(
70 const VTableLayout &layout, unsigned componentIndex, mlir::Attribute rtti,
71 unsigned &nextVTableThunkIndex, unsigned vtableAddressPoint,
72 bool vtableHasLocalLinkage) {
73 const VTableComponent &component = layout.vtable_components()[componentIndex];
74
75 CIRGenBuilderTy builder = cgm.getBuilder();
76
78
79 switch (component.getKind()) {
81 cgm.errorNYI("getVTableComponent: CompleteDtorPointer");
82 return mlir::Attribute();
84 cgm.errorNYI("getVTableComponent: DeletingDtorPointer");
85 return mlir::Attribute();
87 cgm.errorNYI("getVTableComponent: UnusedFunctionPointer");
88 return mlir::Attribute();
89
91 return builder.getConstPtrAttr(builder.getUInt8PtrTy(),
92 component.getVCallOffset().getQuantity());
93
95 return builder.getConstPtrAttr(builder.getUInt8PtrTy(),
96 component.getVBaseOffset().getQuantity());
97
99 return builder.getConstPtrAttr(builder.getUInt8PtrTy(),
100 component.getOffsetToTop().getQuantity());
101
103 assert((mlir::isa<cir::GlobalViewAttr>(rtti) ||
104 mlir::isa<cir::ConstPtrAttr>(rtti)) &&
105 "expected GlobalViewAttr or ConstPtrAttr");
106 return rtti;
107
109 GlobalDecl gd = component.getGlobalDecl();
110
112
113 cir::FuncOp fnPtr;
114 if (cast<CXXMethodDecl>(gd.getDecl())->isPureVirtual()) {
115 cgm.errorNYI("getVTableComponent: CK_FunctionPointer: pure virtual");
116 return mlir::Attribute();
117 } else if (cast<CXXMethodDecl>(gd.getDecl())->isDeleted()) {
118 cgm.errorNYI("getVTableComponent: CK_FunctionPointer: deleted virtual");
119 return mlir::Attribute();
120 } else if (nextVTableThunkIndex < layout.vtable_thunks().size() &&
121 layout.vtable_thunks()[nextVTableThunkIndex].first ==
122 componentIndex) {
123 cgm.errorNYI("getVTableComponent: CK_FunctionPointer: thunk");
124 return mlir::Attribute();
125 } else {
126 // Otherwise we can use the method definition directly.
127 cir::FuncType fnTy = cgm.getTypes().getFunctionTypeForVTable(gd);
128 fnPtr = cgm.getAddrOfFunction(gd, fnTy, /*ForVTable=*/true);
129 }
130
131 return cir::GlobalViewAttr::get(
132 builder.getUInt8PtrTy(),
133 mlir::FlatSymbolRefAttr::get(fnPtr.getSymNameAttr()));
134 }
135 }
136
137 llvm_unreachable("Unexpected vtable component kind");
138}
139
140void CIRGenVTables::createVTableInitializer(cir::GlobalOp &vtableOp,
141 const clang::VTableLayout &layout,
142 mlir::Attribute rtti,
143 bool vtableHasLocalLinkage) {
144 mlir::Type componentType = getVTableComponentType();
145
146 const llvm::SmallVectorImpl<unsigned> &addressPoints =
147 layout.getAddressPointIndices();
148 unsigned nextVTableThunkIndex = 0;
149
150 mlir::MLIRContext *mlirContext = &cgm.getMLIRContext();
151
153 for (auto [vtableIndex, addressPoint] : llvm::enumerate(addressPoints)) {
154 // Build a ConstArrayAttr of the vtable components.
155 size_t vtableStart = layout.getVTableOffset(vtableIndex);
156 size_t vtableEnd = vtableStart + layout.getVTableSize(vtableIndex);
158 components.reserve(vtableEnd - vtableStart);
159 for (size_t componentIndex : llvm::seq(vtableStart, vtableEnd))
160 components.push_back(
161 getVTableComponent(layout, componentIndex, rtti, nextVTableThunkIndex,
162 addressPoint, vtableHasLocalLinkage));
163 // Create a ConstArrayAttr to hold the components.
164 auto arr = cir::ConstArrayAttr::get(
165 cir::ArrayType::get(componentType, components.size()),
166 mlir::ArrayAttr::get(mlirContext, components));
167 vtables.push_back(arr);
168 }
169
170 // Create a ConstRecordAttr to hold the component array.
171 const auto members = mlir::ArrayAttr::get(mlirContext, vtables);
172 cir::ConstRecordAttr record = cgm.getBuilder().getAnonConstRecord(members);
173
174 // Create a VTableAttr
175 auto vtableAttr = cir::VTableAttr::get(record.getType(), record.getMembers());
176
177 // Add the vtable initializer to the vtable global op.
178 cgm.setInitializer(vtableOp, vtableAttr);
179}
180
182 const CXXRecordDecl *rd, const BaseSubobject &base, bool baseIsVirtual,
183 cir::GlobalLinkageKind linkage, VTableAddressPointsMapTy &addressPoints) {
185
186 std::unique_ptr<VTableLayout> vtLayout(
187 getItaniumVTableContext().createConstructionVTableLayout(
188 base.getBase(), base.getBaseOffset(), baseIsVirtual, rd));
189
190 // Add the address points.
191 addressPoints = vtLayout->getAddressPoints();
192
193 // Get the mangled construction vtable name.
194 SmallString<256> outName;
195 llvm::raw_svector_ostream out(outName);
196 cast<ItaniumMangleContext>(cgm.getCXXABI().getMangleContext())
197 .mangleCXXCtorVTable(rd, base.getBaseOffset().getQuantity(),
198 base.getBase(), out);
199 SmallString<256> name(outName);
200
202
203 cir::RecordType vtType = getVTableType(*vtLayout);
204
205 // Construction vtable symbols are not part of the Itanium ABI, so we cannot
206 // guarantee that they actually will be available externally. Instead, when
207 // emitting an available_externally VTT, we provide references to an internal
208 // linkage construction vtable. The ABI only requires complete-object vtables
209 // to be the same for all instances of a type, not construction vtables.
210 if (linkage == cir::GlobalLinkageKind::AvailableExternallyLinkage)
211 linkage = cir::GlobalLinkageKind::InternalLinkage;
212
213 llvm::Align align = cgm.getDataLayout().getABITypeAlign(vtType);
214 mlir::Location loc = cgm.getLoc(rd->getSourceRange());
215
216 // Create the variable that will hold the construction vtable.
217 cir::GlobalOp vtable = cgm.createOrReplaceCXXRuntimeVariable(
218 loc, name, vtType, linkage, CharUnits::fromQuantity(align));
219
220 // V-tables are always unnamed_addr.
222
223 mlir::Attribute rtti = cgm.getAddrOfRTTIDescriptor(
224 loc, cgm.getASTContext().getCanonicalTagType(base.getBase()));
225
226 // Create and set the initializer.
227 createVTableInitializer(vtable, *vtLayout, rtti,
228 cir::isLocalLinkage(vtable.getLinkage()));
229
230 // Set properties only after the initializer has been set to ensure that the
231 // GV is treated as definition and not declaration.
232 assert(!vtable.isDeclaration() && "Shouldn't set properties on declaration");
233 cgm.setGVProperties(vtable, rd);
234
237
238 return vtable;
239}
240
241/// Compute the required linkage of the vtable for the given class.
242///
243/// Note that we only call this at the end of the translation unit.
244cir::GlobalLinkageKind CIRGenModule::getVTableLinkage(const CXXRecordDecl *rd) {
245 if (!rd->isExternallyVisible())
246 return cir::GlobalLinkageKind::InternalLinkage;
247
248 // We're at the end of the translation unit, so the current key
249 // function is fully correct.
250 const CXXMethodDecl *keyFunction = astContext.getCurrentKeyFunction(rd);
251 if (keyFunction && !rd->hasAttr<DLLImportAttr>()) {
252 // If this class has a key function, use that to determine the
253 // linkage of the vtable.
254 const FunctionDecl *def = nullptr;
255 if (keyFunction->hasBody(def))
256 keyFunction = cast<CXXMethodDecl>(def);
257
258 // All of the cases below do something different with AppleKext enabled.
260 switch (keyFunction->getTemplateSpecializationKind()) {
261 case TSK_Undeclared:
263 assert(
264 (def || codeGenOpts.OptimizationLevel > 0 ||
265 codeGenOpts.getDebugInfo() != llvm::codegenoptions::NoDebugInfo) &&
266 "Shouldn't query vtable linkage without key function, "
267 "optimizations, or debug info");
268 if (!def && codeGenOpts.OptimizationLevel > 0)
269 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
270
271 if (keyFunction->isInlined())
272 return !astContext.getLangOpts().AppleKext
273 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
274 : cir::GlobalLinkageKind::InternalLinkage;
275 return cir::GlobalLinkageKind::ExternalLinkage;
276
278 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
279
281 return cir::GlobalLinkageKind::WeakODRLinkage;
282
284 llvm_unreachable("Should not have been asked to emit this");
285 }
286 }
287
288 errorNYI(rd->getSourceRange(), "getVTableLinkage: no key function");
289 return cir::GlobalLinkageKind::ExternalLinkage;
290}
291
293 assert(rd->getNumVBases() && "Only classes with virtual bases need a VTT");
294
295 SmallString<256> outName;
296 llvm::raw_svector_ostream out(outName);
297 cast<ItaniumMangleContext>(cgm.getCXXABI().getMangleContext())
298 .mangleCXXVTT(rd, out);
299 StringRef name = outName.str();
300
301 // This will also defer the definition of the VTT.
302 (void)cgm.getCXXABI().getAddrOfVTable(rd, CharUnits());
303
304 VTTBuilder builder(cgm.getASTContext(), rd, /*GenerateDefinition=*/false);
305
306 auto arrayType = cir::ArrayType::get(cgm.getBuilder().getUInt8PtrTy(),
307 builder.getVTTComponents().size());
308 llvm::Align align =
310 cir::GlobalOp vtt = cgm.createOrReplaceCXXRuntimeVariable(
311 cgm.getLoc(rd->getSourceRange()), name, arrayType,
312 cir::GlobalLinkageKind::ExternalLinkage, CharUnits::fromQuantity(align));
313 cgm.setGVProperties(vtt, rd);
314 return vtt;
315}
316
317static cir::GlobalOp
319 const CXXRecordDecl *mostDerivedClass,
320 const VTTVTable &vtable, cir::GlobalLinkageKind linkage,
321 VTableLayout::AddressPointsMapTy &addressPoints) {
322 if (vtable.getBase() == mostDerivedClass) {
323 assert(vtable.getBaseOffset().isZero() &&
324 "Most derived class vtable must have a zero offset!");
325 // This is a regular vtable.
326 return cgm.getCXXABI().getAddrOfVTable(mostDerivedClass, CharUnits());
327 }
328 return cgvt.generateConstructionVTable(
329 mostDerivedClass, vtable.getBaseSubobject(), vtable.isVirtual(), linkage,
330 addressPoints);
331}
332
333/// Emit the definition of the given vtable.
334void CIRGenVTables::emitVTTDefinition(cir::GlobalOp vttOp,
335 cir::GlobalLinkageKind linkage,
336 const CXXRecordDecl *rd) {
337 VTTBuilder builder(cgm.getASTContext(), rd, /*GenerateDefinition=*/true);
338
339 mlir::MLIRContext *mlirContext = &cgm.getMLIRContext();
340
341 auto arrayType = cir::ArrayType::get(cgm.getBuilder().getUInt8PtrTy(),
342 builder.getVTTComponents().size());
343
345 SmallVector<VTableAddressPointsMapTy> vtableAddressPoints;
346 for (const VTTVTable &vtt : builder.getVTTVTables()) {
347 vtableAddressPoints.push_back(VTableAddressPointsMapTy());
348 vtables.push_back(getAddrOfVTTVTable(*this, cgm, rd, vtt, linkage,
349 vtableAddressPoints.back()));
350 }
351
352 SmallVector<mlir::Attribute> vttComponents;
353 for (const VTTComponent &vttComponent : builder.getVTTComponents()) {
354 const VTTVTable &vttVT = builder.getVTTVTables()[vttComponent.VTableIndex];
355 cir::GlobalOp vtable = vtables[vttComponent.VTableIndex];
357 if (vttVT.getBase() == rd) {
358 // Just get the address point for the regular vtable.
359 addressPoint =
361 vttComponent.VTableBase);
362 } else {
363 addressPoint = vtableAddressPoints[vttComponent.VTableIndex].lookup(
364 vttComponent.VTableBase);
365 assert(addressPoint.AddressPointIndex != 0 &&
366 "Did not find ctor vtable address point!");
367 }
368
369 mlir::Attribute indices[2] = {
370 cgm.getBuilder().getI32IntegerAttr(addressPoint.VTableIndex),
371 cgm.getBuilder().getI32IntegerAttr(addressPoint.AddressPointIndex),
372 };
373
374 auto indicesAttr = mlir::ArrayAttr::get(mlirContext, indices);
375 cir::GlobalViewAttr init = cgm.getBuilder().getGlobalViewAttr(
376 cgm.getBuilder().getUInt8PtrTy(), vtable, indicesAttr);
377
378 vttComponents.push_back(init);
379 }
380
381 auto init = cir::ConstArrayAttr::get(
382 arrayType, mlir::ArrayAttr::get(mlirContext, vttComponents));
383
384 vttOp.setInitialValueAttr(init);
385
386 // Set the correct linkage.
387 vttOp.setLinkage(linkage);
388 mlir::SymbolTable::setSymbolVisibility(
389 vttOp, CIRGenModule::getMLIRVisibility(vttOp));
390
391 if (cgm.supportsCOMDAT() && vttOp.isWeakForLinker())
392 vttOp.setComdat(true);
393}
394
396 const CXXMethodDecl *md =
397 cast<CXXMethodDecl>(gd.getDecl())->getCanonicalDecl();
398
399 // We don't need to generate thunks for the base destructor.
400 if (isa<CXXDestructorDecl>(md) && gd.getDtorType() == Dtor_Base)
401 return;
402
403 const VTableContextBase::ThunkInfoVectorTy *thunkInfoVector =
404 vtContext->getThunkInfo(gd);
405
406 if (!thunkInfoVector)
407 return;
408
409 cgm.errorNYI(md->getSourceRange(), "emitThunks");
410}
static cir::GlobalOp getAddrOfVTTVTable(CIRGenVTables &cgvt, CIRGenModule &cgm, const CXXRecordDecl *mostDerivedClass, const VTTVTable &vtable, cir::GlobalLinkageKind linkage, VTableLayout::AddressPointsMapTy &addressPoints)
cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type, cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value)
llvm::Align getABITypeAlign(mlir::Type ty) const
Definition: CIRDataLayout.h:41
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
Definition: ASTContext.h:894
CanQualType getCanonicalTagType(const TagDecl *TD) const
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
Definition: BaseSubobject.h:43
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
Definition: BaseSubobject.h:46
cir::ConstRecordAttr getAnonConstRecord(mlir::ArrayAttr arrayAttr, bool packed=false, bool padded=false, mlir::Type ty={})
Definition: CIRGenBuilder.h:63
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 emitVirtualInheritanceTables(const CXXRecordDecl *rd)=0
Emit any tables needed to implement virtual inheritance.
virtual cir::GlobalOp getAddrOfVTable(const CXXRecordDecl *rd, CharUnits vptrOffset)=0
Get the address of the vtable for the given record decl which should be used for the vptr at the give...
clang::MangleContext & getMangleContext()
Gets the mangle context.
Definition: CIRGenCXXABI.h:164
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.
Definition: CIRGenModule.h:56
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
clang::ASTContext & getASTContext() const
Definition: CIRGenModule.h:102
CIRGenBuilderTy & getBuilder()
Definition: CIRGenModule.h:101
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.
static mlir::SymbolTable::Visibility getMLIRVisibility(cir::GlobalOp op)
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 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.
const cir::CIRDataLayout getDataLayout() const
Definition: CIRGenModule.h:112
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
mlir::MLIRContext & getMLIRContext()
Definition: CIRGenModule.h:110
CIRGenCXXABI & getCXXABI() const
Definition: CIRGenModule.h:109
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.
Definition: CIRGenCall.cpp:63
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.
cir::GlobalOp generateConstructionVTable(const CXXRecordDecl *rd, const BaseSubobject &base, bool baseIsVirtual, cir::GlobalLinkageKind linkage, VTableAddressPointsMapTy &addressPoints)
Generate a construction vtable for the given base subobject.
void emitThunks(GlobalDecl gd)
Emit the associated thunks for the given global decl.
void emitVTTDefinition(cir::GlobalOp vttOp, cir::GlobalLinkageKind linkage, const CXXRecordDecl *rd)
Emit the definition of the given vtable.
CIRGenVTables(CIRGenModule &cgm)
void generateClassData(const CXXRecordDecl *rd)
Generate all the class data required to be generated upon definition of a KeyFunction.
cir::GlobalOp getAddrOfVTT(const CXXRecordDecl *rd)
Get the address of the VTT for the given record decl.
clang::ItaniumVTableContext & getItaniumVTableContext()
Definition: CIRGenVTables.h:53
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2129
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclCXX.h:2225
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
Definition: DeclCXX.h:623
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition: CharUnits.h:122
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition: CharUnits.h:63
bool hasAttr() const
Definition: DeclBase.h:577
Represents a function declaration or definition.
Definition: Decl.h:1999
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
Definition: Decl.h:2918
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:4490
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template instantiation this function represents.
Definition: Decl.cpp:4358
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Definition: Decl.cpp:3191
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:57
CXXDtorType getDtorType() const
Definition: GlobalDecl.h:113
const Decl * getDecl() const
Definition: GlobalDecl.h:106
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
bool isExternallyVisible() const
Definition: Decl.h:432
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:4834
Class for building VTT layout information.
Definition: VTTBuilder.h:71
const VTTComponentsVectorTy & getVTTComponents() const
Definition: VTTBuilder.h:141
const VTTVTablesVectorTy & getVTTVTables() const
Definition: VTTBuilder.h:146
CharUnits getBaseOffset() const
Definition: VTTBuilder.h:48
bool isVirtual() const
Definition: VTTBuilder.h:52
const CXXRecordDecl * getBase() const
Definition: VTTBuilder.h:44
BaseSubobject getBaseSubobject() const
Definition: VTTBuilder.h:56
Represents a single component in a vtable.
Definition: VTableBuilder.h:30
GlobalDecl getGlobalDecl() const
CharUnits getVBaseOffset() const
Kind getKind() const
Get the kind of this vtable component.
Definition: VTableBuilder.h:97
@ CK_DeletingDtorPointer
A pointer to the deleting destructor.
Definition: VTableBuilder.h:43
@ CK_UnusedFunctionPointer
An entry that is never used.
Definition: VTableBuilder.h:50
@ CK_CompleteDtorPointer
A pointer to the complete destructor.
Definition: VTableBuilder.h:40
CharUnits getOffsetToTop() const
CharUnits getVCallOffset() const
virtual const ThunkInfoVectorTy * getThunkInfo(GlobalDecl GD)
const AddressPointsIndexMapTy & getAddressPointIndices() const
size_t getVTableOffset(size_t i) const
llvm::DenseMap< BaseSubobject, AddressPointLocation > AddressPointsMapTy
AddressPointLocation getAddressPoint(BaseSubobject Base) const
ArrayRef< VTableComponent > vtable_components() const
size_t getNumVTables() const
ArrayRef< VTableThunkTy > vtable_thunks() const
size_t getVTableSize(size_t i) const
static bool isLocalLinkage(GlobalLinkageKind linkage)
Definition: CIROpsEnums.h:51
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
The JSON file list parser is used to communicate input to InstallAPI.
@ Dtor_Base
Base object dtor.
Definition: ABI.h:36
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition: Specifiers.h:206
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition: Specifiers.h:202
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:198
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:194
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:191
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
static bool opGlobalUnnamedAddr()
static bool vtableEmitMetadata()
static bool appleKext()
static bool cudaSupport()
static bool generateDebugInfo()
static bool vtableRelativeLayout()