blob: 3cfdb181f969f7c5bca5285d89709738960f4b17 [file] [log] [blame]
Anders Carlsson461e3262010-04-08 16:30:25 +00001//===--- CGVTables.h - Emit LLVM Code for C++ vtables ---------------------===//
Anders Carlssondbd920c2009-10-11 22:13:54 +00002//
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"
Anders Carlsson35272252009-12-06 00:23:49 +000018#include "llvm/GlobalVariable.h"
Anders Carlssona0fdd912009-11-13 17:08:56 +000019#include "GlobalDecl.h"
Anders Carlssondbd920c2009-10-11 22:13:54 +000020
21namespace clang {
Anders Carlssondbd920c2009-10-11 22:13:54 +000022 class CXXRecordDecl;
Benjamin Kramer39411b92009-11-26 13:09:03 +000023
Anders Carlssondbd920c2009-10-11 22:13:54 +000024namespace CodeGen {
25 class CodeGenModule;
Anders Carlssona94822e2009-11-26 02:32:05 +000026
Anders Carlsson80d8d7d2010-03-23 15:13:06 +000027/// ReturnAdjustment - A return adjustment.
28struct ReturnAdjustment {
29 /// NonVirtual - The non-virtual adjustment from the derived object to its
30 /// nearest virtual base.
31 int64_t NonVirtual;
32
33 /// VBaseOffsetOffset - The offset (in bytes), relative to the address point
34 /// of the virtual base class offset.
35 int64_t VBaseOffsetOffset;
36
37 ReturnAdjustment() : NonVirtual(0), VBaseOffsetOffset(0) { }
38
39 bool isEmpty() const { return !NonVirtual && !VBaseOffsetOffset; }
40
41 friend bool operator==(const ReturnAdjustment &LHS,
42 const ReturnAdjustment &RHS) {
43 return LHS.NonVirtual == RHS.NonVirtual &&
44 LHS.VBaseOffsetOffset == RHS.VBaseOffsetOffset;
45 }
46
47 friend bool operator<(const ReturnAdjustment &LHS,
48 const ReturnAdjustment &RHS) {
49 if (LHS.NonVirtual < RHS.NonVirtual)
50 return true;
51
52 return LHS.NonVirtual == RHS.NonVirtual &&
53 LHS.VBaseOffsetOffset < RHS.VBaseOffsetOffset;
54 }
55};
56
57/// ThisAdjustment - A 'this' pointer adjustment.
58struct ThisAdjustment {
59 /// NonVirtual - The non-virtual adjustment from the derived object to its
60 /// nearest virtual base.
61 int64_t NonVirtual;
62
63 /// VCallOffsetOffset - The offset (in bytes), relative to the address point,
64 /// of the virtual call offset.
65 int64_t VCallOffsetOffset;
66
67 ThisAdjustment() : NonVirtual(0), VCallOffsetOffset(0) { }
68
69 bool isEmpty() const { return !NonVirtual && !VCallOffsetOffset; }
70
71 friend bool operator==(const ThisAdjustment &LHS,
72 const ThisAdjustment &RHS) {
73 return LHS.NonVirtual == RHS.NonVirtual &&
74 LHS.VCallOffsetOffset == RHS.VCallOffsetOffset;
75 }
76
77 friend bool operator<(const ThisAdjustment &LHS,
78 const ThisAdjustment &RHS) {
79 if (LHS.NonVirtual < RHS.NonVirtual)
80 return true;
81
82 return LHS.NonVirtual == RHS.NonVirtual &&
83 LHS.VCallOffsetOffset < RHS.VCallOffsetOffset;
84 }
Anders Carlsson80d8d7d2010-03-23 15:13:06 +000085};
86
Anders Carlssonb4e4c962010-03-23 15:17:13 +000087/// ThunkInfo - The 'this' pointer adjustment as well as an optional return
88/// adjustment for a thunk.
89struct ThunkInfo {
90 /// This - The 'this' pointer adjustment.
91 ThisAdjustment This;
92
93 /// Return - The return adjustment.
94 ReturnAdjustment Return;
95
96 ThunkInfo() { }
97
98 ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return)
99 : This(This), Return(Return) { }
100
101 friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
102 return LHS.This == RHS.This && LHS.Return == RHS.Return;
103 }
104
105 friend bool operator<(const ThunkInfo &LHS, const ThunkInfo &RHS) {
106 if (LHS.This < RHS.This)
107 return true;
108
109 return LHS.This == RHS.This && LHS.Return < RHS.Return;
110 }
111
112 bool isEmpty() const { return This.isEmpty() && Return.isEmpty(); }
113};
114
Anders Carlsson6b4333d2010-01-13 20:11:15 +0000115// BaseSubobject - Uniquely identifies a direct or indirect base class.
116// Stores both the base class decl and the offset from the most derived class to
117// the base class.
118class BaseSubobject {
119 /// Base - The base class declaration.
120 const CXXRecordDecl *Base;
121
122 /// BaseOffset - The offset from the most derived class to the base class.
123 uint64_t BaseOffset;
124
125public:
126 BaseSubobject(const CXXRecordDecl *Base, uint64_t BaseOffset)
127 : Base(Base), BaseOffset(BaseOffset) { }
128
129 /// getBase - Returns the base class declaration.
130 const CXXRecordDecl *getBase() const { return Base; }
131
132 /// getBaseOffset - Returns the base class offset.
133 uint64_t getBaseOffset() const { return BaseOffset; }
Anders Carlsson7e37a692010-01-14 01:39:42 +0000134
Anders Carlsson6b4333d2010-01-13 20:11:15 +0000135 friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
136 return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
137 }
138};
Anders Carlsson7e37a692010-01-14 01:39:42 +0000139
140} // end namespace CodeGen
141} // end namespace clang
142
143namespace llvm {
144
145template<> struct DenseMapInfo<clang::CodeGen::BaseSubobject> {
146 static clang::CodeGen::BaseSubobject getEmptyKey() {
147 return clang::CodeGen::BaseSubobject(
148 DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
149 DenseMapInfo<uint64_t>::getEmptyKey());
150 }
151
152 static clang::CodeGen::BaseSubobject getTombstoneKey() {
153 return clang::CodeGen::BaseSubobject(
154 DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
155 DenseMapInfo<uint64_t>::getTombstoneKey());
156 }
157
158 static unsigned getHashValue(const clang::CodeGen::BaseSubobject &Base) {
159 return
160 DenseMapInfo<const clang::CXXRecordDecl *>::getHashValue(Base.getBase()) ^
161 DenseMapInfo<uint64_t>::getHashValue(Base.getBaseOffset());
162 }
163
164 static bool isEqual(const clang::CodeGen::BaseSubobject &LHS,
165 const clang::CodeGen::BaseSubobject &RHS) {
166 return LHS == RHS;
167 }
168};
169
Anders Carlsson1bb60992010-01-14 02:29:07 +0000170// It's OK to treat BaseSubobject as a POD type.
171template <> struct isPodLike<clang::CodeGen::BaseSubobject> {
172 static const bool value = true;
173};
174
Anders Carlsson7e37a692010-01-14 01:39:42 +0000175}
176
177namespace clang {
178namespace CodeGen {
179
Anders Carlssonaf440352010-03-23 04:11:45 +0000180class CodeGenVTables {
Anders Carlssondbd920c2009-10-11 22:13:54 +0000181 CodeGenModule &CGM;
Benjamin Kramer39411b92009-11-26 13:09:03 +0000182
Anders Carlsson046c2942010-04-17 20:15:18 +0000183 /// MethodVTableIndices - Contains the index (relative to the vtable address
Anders Carlssondbd920c2009-10-11 22:13:54 +0000184 /// point) where the function pointer for a virtual function is stored.
Anders Carlsson046c2942010-04-17 20:15:18 +0000185 typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
186 MethodVTableIndicesTy MethodVTableIndices;
Benjamin Kramer39411b92009-11-26 13:09:03 +0000187
Anders Carlssondbd920c2009-10-11 22:13:54 +0000188 typedef std::pair<const CXXRecordDecl *,
189 const CXXRecordDecl *> ClassPairTy;
Benjamin Kramer39411b92009-11-26 13:09:03 +0000190
Anders Carlssonbba16072010-03-11 07:15:17 +0000191 /// VirtualBaseClassOffsetOffsets - Contains the vtable offset (relative to
192 /// the address point) in bytes where the offsets for virtual bases of a class
193 /// are stored.
194 typedef llvm::DenseMap<ClassPairTy, int64_t>
195 VirtualBaseClassOffsetOffsetsMapTy;
196 VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
Mike Stump380dd752009-11-10 07:44:33 +0000197
Anders Carlsson046c2942010-04-17 20:15:18 +0000198 /// VTables - All the vtables which have been defined.
199 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
Anders Carlssond6b07fb2009-11-27 20:47:55 +0000200
201 /// NumVirtualFunctionPointers - Contains the number of virtual function
202 /// pointers in the vtable for a given record decl.
203 llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers;
204
Anders Carlssonfbf6ed42010-03-23 16:36:50 +0000205 typedef llvm::SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
206 typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
207
208 /// Thunks - Contains all thunks that a given method decl will need.
209 ThunksMapTy Thunks;
Anders Carlssonfbf6ed42010-03-23 16:36:50 +0000210
Anders Carlssonccd83d72010-03-24 16:42:11 +0000211 typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t *> VTableLayoutMapTy;
212
213 /// VTableLayoutMap - Stores the vtable layout for all record decls.
214 /// The layout is stored as an array of 64-bit integers, where the first
215 /// integer is the number of vtable entries in the layout, and the subsequent
216 /// integers are the vtable components.
217 VTableLayoutMapTy VTableLayoutMap;
218
Anders Carlssonff143f82010-03-25 00:35:49 +0000219 typedef llvm::DenseMap<std::pair<const CXXRecordDecl *,
220 BaseSubobject>, uint64_t> AddressPointsMapTy;
Anders Carlsson66d567d2010-03-25 00:51:13 +0000221
Anders Carlsson2c822f12010-03-26 03:56:54 +0000222 /// Address points - Address points for all vtables.
Anders Carlsson66d567d2010-03-25 00:51:13 +0000223 AddressPointsMapTy AddressPoints;
Anders Carlsson2c822f12010-03-26 03:56:54 +0000224
225 /// VTableAddressPointsMapTy - Address points for a single vtable.
226 typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy;
227
Anders Carlsson0d1407e2010-03-25 15:26:28 +0000228 typedef llvm::SmallVector<std::pair<uint64_t, ThunkInfo>, 1>
229 VTableThunksTy;
230
231 typedef llvm::DenseMap<const CXXRecordDecl *, VTableThunksTy>
232 VTableThunksMapTy;
233
234 /// VTableThunksMap - Contains thunks needed by vtables.
235 VTableThunksMapTy VTableThunksMap;
236
Anders Carlssonccd83d72010-03-24 16:42:11 +0000237 uint64_t getNumVTableComponents(const CXXRecordDecl *RD) const {
238 assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
239
240 return VTableLayoutMap.lookup(RD)[0];
241 }
242
Anders Carlssona7cde3b2010-03-29 03:38:52 +0000243 const uint64_t *getVTableComponentsData(const CXXRecordDecl *RD) const {
244 assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
245
246 uint64_t *Components = VTableLayoutMap.lookup(RD);
247 return &Components[1];
248 }
249
Anders Carlssone1dcc222010-03-26 04:23:58 +0000250 typedef llvm::DenseMap<ClassPairTy, uint64_t> SubVTTIndiciesMapTy;
251
252 /// SubVTTIndicies - Contains indices into the various sub-VTTs.
253 SubVTTIndiciesMapTy SubVTTIndicies;
254
255
256 typedef llvm::DenseMap<std::pair<const CXXRecordDecl *,
257 BaseSubobject>, uint64_t>
258 SecondaryVirtualPointerIndicesMapTy;
259
260 /// SecondaryVirtualPointerIndices - Contains the secondary virtual pointer
261 /// indices.
262 SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices;
Anders Carlssonc997d422010-01-02 01:01:18 +0000263
Anders Carlssond6b07fb2009-11-27 20:47:55 +0000264 /// getNumVirtualFunctionPointers - Return the number of virtual function
265 /// pointers in the vtable for a given record decl.
266 uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
267
Anders Carlsson046c2942010-04-17 20:15:18 +0000268 void ComputeMethodVTableIndices(const CXXRecordDecl *RD);
Anders Carlssonc3a46ef2009-12-06 01:09:21 +0000269
270 llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
Anders Carlssonc997d422010-01-02 01:01:18 +0000271 bool GenerateDefinition,
Anders Carlssonc3a46ef2009-12-06 01:09:21 +0000272 const CXXRecordDecl *RD);
273
Anders Carlssonfbf6ed42010-03-23 16:36:50 +0000274 /// EmitThunk - Emit a single thunk.
275 void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk);
276
Anders Carlssonee5ab9f2010-03-23 04:59:02 +0000277 /// EmitThunks - Emit the associated thunks for the given global decl.
278 void EmitThunks(GlobalDecl GD);
279
Anders Carlssonccd83d72010-03-24 16:42:11 +0000280 /// ComputeVTableRelatedInformation - Compute and store all vtable related
281 /// information (vtable layout, vbase offset offsets, thunks etc) for the
282 /// given record decl.
283 void ComputeVTableRelatedInformation(const CXXRecordDecl *RD);
284
Anders Carlsson0d1407e2010-03-25 15:26:28 +0000285 /// CreateVTableInitializer - Create a vtable initializer for the given record
286 /// decl.
287 /// \param Components - The vtable components; this is really an array of
288 /// VTableComponents.
289 llvm::Constant *CreateVTableInitializer(const CXXRecordDecl *RD,
290 const uint64_t *Components,
291 unsigned NumComponents,
292 const VTableThunksTy &VTableThunks);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000293
Anders Carlssondbd920c2009-10-11 22:13:54 +0000294public:
Anders Carlssonaf440352010-03-23 04:11:45 +0000295 CodeGenVTables(CodeGenModule &CGM)
Anders Carlssondbd920c2009-10-11 22:13:54 +0000296 : CGM(CGM) { }
297
Rafael Espindolab8cab182010-04-19 00:44:22 +0000298 // isKeyFunctionInAnotherTU - True if this record has a key function and it is
299 // in another translation unit.
300 static bool isKeyFunctionInAnotherTU(ASTContext &Context,
301 const CXXRecordDecl *RD) {
302 assert (RD->isDynamicClass() && "Non dynamic classes have no key.");
303 const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD);
304 return KeyFunction && !KeyFunction->getBody();
305 }
306
Anders Carlssonc997d422010-01-02 01:01:18 +0000307 /// needsVTTParameter - Return whether the given global decl needs a VTT
308 /// parameter, which it does if it's a base constructor or destructor with
309 /// virtual bases.
310 static bool needsVTTParameter(GlobalDecl GD);
311
312 /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
313 /// given record decl.
Anders Carlssonc11bb212010-05-02 23:53:25 +0000314 uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base);
Anders Carlssonc997d422010-01-02 01:01:18 +0000315
Anders Carlssone1dcc222010-03-26 04:23:58 +0000316 /// getSecondaryVirtualPointerIndex - Return the index in the VTT where the
317 /// virtual pointer for the given subobject is located.
318 uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
319 BaseSubobject Base);
320
Anders Carlsson046c2942010-04-17 20:15:18 +0000321 /// getMethodVTableIndex - Return the index (relative to the vtable address
Benjamin Kramer39411b92009-11-26 13:09:03 +0000322 /// point) where the function pointer for the given virtual function is
Anders Carlssondbd920c2009-10-11 22:13:54 +0000323 /// stored.
Anders Carlsson046c2942010-04-17 20:15:18 +0000324 uint64_t getMethodVTableIndex(GlobalDecl GD);
Benjamin Kramer39411b92009-11-26 13:09:03 +0000325
Anders Carlssonbba16072010-03-11 07:15:17 +0000326 /// getVirtualBaseOffsetOffset - Return the offset in bytes (relative to the
327 /// vtable address point) where the offset of the virtual base that contains
328 /// the given base is stored, otherwise, if no virtual base contains the given
Mike Stumpab28c132009-10-13 22:54:56 +0000329 /// class, return 0. Base must be a virtual base class or an unambigious
330 /// base.
Anders Carlssonbba16072010-03-11 07:15:17 +0000331 int64_t getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
332 const CXXRecordDecl *VBase);
Mike Stump380dd752009-11-10 07:44:33 +0000333
Anders Carlsson64c9eca2010-03-29 02:08:26 +0000334 /// getAddressPoint - Get the address point of the given subobject in the
335 /// class decl.
336 uint64_t getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD);
337
Anders Carlsson5eea8762010-03-24 05:32:05 +0000338 /// GetAddrOfVTable - Get the address of the vtable for the given record decl.
Anders Carlsson9dc338a2010-03-30 03:35:35 +0000339 llvm::GlobalVariable *GetAddrOfVTable(const CXXRecordDecl *RD);
Anders Carlsson5c6c1d92010-03-24 03:57:14 +0000340
Anders Carlssona7cde3b2010-03-29 03:38:52 +0000341 /// EmitVTableDefinition - Emit the definition of the given vtable.
342 void EmitVTableDefinition(llvm::GlobalVariable *VTable,
343 llvm::GlobalVariable::LinkageTypes Linkage,
344 const CXXRecordDecl *RD);
345
Anders Carlssonff143f82010-03-25 00:35:49 +0000346 /// GenerateConstructionVTable - Generate a construction vtable for the given
347 /// base subobject.
348 llvm::GlobalVariable *
349 GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base,
350 bool BaseIsVirtual,
Anders Carlsson2c822f12010-03-26 03:56:54 +0000351 VTableAddressPointsMapTy& AddressPoints);
Anders Carlsson1a5e0d72009-11-30 23:41:22 +0000352
Anders Carlssonc997d422010-01-02 01:01:18 +0000353 llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
Anders Carlsson1a5e0d72009-11-30 23:41:22 +0000354
Anders Carlsson13189d02010-03-23 04:15:00 +0000355 // EmitVTableRelatedData - Will emit any thunks that the global decl might
356 // have, as well as the vtable itself if the global decl is the key function.
357 void EmitVTableRelatedData(GlobalDecl GD);
Rafael Espindolabbf58bb2010-03-10 02:19:29 +0000358
Anders Carlsson7986ad52010-03-23 18:18:41 +0000359 /// GenerateClassData - Generate all the class data required to be generated
Rafael Espindolabbf58bb2010-03-10 02:19:29 +0000360 /// upon definition of a KeyFunction. This includes the vtable, the
361 /// rtti data structure and the VTT.
362 ///
363 /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
364 void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
365 const CXXRecordDecl *RD);
Anders Carlssondbd920c2009-10-11 22:13:54 +0000366};
Benjamin Kramer39411b92009-11-26 13:09:03 +0000367
Anders Carlsson1bb60992010-01-14 02:29:07 +0000368} // end namespace CodeGen
369} // end namespace clang
Anders Carlssondbd920c2009-10-11 22:13:54 +0000370#endif