zcov: / lib/CodeGen/CGVtable.h


Files: 1 Branches Taken: 100.0% 8 / 8
Generated: 2010-02-10 01:31 Branches Executed: 100.0% 8 / 8
Line Coverage: 100.0% 29 / 29


Programs: 5 Runs 14485


       1                 : //===--- CGVtable.h - Emit LLVM Code for C++ vtables ----------------------===//
       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/ADT/DenseSet.h"
      19                 : #include "llvm/GlobalVariable.h"
      20                 : #include "GlobalDecl.h"
      21                 : 
      22                 : namespace clang {
      23                 :   class CXXRecordDecl;
      24                 : 
      25                 : namespace CodeGen {
      26                 :   class CodeGenModule;
      27                 : 
      28                 : /// ThunkAdjustment - Virtual and non-virtual adjustment for thunks.
      29              265: class ThunkAdjustment {
      30                 : public:
      31              700:   ThunkAdjustment(int64_t NonVirtual, int64_t Virtual)
      32                 :   : NonVirtual(NonVirtual),
      33              700:     Virtual(Virtual) { }
      34                 : 
      35             2617:   ThunkAdjustment()
      36             2617:     : NonVirtual(0), Virtual(0) { }
      37                 : 
      38                 :   // isEmpty - Return whether this thunk adjustment is empty.
      39             3290:   bool isEmpty() const {
                     2962: branch 0 taken
                      328: branch 1 taken
                     2390: branch 2 taken
                      572: branch 3 taken
      40             3290:     return NonVirtual == 0 && Virtual == 0;
      41                 :   }
      42                 : 
      43                 :   /// NonVirtual - The non-virtual adjustment.
      44                 :   int64_t NonVirtual;
      45                 : 
      46                 :   /// Virtual - The virtual adjustment.
      47                 :   int64_t Virtual;
      48                 : };
      49                 : 
      50                 : /// CovariantThunkAdjustment - Adjustment of the 'this' pointer and the
      51                 : /// return pointer for covariant thunks.
      52                 : class CovariantThunkAdjustment {
      53                 : public:
      54                 :   CovariantThunkAdjustment(const ThunkAdjustment &ThisAdjustment,
      55              353:                            const ThunkAdjustment &ReturnAdjustment)
      56              353:   : ThisAdjustment(ThisAdjustment), ReturnAdjustment(ReturnAdjustment) { }
      57                 : 
      58                 :   CovariantThunkAdjustment() { }
      59                 : 
      60                 :   ThunkAdjustment ThisAdjustment;
      61                 :   ThunkAdjustment ReturnAdjustment;
      62                 : };
      63                 : 
      64                 : // BaseSubobject - Uniquely identifies a direct or indirect base class. 
      65                 : // Stores both the base class decl and the offset from the most derived class to
      66                 : // the base class.
      67            50304: class BaseSubobject {
      68                 :   /// Base - The base class declaration.
      69                 :   const CXXRecordDecl *Base;
      70                 :   
      71                 :   /// BaseOffset - The offset from the most derived class to the base class.
      72                 :   uint64_t BaseOffset;
      73                 :   
      74                 : public:
      75            12276:   BaseSubobject(const CXXRecordDecl *Base, uint64_t BaseOffset)
      76            12276:     : Base(Base), BaseOffset(BaseOffset) { }
      77                 :   
      78                 :   /// getBase - Returns the base class declaration.
      79             2621:   const CXXRecordDecl *getBase() const { return Base; }
      80                 : 
      81                 :   /// getBaseOffset - Returns the base class offset.
      82             2346:   uint64_t getBaseOffset() const { return BaseOffset; }
      83                 : 
      84            77456:   friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
                    68014: branch 0 taken
                     9442: branch 1 taken
                    67944: branch 2 taken
                       70: branch 3 taken
      85            77456:     return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
      86                 :  }
      87                 : };
      88                 : 
      89                 : } // end namespace CodeGen
      90                 : } // end namespace clang
      91                 : 
      92                 : namespace llvm {
      93                 : 
      94                 : template<> struct DenseMapInfo<clang::CodeGen::BaseSubobject> {
      95             7216:   static clang::CodeGen::BaseSubobject getEmptyKey() {
      96                 :     return clang::CodeGen::BaseSubobject(
      97                 :       DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
      98             7216:       DenseMapInfo<uint64_t>::getEmptyKey());
      99                 :   }
     100                 : 
     101             3002:   static clang::CodeGen::BaseSubobject getTombstoneKey() {
     102                 :     return clang::CodeGen::BaseSubobject(
     103                 :       DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
     104             3002:       DenseMapInfo<uint64_t>::getTombstoneKey());
     105                 :   }
     106                 : 
     107             2235:   static unsigned getHashValue(const clang::CodeGen::BaseSubobject &Base) {
     108                 :     return 
     109                 :       DenseMapInfo<const clang::CXXRecordDecl *>::getHashValue(Base.getBase()) ^
     110             2235:       DenseMapInfo<uint64_t>::getHashValue(Base.getBaseOffset());
     111                 :   }
     112                 : 
     113                 :   static bool isEqual(const clang::CodeGen::BaseSubobject &LHS, 
     114            68357:                       const clang::CodeGen::BaseSubobject &RHS) {
     115            68357:     return LHS == RHS;
     116                 :   }
     117                 : };
     118                 : 
     119                 : // It's OK to treat BaseSubobject as a POD type.
     120                 : template <> struct isPodLike<clang::CodeGen::BaseSubobject> {
     121                 :   static const bool value = true;
     122                 : };
     123                 : 
     124                 : }
     125                 : 
     126                 : namespace clang {
     127                 : namespace CodeGen {
     128                 : 
     129              599: class CGVtableInfo {
     130                 : public:
     131                 :   typedef std::vector<std::pair<GlobalDecl, ThunkAdjustment> >
     132                 :       AdjustmentVectorTy;
     133                 : 
     134                 :   typedef std::pair<const CXXRecordDecl *, uint64_t> CtorVtable_t;
     135                 :   typedef llvm::DenseMap<CtorVtable_t, int64_t> AddrSubMap_t;
     136                 :   typedef llvm::DenseMap<const CXXRecordDecl *, AddrSubMap_t *> AddrMap_t;
     137                 :   llvm::DenseMap<const CXXRecordDecl *, AddrMap_t*> AddressPoints;
     138                 : 
     139                 :   typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
     140                 : 
     141                 : private:
     142                 :   CodeGenModule &CGM;
     143                 : 
     144                 :   /// MethodVtableIndices - Contains the index (relative to the vtable address
     145                 :   /// point) where the function pointer for a virtual function is stored.
     146                 :   typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVtableIndicesTy;
     147                 :   MethodVtableIndicesTy MethodVtableIndices;
     148                 : 
     149                 :   typedef std::pair<const CXXRecordDecl *,
     150                 :                     const CXXRecordDecl *> ClassPairTy;
     151                 : 
     152                 :   /// VirtualBaseClassIndicies - Contains the index into the vtable where the
     153                 :   /// offsets for virtual bases of a class are stored.
     154                 :   typedef llvm::DenseMap<ClassPairTy, int64_t> VirtualBaseClassIndiciesTy;
     155                 :   VirtualBaseClassIndiciesTy VirtualBaseClassIndicies;
     156                 : 
     157                 :   /// Vtables - All the vtables which have been defined.
     158                 :   llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> Vtables;
     159                 :   
     160                 :   /// NumVirtualFunctionPointers - Contains the number of virtual function 
     161                 :   /// pointers in the vtable for a given record decl.
     162                 :   llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers;
     163                 : 
     164                 :   typedef llvm::DenseMap<GlobalDecl, AdjustmentVectorTy> SavedAdjustmentsTy;
     165                 :   SavedAdjustmentsTy SavedAdjustments;
     166                 :   llvm::DenseSet<const CXXRecordDecl*> SavedAdjustmentRecords;
     167                 : 
     168                 :   typedef llvm::DenseMap<ClassPairTy, uint64_t> SubVTTIndiciesTy;
     169                 :   SubVTTIndiciesTy SubVTTIndicies;
     170                 : 
     171                 :   /// getNumVirtualFunctionPointers - Return the number of virtual function
     172                 :   /// pointers in the vtable for a given record decl.
     173                 :   uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
     174                 :   
     175                 :   void ComputeMethodVtableIndices(const CXXRecordDecl *RD);
     176                 :   
     177                 :   /// GenerateClassData - Generate all the class data requires to be generated
     178                 :   /// upon definition of a KeyFunction.  This includes the vtable, the
     179                 :   /// rtti data structure and the VTT.
     180                 :   /// 
     181                 :   /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
     182                 :   void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
     183                 :                          const CXXRecordDecl *RD);
     184                 :  
     185                 :   llvm::GlobalVariable *
     186                 :   GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
     187                 :                  bool GenerateDefinition, const CXXRecordDecl *LayoutClass, 
     188                 :                  const CXXRecordDecl *RD, uint64_t Offset,
     189                 :                  AddressPointsMapTy& AddressPoints);
     190                 : 
     191                 :   llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
     192                 :                                     bool GenerateDefinition,
     193                 :                                     const CXXRecordDecl *RD);
     194                 : 
     195                 : public:
     196              625:   CGVtableInfo(CodeGenModule &CGM)
     197              625:     : CGM(CGM) { }
     198                 : 
     199                 :   /// needsVTTParameter - Return whether the given global decl needs a VTT
     200                 :   /// parameter, which it does if it's a base constructor or destructor with
     201                 :   /// virtual bases.
     202                 :   static bool needsVTTParameter(GlobalDecl GD);
     203                 : 
     204                 :   /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
     205                 :   /// given record decl.
     206                 :   uint64_t getSubVTTIndex(const CXXRecordDecl *RD, const CXXRecordDecl *Base);
     207                 :   
     208                 :   /// getMethodVtableIndex - Return the index (relative to the vtable address
     209                 :   /// point) where the function pointer for the given virtual function is
     210                 :   /// stored.
     211                 :   uint64_t getMethodVtableIndex(GlobalDecl GD);
     212                 : 
     213                 :   /// getVirtualBaseOffsetIndex - Return the index (relative to the vtable
     214                 :   /// address point) where the offset of the virtual base that contains the
     215                 :   /// given Base is stored, otherwise, if no virtual base contains the given
     216                 :   /// class, return 0.  Base must be a virtual base class or an unambigious
     217                 :   /// base.
     218                 :   int64_t getVirtualBaseOffsetIndex(const CXXRecordDecl *RD,
     219                 :                                     const CXXRecordDecl *VBase);
     220                 : 
     221                 :   AdjustmentVectorTy *getAdjustments(GlobalDecl GD);
     222                 : 
     223                 :   /// getVtableAddressPoint - returns the address point of the vtable for the
     224                 :   /// given record decl.
     225                 :   /// FIXME: This should return a list of address points.
     226                 :   uint64_t getVtableAddressPoint(const CXXRecordDecl *RD);
     227                 :   
     228                 :   llvm::GlobalVariable *getVtable(const CXXRecordDecl *RD);
     229                 :   
     230                 :   /// CtorVtableInfo - Information about a constructor vtable.
     231              111:   struct CtorVtableInfo {
     232                 :     /// Vtable - The vtable itself.
     233                 :     llvm::GlobalVariable *Vtable;
     234                 :   
     235                 :     /// AddressPoints - The address points in this constructor vtable.
     236                 :     AddressPointsMapTy AddressPoints;
     237                 :     
     238              111:     CtorVtableInfo() : Vtable(0) { }
     239                 :   };
     240                 :   
     241                 :   CtorVtableInfo getCtorVtable(const CXXRecordDecl *RD, 
     242                 :                                const BaseSubobject &Base);
     243                 :   
     244                 :   llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
     245                 :   
     246                 :   void MaybeEmitVtable(GlobalDecl GD);
     247                 : };
     248                 : 
     249                 : } // end namespace CodeGen
     250                 : } // end namespace clang
     251                 : #endif

Generated: 2010-02-10 01:31 by zcov