Home | History | Annotate | Download | only in CodeGen
      1 //===--- CGVTables.h - Emit LLVM Code for C++ vtables -----------*- 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 C++ code generation of virtual tables.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef CLANG_CODEGEN_CGVTABLE_H
     15 #define CLANG_CODEGEN_CGVTABLE_H
     16 
     17 #include "llvm/ADT/DenseMap.h"
     18 #include "llvm/GlobalVariable.h"
     19 #include "clang/Basic/ABI.h"
     20 #include "clang/AST/CharUnits.h"
     21 #include "clang/AST/GlobalDecl.h"
     22 
     23 namespace clang {
     24   class CXXRecordDecl;
     25 
     26 namespace CodeGen {
     27   class CodeGenModule;
     28 
     29 // BaseSubobject - Uniquely identifies a direct or indirect base class.
     30 // Stores both the base class decl and the offset from the most derived class to
     31 // the base class.
     32 class BaseSubobject {
     33   /// Base - The base class declaration.
     34   const CXXRecordDecl *Base;
     35 
     36   /// BaseOffset - The offset from the most derived class to the base class.
     37   CharUnits BaseOffset;
     38 
     39 public:
     40   BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset)
     41     : Base(Base), BaseOffset(BaseOffset) { }
     42 
     43   /// getBase - Returns the base class declaration.
     44   const CXXRecordDecl *getBase() const { return Base; }
     45 
     46   /// getBaseOffset - Returns the base class offset.
     47   CharUnits getBaseOffset() const { return BaseOffset; }
     48 
     49   friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
     50     return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
     51  }
     52 };
     53 
     54 } // end namespace CodeGen
     55 } // end namespace clang
     56 
     57 namespace llvm {
     58 
     59 template<> struct DenseMapInfo<clang::CodeGen::BaseSubobject> {
     60   static clang::CodeGen::BaseSubobject getEmptyKey() {
     61     return clang::CodeGen::BaseSubobject(
     62       DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
     63       clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getEmptyKey()));
     64   }
     65 
     66   static clang::CodeGen::BaseSubobject getTombstoneKey() {
     67     return clang::CodeGen::BaseSubobject(
     68       DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
     69       clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getTombstoneKey()));
     70   }
     71 
     72   static unsigned getHashValue(const clang::CodeGen::BaseSubobject &Base) {
     73     return
     74       DenseMapInfo<const clang::CXXRecordDecl *>::getHashValue(Base.getBase()) ^
     75       DenseMapInfo<int64_t>::getHashValue(Base.getBaseOffset().getQuantity());
     76   }
     77 
     78   static bool isEqual(const clang::CodeGen::BaseSubobject &LHS,
     79                       const clang::CodeGen::BaseSubobject &RHS) {
     80     return LHS == RHS;
     81   }
     82 };
     83 
     84 // It's OK to treat BaseSubobject as a POD type.
     85 template <> struct isPodLike<clang::CodeGen::BaseSubobject> {
     86   static const bool value = true;
     87 };
     88 
     89 }
     90 
     91 namespace clang {
     92 namespace CodeGen {
     93 
     94 class CodeGenVTables {
     95   CodeGenModule &CGM;
     96 
     97   /// MethodVTableIndices - Contains the index (relative to the vtable address
     98   /// point) where the function pointer for a virtual function is stored.
     99   typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
    100   MethodVTableIndicesTy MethodVTableIndices;
    101 
    102   typedef std::pair<const CXXRecordDecl *,
    103                     const CXXRecordDecl *> ClassPairTy;
    104 
    105   /// VirtualBaseClassOffsetOffsets - Contains the vtable offset (relative to
    106   /// the address point) in chars where the offsets for virtual bases of a class
    107   /// are stored.
    108   typedef llvm::DenseMap<ClassPairTy, CharUnits>
    109     VirtualBaseClassOffsetOffsetsMapTy;
    110   VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
    111 
    112   /// VTables - All the vtables which have been defined.
    113   llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
    114 
    115   /// NumVirtualFunctionPointers - Contains the number of virtual function
    116   /// pointers in the vtable for a given record decl.
    117   llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers;
    118 
    119   typedef llvm::SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
    120   typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
    121 
    122   /// Thunks - Contains all thunks that a given method decl will need.
    123   ThunksMapTy Thunks;
    124 
    125   // The layout entry and a bool indicating whether we've actually emitted
    126   // the vtable.
    127   typedef llvm::PointerIntPair<uint64_t *, 1, bool> VTableLayoutData;
    128   typedef llvm::DenseMap<const CXXRecordDecl *, VTableLayoutData>
    129     VTableLayoutMapTy;
    130 
    131   /// VTableLayoutMap - Stores the vtable layout for all record decls.
    132   /// The layout is stored as an array of 64-bit integers, where the first
    133   /// integer is the number of vtable entries in the layout, and the subsequent
    134   /// integers are the vtable components.
    135   VTableLayoutMapTy VTableLayoutMap;
    136 
    137   typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy;
    138   typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> AddressPointsMapTy;
    139 
    140   /// Address points - Address points for all vtables.
    141   AddressPointsMapTy AddressPoints;
    142 
    143   /// VTableAddressPointsMapTy - Address points for a single vtable.
    144   typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy;
    145 
    146   typedef llvm::SmallVector<std::pair<uint64_t, ThunkInfo>, 1>
    147     VTableThunksTy;
    148 
    149   typedef llvm::DenseMap<const CXXRecordDecl *, VTableThunksTy>
    150     VTableThunksMapTy;
    151 
    152   /// VTableThunksMap - Contains thunks needed by vtables.
    153   VTableThunksMapTy VTableThunksMap;
    154 
    155   uint64_t getNumVTableComponents(const CXXRecordDecl *RD) const {
    156     assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
    157 
    158     return VTableLayoutMap.lookup(RD).getPointer()[0];
    159   }
    160 
    161   const uint64_t *getVTableComponentsData(const CXXRecordDecl *RD) const {
    162     assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
    163 
    164     uint64_t *Components = VTableLayoutMap.lookup(RD).getPointer();
    165     return &Components[1];
    166   }
    167 
    168   typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> SubVTTIndiciesMapTy;
    169 
    170   /// SubVTTIndicies - Contains indices into the various sub-VTTs.
    171   SubVTTIndiciesMapTy SubVTTIndicies;
    172 
    173   typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t>
    174     SecondaryVirtualPointerIndicesMapTy;
    175 
    176   /// SecondaryVirtualPointerIndices - Contains the secondary virtual pointer
    177   /// indices.
    178   SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices;
    179 
    180   /// getNumVirtualFunctionPointers - Return the number of virtual function
    181   /// pointers in the vtable for a given record decl.
    182   uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
    183 
    184   void ComputeMethodVTableIndices(const CXXRecordDecl *RD);
    185 
    186   /// EmitThunk - Emit a single thunk.
    187   void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk,
    188                  bool UseAvailableExternallyLinkage);
    189 
    190   /// MaybeEmitThunkAvailableExternally - Try to emit the given thunk with
    191   /// available_externally linkage to allow for inlining of thunks.
    192   /// This will be done iff optimizations are enabled and the member function
    193   /// doesn't contain any incomplete types.
    194   void MaybeEmitThunkAvailableExternally(GlobalDecl GD, const ThunkInfo &Thunk);
    195 
    196   /// ComputeVTableRelatedInformation - Compute and store all vtable related
    197   /// information (vtable layout, vbase offset offsets, thunks etc) for the
    198   /// given record decl.
    199   void ComputeVTableRelatedInformation(const CXXRecordDecl *RD,
    200                                        bool VTableRequired);
    201 
    202   /// CreateVTableInitializer - Create a vtable initializer for the given record
    203   /// decl.
    204   /// \param Components - The vtable components; this is really an array of
    205   /// VTableComponents.
    206   llvm::Constant *CreateVTableInitializer(const CXXRecordDecl *RD,
    207                                           const uint64_t *Components,
    208                                           unsigned NumComponents,
    209                                           const VTableThunksTy &VTableThunks);
    210 
    211 public:
    212   CodeGenVTables(CodeGenModule &CGM)
    213     : CGM(CGM) { }
    214 
    215   /// \brief True if the VTable of this record must be emitted in the
    216   /// translation unit.
    217   bool ShouldEmitVTableInThisTU(const CXXRecordDecl *RD);
    218 
    219   /// needsVTTParameter - Return whether the given global decl needs a VTT
    220   /// parameter, which it does if it's a base constructor or destructor with
    221   /// virtual bases.
    222   static bool needsVTTParameter(GlobalDecl GD);
    223 
    224   /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
    225   /// given record decl.
    226   uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base);
    227 
    228   /// getSecondaryVirtualPointerIndex - Return the index in the VTT where the
    229   /// virtual pointer for the given subobject is located.
    230   uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
    231                                            BaseSubobject Base);
    232 
    233   /// getMethodVTableIndex - Return the index (relative to the vtable address
    234   /// point) where the function pointer for the given virtual function is
    235   /// stored.
    236   uint64_t getMethodVTableIndex(GlobalDecl GD);
    237 
    238   /// getVirtualBaseOffsetOffset - Return the offset in chars (relative to the
    239   /// vtable address point) where the offset of the virtual base that contains
    240   /// the given base is stored, otherwise, if no virtual base contains the given
    241   /// class, return 0.  Base must be a virtual base class or an unambigious
    242   /// base.
    243   CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
    244                                        const CXXRecordDecl *VBase);
    245 
    246   /// getAddressPoint - Get the address point of the given subobject in the
    247   /// class decl.
    248   uint64_t getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD);
    249 
    250   /// GetAddrOfVTable - Get the address of the vtable for the given record decl.
    251   llvm::GlobalVariable *GetAddrOfVTable(const CXXRecordDecl *RD);
    252 
    253   /// EmitVTableDefinition - Emit the definition of the given vtable.
    254   void EmitVTableDefinition(llvm::GlobalVariable *VTable,
    255                             llvm::GlobalVariable::LinkageTypes Linkage,
    256                             const CXXRecordDecl *RD);
    257 
    258   /// GenerateConstructionVTable - Generate a construction vtable for the given
    259   /// base subobject.
    260   llvm::GlobalVariable *
    261   GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base,
    262                              bool BaseIsVirtual,
    263                              llvm::GlobalVariable::LinkageTypes Linkage,
    264                              VTableAddressPointsMapTy& AddressPoints);
    265 
    266 
    267   /// GetAddrOfVTable - Get the address of the VTT for the given record decl.
    268   llvm::GlobalVariable *GetAddrOfVTT(const CXXRecordDecl *RD);
    269 
    270   /// EmitVTTDefinition - Emit the definition of the given vtable.
    271   void EmitVTTDefinition(llvm::GlobalVariable *VTT,
    272                          llvm::GlobalVariable::LinkageTypes Linkage,
    273                          const CXXRecordDecl *RD);
    274 
    275   /// EmitThunks - Emit the associated thunks for the given global decl.
    276   void EmitThunks(GlobalDecl GD);
    277 
    278   /// GenerateClassData - Generate all the class data required to be generated
    279   /// upon definition of a KeyFunction.  This includes the vtable, the
    280   /// rtti data structure and the VTT.
    281   ///
    282   /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
    283   void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
    284                          const CXXRecordDecl *RD);
    285 };
    286 
    287 } // end namespace CodeGen
    288 } // end namespace clang
    289 #endif
    290