blob: cdc8133c12550c8dc24f3d40e629942c755cb775 [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.
Anders Carlsson80faf692010-03-29 01:12:13 +0000169 if (VTableClass == MostDerivedClass) {
Anders Carlssonf6da6a02010-03-29 01:04:16 +0000170 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 {
Anders Carlsson0a4a2fd2010-03-29 02:14:35 +0000186 // Just get the address point for the regular vtable.
187 AddressPoint = CGM.getVTables().getAddressPoint(Base, VTableClass);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000188 }
189
190 if (!AddressPoint) AddressPoint = 0;
191 assert(AddressPoint != 0 && "Did not find an address point!");
192
193 llvm::Value *Idxs[] = {
194 llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0),
195 llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()),
196 AddressPoint)
197 };
198
199 llvm::Constant *Init =
200 llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Idxs, 2);
201
202 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
203 Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
204
Anders Carlsson19f191f2010-03-26 04:10:39 +0000205 VTTComponents.push_back(Init);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000206}
207
Anders Carlssonc1246c82010-03-26 00:35:45 +0000208void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
209 const CXXRecordDecl *RD = Base.getBase();
210
211 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
212 E = RD->bases_end(); I != E; ++I) {
213
214 // Don't layout virtual bases.
215 if (I->isVirtual())
216 continue;
217
218 const CXXRecordDecl *BaseDecl =
219 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
220
221 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
222 uint64_t BaseOffset = Base.getBaseOffset() +
223 Layout.getBaseClassOffset(BaseDecl);
224
225 // Layout the VTT for this base.
226 LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false);
227 }
228}
229
Anders Carlsson2c822f12010-03-26 03:56:54 +0000230void
231VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
232 bool BaseIsMorallyVirtual,
233 llvm::Constant *VTable,
234 const CXXRecordDecl *VTableClass,
235 const AddressPointsMapTy& AddressPoints,
236 VisitedVirtualBasesSetTy &VBases) {
237 const CXXRecordDecl *RD = Base.getBase();
238
239 // We're not interested in bases that don't have virtual bases, and not
240 // morally virtual bases.
241 if (!RD->getNumVBases() && !BaseIsMorallyVirtual)
242 return;
243
244 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
245 E = RD->bases_end(); I != E; ++I) {
246 const CXXRecordDecl *BaseDecl =
247 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
248
249 // Itanium C++ ABI 2.6.2:
250 // Secondary virtual pointers are present for all bases with either
251 // virtual bases or virtual function declarations overridden along a
252 // virtual path.
253 //
254 // If the base class is not dynamic, we don't want to add it, nor any
255 // of its base classes.
256 if (!BaseDecl->isDynamicClass())
257 continue;
258
259 bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual;
260 bool BaseDeclIsNonVirtualPrimaryBase = false;
261 uint64_t BaseOffset;
262 if (I->isVirtual()) {
263 // Ignore virtual bases that we've already visited.
264 if (!VBases.insert(BaseDecl))
265 continue;
266
267 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
268 BaseDeclIsMorallyVirtual = true;
269 } else {
270 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
271
272 BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl);
273
274 if (!Layout.getPrimaryBaseWasVirtual() &&
275 Layout.getPrimaryBase() == BaseDecl)
276 BaseDeclIsNonVirtualPrimaryBase = true;
277 }
278
279 // Itanium C++ ABI 2.6.2:
280 // Secondary virtual pointers: for each base class X which (a) has virtual
281 // bases or is reachable along a virtual path from D, and (b) is not a
282 // non-virtual primary base, the address of the virtual table for X-in-D
283 // or an appropriate construction virtual table.
284 if (!BaseDeclIsNonVirtualPrimaryBase &&
285 (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) {
286 // Add the vtable pointer.
287 AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTable, VTableClass,
288 AddressPoints);
289 }
290
291 // And lay out the secondary virtual pointers for the base class.
292 LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset),
293 BaseDeclIsMorallyVirtual, VTable,
294 VTableClass, AddressPoints, VBases);
295 }
296}
297
298void
299VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
300 llvm::Constant *VTable,
301 const AddressPointsMapTy& AddressPoints) {
302 VisitedVirtualBasesSetTy VBases;
303 LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false,
304 VTable, Base.getBase(), AddressPoints, VBases);
305}
306
Anders Carlsson9f17d412010-03-26 00:50:17 +0000307void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
308 VisitedVirtualBasesSetTy &VBases) {
309 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
310 E = RD->bases_end(); I != E; ++I) {
311 const CXXRecordDecl *BaseDecl =
312 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
313
314 // Check if this is a virtual base.
315 if (I->isVirtual()) {
316 // Check if we've seen this base before.
317 if (!VBases.insert(BaseDecl))
318 continue;
319
Anders Carlsson9f17d412010-03-26 00:50:17 +0000320 uint64_t BaseOffset =
321 MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
322
323 LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true);
324 }
325
326 // We only need to layout virtual VTTs for this base if it actually has
327 // virtual bases.
328 if (BaseDecl->getNumVBases())
329 LayoutVirtualVTTs(BaseDecl, VBases);
330 }
331}
332
Anders Carlssonc1246c82010-03-26 00:35:45 +0000333void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) {
334 const CXXRecordDecl *RD = Base.getBase();
335
336 // Itanium C++ ABI 2.6.2:
337 // An array of virtual table addresses, called the VTT, is declared for
338 // each class type that has indirect or direct virtual base classes.
339 if (RD->getNumVBases() == 0)
340 return;
Anders Carlsson19f191f2010-03-26 04:10:39 +0000341
342 bool IsPrimaryVTT = Base.getBase() == MostDerivedClass;
343
344 if (!IsPrimaryVTT) {
345 // Remember the sub-VTT index.
346 SubVTTIndicies[RD] = VTTComponents.size();
347 }
Anders Carlssonc1246c82010-03-26 00:35:45 +0000348
Anders Carlsson2c822f12010-03-26 03:56:54 +0000349 AddressPointsMapTy AddressPoints;
350 llvm::Constant *VTable = GetAddrOfVTable(Base, BaseIsVirtual, AddressPoints);
Anders Carlssonc1246c82010-03-26 00:35:45 +0000351
Anders Carlsson2c822f12010-03-26 03:56:54 +0000352 // Add the primary vtable pointer.
353 AddVTablePointer(Base, VTable, RD, AddressPoints);
Anders Carlssonc1246c82010-03-26 00:35:45 +0000354
Anders Carlsson2c822f12010-03-26 03:56:54 +0000355 // Add the secondary VTTs.
Anders Carlssonc1246c82010-03-26 00:35:45 +0000356 LayoutSecondaryVTTs(Base);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000357
358 // Add the secondary virtual pointers.
359 LayoutSecondaryVirtualPointers(Base, VTable, AddressPoints);
360
361 // If this is the primary VTT, we want to lay out virtual VTTs as well.
Anders Carlsson19f191f2010-03-26 04:10:39 +0000362 if (IsPrimaryVTT) {
Anders Carlsson2c822f12010-03-26 03:56:54 +0000363 VisitedVirtualBasesSetTy VBases;
364 LayoutVirtualVTTs(Base.getBase(), VBases);
365 }
Anders Carlssonc1246c82010-03-26 00:35:45 +0000366}
367
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000368}
369
370llvm::GlobalVariable *
Anders Carlssonaf440352010-03-23 04:11:45 +0000371CodeGenVTables::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
372 bool GenerateDefinition,
373 const CXXRecordDecl *RD) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000374 // Only classes that have virtual bases need a VTT.
375 if (RD->getNumVBases() == 0)
376 return 0;
377
378 llvm::SmallString<256> OutName;
379 CGM.getMangleContext().mangleCXXVTT(RD, OutName);
380 llvm::StringRef Name = OutName.str();
381
382 D1(printf("vtt %s\n", RD->getNameAsCString()));
383
384 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
385 if (GV == 0 || GV->isDeclaration()) {
386 const llvm::Type *Int8PtrTy =
387 llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
388
Anders Carlsson19f191f2010-03-26 04:10:39 +0000389 VTTBuilder Builder(CGM, RD, GenerateDefinition);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000390
Anders Carlsson19f191f2010-03-26 04:10:39 +0000391 const llvm::ArrayType *Type =
392 llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
393
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000394 llvm::Constant *Init = 0;
395 if (GenerateDefinition)
Anders Carlsson19f191f2010-03-26 04:10:39 +0000396 Init = llvm::ConstantArray::get(Type, Builder.getVTTComponents().data(),
397 Builder.getVTTComponents().size());
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000398
399 llvm::GlobalVariable *OldGV = GV;
400 GV = new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true,
401 Linkage, Init, Name);
402 CGM.setGlobalVisibility(GV, RD);
403
404 if (OldGV) {
405 GV->takeName(OldGV);
406 llvm::Constant *NewPtr =
407 llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
408 OldGV->replaceAllUsesWith(NewPtr);
409 OldGV->eraseFromParent();
410 }
411 }
412
413 return GV;
414}
415
Anders Carlssonaf440352010-03-23 04:11:45 +0000416llvm::GlobalVariable *CodeGenVTables::getVTT(const CXXRecordDecl *RD) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000417 return GenerateVTT(llvm::GlobalValue::ExternalLinkage,
418 /*GenerateDefinition=*/false, RD);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000419}
420
Anders Carlssonaf440352010-03-23 04:11:45 +0000421bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000422 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
423
424 // We don't have any virtual bases, just return early.
425 if (!MD->getParent()->getNumVBases())
426 return false;
427
428 // Check if we have a base constructor.
429 if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
430 return true;
431
432 // Check if we have a base destructor.
433 if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
434 return true;
435
436 return false;
437}
438
Anders Carlssonaf440352010-03-23 04:11:45 +0000439uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD,
440 const CXXRecordDecl *Base) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000441 ClassPairTy ClassPair(RD, Base);
442
Anders Carlssone1dcc222010-03-26 04:23:58 +0000443 SubVTTIndiciesMapTy::iterator I = SubVTTIndicies.find(ClassPair);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000444 if (I != SubVTTIndicies.end())
445 return I->second;
446
Anders Carlsson19f191f2010-03-26 04:10:39 +0000447 VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000448
Anders Carlssone1dcc222010-03-26 04:23:58 +0000449 for (llvm::DenseMap<const CXXRecordDecl *, uint64_t>::const_iterator I =
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000450 Builder.getSubVTTIndicies().begin(),
451 E = Builder.getSubVTTIndicies().end(); I != E; ++I) {
452 // Insert all indices.
453 ClassPairTy ClassPair(RD, I->first);
454
455 SubVTTIndicies.insert(std::make_pair(ClassPair, I->second));
456 }
457
458 I = SubVTTIndicies.find(ClassPair);
459 assert(I != SubVTTIndicies.end() && "Did not find index!");
460
461 return I->second;
462}
Anders Carlssone1dcc222010-03-26 04:23:58 +0000463
464uint64_t
465CodeGenVTables::getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
466 BaseSubobject Base) {
467 SecondaryVirtualPointerIndicesMapTy::iterator I =
468 SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
469
470 if (I != SecondaryVirtualPointerIndices.end())
471 return I->second;
472
473 VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
474
475 // Insert all secondary vpointer indices.
476 for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
477 Builder.getSecondaryVirtualPointerIndices().begin(),
478 E = Builder.getSecondaryVirtualPointerIndices().end(); I != E; ++I) {
479 std::pair<const CXXRecordDecl *, BaseSubobject> Pair =
480 std::make_pair(RD, I->first);
481
482 SecondaryVirtualPointerIndices.insert(std::make_pair(Pair, I->second));
483 }
484
485 I = SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
486 assert(I != SecondaryVirtualPointerIndices.end() && "Did not find index!");
487
488 return I->second;
489}
490