clang 23.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 "llvm/ADT/SmallVector.h"
24#include <memory>
25#include <utility>
26
27namespace clang {
28 class CXXRecordDecl;
29
30/// Represents a single component in a vtable.
32public:
33 enum Kind {
39
40 /// A pointer to the complete destructor.
42
43 /// A pointer to the deleting destructor.
45
46 /// An entry that is never used.
47 ///
48 /// In some cases, a vtable function pointer will end up never being
49 /// called. Such vtable function pointers are represented as a
50 /// CK_UnusedFunctionPointer.
52 };
53
54 VTableComponent() = default;
55
57 return VTableComponent(CK_VCallOffset, Offset);
58 }
59
61 return VTableComponent(CK_VBaseOffset, Offset);
62 }
63
65 return VTableComponent(CK_OffsetToTop, Offset);
66 }
67
69 return VTableComponent(CK_RTTI, reinterpret_cast<uintptr_t>(RD));
70 }
71
73 assert(!isa<CXXDestructorDecl>(MD) &&
74 "Don't use MakeFunction with destructors!");
75
77 reinterpret_cast<uintptr_t>(MD));
78 }
79
82 reinterpret_cast<uintptr_t>(DD));
83 }
84
87 reinterpret_cast<uintptr_t>(DD));
88 }
89
91 assert(!isa<CXXDestructorDecl>(MD) &&
92 "Don't use MakeUnusedFunction with destructors!");
94 reinterpret_cast<uintptr_t>(MD));
95 }
96
97 /// Get the kind of this vtable component.
98 Kind getKind() const {
99 return (Kind)(Value & 0x7);
100 }
101
103 assert(getKind() == CK_VCallOffset && "Invalid component kind!");
104
105 return getOffset();
106 }
107
109 assert(getKind() == CK_VBaseOffset && "Invalid component kind!");
110
111 return getOffset();
112 }
113
115 assert(getKind() == CK_OffsetToTop && "Invalid component kind!");
116
117 return getOffset();
118 }
119
120 const CXXRecordDecl *getRTTIDecl() const {
121 assert(isRTTIKind() && "Invalid component kind!");
122 return reinterpret_cast<CXXRecordDecl *>(getPointer());
123 }
124
126 assert(isFunctionPointerKind() && "Invalid component kind!");
127 if (isDestructorKind())
128 return getDestructorDecl();
129 return reinterpret_cast<CXXMethodDecl *>(getPointer());
130 }
131
133 assert(isDestructorKind() && "Invalid component kind!");
134 return reinterpret_cast<CXXDestructorDecl *>(getPointer());
135 }
136
138 assert(getKind() == CK_UnusedFunctionPointer && "Invalid component kind!");
139 return reinterpret_cast<CXXMethodDecl *>(getPointer());
140 }
141
142 bool isDestructorKind() const { return isDestructorKind(getKind()); }
143
147
150 }
151
152 bool isRTTIKind() const { return isRTTIKind(getKind()); }
153
154 GlobalDecl getGlobalDecl(bool HasVectorDeletingDtors) const {
155 assert(isUsedFunctionPointerKind() &&
156 "GlobalDecl can be created only from virtual function");
157
158 auto *DtorDecl = dyn_cast<CXXDestructorDecl>(getFunctionDecl());
159 switch (getKind()) {
161 return GlobalDecl(getFunctionDecl());
163 return GlobalDecl(DtorDecl, CXXDtorType::Dtor_Complete);
165 return GlobalDecl(DtorDecl, (HasVectorDeletingDtors)
168 case CK_VCallOffset:
169 case CK_VBaseOffset:
170 case CK_OffsetToTop:
171 case CK_RTTI:
173 llvm_unreachable("Only function pointers kinds");
174 }
175 llvm_unreachable("Should already return");
176 }
177
178private:
179 static bool isFunctionPointerKind(Kind ComponentKind) {
180 return isUsedFunctionPointerKind(ComponentKind) ||
181 ComponentKind == CK_UnusedFunctionPointer;
182 }
183 static bool isUsedFunctionPointerKind(Kind ComponentKind) {
184 return ComponentKind == CK_FunctionPointer ||
185 isDestructorKind(ComponentKind);
186 }
187 static bool isDestructorKind(Kind ComponentKind) {
188 return ComponentKind == CK_CompleteDtorPointer ||
189 ComponentKind == CK_DeletingDtorPointer;
190 }
191 static bool isRTTIKind(Kind ComponentKind) {
192 return ComponentKind == CK_RTTI;
193 }
194
195 VTableComponent(Kind ComponentKind, CharUnits Offset) {
196 assert((ComponentKind == CK_VCallOffset ||
197 ComponentKind == CK_VBaseOffset ||
198 ComponentKind == CK_OffsetToTop) && "Invalid component kind!");
199 assert(Offset.getQuantity() < (1LL << 56) && "Offset is too big!");
200 assert(Offset.getQuantity() >= -(1LL << 56) && "Offset is too small!");
201
202 Value = (uint64_t(Offset.getQuantity()) << 3) | ComponentKind;
203 }
204
205 VTableComponent(Kind ComponentKind, uintptr_t Ptr) {
206 assert((isRTTIKind(ComponentKind) || isFunctionPointerKind(ComponentKind)) &&
207 "Invalid component kind!");
208
209 assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!");
210
211 Value = Ptr | ComponentKind;
212 }
213
214 CharUnits getOffset() const {
215 assert((getKind() == CK_VCallOffset || getKind() == CK_VBaseOffset ||
216 getKind() == CK_OffsetToTop) && "Invalid component kind!");
217
218 return CharUnits::fromQuantity(Value >> 3);
219 }
220
221 uintptr_t getPointer() const {
222 assert((getKind() == CK_RTTI || isFunctionPointerKind()) &&
223 "Invalid component kind!");
224
225 return static_cast<uintptr_t>(Value & ~7ULL);
226 }
227
228 /// The kind is stored in the lower 3 bits of the value. For offsets, we
229 /// make use of the facts that classes can't be larger than 2^55 bytes,
230 /// so we store the offset in the lower part of the 61 bits that remain.
231 /// (The reason that we're not simply using a PointerIntPair here is that we
232 /// need the offsets to be 64-bit, even when on a 32-bit machine).
233 int64_t Value;
234};
235
237public:
238 typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy;
242 typedef llvm::DenseMap<BaseSubobject, AddressPointLocation>
244
245 // Mapping between the VTable index and address point index. This is useful
246 // when you don't care about the base subobjects and only want the address
247 // point for a given vtable index.
249
251
252private:
253 // Stores the component indices of the first component of each virtual table
254 // in the virtual table group.
255 VTableIndicesTy VTableIndices;
256
258
259 /// Contains thunks needed by vtables, sorted by indices.
261
262 /// Address points for all vtables.
263 AddressPointsMapTy AddressPoints;
264
265 /// Address points for all vtable indices.
266 AddressPointsIndexMapTy AddressPointIndices;
267
268public:
269 // Requires `VTableIndices.front() == 0`
270 VTableLayout(VTableIndicesTy VTableIndices,
271 ArrayRef<VTableComponent> VTableComponents,
272 ArrayRef<VTableThunkTy> VTableThunks,
273 const AddressPointsMapTy &AddressPoints);
275
277 return VTableComponents;
278 }
279
281 return VTableThunks;
282 }
283
285 assert(AddressPoints.count(Base) && "Did not find address point!");
286 return AddressPoints.lookup(Base);
287 }
288
290 return AddressPoints;
291 }
292
294 return AddressPointIndices;
295 }
296
297 size_t getNumVTables() const { return VTableIndices.size(); }
298
299 size_t getVTableOffset(size_t i) const { return VTableIndices[i]; }
300
301 size_t getVTableSize(size_t i) const {
302 size_t thisIndex = VTableIndices[i];
303 size_t nextIndex = (i + 1 == VTableIndices.size())
304 ? vtable_components().size()
305 : VTableIndices[i + 1];
306 return nextIndex - thisIndex;
307 }
308};
309
311public:
313
314 bool isMicrosoft() const { return IsMicrosoftABI; }
315
317
318protected:
319 typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
320
321 /// Contains all thunks that a given method decl will need.
323
324 /// Compute and store all vtable related information (vtable layout, vbase
325 /// offset offsets, thunks etc) for the given record decl.
327
329
330public:
334
335 // This assumes that all the destructors present in the vtable
336 // use exactly the same set of thunks.
337 ThunksMapTy::const_iterator I = Thunks.find(MD);
338 if (I == Thunks.end()) {
339 // We did not find a thunk for this method.
340 return nullptr;
341 }
342
343 return &I->second;
344 }
345
347
348 /// Determine whether this function should be assigned a vtable slot.
349 static bool hasVtableSlot(const CXXMethodDecl *MD);
350};
351
353public:
354 typedef llvm::DenseMap<const CXXMethodDecl *, const CXXMethodDecl *>
356
357private:
358
359 /// Contains the index (relative to the vtable address point)
360 /// where the function pointer for a virtual function is stored.
361 typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
362 MethodVTableIndicesTy MethodVTableIndices;
363
364 typedef llvm::DenseMap<const CXXRecordDecl *,
365 std::unique_ptr<const VTableLayout>>
366 VTableLayoutMapTy;
367 VTableLayoutMapTy VTableLayouts;
368
369 typedef std::pair<const CXXRecordDecl *,
370 const CXXRecordDecl *> ClassPairTy;
371
372 /// vtable offsets for offsets of virtual bases of a class.
373 ///
374 /// Contains the vtable offset (relative to the address point) in chars
375 /// where the offsets for virtual bases of a class are stored.
376 typedef llvm::DenseMap<ClassPairTy, CharUnits>
377 VirtualBaseClassOffsetOffsetsMapTy;
378 VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
379
380 /// Map from a virtual method to the nearest method in the primary base class
381 /// chain that it overrides.
382 OriginalMethodMapTy OriginalMethodMap;
383
384 void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
385
386public:
388 /// Components in the vtable are pointers to other structs/functions.
390
391 /// Components in the vtable are relative offsets between the vtable and the
392 /// other structs/functions.
394 };
395
397 VTableComponentLayout ComponentLayout = Pointer);
398 ~ItaniumVTableContext() override;
399
401 computeVTableRelatedInformation(RD);
402 assert(VTableLayouts.count(RD) && "No layout for this record decl!");
403
404 return *VTableLayouts[RD];
405 }
406
407 std::unique_ptr<VTableLayout> createConstructionVTableLayout(
408 const CXXRecordDecl *MostDerivedClass, CharUnits MostDerivedClassOffset,
409 bool MostDerivedClassIsVirtual, const CXXRecordDecl *LayoutClass);
410
411 /// Locate a virtual function in the vtable.
412 ///
413 /// Return the index (relative to the vtable address point) where the
414 /// function pointer for the given virtual function is stored.
415 uint64_t getMethodVTableIndex(GlobalDecl GD);
416
417 /// Return the offset in chars (relative to the vtable address point) where
418 /// the offset of the virtual base that contains the given base is stored,
419 /// otherwise, if no virtual base contains the given class, return 0.
420 ///
421 /// Base must be a virtual base class or an unambiguous base.
423 const CXXRecordDecl *VBase);
424
425 /// Return the method that added the v-table slot that will be used to call
426 /// the given method.
427 ///
428 /// In the Itanium ABI, where overrides always cause methods to be added to
429 /// the primary v-table if they're not already there, this will be the first
430 /// declaration in the primary base class chain for which the return type
431 /// adjustment is trivial.
433
435
436 void setOriginalMethod(const CXXMethodDecl *Key, const CXXMethodDecl *Val) {
437 OriginalMethodMap[Key] = Val;
438 }
439
440 /// This method is reserved for the implementation and shouldn't be used
441 /// directly.
443 return OriginalMethodMap;
444 }
445
446 static bool classof(const VTableContextBase *VT) {
447 return !VT->isMicrosoft();
448 }
449
451 return ComponentLayout;
452 }
453
454 bool isPointerLayout() const { return ComponentLayout == Pointer; }
455 bool isRelativeLayout() const { return ComponentLayout == Relative; }
456
457private:
458 VTableComponentLayout ComponentLayout;
459};
460
461/// Holds information about the inheritance path to a virtual base or function
462/// table pointer. A record may contain as many vfptrs or vbptrs as there are
463/// base subobjects.
464struct VPtrInfo {
466
469
470 /// This is the most derived class that has this vptr at offset zero. When
471 /// single inheritance is used, this is always the most derived class. If
472 /// multiple inheritance is used, it may be any direct or indirect base.
474
475 /// This is the class that introduced the vptr by declaring new virtual
476 /// methods or virtual bases.
478
479 /// IntroducingObject is at this offset from its containing complete object or
480 /// virtual base.
482
483 /// The bases from the inheritance path that got used to mangle the vbtable
484 /// name. This is not really a full path like a CXXBasePath. It holds the
485 /// subset of records that need to be mangled into the vbtable symbol name in
486 /// order to get a unique name.
488
489 /// The next base to push onto the mangled path if this path is ambiguous in a
490 /// derived class. If it's null, then it's already been pushed onto the path.
492
493 /// The set of possibly indirect vbases that contain this vbtable. When a
494 /// derived class indirectly inherits from the same vbase twice, we only keep
495 /// vtables and their paths from the first instance.
497
498 /// This holds the base classes path from the complete type to the first base
499 /// with the given vfptr offset, in the base-to-derived order. Only used for
500 /// vftables.
502
503 /// Static offset from the top of the most derived class to this vfptr,
504 /// including any virtual base offset. Only used for vftables.
506
507 /// The vptr is stored inside the non-virtual component of this virtual base.
509 return ContainingVBases.empty() ? nullptr : ContainingVBases.front();
510 }
511};
512
514
515/// All virtual base related information about a given record decl. Includes
516/// information on all virtual base tables and the path components that are used
517/// to mangle them.
519 /// A map from virtual base to vbtable index for doing a conversion from the
520 /// the derived class to the a base.
521 llvm::DenseMap<const CXXRecordDecl *, unsigned> VBTableIndices;
522
523 /// Information on all virtual base tables used when this record is the most
524 /// derived class.
526};
527
529 /// If nonzero, holds the vbtable index of the virtual base with the vfptr.
530 uint64_t VBTableIndex;
531
532 /// If nonnull, holds the last vbase which contains the vfptr that the
533 /// method definition is adjusted to.
535
536 /// This is the offset of the vfptr from the start of the last vbase, or the
537 /// complete type if there are no virtual bases.
539
540 /// Method's index in the vftable.
541 uint64_t Index;
542
546
551
552 bool operator<(const MethodVFTableLocation &other) const {
553 if (VBTableIndex != other.VBTableIndex) {
554 assert(VBase != other.VBase);
555 return VBTableIndex < other.VBTableIndex;
556 }
557 return std::tie(VFPtrOffset, Index) <
558 std::tie(other.VFPtrOffset, other.Index);
559 }
560};
561
563public:
564
565private:
566 ASTContext &Context;
567
568 typedef llvm::DenseMap<GlobalDecl, MethodVFTableLocation>
569 MethodVFTableLocationsTy;
570 MethodVFTableLocationsTy MethodVFTableLocations;
571
572 typedef llvm::DenseMap<const CXXRecordDecl *, std::unique_ptr<VPtrInfoVector>>
573 VFPtrLocationsMapTy;
574 VFPtrLocationsMapTy VFPtrLocations;
575
576 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
577 typedef llvm::DenseMap<VFTableIdTy, std::unique_ptr<const VTableLayout>>
578 VFTableLayoutMapTy;
579 VFTableLayoutMapTy VFTableLayouts;
580
581 llvm::DenseMap<const CXXRecordDecl *, std::unique_ptr<VirtualBaseInfo>>
582 VBaseInfo;
583
584 void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
585
586 void dumpMethodLocations(const CXXRecordDecl *RD,
587 const MethodVFTableLocationsTy &NewMethods,
588 raw_ostream &);
589
590 const VirtualBaseInfo &
591 computeVBTableRelatedInformation(const CXXRecordDecl *RD);
592
593 void computeVTablePaths(bool ForVBTables, const CXXRecordDecl *RD,
594 VPtrInfoVector &Paths);
595
596public:
598 : VTableContextBase(/*MS=*/true), Context(Context) {}
599
600 ~MicrosoftVTableContext() override;
601
603
605 CharUnits VFPtrOffset);
606
608
610 // Complete destructors don't have a slot in a vftable, so no thunks needed.
613 return nullptr;
615 }
616
617 /// Returns the index of VBase in the vbtable of Derived.
618 /// VBase must be a morally virtual base of Derived.
619 /// The vbtable is an array of i32 offsets. The first entry is a self entry,
620 /// and the rest are offsets from the vbptr to virtual bases.
621 unsigned getVBTableIndex(const CXXRecordDecl *Derived,
622 const CXXRecordDecl *VBase);
623
625
626 static bool classof(const VTableContextBase *VT) { return VT->isMicrosoft(); }
627};
628
629} // namespace clang
630
631#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:220
Represents a C++ destructor within a class.
Definition DeclCXX.h:2869
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2129
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition DeclCXX.h:2255
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:978
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:57
CXXDtorType getDtorType() const
Definition GlobalDecl.h:113
const Decl * getDecl() const
Definition GlobalDecl.h:106
@ 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.
const CXXMethodDecl * findOriginalMethodInMap(const CXXMethodDecl *MD) const
const OriginalMethodMapTy & getOriginalMethodMap()
This method is reserved for the implementation and shouldn't be used directly.
VTableComponentLayout getVTableComponentLayout() const
uint64_t getMethodVTableIndex(GlobalDecl GD)
Locate a virtual function in the vtable.
llvm::DenseMap< const CXXMethodDecl *, const CXXMethodDecl * > OriginalMethodMapTy
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...
ItaniumVTableContext(ASTContext &Context, VTableComponentLayout ComponentLayout=Pointer)
GlobalDecl findOriginalMethod(GlobalDecl GD)
Return the method that added the v-table slot that will be used to call the given method.
void setOriginalMethod(const CXXMethodDecl *Key, const CXXMethodDecl *Val)
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)
static VTableComponent MakeCompleteDtor(const CXXDestructorDecl *DD)
static VTableComponent MakeRTTI(const CXXRecordDecl *RD)
const CXXMethodDecl * getUnusedFunctionDecl() const
static VTableComponent MakeOffsetToTop(CharUnits Offset)
bool isUsedFunctionPointerKind() const
bool isDestructorKind() const
CharUnits getVBaseOffset() const
static VTableComponent MakeUnusedFunction(const CXXMethodDecl *MD)
Kind getKind() const
Get the kind of this vtable component.
static VTableComponent MakeFunction(const CXXMethodDecl *MD)
@ CK_DeletingDtorPointer
A pointer to the deleting destructor.
@ CK_UnusedFunctionPointer
An entry that is never used.
@ CK_CompleteDtorPointer
A pointer to the complete destructor.
static VTableComponent MakeVBaseOffset(CharUnits Offset)
const CXXRecordDecl * getRTTIDecl() const
static VTableComponent MakeDeletingDtor(const CXXDestructorDecl *DD)
bool isFunctionPointerKind() const
CharUnits getOffsetToTop() const
const CXXMethodDecl * getFunctionDecl() const
GlobalDecl getGlobalDecl(bool HasVectorDeletingDtors) const
static VTableComponent MakeVCallOffset(CharUnits Offset)
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.
llvm::SmallVector< std::size_t > VTableIndicesTy
VTableLayout(VTableIndicesTy VTableIndices, ArrayRef< VTableComponent > VTableComponents, ArrayRef< VTableThunkTy > VTableThunks, const AddressPointsMapTy &AddressPoints)
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.
bool isa(CodeGen::Address addr)
Definition Address.h:330
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
SmallVector< std::unique_ptr< VPtrInfo >, 2 > VPtrInfoVector
@ Dtor_VectorDeleting
Vector deleting dtor.
Definition ABI.h:40
@ Dtor_Complete
Complete object dtor.
Definition ABI.h:36
@ Dtor_Deleting
Deleting dtor.
Definition ABI.h:35
U cast(CodeGen::Address addr)
Definition Address.h:327
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:25
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.
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...