Thanks to visit codestin.com
Credit goes to clang.llvm.org

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/// At this point in the translation unit, does it appear that can we
51/// rely on the vtable being defined elsewhere in the program?
52///
53/// The response is really only definitive when called at the end of
54/// the translation unit.
55///
56/// The only semantic restriction here is that the object file should
57/// not contain a vtable definition when that vtable is defined
58/// strongly elsewhere. Otherwise, we'd just like to avoid emitting
59/// vtables when unnecessary.
60/// TODO(cir): this should be merged into common AST helper for codegen.
62 assert(rd->isDynamicClass() && "Non-dynamic classes have no VTable.");
63
64 // We always synthesize vtables if they are needed in the MS ABI. MSVC doesn't
65 // emit them even if there is an explicit template instantiation.
66 if (cgm.getTarget().getCXXABI().isMicrosoft())
67 return false;
68
69 // If we have an explicit instantiation declaration (and not a
70 // definition), the vtable is defined elsewhere.
73 return true;
74
75 // Otherwise, if the class is an instantiated template, the
76 // vtable must be defined here.
77 if (tsk == TSK_ImplicitInstantiation ||
79 return false;
80
81 // Otherwise, if the class doesn't have a key function (possibly
82 // anymore), the vtable must be defined here.
83 const CXXMethodDecl *keyFunction =
85 if (!keyFunction)
86 return false;
87
88 // Otherwise, if we don't have a definition of the key function, the
89 // vtable must be defined somewhere else.
90 return !keyFunction->hasBody();
91}
92
93/// This is a callback from Sema to tell us that a particular vtable is
94/// required to be emitted in this translation unit.
95///
96/// This is only called for vtables that _must_ be emitted (mainly due to key
97/// functions). For weak vtables, CodeGen tracks when they are needed and
98/// emits them as-needed.
100 vtables.generateClassData(rd);
101}
102
105
106 if (rd->getNumVBases())
107 cgm.getCXXABI().emitVirtualInheritanceTables(rd);
108
109 cgm.getCXXABI().emitVTableDefinitions(*this, rd);
110}
111
112mlir::Attribute CIRGenVTables::getVTableComponent(
113 const VTableLayout &layout, unsigned componentIndex, mlir::Attribute rtti,
114 unsigned &nextVTableThunkIndex, unsigned vtableAddressPoint,
115 bool vtableHasLocalLinkage) {
116 const VTableComponent &component = layout.vtable_components()[componentIndex];
117
118 CIRGenBuilderTy builder = cgm.getBuilder();
119
121
122 switch (component.getKind()) {
124 cgm.errorNYI("getVTableComponent: CompleteDtorPointer");
125 return mlir::Attribute();
127 cgm.errorNYI("getVTableComponent: DeletingDtorPointer");
128 return mlir::Attribute();
130 cgm.errorNYI("getVTableComponent: UnusedFunctionPointer");
131 return mlir::Attribute();
132
134 return builder.getConstPtrAttr(builder.getUInt8PtrTy(),
135 component.getVCallOffset().getQuantity());
136
138 return builder.getConstPtrAttr(builder.getUInt8PtrTy(),
139 component.getVBaseOffset().getQuantity());
140
142 return builder.getConstPtrAttr(builder.getUInt8PtrTy(),
143 component.getOffsetToTop().getQuantity());
144
146 assert((mlir::isa<cir::GlobalViewAttr>(rtti) ||
147 mlir::isa<cir::ConstPtrAttr>(rtti)) &&
148 "expected GlobalViewAttr or ConstPtrAttr");
149 return rtti;
150
152 GlobalDecl gd = component.getGlobalDecl();
153
155
156 cir::FuncOp fnPtr;
157 if (cast<CXXMethodDecl>(gd.getDecl())->isPureVirtual()) {
158 cgm.errorNYI("getVTableComponent: CK_FunctionPointer: pure virtual");
159 return mlir::Attribute();
160 } else if (cast<CXXMethodDecl>(gd.getDecl())->isDeleted()) {
161 cgm.errorNYI("getVTableComponent: CK_FunctionPointer: deleted virtual");
162 return mlir::Attribute();
163 } else if (nextVTableThunkIndex < layout.vtable_thunks().size() &&
164 layout.vtable_thunks()[nextVTableThunkIndex].first ==
165 componentIndex) {
166 cgm.errorNYI("getVTableComponent: CK_FunctionPointer: thunk");
167 return mlir::Attribute();
168 } else {
169 // Otherwise we can use the method definition directly.
170 cir::FuncType fnTy = cgm.getTypes().getFunctionTypeForVTable(gd);
171 fnPtr = cgm.getAddrOfFunction(gd, fnTy, /*ForVTable=*/true);
172 }
173
174 return cir::GlobalViewAttr::get(
175 builder.getUInt8PtrTy(),
176 mlir::FlatSymbolRefAttr::get(fnPtr.getSymNameAttr()));
177 }
178 }
179
180 llvm_unreachable("Unexpected vtable component kind");
181}
182
183void CIRGenVTables::createVTableInitializer(cir::GlobalOp &vtableOp,
184 const clang::VTableLayout &layout,
185 mlir::Attribute rtti,
186 bool vtableHasLocalLinkage) {
187 mlir::Type componentType = getVTableComponentType();
188
189 const llvm::SmallVectorImpl<unsigned> &addressPoints =
190 layout.getAddressPointIndices();
191 unsigned nextVTableThunkIndex = 0;
192
193 mlir::MLIRContext *mlirContext = &cgm.getMLIRContext();
194
196 for (auto [vtableIndex, addressPoint] : llvm::enumerate(addressPoints)) {
197 // Build a ConstArrayAttr of the vtable components.
198 size_t vtableStart = layout.getVTableOffset(vtableIndex);
199 size_t vtableEnd = vtableStart + layout.getVTableSize(vtableIndex);
201 components.reserve(vtableEnd - vtableStart);
202 for (size_t componentIndex : llvm::seq(vtableStart, vtableEnd))
203 components.push_back(
204 getVTableComponent(layout, componentIndex, rtti, nextVTableThunkIndex,
205 addressPoint, vtableHasLocalLinkage));
206 // Create a ConstArrayAttr to hold the components.
207 auto arr = cir::ConstArrayAttr::get(
208 cir::ArrayType::get(componentType, components.size()),
209 mlir::ArrayAttr::get(mlirContext, components));
210 vtables.push_back(arr);
211 }
212
213 // Create a ConstRecordAttr to hold the component array.
214 const auto members = mlir::ArrayAttr::get(mlirContext, vtables);
215 cir::ConstRecordAttr record = cgm.getBuilder().getAnonConstRecord(members);
216
217 // Create a VTableAttr
218 auto vtableAttr = cir::VTableAttr::get(record.getType(), record.getMembers());
219
220 // Add the vtable initializer to the vtable global op.
221 cgm.setInitializer(vtableOp, vtableAttr);
222}
223
225 const CXXRecordDecl *rd, const BaseSubobject &base, bool baseIsVirtual,
226 cir::GlobalLinkageKind linkage, VTableAddressPointsMapTy &addressPoints) {
228
229 std::unique_ptr<VTableLayout> vtLayout(
230 getItaniumVTableContext().createConstructionVTableLayout(
231 base.getBase(), base.getBaseOffset(), baseIsVirtual, rd));
232
233 // Add the address points.
234 addressPoints = vtLayout->getAddressPoints();
235
236 // Get the mangled construction vtable name.
237 SmallString<256> outName;
238 llvm::raw_svector_ostream out(outName);
239 cast<ItaniumMangleContext>(cgm.getCXXABI().getMangleContext())
240 .mangleCXXCtorVTable(rd, base.getBaseOffset().getQuantity(),
241 base.getBase(), out);
242 SmallString<256> name(outName);
243
245
246 cir::RecordType vtType = getVTableType(*vtLayout);
247
248 // Construction vtable symbols are not part of the Itanium ABI, so we cannot
249 // guarantee that they actually will be available externally. Instead, when
250 // emitting an available_externally VTT, we provide references to an internal
251 // linkage construction vtable. The ABI only requires complete-object vtables
252 // to be the same for all instances of a type, not construction vtables.
253 if (linkage == cir::GlobalLinkageKind::AvailableExternallyLinkage)
254 linkage = cir::GlobalLinkageKind::InternalLinkage;
255
256 llvm::Align align = cgm.getDataLayout().getABITypeAlign(vtType);
257 mlir::Location loc = cgm.getLoc(rd->getSourceRange());
258
259 // Create the variable that will hold the construction vtable.
260 cir::GlobalOp vtable = cgm.createOrReplaceCXXRuntimeVariable(
261 loc, name, vtType, linkage, CharUnits::fromQuantity(align));
262
263 // V-tables are always unnamed_addr.
265
266 mlir::Attribute rtti = cgm.getAddrOfRTTIDescriptor(
267 loc, cgm.getASTContext().getCanonicalTagType(base.getBase()));
268
269 // Create and set the initializer.
270 createVTableInitializer(vtable, *vtLayout, rtti,
271 cir::isLocalLinkage(vtable.getLinkage()));
272
273 // Set properties only after the initializer has been set to ensure that the
274 // GV is treated as definition and not declaration.
275 assert(!vtable.isDeclaration() && "Shouldn't set properties on declaration");
276 cgm.setGVProperties(vtable, rd);
277
280
281 return vtable;
282}
283
284/// Compute the required linkage of the vtable for the given class.
285///
286/// Note that we only call this at the end of the translation unit.
287cir::GlobalLinkageKind CIRGenModule::getVTableLinkage(const CXXRecordDecl *rd) {
288 if (!rd->isExternallyVisible())
289 return cir::GlobalLinkageKind::InternalLinkage;
290
291 // We're at the end of the translation unit, so the current key
292 // function is fully correct.
293 const CXXMethodDecl *keyFunction = astContext.getCurrentKeyFunction(rd);
294 if (keyFunction && !rd->hasAttr<DLLImportAttr>()) {
295 // If this class has a key function, use that to determine the
296 // linkage of the vtable.
297 const FunctionDecl *def = nullptr;
298 if (keyFunction->hasBody(def))
299 keyFunction = cast<CXXMethodDecl>(def);
300
301 // All of the cases below do something different with AppleKext enabled.
303 switch (keyFunction->getTemplateSpecializationKind()) {
304 case TSK_Undeclared:
306 assert(
307 (def || codeGenOpts.OptimizationLevel > 0 ||
308 codeGenOpts.getDebugInfo() != llvm::codegenoptions::NoDebugInfo) &&
309 "Shouldn't query vtable linkage without key function, "
310 "optimizations, or debug info");
311 if (!def && codeGenOpts.OptimizationLevel > 0)
312 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
313
314 if (keyFunction->isInlined())
315 return !astContext.getLangOpts().AppleKext
316 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
317 : cir::GlobalLinkageKind::InternalLinkage;
318 return cir::GlobalLinkageKind::ExternalLinkage;
319
321 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
322
324 return cir::GlobalLinkageKind::WeakODRLinkage;
325
327 llvm_unreachable("Should not have been asked to emit this");
328 }
329 }
330
331 errorNYI(rd->getSourceRange(), "getVTableLinkage: no key function");
332 return cir::GlobalLinkageKind::ExternalLinkage;
333}
334
336 assert(rd->getNumVBases() && "Only classes with virtual bases need a VTT");
337
338 SmallString<256> outName;
339 llvm::raw_svector_ostream out(outName);
340 cast<ItaniumMangleContext>(cgm.getCXXABI().getMangleContext())
341 .mangleCXXVTT(rd, out);
342 StringRef name = outName.str();
343
344 // This will also defer the definition of the VTT.
345 (void)cgm.getCXXABI().getAddrOfVTable(rd, CharUnits());
346
347 VTTBuilder builder(cgm.getASTContext(), rd, /*GenerateDefinition=*/false);
348
349 auto arrayType = cir::ArrayType::get(cgm.getBuilder().getUInt8PtrTy(),
350 builder.getVTTComponents().size());
351 llvm::Align align =
352 cgm.getDataLayout().getABITypeAlign(cgm.getBuilder().getUInt8PtrTy());
353 cir::GlobalOp vtt = cgm.createOrReplaceCXXRuntimeVariable(
354 cgm.getLoc(rd->getSourceRange()), name, arrayType,
355 cir::GlobalLinkageKind::ExternalLinkage, CharUnits::fromQuantity(align));
356 cgm.setGVProperties(vtt, rd);
357 return vtt;
358}
359
360static cir::GlobalOp
362 const CXXRecordDecl *mostDerivedClass,
363 const VTTVTable &vtable, cir::GlobalLinkageKind linkage,
364 VTableLayout::AddressPointsMapTy &addressPoints) {
365 if (vtable.getBase() == mostDerivedClass) {
366 assert(vtable.getBaseOffset().isZero() &&
367 "Most derived class vtable must have a zero offset!");
368 // This is a regular vtable.
369 return cgm.getCXXABI().getAddrOfVTable(mostDerivedClass, CharUnits());
370 }
371 return cgvt.generateConstructionVTable(
372 mostDerivedClass, vtable.getBaseSubobject(), vtable.isVirtual(), linkage,
373 addressPoints);
374}
375
376/// Emit the definition of the given vtable.
377void CIRGenVTables::emitVTTDefinition(cir::GlobalOp vttOp,
378 cir::GlobalLinkageKind linkage,
379 const CXXRecordDecl *rd) {
380 VTTBuilder builder(cgm.getASTContext(), rd, /*GenerateDefinition=*/true);
381
382 mlir::MLIRContext *mlirContext = &cgm.getMLIRContext();
383
384 auto arrayType = cir::ArrayType::get(cgm.getBuilder().getUInt8PtrTy(),
385 builder.getVTTComponents().size());
386
388 SmallVector<VTableAddressPointsMapTy> vtableAddressPoints;
389 for (const VTTVTable &vtt : builder.getVTTVTables()) {
390 vtableAddressPoints.push_back(VTableAddressPointsMapTy());
391 vtables.push_back(getAddrOfVTTVTable(*this, cgm, rd, vtt, linkage,
392 vtableAddressPoints.back()));
393 }
394
395 SmallVector<mlir::Attribute> vttComponents;
396 for (const VTTComponent &vttComponent : builder.getVTTComponents()) {
397 const VTTVTable &vttVT = builder.getVTTVTables()[vttComponent.VTableIndex];
398 cir::GlobalOp vtable = vtables[vttComponent.VTableIndex];
400 if (vttVT.getBase() == rd) {
401 // Just get the address point for the regular vtable.
402 addressPoint =
404 vttComponent.VTableBase);
405 } else {
406 addressPoint = vtableAddressPoints[vttComponent.VTableIndex].lookup(
407 vttComponent.VTableBase);
408 assert(addressPoint.AddressPointIndex != 0 &&
409 "Did not find ctor vtable address point!");
410 }
411
412 mlir::Attribute indices[2] = {
413 cgm.getBuilder().getI32IntegerAttr(addressPoint.VTableIndex),
414 cgm.getBuilder().getI32IntegerAttr(addressPoint.AddressPointIndex),
415 };
416
417 auto indicesAttr = mlir::ArrayAttr::get(mlirContext, indices);
418 cir::GlobalViewAttr init = cgm.getBuilder().getGlobalViewAttr(
419 cgm.getBuilder().getUInt8PtrTy(), vtable, indicesAttr);
420
421 vttComponents.push_back(init);
422 }
423
424 auto init = cir::ConstArrayAttr::get(
425 arrayType, mlir::ArrayAttr::get(mlirContext, vttComponents));
426
427 vttOp.setInitialValueAttr(init);
428
429 // Set the correct linkage.
430 vttOp.setLinkage(linkage);
431 mlir::SymbolTable::setSymbolVisibility(
432 vttOp, CIRGenModule::getMLIRVisibility(vttOp));
433
434 if (cgm.supportsCOMDAT() && vttOp.isWeakForLinker())
435 vttOp.setComdat(true);
436}
437
439 BaseSubobject base) {
440 BaseSubobjectPairTy classSubobjectPair(rd, base);
441
442 SubVTTIndiciesMapTy::iterator it = subVTTIndicies.find(classSubobjectPair);
443 if (it != subVTTIndicies.end())
444 return it->second;
445
446 VTTBuilder builder(cgm.getASTContext(), rd, /*GenerateDefinition=*/false);
447
448 for (const auto &entry : builder.getSubVTTIndices()) {
449 // Insert all indices.
450 BaseSubobjectPairTy subclassSubobjectPair(rd, entry.first);
451
452 subVTTIndicies.insert(std::make_pair(subclassSubobjectPair, entry.second));
453 }
454
455 it = subVTTIndicies.find(classSubobjectPair);
456 assert(it != subVTTIndicies.end() && "Did not find index!");
457
458 return it->second;
459}
460
462 BaseSubobject base) {
463 auto it = secondaryVirtualPointerIndices.find(std::make_pair(rd, base));
464
465 if (it != secondaryVirtualPointerIndices.end())
466 return it->second;
467
468 VTTBuilder builder(cgm.getASTContext(), rd, /*GenerateDefinition=*/false);
469
470 // Insert all secondary vpointer indices.
471 for (const auto &entry : builder.getSecondaryVirtualPointerIndices()) {
472 std::pair<const CXXRecordDecl *, BaseSubobject> pair =
473 std::make_pair(rd, entry.first);
474
475 secondaryVirtualPointerIndices.insert(std::make_pair(pair, entry.second));
476 }
477
478 it = secondaryVirtualPointerIndices.find(std::make_pair(rd, base));
479 assert(it != secondaryVirtualPointerIndices.end() && "Did not find index!");
480
481 return it->second;
482}
483
485 const CXXMethodDecl *md =
486 cast<CXXMethodDecl>(gd.getDecl())->getCanonicalDecl();
487
488 // We don't need to generate thunks for the base destructor.
490 return;
491
492 const VTableContextBase::ThunkInfoVectorTy *thunkInfoVector =
493 vtContext->getThunkInfo(gd);
494
495 if (!thunkInfoVector)
496 return;
497
498 cgm.errorNYI(md->getSourceRange(), "emitThunks");
499}
static cir::GlobalOp getAddrOfVTTVTable(CIRGenVTables &cgvt, CIRGenModule &cgm, const CXXRecordDecl *mostDerivedClass, const VTTVTable &vtable, cir::GlobalLinkageKind linkage, VTableLayout::AddressPointsMapTy &addressPoints)
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 CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
cir::PointerType getUInt8PtrTy()
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...
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()
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
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::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.
uint64_t getSubVTTIndex(const CXXRecordDecl *rd, BaseSubobject base)
Return the index of the sub-VTT for the base class of the given record decl.
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()
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 static or instance method of a struct/union/class.
Definition DeclCXX.h:2129
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
Definition DeclCXX.cpp:2050
bool isDynamicClass() const
Definition DeclCXX.h:574
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
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:524
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 llvm::DenseMap< BaseSubobject, uint64_t > & getSecondaryVirtualPointerIndices() const
Returns a reference to the secondary virtual pointer indices.
Definition VTTBuilder.h:157
const llvm::DenseMap< BaseSubobject, uint64_t > & getSubVTTIndices() const
Returns a reference to the sub-VTT indices.
Definition VTTBuilder.h:151
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.
GlobalDecl getGlobalDecl() const
CharUnits getVBaseOffset() 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
CharUnits getVCallOffset() const
SmallVector< ThunkInfo, 1 > ThunkInfoVectorTy
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
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ Dtor_Base
Base object dtor.
Definition ABI.h:37
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
Definition Specifiers.h:188
@ 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
U cast(CodeGen::Address addr)
Definition Address.h:327
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
static bool opGlobalUnnamedAddr()
static bool vtableEmitMetadata()
static bool cudaSupport()
static bool generateDebugInfo()
static bool vtableRelativeLayout()