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