VTTBuilder.cpp revision 239462
11541Srgrimes//===--- VTTBuilder.cpp - C++ VTT layout builder --------------------------===// 21541Srgrimes// 31541Srgrimes// The LLVM Compiler Infrastructure 41541Srgrimes// 517703Ssmpatel// This file is distributed under the University of Illinois Open Source 61541Srgrimes// License. See LICENSE.TXT for details. 71541Srgrimes// 811295Sswallace//===----------------------------------------------------------------------===// 91541Srgrimes// 1011295Sswallace// This contains code dealing with generation of the layout of virtual table 112257Ssos// tables (VTT). 1210907Sbde// 131541Srgrimes//===----------------------------------------------------------------------===// 141541Srgrimes 1510907Sbde#include "clang/AST/VTTBuilder.h" 161541Srgrimes#include "clang/AST/ASTContext.h" 1710907Sbde#include "clang/AST/CXXInheritance.h" 181541Srgrimes#include "clang/AST/RecordLayout.h" 191541Srgrimes#include "clang/Basic/TargetInfo.h" 2010907Sbde#include "llvm/Support/Format.h" 211541Srgrimes#include <algorithm> 2210907Sbde#include <cstdio> 2310907Sbde 2410907Sbdeusing namespace clang; 2510907Sbde 2610907Sbde#define DUMP_OVERRIDERS 0 2710907Sbde 2810907SbdeVTTBuilder::VTTBuilder(ASTContext &Ctx, 2910907Sbde const CXXRecordDecl *MostDerivedClass, 301541Srgrimes bool GenerateDefinition) 3110907Sbde : Ctx(Ctx), MostDerivedClass(MostDerivedClass), 3210907Sbde MostDerivedClassLayout(Ctx.getASTRecordLayout(MostDerivedClass)), 3310907Sbde GenerateDefinition(GenerateDefinition) { 3410907Sbde // Lay out this VTT. 3510907Sbde LayoutVTT(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 3610907Sbde /*BaseIsVirtual=*/false); 3710907Sbde} 3810907Sbde 3910907Sbdevoid VTTBuilder::AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex, 4010907Sbde const CXXRecordDecl *VTableClass) { 411541Srgrimes // Store the vtable pointer index if we're generating the primary VTT. 4210907Sbde if (VTableClass == MostDerivedClass) { 4310907Sbde assert(!SecondaryVirtualPointerIndices.count(Base) && 4410907Sbde "A virtual pointer index already exists for this base subobject!"); 4510907Sbde SecondaryVirtualPointerIndices[Base] = VTTComponents.size(); 4610907Sbde } 4710907Sbde 4810907Sbde if (!GenerateDefinition) { 4910907Sbde VTTComponents.push_back(VTTComponent()); 5010907Sbde return; 5110907Sbde } 5210907Sbde 5311295Sswallace VTTComponents.push_back(VTTComponent(VTableIndex, Base)); 5411295Sswallace} 5510907Sbde 5610907Sbdevoid VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) { 5710907Sbde const CXXRecordDecl *RD = Base.getBase(); 5810907Sbde 5910907Sbde for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 601541Srgrimes E = RD->bases_end(); I != E; ++I) { 6110907Sbde 621541Srgrimes // Don't layout virtual bases. 6311295Sswallace if (I->isVirtual()) 6410907Sbde continue; 6510907Sbde 6610907Sbde const CXXRecordDecl *BaseDecl = 6710907Sbde cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 6810907Sbde 6910907Sbde const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); 7011295Sswallace CharUnits BaseOffset = Base.getBaseOffset() + 7110907Sbde Layout.getBaseClassOffset(BaseDecl); 7210907Sbde 7310907Sbde // Layout the VTT for this base. 7410907Sbde LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false); 7511295Sswallace } 7610907Sbde} 7710907Sbde 7810907Sbdevoid 7910907SbdeVTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 8010907Sbde bool BaseIsMorallyVirtual, 8110907Sbde uint64_t VTableIndex, 8210907Sbde const CXXRecordDecl *VTableClass, 8310907Sbde VisitedVirtualBasesSetTy &VBases) { 841541Srgrimes const CXXRecordDecl *RD = Base.getBase(); 851541Srgrimes 861541Srgrimes // We're not interested in bases that don't have virtual bases, and not 8710907Sbde // morally virtual bases. 8810907Sbde if (!RD->getNumVBases() && !BaseIsMorallyVirtual) 8910907Sbde return; 9010907Sbde 9110907Sbde for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 9210907Sbde E = RD->bases_end(); I != E; ++I) { 931549Srgrimes const CXXRecordDecl *BaseDecl = 9410907Sbde cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 9510907Sbde 9610907Sbde // Itanium C++ ABI 2.6.2: 9710907Sbde // Secondary virtual pointers are present for all bases with either 9810907Sbde // virtual bases or virtual function declarations overridden along a 9910907Sbde // virtual path. 10010907Sbde // 10110907Sbde // If the base class is not dynamic, we don't want to add it, nor any 10210907Sbde // of its base classes. 10310907Sbde if (!BaseDecl->isDynamicClass()) 10410907Sbde continue; 10510907Sbde 1061541Srgrimes bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual; 10710907Sbde bool BaseDeclIsNonVirtualPrimaryBase = false; 10810907Sbde CharUnits BaseOffset; 1091541Srgrimes if (I->isVirtual()) { 1101541Srgrimes // Ignore virtual bases that we've already visited. 11111295Sswallace if (!VBases.insert(BaseDecl)) 11210907Sbde continue; 11310907Sbde 11410907Sbde BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 11510907Sbde BaseDeclIsMorallyVirtual = true; 11610907Sbde } else { 11710907Sbde const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); 11811295Sswallace 11910907Sbde BaseOffset = Base.getBaseOffset() + 12010907Sbde Layout.getBaseClassOffset(BaseDecl); 1211541Srgrimes 12211295Sswallace if (!Layout.isPrimaryBaseVirtual() && 1231541Srgrimes Layout.getPrimaryBase() == BaseDecl) 1241541Srgrimes BaseDeclIsNonVirtualPrimaryBase = true; 12510907Sbde } 12610907Sbde 12710907Sbde // Itanium C++ ABI 2.6.2: 12810907Sbde // Secondary virtual pointers: for each base class X which (a) has virtual 12910907Sbde // bases or is reachable along a virtual path from D, and (b) is not a 1301541Srgrimes // non-virtual primary base, the address of the virtual table for X-in-D 1311541Srgrimes // or an appropriate construction virtual table. 1321541Srgrimes if (!BaseDeclIsNonVirtualPrimaryBase && 13310907Sbde (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) { 1341541Srgrimes // Add the vtable pointer. 1351541Srgrimes AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTableIndex, 1361541Srgrimes VTableClass); 13710907Sbde } 13811295Sswallace 13910907Sbde // And lay out the secondary virtual pointers for the base class. 14010907Sbde LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset), 14114220Speter BaseDeclIsMorallyVirtual, VTableIndex, 14210907Sbde VTableClass, VBases); 14310907Sbde } 14411295Sswallace} 14510907Sbde 14610907Sbdevoid 1471541SrgrimesVTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 14810907Sbde uint64_t VTableIndex) { 14910907Sbde VisitedVirtualBasesSetTy VBases; 15010907Sbde LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false, 1511541Srgrimes VTableIndex, Base.getBase(), VBases); 1521541Srgrimes} 15310907Sbde 15410907Sbdevoid VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD, 15510907Sbde VisitedVirtualBasesSetTy &VBases) { 15610907Sbde for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 15711295Sswallace E = RD->bases_end(); I != E; ++I) { 15810907Sbde const CXXRecordDecl *BaseDecl = 15910907Sbde cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 16010907Sbde 16110907Sbde // Check if this is a virtual base. 16210907Sbde if (I->isVirtual()) { 1631541Srgrimes // Check if we've seen this base before. 1641541Srgrimes if (!VBases.insert(BaseDecl)) 1651541Srgrimes continue; 1661541Srgrimes 1671541Srgrimes CharUnits BaseOffset = 1681541Srgrimes MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 16910907Sbde 17010907Sbde LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true); 17111295Sswallace } 1721541Srgrimes 17314220Speter // We only need to layout virtual VTTs for this base if it actually has 17414220Speter // virtual bases. 17514220Speter if (BaseDecl->getNumVBases()) 17610907Sbde LayoutVirtualVTTs(BaseDecl, VBases); 1771541Srgrimes } 17810907Sbde} 1791541Srgrimes 18010907Sbdevoid VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) { 1811541Srgrimes const CXXRecordDecl *RD = Base.getBase(); 1821541Srgrimes 18310907Sbde // Itanium C++ ABI 2.6.2: 18410907Sbde // An array of virtual table addresses, called the VTT, is declared for 18510907Sbde // each class type that has indirect or direct virtual base classes. 18610907Sbde if (RD->getNumVBases() == 0) 18713416Sphk return; 18810907Sbde 1891541Srgrimes bool IsPrimaryVTT = Base.getBase() == MostDerivedClass; 19010907Sbde 1911541Srgrimes if (!IsPrimaryVTT) { 19211295Sswallace // Remember the sub-VTT index. 19311295Sswallace SubVTTIndicies[Base] = VTTComponents.size(); 19410907Sbde } 19510907Sbde 19610907Sbde uint64_t VTableIndex = VTTVTables.size(); 19710907Sbde VTTVTables.push_back(VTTVTable(Base, BaseIsVirtual)); 19810907Sbde 19910907Sbde // Add the primary vtable pointer. 20010907Sbde AddVTablePointer(Base, VTableIndex, RD); 20110907Sbde 20210907Sbde // Add the secondary VTTs. 20310907Sbde LayoutSecondaryVTTs(Base); 20410907Sbde 20510907Sbde // Add the secondary virtual pointers. 20611295Sswallace LayoutSecondaryVirtualPointers(Base, VTableIndex); 20714220Speter 20814220Speter // If this is the primary VTT, we want to lay out virtual VTTs as well. 20914220Speter if (IsPrimaryVTT) { 21010907Sbde VisitedVirtualBasesSetTy VBases; 21110907Sbde LayoutVirtualVTTs(Base.getBase(), VBases); 21210907Sbde } 21310907Sbde} 2141541Srgrimes