blob: 471d6384d6b25fea70974b3d6716753801bbad89 [file] [log] [blame]
Shih-wei Liaof8fd82b2010-02-10 11:10:31 -08001//===--- 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"
18#include "llvm/ADT/DenseSet.h"
19#include "llvm/GlobalVariable.h"
20#include "GlobalDecl.h"
21
22namespace clang {
23 class CXXRecordDecl;
24
25namespace CodeGen {
26 class CodeGenModule;
27
28/// ThunkAdjustment - Virtual and non-virtual adjustment for thunks.
29class ThunkAdjustment {
30public:
31 ThunkAdjustment(int64_t NonVirtual, int64_t Virtual)
32 : NonVirtual(NonVirtual),
33 Virtual(Virtual) { }
34
35 ThunkAdjustment()
36 : NonVirtual(0), Virtual(0) { }
37
38 // isEmpty - Return whether this thunk adjustment is empty.
39 bool isEmpty() const {
40 return NonVirtual == 0 && Virtual == 0;
41 }
42
43 /// NonVirtual - The non-virtual adjustment.
44 int64_t NonVirtual;
45
46 /// Virtual - The virtual adjustment.
47 int64_t Virtual;
48};
49
50/// CovariantThunkAdjustment - Adjustment of the 'this' pointer and the
51/// return pointer for covariant thunks.
52class CovariantThunkAdjustment {
53public:
54 CovariantThunkAdjustment(const ThunkAdjustment &ThisAdjustment,
55 const ThunkAdjustment &ReturnAdjustment)
56 : ThisAdjustment(ThisAdjustment), ReturnAdjustment(ReturnAdjustment) { }
57
58 CovariantThunkAdjustment() { }
59
60 ThunkAdjustment ThisAdjustment;
61 ThunkAdjustment ReturnAdjustment;
62};
63
64// BaseSubobject - Uniquely identifies a direct or indirect base class.
65// Stores both the base class decl and the offset from the most derived class to
66// the base class.
67class BaseSubobject {
68 /// Base - The base class declaration.
69 const CXXRecordDecl *Base;
70
71 /// BaseOffset - The offset from the most derived class to the base class.
72 uint64_t BaseOffset;
73
74public:
75 BaseSubobject(const CXXRecordDecl *Base, uint64_t BaseOffset)
76 : Base(Base), BaseOffset(BaseOffset) { }
77
78 /// getBase - Returns the base class declaration.
79 const CXXRecordDecl *getBase() const { return Base; }
80
81 /// getBaseOffset - Returns the base class offset.
82 uint64_t getBaseOffset() const { return BaseOffset; }
83
84 friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
85 return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
86 }
87};
88
89} // end namespace CodeGen
90} // end namespace clang
91
92namespace llvm {
93
94template<> struct DenseMapInfo<clang::CodeGen::BaseSubobject> {
95 static clang::CodeGen::BaseSubobject getEmptyKey() {
96 return clang::CodeGen::BaseSubobject(
97 DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
98 DenseMapInfo<uint64_t>::getEmptyKey());
99 }
100
101 static clang::CodeGen::BaseSubobject getTombstoneKey() {
102 return clang::CodeGen::BaseSubobject(
103 DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
104 DenseMapInfo<uint64_t>::getTombstoneKey());
105 }
106
107 static unsigned getHashValue(const clang::CodeGen::BaseSubobject &Base) {
108 return
109 DenseMapInfo<const clang::CXXRecordDecl *>::getHashValue(Base.getBase()) ^
110 DenseMapInfo<uint64_t>::getHashValue(Base.getBaseOffset());
111 }
112
113 static bool isEqual(const clang::CodeGen::BaseSubobject &LHS,
114 const clang::CodeGen::BaseSubobject &RHS) {
115 return LHS == RHS;
116 }
117};
118
119// It's OK to treat BaseSubobject as a POD type.
120template <> struct isPodLike<clang::CodeGen::BaseSubobject> {
121 static const bool value = true;
122};
123
124}
125
126namespace clang {
127namespace CodeGen {
128
129class CGVtableInfo {
130public:
131 typedef std::vector<std::pair<GlobalDecl, ThunkAdjustment> >
132 AdjustmentVectorTy;
133
134 typedef std::pair<const CXXRecordDecl *, uint64_t> CtorVtable_t;
135 typedef llvm::DenseMap<CtorVtable_t, int64_t> AddrSubMap_t;
136 typedef llvm::DenseMap<const CXXRecordDecl *, AddrSubMap_t *> AddrMap_t;
137 llvm::DenseMap<const CXXRecordDecl *, AddrMap_t*> AddressPoints;
138
139 typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
140
141private:
142 CodeGenModule &CGM;
143
144 /// MethodVtableIndices - Contains the index (relative to the vtable address
145 /// point) where the function pointer for a virtual function is stored.
146 typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVtableIndicesTy;
147 MethodVtableIndicesTy MethodVtableIndices;
148
149 typedef std::pair<const CXXRecordDecl *,
150 const CXXRecordDecl *> ClassPairTy;
151
152 /// VirtualBaseClassIndicies - Contains the index into the vtable where the
153 /// offsets for virtual bases of a class are stored.
154 typedef llvm::DenseMap<ClassPairTy, int64_t> VirtualBaseClassIndiciesTy;
155 VirtualBaseClassIndiciesTy VirtualBaseClassIndicies;
156
157 /// Vtables - All the vtables which have been defined.
158 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> Vtables;
159
160 /// NumVirtualFunctionPointers - Contains the number of virtual function
161 /// pointers in the vtable for a given record decl.
162 llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers;
163
164 typedef llvm::DenseMap<GlobalDecl, AdjustmentVectorTy> SavedAdjustmentsTy;
165 SavedAdjustmentsTy SavedAdjustments;
166 llvm::DenseSet<const CXXRecordDecl*> SavedAdjustmentRecords;
167
168 typedef llvm::DenseMap<ClassPairTy, uint64_t> SubVTTIndiciesTy;
169 SubVTTIndiciesTy SubVTTIndicies;
170
171 /// getNumVirtualFunctionPointers - Return the number of virtual function
172 /// pointers in the vtable for a given record decl.
173 uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
174
175 void ComputeMethodVtableIndices(const CXXRecordDecl *RD);
176
177 /// GenerateClassData - Generate all the class data requires to be generated
178 /// upon definition of a KeyFunction. This includes the vtable, the
179 /// rtti data structure and the VTT.
180 ///
181 /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
182 void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
183 const CXXRecordDecl *RD);
184
185 llvm::GlobalVariable *
186 GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
187 bool GenerateDefinition, const CXXRecordDecl *LayoutClass,
188 const CXXRecordDecl *RD, uint64_t Offset,
189 AddressPointsMapTy& AddressPoints);
190
191 llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
192 bool GenerateDefinition,
193 const CXXRecordDecl *RD);
194
195public:
196 CGVtableInfo(CodeGenModule &CGM)
197 : CGM(CGM) { }
198
199 /// needsVTTParameter - Return whether the given global decl needs a VTT
200 /// parameter, which it does if it's a base constructor or destructor with
201 /// virtual bases.
202 static bool needsVTTParameter(GlobalDecl GD);
203
204 /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
205 /// given record decl.
206 uint64_t getSubVTTIndex(const CXXRecordDecl *RD, const CXXRecordDecl *Base);
207
208 /// getMethodVtableIndex - Return the index (relative to the vtable address
209 /// point) where the function pointer for the given virtual function is
210 /// stored.
211 uint64_t getMethodVtableIndex(GlobalDecl GD);
212
213 /// getVirtualBaseOffsetIndex - Return the index (relative to the vtable
214 /// address point) where the offset of the virtual base that contains the
215 /// given Base is stored, otherwise, if no virtual base contains the given
216 /// class, return 0. Base must be a virtual base class or an unambigious
217 /// base.
218 int64_t getVirtualBaseOffsetIndex(const CXXRecordDecl *RD,
219 const CXXRecordDecl *VBase);
220
221 AdjustmentVectorTy *getAdjustments(GlobalDecl GD);
222
223 /// getVtableAddressPoint - returns the address point of the vtable for the
224 /// given record decl.
225 /// FIXME: This should return a list of address points.
226 uint64_t getVtableAddressPoint(const CXXRecordDecl *RD);
227
228 llvm::GlobalVariable *getVtable(const CXXRecordDecl *RD);
229
230 /// CtorVtableInfo - Information about a constructor vtable.
231 struct CtorVtableInfo {
232 /// Vtable - The vtable itself.
233 llvm::GlobalVariable *Vtable;
234
235 /// AddressPoints - The address points in this constructor vtable.
236 AddressPointsMapTy AddressPoints;
237
238 CtorVtableInfo() : Vtable(0) { }
239 };
240
241 CtorVtableInfo getCtorVtable(const CXXRecordDecl *RD,
242 const BaseSubobject &Base);
243
244 llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
245
246 void MaybeEmitVtable(GlobalDecl GD);
247};
248
249} // end namespace CodeGen
250} // end namespace clang
251#endif