blob: 6177dfed155ffb54f7e75dec82218f40eafa86dd [file] [log] [blame]
John McCall358d0562011-03-27 09:00:25 +00001//===--- CGVTables.h - Emit LLVM Code for C++ vtables -----------*- C++ -*-===//
Anders Carlsson2bb27f52009-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 Carlsson0911ae82009-12-06 00:23:49 +000018#include "llvm/GlobalVariable.h"
Peter Collingbourne0ff0b372011-01-13 18:57:25 +000019#include "clang/Basic/ABI.h"
Peter Collingbourne66c3a832011-09-26 01:56:16 +000020#include "clang/AST/BaseSubobject.h"
Ken Dyck16ffcac2011-03-24 01:21:01 +000021#include "clang/AST/CharUnits.h"
Peter Collingbourneee781d52011-06-14 04:02:39 +000022#include "clang/AST/GlobalDecl.h"
Anders Carlsson2bb27f52009-10-11 22:13:54 +000023
24namespace clang {
Anders Carlsson2bb27f52009-10-11 22:13:54 +000025 class CXXRecordDecl;
Benjamin Kramer334af992009-11-26 13:09:03 +000026
Anders Carlsson2bb27f52009-10-11 22:13:54 +000027namespace CodeGen {
28 class CodeGenModule;
Anders Carlssonc7785402009-11-26 02:32:05 +000029
Peter Collingbournea8341662011-09-26 01:56:30 +000030class VTableContext {
31 ASTContext &Context;
Benjamin Kramer334af992009-11-26 13:09:03 +000032
Peter Collingbourne5ee9ee42011-09-26 01:56:41 +000033public:
34 typedef SmallVector<std::pair<uint64_t, ThunkInfo>, 1>
35 VTableThunksTy;
36 typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
37
38private:
Anders Carlsson11e51402010-04-17 20:15:18 +000039 /// MethodVTableIndices - Contains the index (relative to the vtable address
Anders Carlsson2bb27f52009-10-11 22:13:54 +000040 /// point) where the function pointer for a virtual function is stored.
Anders Carlsson11e51402010-04-17 20:15:18 +000041 typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
42 MethodVTableIndicesTy MethodVTableIndices;
Benjamin Kramer334af992009-11-26 13:09:03 +000043
Peter Collingbournea8341662011-09-26 01:56:30 +000044 /// NumVirtualFunctionPointers - Contains the number of virtual function
45 /// pointers in the vtable for a given record decl.
46 llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers;
47
Anders Carlsson2bb27f52009-10-11 22:13:54 +000048 typedef std::pair<const CXXRecordDecl *,
49 const CXXRecordDecl *> ClassPairTy;
Benjamin Kramer334af992009-11-26 13:09:03 +000050
Anders Carlsson4cbe83c2010-03-11 07:15:17 +000051 /// VirtualBaseClassOffsetOffsets - Contains the vtable offset (relative to
Ken Dyck3a09bc52011-04-07 01:22:42 +000052 /// the address point) in chars where the offsets for virtual bases of a class
Anders Carlsson4cbe83c2010-03-11 07:15:17 +000053 /// are stored.
Ken Dyck3a09bc52011-04-07 01:22:42 +000054 typedef llvm::DenseMap<ClassPairTy, CharUnits>
Anders Carlsson4cbe83c2010-03-11 07:15:17 +000055 VirtualBaseClassOffsetOffsetsMapTy;
56 VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
Mike Stumpd846d082009-11-10 07:44:33 +000057
Peter Collingbourne5ee9ee42011-09-26 01:56:41 +000058 // The layout entry.
59 typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t *> VTableLayoutMapTy;
60
61 /// VTableLayoutMap - Stores the vtable layout for all record decls.
62 /// The layout is stored as an array of 64-bit integers, where the first
63 /// integer is the number of vtable entries in the layout, and the subsequent
64 /// integers are the vtable components.
65 VTableLayoutMapTy VTableLayoutMap;
66
67 typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
68
69 /// Thunks - Contains all thunks that a given method decl will need.
70 ThunksMapTy Thunks;
71
72 typedef llvm::DenseMap<const CXXRecordDecl *, VTableThunksTy>
73 VTableThunksMapTy;
74
75 /// VTableThunksMap - Contains thunks needed by vtables.
76 VTableThunksMapTy VTableThunksMap;
77
78 typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy;
79 typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> AddressPointsMapTy;
80
81 /// Address points - Address points for all vtables.
82 AddressPointsMapTy AddressPoints;
83
Peter Collingbournea8341662011-09-26 01:56:30 +000084 void ComputeMethodVTableIndices(const CXXRecordDecl *RD);
85
Peter Collingbourne5ee9ee42011-09-26 01:56:41 +000086 /// ComputeVTableRelatedInformation - Compute and store all vtable related
87 /// information (vtable layout, vbase offset offsets, thunks etc) for the
88 /// given record decl.
89 void ComputeVTableRelatedInformation(const CXXRecordDecl *RD);
90
Peter Collingbournea8341662011-09-26 01:56:30 +000091public:
92 VTableContext(ASTContext &Context) : Context(Context) {}
93
Peter Collingbourne5ee9ee42011-09-26 01:56:41 +000094 uint64_t getNumVTableComponents(const CXXRecordDecl *RD) {
95 ComputeVTableRelatedInformation(RD);
96 assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
97
98 return VTableLayoutMap.lookup(RD)[0];
99 }
100
101 const uint64_t *getVTableComponentsData(const CXXRecordDecl *RD) {
102 ComputeVTableRelatedInformation(RD);
103 assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
104
105 uint64_t *Components = VTableLayoutMap.lookup(RD);
106 return &Components[1];
107 }
108
109 const ThunkInfoVectorTy *getThunkInfo(const CXXMethodDecl *MD) {
110 ComputeVTableRelatedInformation(MD->getParent());
111
112 ThunksMapTy::const_iterator I = Thunks.find(MD);
113 if (I == Thunks.end()) {
114 // We did not find a thunk for this method.
115 return 0;
116 }
117
118 return &I->second;
119 }
120
121 const VTableThunksTy &getVTableThunks(const CXXRecordDecl *RD) {
122 ComputeVTableRelatedInformation(RD);
123 assert(VTableThunksMap.count(RD) &&
124 "No thunk status for this record decl!");
125
126 return VTableThunksMap[RD];
127 }
128
129 uint64_t getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD) {
130 ComputeVTableRelatedInformation(RD);
131 assert(AddressPoints.count(std::make_pair(RD, Base)) &&
132 "Did not find address point!");
133
134 uint64_t AddressPoint = AddressPoints.lookup(std::make_pair(RD, Base));
135 assert(AddressPoint && "Address point must not be zero!");
136
137 return AddressPoint;
138 }
139
Peter Collingbournea8341662011-09-26 01:56:30 +0000140 /// getNumVirtualFunctionPointers - Return the number of virtual function
141 /// pointers in the vtable for a given record decl.
142 uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
143
144 /// getMethodVTableIndex - Return the index (relative to the vtable address
145 /// point) where the function pointer for the given virtual function is
146 /// stored.
147 uint64_t getMethodVTableIndex(GlobalDecl GD);
148
149 /// getVirtualBaseOffsetOffset - Return the offset in chars (relative to the
150 /// vtable address point) where the offset of the virtual base that contains
151 /// the given base is stored, otherwise, if no virtual base contains the given
152 /// class, return 0. Base must be a virtual base class or an unambigious
153 /// base.
154 CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
155 const CXXRecordDecl *VBase);
Peter Collingbournea8341662011-09-26 01:56:30 +0000156};
157
158class CodeGenVTables {
159 CodeGenModule &CGM;
160
161 VTableContext VTContext;
162
Anders Carlsson11e51402010-04-17 20:15:18 +0000163 /// VTables - All the vtables which have been defined.
164 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
Anders Carlssonf942ee02009-11-27 20:47:55 +0000165
Anders Carlssona208b392010-03-26 03:56:54 +0000166 /// VTableAddressPointsMapTy - Address points for a single vtable.
167 typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy;
168
Peter Collingbourne5ee9ee42011-09-26 01:56:41 +0000169 typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy;
Anders Carlsson8bdbb5b2010-05-03 00:55:11 +0000170 typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> SubVTTIndiciesMapTy;
Anders Carlssonf1a994c2010-03-26 04:23:58 +0000171
172 /// SubVTTIndicies - Contains indices into the various sub-VTTs.
173 SubVTTIndiciesMapTy SubVTTIndicies;
174
Anders Carlsson8bdbb5b2010-05-03 00:55:11 +0000175 typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t>
Anders Carlssonf1a994c2010-03-26 04:23:58 +0000176 SecondaryVirtualPointerIndicesMapTy;
177
178 /// SecondaryVirtualPointerIndices - Contains the secondary virtual pointer
179 /// indices.
180 SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices;
Anders Carlssone36a6b32010-01-02 01:01:18 +0000181
Anders Carlsson5c5abad2010-03-23 16:36:50 +0000182 /// EmitThunk - Emit a single thunk.
Anders Carlsson8b021832011-02-06 18:31:40 +0000183 void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk,
184 bool UseAvailableExternallyLinkage);
185
186 /// MaybeEmitThunkAvailableExternally - Try to emit the given thunk with
187 /// available_externally linkage to allow for inlining of thunks.
188 /// This will be done iff optimizations are enabled and the member function
189 /// doesn't contain any incomplete types.
190 void MaybeEmitThunkAvailableExternally(GlobalDecl GD, const ThunkInfo &Thunk);
191
Anders Carlssona4147142010-03-25 15:26:28 +0000192 /// CreateVTableInitializer - Create a vtable initializer for the given record
193 /// decl.
194 /// \param Components - The vtable components; this is really an array of
195 /// VTableComponents.
196 llvm::Constant *CreateVTableInitializer(const CXXRecordDecl *RD,
197 const uint64_t *Components,
198 unsigned NumComponents,
Peter Collingbourne5ee9ee42011-09-26 01:56:41 +0000199 const VTableContext::VTableThunksTy &VTableThunks);
Anders Carlssona208b392010-03-26 03:56:54 +0000200
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000201public:
Peter Collingbournea8341662011-09-26 01:56:30 +0000202 CodeGenVTables(CodeGenModule &CGM);
203
204 VTableContext &getVTableContext() { return VTContext; }
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000205
Argyrios Kyrtzidis0c34b132010-10-11 03:25:57 +0000206 /// \brief True if the VTable of this record must be emitted in the
207 /// translation unit.
208 bool ShouldEmitVTableInThisTU(const CXXRecordDecl *RD);
Rafael Espindola683fe4f2010-04-19 00:44:22 +0000209
Anders Carlssone36a6b32010-01-02 01:01:18 +0000210 /// needsVTTParameter - Return whether the given global decl needs a VTT
211 /// parameter, which it does if it's a base constructor or destructor with
212 /// virtual bases.
213 static bool needsVTTParameter(GlobalDecl GD);
214
215 /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
216 /// given record decl.
Anders Carlsson859b3062010-05-02 23:53:25 +0000217 uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base);
Anders Carlssone36a6b32010-01-02 01:01:18 +0000218
Anders Carlssonf1a994c2010-03-26 04:23:58 +0000219 /// getSecondaryVirtualPointerIndex - Return the index in the VTT where the
220 /// virtual pointer for the given subobject is located.
221 uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
222 BaseSubobject Base);
223
Anders Carlssonf6f24c62010-03-29 02:08:26 +0000224 /// getAddressPoint - Get the address point of the given subobject in the
225 /// class decl.
226 uint64_t getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD);
227
Anders Carlsson67fbf982010-03-24 05:32:05 +0000228 /// GetAddrOfVTable - Get the address of the vtable for the given record decl.
Anders Carlssona086edc2010-03-30 03:35:35 +0000229 llvm::GlobalVariable *GetAddrOfVTable(const CXXRecordDecl *RD);
Anders Carlssonb35ea552010-03-24 03:57:14 +0000230
Anders Carlssona627ac7e2010-03-29 03:38:52 +0000231 /// EmitVTableDefinition - Emit the definition of the given vtable.
232 void EmitVTableDefinition(llvm::GlobalVariable *VTable,
233 llvm::GlobalVariable::LinkageTypes Linkage,
234 const CXXRecordDecl *RD);
235
Anders Carlsson0534b022010-03-25 00:35:49 +0000236 /// GenerateConstructionVTable - Generate a construction vtable for the given
237 /// base subobject.
238 llvm::GlobalVariable *
239 GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base,
240 bool BaseIsVirtual,
John McCall358d0562011-03-27 09:00:25 +0000241 llvm::GlobalVariable::LinkageTypes Linkage,
Anders Carlssona208b392010-03-26 03:56:54 +0000242 VTableAddressPointsMapTy& AddressPoints);
Anders Carlsson883fc722011-01-29 19:16:51 +0000243
244
245 /// GetAddrOfVTable - Get the address of the VTT for the given record decl.
246 llvm::GlobalVariable *GetAddrOfVTT(const CXXRecordDecl *RD);
247
248 /// EmitVTTDefinition - Emit the definition of the given vtable.
249 void EmitVTTDefinition(llvm::GlobalVariable *VTT,
250 llvm::GlobalVariable::LinkageTypes Linkage,
251 const CXXRecordDecl *RD);
Rafael Espindolae7113ca2010-03-10 02:19:29 +0000252
Douglas Gregor88d292c2010-05-13 16:44:06 +0000253 /// EmitThunks - Emit the associated thunks for the given global decl.
254 void EmitThunks(GlobalDecl GD);
255
Anders Carlsson55e89f82010-03-23 18:18:41 +0000256 /// GenerateClassData - Generate all the class data required to be generated
Rafael Espindolae7113ca2010-03-10 02:19:29 +0000257 /// upon definition of a KeyFunction. This includes the vtable, the
258 /// rtti data structure and the VTT.
259 ///
260 /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
261 void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
262 const CXXRecordDecl *RD);
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000263};
Benjamin Kramer334af992009-11-26 13:09:03 +0000264
Anders Carlsson5f9a8812010-01-14 02:29:07 +0000265} // end namespace CodeGen
266} // end namespace clang
Anders Carlsson2bb27f52009-10-11 22:13:54 +0000267#endif