blob: aefc41e50002a22b1fa276a0dcb701de88ff2445 [file] [log] [blame]
Anders Carlsson58b7eee2010-01-21 16:50:45 +00001//===--- CGVTT.cpp - Emit LLVM Code for C++ VTTs --------------------------===//
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 VTTs (vtable tables).
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenModule.h"
John McCall4c40d982010-08-31 07:33:07 +000015#include "CGCXXABI.h"
Anders Carlsson58b7eee2010-01-21 16:50:45 +000016#include "clang/AST/RecordLayout.h"
17using namespace clang;
18using namespace CodeGen;
19
20#define D1(x)
21
22namespace {
Anders Carlsson50a2b422010-03-26 00:58:21 +000023
24/// VTT builder - Class for building VTT layout information.
Anders Carlsson58b7eee2010-01-21 16:50:45 +000025class VTTBuilder {
Anders Carlsson19f191f2010-03-26 04:10:39 +000026
27 CodeGenModule &CGM;
28
Anders Carlsson50a2b422010-03-26 00:58:21 +000029 /// MostDerivedClass - The most derived class for which we're building this
30 /// vtable.
31 const CXXRecordDecl *MostDerivedClass;
32
Anders Carlsson19f191f2010-03-26 04:10:39 +000033 typedef llvm::SmallVector<llvm::Constant *, 64> VTTComponentsVectorTy;
34
35 /// VTTComponents - The VTT components.
36 VTTComponentsVectorTy VTTComponents;
Anders Carlsson50a2b422010-03-26 00:58:21 +000037
38 /// MostDerivedClassLayout - the AST record layout of the most derived class.
39 const ASTRecordLayout &MostDerivedClassLayout;
40
Anders Carlsson9f17d412010-03-26 00:50:17 +000041 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
42
Anders Carlsson2c822f12010-03-26 03:56:54 +000043 typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
44
Anders Carlsson19f191f2010-03-26 04:10:39 +000045 /// SubVTTIndicies - The sub-VTT indices for the bases of the most derived
Anders Carlssone1dcc222010-03-26 04:23:58 +000046 /// class.
Anders Carlsson3855a072010-05-03 00:55:11 +000047 llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
Anders Carlssone1dcc222010-03-26 04:23:58 +000048
49 /// SecondaryVirtualPointerIndices - The secondary virtual pointer indices of
50 /// all subobjects of the most derived class.
51 llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
52
Anders Carlsson19f191f2010-03-26 04:10:39 +000053 /// GenerateDefinition - Whether the VTT builder should generate LLVM IR for
54 /// the VTT.
Anders Carlsson58b7eee2010-01-21 16:50:45 +000055 bool GenerateDefinition;
John McCallbda0d6b2011-03-27 09:00:25 +000056
57 /// The linkage to use for any construction vtables required by this VTT.
58 /// Only required if we're building a definition.
59 llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables;
Anders Carlsson58b7eee2010-01-21 16:50:45 +000060
Anders Carlsson2c822f12010-03-26 03:56:54 +000061 /// GetAddrOfVTable - Returns the address of the vtable for the base class in
62 /// the given vtable class.
63 ///
64 /// \param AddressPoints - If the returned vtable is a construction vtable,
65 /// this will hold the address points for it.
66 llvm::Constant *GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
67 AddressPointsMapTy& AddressPoints);
68
69 /// AddVTablePointer - Add a vtable pointer to the VTT currently being built.
70 ///
71 /// \param AddressPoints - If the vtable is a construction vtable, this has
72 /// the address points for it.
73 void AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
74 const CXXRecordDecl *VTableClass,
75 const AddressPointsMapTy& AddressPoints);
76
Anders Carlssonc1246c82010-03-26 00:35:45 +000077 /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base
78 /// subobject.
79 void LayoutSecondaryVTTs(BaseSubobject Base);
80
Anders Carlsson2c822f12010-03-26 03:56:54 +000081 /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
82 /// for the given base subobject.
83 ///
84 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
85 /// or a direct or indirect base of a virtual base.
86 ///
87 /// \param AddressPoints - If the vtable is a construction vtable, this has
88 /// the address points for it.
89 void LayoutSecondaryVirtualPointers(BaseSubobject Base,
90 bool BaseIsMorallyVirtual,
91 llvm::Constant *VTable,
92 const CXXRecordDecl *VTableClass,
93 const AddressPointsMapTy& AddressPoints,
94 VisitedVirtualBasesSetTy &VBases);
95
96 /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
97 /// for the given base subobject.
98 ///
99 /// \param AddressPoints - If the vtable is a construction vtable, this has
100 /// the address points for it.
101 void LayoutSecondaryVirtualPointers(BaseSubobject Base,
102 llvm::Constant *VTable,
103 const AddressPointsMapTy& AddressPoints);
104
Anders Carlsson9f17d412010-03-26 00:50:17 +0000105 /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the
106 /// given record decl.
107 void LayoutVirtualVTTs(const CXXRecordDecl *RD,
108 VisitedVirtualBasesSetTy &VBases);
109
110 /// LayoutVTT - Will lay out the VTT for the given subobject, including any
111 /// secondary VTTs, secondary virtual pointers and virtual VTTs.
112 void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
113
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000114public:
Anders Carlsson19f191f2010-03-26 04:10:39 +0000115 VTTBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerivedClass,
John McCallbda0d6b2011-03-27 09:00:25 +0000116 bool GenerateDefinition,
117 llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables
118 = (llvm::GlobalVariable::LinkageTypes) -1);
Anders Carlssone1dcc222010-03-26 04:23:58 +0000119
Anders Carlsson19f191f2010-03-26 04:10:39 +0000120 // getVTTComponents - Returns a reference to the VTT components.
121 const VTTComponentsVectorTy &getVTTComponents() const {
122 return VTTComponents;
123 }
Anders Carlssone1dcc222010-03-26 04:23:58 +0000124
125 /// getSubVTTIndicies - Returns a reference to the sub-VTT indices.
Anders Carlsson3855a072010-05-03 00:55:11 +0000126 const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
Anders Carlssone1dcc222010-03-26 04:23:58 +0000127 return SubVTTIndicies;
128 }
129
130 /// getSecondaryVirtualPointerIndices - Returns a reference to the secondary
131 /// virtual pointer indices.
132 const llvm::DenseMap<BaseSubobject, uint64_t> &
133 getSecondaryVirtualPointerIndices() const {
134 return SecondaryVirtualPointerIndices;
135 }
136
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000137};
Anders Carlsson2c822f12010-03-26 03:56:54 +0000138
Anders Carlsson19f191f2010-03-26 04:10:39 +0000139VTTBuilder::VTTBuilder(CodeGenModule &CGM,
140 const CXXRecordDecl *MostDerivedClass,
John McCallbda0d6b2011-03-27 09:00:25 +0000141 bool GenerateDefinition,
142 llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables)
Anders Carlsson19f191f2010-03-26 04:10:39 +0000143 : CGM(CGM), MostDerivedClass(MostDerivedClass),
144 MostDerivedClassLayout(CGM.getContext().getASTRecordLayout(MostDerivedClass)),
John McCallbda0d6b2011-03-27 09:00:25 +0000145 GenerateDefinition(GenerateDefinition),
146 LinkageForConstructionVTables(LinkageForConstructionVTables) {
147 assert(!GenerateDefinition ||
148 LinkageForConstructionVTables
149 != (llvm::GlobalVariable::LinkageTypes) -1);
Anders Carlsson19f191f2010-03-26 04:10:39 +0000150
151 // Lay out this VTT.
Ken Dyck4230d522011-03-24 01:21:01 +0000152 LayoutVTT(BaseSubobject(MostDerivedClass, CharUnits::Zero()),
153 /*BaseIsVirtual=*/false);
Anders Carlsson19f191f2010-03-26 04:10:39 +0000154}
155
Anders Carlsson2c822f12010-03-26 03:56:54 +0000156llvm::Constant *
157VTTBuilder::GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
158 AddressPointsMapTy& AddressPoints) {
159 if (!GenerateDefinition)
160 return 0;
Anders Carlssonc1246c82010-03-26 00:35:45 +0000161
Anders Carlsson2c822f12010-03-26 03:56:54 +0000162 if (Base.getBase() == MostDerivedClass) {
Ken Dyck4230d522011-03-24 01:21:01 +0000163 assert(Base.getBaseOffset().isZero() &&
Anders Carlsson2c822f12010-03-26 03:56:54 +0000164 "Most derived class vtable must have a zero offset!");
165 // This is a regular vtable.
166 return CGM.getVTables().GetAddrOfVTable(MostDerivedClass);
167 }
168
169 return CGM.getVTables().GenerateConstructionVTable(MostDerivedClass,
170 Base, BaseIsVirtual,
John McCallbda0d6b2011-03-27 09:00:25 +0000171 LinkageForConstructionVTables,
Anders Carlsson2c822f12010-03-26 03:56:54 +0000172 AddressPoints);
173}
174
175void VTTBuilder::AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
176 const CXXRecordDecl *VTableClass,
177 const AddressPointsMapTy& AddressPoints) {
Anders Carlssonf6da6a02010-03-29 01:04:16 +0000178 // Store the vtable pointer index if we're generating the primary VTT.
Anders Carlsson80faf692010-03-29 01:12:13 +0000179 if (VTableClass == MostDerivedClass) {
Anders Carlssonf6da6a02010-03-29 01:04:16 +0000180 assert(!SecondaryVirtualPointerIndices.count(Base) &&
181 "A virtual pointer index already exists for this base subobject!");
182 SecondaryVirtualPointerIndices[Base] = VTTComponents.size();
183 }
184
Anders Carlsson2c822f12010-03-26 03:56:54 +0000185 if (!GenerateDefinition) {
Anders Carlsson19f191f2010-03-26 04:10:39 +0000186 VTTComponents.push_back(0);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000187 return;
188 }
189
190 uint64_t AddressPoint;
191 if (VTableClass != MostDerivedClass) {
192 // The vtable is a construction vtable, look in the construction vtable
193 // address points.
194 AddressPoint = AddressPoints.lookup(Base);
Anders Carlsson836d9dd2010-04-11 20:23:06 +0000195 assert(AddressPoint != 0 && "Did not find ctor vtable address point!");
Anders Carlsson2c822f12010-03-26 03:56:54 +0000196 } else {
Anders Carlsson0a4a2fd2010-03-29 02:14:35 +0000197 // Just get the address point for the regular vtable.
198 AddressPoint = CGM.getVTables().getAddressPoint(Base, VTableClass);
Anders Carlsson836d9dd2010-04-11 20:23:06 +0000199 assert(AddressPoint != 0 && "Did not find vtable address point!");
Anders Carlsson2c822f12010-03-26 03:56:54 +0000200 }
201
202 if (!AddressPoint) AddressPoint = 0;
Anders Carlsson2c822f12010-03-26 03:56:54 +0000203
204 llvm::Value *Idxs[] = {
205 llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0),
206 llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()),
207 AddressPoint)
208 };
209
210 llvm::Constant *Init =
211 llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Idxs, 2);
212
213 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
214 Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
215
Anders Carlsson19f191f2010-03-26 04:10:39 +0000216 VTTComponents.push_back(Init);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000217}
218
Anders Carlssonc1246c82010-03-26 00:35:45 +0000219void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
220 const CXXRecordDecl *RD = Base.getBase();
221
222 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
223 E = RD->bases_end(); I != E; ++I) {
224
225 // Don't layout virtual bases.
226 if (I->isVirtual())
227 continue;
228
229 const CXXRecordDecl *BaseDecl =
230 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
231
232 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
Ken Dyck4230d522011-03-24 01:21:01 +0000233 CharUnits BaseOffset = Base.getBaseOffset() +
234 Layout.getBaseClassOffset(BaseDecl);
Anders Carlssonc1246c82010-03-26 00:35:45 +0000235
236 // Layout the VTT for this base.
237 LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false);
238 }
239}
240
Anders Carlsson2c822f12010-03-26 03:56:54 +0000241void
242VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
243 bool BaseIsMorallyVirtual,
244 llvm::Constant *VTable,
245 const CXXRecordDecl *VTableClass,
246 const AddressPointsMapTy& AddressPoints,
247 VisitedVirtualBasesSetTy &VBases) {
248 const CXXRecordDecl *RD = Base.getBase();
249
250 // We're not interested in bases that don't have virtual bases, and not
251 // morally virtual bases.
252 if (!RD->getNumVBases() && !BaseIsMorallyVirtual)
253 return;
254
255 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
256 E = RD->bases_end(); I != E; ++I) {
257 const CXXRecordDecl *BaseDecl =
258 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
259
260 // Itanium C++ ABI 2.6.2:
261 // Secondary virtual pointers are present for all bases with either
262 // virtual bases or virtual function declarations overridden along a
263 // virtual path.
264 //
265 // If the base class is not dynamic, we don't want to add it, nor any
266 // of its base classes.
267 if (!BaseDecl->isDynamicClass())
268 continue;
269
270 bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual;
271 bool BaseDeclIsNonVirtualPrimaryBase = false;
Ken Dyck4230d522011-03-24 01:21:01 +0000272 CharUnits BaseOffset;
Anders Carlsson2c822f12010-03-26 03:56:54 +0000273 if (I->isVirtual()) {
274 // Ignore virtual bases that we've already visited.
275 if (!VBases.insert(BaseDecl))
276 continue;
277
Ken Dyck4230d522011-03-24 01:21:01 +0000278 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000279 BaseDeclIsMorallyVirtual = true;
280 } else {
281 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
282
Ken Dyck4230d522011-03-24 01:21:01 +0000283 BaseOffset = Base.getBaseOffset() +
284 Layout.getBaseClassOffset(BaseDecl);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000285
Anders Carlssonc9e814b2010-11-24 23:12:57 +0000286 if (!Layout.isPrimaryBaseVirtual() &&
Anders Carlsson2c822f12010-03-26 03:56:54 +0000287 Layout.getPrimaryBase() == BaseDecl)
288 BaseDeclIsNonVirtualPrimaryBase = true;
289 }
290
291 // Itanium C++ ABI 2.6.2:
292 // Secondary virtual pointers: for each base class X which (a) has virtual
293 // bases or is reachable along a virtual path from D, and (b) is not a
294 // non-virtual primary base, the address of the virtual table for X-in-D
295 // or an appropriate construction virtual table.
296 if (!BaseDeclIsNonVirtualPrimaryBase &&
297 (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) {
298 // Add the vtable pointer.
Ken Dyck4230d522011-03-24 01:21:01 +0000299 AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTable,
300 VTableClass, AddressPoints);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000301 }
302
303 // And lay out the secondary virtual pointers for the base class.
304 LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset),
305 BaseDeclIsMorallyVirtual, VTable,
306 VTableClass, AddressPoints, VBases);
307 }
308}
309
310void
311VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
312 llvm::Constant *VTable,
313 const AddressPointsMapTy& AddressPoints) {
314 VisitedVirtualBasesSetTy VBases;
315 LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false,
316 VTable, Base.getBase(), AddressPoints, VBases);
317}
318
Anders Carlsson9f17d412010-03-26 00:50:17 +0000319void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
320 VisitedVirtualBasesSetTy &VBases) {
321 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
322 E = RD->bases_end(); I != E; ++I) {
323 const CXXRecordDecl *BaseDecl =
324 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
325
326 // Check if this is a virtual base.
327 if (I->isVirtual()) {
328 // Check if we've seen this base before.
329 if (!VBases.insert(BaseDecl))
330 continue;
331
Ken Dyck4230d522011-03-24 01:21:01 +0000332 CharUnits BaseOffset =
333 MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
Anders Carlsson9f17d412010-03-26 00:50:17 +0000334
335 LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true);
336 }
337
338 // We only need to layout virtual VTTs for this base if it actually has
339 // virtual bases.
340 if (BaseDecl->getNumVBases())
341 LayoutVirtualVTTs(BaseDecl, VBases);
342 }
343}
344
Anders Carlssonc1246c82010-03-26 00:35:45 +0000345void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) {
346 const CXXRecordDecl *RD = Base.getBase();
347
348 // Itanium C++ ABI 2.6.2:
349 // An array of virtual table addresses, called the VTT, is declared for
350 // each class type that has indirect or direct virtual base classes.
351 if (RD->getNumVBases() == 0)
352 return;
Anders Carlsson19f191f2010-03-26 04:10:39 +0000353
354 bool IsPrimaryVTT = Base.getBase() == MostDerivedClass;
355
356 if (!IsPrimaryVTT) {
357 // Remember the sub-VTT index.
Anders Carlsson3855a072010-05-03 00:55:11 +0000358 SubVTTIndicies[Base] = VTTComponents.size();
Anders Carlsson19f191f2010-03-26 04:10:39 +0000359 }
Anders Carlssonc1246c82010-03-26 00:35:45 +0000360
Anders Carlsson2c822f12010-03-26 03:56:54 +0000361 AddressPointsMapTy AddressPoints;
362 llvm::Constant *VTable = GetAddrOfVTable(Base, BaseIsVirtual, AddressPoints);
Anders Carlssonc1246c82010-03-26 00:35:45 +0000363
Anders Carlsson2c822f12010-03-26 03:56:54 +0000364 // Add the primary vtable pointer.
365 AddVTablePointer(Base, VTable, RD, AddressPoints);
Anders Carlssonc1246c82010-03-26 00:35:45 +0000366
Anders Carlsson2c822f12010-03-26 03:56:54 +0000367 // Add the secondary VTTs.
Anders Carlssonc1246c82010-03-26 00:35:45 +0000368 LayoutSecondaryVTTs(Base);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000369
370 // Add the secondary virtual pointers.
371 LayoutSecondaryVirtualPointers(Base, VTable, AddressPoints);
372
373 // If this is the primary VTT, we want to lay out virtual VTTs as well.
Anders Carlsson19f191f2010-03-26 04:10:39 +0000374 if (IsPrimaryVTT) {
Anders Carlsson2c822f12010-03-26 03:56:54 +0000375 VisitedVirtualBasesSetTy VBases;
376 LayoutVirtualVTTs(Base.getBase(), VBases);
377 }
Anders Carlssonc1246c82010-03-26 00:35:45 +0000378}
379
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000380}
381
Anders Carlsson1cbce122011-01-29 19:16:51 +0000382void
383CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
384 llvm::GlobalVariable::LinkageTypes Linkage,
385 const CXXRecordDecl *RD) {
John McCallbda0d6b2011-03-27 09:00:25 +0000386 VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/true, Linkage);
Anders Carlsson1cbce122011-01-29 19:16:51 +0000387
388 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
389 const llvm::ArrayType *ArrayType =
390 llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
391
392 llvm::Constant *Init =
393 llvm::ConstantArray::get(ArrayType, Builder.getVTTComponents().data(),
394 Builder.getVTTComponents().size());
395
396 VTT->setInitializer(Init);
397
398 // Set the correct linkage.
399 VTT->setLinkage(Linkage);
Anders Carlsson691222d2011-01-29 19:34:19 +0000400
401 // Set the right visibility.
Anders Carlssonfa2e99f2011-01-29 20:24:48 +0000402 CGM.setTypeVisibility(VTT, RD, CodeGenModule::TVK_ForVTT);
Anders Carlsson1cbce122011-01-29 19:16:51 +0000403}
404
405llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) {
406 assert(RD->getNumVBases() && "Only classes with virtual bases need a VTT");
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000407
408 llvm::SmallString<256> OutName;
Rafael Espindolaf0be9792011-02-11 02:52:17 +0000409 llvm::raw_svector_ostream Out(OutName);
410 CGM.getCXXABI().getMangleContext().mangleCXXVTT(RD, Out);
411 Out.flush();
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000412 llvm::StringRef Name = OutName.str();
413
Anders Carlssone3d6cf22011-05-16 04:08:36 +0000414 ComputeVTableRelatedInformation(RD, /*VTableRequired=*/true);
415
Anders Carlsson1cbce122011-01-29 19:16:51 +0000416 VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000417
Anders Carlsson1cbce122011-01-29 19:16:51 +0000418 const llvm::Type *Int8PtrTy =
419 llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
420 const llvm::ArrayType *ArrayType =
421 llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000422
Anders Carlsson1cbce122011-01-29 19:16:51 +0000423 llvm::GlobalVariable *GV =
424 CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType,
425 llvm::GlobalValue::ExternalLinkage);
426 GV->setUnnamedAddr(true);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000427 return GV;
428}
429
Anders Carlssonaf440352010-03-23 04:11:45 +0000430bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000431 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
432
433 // We don't have any virtual bases, just return early.
434 if (!MD->getParent()->getNumVBases())
435 return false;
436
437 // Check if we have a base constructor.
438 if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
439 return true;
440
441 // Check if we have a base destructor.
442 if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
443 return true;
444
445 return false;
446}
447
Anders Carlssonaf440352010-03-23 04:11:45 +0000448uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD,
Anders Carlssonc11bb212010-05-02 23:53:25 +0000449 BaseSubobject Base) {
Anders Carlsson3855a072010-05-03 00:55:11 +0000450 BaseSubobjectPairTy ClassSubobjectPair(RD, Base);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000451
Anders Carlsson3855a072010-05-03 00:55:11 +0000452 SubVTTIndiciesMapTy::iterator I = SubVTTIndicies.find(ClassSubobjectPair);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000453 if (I != SubVTTIndicies.end())
454 return I->second;
455
Anders Carlsson19f191f2010-03-26 04:10:39 +0000456 VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000457
Anders Carlsson3855a072010-05-03 00:55:11 +0000458 for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000459 Builder.getSubVTTIndicies().begin(),
460 E = Builder.getSubVTTIndicies().end(); I != E; ++I) {
461 // Insert all indices.
Anders Carlsson3855a072010-05-03 00:55:11 +0000462 BaseSubobjectPairTy ClassSubobjectPair(RD, I->first);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000463
Anders Carlsson3855a072010-05-03 00:55:11 +0000464 SubVTTIndicies.insert(std::make_pair(ClassSubobjectPair, I->second));
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000465 }
466
Anders Carlsson3855a072010-05-03 00:55:11 +0000467 I = SubVTTIndicies.find(ClassSubobjectPair);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000468 assert(I != SubVTTIndicies.end() && "Did not find index!");
469
470 return I->second;
471}
Anders Carlssone1dcc222010-03-26 04:23:58 +0000472
473uint64_t
474CodeGenVTables::getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
475 BaseSubobject Base) {
476 SecondaryVirtualPointerIndicesMapTy::iterator I =
477 SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
478
479 if (I != SecondaryVirtualPointerIndices.end())
480 return I->second;
481
482 VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
483
484 // Insert all secondary vpointer indices.
485 for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
486 Builder.getSecondaryVirtualPointerIndices().begin(),
487 E = Builder.getSecondaryVirtualPointerIndices().end(); I != E; ++I) {
488 std::pair<const CXXRecordDecl *, BaseSubobject> Pair =
489 std::make_pair(RD, I->first);
490
491 SecondaryVirtualPointerIndices.insert(std::make_pair(Pair, I->second));
492 }
493
494 I = SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
495 assert(I != SecondaryVirtualPointerIndices.end() && "Did not find index!");
496
497 return I->second;
498}
499