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: UnusedFunctionPointer");
125 return mlir::Attribute();
126
128 return builder.getConstPtrAttr(builder.getUInt8PtrTy(),
129 component.getVCallOffset().getQuantity());
130
132 return builder.getConstPtrAttr(builder.getUInt8PtrTy(),
133 component.getVBaseOffset().getQuantity());
134
136 return builder.getConstPtrAttr(builder.getUInt8PtrTy(),
137 component.getOffsetToTop().getQuantity());
138
140 assert((mlir::isa<cir::GlobalViewAttr>(rtti) ||
141 mlir::isa<cir::ConstPtrAttr>(rtti)) &&
142 "expected GlobalViewAttr or ConstPtrAttr");
143 return rtti;
144
148 GlobalDecl gd = component.getGlobalDecl();
149
151
152 cir::FuncOp fnPtr;
153 if (cast<CXXMethodDecl>(gd.getDecl())->isPureVirtual()) {
154 cgm.errorNYI("getVTableComponent: CK_FunctionPointer: pure virtual");
155 return mlir::Attribute();
156 } else if (cast<CXXMethodDecl>(gd.getDecl())->isDeleted()) {
157 cgm.errorNYI("getVTableComponent: CK_FunctionPointer: deleted virtual");
158 return mlir::Attribute();
159 } else if (nextVTableThunkIndex < layout.vtable_thunks().size() &&
160 layout.vtable_thunks()[nextVTableThunkIndex].first ==
161 componentIndex) {
162 cgm.errorNYI("getVTableComponent: CK_FunctionPointer: thunk");
163 return mlir::Attribute();
164 } else {
165 // Otherwise we can use the method definition directly.
166 cir::FuncType fnTy = cgm.getTypes().getFunctionTypeForVTable(gd);
167 fnPtr = cgm.getAddrOfFunction(gd, fnTy, /*ForVTable=*/true);
168 }
169
170 return cir::GlobalViewAttr::get(
171 builder.getUInt8PtrTy(),
172 mlir::FlatSymbolRefAttr::get(fnPtr.getSymNameAttr()));
173 }
174 }
175
176 llvm_unreachable("Unexpected vtable component kind");
177}
178
179void CIRGenVTables::createVTableInitializer(cir::GlobalOp &vtableOp,
180 const clang::VTableLayout &layout,
181 mlir::Attribute rtti,
182 bool vtableHasLocalLinkage) {
183 mlir::Type componentType = getVTableComponentType();
184
185 const llvm::SmallVectorImpl<unsigned> &addressPoints =
186 layout.getAddressPointIndices();
187 unsigned nextVTableThunkIndex = 0;
188
189 mlir::MLIRContext *mlirContext = &cgm.getMLIRContext();
190
192 for (auto [vtableIndex, addressPoint] : llvm::enumerate(addressPoints)) {
193 // Build a ConstArrayAttr of the vtable components.
194 size_t vtableStart = layout.getVTableOffset(vtableIndex);
195 size_t vtableEnd = vtableStart + layout.getVTableSize(vtableIndex);
197 components.reserve(vtableEnd - vtableStart);
198 for (size_t componentIndex : llvm::seq(vtableStart, vtableEnd))
199 components.push_back(
200 getVTableComponent(layout, componentIndex, rtti, nextVTableThunkIndex,
201 addressPoint, vtableHasLocalLinkage));
202 // Create a ConstArrayAttr to hold the components.
203 auto arr = cir::ConstArrayAttr::get(
204 cir::ArrayType::get(componentType, components.size()),
205 mlir::ArrayAttr::get(mlirContext, components));
206 vtables.push_back(arr);
207 }
208
209 // Create a ConstRecordAttr to hold the component array.
210 const auto members = mlir::ArrayAttr::get(mlirContext, vtables);
211 cir::ConstRecordAttr record = cgm.getBuilder().getAnonConstRecord(members);
212
213 // Create a VTableAttr
214 auto vtableAttr = cir::VTableAttr::get(record.getType(), record.getMembers());
215
216 // Add the vtable initializer to the vtable global op.
217 cgm.setInitializer(vtableOp, vtableAttr);
218}
219
221 const CXXRecordDecl *rd, const BaseSubobject &base, bool baseIsVirtual,
222 cir::GlobalLinkageKind linkage, VTableAddressPointsMapTy &addressPoints) {
224
225 std::unique_ptr<VTableLayout> vtLayout(
226 getItaniumVTableContext().createConstructionVTableLayout(
227 base.getBase(), base.getBaseOffset(), baseIsVirtual, rd));
228
229 // Add the address points.
230 addressPoints = vtLayout->getAddressPoints();
231
232 // Get the mangled construction vtable name.
233 SmallString<256> outName;
234 llvm::raw_svector_ostream out(outName);
235 cast<ItaniumMangleContext>(cgm.getCXXABI().getMangleContext())
236 .mangleCXXCtorVTable(rd, base.getBaseOffset().getQuantity(),
237 base.getBase(), out);
238 SmallString<256> name(outName);
239
241
242 cir::RecordType vtType = getVTableType(*vtLayout);
243
244 // Construction vtable symbols are not part of the Itanium ABI, so we cannot
245 // guarantee that they actually will be available externally. Instead, when
246 // emitting an available_externally VTT, we provide references to an internal
247 // linkage construction vtable. The ABI only requires complete-object vtables
248 // to be the same for all instances of a type, not construction vtables.
249 if (linkage == cir::GlobalLinkageKind::AvailableExternallyLinkage)
250 linkage = cir::GlobalLinkageKind::InternalLinkage;
251
252 llvm::Align align = cgm.getDataLayout().getABITypeAlign(vtType);
253 mlir::Location loc = cgm.getLoc(rd->getSourceRange());
254
255 // Create the variable that will hold the construction vtable.
256 cir::GlobalOp vtable = cgm.createOrReplaceCXXRuntimeVariable(
257 loc, name, vtType, linkage, CharUnits::fromQuantity(align));
258
259 // V-tables are always unnamed_addr.
261
262 mlir::Attribute rtti = cgm.getAddrOfRTTIDescriptor(
263 loc, cgm.getASTContext().getCanonicalTagType(base.getBase()));
264
265 // Create and set the initializer.
266 createVTableInitializer(vtable, *vtLayout, rtti,
267 cir::isLocalLinkage(vtable.getLinkage()));
268
269 // Set properties only after the initializer has been set to ensure that the
270 // GV is treated as definition and not declaration.
271 assert(!vtable.isDeclaration() && "Shouldn't set properties on declaration");
272 cgm.setGVProperties(vtable, rd);
273
276
277 return vtable;
278}
279
280/// Compute the required linkage of the vtable for the given class.
281///
282/// Note that we only call this at the end of the translation unit.
283cir::GlobalLinkageKind CIRGenModule::getVTableLinkage(const CXXRecordDecl *rd) {
284 if (!rd->isExternallyVisible())
285 return cir::GlobalLinkageKind::InternalLinkage;
286
287 // We're at the end of the translation unit, so the current key
288 // function is fully correct.
289 const CXXMethodDecl *keyFunction = astContext.getCurrentKeyFunction(rd);
290 if (keyFunction && !rd->hasAttr<DLLImportAttr>()) {
291 // If this class has a key function, use that to determine the
292 // linkage of the vtable.
293 const FunctionDecl *def = nullptr;
294 if (keyFunction->hasBody(def))
295 keyFunction = cast<CXXMethodDecl>(def);
296
297 // All of the cases below do something different with AppleKext enabled.
299 switch (keyFunction->getTemplateSpecializationKind()) {
300 case TSK_Undeclared:
302 assert(
303 (def || codeGenOpts.OptimizationLevel > 0 ||
304 codeGenOpts.getDebugInfo() != llvm::codegenoptions::NoDebugInfo) &&
305 "Shouldn't query vtable linkage without key function, "
306 "optimizations, or debug info");
307 if (!def && codeGenOpts.OptimizationLevel > 0)
308 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
309
310 if (keyFunction->isInlined())
311 return !astContext.getLangOpts().AppleKext
312 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
313 : cir::GlobalLinkageKind::InternalLinkage;
314 return cir::GlobalLinkageKind::ExternalLinkage;
315
317 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
318
320 return cir::GlobalLinkageKind::WeakODRLinkage;
321
323 llvm_unreachable("Should not have been asked to emit this");
324 }
325 }
326 // -fapple-kext mode does not support weak linkage, so we must use
327 // internal linkage.
328 if (astContext.getLangOpts().AppleKext)
329 return cir::GlobalLinkageKind::InternalLinkage;
330
331 auto discardableODRLinkage = cir::GlobalLinkageKind::LinkOnceODRLinkage;
332 auto nonDiscardableODRLinkage = cir::GlobalLinkageKind::WeakODRLinkage;
333 if (rd->hasAttr<DLLExportAttr>()) {
334 // Cannot discard exported vtables.
335 discardableODRLinkage = nonDiscardableODRLinkage;
336 } else if (rd->hasAttr<DLLImportAttr>()) {
337 // Imported vtables are available externally.
338 discardableODRLinkage = cir::GlobalLinkageKind::AvailableExternallyLinkage;
339 nonDiscardableODRLinkage =
340 cir::GlobalLinkageKind::AvailableExternallyLinkage;
341 }
342
343 switch (rd->getTemplateSpecializationKind()) {
344 case TSK_Undeclared:
347 return discardableODRLinkage;
348
351 "getVTableLinkage: explicit instantiation declaration");
352 return cir::GlobalLinkageKind::ExternalLinkage;
353 }
354
356 return nonDiscardableODRLinkage;
357 }
358
359 llvm_unreachable("Invalid TemplateSpecializationKind!");
360}
361
363 assert(rd->getNumVBases() && "Only classes with virtual bases need a VTT");
364
365 SmallString<256> outName;
366 llvm::raw_svector_ostream out(outName);
367 cast<ItaniumMangleContext>(cgm.getCXXABI().getMangleContext())
368 .mangleCXXVTT(rd, out);
369 StringRef name = outName.str();
370
371 // This will also defer the definition of the VTT.
372 (void)cgm.getCXXABI().getAddrOfVTable(rd, CharUnits());
373
374 VTTBuilder builder(cgm.getASTContext(), rd, /*GenerateDefinition=*/false);
375
376 auto arrayType = cir::ArrayType::get(cgm.getBuilder().getUInt8PtrTy(),
377 builder.getVTTComponents().size());
378 llvm::Align align =
379 cgm.getDataLayout().getABITypeAlign(cgm.getBuilder().getUInt8PtrTy());
380 cir::GlobalOp vtt = cgm.createOrReplaceCXXRuntimeVariable(
381 cgm.getLoc(rd->getSourceRange()), name, arrayType,
382 cir::GlobalLinkageKind::ExternalLinkage, CharUnits::fromQuantity(align));
383 cgm.setGVProperties(vtt, rd);
384 return vtt;
385}
386
387static cir::GlobalOp
389 const CXXRecordDecl *mostDerivedClass,
390 const VTTVTable &vtable, cir::GlobalLinkageKind linkage,
391 VTableLayout::AddressPointsMapTy &addressPoints) {
392 if (vtable.getBase() == mostDerivedClass) {
393 assert(vtable.getBaseOffset().isZero() &&
394 "Most derived class vtable must have a zero offset!");
395 // This is a regular vtable.
396 return cgm.getCXXABI().getAddrOfVTable(mostDerivedClass, CharUnits());
397 }
398 return cgvt.generateConstructionVTable(
399 mostDerivedClass, vtable.getBaseSubobject(), vtable.isVirtual(), linkage,
400 addressPoints);
401}
402
403/// Emit the definition of the given vtable.
404void CIRGenVTables::emitVTTDefinition(cir::GlobalOp vttOp,
405 cir::GlobalLinkageKind linkage,
406 const CXXRecordDecl *rd) {
407 VTTBuilder builder(cgm.getASTContext(), rd, /*GenerateDefinition=*/true);
408
409 mlir::MLIRContext *mlirContext = &cgm.getMLIRContext();
410
411 auto arrayType = cir::ArrayType::get(cgm.getBuilder().getUInt8PtrTy(),
412 builder.getVTTComponents().size());
413
415 SmallVector<VTableAddressPointsMapTy> vtableAddressPoints;
416 for (const VTTVTable &vtt : builder.getVTTVTables()) {
417 vtableAddressPoints.push_back(VTableAddressPointsMapTy());
418 vtables.push_back(getAddrOfVTTVTable(*this, cgm, rd, vtt, linkage,
419 vtableAddressPoints.back()));
420 }
421
422 SmallVector<mlir::Attribute> vttComponents;
423 for (const VTTComponent &vttComponent : builder.getVTTComponents()) {
424 const VTTVTable &vttVT = builder.getVTTVTables()[vttComponent.VTableIndex];
425 cir::GlobalOp vtable = vtables[vttComponent.VTableIndex];
427 if (vttVT.getBase() == rd) {
428 // Just get the address point for the regular vtable.
429 addressPoint =
431 vttComponent.VTableBase);
432 } else {
433 addressPoint = vtableAddressPoints[vttComponent.VTableIndex].lookup(
434 vttComponent.VTableBase);
435 assert(addressPoint.AddressPointIndex != 0 &&
436 "Did not find ctor vtable address point!");
437 }
438
439 mlir::Attribute indices[2] = {
440 cgm.getBuilder().getI32IntegerAttr(addressPoint.VTableIndex),
441 cgm.getBuilder().getI32IntegerAttr(addressPoint.AddressPointIndex),
442 };
443
444 auto indicesAttr = mlir::ArrayAttr::get(mlirContext, indices);
445 cir::GlobalViewAttr init = cgm.getBuilder().getGlobalViewAttr(
446 cgm.getBuilder().getUInt8PtrTy(), vtable, indicesAttr);
447
448 vttComponents.push_back(init);
449 }
450
451 auto init = cir::ConstArrayAttr::get(
452 arrayType, mlir::ArrayAttr::get(mlirContext, vttComponents));
453
454 vttOp.setInitialValueAttr(init);
455
456 // Set the correct linkage.
457 vttOp.setLinkage(linkage);
458 mlir::SymbolTable::setSymbolVisibility(
459 vttOp, CIRGenModule::getMLIRVisibility(vttOp));
460
461 if (cgm.supportsCOMDAT() && vttOp.isWeakForLinker())
462 vttOp.setComdat(true);
463}
464
466 BaseSubobject base) {
467 BaseSubobjectPairTy classSubobjectPair(rd, base);
468
469 SubVTTIndiciesMapTy::iterator it = subVTTIndicies.find(classSubobjectPair);
470 if (it != subVTTIndicies.end())
471 return it->second;
472
473 VTTBuilder builder(cgm.getASTContext(), rd, /*GenerateDefinition=*/false);
474
475 for (const auto &entry : builder.getSubVTTIndices()) {
476 // Insert all indices.
477 BaseSubobjectPairTy subclassSubobjectPair(rd, entry.first);
478
479 subVTTIndicies.insert(std::make_pair(subclassSubobjectPair, entry.second));
480 }
481
482 it = subVTTIndicies.find(classSubobjectPair);
483 assert(it != subVTTIndicies.end() && "Did not find index!");
484
485 return it->second;
486}
487
489 BaseSubobject base) {
490 auto it = secondaryVirtualPointerIndices.find(std::make_pair(rd, base));
491
492 if (it != secondaryVirtualPointerIndices.end())
493 return it->second;
494
495 VTTBuilder builder(cgm.getASTContext(), rd, /*GenerateDefinition=*/false);
496
497 // Insert all secondary vpointer indices.
498 for (const auto &entry : builder.getSecondaryVirtualPointerIndices()) {
499 std::pair<const CXXRecordDecl *, BaseSubobject> pair =
500 std::make_pair(rd, entry.first);
501
502 secondaryVirtualPointerIndices.insert(std::make_pair(pair, entry.second));
503 }
504
505 it = secondaryVirtualPointerIndices.find(std::make_pair(rd, base));
506 assert(it != secondaryVirtualPointerIndices.end() && "Did not find index!");
507
508 return it->second;
509}
510
512 const CXXMethodDecl *md =
513 cast<CXXMethodDecl>(gd.getDecl())->getCanonicalDecl();
514
515 // We don't need to generate thunks for the base destructor.
517 return;
518
519 const VTableContextBase::ThunkInfoVectorTy *thunkInfoVector =
520 vtContext->getThunkInfo(gd);
521
522 if (!thunkInfoVector)
523 return;
524
525 cgm.errorNYI(md->getSourceRange(), "emitThunks");
526}
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:546
bool hasAttr() const
Definition DeclBase.h:577
Represents a function declaration or definition.
Definition Decl.h:2000
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
Definition Decl.h:2921
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4538
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template instantiation this function represents.
Definition Decl.cpp:4406
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Definition Decl.cpp:3188
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:433
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4882
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()