blob: 1d2e8c1e0447187fb4afb3a45df853092333e5a8 [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;
John McCalle2132352010-06-02 21:22:02 +0000210
211 // The layout entry and a bool indicating whether we've actually emitted
212 // the vtable.
213 typedef llvm::PointerIntPair<uint64_t *, 1, bool> VTableLayoutData;
214 typedef llvm::DenseMap<const CXXRecordDecl *, VTableLayoutData>
215 VTableLayoutMapTy;
Anders Carlssonccd83d72010-03-24 16:42:11 +0000216
217 /// VTableLayoutMap - Stores the vtable layout for all record decls.
218 /// The layout is stored as an array of 64-bit integers, where the first
219 /// integer is the number of vtable entries in the layout, and the subsequent
220 /// integers are the vtable components.
221 VTableLayoutMapTy VTableLayoutMap;
222
Anders Carlsson3855a072010-05-03 00:55:11 +0000223 typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy;
224 typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> AddressPointsMapTy;
Anders Carlsson66d567d2010-03-25 00:51:13 +0000225
Anders Carlsson2c822f12010-03-26 03:56:54 +0000226 /// Address points - Address points for all vtables.
Anders Carlsson66d567d2010-03-25 00:51:13 +0000227 AddressPointsMapTy AddressPoints;
Anders Carlsson2c822f12010-03-26 03:56:54 +0000228
229 /// VTableAddressPointsMapTy - Address points for a single vtable.
230 typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy;
231
Anders Carlsson0d1407e2010-03-25 15:26:28 +0000232 typedef llvm::SmallVector<std::pair<uint64_t, ThunkInfo>, 1>
233 VTableThunksTy;
234
235 typedef llvm::DenseMap<const CXXRecordDecl *, VTableThunksTy>
236 VTableThunksMapTy;
237
238 /// VTableThunksMap - Contains thunks needed by vtables.
239 VTableThunksMapTy VTableThunksMap;
240
Anders Carlssonccd83d72010-03-24 16:42:11 +0000241 uint64_t getNumVTableComponents(const CXXRecordDecl *RD) const {
242 assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
243
John McCalle2132352010-06-02 21:22:02 +0000244 return VTableLayoutMap.lookup(RD).getPointer()[0];
Anders Carlssonccd83d72010-03-24 16:42:11 +0000245 }
246
Anders Carlssona7cde3b2010-03-29 03:38:52 +0000247 const uint64_t *getVTableComponentsData(const CXXRecordDecl *RD) const {
248 assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
249
John McCalle2132352010-06-02 21:22:02 +0000250 uint64_t *Components = VTableLayoutMap.lookup(RD).getPointer();
Anders Carlssona7cde3b2010-03-29 03:38:52 +0000251 return &Components[1];
252 }
253
Anders Carlsson3855a072010-05-03 00:55:11 +0000254 typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> SubVTTIndiciesMapTy;
Anders Carlssone1dcc222010-03-26 04:23:58 +0000255
256 /// SubVTTIndicies - Contains indices into the various sub-VTTs.
257 SubVTTIndiciesMapTy SubVTTIndicies;
258
Anders Carlsson3855a072010-05-03 00:55:11 +0000259 typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t>
Anders Carlssone1dcc222010-03-26 04:23:58 +0000260 SecondaryVirtualPointerIndicesMapTy;
261
262 /// SecondaryVirtualPointerIndices - Contains the secondary virtual pointer
263 /// indices.
264 SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices;
Anders Carlssonc997d422010-01-02 01:01:18 +0000265
Anders Carlssond6b07fb2009-11-27 20:47:55 +0000266 /// getNumVirtualFunctionPointers - Return the number of virtual function
267 /// pointers in the vtable for a given record decl.
268 uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
269
Anders Carlsson046c2942010-04-17 20:15:18 +0000270 void ComputeMethodVTableIndices(const CXXRecordDecl *RD);
Anders Carlssonc3a46ef2009-12-06 01:09:21 +0000271
272 llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
Anders Carlssonc997d422010-01-02 01:01:18 +0000273 bool GenerateDefinition,
Anders Carlssonc3a46ef2009-12-06 01:09:21 +0000274 const CXXRecordDecl *RD);
275
Anders Carlssonfbf6ed42010-03-23 16:36:50 +0000276 /// EmitThunk - Emit a single thunk.
277 void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk);
278
Anders Carlssonccd83d72010-03-24 16:42:11 +0000279 /// ComputeVTableRelatedInformation - Compute and store all vtable related
280 /// information (vtable layout, vbase offset offsets, thunks etc) for the
281 /// given record decl.
John McCalle2132352010-06-02 21:22:02 +0000282 void ComputeVTableRelatedInformation(const CXXRecordDecl *RD,
283 bool VTableRequired);
Anders Carlssonccd83d72010-03-24 16:42:11 +0000284
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
Argyrios Kyrtzidisd2c47bd2010-10-11 03:25:57 +0000298 /// \brief True if the VTable of this record must be emitted in the
299 /// translation unit.
300 bool ShouldEmitVTableInThisTU(const CXXRecordDecl *RD);
Rafael Espindolab8cab182010-04-19 00:44:22 +0000301
Anders Carlssonc997d422010-01-02 01:01:18 +0000302 /// needsVTTParameter - Return whether the given global decl needs a VTT
303 /// parameter, which it does if it's a base constructor or destructor with
304 /// virtual bases.
305 static bool needsVTTParameter(GlobalDecl GD);
306
307 /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
308 /// given record decl.
Anders Carlssonc11bb212010-05-02 23:53:25 +0000309 uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base);
Anders Carlssonc997d422010-01-02 01:01:18 +0000310
Anders Carlssone1dcc222010-03-26 04:23:58 +0000311 /// getSecondaryVirtualPointerIndex - Return the index in the VTT where the
312 /// virtual pointer for the given subobject is located.
313 uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
314 BaseSubobject Base);
315
Anders Carlsson046c2942010-04-17 20:15:18 +0000316 /// getMethodVTableIndex - Return the index (relative to the vtable address
Benjamin Kramer39411b92009-11-26 13:09:03 +0000317 /// point) where the function pointer for the given virtual function is
Anders Carlssondbd920c2009-10-11 22:13:54 +0000318 /// stored.
Anders Carlsson046c2942010-04-17 20:15:18 +0000319 uint64_t getMethodVTableIndex(GlobalDecl GD);
Benjamin Kramer39411b92009-11-26 13:09:03 +0000320
Anders Carlssonbba16072010-03-11 07:15:17 +0000321 /// getVirtualBaseOffsetOffset - Return the offset in bytes (relative to the
322 /// vtable address point) where the offset of the virtual base that contains
323 /// the given base is stored, otherwise, if no virtual base contains the given
Mike Stumpab28c132009-10-13 22:54:56 +0000324 /// class, return 0. Base must be a virtual base class or an unambigious
325 /// base.
Anders Carlssonbba16072010-03-11 07:15:17 +0000326 int64_t getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
327 const CXXRecordDecl *VBase);
Mike Stump380dd752009-11-10 07:44:33 +0000328
Anders Carlsson64c9eca2010-03-29 02:08:26 +0000329 /// getAddressPoint - Get the address point of the given subobject in the
330 /// class decl.
331 uint64_t getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD);
332
Anders Carlsson5eea8762010-03-24 05:32:05 +0000333 /// GetAddrOfVTable - Get the address of the vtable for the given record decl.
Anders Carlsson9dc338a2010-03-30 03:35:35 +0000334 llvm::GlobalVariable *GetAddrOfVTable(const CXXRecordDecl *RD);
Anders Carlsson5c6c1d92010-03-24 03:57:14 +0000335
Anders Carlssona7cde3b2010-03-29 03:38:52 +0000336 /// EmitVTableDefinition - Emit the definition of the given vtable.
337 void EmitVTableDefinition(llvm::GlobalVariable *VTable,
338 llvm::GlobalVariable::LinkageTypes Linkage,
339 const CXXRecordDecl *RD);
340
Anders Carlssonff143f82010-03-25 00:35:49 +0000341 /// GenerateConstructionVTable - Generate a construction vtable for the given
342 /// base subobject.
343 llvm::GlobalVariable *
344 GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base,
345 bool BaseIsVirtual,
Anders Carlsson2c822f12010-03-26 03:56:54 +0000346 VTableAddressPointsMapTy& AddressPoints);
Anders Carlsson1a5e0d72009-11-30 23:41:22 +0000347
Anders Carlssonc997d422010-01-02 01:01:18 +0000348 llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
Rafael Espindolabbf58bb2010-03-10 02:19:29 +0000349
Douglas Gregor6fb745b2010-05-13 16:44:06 +0000350 /// EmitThunks - Emit the associated thunks for the given global decl.
351 void EmitThunks(GlobalDecl GD);
352
Anders Carlsson7986ad52010-03-23 18:18:41 +0000353 /// GenerateClassData - Generate all the class data required to be generated
Rafael Espindolabbf58bb2010-03-10 02:19:29 +0000354 /// upon definition of a KeyFunction. This includes the vtable, the
355 /// rtti data structure and the VTT.
356 ///
357 /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
358 void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
359 const CXXRecordDecl *RD);
Anders Carlssondbd920c2009-10-11 22:13:54 +0000360};
Benjamin Kramer39411b92009-11-26 13:09:03 +0000361
Anders Carlsson1bb60992010-01-14 02:29:07 +0000362} // end namespace CodeGen
363} // end namespace clang
Anders Carlssondbd920c2009-10-11 22:13:54 +0000364#endif