clang API Documentation

VTTBuilder.cpp
Go to the documentation of this file.
00001 //===--- VTTBuilder.cpp - C++ VTT layout builder --------------------------===//
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 generation of the layout of virtual table
00011 // tables (VTT).
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "clang/AST/VTTBuilder.h"
00016 #include "clang/AST/CXXInheritance.h"
00017 #include "clang/AST/RecordLayout.h"
00018 #include "clang/Basic/TargetInfo.h"
00019 #include "llvm/Support/Format.h"
00020 #include <algorithm>
00021 #include <cstdio>
00022 
00023 using namespace clang;
00024 
00025 #define DUMP_OVERRIDERS 0
00026 
00027 VTTBuilder::VTTBuilder(ASTContext &Ctx,
00028                        const CXXRecordDecl *MostDerivedClass,
00029                        bool GenerateDefinition)
00030   : Ctx(Ctx), MostDerivedClass(MostDerivedClass), 
00031   MostDerivedClassLayout(Ctx.getASTRecordLayout(MostDerivedClass)),
00032     GenerateDefinition(GenerateDefinition) {
00033   // Lay out this VTT.
00034   LayoutVTT(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 
00035             /*BaseIsVirtual=*/false);
00036 }
00037 
00038 void VTTBuilder::AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
00039                                   const CXXRecordDecl *VTableClass) {
00040   // Store the vtable pointer index if we're generating the primary VTT.
00041   if (VTableClass == MostDerivedClass) {
00042     assert(!SecondaryVirtualPointerIndices.count(Base) &&
00043            "A virtual pointer index already exists for this base subobject!");
00044     SecondaryVirtualPointerIndices[Base] = VTTComponents.size();
00045   }
00046 
00047   if (!GenerateDefinition) {
00048     VTTComponents.push_back(VTTComponent());
00049     return;
00050   }
00051 
00052   VTTComponents.push_back(VTTComponent(VTableIndex, Base));
00053 }
00054 
00055 void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
00056   const CXXRecordDecl *RD = Base.getBase();
00057 
00058   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
00059        E = RD->bases_end(); I != E; ++I) {
00060     
00061     // Don't layout virtual bases.
00062     if (I->isVirtual())
00063         continue;
00064 
00065     const CXXRecordDecl *BaseDecl =
00066       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
00067 
00068     const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
00069     CharUnits BaseOffset = Base.getBaseOffset() + 
00070       Layout.getBaseClassOffset(BaseDecl);
00071    
00072     // Layout the VTT for this base.
00073     LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false);
00074   }
00075 }
00076 
00077 void
00078 VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 
00079                                            bool BaseIsMorallyVirtual,
00080                                            uint64_t VTableIndex,
00081                                            const CXXRecordDecl *VTableClass,
00082                                            VisitedVirtualBasesSetTy &VBases) {
00083   const CXXRecordDecl *RD = Base.getBase();
00084   
00085   // We're not interested in bases that don't have virtual bases, and not
00086   // morally virtual bases.
00087   if (!RD->getNumVBases() && !BaseIsMorallyVirtual)
00088     return;
00089 
00090   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
00091        E = RD->bases_end(); I != E; ++I) {
00092     const CXXRecordDecl *BaseDecl =
00093       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
00094 
00095     // Itanium C++ ABI 2.6.2:
00096     //   Secondary virtual pointers are present for all bases with either
00097     //   virtual bases or virtual function declarations overridden along a 
00098     //   virtual path.
00099     //
00100     // If the base class is not dynamic, we don't want to add it, nor any
00101     // of its base classes.
00102     if (!BaseDecl->isDynamicClass())
00103       continue;
00104     
00105     bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual;
00106     bool BaseDeclIsNonVirtualPrimaryBase = false;
00107     CharUnits BaseOffset;
00108     if (I->isVirtual()) {
00109       // Ignore virtual bases that we've already visited.
00110       if (!VBases.insert(BaseDecl))
00111         continue;
00112       
00113       BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
00114       BaseDeclIsMorallyVirtual = true;
00115     } else {
00116       const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
00117       
00118       BaseOffset = Base.getBaseOffset() + 
00119         Layout.getBaseClassOffset(BaseDecl);
00120       
00121       if (!Layout.isPrimaryBaseVirtual() &&
00122           Layout.getPrimaryBase() == BaseDecl)
00123         BaseDeclIsNonVirtualPrimaryBase = true;
00124     }
00125 
00126     // Itanium C++ ABI 2.6.2:
00127     //   Secondary virtual pointers: for each base class X which (a) has virtual
00128     //   bases or is reachable along a virtual path from D, and (b) is not a
00129     //   non-virtual primary base, the address of the virtual table for X-in-D
00130     //   or an appropriate construction virtual table.
00131     if (!BaseDeclIsNonVirtualPrimaryBase &&
00132         (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) {
00133       // Add the vtable pointer.
00134       AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTableIndex, 
00135                        VTableClass);
00136     }
00137 
00138     // And lay out the secondary virtual pointers for the base class.
00139     LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset),
00140                                    BaseDeclIsMorallyVirtual, VTableIndex, 
00141                                    VTableClass, VBases);
00142   }
00143 }
00144 
00145 void 
00146 VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 
00147                                            uint64_t VTableIndex) {
00148   VisitedVirtualBasesSetTy VBases;
00149   LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false,
00150                                  VTableIndex, Base.getBase(), VBases);
00151 }
00152 
00153 void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
00154                                    VisitedVirtualBasesSetTy &VBases) {
00155   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
00156        E = RD->bases_end(); I != E; ++I) {
00157     const CXXRecordDecl *BaseDecl = 
00158       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
00159     
00160     // Check if this is a virtual base.
00161     if (I->isVirtual()) {
00162       // Check if we've seen this base before.
00163       if (!VBases.insert(BaseDecl))
00164         continue;
00165     
00166       CharUnits BaseOffset = 
00167         MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
00168       
00169       LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true);
00170     }
00171     
00172     // We only need to layout virtual VTTs for this base if it actually has
00173     // virtual bases.
00174     if (BaseDecl->getNumVBases())
00175       LayoutVirtualVTTs(BaseDecl, VBases);
00176   }
00177 }
00178 
00179 void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) {
00180   const CXXRecordDecl *RD = Base.getBase();
00181 
00182   // Itanium C++ ABI 2.6.2:
00183   //   An array of virtual table addresses, called the VTT, is declared for 
00184   //   each class type that has indirect or direct virtual base classes.
00185   if (RD->getNumVBases() == 0)
00186     return;
00187 
00188   bool IsPrimaryVTT = Base.getBase() == MostDerivedClass;
00189 
00190   if (!IsPrimaryVTT) {
00191     // Remember the sub-VTT index.
00192     SubVTTIndicies[Base] = VTTComponents.size();
00193   }
00194 
00195   uint64_t VTableIndex = VTTVTables.size();
00196   VTTVTables.push_back(VTTVTable(Base, BaseIsVirtual));
00197 
00198   // Add the primary vtable pointer.
00199   AddVTablePointer(Base, VTableIndex, RD);
00200 
00201   // Add the secondary VTTs.
00202   LayoutSecondaryVTTs(Base);
00203   
00204   // Add the secondary virtual pointers.
00205   LayoutSecondaryVirtualPointers(Base, VTableIndex);
00206   
00207   // If this is the primary VTT, we want to lay out virtual VTTs as well.
00208   if (IsPrimaryVTT) {
00209     VisitedVirtualBasesSetTy VBases;
00210     LayoutVirtualVTTs(Base.getBase(), VBases);
00211   }
00212 }