• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
BaseSubobject(const CXXRecordDecl * Base,CharUnits BaseOffset)40   BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset)
41     : Base(Base), BaseOffset(BaseOffset) { }
42 
43   /// getBase - Returns the base class declaration.
getBase()44   const CXXRecordDecl *getBase() const { return Base; }
45 
46   /// getBaseOffset - Returns the base class offset.
getBaseOffset()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