blob: 216fd059a8302be897056f6e6db90349267f9450 [file] [log] [blame]
Anders Carlsson2bb27f52009-10-11 22:13:54 +00001//===--- 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"
Eli Friedman8174f2c2009-12-06 22:01:30 +000018#include "llvm/ADT/DenseSet.h"
Anders Carlsson0911ae82009-12-06 00:23:49 +000019#include "llvm/GlobalVariable.h"
Anders Carlssonfb4dda42009-11-13 17:08:56 +000020#include "GlobalDecl.h"
Anders Carlsson2bb27f52009-10-11 22:13:54 +000021
22namespace clang {
Anders Carlsson2bb27f52009-10-11 22:13:54 +000023 class CXXRecordDecl;
Benjamin Kramer334af992009-11-26 13:09:03 +000024
Anders Carlsson2bb27f52009-10-11 22:13:54 +000025namespace CodeGen {
26 class CodeGenModule;
Anders Carlssonc7785402009-11-26 02:32:05 +000027
Anders Carlsson67fd3a50d2010-03-23 15:13:06 +000028/// ReturnAdjustment - A return adjustment.
29struct ReturnAdjustment {
30 /// NonVirtual - The non-virtual adjustment from the derived object to its
31 /// nearest virtual base.
32 int64_t NonVirtual;
33
34 /// VBaseOffsetOffset - The offset (in bytes), relative to the address point
35 /// of the virtual base class offset.
36 int64_t VBaseOffsetOffset;
37
38 ReturnAdjustment() : NonVirtual(0), VBaseOffsetOffset(0) { }
39
40 bool isEmpty() const { return !NonVirtual && !VBaseOffsetOffset; }
41
42 friend bool operator==(const ReturnAdjustment &LHS,
43 const ReturnAdjustment &RHS) {
44 return LHS.NonVirtual == RHS.NonVirtual &&
45 LHS.VBaseOffsetOffset == RHS.VBaseOffsetOffset;
46 }
47
48 friend bool operator<(const ReturnAdjustment &LHS,
49 const ReturnAdjustment &RHS) {
50 if (LHS.NonVirtual < RHS.NonVirtual)
51 return true;
52
53 return LHS.NonVirtual == RHS.NonVirtual &&
54 LHS.VBaseOffsetOffset < RHS.VBaseOffsetOffset;
55 }
56};
57
58/// ThisAdjustment - A 'this' pointer adjustment.
59struct ThisAdjustment {
60 /// NonVirtual - The non-virtual adjustment from the derived object to its
61 /// nearest virtual base.
62 int64_t NonVirtual;
63
64 /// VCallOffsetOffset - The offset (in bytes), relative to the address point,
65 /// of the virtual call offset.
66 int64_t VCallOffsetOffset;
67
68 ThisAdjustment() : NonVirtual(0), VCallOffsetOffset(0) { }
69
70 bool isEmpty() const { return !NonVirtual && !VCallOffsetOffset; }
71
72 friend bool operator==(const ThisAdjustment &LHS,
73 const ThisAdjustment &RHS) {
74 return LHS.NonVirtual == RHS.NonVirtual &&
75 LHS.VCallOffsetOffset == RHS.VCallOffsetOffset;
76 }
77
78 friend bool operator<(const ThisAdjustment &LHS,
79 const ThisAdjustment &RHS) {
80 if (LHS.NonVirtual < RHS.NonVirtual)
81 return true;
82
83 return LHS.NonVirtual == RHS.NonVirtual &&
84 LHS.VCallOffsetOffset < RHS.VCallOffsetOffset;
85 }
Anders Carlsson67fd3a50d2010-03-23 15:13:06 +000086};
87
Anders Carlsson274fc822010-03-23 15:17:13 +000088/// ThunkInfo - The 'this' pointer adjustment as well as an optional return
89/// adjustment for a thunk.
90struct ThunkInfo {
91 /// This - The 'this' pointer adjustment.
92 ThisAdjustment This;
93
94 /// Return - The return adjustment.
95 ReturnAdjustment Return;
96
97 ThunkInfo() { }
98
99 ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return)
100 : This(This), Return(Return) { }
101
102 friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
103 return LHS.This == RHS.This && LHS.Return == RHS.Return;
104 }
105
106 friend bool operator<(const ThunkInfo &LHS, const ThunkInfo &RHS) {
107 if (LHS.This < RHS.This)
108 return true;
109
110 return LHS.This == RHS.This && LHS.Return < RHS.Return;
111 }
112
113 bool isEmpty() const { return This.isEmpty() && Return.isEmpty(); }
114};
115
Benjamin Kramer334af992009-11-26 13:09:03 +0000116/// ThunkAdjustment - Virtual and non-virtual adjustment for thunks.
117class ThunkAdjustment {
118public:
Anders Carlssonc7785402009-11-26 02:32:05 +0000119 ThunkAdjustment(int64_t NonVirtual, int64_t Virtual)
Benjamin Kramer334af992009-11-26 13:09:03 +0000120 : NonVirtual(NonVirtual),
Anders Carlssonc7785402009-11-26 02:32:05 +0000121 Virtual(Virtual) { }
Benjamin Kramer334af992009-11-26 13:09:03 +0000122
Anders Carlssonc7785402009-11-26 02:32:05 +0000123 ThunkAdjustment()
124 : NonVirtual(0), Virtual(0) { }
Benjamin Kramer334af992009-11-26 13:09:03 +0000125
Anders Carlssonc7785402009-11-26 02:32:05 +0000126 // isEmpty - Return whether this thunk adjustment is empty.
Benjamin Kramer334af992009-11-26 13:09:03 +0000127 bool isEmpty() const {
Anders Carlssonc7785402009-11-26 02:32:05 +0000128 return NonVirtual == 0 && Virtual == 0;
129 }
Benjamin Kramer334af992009-11-26 13:09:03 +0000130
Anders Carlssonc7785402009-11-26 02:32:05 +0000131 /// NonVirtual - The non-virtual adjustment.
132 int64_t NonVirtual;
Benjamin Kramer334af992009-11-26 13:09:03 +0000133
Anders Carlssonc7785402009-11-26 02:32:05 +0000134 /// Virtual - The virtual adjustment.
135 int64_t Virtual;
136};
137
Anders Carlsson2f87c4f2009-11-26 03:09:37 +0000138/// CovariantThunkAdjustment - Adjustment of the 'this' pointer and the
139/// return pointer for covariant thunks.
Benjamin Kramer334af992009-11-26 13:09:03 +0000140class CovariantThunkAdjustment {
141public:
Anders Carlsson2f87c4f2009-11-26 03:09:37 +0000142 CovariantThunkAdjustment(const ThunkAdjustment &ThisAdjustment,
143 const ThunkAdjustment &ReturnAdjustment)
144 : ThisAdjustment(ThisAdjustment), ReturnAdjustment(ReturnAdjustment) { }
145
146 CovariantThunkAdjustment() { }
147
148 ThunkAdjustment ThisAdjustment;
149 ThunkAdjustment ReturnAdjustment;
150};
151
Anders Carlsson20871482010-01-13 20:11:15 +0000152// BaseSubobject - Uniquely identifies a direct or indirect base class.
153// Stores both the base class decl and the offset from the most derived class to
154// the base class.
155class BaseSubobject {
156 /// Base - The base class declaration.
157 const CXXRecordDecl *Base;
158
159 /// BaseOffset - The offset from the most derived class to the base class.
160 uint64_t BaseOffset;
161
162public:
163 BaseSubobject(const CXXRecordDecl *Base, uint64_t BaseOffset)
164 : Base(Base), BaseOffset(BaseOffset) { }
165
166 /// getBase - Returns the base class declaration.
167 const CXXRecordDecl *getBase() const { return Base; }
168
169 /// getBaseOffset - Returns the base class offset.
170 uint64_t getBaseOffset() const { return BaseOffset; }
Anders Carlsson2a4adbe2010-01-14 01:39:42 +0000171
Anders Carlsson20871482010-01-13 20:11:15 +0000172 friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
173 return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
174 }
175};
Anders Carlsson2a4adbe2010-01-14 01:39:42 +0000176
177} // end namespace CodeGen
178} // end namespace clang
179
180namespace llvm {
181
182template<> struct DenseMapInfo<clang::CodeGen::BaseSubobject> {
183 static clang::CodeGen::BaseSubobject getEmptyKey() {
184 return clang::CodeGen::BaseSubobject(
185 DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
186 DenseMapInfo<uint64_t>::getEmptyKey());
187 }
188
189 static clang::CodeGen::BaseSubobject getTombstoneKey() {
190 return clang::CodeGen::BaseSubobject(
191 DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
192 DenseMapInfo<uint64_t>::getTombstoneKey());
193 }
194
195 static unsigned getHashValue(const clang::CodeGen::BaseSubobject &Base) {
196 return
197 DenseMapInfo<const clang::CXXRecordDecl *>::getHashValue(Base.getBase()) ^
198 DenseMapInfo<uint64_t>::getHashValue(Base.getBaseOffset());
199 }
200
201 static bool isEqual(const clang::CodeGen::BaseSubobject &LHS,
202 const clang::CodeGen::BaseSubobject &RHS) {
203 return LHS == RHS;
204 }
205};
206
Anders Carlsson5f9a8812010-01-14 02:29:07 +0000207// It's OK to treat BaseSubobject as a POD type.
208template <> struct isPodLike<clang::CodeGen::BaseSubobject> {
209 static const bool value = true;
210};
211
Anders Carlsson2a4adbe2010-01-14 01:39:42 +0000212}
213
214namespace clang {
215namespace CodeGen {
216
Anders Carlssona864caf2010-03-23 04:11:45 +0000217class CodeGenVTables {
Eli Friedman31bc3ad2009-12-07 23:56:34 +0000218public:
219 typedef std::vector<std::pair<GlobalDecl, ThunkAdjustment> >
220 AdjustmentVectorTy;
221
Anders Carlsson93a18842010-01-02 18:02:32 +0000222 typedef std::pair<const CXXRecordDecl *, uint64_t> CtorVtable_t;
223 typedef llvm::DenseMap<CtorVtable_t, int64_t> AddrSubMap_t;
224 typedef llvm::DenseMap<const CXXRecordDecl *, AddrSubMap_t *> AddrMap_t;
Anders Carlsson93a18842010-01-02 18:02:32 +0000225
Anders Carlssonb35ea552010-03-24 03:57:14 +0000226 const CodeGenVTables::AddrSubMap_t& getAddressPoints(const CXXRecordDecl *RD);
227
Anders Carlssond03325c2010-03-25 00:51:13 +0000228 // FIXME: Remove this.
229 llvm::DenseMap<const CXXRecordDecl *, AddrMap_t*> OldAddressPoints;
Anders Carlssonb35ea552010-03-24 03:57:14 +0000230
Eli Friedman31bc3ad2009-12-07 23:56:34 +0000231private:
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000232 CodeGenModule &CGM;
Benjamin Kramer334af992009-11-26 13:09:03 +0000233
Anders Carlssonb35ea552010-03-24 03:57:14 +0000234
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000235 /// MethodVtableIndices - Contains the index (relative to the vtable address
236 /// point) where the function pointer for a virtual function is stored.
Anders Carlssonfb4dda42009-11-13 17:08:56 +0000237 typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVtableIndicesTy;
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000238 MethodVtableIndicesTy MethodVtableIndices;
Benjamin Kramer334af992009-11-26 13:09:03 +0000239
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000240 typedef std::pair<const CXXRecordDecl *,
241 const CXXRecordDecl *> ClassPairTy;
Benjamin Kramer334af992009-11-26 13:09:03 +0000242
Anders Carlsson4cbe83c2010-03-11 07:15:17 +0000243 /// VirtualBaseClassOffsetOffsets - Contains the vtable offset (relative to
244 /// the address point) in bytes where the offsets for virtual bases of a class
245 /// are stored.
246 typedef llvm::DenseMap<ClassPairTy, int64_t>
247 VirtualBaseClassOffsetOffsetsMapTy;
248 VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
Mike Stumpd846d082009-11-10 07:44:33 +0000249
Anders Carlsson7e28c5f2009-12-06 00:01:05 +0000250 /// Vtables - All the vtables which have been defined.
251 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> Vtables;
Anders Carlssonf942ee02009-11-27 20:47:55 +0000252
253 /// NumVirtualFunctionPointers - Contains the number of virtual function
254 /// pointers in the vtable for a given record decl.
255 llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers;
256
Anders Carlsson5c5abad2010-03-23 16:36:50 +0000257 typedef llvm::SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
258 typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
259
260 /// Thunks - Contains all thunks that a given method decl will need.
261 ThunksMapTy Thunks;
Anders Carlsson5c5abad2010-03-23 16:36:50 +0000262
Anders Carlssone90954d2010-03-24 16:42:11 +0000263 typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t *> VTableLayoutMapTy;
264
265 /// VTableLayoutMap - Stores the vtable layout for all record decls.
266 /// The layout is stored as an array of 64-bit integers, where the first
267 /// integer is the number of vtable entries in the layout, and the subsequent
268 /// integers are the vtable components.
269 VTableLayoutMapTy VTableLayoutMap;
270
Anders Carlsson0534b022010-03-25 00:35:49 +0000271 typedef llvm::DenseMap<std::pair<const CXXRecordDecl *,
272 BaseSubobject>, uint64_t> AddressPointsMapTy;
Anders Carlssond03325c2010-03-25 00:51:13 +0000273
Anders Carlssona208b392010-03-26 03:56:54 +0000274 /// Address points - Address points for all vtables.
Anders Carlssond03325c2010-03-25 00:51:13 +0000275 AddressPointsMapTy AddressPoints;
Anders Carlssona208b392010-03-26 03:56:54 +0000276
277 /// VTableAddressPointsMapTy - Address points for a single vtable.
278 typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy;
279
Anders Carlssona4147142010-03-25 15:26:28 +0000280 typedef llvm::SmallVector<std::pair<uint64_t, ThunkInfo>, 1>
281 VTableThunksTy;
282
283 typedef llvm::DenseMap<const CXXRecordDecl *, VTableThunksTy>
284 VTableThunksMapTy;
285
286 /// VTableThunksMap - Contains thunks needed by vtables.
287 VTableThunksMapTy VTableThunksMap;
288
Anders Carlssone90954d2010-03-24 16:42:11 +0000289 uint64_t getNumVTableComponents(const CXXRecordDecl *RD) const {
290 assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
291
292 return VTableLayoutMap.lookup(RD)[0];
293 }
294
Anders Carlssone36a6b32010-01-02 01:01:18 +0000295 typedef llvm::DenseMap<ClassPairTy, uint64_t> SubVTTIndiciesTy;
296 SubVTTIndiciesTy SubVTTIndicies;
297
Anders Carlssonf942ee02009-11-27 20:47:55 +0000298 /// getNumVirtualFunctionPointers - Return the number of virtual function
299 /// pointers in the vtable for a given record decl.
300 uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
301
302 void ComputeMethodVtableIndices(const CXXRecordDecl *RD);
Rafael Espindolae7113ca2010-03-10 02:19:29 +0000303
Anders Carlsson0911ae82009-12-06 00:23:49 +0000304 llvm::GlobalVariable *
Anders Carlsson0911ae82009-12-06 00:23:49 +0000305 GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
Anders Carlsson232324c2009-12-06 00:53:22 +0000306 bool GenerateDefinition, const CXXRecordDecl *LayoutClass,
Anders Carlsson62c6c722010-02-28 00:36:23 +0000307 const CXXRecordDecl *RD, uint64_t Offset, bool IsVirtual,
Anders Carlsson0534b022010-03-25 00:35:49 +0000308 llvm::DenseMap<BaseSubobject, uint64_t> &AddressPoints);
Anders Carlssonfe5f7d92009-12-06 01:09:21 +0000309
310 llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
Anders Carlssone36a6b32010-01-02 01:01:18 +0000311 bool GenerateDefinition,
Anders Carlssonfe5f7d92009-12-06 01:09:21 +0000312 const CXXRecordDecl *RD);
313
Anders Carlsson5c5abad2010-03-23 16:36:50 +0000314 /// EmitThunk - Emit a single thunk.
315 void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk);
316
Anders Carlsson917229c2010-03-23 04:59:02 +0000317 /// EmitThunks - Emit the associated thunks for the given global decl.
318 void EmitThunks(GlobalDecl GD);
319
Anders Carlssone90954d2010-03-24 16:42:11 +0000320 /// ComputeVTableRelatedInformation - Compute and store all vtable related
321 /// information (vtable layout, vbase offset offsets, thunks etc) for the
322 /// given record decl.
323 void ComputeVTableRelatedInformation(const CXXRecordDecl *RD);
324
Anders Carlssona4147142010-03-25 15:26:28 +0000325 /// CreateVTableInitializer - Create a vtable initializer for the given record
326 /// decl.
327 /// \param Components - The vtable components; this is really an array of
328 /// VTableComponents.
329 llvm::Constant *CreateVTableInitializer(const CXXRecordDecl *RD,
330 const uint64_t *Components,
331 unsigned NumComponents,
332 const VTableThunksTy &VTableThunks);
Anders Carlssona208b392010-03-26 03:56:54 +0000333
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000334public:
Anders Carlssona864caf2010-03-23 04:11:45 +0000335 CodeGenVTables(CodeGenModule &CGM)
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000336 : CGM(CGM) { }
337
Anders Carlssone36a6b32010-01-02 01:01:18 +0000338 /// needsVTTParameter - Return whether the given global decl needs a VTT
339 /// parameter, which it does if it's a base constructor or destructor with
340 /// virtual bases.
341 static bool needsVTTParameter(GlobalDecl GD);
342
343 /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
344 /// given record decl.
345 uint64_t getSubVTTIndex(const CXXRecordDecl *RD, const CXXRecordDecl *Base);
346
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000347 /// getMethodVtableIndex - Return the index (relative to the vtable address
Benjamin Kramer334af992009-11-26 13:09:03 +0000348 /// point) where the function pointer for the given virtual function is
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000349 /// stored.
Anders Carlssonf942ee02009-11-27 20:47:55 +0000350 uint64_t getMethodVtableIndex(GlobalDecl GD);
Benjamin Kramer334af992009-11-26 13:09:03 +0000351
Anders Carlsson4cbe83c2010-03-11 07:15:17 +0000352 /// getVirtualBaseOffsetOffset - Return the offset in bytes (relative to the
353 /// vtable address point) where the offset of the virtual base that contains
354 /// the given base is stored, otherwise, if no virtual base contains the given
Mike Stump28431212009-10-13 22:54:56 +0000355 /// class, return 0. Base must be a virtual base class or an unambigious
356 /// base.
Anders Carlsson4cbe83c2010-03-11 07:15:17 +0000357 int64_t getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
358 const CXXRecordDecl *VBase);
Mike Stumpd846d082009-11-10 07:44:33 +0000359
Anders Carlsson67fbf982010-03-24 05:32:05 +0000360 /// GetAddrOfVTable - Get the address of the vtable for the given record decl.
361 llvm::Constant *GetAddrOfVTable(const CXXRecordDecl *RD);
Anders Carlssonb35ea552010-03-24 03:57:14 +0000362
Anders Carlsson0534b022010-03-25 00:35:49 +0000363 /// GenerateConstructionVTable - Generate a construction vtable for the given
364 /// base subobject.
365 llvm::GlobalVariable *
366 GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base,
367 bool BaseIsVirtual,
Anders Carlssona208b392010-03-26 03:56:54 +0000368 VTableAddressPointsMapTy& AddressPoints);
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +0000369
Anders Carlssone36a6b32010-01-02 01:01:18 +0000370 llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
Anders Carlssonb1d3f7c2009-11-30 23:41:22 +0000371
Anders Carlsson88410242010-03-23 04:15:00 +0000372 // EmitVTableRelatedData - Will emit any thunks that the global decl might
373 // have, as well as the vtable itself if the global decl is the key function.
374 void EmitVTableRelatedData(GlobalDecl GD);
Rafael Espindolae7113ca2010-03-10 02:19:29 +0000375
Anders Carlsson55e89f82010-03-23 18:18:41 +0000376 /// GenerateClassData - Generate all the class data required to be generated
Rafael Espindolae7113ca2010-03-10 02:19:29 +0000377 /// upon definition of a KeyFunction. This includes the vtable, the
378 /// rtti data structure and the VTT.
379 ///
380 /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
381 void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
382 const CXXRecordDecl *RD);
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000383};
Benjamin Kramer334af992009-11-26 13:09:03 +0000384
Anders Carlsson5f9a8812010-01-14 02:29:07 +0000385} // end namespace CodeGen
386} // end namespace clang
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000387#endif