• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "CGCXXABI.h"
16 #include "clang/AST/RecordLayout.h"
17 using namespace clang;
18 using namespace CodeGen;
19 
20 #define D1(x)
21 
22 namespace {
23 
24 /// VTT builder - Class for building VTT layout information.
25 class VTTBuilder {
26 
27   CodeGenModule &CGM;
28 
29   /// MostDerivedClass - The most derived class for which we're building this
30   /// vtable.
31   const CXXRecordDecl *MostDerivedClass;
32 
33   typedef llvm::SmallVector<llvm::Constant *, 64> VTTComponentsVectorTy;
34 
35   /// VTTComponents - The VTT components.
36   VTTComponentsVectorTy VTTComponents;
37 
38   /// MostDerivedClassLayout - the AST record layout of the most derived class.
39   const ASTRecordLayout &MostDerivedClassLayout;
40 
41   typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
42 
43   typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
44 
45   /// SubVTTIndicies - The sub-VTT indices for the bases of the most derived
46   /// class.
47   llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
48 
49   /// SecondaryVirtualPointerIndices - The secondary virtual pointer indices of
50   /// all subobjects of the most derived class.
51   llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
52 
53   /// GenerateDefinition - Whether the VTT builder should generate LLVM IR for
54   /// the VTT.
55   bool GenerateDefinition;
56 
57   /// The linkage to use for any construction vtables required by this VTT.
58   /// Only required if we're building a definition.
59   llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables;
60 
61   /// GetAddrOfVTable - Returns the address of the vtable for the base class in
62   /// the given vtable class.
63   ///
64   /// \param AddressPoints - If the returned vtable is a construction vtable,
65   /// this will hold the address points for it.
66   llvm::Constant *GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
67                                   AddressPointsMapTy& AddressPoints);
68 
69   /// AddVTablePointer - Add a vtable pointer to the VTT currently being built.
70   ///
71   /// \param AddressPoints - If the vtable is a construction vtable, this has
72   /// the address points for it.
73   void AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
74                         const CXXRecordDecl *VTableClass,
75                         const AddressPointsMapTy& AddressPoints);
76 
77   /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base
78   /// subobject.
79   void LayoutSecondaryVTTs(BaseSubobject Base);
80 
81   /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
82   /// for the given base subobject.
83   ///
84   /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
85   /// or a direct or indirect base of a virtual base.
86   ///
87   /// \param AddressPoints - If the vtable is a construction vtable, this has
88   /// the address points for it.
89   void LayoutSecondaryVirtualPointers(BaseSubobject Base,
90                                       bool BaseIsMorallyVirtual,
91                                       llvm::Constant *VTable,
92                                       const CXXRecordDecl *VTableClass,
93                                       const AddressPointsMapTy& AddressPoints,
94                                       VisitedVirtualBasesSetTy &VBases);
95 
96   /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
97   /// for the given base subobject.
98   ///
99   /// \param AddressPoints - If the vtable is a construction vtable, this has
100   /// the address points for it.
101   void LayoutSecondaryVirtualPointers(BaseSubobject Base,
102                                       llvm::Constant *VTable,
103                                       const AddressPointsMapTy& AddressPoints);
104 
105   /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the
106   /// given record decl.
107   void LayoutVirtualVTTs(const CXXRecordDecl *RD,
108                          VisitedVirtualBasesSetTy &VBases);
109 
110   /// LayoutVTT - Will lay out the VTT for the given subobject, including any
111   /// secondary VTTs, secondary virtual pointers and virtual VTTs.
112   void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
113 
114 public:
115   VTTBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerivedClass,
116              bool GenerateDefinition,
117              llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables
118                = (llvm::GlobalVariable::LinkageTypes) -1);
119 
120   // getVTTComponents - Returns a reference to the VTT components.
getVTTComponents() const121   const VTTComponentsVectorTy &getVTTComponents() const {
122     return VTTComponents;
123   }
124 
125   /// getSubVTTIndicies - Returns a reference to the sub-VTT indices.
getSubVTTIndicies() const126   const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
127     return SubVTTIndicies;
128   }
129 
130   /// getSecondaryVirtualPointerIndices - Returns a reference to the secondary
131   /// virtual pointer indices.
132   const llvm::DenseMap<BaseSubobject, uint64_t> &
getSecondaryVirtualPointerIndices() const133   getSecondaryVirtualPointerIndices() const {
134     return SecondaryVirtualPointerIndices;
135   }
136 
137 };
138 
VTTBuilder(CodeGenModule & CGM,const CXXRecordDecl * MostDerivedClass,bool GenerateDefinition,llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables)139 VTTBuilder::VTTBuilder(CodeGenModule &CGM,
140                        const CXXRecordDecl *MostDerivedClass,
141                        bool GenerateDefinition,
142           llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables)
143   : CGM(CGM), MostDerivedClass(MostDerivedClass),
144   MostDerivedClassLayout(CGM.getContext().getASTRecordLayout(MostDerivedClass)),
145     GenerateDefinition(GenerateDefinition),
146     LinkageForConstructionVTables(LinkageForConstructionVTables) {
147   assert(!GenerateDefinition ||
148          LinkageForConstructionVTables
149            != (llvm::GlobalVariable::LinkageTypes) -1);
150 
151   // Lay out this VTT.
152   LayoutVTT(BaseSubobject(MostDerivedClass, CharUnits::Zero()),
153             /*BaseIsVirtual=*/false);
154 }
155 
156 llvm::Constant *
GetAddrOfVTable(BaseSubobject Base,bool BaseIsVirtual,AddressPointsMapTy & AddressPoints)157 VTTBuilder::GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
158                             AddressPointsMapTy& AddressPoints) {
159   if (!GenerateDefinition)
160     return 0;
161 
162   if (Base.getBase() == MostDerivedClass) {
163     assert(Base.getBaseOffset().isZero() &&
164            "Most derived class vtable must have a zero offset!");
165     // This is a regular vtable.
166     return CGM.getVTables().GetAddrOfVTable(MostDerivedClass);
167   }
168 
169   return CGM.getVTables().GenerateConstructionVTable(MostDerivedClass,
170                                                      Base, BaseIsVirtual,
171                                            LinkageForConstructionVTables,
172                                                      AddressPoints);
173 }
174 
AddVTablePointer(BaseSubobject Base,llvm::Constant * VTable,const CXXRecordDecl * VTableClass,const AddressPointsMapTy & AddressPoints)175 void VTTBuilder::AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
176                                   const CXXRecordDecl *VTableClass,
177                                   const AddressPointsMapTy& AddressPoints) {
178   // Store the vtable pointer index if we're generating the primary VTT.
179   if (VTableClass == MostDerivedClass) {
180     assert(!SecondaryVirtualPointerIndices.count(Base) &&
181            "A virtual pointer index already exists for this base subobject!");
182     SecondaryVirtualPointerIndices[Base] = VTTComponents.size();
183   }
184 
185   if (!GenerateDefinition) {
186     VTTComponents.push_back(0);
187     return;
188   }
189 
190   uint64_t AddressPoint;
191   if (VTableClass != MostDerivedClass) {
192     // The vtable is a construction vtable, look in the construction vtable
193     // address points.
194     AddressPoint = AddressPoints.lookup(Base);
195     assert(AddressPoint != 0 && "Did not find ctor vtable address point!");
196   } else {
197     // Just get the address point for the regular vtable.
198     AddressPoint = CGM.getVTables().getAddressPoint(Base, VTableClass);
199     assert(AddressPoint != 0 && "Did not find vtable address point!");
200   }
201 
202   if (!AddressPoint) AddressPoint = 0;
203 
204   llvm::Value *Idxs[] = {
205     llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0),
206     llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()),
207                            AddressPoint)
208   };
209 
210   llvm::Constant *Init =
211     llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Idxs, 2);
212 
213   llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
214   Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
215 
216   VTTComponents.push_back(Init);
217 }
218 
LayoutSecondaryVTTs(BaseSubobject Base)219 void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
220   const CXXRecordDecl *RD = Base.getBase();
221 
222   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
223        E = RD->bases_end(); I != E; ++I) {
224 
225     // Don't layout virtual bases.
226     if (I->isVirtual())
227         continue;
228 
229     const CXXRecordDecl *BaseDecl =
230       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
231 
232     const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
233     CharUnits BaseOffset = Base.getBaseOffset() +
234       Layout.getBaseClassOffset(BaseDecl);
235 
236     // Layout the VTT for this base.
237     LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false);
238   }
239 }
240 
241 void
LayoutSecondaryVirtualPointers(BaseSubobject Base,bool BaseIsMorallyVirtual,llvm::Constant * VTable,const CXXRecordDecl * VTableClass,const AddressPointsMapTy & AddressPoints,VisitedVirtualBasesSetTy & VBases)242 VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
243                                         bool BaseIsMorallyVirtual,
244                                         llvm::Constant *VTable,
245                                         const CXXRecordDecl *VTableClass,
246                                         const AddressPointsMapTy& AddressPoints,
247                                         VisitedVirtualBasesSetTy &VBases) {
248   const CXXRecordDecl *RD = Base.getBase();
249 
250   // We're not interested in bases that don't have virtual bases, and not
251   // morally virtual bases.
252   if (!RD->getNumVBases() && !BaseIsMorallyVirtual)
253     return;
254 
255   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
256        E = RD->bases_end(); I != E; ++I) {
257     const CXXRecordDecl *BaseDecl =
258       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
259 
260     // Itanium C++ ABI 2.6.2:
261     //   Secondary virtual pointers are present for all bases with either
262     //   virtual bases or virtual function declarations overridden along a
263     //   virtual path.
264     //
265     // If the base class is not dynamic, we don't want to add it, nor any
266     // of its base classes.
267     if (!BaseDecl->isDynamicClass())
268       continue;
269 
270     bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual;
271     bool BaseDeclIsNonVirtualPrimaryBase = false;
272     CharUnits BaseOffset;
273     if (I->isVirtual()) {
274       // Ignore virtual bases that we've already visited.
275       if (!VBases.insert(BaseDecl))
276         continue;
277 
278       BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
279       BaseDeclIsMorallyVirtual = true;
280     } else {
281       const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
282 
283       BaseOffset = Base.getBaseOffset() +
284         Layout.getBaseClassOffset(BaseDecl);
285 
286       if (!Layout.isPrimaryBaseVirtual() &&
287           Layout.getPrimaryBase() == BaseDecl)
288         BaseDeclIsNonVirtualPrimaryBase = true;
289     }
290 
291     // Itanium C++ ABI 2.6.2:
292     //   Secondary virtual pointers: for each base class X which (a) has virtual
293     //   bases or is reachable along a virtual path from D, and (b) is not a
294     //   non-virtual primary base, the address of the virtual table for X-in-D
295     //   or an appropriate construction virtual table.
296     if (!BaseDeclIsNonVirtualPrimaryBase &&
297         (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) {
298       // Add the vtable pointer.
299       AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTable,
300                        VTableClass, AddressPoints);
301     }
302 
303     // And lay out the secondary virtual pointers for the base class.
304     LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset),
305                                    BaseDeclIsMorallyVirtual, VTable,
306                                    VTableClass, AddressPoints, VBases);
307   }
308 }
309 
310 void
LayoutSecondaryVirtualPointers(BaseSubobject Base,llvm::Constant * VTable,const AddressPointsMapTy & AddressPoints)311 VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
312                                       llvm::Constant *VTable,
313                                       const AddressPointsMapTy& AddressPoints) {
314   VisitedVirtualBasesSetTy VBases;
315   LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false,
316                                  VTable, Base.getBase(), AddressPoints, VBases);
317 }
318 
LayoutVirtualVTTs(const CXXRecordDecl * RD,VisitedVirtualBasesSetTy & VBases)319 void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
320                                    VisitedVirtualBasesSetTy &VBases) {
321   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
322        E = RD->bases_end(); I != E; ++I) {
323     const CXXRecordDecl *BaseDecl =
324       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
325 
326     // Check if this is a virtual base.
327     if (I->isVirtual()) {
328       // Check if we've seen this base before.
329       if (!VBases.insert(BaseDecl))
330         continue;
331 
332       CharUnits BaseOffset =
333         MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
334 
335       LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true);
336     }
337 
338     // We only need to layout virtual VTTs for this base if it actually has
339     // virtual bases.
340     if (BaseDecl->getNumVBases())
341       LayoutVirtualVTTs(BaseDecl, VBases);
342   }
343 }
344 
LayoutVTT(BaseSubobject Base,bool BaseIsVirtual)345 void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) {
346   const CXXRecordDecl *RD = Base.getBase();
347 
348   // Itanium C++ ABI 2.6.2:
349   //   An array of virtual table addresses, called the VTT, is declared for
350   //   each class type that has indirect or direct virtual base classes.
351   if (RD->getNumVBases() == 0)
352     return;
353 
354   bool IsPrimaryVTT = Base.getBase() == MostDerivedClass;
355 
356   if (!IsPrimaryVTT) {
357     // Remember the sub-VTT index.
358     SubVTTIndicies[Base] = VTTComponents.size();
359   }
360 
361   AddressPointsMapTy AddressPoints;
362   llvm::Constant *VTable = GetAddrOfVTable(Base, BaseIsVirtual, AddressPoints);
363 
364   // Add the primary vtable pointer.
365   AddVTablePointer(Base, VTable, RD, AddressPoints);
366 
367   // Add the secondary VTTs.
368   LayoutSecondaryVTTs(Base);
369 
370   // Add the secondary virtual pointers.
371   LayoutSecondaryVirtualPointers(Base, VTable, AddressPoints);
372 
373   // If this is the primary VTT, we want to lay out virtual VTTs as well.
374   if (IsPrimaryVTT) {
375     VisitedVirtualBasesSetTy VBases;
376     LayoutVirtualVTTs(Base.getBase(), VBases);
377   }
378 }
379 
380 }
381 
382 void
EmitVTTDefinition(llvm::GlobalVariable * VTT,llvm::GlobalVariable::LinkageTypes Linkage,const CXXRecordDecl * RD)383 CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
384                                   llvm::GlobalVariable::LinkageTypes Linkage,
385                                   const CXXRecordDecl *RD) {
386   VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/true, Linkage);
387 
388   llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
389   llvm::ArrayType *ArrayType =
390     llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
391 
392   llvm::Constant *Init =
393     llvm::ConstantArray::get(ArrayType, Builder.getVTTComponents());
394 
395   VTT->setInitializer(Init);
396 
397   // Set the correct linkage.
398   VTT->setLinkage(Linkage);
399 
400   // Set the right visibility.
401   CGM.setTypeVisibility(VTT, RD, CodeGenModule::TVK_ForVTT);
402 }
403 
GetAddrOfVTT(const CXXRecordDecl * RD)404 llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) {
405   assert(RD->getNumVBases() && "Only classes with virtual bases need a VTT");
406 
407   llvm::SmallString<256> OutName;
408   llvm::raw_svector_ostream Out(OutName);
409   CGM.getCXXABI().getMangleContext().mangleCXXVTT(RD, Out);
410   Out.flush();
411   llvm::StringRef Name = OutName.str();
412 
413   ComputeVTableRelatedInformation(RD, /*VTableRequired=*/true);
414 
415   VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
416 
417   llvm::Type *Int8PtrTy =
418     llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
419   llvm::ArrayType *ArrayType =
420     llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
421 
422   llvm::GlobalVariable *GV =
423     CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType,
424                                           llvm::GlobalValue::ExternalLinkage);
425   GV->setUnnamedAddr(true);
426   return GV;
427 }
428 
needsVTTParameter(GlobalDecl GD)429 bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) {
430   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
431 
432   // We don't have any virtual bases, just return early.
433   if (!MD->getParent()->getNumVBases())
434     return false;
435 
436   // Check if we have a base constructor.
437   if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
438     return true;
439 
440   // Check if we have a base destructor.
441   if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
442     return true;
443 
444   return false;
445 }
446 
getSubVTTIndex(const CXXRecordDecl * RD,BaseSubobject Base)447 uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD,
448                                         BaseSubobject Base) {
449   BaseSubobjectPairTy ClassSubobjectPair(RD, Base);
450 
451   SubVTTIndiciesMapTy::iterator I = SubVTTIndicies.find(ClassSubobjectPair);
452   if (I != SubVTTIndicies.end())
453     return I->second;
454 
455   VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
456 
457   for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
458        Builder.getSubVTTIndicies().begin(),
459        E = Builder.getSubVTTIndicies().end(); I != E; ++I) {
460     // Insert all indices.
461     BaseSubobjectPairTy ClassSubobjectPair(RD, I->first);
462 
463     SubVTTIndicies.insert(std::make_pair(ClassSubobjectPair, I->second));
464   }
465 
466   I = SubVTTIndicies.find(ClassSubobjectPair);
467   assert(I != SubVTTIndicies.end() && "Did not find index!");
468 
469   return I->second;
470 }
471 
472 uint64_t
getSecondaryVirtualPointerIndex(const CXXRecordDecl * RD,BaseSubobject Base)473 CodeGenVTables::getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
474                                                 BaseSubobject Base) {
475   SecondaryVirtualPointerIndicesMapTy::iterator I =
476     SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
477 
478   if (I != SecondaryVirtualPointerIndices.end())
479     return I->second;
480 
481   VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
482 
483   // Insert all secondary vpointer indices.
484   for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
485        Builder.getSecondaryVirtualPointerIndices().begin(),
486        E = Builder.getSecondaryVirtualPointerIndices().end(); I != E; ++I) {
487     std::pair<const CXXRecordDecl *, BaseSubobject> Pair =
488       std::make_pair(RD, I->first);
489 
490     SecondaryVirtualPointerIndices.insert(std::make_pair(Pair, I->second));
491   }
492 
493   I = SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
494   assert(I != SecondaryVirtualPointerIndices.end() && "Did not find index!");
495 
496   return I->second;
497 }
498 
499