Home | History | Annotate | Download | only in AST
      1 //===--- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-=//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This contains code dealing with generation of the layout of virtual table
     11 // tables (VTT).
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_AST_VTTBUILDER_H
     16 #define LLVM_CLANG_AST_VTTBUILDER_H
     17 
     18 #include "clang/AST/BaseSubobject.h"
     19 #include "clang/AST/CXXInheritance.h"
     20 #include "clang/AST/GlobalDecl.h"
     21 #include "clang/AST/RecordLayout.h"
     22 #include "clang/Basic/ABI.h"
     23 #include "llvm/ADT/SetVector.h"
     24 #include <utility>
     25 
     26 namespace clang {
     27 
     28 class VTTVTable {
     29   llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
     30   CharUnits BaseOffset;
     31 
     32 public:
     33   VTTVTable() {}
     34   VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
     35     : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
     36   VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
     37     : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
     38       BaseOffset(Base.getBaseOffset()) {}
     39 
     40   const CXXRecordDecl *getBase() const {
     41     return BaseAndIsVirtual.getPointer();
     42   }
     43 
     44   CharUnits getBaseOffset() const {
     45     return BaseOffset;
     46   }
     47 
     48   bool isVirtual() const {
     49     return BaseAndIsVirtual.getInt();
     50   }
     51 
     52   BaseSubobject getBaseSubobject() const {
     53     return BaseSubobject(getBase(), getBaseOffset());
     54   }
     55 };
     56 
     57 struct VTTComponent {
     58   uint64_t VTableIndex;
     59   BaseSubobject VTableBase;
     60 
     61   VTTComponent() {}
     62   VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
     63     : VTableIndex(VTableIndex), VTableBase(VTableBase) {}
     64 };
     65 
     66 /// \brief Class for building VTT layout information.
     67 class VTTBuilder {
     68 
     69   ASTContext &Ctx;
     70 
     71   /// \brief The most derived class for which we're building this vtable.
     72   const CXXRecordDecl *MostDerivedClass;
     73 
     74   typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy;
     75 
     76   /// \brief The VTT vtables.
     77   VTTVTablesVectorTy VTTVTables;
     78 
     79   typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy;
     80 
     81   /// \brief The VTT components.
     82   VTTComponentsVectorTy VTTComponents;
     83 
     84   /// \brief The AST record layout of the most derived class.
     85   const ASTRecordLayout &MostDerivedClassLayout;
     86 
     87   typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
     88 
     89   typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
     90 
     91   /// \brief The sub-VTT indices for the bases of the most derived class.
     92   llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
     93 
     94   /// \brief The secondary virtual pointer indices of all subobjects of
     95   /// the most derived class.
     96   llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
     97 
     98   /// \brief Whether the VTT builder should generate LLVM IR for the VTT.
     99   bool GenerateDefinition;
    100 
    101   /// \brief Add a vtable pointer to the VTT currently being built.
    102   void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
    103                         const CXXRecordDecl *VTableClass);
    104 
    105   /// \brief Lay out the secondary VTTs of the given base subobject.
    106   void LayoutSecondaryVTTs(BaseSubobject Base);
    107 
    108   /// \brief Lay out the secondary virtual pointers for the given base
    109   /// subobject.
    110   ///
    111   /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
    112   /// or a direct or indirect base of a virtual base.
    113   void LayoutSecondaryVirtualPointers(BaseSubobject Base,
    114                                       bool BaseIsMorallyVirtual,
    115                                       uint64_t VTableIndex,
    116                                       const CXXRecordDecl *VTableClass,
    117                                       VisitedVirtualBasesSetTy &VBases);
    118 
    119   /// \brief Lay out the secondary virtual pointers for the given base
    120   /// subobject.
    121   void LayoutSecondaryVirtualPointers(BaseSubobject Base,
    122                                       uint64_t VTableIndex);
    123 
    124   /// \brief Lay out the VTTs for the virtual base classes of the given
    125   /// record declaration.
    126   void LayoutVirtualVTTs(const CXXRecordDecl *RD,
    127                          VisitedVirtualBasesSetTy &VBases);
    128 
    129   /// \brief Lay out the VTT for the given subobject, including any
    130   /// secondary VTTs, secondary virtual pointers and virtual VTTs.
    131   void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
    132 
    133 public:
    134   VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass,
    135              bool GenerateDefinition);
    136 
    137   // \brief Returns a reference to the VTT components.
    138   const VTTComponentsVectorTy &getVTTComponents() const {
    139     return VTTComponents;
    140   }
    141 
    142   // \brief Returns a reference to the VTT vtables.
    143   const VTTVTablesVectorTy &getVTTVTables() const {
    144     return VTTVTables;
    145   }
    146 
    147   /// \brief Returns a reference to the sub-VTT indices.
    148   const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
    149     return SubVTTIndicies;
    150   }
    151 
    152   /// \brief Returns a reference to the secondary virtual pointer indices.
    153   const llvm::DenseMap<BaseSubobject, uint64_t> &
    154   getSecondaryVirtualPointerIndices() const {
    155     return SecondaryVirtualPointerIndices;
    156   }
    157 
    158 };
    159 
    160 }
    161 
    162 #endif
    163