xref: /freebsd/contrib/llvm-project/clang/include/clang/AST/VTTBuilder.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This contains code dealing with generation of the layout of virtual table
100b57cec5SDimitry Andric // tables (VTT).
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #ifndef LLVM_CLANG_AST_VTTBUILDER_H
150b57cec5SDimitry Andric #define LLVM_CLANG_AST_VTTBUILDER_H
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include "clang/AST/BaseSubobject.h"
180b57cec5SDimitry Andric #include "clang/AST/CharUnits.h"
190b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
200b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
210b57cec5SDimitry Andric #include "llvm/ADT/PointerIntPair.h"
220b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
230b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
240b57cec5SDimitry Andric #include <cstdint>
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric namespace clang {
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric class ASTContext;
290b57cec5SDimitry Andric class ASTRecordLayout;
300b57cec5SDimitry Andric class CXXRecordDecl;
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric class VTTVTable {
330b57cec5SDimitry Andric   llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
340b57cec5SDimitry Andric   CharUnits BaseOffset;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric public:
370b57cec5SDimitry Andric   VTTVTable() = default;
VTTVTable(const CXXRecordDecl * Base,CharUnits BaseOffset,bool BaseIsVirtual)380b57cec5SDimitry Andric   VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
390b57cec5SDimitry Andric       : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
VTTVTable(BaseSubobject Base,bool BaseIsVirtual)400b57cec5SDimitry Andric   VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
410b57cec5SDimitry Andric       : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
420b57cec5SDimitry Andric         BaseOffset(Base.getBaseOffset()) {}
430b57cec5SDimitry Andric 
getBase()440b57cec5SDimitry Andric   const CXXRecordDecl *getBase() const {
450b57cec5SDimitry Andric     return BaseAndIsVirtual.getPointer();
460b57cec5SDimitry Andric   }
470b57cec5SDimitry Andric 
getBaseOffset()480b57cec5SDimitry Andric   CharUnits getBaseOffset() const {
490b57cec5SDimitry Andric     return BaseOffset;
500b57cec5SDimitry Andric   }
510b57cec5SDimitry Andric 
isVirtual()520b57cec5SDimitry Andric   bool isVirtual() const {
530b57cec5SDimitry Andric     return BaseAndIsVirtual.getInt();
540b57cec5SDimitry Andric   }
550b57cec5SDimitry Andric 
getBaseSubobject()560b57cec5SDimitry Andric   BaseSubobject getBaseSubobject() const {
570b57cec5SDimitry Andric     return BaseSubobject(getBase(), getBaseOffset());
580b57cec5SDimitry Andric   }
590b57cec5SDimitry Andric };
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric struct VTTComponent {
620b57cec5SDimitry Andric   uint64_t VTableIndex;
630b57cec5SDimitry Andric   BaseSubobject VTableBase;
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   VTTComponent() = default;
VTTComponentVTTComponent660b57cec5SDimitry Andric   VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
670b57cec5SDimitry Andric      : VTableIndex(VTableIndex), VTableBase(VTableBase) {}
680b57cec5SDimitry Andric };
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric /// Class for building VTT layout information.
710b57cec5SDimitry Andric class VTTBuilder {
720b57cec5SDimitry Andric   ASTContext &Ctx;
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   /// The most derived class for which we're building this vtable.
750b57cec5SDimitry Andric   const CXXRecordDecl *MostDerivedClass;
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric   using VTTVTablesVectorTy = SmallVector<VTTVTable, 64>;
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   /// The VTT vtables.
800b57cec5SDimitry Andric   VTTVTablesVectorTy VTTVTables;
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   using VTTComponentsVectorTy = SmallVector<VTTComponent, 64>;
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric   /// The VTT components.
850b57cec5SDimitry Andric   VTTComponentsVectorTy VTTComponents;
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   /// The AST record layout of the most derived class.
880b57cec5SDimitry Andric   const ASTRecordLayout &MostDerivedClassLayout;
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric   using VisitedVirtualBasesSetTy = llvm::SmallPtrSet<const CXXRecordDecl *, 4>;
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   using AddressPointsMapTy = llvm::DenseMap<BaseSubobject, uint64_t>;
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric   /// The sub-VTT indices for the bases of the most derived class.
95*0fca6ea1SDimitry Andric   llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndices;
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   /// The secondary virtual pointer indices of all subobjects of
980b57cec5SDimitry Andric   /// the most derived class.
990b57cec5SDimitry Andric   llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric   /// Whether the VTT builder should generate LLVM IR for the VTT.
1020b57cec5SDimitry Andric   bool GenerateDefinition;
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric   /// Add a vtable pointer to the VTT currently being built.
1050b57cec5SDimitry Andric   void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
1060b57cec5SDimitry Andric                         const CXXRecordDecl *VTableClass);
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric   /// Lay out the secondary VTTs of the given base subobject.
1090b57cec5SDimitry Andric   void LayoutSecondaryVTTs(BaseSubobject Base);
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric   /// Lay out the secondary virtual pointers for the given base
1120b57cec5SDimitry Andric   /// subobject.
1130b57cec5SDimitry Andric   ///
1140b57cec5SDimitry Andric   /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
1150b57cec5SDimitry Andric   /// or a direct or indirect base of a virtual base.
1160b57cec5SDimitry Andric   void LayoutSecondaryVirtualPointers(BaseSubobject Base,
1170b57cec5SDimitry Andric                                       bool BaseIsMorallyVirtual,
1180b57cec5SDimitry Andric                                       uint64_t VTableIndex,
1190b57cec5SDimitry Andric                                       const CXXRecordDecl *VTableClass,
1200b57cec5SDimitry Andric                                       VisitedVirtualBasesSetTy &VBases);
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   /// Lay out the secondary virtual pointers for the given base
1230b57cec5SDimitry Andric   /// subobject.
1240b57cec5SDimitry Andric   void LayoutSecondaryVirtualPointers(BaseSubobject Base,
1250b57cec5SDimitry Andric                                       uint64_t VTableIndex);
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric   /// Lay out the VTTs for the virtual base classes of the given
1280b57cec5SDimitry Andric   /// record declaration.
1290b57cec5SDimitry Andric   void LayoutVirtualVTTs(const CXXRecordDecl *RD,
1300b57cec5SDimitry Andric                          VisitedVirtualBasesSetTy &VBases);
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric   /// Lay out the VTT for the given subobject, including any
1330b57cec5SDimitry Andric   /// secondary VTTs, secondary virtual pointers and virtual VTTs.
1340b57cec5SDimitry Andric   void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric public:
1370b57cec5SDimitry Andric   VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass,
1380b57cec5SDimitry Andric              bool GenerateDefinition);
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   // Returns a reference to the VTT components.
getVTTComponents()1410b57cec5SDimitry Andric   const VTTComponentsVectorTy &getVTTComponents() const {
1420b57cec5SDimitry Andric     return VTTComponents;
1430b57cec5SDimitry Andric   }
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric   // Returns a reference to the VTT vtables.
getVTTVTables()1460b57cec5SDimitry Andric   const VTTVTablesVectorTy &getVTTVTables() const {
1470b57cec5SDimitry Andric     return VTTVTables;
1480b57cec5SDimitry Andric   }
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric   /// Returns a reference to the sub-VTT indices.
getSubVTTIndices()151*0fca6ea1SDimitry Andric   const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndices() const {
152*0fca6ea1SDimitry Andric     return SubVTTIndices;
1530b57cec5SDimitry Andric   }
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric   /// Returns a reference to the secondary virtual pointer indices.
1560b57cec5SDimitry Andric   const llvm::DenseMap<BaseSubobject, uint64_t> &
getSecondaryVirtualPointerIndices()1570b57cec5SDimitry Andric   getSecondaryVirtualPointerIndices() const {
1580b57cec5SDimitry Andric     return SecondaryVirtualPointerIndices;
1590b57cec5SDimitry Andric   }
1600b57cec5SDimitry Andric };
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric } // namespace clang
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric #endif // LLVM_CLANG_AST_VTTBUILDER_H
165