blob: bd03583fdce41a810c41b425e24f32b3d54aeba6 [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"
15#include "clang/AST/RecordLayout.h"
16using namespace clang;
17using namespace CodeGen;
18
19#define D1(x)
20
21namespace {
Anders Carlsson50a2b422010-03-26 00:58:21 +000022
23/// VTT builder - Class for building VTT layout information.
Anders Carlsson58b7eee2010-01-21 16:50:45 +000024class VTTBuilder {
Anders Carlsson50a2b422010-03-26 00:58:21 +000025 /// MostDerivedClass - The most derived class for which we're building this
26 /// vtable.
27 const CXXRecordDecl *MostDerivedClass;
28
Anders Carlsson58b7eee2010-01-21 16:50:45 +000029 /// Inits - The list of values built for the VTT.
30 std::vector<llvm::Constant *> &Inits;
Anders Carlsson50a2b422010-03-26 00:58:21 +000031
32 /// MostDerivedClassLayout - the AST record layout of the most derived class.
33 const ASTRecordLayout &MostDerivedClassLayout;
34
Anders Carlsson58b7eee2010-01-21 16:50:45 +000035 CodeGenModule &CGM; // Per-module state.
Anders Carlsson50a2b422010-03-26 00:58:21 +000036
Anders Carlssonaf440352010-03-23 04:11:45 +000037 CodeGenVTables::AddrMap_t &AddressPoints;
Anders Carlsson58b7eee2010-01-21 16:50:45 +000038 // vtbl - A pointer to the vtable for Class.
39 llvm::Constant *ClassVtbl;
40 llvm::LLVMContext &VMContext;
41
Anders Carlsson9f17d412010-03-26 00:50:17 +000042 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
43
Anders Carlsson2c822f12010-03-26 03:56:54 +000044 typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
45
Anders Carlsson58b7eee2010-01-21 16:50:45 +000046 /// SeenVBasesInSecondary - The seen virtual bases when building the
47 /// secondary virtual pointers.
48 llvm::SmallPtrSet<const CXXRecordDecl *, 32> SeenVBasesInSecondary;
49
50 llvm::DenseMap<const CXXRecordDecl *, uint64_t> SubVTTIndicies;
51
52 bool GenerateDefinition;
53
54 llvm::DenseMap<BaseSubobject, llvm::Constant *> CtorVtables;
55 llvm::DenseMap<std::pair<const CXXRecordDecl *, BaseSubobject>, uint64_t>
56 CtorVtableAddressPoints;
57
Anders Carlsson5d7af6b2010-02-28 00:36:23 +000058 llvm::Constant *getCtorVtable(const BaseSubobject &Base,
59 bool BaseIsVirtual) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +000060 if (!GenerateDefinition)
61 return 0;
62
63 llvm::Constant *&CtorVtable = CtorVtables[Base];
Anders Carlsson58b7eee2010-01-21 16:50:45 +000064 return CtorVtable;
65 }
66
67
68 /// BuildVtablePtr - Build up a referene to the given secondary vtable
69 llvm::Constant *BuildVtablePtr(llvm::Constant *Vtable,
70 const CXXRecordDecl *VtableClass,
71 const CXXRecordDecl *RD,
72 uint64_t Offset) {
73 if (!GenerateDefinition)
74 return 0;
75
76 uint64_t AddressPoint;
77
Anders Carlsson50a2b422010-03-26 00:58:21 +000078 if (VtableClass != MostDerivedClass) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +000079 // We have a ctor vtable, look for the address point in the ctor vtable
80 // address points.
81 AddressPoint =
82 CtorVtableAddressPoints[std::make_pair(VtableClass,
83 BaseSubobject(RD, Offset))];
84 } else {
85 AddressPoint =
86 (*AddressPoints[VtableClass])[std::make_pair(RD, Offset)];
87 }
88
89 // FIXME: We can never have 0 address point. Do this for now so gepping
90 // retains the same structure. Later we'll just assert.
91 if (AddressPoint == 0)
92 AddressPoint = 1;
93 D1(printf("XXX address point for %s in %s layout %s at offset %d was %d\n",
94 RD->getNameAsCString(), VtblClass->getNameAsCString(),
95 Class->getNameAsCString(), (int)Offset, (int)AddressPoint));
96
97 llvm::Value *Idxs[] = {
98 llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 0),
99 llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), AddressPoint)
100 };
101
102 llvm::Constant *Init =
103 llvm::ConstantExpr::getInBoundsGetElementPtr(Vtable, Idxs, 2);
104
105 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
106 return llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
107 }
108
109 /// Secondary - Add the secondary vtable pointers to Inits. Offset is the
110 /// current offset in bits to the object we're working on.
111 void Secondary(const CXXRecordDecl *RD, llvm::Constant *vtbl,
Anders Carlsson18222542010-03-26 00:11:51 +0000112 const CXXRecordDecl *VtblClass, uint64_t Offset,
113 bool MorallyVirtual) {
Anders Carlsson2c822f12010-03-26 03:56:54 +0000114 if (RD->getNumVBases() == 0 && !MorallyVirtual)
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000115 return;
116
117 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
118 e = RD->bases_end(); i != e; ++i) {
119 const CXXRecordDecl *Base =
120 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
121
122 // We only want to visit each virtual base once.
123 if (i->isVirtual() && SeenVBasesInSecondary.count(Base))
124 continue;
125
126 // Itanium C++ ABI 2.6.2:
127 // Secondary virtual pointers are present for all bases with either
128 // virtual bases or virtual function declarations overridden along a
129 // virtual path.
130 //
131 // If the base class is not dynamic, we don't want to add it, nor any
132 // of its base classes.
133 if (!Base->isDynamicClass())
134 continue;
135
136 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
137 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
138 const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
139 bool NonVirtualPrimaryBase;
140 NonVirtualPrimaryBase = !PrimaryBaseWasVirtual && Base == PrimaryBase;
141 bool BaseMorallyVirtual = MorallyVirtual | i->isVirtual();
142 uint64_t BaseOffset;
143 if (!i->isVirtual()) {
144 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
145 BaseOffset = Offset + Layout.getBaseClassOffset(Base);
146 } else
Anders Carlsson50a2b422010-03-26 00:58:21 +0000147 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(Base);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000148 llvm::Constant *subvtbl = vtbl;
149 const CXXRecordDecl *subVtblClass = VtblClass;
150 if ((Base->getNumVBases() || BaseMorallyVirtual)
151 && !NonVirtualPrimaryBase) {
152 llvm::Constant *init;
Anders Carlsson50a2b422010-03-26 00:58:21 +0000153 if (BaseMorallyVirtual || VtblClass == MostDerivedClass)
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000154 init = BuildVtablePtr(vtbl, VtblClass, Base, BaseOffset);
155 else {
Anders Carlsson5d7af6b2010-02-28 00:36:23 +0000156 init = getCtorVtable(BaseSubobject(Base, BaseOffset), i->isVirtual());
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000157
158 subvtbl = init;
159 subVtblClass = Base;
160
Anders Carlsson50a2b422010-03-26 00:58:21 +0000161 init = BuildVtablePtr(init, MostDerivedClass, Base, BaseOffset);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000162 }
163
164 Inits.push_back(init);
165 }
166
167 if (i->isVirtual())
168 SeenVBasesInSecondary.insert(Base);
169
170 Secondary(Base, subvtbl, subVtblClass, BaseOffset, BaseMorallyVirtual);
171 }
172 }
173
Anders Carlsson2c822f12010-03-26 03:56:54 +0000174 /// GetAddrOfVTable - Returns the address of the vtable for the base class in
175 /// the given vtable class.
176 ///
177 /// \param AddressPoints - If the returned vtable is a construction vtable,
178 /// this will hold the address points for it.
179 llvm::Constant *GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
180 AddressPointsMapTy& AddressPoints);
181
182 /// AddVTablePointer - Add a vtable pointer to the VTT currently being built.
183 ///
184 /// \param AddressPoints - If the vtable is a construction vtable, this has
185 /// the address points for it.
186 void AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
187 const CXXRecordDecl *VTableClass,
188 const AddressPointsMapTy& AddressPoints);
189
Anders Carlssonc1246c82010-03-26 00:35:45 +0000190 /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base
191 /// subobject.
192 void LayoutSecondaryVTTs(BaseSubobject Base);
193
Anders Carlsson2c822f12010-03-26 03:56:54 +0000194 /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
195 /// for the given base subobject.
196 ///
197 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
198 /// or a direct or indirect base of a virtual base.
199 ///
200 /// \param AddressPoints - If the vtable is a construction vtable, this has
201 /// the address points for it.
202 void LayoutSecondaryVirtualPointers(BaseSubobject Base,
203 bool BaseIsMorallyVirtual,
204 llvm::Constant *VTable,
205 const CXXRecordDecl *VTableClass,
206 const AddressPointsMapTy& AddressPoints,
207 VisitedVirtualBasesSetTy &VBases);
208
209 /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
210 /// for the given base subobject.
211 ///
212 /// \param AddressPoints - If the vtable is a construction vtable, this has
213 /// the address points for it.
214 void LayoutSecondaryVirtualPointers(BaseSubobject Base,
215 llvm::Constant *VTable,
216 const AddressPointsMapTy& AddressPoints);
217
Anders Carlsson9f17d412010-03-26 00:50:17 +0000218 /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the
219 /// given record decl.
220 void LayoutVirtualVTTs(const CXXRecordDecl *RD,
221 VisitedVirtualBasesSetTy &VBases);
222
223 /// LayoutVTT - Will lay out the VTT for the given subobject, including any
224 /// secondary VTTs, secondary virtual pointers and virtual VTTs.
225 void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
226
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000227public:
Anders Carlsson50a2b422010-03-26 00:58:21 +0000228 VTTBuilder(std::vector<llvm::Constant *> &inits,
229 const CXXRecordDecl *MostDerivedClass,
Anders Carlsson2c822f12010-03-26 03:56:54 +0000230 CodeGenModule &cgm, bool GenerateDefinition)
Anders Carlsson50a2b422010-03-26 00:58:21 +0000231 : MostDerivedClass(MostDerivedClass),
232 Inits(inits),
233 MostDerivedClassLayout(cgm.getContext().getASTRecordLayout(MostDerivedClass)),
234 CGM(cgm),
235 AddressPoints(*cgm.getVTables().OldAddressPoints[MostDerivedClass]),
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000236 VMContext(cgm.getModule().getContext()),
237 GenerateDefinition(GenerateDefinition) {
238
Anders Carlsson2c822f12010-03-26 03:56:54 +0000239 LayoutVTT(BaseSubobject(MostDerivedClass, 0), /*BaseIsVirtual=*/false);
240#if 0
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000241 // First comes the primary virtual table pointer for the complete class...
Anders Carlsson50a2b422010-03-26 00:58:21 +0000242 ClassVtbl = GenerateDefinition ?
243 CGM.getVTables().GetAddrOfVTable(MostDerivedClass) :0;
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000244
Anders Carlsson50a2b422010-03-26 00:58:21 +0000245 llvm::Constant *Init = BuildVtablePtr(ClassVtbl, MostDerivedClass,
246 MostDerivedClass, 0);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000247 Inits.push_back(Init);
248
249 // then the secondary VTTs...
Anders Carlsson50a2b422010-03-26 00:58:21 +0000250 LayoutSecondaryVTTs(BaseSubobject(MostDerivedClass, 0));
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000251
252 // Make sure to clear the set of seen virtual bases.
253 SeenVBasesInSecondary.clear();
254
255 // then the secondary vtable pointers...
Anders Carlsson50a2b422010-03-26 00:58:21 +0000256 Secondary(MostDerivedClass, ClassVtbl, MostDerivedClass, 0, false);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000257
258 // and last, the virtual VTTs.
Anders Carlsson9f17d412010-03-26 00:50:17 +0000259 VisitedVirtualBasesSetTy VBases;
Anders Carlsson50a2b422010-03-26 00:58:21 +0000260 LayoutVirtualVTTs(MostDerivedClass, VBases);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000261#endif
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000262 }
263
264 llvm::DenseMap<const CXXRecordDecl *, uint64_t> &getSubVTTIndicies() {
265 return SubVTTIndicies;
266 }
267};
Anders Carlsson2c822f12010-03-26 03:56:54 +0000268
269llvm::Constant *
270VTTBuilder::GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
271 AddressPointsMapTy& AddressPoints) {
272 if (!GenerateDefinition)
273 return 0;
Anders Carlssonc1246c82010-03-26 00:35:45 +0000274
Anders Carlsson2c822f12010-03-26 03:56:54 +0000275 if (Base.getBase() == MostDerivedClass) {
276 assert(Base.getBaseOffset() == 0 &&
277 "Most derived class vtable must have a zero offset!");
278 // This is a regular vtable.
279 return CGM.getVTables().GetAddrOfVTable(MostDerivedClass);
280 }
281
282 return CGM.getVTables().GenerateConstructionVTable(MostDerivedClass,
283 Base, BaseIsVirtual,
284 AddressPoints);
285}
286
287void VTTBuilder::AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
288 const CXXRecordDecl *VTableClass,
289 const AddressPointsMapTy& AddressPoints) {
290 if (!GenerateDefinition) {
291 Inits.push_back(0);
292 return;
293 }
294
295 uint64_t AddressPoint;
296 if (VTableClass != MostDerivedClass) {
297 // The vtable is a construction vtable, look in the construction vtable
298 // address points.
299 AddressPoint = AddressPoints.lookup(Base);
300 } else {
301 AddressPoint =
302 (*this->AddressPoints[VTableClass])[std::make_pair(Base.getBase(),
303 Base.getBaseOffset())];
304 }
305
306 if (!AddressPoint) AddressPoint = 0;
307 assert(AddressPoint != 0 && "Did not find an address point!");
308
309 llvm::Value *Idxs[] = {
310 llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0),
311 llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()),
312 AddressPoint)
313 };
314
315 llvm::Constant *Init =
316 llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Idxs, 2);
317
318 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
319 Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
320
321 Inits.push_back(Init);
322}
323
Anders Carlssonc1246c82010-03-26 00:35:45 +0000324void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
325 const CXXRecordDecl *RD = Base.getBase();
326
327 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
328 E = RD->bases_end(); I != E; ++I) {
329
330 // Don't layout virtual bases.
331 if (I->isVirtual())
332 continue;
333
334 const CXXRecordDecl *BaseDecl =
335 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
336
337 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
338 uint64_t BaseOffset = Base.getBaseOffset() +
339 Layout.getBaseClassOffset(BaseDecl);
340
341 // Layout the VTT for this base.
342 LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false);
343 }
344}
345
Anders Carlsson2c822f12010-03-26 03:56:54 +0000346void
347VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
348 bool BaseIsMorallyVirtual,
349 llvm::Constant *VTable,
350 const CXXRecordDecl *VTableClass,
351 const AddressPointsMapTy& AddressPoints,
352 VisitedVirtualBasesSetTy &VBases) {
353 const CXXRecordDecl *RD = Base.getBase();
354
355 // We're not interested in bases that don't have virtual bases, and not
356 // morally virtual bases.
357 if (!RD->getNumVBases() && !BaseIsMorallyVirtual)
358 return;
359
360 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
361 E = RD->bases_end(); I != E; ++I) {
362 const CXXRecordDecl *BaseDecl =
363 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
364
365 // Itanium C++ ABI 2.6.2:
366 // Secondary virtual pointers are present for all bases with either
367 // virtual bases or virtual function declarations overridden along a
368 // virtual path.
369 //
370 // If the base class is not dynamic, we don't want to add it, nor any
371 // of its base classes.
372 if (!BaseDecl->isDynamicClass())
373 continue;
374
375 bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual;
376 bool BaseDeclIsNonVirtualPrimaryBase = false;
377 uint64_t BaseOffset;
378 if (I->isVirtual()) {
379 // Ignore virtual bases that we've already visited.
380 if (!VBases.insert(BaseDecl))
381 continue;
382
383 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
384 BaseDeclIsMorallyVirtual = true;
385 } else {
386 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
387
388 BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl);
389
390 if (!Layout.getPrimaryBaseWasVirtual() &&
391 Layout.getPrimaryBase() == BaseDecl)
392 BaseDeclIsNonVirtualPrimaryBase = true;
393 }
394
395 // Itanium C++ ABI 2.6.2:
396 // Secondary virtual pointers: for each base class X which (a) has virtual
397 // bases or is reachable along a virtual path from D, and (b) is not a
398 // non-virtual primary base, the address of the virtual table for X-in-D
399 // or an appropriate construction virtual table.
400 if (!BaseDeclIsNonVirtualPrimaryBase &&
401 (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) {
402 // Add the vtable pointer.
403 AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTable, VTableClass,
404 AddressPoints);
405 }
406
407 // And lay out the secondary virtual pointers for the base class.
408 LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset),
409 BaseDeclIsMorallyVirtual, VTable,
410 VTableClass, AddressPoints, VBases);
411 }
412}
413
414void
415VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
416 llvm::Constant *VTable,
417 const AddressPointsMapTy& AddressPoints) {
418 VisitedVirtualBasesSetTy VBases;
419 LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false,
420 VTable, Base.getBase(), AddressPoints, VBases);
421}
422
Anders Carlsson9f17d412010-03-26 00:50:17 +0000423void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
424 VisitedVirtualBasesSetTy &VBases) {
425 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
426 E = RD->bases_end(); I != E; ++I) {
427 const CXXRecordDecl *BaseDecl =
428 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
429
430 // Check if this is a virtual base.
431 if (I->isVirtual()) {
432 // Check if we've seen this base before.
433 if (!VBases.insert(BaseDecl))
434 continue;
435
Anders Carlsson9f17d412010-03-26 00:50:17 +0000436 uint64_t BaseOffset =
437 MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
438
439 LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true);
440 }
441
442 // We only need to layout virtual VTTs for this base if it actually has
443 // virtual bases.
444 if (BaseDecl->getNumVBases())
445 LayoutVirtualVTTs(BaseDecl, VBases);
446 }
447}
448
Anders Carlssonc1246c82010-03-26 00:35:45 +0000449void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) {
450 const CXXRecordDecl *RD = Base.getBase();
451
452 // Itanium C++ ABI 2.6.2:
453 // An array of virtual table addresses, called the VTT, is declared for
454 // each class type that has indirect or direct virtual base classes.
455 if (RD->getNumVBases() == 0)
456 return;
457
458 // Remember the sub-VTT index.
459 SubVTTIndicies[RD] = Inits.size();
460
Anders Carlsson2c822f12010-03-26 03:56:54 +0000461 AddressPointsMapTy AddressPoints;
462 llvm::Constant *VTable = GetAddrOfVTable(Base, BaseIsVirtual, AddressPoints);
Anders Carlssonc1246c82010-03-26 00:35:45 +0000463
Anders Carlsson2c822f12010-03-26 03:56:54 +0000464 // Add the primary vtable pointer.
465 AddVTablePointer(Base, VTable, RD, AddressPoints);
Anders Carlssonc1246c82010-03-26 00:35:45 +0000466
Anders Carlsson2c822f12010-03-26 03:56:54 +0000467 // Add the secondary VTTs.
Anders Carlssonc1246c82010-03-26 00:35:45 +0000468 LayoutSecondaryVTTs(Base);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000469
470 // Add the secondary virtual pointers.
471 LayoutSecondaryVirtualPointers(Base, VTable, AddressPoints);
472
473 // If this is the primary VTT, we want to lay out virtual VTTs as well.
474 if (Base.getBase() == MostDerivedClass) {
475 VisitedVirtualBasesSetTy VBases;
476 LayoutVirtualVTTs(Base.getBase(), VBases);
477 }
Anders Carlssonc1246c82010-03-26 00:35:45 +0000478}
479
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000480}
481
482llvm::GlobalVariable *
Anders Carlssonaf440352010-03-23 04:11:45 +0000483CodeGenVTables::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
484 bool GenerateDefinition,
485 const CXXRecordDecl *RD) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000486 // Only classes that have virtual bases need a VTT.
487 if (RD->getNumVBases() == 0)
488 return 0;
489
490 llvm::SmallString<256> OutName;
491 CGM.getMangleContext().mangleCXXVTT(RD, OutName);
492 llvm::StringRef Name = OutName.str();
493
494 D1(printf("vtt %s\n", RD->getNameAsCString()));
495
496 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
497 if (GV == 0 || GV->isDeclaration()) {
498 const llvm::Type *Int8PtrTy =
499 llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
500
501 std::vector<llvm::Constant *> inits;
502 VTTBuilder b(inits, RD, CGM, GenerateDefinition);
503
504 const llvm::ArrayType *Type = llvm::ArrayType::get(Int8PtrTy, inits.size());
505 llvm::Constant *Init = 0;
506 if (GenerateDefinition)
507 Init = llvm::ConstantArray::get(Type, inits);
508
509 llvm::GlobalVariable *OldGV = GV;
510 GV = new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true,
511 Linkage, Init, Name);
512 CGM.setGlobalVisibility(GV, RD);
513
514 if (OldGV) {
515 GV->takeName(OldGV);
516 llvm::Constant *NewPtr =
517 llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
518 OldGV->replaceAllUsesWith(NewPtr);
519 OldGV->eraseFromParent();
520 }
521 }
522
523 return GV;
524}
525
Anders Carlssonaf440352010-03-23 04:11:45 +0000526llvm::GlobalVariable *CodeGenVTables::getVTT(const CXXRecordDecl *RD) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000527 return GenerateVTT(llvm::GlobalValue::ExternalLinkage,
528 /*GenerateDefinition=*/false, RD);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000529}
530
Anders Carlssonaf440352010-03-23 04:11:45 +0000531bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000532 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
533
534 // We don't have any virtual bases, just return early.
535 if (!MD->getParent()->getNumVBases())
536 return false;
537
538 // Check if we have a base constructor.
539 if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
540 return true;
541
542 // Check if we have a base destructor.
543 if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
544 return true;
545
546 return false;
547}
548
Anders Carlssonaf440352010-03-23 04:11:45 +0000549uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD,
550 const CXXRecordDecl *Base) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000551 ClassPairTy ClassPair(RD, Base);
552
553 SubVTTIndiciesTy::iterator I =
554 SubVTTIndicies.find(ClassPair);
555 if (I != SubVTTIndicies.end())
556 return I->second;
557
558 std::vector<llvm::Constant *> inits;
559 VTTBuilder Builder(inits, RD, CGM, /*GenerateDefinition=*/false);
560
561 for (llvm::DenseMap<const CXXRecordDecl *, uint64_t>::iterator I =
562 Builder.getSubVTTIndicies().begin(),
563 E = Builder.getSubVTTIndicies().end(); I != E; ++I) {
564 // Insert all indices.
565 ClassPairTy ClassPair(RD, I->first);
566
567 SubVTTIndicies.insert(std::make_pair(ClassPair, I->second));
568 }
569
570 I = SubVTTIndicies.find(ClassPair);
571 assert(I != SubVTTIndicies.end() && "Did not find index!");
572
573 return I->second;
574}