1*f4a2713aSLionel Sambuc //===--- VTTBuilder.cpp - C++ VTT layout builder --------------------------===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc // 10*f4a2713aSLionel Sambuc // This contains code dealing with generation of the layout of virtual table 11*f4a2713aSLionel Sambuc // tables (VTT). 12*f4a2713aSLionel Sambuc // 13*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 14*f4a2713aSLionel Sambuc 15*f4a2713aSLionel Sambuc #include "clang/AST/VTTBuilder.h" 16*f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h" 17*f4a2713aSLionel Sambuc #include "clang/AST/CXXInheritance.h" 18*f4a2713aSLionel Sambuc #include "clang/AST/RecordLayout.h" 19*f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h" 20*f4a2713aSLionel Sambuc #include "llvm/Support/Format.h" 21*f4a2713aSLionel Sambuc #include <algorithm> 22*f4a2713aSLionel Sambuc #include <cstdio> 23*f4a2713aSLionel Sambuc 24*f4a2713aSLionel Sambuc using namespace clang; 25*f4a2713aSLionel Sambuc 26*f4a2713aSLionel Sambuc #define DUMP_OVERRIDERS 0 27*f4a2713aSLionel Sambuc 28*f4a2713aSLionel Sambuc VTTBuilder::VTTBuilder(ASTContext &Ctx, 29*f4a2713aSLionel Sambuc const CXXRecordDecl *MostDerivedClass, 30*f4a2713aSLionel Sambuc bool GenerateDefinition) 31*f4a2713aSLionel Sambuc : Ctx(Ctx), MostDerivedClass(MostDerivedClass), 32*f4a2713aSLionel Sambuc MostDerivedClassLayout(Ctx.getASTRecordLayout(MostDerivedClass)), 33*f4a2713aSLionel Sambuc GenerateDefinition(GenerateDefinition) { 34*f4a2713aSLionel Sambuc // Lay out this VTT. 35*f4a2713aSLionel Sambuc LayoutVTT(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 36*f4a2713aSLionel Sambuc /*BaseIsVirtual=*/false); 37*f4a2713aSLionel Sambuc } 38*f4a2713aSLionel Sambuc 39*f4a2713aSLionel Sambuc void VTTBuilder::AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex, 40*f4a2713aSLionel Sambuc const CXXRecordDecl *VTableClass) { 41*f4a2713aSLionel Sambuc // Store the vtable pointer index if we're generating the primary VTT. 42*f4a2713aSLionel Sambuc if (VTableClass == MostDerivedClass) { 43*f4a2713aSLionel Sambuc assert(!SecondaryVirtualPointerIndices.count(Base) && 44*f4a2713aSLionel Sambuc "A virtual pointer index already exists for this base subobject!"); 45*f4a2713aSLionel Sambuc SecondaryVirtualPointerIndices[Base] = VTTComponents.size(); 46*f4a2713aSLionel Sambuc } 47*f4a2713aSLionel Sambuc 48*f4a2713aSLionel Sambuc if (!GenerateDefinition) { 49*f4a2713aSLionel Sambuc VTTComponents.push_back(VTTComponent()); 50*f4a2713aSLionel Sambuc return; 51*f4a2713aSLionel Sambuc } 52*f4a2713aSLionel Sambuc 53*f4a2713aSLionel Sambuc VTTComponents.push_back(VTTComponent(VTableIndex, Base)); 54*f4a2713aSLionel Sambuc } 55*f4a2713aSLionel Sambuc 56*f4a2713aSLionel Sambuc void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) { 57*f4a2713aSLionel Sambuc const CXXRecordDecl *RD = Base.getBase(); 58*f4a2713aSLionel Sambuc 59*f4a2713aSLionel Sambuc for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 60*f4a2713aSLionel Sambuc E = RD->bases_end(); I != E; ++I) { 61*f4a2713aSLionel Sambuc 62*f4a2713aSLionel Sambuc // Don't layout virtual bases. 63*f4a2713aSLionel Sambuc if (I->isVirtual()) 64*f4a2713aSLionel Sambuc continue; 65*f4a2713aSLionel Sambuc 66*f4a2713aSLionel Sambuc const CXXRecordDecl *BaseDecl = 67*f4a2713aSLionel Sambuc cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 68*f4a2713aSLionel Sambuc 69*f4a2713aSLionel Sambuc const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); 70*f4a2713aSLionel Sambuc CharUnits BaseOffset = Base.getBaseOffset() + 71*f4a2713aSLionel Sambuc Layout.getBaseClassOffset(BaseDecl); 72*f4a2713aSLionel Sambuc 73*f4a2713aSLionel Sambuc // Layout the VTT for this base. 74*f4a2713aSLionel Sambuc LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false); 75*f4a2713aSLionel Sambuc } 76*f4a2713aSLionel Sambuc } 77*f4a2713aSLionel Sambuc 78*f4a2713aSLionel Sambuc void 79*f4a2713aSLionel Sambuc VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 80*f4a2713aSLionel Sambuc bool BaseIsMorallyVirtual, 81*f4a2713aSLionel Sambuc uint64_t VTableIndex, 82*f4a2713aSLionel Sambuc const CXXRecordDecl *VTableClass, 83*f4a2713aSLionel Sambuc VisitedVirtualBasesSetTy &VBases) { 84*f4a2713aSLionel Sambuc const CXXRecordDecl *RD = Base.getBase(); 85*f4a2713aSLionel Sambuc 86*f4a2713aSLionel Sambuc // We're not interested in bases that don't have virtual bases, and not 87*f4a2713aSLionel Sambuc // morally virtual bases. 88*f4a2713aSLionel Sambuc if (!RD->getNumVBases() && !BaseIsMorallyVirtual) 89*f4a2713aSLionel Sambuc return; 90*f4a2713aSLionel Sambuc 91*f4a2713aSLionel Sambuc for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 92*f4a2713aSLionel Sambuc E = RD->bases_end(); I != E; ++I) { 93*f4a2713aSLionel Sambuc const CXXRecordDecl *BaseDecl = 94*f4a2713aSLionel Sambuc cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 95*f4a2713aSLionel Sambuc 96*f4a2713aSLionel Sambuc // Itanium C++ ABI 2.6.2: 97*f4a2713aSLionel Sambuc // Secondary virtual pointers are present for all bases with either 98*f4a2713aSLionel Sambuc // virtual bases or virtual function declarations overridden along a 99*f4a2713aSLionel Sambuc // virtual path. 100*f4a2713aSLionel Sambuc // 101*f4a2713aSLionel Sambuc // If the base class is not dynamic, we don't want to add it, nor any 102*f4a2713aSLionel Sambuc // of its base classes. 103*f4a2713aSLionel Sambuc if (!BaseDecl->isDynamicClass()) 104*f4a2713aSLionel Sambuc continue; 105*f4a2713aSLionel Sambuc 106*f4a2713aSLionel Sambuc bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual; 107*f4a2713aSLionel Sambuc bool BaseDeclIsNonVirtualPrimaryBase = false; 108*f4a2713aSLionel Sambuc CharUnits BaseOffset; 109*f4a2713aSLionel Sambuc if (I->isVirtual()) { 110*f4a2713aSLionel Sambuc // Ignore virtual bases that we've already visited. 111*f4a2713aSLionel Sambuc if (!VBases.insert(BaseDecl)) 112*f4a2713aSLionel Sambuc continue; 113*f4a2713aSLionel Sambuc 114*f4a2713aSLionel Sambuc BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 115*f4a2713aSLionel Sambuc BaseDeclIsMorallyVirtual = true; 116*f4a2713aSLionel Sambuc } else { 117*f4a2713aSLionel Sambuc const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); 118*f4a2713aSLionel Sambuc 119*f4a2713aSLionel Sambuc BaseOffset = Base.getBaseOffset() + 120*f4a2713aSLionel Sambuc Layout.getBaseClassOffset(BaseDecl); 121*f4a2713aSLionel Sambuc 122*f4a2713aSLionel Sambuc if (!Layout.isPrimaryBaseVirtual() && 123*f4a2713aSLionel Sambuc Layout.getPrimaryBase() == BaseDecl) 124*f4a2713aSLionel Sambuc BaseDeclIsNonVirtualPrimaryBase = true; 125*f4a2713aSLionel Sambuc } 126*f4a2713aSLionel Sambuc 127*f4a2713aSLionel Sambuc // Itanium C++ ABI 2.6.2: 128*f4a2713aSLionel Sambuc // Secondary virtual pointers: for each base class X which (a) has virtual 129*f4a2713aSLionel Sambuc // bases or is reachable along a virtual path from D, and (b) is not a 130*f4a2713aSLionel Sambuc // non-virtual primary base, the address of the virtual table for X-in-D 131*f4a2713aSLionel Sambuc // or an appropriate construction virtual table. 132*f4a2713aSLionel Sambuc if (!BaseDeclIsNonVirtualPrimaryBase && 133*f4a2713aSLionel Sambuc (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) { 134*f4a2713aSLionel Sambuc // Add the vtable pointer. 135*f4a2713aSLionel Sambuc AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTableIndex, 136*f4a2713aSLionel Sambuc VTableClass); 137*f4a2713aSLionel Sambuc } 138*f4a2713aSLionel Sambuc 139*f4a2713aSLionel Sambuc // And lay out the secondary virtual pointers for the base class. 140*f4a2713aSLionel Sambuc LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset), 141*f4a2713aSLionel Sambuc BaseDeclIsMorallyVirtual, VTableIndex, 142*f4a2713aSLionel Sambuc VTableClass, VBases); 143*f4a2713aSLionel Sambuc } 144*f4a2713aSLionel Sambuc } 145*f4a2713aSLionel Sambuc 146*f4a2713aSLionel Sambuc void 147*f4a2713aSLionel Sambuc VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 148*f4a2713aSLionel Sambuc uint64_t VTableIndex) { 149*f4a2713aSLionel Sambuc VisitedVirtualBasesSetTy VBases; 150*f4a2713aSLionel Sambuc LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false, 151*f4a2713aSLionel Sambuc VTableIndex, Base.getBase(), VBases); 152*f4a2713aSLionel Sambuc } 153*f4a2713aSLionel Sambuc 154*f4a2713aSLionel Sambuc void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD, 155*f4a2713aSLionel Sambuc VisitedVirtualBasesSetTy &VBases) { 156*f4a2713aSLionel Sambuc for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 157*f4a2713aSLionel Sambuc E = RD->bases_end(); I != E; ++I) { 158*f4a2713aSLionel Sambuc const CXXRecordDecl *BaseDecl = 159*f4a2713aSLionel Sambuc cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 160*f4a2713aSLionel Sambuc 161*f4a2713aSLionel Sambuc // Check if this is a virtual base. 162*f4a2713aSLionel Sambuc if (I->isVirtual()) { 163*f4a2713aSLionel Sambuc // Check if we've seen this base before. 164*f4a2713aSLionel Sambuc if (!VBases.insert(BaseDecl)) 165*f4a2713aSLionel Sambuc continue; 166*f4a2713aSLionel Sambuc 167*f4a2713aSLionel Sambuc CharUnits BaseOffset = 168*f4a2713aSLionel Sambuc MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 169*f4a2713aSLionel Sambuc 170*f4a2713aSLionel Sambuc LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true); 171*f4a2713aSLionel Sambuc } 172*f4a2713aSLionel Sambuc 173*f4a2713aSLionel Sambuc // We only need to layout virtual VTTs for this base if it actually has 174*f4a2713aSLionel Sambuc // virtual bases. 175*f4a2713aSLionel Sambuc if (BaseDecl->getNumVBases()) 176*f4a2713aSLionel Sambuc LayoutVirtualVTTs(BaseDecl, VBases); 177*f4a2713aSLionel Sambuc } 178*f4a2713aSLionel Sambuc } 179*f4a2713aSLionel Sambuc 180*f4a2713aSLionel Sambuc void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) { 181*f4a2713aSLionel Sambuc const CXXRecordDecl *RD = Base.getBase(); 182*f4a2713aSLionel Sambuc 183*f4a2713aSLionel Sambuc // Itanium C++ ABI 2.6.2: 184*f4a2713aSLionel Sambuc // An array of virtual table addresses, called the VTT, is declared for 185*f4a2713aSLionel Sambuc // each class type that has indirect or direct virtual base classes. 186*f4a2713aSLionel Sambuc if (RD->getNumVBases() == 0) 187*f4a2713aSLionel Sambuc return; 188*f4a2713aSLionel Sambuc 189*f4a2713aSLionel Sambuc bool IsPrimaryVTT = Base.getBase() == MostDerivedClass; 190*f4a2713aSLionel Sambuc 191*f4a2713aSLionel Sambuc if (!IsPrimaryVTT) { 192*f4a2713aSLionel Sambuc // Remember the sub-VTT index. 193*f4a2713aSLionel Sambuc SubVTTIndicies[Base] = VTTComponents.size(); 194*f4a2713aSLionel Sambuc } 195*f4a2713aSLionel Sambuc 196*f4a2713aSLionel Sambuc uint64_t VTableIndex = VTTVTables.size(); 197*f4a2713aSLionel Sambuc VTTVTables.push_back(VTTVTable(Base, BaseIsVirtual)); 198*f4a2713aSLionel Sambuc 199*f4a2713aSLionel Sambuc // Add the primary vtable pointer. 200*f4a2713aSLionel Sambuc AddVTablePointer(Base, VTableIndex, RD); 201*f4a2713aSLionel Sambuc 202*f4a2713aSLionel Sambuc // Add the secondary VTTs. 203*f4a2713aSLionel Sambuc LayoutSecondaryVTTs(Base); 204*f4a2713aSLionel Sambuc 205*f4a2713aSLionel Sambuc // Add the secondary virtual pointers. 206*f4a2713aSLionel Sambuc LayoutSecondaryVirtualPointers(Base, VTableIndex); 207*f4a2713aSLionel Sambuc 208*f4a2713aSLionel Sambuc // If this is the primary VTT, we want to lay out virtual VTTs as well. 209*f4a2713aSLionel Sambuc if (IsPrimaryVTT) { 210*f4a2713aSLionel Sambuc VisitedVirtualBasesSetTy VBases; 211*f4a2713aSLionel Sambuc LayoutVirtualVTTs(Base.getBase(), VBases); 212*f4a2713aSLionel Sambuc } 213*f4a2713aSLionel Sambuc } 214