 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
100.0% |
8 / 8 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
100.0% |
8 / 8 |
| |
|
Line Coverage: |
100.0% |
29 / 29 |
| |
 |
|
 |
1 : //===--- 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 :
22 : namespace clang {
23 : class CXXRecordDecl;
24 :
25 : namespace CodeGen {
26 : class CodeGenModule;
27 :
28 : /// ThunkAdjustment - Virtual and non-virtual adjustment for thunks.
29 265: class ThunkAdjustment {
30 : public:
31 700: ThunkAdjustment(int64_t NonVirtual, int64_t Virtual)
32 : : NonVirtual(NonVirtual),
33 700: Virtual(Virtual) { }
34 :
35 2617: ThunkAdjustment()
36 2617: : NonVirtual(0), Virtual(0) { }
37 :
38 : // isEmpty - Return whether this thunk adjustment is empty.
39 3290: bool isEmpty() const {
2962: branch 0 taken
328: branch 1 taken
2390: branch 2 taken
572: branch 3 taken
40 3290: 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.
52 : class CovariantThunkAdjustment {
53 : public:
54 : CovariantThunkAdjustment(const ThunkAdjustment &ThisAdjustment,
55 353: const ThunkAdjustment &ReturnAdjustment)
56 353: : 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.
67 50304: class 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 :
74 : public:
75 12276: BaseSubobject(const CXXRecordDecl *Base, uint64_t BaseOffset)
76 12276: : Base(Base), BaseOffset(BaseOffset) { }
77 :
78 : /// getBase - Returns the base class declaration.
79 2621: const CXXRecordDecl *getBase() const { return Base; }
80 :
81 : /// getBaseOffset - Returns the base class offset.
82 2346: uint64_t getBaseOffset() const { return BaseOffset; }
83 :
84 77456: friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
68014: branch 0 taken
9442: branch 1 taken
67944: branch 2 taken
70: branch 3 taken
85 77456: return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
86 : }
87 : };
88 :
89 : } // end namespace CodeGen
90 : } // end namespace clang
91 :
92 : namespace llvm {
93 :
94 : template<> struct DenseMapInfo<clang::CodeGen::BaseSubobject> {
95 7216: static clang::CodeGen::BaseSubobject getEmptyKey() {
96 : return clang::CodeGen::BaseSubobject(
97 : DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
98 7216: DenseMapInfo<uint64_t>::getEmptyKey());
99 : }
100 :
101 3002: static clang::CodeGen::BaseSubobject getTombstoneKey() {
102 : return clang::CodeGen::BaseSubobject(
103 : DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
104 3002: DenseMapInfo<uint64_t>::getTombstoneKey());
105 : }
106 :
107 2235: static unsigned getHashValue(const clang::CodeGen::BaseSubobject &Base) {
108 : return
109 : DenseMapInfo<const clang::CXXRecordDecl *>::getHashValue(Base.getBase()) ^
110 2235: DenseMapInfo<uint64_t>::getHashValue(Base.getBaseOffset());
111 : }
112 :
113 : static bool isEqual(const clang::CodeGen::BaseSubobject &LHS,
114 68357: const clang::CodeGen::BaseSubobject &RHS) {
115 68357: return LHS == RHS;
116 : }
117 : };
118 :
119 : // It's OK to treat BaseSubobject as a POD type.
120 : template <> struct isPodLike<clang::CodeGen::BaseSubobject> {
121 : static const bool value = true;
122 : };
123 :
124 : }
125 :
126 : namespace clang {
127 : namespace CodeGen {
128 :
129 599: class CGVtableInfo {
130 : public:
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 :
141 : private:
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 :
195 : public:
196 625: CGVtableInfo(CodeGenModule &CGM)
197 625: : 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 111: 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 111: 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
Generated: 2010-02-10 01:31 by zcov