blob: f3574987fa20786a617a4eb7d65a2ed269e60e1c [file] [log] [blame]
Anders Carlssondbd920c2009-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 Friedman72649ed2009-12-06 22:01:30 +000018#include "llvm/ADT/DenseSet.h"
Anders Carlsson35272252009-12-06 00:23:49 +000019#include "llvm/GlobalVariable.h"
Anders Carlssona0fdd912009-11-13 17:08:56 +000020#include "GlobalDecl.h"
Anders Carlssondbd920c2009-10-11 22:13:54 +000021
22namespace clang {
Anders Carlssondbd920c2009-10-11 22:13:54 +000023 class CXXRecordDecl;
Benjamin Kramer39411b92009-11-26 13:09:03 +000024
Anders Carlssondbd920c2009-10-11 22:13:54 +000025namespace CodeGen {
26 class CodeGenModule;
Anders Carlssona94822e2009-11-26 02:32:05 +000027
Benjamin Kramer39411b92009-11-26 13:09:03 +000028/// ThunkAdjustment - Virtual and non-virtual adjustment for thunks.
29class ThunkAdjustment {
30public:
Anders Carlssona94822e2009-11-26 02:32:05 +000031 ThunkAdjustment(int64_t NonVirtual, int64_t Virtual)
Benjamin Kramer39411b92009-11-26 13:09:03 +000032 : NonVirtual(NonVirtual),
Anders Carlssona94822e2009-11-26 02:32:05 +000033 Virtual(Virtual) { }
Benjamin Kramer39411b92009-11-26 13:09:03 +000034
Anders Carlssona94822e2009-11-26 02:32:05 +000035 ThunkAdjustment()
36 : NonVirtual(0), Virtual(0) { }
Benjamin Kramer39411b92009-11-26 13:09:03 +000037
Anders Carlssona94822e2009-11-26 02:32:05 +000038 // isEmpty - Return whether this thunk adjustment is empty.
Benjamin Kramer39411b92009-11-26 13:09:03 +000039 bool isEmpty() const {
Anders Carlssona94822e2009-11-26 02:32:05 +000040 return NonVirtual == 0 && Virtual == 0;
41 }
Benjamin Kramer39411b92009-11-26 13:09:03 +000042
Anders Carlssona94822e2009-11-26 02:32:05 +000043 /// NonVirtual - The non-virtual adjustment.
44 int64_t NonVirtual;
Benjamin Kramer39411b92009-11-26 13:09:03 +000045
Anders Carlssona94822e2009-11-26 02:32:05 +000046 /// Virtual - The virtual adjustment.
47 int64_t Virtual;
48};
49
Anders Carlsson7622cd32009-11-26 03:09:37 +000050/// CovariantThunkAdjustment - Adjustment of the 'this' pointer and the
51/// return pointer for covariant thunks.
Benjamin Kramer39411b92009-11-26 13:09:03 +000052class CovariantThunkAdjustment {
53public:
Anders Carlsson7622cd32009-11-26 03:09:37 +000054 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
Anders Carlsson6b4333d2010-01-13 20:11:15 +000064// 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; }
Anders Carlsson7e37a692010-01-14 01:39:42 +000083
Anders Carlsson6b4333d2010-01-13 20:11:15 +000084 friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
85 return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
86 }
87};
Anders Carlsson7e37a692010-01-14 01:39:42 +000088
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
Anders Carlsson1bb60992010-01-14 02:29:07 +0000119// It's OK to treat BaseSubobject as a POD type.
120template <> struct isPodLike<clang::CodeGen::BaseSubobject> {
121 static const bool value = true;
122};
123
Anders Carlsson7e37a692010-01-14 01:39:42 +0000124}
125
126namespace clang {
127namespace CodeGen {
128
Anders Carlssonaf440352010-03-23 04:11:45 +0000129class CodeGenVTables {
Eli Friedmanb455f0e2009-12-07 23:56:34 +0000130public:
131 typedef std::vector<std::pair<GlobalDecl, ThunkAdjustment> >
132 AdjustmentVectorTy;
133
Anders Carlsson21431c52010-01-02 18:02:32 +0000134 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
Anders Carlsson1bb60992010-01-14 02:29:07 +0000139 typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
140
Eli Friedmanb455f0e2009-12-07 23:56:34 +0000141private:
Anders Carlssondbd920c2009-10-11 22:13:54 +0000142 CodeGenModule &CGM;
Benjamin Kramer39411b92009-11-26 13:09:03 +0000143
Anders Carlssondbd920c2009-10-11 22:13:54 +0000144 /// MethodVtableIndices - Contains the index (relative to the vtable address
145 /// point) where the function pointer for a virtual function is stored.
Anders Carlssona0fdd912009-11-13 17:08:56 +0000146 typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVtableIndicesTy;
Anders Carlssondbd920c2009-10-11 22:13:54 +0000147 MethodVtableIndicesTy MethodVtableIndices;
Benjamin Kramer39411b92009-11-26 13:09:03 +0000148
Anders Carlssondbd920c2009-10-11 22:13:54 +0000149 typedef std::pair<const CXXRecordDecl *,
150 const CXXRecordDecl *> ClassPairTy;
Benjamin Kramer39411b92009-11-26 13:09:03 +0000151
Anders Carlssonbba16072010-03-11 07:15:17 +0000152 /// VirtualBaseClassOffsetOffsets - Contains the vtable offset (relative to
153 /// the address point) in bytes where the offsets for virtual bases of a class
154 /// are stored.
155 typedef llvm::DenseMap<ClassPairTy, int64_t>
156 VirtualBaseClassOffsetOffsetsMapTy;
157 VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
Mike Stump380dd752009-11-10 07:44:33 +0000158
Anders Carlsson8c2d36f2009-12-06 00:01:05 +0000159 /// Vtables - All the vtables which have been defined.
160 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> Vtables;
Anders Carlssond6b07fb2009-11-27 20:47:55 +0000161
162 /// NumVirtualFunctionPointers - Contains the number of virtual function
163 /// pointers in the vtable for a given record decl.
164 llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers;
165
Eli Friedmanb455f0e2009-12-07 23:56:34 +0000166 typedef llvm::DenseMap<GlobalDecl, AdjustmentVectorTy> SavedAdjustmentsTy;
167 SavedAdjustmentsTy SavedAdjustments;
168 llvm::DenseSet<const CXXRecordDecl*> SavedAdjustmentRecords;
Eli Friedman72649ed2009-12-06 22:01:30 +0000169
Anders Carlssonc997d422010-01-02 01:01:18 +0000170 typedef llvm::DenseMap<ClassPairTy, uint64_t> SubVTTIndiciesTy;
171 SubVTTIndiciesTy SubVTTIndicies;
172
Anders Carlssond6b07fb2009-11-27 20:47:55 +0000173 /// getNumVirtualFunctionPointers - Return the number of virtual function
174 /// pointers in the vtable for a given record decl.
175 uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
176
177 void ComputeMethodVtableIndices(const CXXRecordDecl *RD);
Rafael Espindolabbf58bb2010-03-10 02:19:29 +0000178
Anders Carlsson35272252009-12-06 00:23:49 +0000179 llvm::GlobalVariable *
Anders Carlsson35272252009-12-06 00:23:49 +0000180 GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
Anders Carlsson5794c972009-12-06 00:53:22 +0000181 bool GenerateDefinition, const CXXRecordDecl *LayoutClass,
Anders Carlsson5d7af6b2010-02-28 00:36:23 +0000182 const CXXRecordDecl *RD, uint64_t Offset, bool IsVirtual,
Anders Carlsson1bb60992010-01-14 02:29:07 +0000183 AddressPointsMapTy& AddressPoints);
Anders Carlssonc3a46ef2009-12-06 01:09:21 +0000184
185 llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
Anders Carlssonc997d422010-01-02 01:01:18 +0000186 bool GenerateDefinition,
Anders Carlssonc3a46ef2009-12-06 01:09:21 +0000187 const CXXRecordDecl *RD);
188
Anders Carlssondbd920c2009-10-11 22:13:54 +0000189public:
Anders Carlssonaf440352010-03-23 04:11:45 +0000190 CodeGenVTables(CodeGenModule &CGM)
Anders Carlssondbd920c2009-10-11 22:13:54 +0000191 : CGM(CGM) { }
192
Anders Carlssonc997d422010-01-02 01:01:18 +0000193 /// needsVTTParameter - Return whether the given global decl needs a VTT
194 /// parameter, which it does if it's a base constructor or destructor with
195 /// virtual bases.
196 static bool needsVTTParameter(GlobalDecl GD);
197
198 /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
199 /// given record decl.
200 uint64_t getSubVTTIndex(const CXXRecordDecl *RD, const CXXRecordDecl *Base);
201
Anders Carlssondbd920c2009-10-11 22:13:54 +0000202 /// getMethodVtableIndex - Return the index (relative to the vtable address
Benjamin Kramer39411b92009-11-26 13:09:03 +0000203 /// point) where the function pointer for the given virtual function is
Anders Carlssondbd920c2009-10-11 22:13:54 +0000204 /// stored.
Anders Carlssond6b07fb2009-11-27 20:47:55 +0000205 uint64_t getMethodVtableIndex(GlobalDecl GD);
Benjamin Kramer39411b92009-11-26 13:09:03 +0000206
Anders Carlssonbba16072010-03-11 07:15:17 +0000207 /// getVirtualBaseOffsetOffset - Return the offset in bytes (relative to the
208 /// vtable address point) where the offset of the virtual base that contains
209 /// the given base is stored, otherwise, if no virtual base contains the given
Mike Stumpab28c132009-10-13 22:54:56 +0000210 /// class, return 0. Base must be a virtual base class or an unambigious
211 /// base.
Anders Carlssonbba16072010-03-11 07:15:17 +0000212 int64_t getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
213 const CXXRecordDecl *VBase);
Mike Stump380dd752009-11-10 07:44:33 +0000214
Eli Friedmanb455f0e2009-12-07 23:56:34 +0000215 AdjustmentVectorTy *getAdjustments(GlobalDecl GD);
Eli Friedman72649ed2009-12-06 22:01:30 +0000216
Anders Carlsson9ac95b92009-12-05 21:03:56 +0000217 /// getVtableAddressPoint - returns the address point of the vtable for the
218 /// given record decl.
219 /// FIXME: This should return a list of address points.
220 uint64_t getVtableAddressPoint(const CXXRecordDecl *RD);
221
Anders Carlsson8c2d36f2009-12-06 00:01:05 +0000222 llvm::GlobalVariable *getVtable(const CXXRecordDecl *RD);
Anders Carlsson1bb60992010-01-14 02:29:07 +0000223
224 /// CtorVtableInfo - Information about a constructor vtable.
225 struct CtorVtableInfo {
226 /// Vtable - The vtable itself.
227 llvm::GlobalVariable *Vtable;
228
229 /// AddressPoints - The address points in this constructor vtable.
230 AddressPointsMapTy AddressPoints;
231
232 CtorVtableInfo() : Vtable(0) { }
233 };
234
235 CtorVtableInfo getCtorVtable(const CXXRecordDecl *RD,
Anders Carlsson5d7af6b2010-02-28 00:36:23 +0000236 const BaseSubobject &Base,
237 bool BaseIsVirtual);
Anders Carlsson1a5e0d72009-11-30 23:41:22 +0000238
Anders Carlssonc997d422010-01-02 01:01:18 +0000239 llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
Anders Carlsson1a5e0d72009-11-30 23:41:22 +0000240
Anders Carlsson13189d02010-03-23 04:15:00 +0000241 // EmitVTableRelatedData - Will emit any thunks that the global decl might
242 // have, as well as the vtable itself if the global decl is the key function.
243 void EmitVTableRelatedData(GlobalDecl GD);
Rafael Espindolabbf58bb2010-03-10 02:19:29 +0000244
245 /// GenerateClassData - Generate all the class data requires to be generated
246 /// upon definition of a KeyFunction. This includes the vtable, the
247 /// rtti data structure and the VTT.
248 ///
249 /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
250 void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
251 const CXXRecordDecl *RD);
Anders Carlssondbd920c2009-10-11 22:13:54 +0000252};
Benjamin Kramer39411b92009-11-26 13:09:03 +0000253
Anders Carlsson1bb60992010-01-14 02:29:07 +0000254} // end namespace CodeGen
255} // end namespace clang
Anders Carlssondbd920c2009-10-11 22:13:54 +0000256#endif