Home | History | Annotate | Download | only in CodeGen
      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 #include "clang/AST/VTTBuilder.h"
     18 using namespace clang;
     19 using namespace CodeGen;
     20 
     21 #define D1(x)
     22 
     23 llvm::Constant *GetAddrOfVTTVTable(CodeGenVTables &CGVT,
     24                                    const CXXRecordDecl *MostDerivedClass,
     25                                    const VTTVTable &VTable,
     26                                    llvm::GlobalVariable::LinkageTypes Linkage,
     27                        llvm::DenseMap<BaseSubobject, uint64_t> &AddressPoints) {
     28   if (VTable.getBase() == MostDerivedClass) {
     29     assert(VTable.getBaseOffset().isZero() &&
     30            "Most derived class vtable must have a zero offset!");
     31     // This is a regular vtable.
     32     return CGVT.GetAddrOfVTable(MostDerivedClass);
     33   }
     34 
     35   return CGVT.GenerateConstructionVTable(MostDerivedClass,
     36                                          VTable.getBaseSubobject(),
     37                                          VTable.isVirtual(),
     38                                          Linkage,
     39                                          AddressPoints);
     40 }
     41 
     42 void
     43 CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
     44                                   llvm::GlobalVariable::LinkageTypes Linkage,
     45                                   const CXXRecordDecl *RD) {
     46   VTTBuilder Builder(CGM.getContext(), RD, /*GenerateDefinition=*/true);
     47 
     48   llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()),
     49              *Int64Ty = llvm::Type::getInt64Ty(CGM.getLLVMContext());
     50   llvm::ArrayType *ArrayType =
     51     llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
     52 
     53   SmallVector<llvm::Constant *, 8> VTables;
     54   SmallVector<VTableAddressPointsMapTy, 8> VTableAddressPoints;
     55   for (const VTTVTable *i = Builder.getVTTVTables().begin(),
     56                        *e = Builder.getVTTVTables().end(); i != e; ++i) {
     57     VTableAddressPoints.push_back(VTableAddressPointsMapTy());
     58     VTables.push_back(GetAddrOfVTTVTable(*this, RD, *i, Linkage,
     59                                          VTableAddressPoints.back()));
     60   }
     61 
     62   SmallVector<llvm::Constant *, 8> VTTComponents;
     63   for (const VTTComponent *i = Builder.getVTTComponents().begin(),
     64                           *e = Builder.getVTTComponents().end(); i != e; ++i) {
     65     const VTTVTable &VTTVT = Builder.getVTTVTables()[i->VTableIndex];
     66     llvm::Constant *VTable = VTables[i->VTableIndex];
     67     uint64_t AddressPoint;
     68     if (VTTVT.getBase() == RD) {
     69       // Just get the address point for the regular vtable.
     70       AddressPoint = VTContext.getVTableLayout(RD)
     71                               .getAddressPoint(i->VTableBase);
     72       assert(AddressPoint != 0 && "Did not find vtable address point!");
     73     } else {
     74       AddressPoint = VTableAddressPoints[i->VTableIndex].lookup(i->VTableBase);
     75       assert(AddressPoint != 0 && "Did not find ctor vtable address point!");
     76     }
     77 
     78      llvm::Value *Idxs[] = {
     79        llvm::ConstantInt::get(Int64Ty, 0),
     80        llvm::ConstantInt::get(Int64Ty, AddressPoint)
     81      };
     82 
     83      llvm::Constant *Init =
     84        llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Idxs);
     85 
     86      Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
     87 
     88      VTTComponents.push_back(Init);
     89   }
     90 
     91   llvm::Constant *Init = llvm::ConstantArray::get(ArrayType, VTTComponents);
     92 
     93   VTT->setInitializer(Init);
     94 
     95   // Set the correct linkage.
     96   VTT->setLinkage(Linkage);
     97 
     98   // Set the right visibility.
     99   CGM.setTypeVisibility(VTT, RD, CodeGenModule::TVK_ForVTT);
    100 }
    101 
    102 llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) {
    103   assert(RD->getNumVBases() && "Only classes with virtual bases need a VTT");
    104 
    105   llvm::SmallString<256> OutName;
    106   llvm::raw_svector_ostream Out(OutName);
    107   CGM.getCXXABI().getMangleContext().mangleCXXVTT(RD, Out);
    108   Out.flush();
    109   StringRef Name = OutName.str();
    110 
    111   // This will also defer the definition of the VTT.
    112   (void) GetAddrOfVTable(RD);
    113 
    114   VTTBuilder Builder(CGM.getContext(), RD, /*GenerateDefinition=*/false);
    115 
    116   llvm::Type *Int8PtrTy =
    117     llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
    118   llvm::ArrayType *ArrayType =
    119     llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
    120 
    121   llvm::GlobalVariable *GV =
    122     CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType,
    123                                           llvm::GlobalValue::ExternalLinkage);
    124   GV->setUnnamedAddr(true);
    125   return GV;
    126 }
    127 
    128 bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) {
    129   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
    130 
    131   // We don't have any virtual bases, just return early.
    132   if (!MD->getParent()->getNumVBases())
    133     return false;
    134 
    135   // Check if we have a base constructor.
    136   if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
    137     return true;
    138 
    139   // Check if we have a base destructor.
    140   if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
    141     return true;
    142 
    143   return false;
    144 }
    145 
    146 uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD,
    147                                         BaseSubobject Base) {
    148   BaseSubobjectPairTy ClassSubobjectPair(RD, Base);
    149 
    150   SubVTTIndiciesMapTy::iterator I = SubVTTIndicies.find(ClassSubobjectPair);
    151   if (I != SubVTTIndicies.end())
    152     return I->second;
    153 
    154   VTTBuilder Builder(CGM.getContext(), RD, /*GenerateDefinition=*/false);
    155 
    156   for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
    157        Builder.getSubVTTIndicies().begin(),
    158        E = Builder.getSubVTTIndicies().end(); I != E; ++I) {
    159     // Insert all indices.
    160     BaseSubobjectPairTy ClassSubobjectPair(RD, I->first);
    161 
    162     SubVTTIndicies.insert(std::make_pair(ClassSubobjectPair, I->second));
    163   }
    164 
    165   I = SubVTTIndicies.find(ClassSubobjectPair);
    166   assert(I != SubVTTIndicies.end() && "Did not find index!");
    167 
    168   return I->second;
    169 }
    170 
    171 uint64_t
    172 CodeGenVTables::getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
    173                                                 BaseSubobject Base) {
    174   SecondaryVirtualPointerIndicesMapTy::iterator I =
    175     SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
    176 
    177   if (I != SecondaryVirtualPointerIndices.end())
    178     return I->second;
    179 
    180   VTTBuilder Builder(CGM.getContext(), RD, /*GenerateDefinition=*/false);
    181 
    182   // Insert all secondary vpointer indices.
    183   for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
    184        Builder.getSecondaryVirtualPointerIndices().begin(),
    185        E = Builder.getSecondaryVirtualPointerIndices().end(); I != E; ++I) {
    186     std::pair<const CXXRecordDecl *, BaseSubobject> Pair =
    187       std::make_pair(RD, I->first);
    188 
    189     SecondaryVirtualPointerIndices.insert(std::make_pair(Pair, I->second));
    190   }
    191 
    192   I = SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
    193   assert(I != SecondaryVirtualPointerIndices.end() && "Did not find index!");
    194 
    195   return I->second;
    196 }
    197 
    198