clang 19.0.0git
VTableBuilder.h
Go to the documentation of this file.
1//===--- VTableBuilder.h - C++ vtable layout builder --------------*- C++ -*-=//
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 generation of the layout of virtual tables.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_VTABLEBUILDER_H
14#define LLVM_CLANG_AST_VTABLEBUILDER_H
15
20#include "clang/Basic/ABI.h"
21#include "clang/Basic/Thunk.h"
22#include "llvm/ADT/DenseMap.h"
23#include <memory>
24#include <utility>
25
26namespace clang {
27 class CXXRecordDecl;
28
29/// Represents a single component in a vtable.
31public:
32 enum Kind {
38
39 /// A pointer to the complete destructor.
41
42 /// A pointer to the deleting destructor.
44
45 /// An entry that is never used.
46 ///
47 /// In some cases, a vtable function pointer will end up never being
48 /// called. Such vtable function pointers are represented as a
49 /// CK_UnusedFunctionPointer.
51 };
52
53 VTableComponent() = default;
54
56 return VTableComponent(CK_VCallOffset, Offset);
57 }
58
60 return VTableComponent(CK_VBaseOffset, Offset);
61 }
62
64 return VTableComponent(CK_OffsetToTop, Offset);
65 }
66
68 return VTableComponent(CK_RTTI, reinterpret_cast<uintptr_t>(RD));
69 }
70
72 assert(!isa<CXXDestructorDecl>(MD) &&
73 "Don't use MakeFunction with destructors!");
74
76 reinterpret_cast<uintptr_t>(MD));
77 }
78
81 reinterpret_cast<uintptr_t>(DD));
82 }
83
86 reinterpret_cast<uintptr_t>(DD));
87 }
88
90 assert(!isa<CXXDestructorDecl>(MD) &&
91 "Don't use MakeUnusedFunction with destructors!");
93 reinterpret_cast<uintptr_t>(MD));
94 }
95
96 /// Get the kind of this vtable component.
97 Kind getKind() const {
98 return (Kind)(Value & 0x7);
99 }
100
102 assert(getKind() == CK_VCallOffset && "Invalid component kind!");
103
104 return getOffset();
105 }
106
108 assert(getKind() == CK_VBaseOffset && "Invalid component kind!");
109
110 return getOffset();
111 }
112
114 assert(getKind() == CK_OffsetToTop && "Invalid component kind!");
115
116 return getOffset();
117 }
118
119 const CXXRecordDecl *getRTTIDecl() const {
120 assert(isRTTIKind() && "Invalid component kind!");
121 return reinterpret_cast<CXXRecordDecl *>(getPointer());
122 }
123
125 assert(isFunctionPointerKind() && "Invalid component kind!");
126 if (isDestructorKind())
127 return getDestructorDecl();
128 return reinterpret_cast<CXXMethodDecl *>(getPointer());
129 }
130
132 assert(isDestructorKind() && "Invalid component kind!");
133 return reinterpret_cast<CXXDestructorDecl *>(getPointer());
134 }
135
137 assert(getKind() == CK_UnusedFunctionPointer && "Invalid component kind!");
138 return reinterpret_cast<CXXMethodDecl *>(getPointer());
139 }
140
141 bool isDestructorKind() const { return isDestructorKind(getKind()); }
142
145 }
146
149 }
150
151 bool isRTTIKind() const { return isRTTIKind(getKind()); }
152
154 assert(isUsedFunctionPointerKind() &&
155 "GlobalDecl can be created only from virtual function");
156
157 auto *DtorDecl = dyn_cast<CXXDestructorDecl>(getFunctionDecl());
158 switch (getKind()) {
160 return GlobalDecl(getFunctionDecl());
162 return GlobalDecl(DtorDecl, CXXDtorType::Dtor_Complete);
164 return GlobalDecl(DtorDecl, CXXDtorType::Dtor_Deleting);
165 case CK_VCallOffset:
166 case CK_VBaseOffset:
167 case CK_OffsetToTop:
168 case CK_RTTI:
170 llvm_unreachable("Only function pointers kinds");
171 }
172 llvm_unreachable("Should already return");
173 }
174
175private:
176 static bool isFunctionPointerKind(Kind ComponentKind) {
177 return isUsedFunctionPointerKind(ComponentKind) ||
178 ComponentKind == CK_UnusedFunctionPointer;
179 }
180 static bool isUsedFunctionPointerKind(Kind ComponentKind) {
181 return ComponentKind == CK_FunctionPointer ||
182 isDestructorKind(ComponentKind);
183 }
184 static bool isDestructorKind(Kind ComponentKind) {
185 return ComponentKind == CK_CompleteDtorPointer ||
186 ComponentKind == CK_DeletingDtorPointer;
187 }
188 static bool isRTTIKind(Kind ComponentKind) {
189 return ComponentKind == CK_RTTI;
190 }
191
192 VTableComponent(Kind ComponentKind, CharUnits Offset) {
193 assert((ComponentKind == CK_VCallOffset ||
194 ComponentKind == CK_VBaseOffset ||
195 ComponentKind == CK_OffsetToTop) && "Invalid component kind!");
196 assert(Offset.getQuantity() < (1LL << 56) && "Offset is too big!");
197 assert(Offset.getQuantity() >= -(1LL << 56) && "Offset is too small!");
198
199 Value = (uint64_t(Offset.getQuantity()) << 3) | ComponentKind;
200 }
201
202 VTableComponent(Kind ComponentKind, uintptr_t Ptr) {
203 assert((isRTTIKind(ComponentKind) || isFunctionPointerKind(ComponentKind)) &&
204 "Invalid component kind!");
205
206 assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!");
207
208 Value = Ptr | ComponentKind;
209 }
210
211 CharUnits getOffset() const {
212 assert((getKind() == CK_VCallOffset || getKind() == CK_VBaseOffset ||
213 getKind() == CK_OffsetToTop) && "Invalid component kind!");
214
215 return CharUnits::fromQuantity(Value >> 3);
216 }
217
218 uintptr_t getPointer() const {
219 assert((getKind() == CK_RTTI || isFunctionPointerKind()) &&
220 "Invalid component kind!");
221
222 return static_cast<uintptr_t>(Value & ~7ULL);
223 }
224
225 /// The kind is stored in the lower 3 bits of the value. For offsets, we
226 /// make use of the facts that classes can't be larger than 2^55 bytes,
227 /// so we store the offset in the lower part of the 61 bits that remain.
228 /// (The reason that we're not simply using a PointerIntPair here is that we
229 /// need the offsets to be 64-bit, even when on a 32-bit machine).
231};
232
234public:
235 typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy;
238 };
239 typedef llvm::DenseMap<BaseSubobject, AddressPointLocation>
241
242 // Mapping between the VTable index and address point index. This is useful
243 // when you don't care about the base subobjects and only want the address
244 // point for a given vtable index.
246
247private:
248 // Stores the component indices of the first component of each virtual table in
249 // the virtual table group. To save a little memory in the common case where
250 // the vtable group contains a single vtable, an empty vector here represents
251 // the vector {0}.
252 OwningArrayRef<size_t> VTableIndices;
253
254 OwningArrayRef<VTableComponent> VTableComponents;
255
256 /// Contains thunks needed by vtables, sorted by indices.
258
259 /// Address points for all vtables.
260 AddressPointsMapTy AddressPoints;
261
262 /// Address points for all vtable indices.
263 AddressPointsIndexMapTy AddressPointIndices;
264
265public:
266 VTableLayout(ArrayRef<size_t> VTableIndices,
267 ArrayRef<VTableComponent> VTableComponents,
268 ArrayRef<VTableThunkTy> VTableThunks,
269 const AddressPointsMapTy &AddressPoints);
271
273 return VTableComponents;
274 }
275
277 return VTableThunks;
278 }
279
281 assert(AddressPoints.count(Base) && "Did not find address point!");
282 return AddressPoints.lookup(Base);
283 }
284
286 return AddressPoints;
287 }
288
290 return AddressPointIndices;
291 }
292
293 size_t getNumVTables() const {
294 if (VTableIndices.empty())
295 return 1;
296 return VTableIndices.size();
297 }
298
299 size_t getVTableOffset(size_t i) const {
300 if (VTableIndices.empty()) {
301 assert(i == 0);
302 return 0;
303 }
304 return VTableIndices[i];
305 }
306
307 size_t getVTableSize(size_t i) const {
308 if (VTableIndices.empty()) {
309 assert(i == 0);
310 return vtable_components().size();
311 }
312
313 size_t thisIndex = VTableIndices[i];
314 size_t nextIndex = (i + 1 == VTableIndices.size())
315 ? vtable_components().size()
316 : VTableIndices[i + 1];
317 return nextIndex - thisIndex;
318 }
319};
320
322public:
324
325 bool isMicrosoft() const { return IsMicrosoftABI; }
326
328
329protected:
330 typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
331
332 /// Contains all thunks that a given method decl will need.
334
335 /// Compute and store all vtable related information (vtable layout, vbase
336 /// offset offsets, thunks etc) for the given record decl.
338
340
341public:
343 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()->getCanonicalDecl());
345
346 // This assumes that all the destructors present in the vtable
347 // use exactly the same set of thunks.
348 ThunksMapTy::const_iterator I = Thunks.find(MD);
349 if (I == Thunks.end()) {
350 // We did not find a thunk for this method.
351 return nullptr;
352 }
353
354 return &I->second;
355 }
356
358
359 /// Determine whether this function should be assigned a vtable slot.
360 static bool hasVtableSlot(const CXXMethodDecl *MD);
361};
362
364private:
365
366 /// Contains the index (relative to the vtable address point)
367 /// where the function pointer for a virtual function is stored.
368 typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
369 MethodVTableIndicesTy MethodVTableIndices;
370
371 typedef llvm::DenseMap<const CXXRecordDecl *,
372 std::unique_ptr<const VTableLayout>>
373 VTableLayoutMapTy;
374 VTableLayoutMapTy VTableLayouts;
375
376 typedef std::pair<const CXXRecordDecl *,
377 const CXXRecordDecl *> ClassPairTy;
378
379 /// vtable offsets for offsets of virtual bases of a class.
380 ///
381 /// Contains the vtable offset (relative to the address point) in chars
382 /// where the offsets for virtual bases of a class are stored.
383 typedef llvm::DenseMap<ClassPairTy, CharUnits>
384 VirtualBaseClassOffsetOffsetsMapTy;
385 VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
386
387 void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
388
389public:
391 /// Components in the vtable are pointers to other structs/functions.
393
394 /// Components in the vtable are relative offsets between the vtable and the
395 /// other structs/functions.
397 };
398
400 VTableComponentLayout ComponentLayout = Pointer);
401 ~ItaniumVTableContext() override;
402
404 computeVTableRelatedInformation(RD);
405 assert(VTableLayouts.count(RD) && "No layout for this record decl!");
406
407 return *VTableLayouts[RD];
408 }
409
410 std::unique_ptr<VTableLayout> createConstructionVTableLayout(
411 const CXXRecordDecl *MostDerivedClass, CharUnits MostDerivedClassOffset,
412 bool MostDerivedClassIsVirtual, const CXXRecordDecl *LayoutClass);
413
414 /// Locate a virtual function in the vtable.
415 ///
416 /// Return the index (relative to the vtable address point) where the
417 /// function pointer for the given virtual function is stored.
418 uint64_t getMethodVTableIndex(GlobalDecl GD);
419
420 /// Return the offset in chars (relative to the vtable address point) where
421 /// the offset of the virtual base that contains the given base is stored,
422 /// otherwise, if no virtual base contains the given class, return 0.
423 ///
424 /// Base must be a virtual base class or an unambiguous base.
426 const CXXRecordDecl *VBase);
427
428 static bool classof(const VTableContextBase *VT) {
429 return !VT->isMicrosoft();
430 }
431
433 return ComponentLayout;
434 }
435
436 bool isPointerLayout() const { return ComponentLayout == Pointer; }
437 bool isRelativeLayout() const { return ComponentLayout == Relative; }
438
439private:
440 VTableComponentLayout ComponentLayout;
441};
442
443/// Holds information about the inheritance path to a virtual base or function
444/// table pointer. A record may contain as many vfptrs or vbptrs as there are
445/// base subobjects.
446struct VPtrInfo {
448
451
452 /// This is the most derived class that has this vptr at offset zero. When
453 /// single inheritance is used, this is always the most derived class. If
454 /// multiple inheritance is used, it may be any direct or indirect base.
456
457 /// This is the class that introduced the vptr by declaring new virtual
458 /// methods or virtual bases.
460
461 /// IntroducingObject is at this offset from its containing complete object or
462 /// virtual base.
464
465 /// The bases from the inheritance path that got used to mangle the vbtable
466 /// name. This is not really a full path like a CXXBasePath. It holds the
467 /// subset of records that need to be mangled into the vbtable symbol name in
468 /// order to get a unique name.
470
471 /// The next base to push onto the mangled path if this path is ambiguous in a
472 /// derived class. If it's null, then it's already been pushed onto the path.
474
475 /// The set of possibly indirect vbases that contain this vbtable. When a
476 /// derived class indirectly inherits from the same vbase twice, we only keep
477 /// vtables and their paths from the first instance.
479
480 /// This holds the base classes path from the complete type to the first base
481 /// with the given vfptr offset, in the base-to-derived order. Only used for
482 /// vftables.
484
485 /// Static offset from the top of the most derived class to this vfptr,
486 /// including any virtual base offset. Only used for vftables.
488
489 /// The vptr is stored inside the non-virtual component of this virtual base.
491 return ContainingVBases.empty() ? nullptr : ContainingVBases.front();
492 }
493};
494
496
497/// All virtual base related information about a given record decl. Includes
498/// information on all virtual base tables and the path components that are used
499/// to mangle them.
501 /// A map from virtual base to vbtable index for doing a conversion from the
502 /// the derived class to the a base.
503 llvm::DenseMap<const CXXRecordDecl *, unsigned> VBTableIndices;
504
505 /// Information on all virtual base tables used when this record is the most
506 /// derived class.
508};
509
511 /// If nonzero, holds the vbtable index of the virtual base with the vfptr.
512 uint64_t VBTableIndex;
513
514 /// If nonnull, holds the last vbase which contains the vfptr that the
515 /// method definition is adjusted to.
517
518 /// This is the offset of the vfptr from the start of the last vbase, or the
519 /// complete type if there are no virtual bases.
521
522 /// Method's index in the vftable.
523 uint64_t Index;
524
526 : VBTableIndex(0), VBase(nullptr), VFPtrOffset(CharUnits::Zero()),
527 Index(0) {}
528
530 CharUnits VFPtrOffset, uint64_t Index)
532 Index(Index) {}
533
534 bool operator<(const MethodVFTableLocation &other) const {
535 if (VBTableIndex != other.VBTableIndex) {
536 assert(VBase != other.VBase);
537 return VBTableIndex < other.VBTableIndex;
538 }
539 return std::tie(VFPtrOffset, Index) <
540 std::tie(other.VFPtrOffset, other.Index);
541 }
542};
543
545public:
546
547private:
548 ASTContext &Context;
549
550 typedef llvm::DenseMap<GlobalDecl, MethodVFTableLocation>
551 MethodVFTableLocationsTy;
552 MethodVFTableLocationsTy MethodVFTableLocations;
553
554 typedef llvm::DenseMap<const CXXRecordDecl *, std::unique_ptr<VPtrInfoVector>>
555 VFPtrLocationsMapTy;
556 VFPtrLocationsMapTy VFPtrLocations;
557
558 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
559 typedef llvm::DenseMap<VFTableIdTy, std::unique_ptr<const VTableLayout>>
560 VFTableLayoutMapTy;
561 VFTableLayoutMapTy VFTableLayouts;
562
563 llvm::DenseMap<const CXXRecordDecl *, std::unique_ptr<VirtualBaseInfo>>
564 VBaseInfo;
565
566 void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
567
568 void dumpMethodLocations(const CXXRecordDecl *RD,
569 const MethodVFTableLocationsTy &NewMethods,
570 raw_ostream &);
571
572 const VirtualBaseInfo &
573 computeVBTableRelatedInformation(const CXXRecordDecl *RD);
574
575 void computeVTablePaths(bool ForVBTables, const CXXRecordDecl *RD,
576 VPtrInfoVector &Paths);
577
578public:
580 : VTableContextBase(/*MS=*/true), Context(Context) {}
581
582 ~MicrosoftVTableContext() override;
583
585
587 CharUnits VFPtrOffset);
588
590
592 // Complete destructors don't have a slot in a vftable, so no thunks needed.
593 if (isa<CXXDestructorDecl>(GD.getDecl()) &&
595 return nullptr;
597 }
598
599 /// Returns the index of VBase in the vbtable of Derived.
600 /// VBase must be a morally virtual base of Derived.
601 /// The vbtable is an array of i32 offsets. The first entry is a self entry,
602 /// and the rest are offsets from the vbptr to virtual bases.
603 unsigned getVBTableIndex(const CXXRecordDecl *Derived,
604 const CXXRecordDecl *VBase);
605
607
608 static bool classof(const VTableContextBase *VT) { return VT->isMicrosoft(); }
609};
610
611} // namespace clang
612
613#endif
Enums/classes describing ABI related information about constructors, destructors and thunks.
Enums/classes describing THUNK related information about constructors, destructors and thunks.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2799
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2060
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition: DeclCXX.h:2186
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition: CharUnits.h:63
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:968
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:56
CXXDtorType getDtorType() const
Definition: GlobalDecl.h:110
const Decl * getDecl() const
Definition: GlobalDecl.h:103
@ Relative
Components in the vtable are relative offsets between the vtable and the other structs/functions.
@ Pointer
Components in the vtable are pointers to other structs/functions.
VTableComponentLayout getVTableComponentLayout() const
uint64_t getMethodVTableIndex(GlobalDecl GD)
Locate a virtual function in the vtable.
std::unique_ptr< VTableLayout > createConstructionVTableLayout(const CXXRecordDecl *MostDerivedClass, CharUnits MostDerivedClassOffset, bool MostDerivedClassIsVirtual, const CXXRecordDecl *LayoutClass)
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)
Return the offset in chars (relative to the vtable address point) where the offset of the virtual bas...
static bool classof(const VTableContextBase *VT)
static bool classof(const VTableContextBase *VT)
const ThunkInfoVectorTy * getThunkInfo(GlobalDecl GD) override
MicrosoftVTableContext(ASTContext &Context)
unsigned getVBTableIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the index of VBase in the vbtable of Derived.
const VPtrInfoVector & enumerateVBTables(const CXXRecordDecl *RD)
MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)
const VPtrInfoVector & getVFPtrOffsets(const CXXRecordDecl *RD)
const VTableLayout & getVFTableLayout(const CXXRecordDecl *RD, CharUnits VFPtrOffset)
Represents a single component in a vtable.
Definition: VTableBuilder.h:30
static VTableComponent MakeCompleteDtor(const CXXDestructorDecl *DD)
Definition: VTableBuilder.h:79
static VTableComponent MakeRTTI(const CXXRecordDecl *RD)
Definition: VTableBuilder.h:67
GlobalDecl getGlobalDecl() const
const CXXMethodDecl * getUnusedFunctionDecl() const
static VTableComponent MakeOffsetToTop(CharUnits Offset)
Definition: VTableBuilder.h:63
bool isUsedFunctionPointerKind() const
bool isDestructorKind() const
CharUnits getVBaseOffset() const
static VTableComponent MakeUnusedFunction(const CXXMethodDecl *MD)
Definition: VTableBuilder.h:89
Kind getKind() const
Get the kind of this vtable component.
Definition: VTableBuilder.h:97
static VTableComponent MakeFunction(const CXXMethodDecl *MD)
Definition: VTableBuilder.h:71
@ 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
static VTableComponent MakeVBaseOffset(CharUnits Offset)
Definition: VTableBuilder.h:59
const CXXRecordDecl * getRTTIDecl() const
static VTableComponent MakeDeletingDtor(const CXXDestructorDecl *DD)
Definition: VTableBuilder.h:84
bool isFunctionPointerKind() const
CharUnits getOffsetToTop() const
const CXXMethodDecl * getFunctionDecl() const
static VTableComponent MakeVCallOffset(CharUnits Offset)
Definition: VTableBuilder.h:55
CharUnits getVCallOffset() const
const CXXDestructorDecl * getDestructorDecl() const
virtual const ThunkInfoVectorTy * getThunkInfo(GlobalDecl GD)
static bool hasVtableSlot(const CXXMethodDecl *MD)
Determine whether this function should be assigned a vtable slot.
virtual void computeVTableRelatedInformation(const CXXRecordDecl *RD)=0
Compute and store all vtable related information (vtable layout, vbase offset offsets,...
SmallVector< ThunkInfo, 1 > ThunkInfoVectorTy
llvm::DenseMap< const CXXMethodDecl *, ThunkInfoVectorTy > ThunksMapTy
ThunksMapTy Thunks
Contains all thunks that a given method decl will need.
const AddressPointsIndexMapTy & getAddressPointIndices() const
size_t getVTableOffset(size_t i) const
llvm::SmallVector< unsigned, 4 > AddressPointsIndexMapTy
llvm::DenseMap< BaseSubobject, AddressPointLocation > AddressPointsMapTy
AddressPointLocation getAddressPoint(BaseSubobject Base) const
std::pair< uint64_t, ThunkInfo > VTableThunkTy
ArrayRef< VTableComponent > vtable_components() const
size_t getNumVTables() const
ArrayRef< VTableThunkTy > vtable_thunks() const
const AddressPointsMapTy & getAddressPoints() const
size_t getVTableSize(size_t i) const
The JSON file list parser is used to communicate input to InstallAPI.
SmallVector< std::unique_ptr< VPtrInfo >, 2 > VPtrInfoVector
@ Dtor_Complete
Complete object dtor.
Definition: ABI.h:35
@ Dtor_Deleting
Deleting dtor.
Definition: ABI.h:34
unsigned long uint64_t
long int64_t
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
#define true
Definition: stdbool.h:21
bool operator<(const MethodVFTableLocation &other) const
const CXXRecordDecl * VBase
If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to.
MethodVFTableLocation(uint64_t VBTableIndex, const CXXRecordDecl *VBase, CharUnits VFPtrOffset, uint64_t Index)
CharUnits VFPtrOffset
This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...
uint64_t VBTableIndex
If nonzero, holds the vbtable index of the virtual base with the vfptr.
uint64_t Index
Method's index in the vftable.
Holds information about the inheritance path to a virtual base or function table pointer.
CharUnits NonVirtualOffset
IntroducingObject is at this offset from its containing complete object or virtual base.
CharUnits FullOffsetInMDC
Static offset from the top of the most derived class to this vfptr, including any virtual base offset...
const CXXRecordDecl * getVBaseWithVPtr() const
The vptr is stored inside the non-virtual component of this virtual base.
SmallVector< const CXXRecordDecl *, 1 > BasePath
VPtrInfo(const CXXRecordDecl *RD)
BasePath ContainingVBases
The set of possibly indirect vbases that contain this vbtable.
const CXXRecordDecl * IntroducingObject
This is the class that introduced the vptr by declaring new virtual methods or virtual bases.
BasePath MangledPath
The bases from the inheritance path that got used to mangle the vbtable name.
const CXXRecordDecl * NextBaseToMangle
The next base to push onto the mangled path if this path is ambiguous in a derived class.
BasePath PathToIntroducingObject
This holds the base classes path from the complete type to the first base with the given vfptr offset...
const CXXRecordDecl * ObjectWithVPtr
This is the most derived class that has this vptr at offset zero.
All virtual base related information about a given record decl.
VPtrInfoVector VBPtrPaths
Information on all virtual base tables used when this record is the most derived class.
llvm::DenseMap< const CXXRecordDecl *, unsigned > VBTableIndices
A map from virtual base to vbtable index for doing a conversion from the the derived class to the a b...