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