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