clang API Documentation

CGVTT.cpp

Go to the documentation of this file.
00001 //===--- CGVTT.cpp - Emit LLVM Code for C++ VTTs --------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This contains code dealing with C++ code generation of VTTs (vtable tables).
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "CodeGenModule.h"
00015 #include "clang/AST/RecordLayout.h"
00016 using namespace clang;
00017 using namespace CodeGen;
00018 
00019 #define D1(x)
00020 
00021 namespace {
00022 
00023 /// VTT builder - Class for building VTT layout information.
00024 class VTTBuilder {
00025   
00026   CodeGenModule &CGM;
00027 
00028   /// MostDerivedClass - The most derived class for which we're building this
00029   /// vtable.
00030   const CXXRecordDecl *MostDerivedClass;
00031 
00032   typedef llvm::SmallVector<llvm::Constant *, 64> VTTComponentsVectorTy;
00033   
00034   /// VTTComponents - The VTT components.
00035   VTTComponentsVectorTy VTTComponents;
00036   
00037   /// MostDerivedClassLayout - the AST record layout of the most derived class.
00038   const ASTRecordLayout &MostDerivedClassLayout;
00039 
00040   typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
00041 
00042   typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
00043 
00044   /// SubVTTIndicies - The sub-VTT indices for the bases of the most derived
00045   /// class.
00046   llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
00047 
00048   /// SecondaryVirtualPointerIndices - The secondary virtual pointer indices of
00049   /// all subobjects of the most derived class.
00050   llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
00051 
00052   /// GenerateDefinition - Whether the VTT builder should generate LLVM IR for
00053   /// the VTT.
00054   bool GenerateDefinition;
00055   
00056   /// GetAddrOfVTable - Returns the address of the vtable for the base class in
00057   /// the given vtable class.
00058   ///
00059   /// \param AddressPoints - If the returned vtable is a construction vtable,
00060   /// this will hold the address points for it.
00061   llvm::Constant *GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
00062                                   AddressPointsMapTy& AddressPoints);
00063 
00064   /// AddVTablePointer - Add a vtable pointer to the VTT currently being built.
00065   ///
00066   /// \param AddressPoints - If the vtable is a construction vtable, this has
00067   /// the address points for it.
00068   void AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
00069                         const CXXRecordDecl *VTableClass,
00070                         const AddressPointsMapTy& AddressPoints);
00071                         
00072   /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base 
00073   /// subobject.
00074   void LayoutSecondaryVTTs(BaseSubobject Base);
00075   
00076   /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
00077   /// for the given base subobject.
00078   ///
00079   /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
00080   /// or a direct or indirect base of a virtual base.
00081   ///
00082   /// \param AddressPoints - If the vtable is a construction vtable, this has
00083   /// the address points for it.
00084   void LayoutSecondaryVirtualPointers(BaseSubobject Base, 
00085                                       bool BaseIsMorallyVirtual,
00086                                       llvm::Constant *VTable,
00087                                       const CXXRecordDecl *VTableClass,
00088                                       const AddressPointsMapTy& AddressPoints,
00089                                       VisitedVirtualBasesSetTy &VBases);
00090   
00091   /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
00092   /// for the given base subobject.
00093   ///
00094   /// \param AddressPoints - If the vtable is a construction vtable, this has
00095   /// the address points for it.
00096   void LayoutSecondaryVirtualPointers(BaseSubobject Base, 
00097                                       llvm::Constant *VTable,
00098                                       const AddressPointsMapTy& AddressPoints);
00099 
00100   /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the
00101   /// given record decl.
00102   void LayoutVirtualVTTs(const CXXRecordDecl *RD,
00103                          VisitedVirtualBasesSetTy &VBases);
00104   
00105   /// LayoutVTT - Will lay out the VTT for the given subobject, including any
00106   /// secondary VTTs, secondary virtual pointers and virtual VTTs.
00107   void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
00108   
00109 public:
00110   VTTBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerivedClass,
00111              bool GenerateDefinition);
00112 
00113   // getVTTComponents - Returns a reference to the VTT components.
00114   const VTTComponentsVectorTy &getVTTComponents() const {
00115     return VTTComponents;
00116   }
00117   
00118   /// getSubVTTIndicies - Returns a reference to the sub-VTT indices.
00119   const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
00120     return SubVTTIndicies;
00121   }
00122   
00123   /// getSecondaryVirtualPointerIndices - Returns a reference to the secondary
00124   /// virtual pointer indices.
00125   const llvm::DenseMap<BaseSubobject, uint64_t> &
00126   getSecondaryVirtualPointerIndices() const {
00127     return SecondaryVirtualPointerIndices;
00128   }
00129 
00130 };
00131 
00132 VTTBuilder::VTTBuilder(CodeGenModule &CGM,
00133                        const CXXRecordDecl *MostDerivedClass,
00134                        bool GenerateDefinition)
00135   : CGM(CGM), MostDerivedClass(MostDerivedClass), 
00136   MostDerivedClassLayout(CGM.getContext().getASTRecordLayout(MostDerivedClass)),
00137   GenerateDefinition(GenerateDefinition) {
00138     
00139   // Lay out this VTT.
00140   LayoutVTT(BaseSubobject(MostDerivedClass, 0), /*BaseIsVirtual=*/false);
00141 }
00142 
00143 llvm::Constant *
00144 VTTBuilder::GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual, 
00145                             AddressPointsMapTy& AddressPoints) {
00146   if (!GenerateDefinition)
00147     return 0;
00148   
00149   if (Base.getBase() == MostDerivedClass) {
00150     assert(Base.getBaseOffset() == 0 &&
00151            "Most derived class vtable must have a zero offset!");
00152     // This is a regular vtable.
00153     return CGM.getVTables().GetAddrOfVTable(MostDerivedClass);
00154   }
00155   
00156   return CGM.getVTables().GenerateConstructionVTable(MostDerivedClass, 
00157                                                      Base, BaseIsVirtual,
00158                                                      AddressPoints);
00159 }
00160 
00161 void VTTBuilder::AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
00162                                   const CXXRecordDecl *VTableClass,
00163                                   const AddressPointsMapTy& AddressPoints) {
00164   // Store the vtable pointer index if we're generating the primary VTT.
00165   if (VTableClass == MostDerivedClass) {
00166     assert(!SecondaryVirtualPointerIndices.count(Base) &&
00167            "A virtual pointer index already exists for this base subobject!");
00168     SecondaryVirtualPointerIndices[Base] = VTTComponents.size();
00169   }
00170 
00171   if (!GenerateDefinition) {
00172     VTTComponents.push_back(0);
00173     return;
00174   }
00175 
00176   uint64_t AddressPoint;
00177   if (VTableClass != MostDerivedClass) {
00178     // The vtable is a construction vtable, look in the construction vtable
00179     // address points.
00180     AddressPoint = AddressPoints.lookup(Base);
00181     assert(AddressPoint != 0 && "Did not find ctor vtable address point!");
00182   } else {
00183     // Just get the address point for the regular vtable.
00184     AddressPoint = CGM.getVTables().getAddressPoint(Base, VTableClass);
00185     assert(AddressPoint != 0 && "Did not find vtable address point!");
00186   }
00187 
00188   if (!AddressPoint) AddressPoint = 0;
00189   
00190   llvm::Value *Idxs[] = {
00191     llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0),
00192     llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()), 
00193                            AddressPoint)
00194   };
00195   
00196   llvm::Constant *Init = 
00197     llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Idxs, 2);
00198   
00199   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
00200   Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
00201   
00202   VTTComponents.push_back(Init);
00203 }
00204 
00205 void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
00206   const CXXRecordDecl *RD = Base.getBase();
00207 
00208   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
00209        E = RD->bases_end(); I != E; ++I) {
00210     
00211     // Don't layout virtual bases.
00212     if (I->isVirtual())
00213         continue;
00214 
00215     const CXXRecordDecl *BaseDecl =
00216       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
00217 
00218     const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
00219     uint64_t BaseOffset = Base.getBaseOffset() + 
00220       Layout.getBaseClassOffset(BaseDecl);
00221    
00222     // Layout the VTT for this base.
00223     LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false);
00224   }
00225 }
00226 
00227 void
00228 VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 
00229                                         bool BaseIsMorallyVirtual,
00230                                         llvm::Constant *VTable,
00231                                         const CXXRecordDecl *VTableClass,
00232                                         const AddressPointsMapTy& AddressPoints,
00233                                         VisitedVirtualBasesSetTy &VBases) {
00234   const CXXRecordDecl *RD = Base.getBase();
00235   
00236   // We're not interested in bases that don't have virtual bases, and not
00237   // morally virtual bases.
00238   if (!RD->getNumVBases() && !BaseIsMorallyVirtual)
00239     return;
00240 
00241   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
00242        E = RD->bases_end(); I != E; ++I) {
00243     const CXXRecordDecl *BaseDecl =
00244       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
00245 
00246     // Itanium C++ ABI 2.6.2:
00247     //   Secondary virtual pointers are present for all bases with either
00248     //   virtual bases or virtual function declarations overridden along a 
00249     //   virtual path.
00250     //
00251     // If the base class is not dynamic, we don't want to add it, nor any
00252     // of its base classes.
00253     if (!BaseDecl->isDynamicClass())
00254       continue;
00255     
00256     bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual;
00257     bool BaseDeclIsNonVirtualPrimaryBase = false;
00258     uint64_t BaseOffset;
00259     if (I->isVirtual()) {
00260       // Ignore virtual bases that we've already visited.
00261       if (!VBases.insert(BaseDecl))
00262         continue;
00263       
00264       BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
00265       BaseDeclIsMorallyVirtual = true;
00266     } else {
00267       const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
00268       
00269       BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl);
00270       
00271       if (!Layout.getPrimaryBaseWasVirtual() &&
00272           Layout.getPrimaryBase() == BaseDecl)
00273         BaseDeclIsNonVirtualPrimaryBase = true;
00274     }
00275 
00276     // Itanium C++ ABI 2.6.2:
00277     //   Secondary virtual pointers: for each base class X which (a) has virtual
00278     //   bases or is reachable along a virtual path from D, and (b) is not a
00279     //   non-virtual primary base, the address of the virtual table for X-in-D
00280     //   or an appropriate construction virtual table.
00281     if (!BaseDeclIsNonVirtualPrimaryBase &&
00282         (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) {
00283       // Add the vtable pointer.
00284       AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTable, VTableClass, 
00285                        AddressPoints);
00286     }
00287 
00288     // And lay out the secondary virtual pointers for the base class.
00289     LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset),
00290                                    BaseDeclIsMorallyVirtual, VTable, 
00291                                    VTableClass, AddressPoints, VBases);
00292   }
00293 }
00294 
00295 void 
00296 VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 
00297                                       llvm::Constant *VTable,
00298                                       const AddressPointsMapTy& AddressPoints) {
00299   VisitedVirtualBasesSetTy VBases;
00300   LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false,
00301                                  VTable, Base.getBase(), AddressPoints, VBases);
00302 }
00303 
00304 void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
00305                                    VisitedVirtualBasesSetTy &VBases) {
00306   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
00307        E = RD->bases_end(); I != E; ++I) {
00308     const CXXRecordDecl *BaseDecl = 
00309       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
00310     
00311     // Check if this is a virtual base.
00312     if (I->isVirtual()) {
00313       // Check if we've seen this base before.
00314       if (!VBases.insert(BaseDecl))
00315         continue;
00316     
00317       uint64_t BaseOffset = 
00318         MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
00319       
00320       LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true);
00321     }
00322     
00323     // We only need to layout virtual VTTs for this base if it actually has
00324     // virtual bases.
00325     if (BaseDecl->getNumVBases())
00326       LayoutVirtualVTTs(BaseDecl, VBases);
00327   }
00328 }
00329 
00330 void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) {
00331   const CXXRecordDecl *RD = Base.getBase();
00332 
00333   // Itanium C++ ABI 2.6.2:
00334   //   An array of virtual table addresses, called the VTT, is declared for 
00335   //   each class type that has indirect or direct virtual base classes.
00336   if (RD->getNumVBases() == 0)
00337     return;
00338 
00339   bool IsPrimaryVTT = Base.getBase() == MostDerivedClass;
00340 
00341   if (!IsPrimaryVTT) {
00342     // Remember the sub-VTT index.
00343     SubVTTIndicies[Base] = VTTComponents.size();
00344   }
00345 
00346   AddressPointsMapTy AddressPoints;
00347   llvm::Constant *VTable = GetAddrOfVTable(Base, BaseIsVirtual, AddressPoints);
00348 
00349   // Add the primary vtable pointer.
00350   AddVTablePointer(Base, VTable, RD, AddressPoints);
00351 
00352   // Add the secondary VTTs.
00353   LayoutSecondaryVTTs(Base);
00354   
00355   // Add the secondary virtual pointers.
00356   LayoutSecondaryVirtualPointers(Base, VTable, AddressPoints);
00357   
00358   // If this is the primary VTT, we want to lay out virtual VTTs as well.
00359   if (IsPrimaryVTT) {
00360     VisitedVirtualBasesSetTy VBases;
00361     LayoutVirtualVTTs(Base.getBase(), VBases);
00362   }
00363 }
00364   
00365 }
00366 
00367 llvm::GlobalVariable *
00368 CodeGenVTables::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
00369                             bool GenerateDefinition,
00370                             const CXXRecordDecl *RD) {
00371   // Only classes that have virtual bases need a VTT.
00372   if (RD->getNumVBases() == 0)
00373     return 0;
00374 
00375   llvm::SmallString<256> OutName;
00376   CGM.getMangleContext().mangleCXXVTT(RD, OutName);
00377   llvm::StringRef Name = OutName.str();
00378 
00379   D1(printf("vtt %s\n", RD->getNameAsCString()));
00380 
00381   llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
00382   if (GV == 0 || GV->isDeclaration()) {
00383     const llvm::Type *Int8PtrTy = 
00384       llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
00385 
00386     VTTBuilder Builder(CGM, RD, GenerateDefinition);
00387 
00388     const llvm::ArrayType *Type = 
00389       llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
00390 
00391     llvm::Constant *Init = 0;
00392     if (GenerateDefinition)
00393       Init = llvm::ConstantArray::get(Type, Builder.getVTTComponents().data(),
00394                                       Builder.getVTTComponents().size());
00395 
00396     llvm::GlobalVariable *OldGV = GV;
00397     GV = new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true, 
00398                                   Linkage, Init, Name);
00399     CGM.setGlobalVisibility(GV, RD);
00400     
00401     if (OldGV) {
00402       GV->takeName(OldGV);
00403       llvm::Constant *NewPtr = 
00404         llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
00405       OldGV->replaceAllUsesWith(NewPtr);
00406       OldGV->eraseFromParent();
00407     }
00408   }
00409   
00410   return GV;
00411 }
00412 
00413 llvm::GlobalVariable *CodeGenVTables::getVTT(const CXXRecordDecl *RD) {
00414   return GenerateVTT(llvm::GlobalValue::ExternalLinkage, 
00415                      /*GenerateDefinition=*/false, RD);
00416 }
00417 
00418 bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) {
00419   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
00420   
00421   // We don't have any virtual bases, just return early.
00422   if (!MD->getParent()->getNumVBases())
00423     return false;
00424   
00425   // Check if we have a base constructor.
00426   if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
00427     return true;
00428 
00429   // Check if we have a base destructor.
00430   if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
00431     return true;
00432   
00433   return false;
00434 }
00435 
00436 uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD, 
00437                                         BaseSubobject Base) {
00438   BaseSubobjectPairTy ClassSubobjectPair(RD, Base);
00439 
00440   SubVTTIndiciesMapTy::iterator I = SubVTTIndicies.find(ClassSubobjectPair);
00441   if (I != SubVTTIndicies.end())
00442     return I->second;
00443   
00444   VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
00445 
00446   for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
00447        Builder.getSubVTTIndicies().begin(), 
00448        E = Builder.getSubVTTIndicies().end(); I != E; ++I) {
00449     // Insert all indices.
00450     BaseSubobjectPairTy ClassSubobjectPair(RD, I->first);
00451     
00452     SubVTTIndicies.insert(std::make_pair(ClassSubobjectPair, I->second));
00453   }
00454     
00455   I = SubVTTIndicies.find(ClassSubobjectPair);
00456   assert(I != SubVTTIndicies.end() && "Did not find index!");
00457   
00458   return I->second;
00459 }
00460 
00461 uint64_t 
00462 CodeGenVTables::getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
00463                                                 BaseSubobject Base) {
00464   SecondaryVirtualPointerIndicesMapTy::iterator I =
00465     SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
00466 
00467   if (I != SecondaryVirtualPointerIndices.end())
00468     return I->second;
00469 
00470   VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
00471 
00472   // Insert all secondary vpointer indices.
00473   for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I = 
00474        Builder.getSecondaryVirtualPointerIndices().begin(),
00475        E = Builder.getSecondaryVirtualPointerIndices().end(); I != E; ++I) {
00476     std::pair<const CXXRecordDecl *, BaseSubobject> Pair =
00477       std::make_pair(RD, I->first);
00478     
00479     SecondaryVirtualPointerIndices.insert(std::make_pair(Pair, I->second));
00480   }
00481 
00482   I = SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
00483   assert(I != SecondaryVirtualPointerIndices.end() && "Did not find index!");
00484   
00485   return I->second;
00486 }
00487