1 //===--- 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"
16 using namespace clang;
17 using namespace CodeGen;
18 
19 #define D1(x)
20 
21 namespace {
22 
23 /// VTT builder - Class for building VTT layout information.
24 class VTTBuilder {
25 
26   CodeGenModule &CGM;
27 
28   /// MostDerivedClass - The most derived class for which we're building this
29   /// vtable.
30   const CXXRecordDecl *MostDerivedClass;
31 
32   typedef llvm::SmallVector<llvm::Constant *, 64> VTTComponentsVectorTy;
33 
34   /// VTTComponents - The VTT components.
35   VTTComponentsVectorTy VTTComponents;
36 
37   /// MostDerivedClassLayout - the AST record layout of the most derived class.
38   const ASTRecordLayout &MostDerivedClassLayout;
39 
40   typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
41 
42   typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
43 
44   /// SubVTTIndicies - The sub-VTT indices for the bases of the most derived
45   /// class.
46   llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
47 
48   /// SecondaryVirtualPointerIndices - The secondary virtual pointer indices of
49   /// all subobjects of the most derived class.
50   llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
51 
52   /// GenerateDefinition - Whether the VTT builder should generate LLVM IR for
53   /// the VTT.
54   bool GenerateDefinition;
55 
56   /// 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 
72   /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base
73   /// subobject.
74   void LayoutSecondaryVTTs(BaseSubobject Base);
75 
76   /// 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 
100   /// 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 
109 public:
110   VTTBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerivedClass,
111              bool GenerateDefinition);
112 
113   // getVTTComponents - Returns a reference to the VTT components.
114   const VTTComponentsVectorTy &getVTTComponents() const {
115     return VTTComponents;
116   }
117 
118   /// getSubVTTIndicies - Returns a reference to the sub-VTT indices.
119   const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
120     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 
130 };
131 
132 VTTBuilder::VTTBuilder(CodeGenModule &CGM,
133                        const CXXRecordDecl *MostDerivedClass,
134                        bool GenerateDefinition)
135   : CGM(CGM), MostDerivedClass(MostDerivedClass),
136   MostDerivedClassLayout(CGM.getContext().getASTRecordLayout(MostDerivedClass)),
137   GenerateDefinition(GenerateDefinition) {
138 
139   // Lay out this VTT.
140   LayoutVTT(BaseSubobject(MostDerivedClass, 0), /*BaseIsVirtual=*/false);
141 }
142 
143 llvm::Constant *
144 VTTBuilder::GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
145                             AddressPointsMapTy& AddressPoints) {
146   if (!GenerateDefinition)
147     return 0;
148 
149   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 
161 void VTTBuilder::AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
162                                   const CXXRecordDecl *VTableClass,
163                                   const AddressPointsMapTy& AddressPoints) {
164   // Store the vtable pointer index if we're generating the primary VTT.
165   if (VTableClass == MostDerivedClass) {
166     assert(!SecondaryVirtualPointerIndices.count(Base) &&
167            "A virtual pointer index already exists for this base subobject!");
168     SecondaryVirtualPointerIndices[Base] = VTTComponents.size();
169   }
170 
171   if (!GenerateDefinition) {
172     VTTComponents.push_back(0);
173     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);
181     assert(AddressPoint != 0 && "Did not find ctor vtable address point!");
182   } else {
183     // Just get the address point for the regular vtable.
184     AddressPoint = CGM.getVTables().getAddressPoint(Base, VTableClass);
185     assert(AddressPoint != 0 && "Did not find vtable address point!");
186   }
187 
188   if (!AddressPoint) AddressPoint = 0;
189 
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 
202   VTTComponents.push_back(Init);
203 }
204 
205 void 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 
227 void
228 VTTBuilder::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 
295 void
296 VTTBuilder::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 
304 void 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 
317       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 
330 void 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;
338 
339   bool IsPrimaryVTT = Base.getBase() == MostDerivedClass;
340 
341   if (!IsPrimaryVTT) {
342     // Remember the sub-VTT index.
343     SubVTTIndicies[Base] = VTTComponents.size();
344   }
345 
346   AddressPointsMapTy AddressPoints;
347   llvm::Constant *VTable = GetAddrOfVTable(Base, BaseIsVirtual, AddressPoints);
348 
349   // Add the primary vtable pointer.
350   AddVTablePointer(Base, VTable, RD, AddressPoints);
351 
352   // Add the secondary VTTs.
353   LayoutSecondaryVTTs(Base);
354 
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.
359   if (IsPrimaryVTT) {
360     VisitedVirtualBasesSetTy VBases;
361     LayoutVirtualVTTs(Base.getBase(), VBases);
362   }
363 }
364 
365 }
366 
367 llvm::GlobalVariable *
368 CodeGenVTables::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
369                             bool GenerateDefinition,
370                             const CXXRecordDecl *RD) {
371   // 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 
381   llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
382   if (GV == 0 || GV->isDeclaration()) {
383     const llvm::Type *Int8PtrTy =
384       llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
385 
386     VTTBuilder Builder(CGM, RD, GenerateDefinition);
387 
388     const llvm::ArrayType *Type =
389       llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
390 
391     llvm::Constant *Init = 0;
392     if (GenerateDefinition)
393       Init = llvm::ConstantArray::get(Type, Builder.getVTTComponents().data(),
394                                       Builder.getVTTComponents().size());
395 
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 
413 llvm::GlobalVariable *CodeGenVTables::getVTT(const CXXRecordDecl *RD) {
414   return GenerateVTT(llvm::GlobalValue::ExternalLinkage,
415                      /*GenerateDefinition=*/false, RD);
416 }
417 
418 bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) {
419   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 
436 uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD,
437                                         BaseSubobject Base) {
438   BaseSubobjectPairTy ClassSubobjectPair(RD, Base);
439 
440   SubVTTIndiciesMapTy::iterator I = SubVTTIndicies.find(ClassSubobjectPair);
441   if (I != SubVTTIndicies.end())
442     return I->second;
443 
444   VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
445 
446   for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
447        Builder.getSubVTTIndicies().begin(),
448        E = Builder.getSubVTTIndicies().end(); I != E; ++I) {
449     // Insert all indices.
450     BaseSubobjectPairTy ClassSubobjectPair(RD, I->first);
451 
452     SubVTTIndicies.insert(std::make_pair(ClassSubobjectPair, I->second));
453   }
454 
455   I = SubVTTIndicies.find(ClassSubobjectPair);
456   assert(I != SubVTTIndicies.end() && "Did not find index!");
457 
458   return I->second;
459 }
460 
461 uint64_t
462 CodeGenVTables::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 
488