blob: 6b21046b4c735705c14a706d5456f4cc58f52a9d [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 Carlsson19f191f2010-03-26 04:10:39 +000025
26 CodeGenModule &CGM;
27
Anders Carlsson50a2b422010-03-26 00:58:21 +000028 /// MostDerivedClass - The most derived class for which we're building this
29 /// vtable.
30 const CXXRecordDecl *MostDerivedClass;
31
Anders Carlsson19f191f2010-03-26 04:10:39 +000032 typedef llvm::SmallVector<llvm::Constant *, 64> VTTComponentsVectorTy;
33
34 /// VTTComponents - The VTT components.
35 VTTComponentsVectorTy VTTComponents;
Anders Carlsson50a2b422010-03-26 00:58:21 +000036
37 /// MostDerivedClassLayout - the AST record layout of the most derived class.
38 const ASTRecordLayout &MostDerivedClassLayout;
39
Anders Carlssonaf440352010-03-23 04:11:45 +000040 CodeGenVTables::AddrMap_t &AddressPoints;
Anders Carlsson58b7eee2010-01-21 16:50:45 +000041
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 Carlsson19f191f2010-03-26 04:10:39 +000046 /// SubVTTIndicies - The sub-VTT indices for the bases of the most derived
Anders Carlssone1dcc222010-03-26 04:23:58 +000047 /// class.
Anders Carlsson58b7eee2010-01-21 16:50:45 +000048 llvm::DenseMap<const CXXRecordDecl *, uint64_t> SubVTTIndicies;
Anders Carlssone1dcc222010-03-26 04:23:58 +000049
50 /// SecondaryVirtualPointerIndices - The secondary virtual pointer indices of
51 /// all subobjects of the most derived class.
52 llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
53
Anders Carlsson19f191f2010-03-26 04:10:39 +000054 /// GenerateDefinition - Whether the VTT builder should generate LLVM IR for
55 /// the VTT.
Anders Carlsson58b7eee2010-01-21 16:50:45 +000056 bool GenerateDefinition;
Anders Carlsson58b7eee2010-01-21 16:50:45 +000057
Anders Carlsson2c822f12010-03-26 03:56:54 +000058 /// GetAddrOfVTable - Returns the address of the vtable for the base class in
59 /// the given vtable class.
60 ///
61 /// \param AddressPoints - If the returned vtable is a construction vtable,
62 /// this will hold the address points for it.
63 llvm::Constant *GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
64 AddressPointsMapTy& AddressPoints);
65
66 /// AddVTablePointer - Add a vtable pointer to the VTT currently being built.
67 ///
68 /// \param AddressPoints - If the vtable is a construction vtable, this has
69 /// the address points for it.
70 void AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
71 const CXXRecordDecl *VTableClass,
72 const AddressPointsMapTy& AddressPoints);
73
Anders Carlssonc1246c82010-03-26 00:35:45 +000074 /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base
75 /// subobject.
76 void LayoutSecondaryVTTs(BaseSubobject Base);
77
Anders Carlsson2c822f12010-03-26 03:56:54 +000078 /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
79 /// for the given base subobject.
80 ///
81 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
82 /// or a direct or indirect base of a virtual base.
83 ///
84 /// \param AddressPoints - If the vtable is a construction vtable, this has
85 /// the address points for it.
86 void LayoutSecondaryVirtualPointers(BaseSubobject Base,
87 bool BaseIsMorallyVirtual,
88 llvm::Constant *VTable,
89 const CXXRecordDecl *VTableClass,
90 const AddressPointsMapTy& AddressPoints,
91 VisitedVirtualBasesSetTy &VBases);
92
93 /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
94 /// for the given base subobject.
95 ///
96 /// \param AddressPoints - If the vtable is a construction vtable, this has
97 /// the address points for it.
98 void LayoutSecondaryVirtualPointers(BaseSubobject Base,
99 llvm::Constant *VTable,
100 const AddressPointsMapTy& AddressPoints);
101
Anders Carlsson9f17d412010-03-26 00:50:17 +0000102 /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the
103 /// given record decl.
104 void LayoutVirtualVTTs(const CXXRecordDecl *RD,
105 VisitedVirtualBasesSetTy &VBases);
106
107 /// LayoutVTT - Will lay out the VTT for the given subobject, including any
108 /// secondary VTTs, secondary virtual pointers and virtual VTTs.
109 void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
110
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000111public:
Anders Carlsson19f191f2010-03-26 04:10:39 +0000112 VTTBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerivedClass,
113 bool GenerateDefinition);
Anders Carlssone1dcc222010-03-26 04:23:58 +0000114
Anders Carlsson19f191f2010-03-26 04:10:39 +0000115 // getVTTComponents - Returns a reference to the VTT components.
116 const VTTComponentsVectorTy &getVTTComponents() const {
117 return VTTComponents;
118 }
Anders Carlssone1dcc222010-03-26 04:23:58 +0000119
120 /// getSubVTTIndicies - Returns a reference to the sub-VTT indices.
121 const llvm::DenseMap<const CXXRecordDecl *, uint64_t> &
122 getSubVTTIndicies() const {
123 return SubVTTIndicies;
124 }
125
126 /// getSecondaryVirtualPointerIndices - Returns a reference to the secondary
127 /// virtual pointer indices.
128 const llvm::DenseMap<BaseSubobject, uint64_t> &
129 getSecondaryVirtualPointerIndices() const {
130 return SecondaryVirtualPointerIndices;
131 }
132
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000133};
Anders Carlsson2c822f12010-03-26 03:56:54 +0000134
Anders Carlsson19f191f2010-03-26 04:10:39 +0000135VTTBuilder::VTTBuilder(CodeGenModule &CGM,
136 const CXXRecordDecl *MostDerivedClass,
137 bool GenerateDefinition)
138 : CGM(CGM), MostDerivedClass(MostDerivedClass),
139 MostDerivedClassLayout(CGM.getContext().getASTRecordLayout(MostDerivedClass)),
140 AddressPoints(*CGM.getVTables().OldAddressPoints[MostDerivedClass]),
141 GenerateDefinition(GenerateDefinition) {
142
143 // Lay out this VTT.
144 LayoutVTT(BaseSubobject(MostDerivedClass, 0), /*BaseIsVirtual=*/false);
145}
146
Anders Carlsson2c822f12010-03-26 03:56:54 +0000147llvm::Constant *
148VTTBuilder::GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
149 AddressPointsMapTy& AddressPoints) {
150 if (!GenerateDefinition)
151 return 0;
Anders Carlssonc1246c82010-03-26 00:35:45 +0000152
Anders Carlsson2c822f12010-03-26 03:56:54 +0000153 if (Base.getBase() == MostDerivedClass) {
154 assert(Base.getBaseOffset() == 0 &&
155 "Most derived class vtable must have a zero offset!");
156 // This is a regular vtable.
157 return CGM.getVTables().GetAddrOfVTable(MostDerivedClass);
158 }
159
160 return CGM.getVTables().GenerateConstructionVTable(MostDerivedClass,
161 Base, BaseIsVirtual,
162 AddressPoints);
163}
164
165void VTTBuilder::AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
166 const CXXRecordDecl *VTableClass,
167 const AddressPointsMapTy& AddressPoints) {
Anders Carlssonf6da6a02010-03-29 01:04:16 +0000168 // Store the vtable pointer index if we're generating the primary VTT.
169 if (Base.getBase() == MostDerivedClass) {
170 assert(!SecondaryVirtualPointerIndices.count(Base) &&
171 "A virtual pointer index already exists for this base subobject!");
172 SecondaryVirtualPointerIndices[Base] = VTTComponents.size();
173 }
174
Anders Carlsson2c822f12010-03-26 03:56:54 +0000175 if (!GenerateDefinition) {
Anders Carlsson19f191f2010-03-26 04:10:39 +0000176 VTTComponents.push_back(0);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000177 return;
178 }
179
180 uint64_t AddressPoint;
181 if (VTableClass != MostDerivedClass) {
182 // The vtable is a construction vtable, look in the construction vtable
183 // address points.
184 AddressPoint = AddressPoints.lookup(Base);
185 } else {
186 AddressPoint =
187 (*this->AddressPoints[VTableClass])[std::make_pair(Base.getBase(),
188 Base.getBaseOffset())];
189 }
190
191 if (!AddressPoint) AddressPoint = 0;
192 assert(AddressPoint != 0 && "Did not find an address point!");
193
194 llvm::Value *Idxs[] = {
195 llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0),
196 llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()),
197 AddressPoint)
198 };
199
200 llvm::Constant *Init =
201 llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Idxs, 2);
202
203 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
204 Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
205
Anders Carlsson19f191f2010-03-26 04:10:39 +0000206 VTTComponents.push_back(Init);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000207}
208
Anders Carlssonc1246c82010-03-26 00:35:45 +0000209void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
210 const CXXRecordDecl *RD = Base.getBase();
211
212 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
213 E = RD->bases_end(); I != E; ++I) {
214
215 // Don't layout virtual bases.
216 if (I->isVirtual())
217 continue;
218
219 const CXXRecordDecl *BaseDecl =
220 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
221
222 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
223 uint64_t BaseOffset = Base.getBaseOffset() +
224 Layout.getBaseClassOffset(BaseDecl);
225
226 // Layout the VTT for this base.
227 LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false);
228 }
229}
230
Anders Carlsson2c822f12010-03-26 03:56:54 +0000231void
232VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
233 bool BaseIsMorallyVirtual,
234 llvm::Constant *VTable,
235 const CXXRecordDecl *VTableClass,
236 const AddressPointsMapTy& AddressPoints,
237 VisitedVirtualBasesSetTy &VBases) {
238 const CXXRecordDecl *RD = Base.getBase();
239
240 // We're not interested in bases that don't have virtual bases, and not
241 // morally virtual bases.
242 if (!RD->getNumVBases() && !BaseIsMorallyVirtual)
243 return;
244
245 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
246 E = RD->bases_end(); I != E; ++I) {
247 const CXXRecordDecl *BaseDecl =
248 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
249
250 // Itanium C++ ABI 2.6.2:
251 // Secondary virtual pointers are present for all bases with either
252 // virtual bases or virtual function declarations overridden along a
253 // virtual path.
254 //
255 // If the base class is not dynamic, we don't want to add it, nor any
256 // of its base classes.
257 if (!BaseDecl->isDynamicClass())
258 continue;
259
260 bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual;
261 bool BaseDeclIsNonVirtualPrimaryBase = false;
262 uint64_t BaseOffset;
263 if (I->isVirtual()) {
264 // Ignore virtual bases that we've already visited.
265 if (!VBases.insert(BaseDecl))
266 continue;
267
268 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
269 BaseDeclIsMorallyVirtual = true;
270 } else {
271 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
272
273 BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl);
274
275 if (!Layout.getPrimaryBaseWasVirtual() &&
276 Layout.getPrimaryBase() == BaseDecl)
277 BaseDeclIsNonVirtualPrimaryBase = true;
278 }
279
280 // Itanium C++ ABI 2.6.2:
281 // Secondary virtual pointers: for each base class X which (a) has virtual
282 // bases or is reachable along a virtual path from D, and (b) is not a
283 // non-virtual primary base, the address of the virtual table for X-in-D
284 // or an appropriate construction virtual table.
285 if (!BaseDeclIsNonVirtualPrimaryBase &&
286 (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) {
287 // Add the vtable pointer.
288 AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTable, VTableClass,
289 AddressPoints);
290 }
291
292 // And lay out the secondary virtual pointers for the base class.
293 LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset),
294 BaseDeclIsMorallyVirtual, VTable,
295 VTableClass, AddressPoints, VBases);
296 }
297}
298
299void
300VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
301 llvm::Constant *VTable,
302 const AddressPointsMapTy& AddressPoints) {
303 VisitedVirtualBasesSetTy VBases;
304 LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false,
305 VTable, Base.getBase(), AddressPoints, VBases);
306}
307
Anders Carlsson9f17d412010-03-26 00:50:17 +0000308void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
309 VisitedVirtualBasesSetTy &VBases) {
310 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
311 E = RD->bases_end(); I != E; ++I) {
312 const CXXRecordDecl *BaseDecl =
313 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
314
315 // Check if this is a virtual base.
316 if (I->isVirtual()) {
317 // Check if we've seen this base before.
318 if (!VBases.insert(BaseDecl))
319 continue;
320
Anders Carlsson9f17d412010-03-26 00:50:17 +0000321 uint64_t BaseOffset =
322 MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
323
324 LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true);
325 }
326
327 // We only need to layout virtual VTTs for this base if it actually has
328 // virtual bases.
329 if (BaseDecl->getNumVBases())
330 LayoutVirtualVTTs(BaseDecl, VBases);
331 }
332}
333
Anders Carlssonc1246c82010-03-26 00:35:45 +0000334void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) {
335 const CXXRecordDecl *RD = Base.getBase();
336
337 // Itanium C++ ABI 2.6.2:
338 // An array of virtual table addresses, called the VTT, is declared for
339 // each class type that has indirect or direct virtual base classes.
340 if (RD->getNumVBases() == 0)
341 return;
Anders Carlsson19f191f2010-03-26 04:10:39 +0000342
343 bool IsPrimaryVTT = Base.getBase() == MostDerivedClass;
344
345 if (!IsPrimaryVTT) {
346 // Remember the sub-VTT index.
347 SubVTTIndicies[RD] = VTTComponents.size();
348 }
Anders Carlssonc1246c82010-03-26 00:35:45 +0000349
Anders Carlsson2c822f12010-03-26 03:56:54 +0000350 AddressPointsMapTy AddressPoints;
351 llvm::Constant *VTable = GetAddrOfVTable(Base, BaseIsVirtual, AddressPoints);
Anders Carlssonc1246c82010-03-26 00:35:45 +0000352
Anders Carlsson2c822f12010-03-26 03:56:54 +0000353 // Add the primary vtable pointer.
354 AddVTablePointer(Base, VTable, RD, AddressPoints);
Anders Carlssonc1246c82010-03-26 00:35:45 +0000355
Anders Carlsson2c822f12010-03-26 03:56:54 +0000356 // Add the secondary VTTs.
Anders Carlssonc1246c82010-03-26 00:35:45 +0000357 LayoutSecondaryVTTs(Base);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000358
359 // Add the secondary virtual pointers.
360 LayoutSecondaryVirtualPointers(Base, VTable, AddressPoints);
361
362 // If this is the primary VTT, we want to lay out virtual VTTs as well.
Anders Carlsson19f191f2010-03-26 04:10:39 +0000363 if (IsPrimaryVTT) {
Anders Carlsson2c822f12010-03-26 03:56:54 +0000364 VisitedVirtualBasesSetTy VBases;
365 LayoutVirtualVTTs(Base.getBase(), VBases);
366 }
Anders Carlssonc1246c82010-03-26 00:35:45 +0000367}
368
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000369}
370
371llvm::GlobalVariable *
Anders Carlssonaf440352010-03-23 04:11:45 +0000372CodeGenVTables::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
373 bool GenerateDefinition,
374 const CXXRecordDecl *RD) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000375 // Only classes that have virtual bases need a VTT.
376 if (RD->getNumVBases() == 0)
377 return 0;
378
379 llvm::SmallString<256> OutName;
380 CGM.getMangleContext().mangleCXXVTT(RD, OutName);
381 llvm::StringRef Name = OutName.str();
382
383 D1(printf("vtt %s\n", RD->getNameAsCString()));
384
385 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
386 if (GV == 0 || GV->isDeclaration()) {
387 const llvm::Type *Int8PtrTy =
388 llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
389
Anders Carlsson19f191f2010-03-26 04:10:39 +0000390 VTTBuilder Builder(CGM, RD, GenerateDefinition);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000391
Anders Carlsson19f191f2010-03-26 04:10:39 +0000392 const llvm::ArrayType *Type =
393 llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
394
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000395 llvm::Constant *Init = 0;
396 if (GenerateDefinition)
Anders Carlsson19f191f2010-03-26 04:10:39 +0000397 Init = llvm::ConstantArray::get(Type, Builder.getVTTComponents().data(),
398 Builder.getVTTComponents().size());
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000399
400 llvm::GlobalVariable *OldGV = GV;
401 GV = new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true,
402 Linkage, Init, Name);
403 CGM.setGlobalVisibility(GV, RD);
404
405 if (OldGV) {
406 GV->takeName(OldGV);
407 llvm::Constant *NewPtr =
408 llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
409 OldGV->replaceAllUsesWith(NewPtr);
410 OldGV->eraseFromParent();
411 }
412 }
413
414 return GV;
415}
416
Anders Carlssonaf440352010-03-23 04:11:45 +0000417llvm::GlobalVariable *CodeGenVTables::getVTT(const CXXRecordDecl *RD) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000418 return GenerateVTT(llvm::GlobalValue::ExternalLinkage,
419 /*GenerateDefinition=*/false, RD);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000420}
421
Anders Carlssonaf440352010-03-23 04:11:45 +0000422bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000423 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
424
425 // We don't have any virtual bases, just return early.
426 if (!MD->getParent()->getNumVBases())
427 return false;
428
429 // Check if we have a base constructor.
430 if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
431 return true;
432
433 // Check if we have a base destructor.
434 if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
435 return true;
436
437 return false;
438}
439
Anders Carlssonaf440352010-03-23 04:11:45 +0000440uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD,
441 const CXXRecordDecl *Base) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000442 ClassPairTy ClassPair(RD, Base);
443
Anders Carlssone1dcc222010-03-26 04:23:58 +0000444 SubVTTIndiciesMapTy::iterator I = SubVTTIndicies.find(ClassPair);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000445 if (I != SubVTTIndicies.end())
446 return I->second;
447
Anders Carlsson19f191f2010-03-26 04:10:39 +0000448 VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000449
Anders Carlssone1dcc222010-03-26 04:23:58 +0000450 for (llvm::DenseMap<const CXXRecordDecl *, uint64_t>::const_iterator I =
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000451 Builder.getSubVTTIndicies().begin(),
452 E = Builder.getSubVTTIndicies().end(); I != E; ++I) {
453 // Insert all indices.
454 ClassPairTy ClassPair(RD, I->first);
455
456 SubVTTIndicies.insert(std::make_pair(ClassPair, I->second));
457 }
458
459 I = SubVTTIndicies.find(ClassPair);
460 assert(I != SubVTTIndicies.end() && "Did not find index!");
461
462 return I->second;
463}
Anders Carlssone1dcc222010-03-26 04:23:58 +0000464
465uint64_t
466CodeGenVTables::getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
467 BaseSubobject Base) {
468 SecondaryVirtualPointerIndicesMapTy::iterator I =
469 SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
470
471 if (I != SecondaryVirtualPointerIndices.end())
472 return I->second;
473
474 VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
475
476 // Insert all secondary vpointer indices.
477 for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
478 Builder.getSecondaryVirtualPointerIndices().begin(),
479 E = Builder.getSecondaryVirtualPointerIndices().end(); I != E; ++I) {
480 std::pair<const CXXRecordDecl *, BaseSubobject> Pair =
481 std::make_pair(RD, I->first);
482
483 SecondaryVirtualPointerIndices.insert(std::make_pair(Pair, I->second));
484 }
485
486 I = SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
487 assert(I != SecondaryVirtualPointerIndices.end() && "Did not find index!");
488
489 return I->second;
490}
491