blob: 61c74230e1183fa9c901ff84a6da09b67c9a648a [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 Carlsson9f17d412010-03-26 00:50:17 +000040 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
41
Anders Carlsson2c822f12010-03-26 03:56:54 +000042 typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
43
Anders Carlsson19f191f2010-03-26 04:10:39 +000044 /// SubVTTIndicies - The sub-VTT indices for the bases of the most derived
Anders Carlssone1dcc222010-03-26 04:23:58 +000045 /// class.
Anders Carlsson3855a072010-05-03 00:55:11 +000046 llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
Anders Carlssone1dcc222010-03-26 04:23:58 +000047
48 /// SecondaryVirtualPointerIndices - The secondary virtual pointer indices of
49 /// all subobjects of the most derived class.
50 llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
51
Anders Carlsson19f191f2010-03-26 04:10:39 +000052 /// GenerateDefinition - Whether the VTT builder should generate LLVM IR for
53 /// the VTT.
Anders Carlsson58b7eee2010-01-21 16:50:45 +000054 bool GenerateDefinition;
Anders Carlsson58b7eee2010-01-21 16:50:45 +000055
Anders Carlsson2c822f12010-03-26 03:56:54 +000056 /// GetAddrOfVTable - Returns the address of the vtable for the base class in
57 /// the given vtable class.
58 ///
59 /// \param AddressPoints - If the returned vtable is a construction vtable,
60 /// this will hold the address points for it.
61 llvm::Constant *GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
62 AddressPointsMapTy& AddressPoints);
63
64 /// AddVTablePointer - Add a vtable pointer to the VTT currently being built.
65 ///
66 /// \param AddressPoints - If the vtable is a construction vtable, this has
67 /// the address points for it.
68 void AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
69 const CXXRecordDecl *VTableClass,
70 const AddressPointsMapTy& AddressPoints);
71
Anders Carlssonc1246c82010-03-26 00:35:45 +000072 /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base
73 /// subobject.
74 void LayoutSecondaryVTTs(BaseSubobject Base);
75
Anders Carlsson2c822f12010-03-26 03:56:54 +000076 /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
77 /// for the given base subobject.
78 ///
79 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
80 /// or a direct or indirect base of a virtual base.
81 ///
82 /// \param AddressPoints - If the vtable is a construction vtable, this has
83 /// the address points for it.
84 void LayoutSecondaryVirtualPointers(BaseSubobject Base,
85 bool BaseIsMorallyVirtual,
86 llvm::Constant *VTable,
87 const CXXRecordDecl *VTableClass,
88 const AddressPointsMapTy& AddressPoints,
89 VisitedVirtualBasesSetTy &VBases);
90
91 /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
92 /// for the given base subobject.
93 ///
94 /// \param AddressPoints - If the vtable is a construction vtable, this has
95 /// the address points for it.
96 void LayoutSecondaryVirtualPointers(BaseSubobject Base,
97 llvm::Constant *VTable,
98 const AddressPointsMapTy& AddressPoints);
99
Anders Carlsson9f17d412010-03-26 00:50:17 +0000100 /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the
101 /// given record decl.
102 void LayoutVirtualVTTs(const CXXRecordDecl *RD,
103 VisitedVirtualBasesSetTy &VBases);
104
105 /// LayoutVTT - Will lay out the VTT for the given subobject, including any
106 /// secondary VTTs, secondary virtual pointers and virtual VTTs.
107 void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
108
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000109public:
Anders Carlsson19f191f2010-03-26 04:10:39 +0000110 VTTBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerivedClass,
111 bool GenerateDefinition);
Anders Carlssone1dcc222010-03-26 04:23:58 +0000112
Anders Carlsson19f191f2010-03-26 04:10:39 +0000113 // getVTTComponents - Returns a reference to the VTT components.
114 const VTTComponentsVectorTy &getVTTComponents() const {
115 return VTTComponents;
116 }
Anders Carlssone1dcc222010-03-26 04:23:58 +0000117
118 /// getSubVTTIndicies - Returns a reference to the sub-VTT indices.
Anders Carlsson3855a072010-05-03 00:55:11 +0000119 const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
Anders Carlssone1dcc222010-03-26 04:23:58 +0000120 return SubVTTIndicies;
121 }
122
123 /// getSecondaryVirtualPointerIndices - Returns a reference to the secondary
124 /// virtual pointer indices.
125 const llvm::DenseMap<BaseSubobject, uint64_t> &
126 getSecondaryVirtualPointerIndices() const {
127 return SecondaryVirtualPointerIndices;
128 }
129
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000130};
Anders Carlsson2c822f12010-03-26 03:56:54 +0000131
Anders Carlsson19f191f2010-03-26 04:10:39 +0000132VTTBuilder::VTTBuilder(CodeGenModule &CGM,
133 const CXXRecordDecl *MostDerivedClass,
134 bool GenerateDefinition)
135 : CGM(CGM), MostDerivedClass(MostDerivedClass),
136 MostDerivedClassLayout(CGM.getContext().getASTRecordLayout(MostDerivedClass)),
Anders Carlsson19f191f2010-03-26 04:10:39 +0000137 GenerateDefinition(GenerateDefinition) {
138
139 // Lay out this VTT.
140 LayoutVTT(BaseSubobject(MostDerivedClass, 0), /*BaseIsVirtual=*/false);
141}
142
Anders Carlsson2c822f12010-03-26 03:56:54 +0000143llvm::Constant *
144VTTBuilder::GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
145 AddressPointsMapTy& AddressPoints) {
146 if (!GenerateDefinition)
147 return 0;
Anders Carlssonc1246c82010-03-26 00:35:45 +0000148
Anders Carlsson2c822f12010-03-26 03:56:54 +0000149 if (Base.getBase() == MostDerivedClass) {
150 assert(Base.getBaseOffset() == 0 &&
151 "Most derived class vtable must have a zero offset!");
152 // This is a regular vtable.
153 return CGM.getVTables().GetAddrOfVTable(MostDerivedClass);
154 }
155
156 return CGM.getVTables().GenerateConstructionVTable(MostDerivedClass,
157 Base, BaseIsVirtual,
158 AddressPoints);
159}
160
161void VTTBuilder::AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
162 const CXXRecordDecl *VTableClass,
163 const AddressPointsMapTy& AddressPoints) {
Anders Carlssonf6da6a02010-03-29 01:04:16 +0000164 // Store the vtable pointer index if we're generating the primary VTT.
Anders Carlsson80faf692010-03-29 01:12:13 +0000165 if (VTableClass == MostDerivedClass) {
Anders Carlssonf6da6a02010-03-29 01:04:16 +0000166 assert(!SecondaryVirtualPointerIndices.count(Base) &&
167 "A virtual pointer index already exists for this base subobject!");
168 SecondaryVirtualPointerIndices[Base] = VTTComponents.size();
169 }
170
Anders Carlsson2c822f12010-03-26 03:56:54 +0000171 if (!GenerateDefinition) {
Anders Carlsson19f191f2010-03-26 04:10:39 +0000172 VTTComponents.push_back(0);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000173 return;
174 }
175
176 uint64_t AddressPoint;
177 if (VTableClass != MostDerivedClass) {
178 // The vtable is a construction vtable, look in the construction vtable
179 // address points.
180 AddressPoint = AddressPoints.lookup(Base);
Anders Carlsson836d9dd2010-04-11 20:23:06 +0000181 assert(AddressPoint != 0 && "Did not find ctor vtable address point!");
Anders Carlsson2c822f12010-03-26 03:56:54 +0000182 } else {
Anders Carlsson0a4a2fd2010-03-29 02:14:35 +0000183 // Just get the address point for the regular vtable.
184 AddressPoint = CGM.getVTables().getAddressPoint(Base, VTableClass);
Anders Carlsson836d9dd2010-04-11 20:23:06 +0000185 assert(AddressPoint != 0 && "Did not find vtable address point!");
Anders Carlsson2c822f12010-03-26 03:56:54 +0000186 }
187
188 if (!AddressPoint) AddressPoint = 0;
Anders Carlsson2c822f12010-03-26 03:56:54 +0000189
190 llvm::Value *Idxs[] = {
191 llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0),
192 llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()),
193 AddressPoint)
194 };
195
196 llvm::Constant *Init =
197 llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Idxs, 2);
198
199 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
200 Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
201
Anders Carlsson19f191f2010-03-26 04:10:39 +0000202 VTTComponents.push_back(Init);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000203}
204
Anders Carlssonc1246c82010-03-26 00:35:45 +0000205void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
206 const CXXRecordDecl *RD = Base.getBase();
207
208 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
209 E = RD->bases_end(); I != E; ++I) {
210
211 // Don't layout virtual bases.
212 if (I->isVirtual())
213 continue;
214
215 const CXXRecordDecl *BaseDecl =
216 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
217
218 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
219 uint64_t BaseOffset = Base.getBaseOffset() +
220 Layout.getBaseClassOffset(BaseDecl);
221
222 // Layout the VTT for this base.
223 LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false);
224 }
225}
226
Anders Carlsson2c822f12010-03-26 03:56:54 +0000227void
228VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
229 bool BaseIsMorallyVirtual,
230 llvm::Constant *VTable,
231 const CXXRecordDecl *VTableClass,
232 const AddressPointsMapTy& AddressPoints,
233 VisitedVirtualBasesSetTy &VBases) {
234 const CXXRecordDecl *RD = Base.getBase();
235
236 // We're not interested in bases that don't have virtual bases, and not
237 // morally virtual bases.
238 if (!RD->getNumVBases() && !BaseIsMorallyVirtual)
239 return;
240
241 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
242 E = RD->bases_end(); I != E; ++I) {
243 const CXXRecordDecl *BaseDecl =
244 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
245
246 // Itanium C++ ABI 2.6.2:
247 // Secondary virtual pointers are present for all bases with either
248 // virtual bases or virtual function declarations overridden along a
249 // virtual path.
250 //
251 // If the base class is not dynamic, we don't want to add it, nor any
252 // of its base classes.
253 if (!BaseDecl->isDynamicClass())
254 continue;
255
256 bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual;
257 bool BaseDeclIsNonVirtualPrimaryBase = false;
258 uint64_t BaseOffset;
259 if (I->isVirtual()) {
260 // Ignore virtual bases that we've already visited.
261 if (!VBases.insert(BaseDecl))
262 continue;
263
264 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
265 BaseDeclIsMorallyVirtual = true;
266 } else {
267 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
268
269 BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl);
270
271 if (!Layout.getPrimaryBaseWasVirtual() &&
272 Layout.getPrimaryBase() == BaseDecl)
273 BaseDeclIsNonVirtualPrimaryBase = true;
274 }
275
276 // Itanium C++ ABI 2.6.2:
277 // Secondary virtual pointers: for each base class X which (a) has virtual
278 // bases or is reachable along a virtual path from D, and (b) is not a
279 // non-virtual primary base, the address of the virtual table for X-in-D
280 // or an appropriate construction virtual table.
281 if (!BaseDeclIsNonVirtualPrimaryBase &&
282 (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) {
283 // Add the vtable pointer.
284 AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTable, VTableClass,
285 AddressPoints);
286 }
287
288 // And lay out the secondary virtual pointers for the base class.
289 LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset),
290 BaseDeclIsMorallyVirtual, VTable,
291 VTableClass, AddressPoints, VBases);
292 }
293}
294
295void
296VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
297 llvm::Constant *VTable,
298 const AddressPointsMapTy& AddressPoints) {
299 VisitedVirtualBasesSetTy VBases;
300 LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false,
301 VTable, Base.getBase(), AddressPoints, VBases);
302}
303
Anders Carlsson9f17d412010-03-26 00:50:17 +0000304void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
305 VisitedVirtualBasesSetTy &VBases) {
306 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
307 E = RD->bases_end(); I != E; ++I) {
308 const CXXRecordDecl *BaseDecl =
309 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
310
311 // Check if this is a virtual base.
312 if (I->isVirtual()) {
313 // Check if we've seen this base before.
314 if (!VBases.insert(BaseDecl))
315 continue;
316
Anders Carlsson9f17d412010-03-26 00:50:17 +0000317 uint64_t BaseOffset =
318 MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
319
320 LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true);
321 }
322
323 // We only need to layout virtual VTTs for this base if it actually has
324 // virtual bases.
325 if (BaseDecl->getNumVBases())
326 LayoutVirtualVTTs(BaseDecl, VBases);
327 }
328}
329
Anders Carlssonc1246c82010-03-26 00:35:45 +0000330void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) {
331 const CXXRecordDecl *RD = Base.getBase();
332
333 // Itanium C++ ABI 2.6.2:
334 // An array of virtual table addresses, called the VTT, is declared for
335 // each class type that has indirect or direct virtual base classes.
336 if (RD->getNumVBases() == 0)
337 return;
Anders Carlsson19f191f2010-03-26 04:10:39 +0000338
339 bool IsPrimaryVTT = Base.getBase() == MostDerivedClass;
340
341 if (!IsPrimaryVTT) {
342 // Remember the sub-VTT index.
Anders Carlsson3855a072010-05-03 00:55:11 +0000343 SubVTTIndicies[Base] = VTTComponents.size();
Anders Carlsson19f191f2010-03-26 04:10:39 +0000344 }
Anders Carlssonc1246c82010-03-26 00:35:45 +0000345
Anders Carlsson2c822f12010-03-26 03:56:54 +0000346 AddressPointsMapTy AddressPoints;
347 llvm::Constant *VTable = GetAddrOfVTable(Base, BaseIsVirtual, AddressPoints);
Anders Carlssonc1246c82010-03-26 00:35:45 +0000348
Anders Carlsson2c822f12010-03-26 03:56:54 +0000349 // Add the primary vtable pointer.
350 AddVTablePointer(Base, VTable, RD, AddressPoints);
Anders Carlssonc1246c82010-03-26 00:35:45 +0000351
Anders Carlsson2c822f12010-03-26 03:56:54 +0000352 // Add the secondary VTTs.
Anders Carlssonc1246c82010-03-26 00:35:45 +0000353 LayoutSecondaryVTTs(Base);
Anders Carlsson2c822f12010-03-26 03:56:54 +0000354
355 // Add the secondary virtual pointers.
356 LayoutSecondaryVirtualPointers(Base, VTable, AddressPoints);
357
358 // If this is the primary VTT, we want to lay out virtual VTTs as well.
Anders Carlsson19f191f2010-03-26 04:10:39 +0000359 if (IsPrimaryVTT) {
Anders Carlsson2c822f12010-03-26 03:56:54 +0000360 VisitedVirtualBasesSetTy VBases;
361 LayoutVirtualVTTs(Base.getBase(), VBases);
362 }
Anders Carlssonc1246c82010-03-26 00:35:45 +0000363}
364
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000365}
366
367llvm::GlobalVariable *
Anders Carlssonaf440352010-03-23 04:11:45 +0000368CodeGenVTables::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
369 bool GenerateDefinition,
370 const CXXRecordDecl *RD) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000371 // Only classes that have virtual bases need a VTT.
372 if (RD->getNumVBases() == 0)
373 return 0;
374
375 llvm::SmallString<256> OutName;
376 CGM.getMangleContext().mangleCXXVTT(RD, OutName);
377 llvm::StringRef Name = OutName.str();
378
379 D1(printf("vtt %s\n", RD->getNameAsCString()));
380
Douglas Gregorf4aac112010-05-06 22:18:21 +0000381 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000382 if (GV == 0 || GV->isDeclaration()) {
383 const llvm::Type *Int8PtrTy =
384 llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
385
Anders Carlsson19f191f2010-03-26 04:10:39 +0000386 VTTBuilder Builder(CGM, RD, GenerateDefinition);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000387
Anders Carlsson19f191f2010-03-26 04:10:39 +0000388 const llvm::ArrayType *Type =
389 llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
390
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000391 llvm::Constant *Init = 0;
392 if (GenerateDefinition)
Anders Carlsson19f191f2010-03-26 04:10:39 +0000393 Init = llvm::ConstantArray::get(Type, Builder.getVTTComponents().data(),
394 Builder.getVTTComponents().size());
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000395
396 llvm::GlobalVariable *OldGV = GV;
397 GV = new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true,
398 Linkage, Init, Name);
399 CGM.setGlobalVisibility(GV, RD);
400
401 if (OldGV) {
402 GV->takeName(OldGV);
403 llvm::Constant *NewPtr =
404 llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
405 OldGV->replaceAllUsesWith(NewPtr);
406 OldGV->eraseFromParent();
407 }
408 }
409
410 return GV;
411}
412
Anders Carlssonaf440352010-03-23 04:11:45 +0000413llvm::GlobalVariable *CodeGenVTables::getVTT(const CXXRecordDecl *RD) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000414 return GenerateVTT(llvm::GlobalValue::ExternalLinkage,
415 /*GenerateDefinition=*/false, RD);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000416}
417
Anders Carlssonaf440352010-03-23 04:11:45 +0000418bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) {
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000419 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
420
421 // We don't have any virtual bases, just return early.
422 if (!MD->getParent()->getNumVBases())
423 return false;
424
425 // Check if we have a base constructor.
426 if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
427 return true;
428
429 // Check if we have a base destructor.
430 if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
431 return true;
432
433 return false;
434}
435
Anders Carlssonaf440352010-03-23 04:11:45 +0000436uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD,
Anders Carlssonc11bb212010-05-02 23:53:25 +0000437 BaseSubobject Base) {
Anders Carlsson3855a072010-05-03 00:55:11 +0000438 BaseSubobjectPairTy ClassSubobjectPair(RD, Base);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000439
Anders Carlsson3855a072010-05-03 00:55:11 +0000440 SubVTTIndiciesMapTy::iterator I = SubVTTIndicies.find(ClassSubobjectPair);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000441 if (I != SubVTTIndicies.end())
442 return I->second;
443
Anders Carlsson19f191f2010-03-26 04:10:39 +0000444 VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000445
Anders Carlsson3855a072010-05-03 00:55:11 +0000446 for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000447 Builder.getSubVTTIndicies().begin(),
448 E = Builder.getSubVTTIndicies().end(); I != E; ++I) {
449 // Insert all indices.
Anders Carlsson3855a072010-05-03 00:55:11 +0000450 BaseSubobjectPairTy ClassSubobjectPair(RD, I->first);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000451
Anders Carlsson3855a072010-05-03 00:55:11 +0000452 SubVTTIndicies.insert(std::make_pair(ClassSubobjectPair, I->second));
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000453 }
454
Anders Carlsson3855a072010-05-03 00:55:11 +0000455 I = SubVTTIndicies.find(ClassSubobjectPair);
Anders Carlsson58b7eee2010-01-21 16:50:45 +0000456 assert(I != SubVTTIndicies.end() && "Did not find index!");
457
458 return I->second;
459}
Anders Carlssone1dcc222010-03-26 04:23:58 +0000460
461uint64_t
462CodeGenVTables::getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
463 BaseSubobject Base) {
464 SecondaryVirtualPointerIndicesMapTy::iterator I =
465 SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
466
467 if (I != SecondaryVirtualPointerIndices.end())
468 return I->second;
469
470 VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
471
472 // Insert all secondary vpointer indices.
473 for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
474 Builder.getSecondaryVirtualPointerIndices().begin(),
475 E = Builder.getSecondaryVirtualPointerIndices().end(); I != E; ++I) {
476 std::pair<const CXXRecordDecl *, BaseSubobject> Pair =
477 std::make_pair(RD, I->first);
478
479 SecondaryVirtualPointerIndices.insert(std::make_pair(Pair, I->second));
480 }
481
482 I = SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
483 assert(I != SecondaryVirtualPointerIndices.end() && "Did not find index!");
484
485 return I->second;
486}
487