15c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne//===--- VTTBuilder.cpp - C++ VTT layout builder --------------------------===// 25c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne// 35c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne// The LLVM Compiler Infrastructure 45c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne// 55c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne// This file is distributed under the University of Illinois Open Source 65c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne// License. See LICENSE.TXT for details. 75c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne// 85c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne//===----------------------------------------------------------------------===// 95c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne// 105c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne// This contains code dealing with generation of the layout of virtual table 115c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne// tables (VTT). 125c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne// 135c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne//===----------------------------------------------------------------------===// 145c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 155c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne#include "clang/AST/VTTBuilder.h" 16d4f5198ae07d9a4958d8191bac694ded12173ad9Benjamin Kramer#include "clang/AST/ASTContext.h" 175c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne#include "clang/AST/CXXInheritance.h" 185c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne#include "clang/AST/RecordLayout.h" 195c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne#include "clang/Basic/TargetInfo.h" 205c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne#include "llvm/Support/Format.h" 215c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne#include <algorithm> 225c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne#include <cstdio> 235c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 245c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourneusing namespace clang; 255c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 265c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne#define DUMP_OVERRIDERS 0 275c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 285c551f7aef7db952eca6133366e5afa9e37ab0b7Peter CollingbourneVTTBuilder::VTTBuilder(ASTContext &Ctx, 295c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne const CXXRecordDecl *MostDerivedClass, 305c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne bool GenerateDefinition) 315c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne : Ctx(Ctx), MostDerivedClass(MostDerivedClass), 325c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne MostDerivedClassLayout(Ctx.getASTRecordLayout(MostDerivedClass)), 335c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne GenerateDefinition(GenerateDefinition) { 345c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Lay out this VTT. 355c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne LayoutVTT(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 365c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne /*BaseIsVirtual=*/false); 375c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne} 385c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 395c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbournevoid VTTBuilder::AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex, 405c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne const CXXRecordDecl *VTableClass) { 415c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Store the vtable pointer index if we're generating the primary VTT. 425c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne if (VTableClass == MostDerivedClass) { 435c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne assert(!SecondaryVirtualPointerIndices.count(Base) && 445c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne "A virtual pointer index already exists for this base subobject!"); 455c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne SecondaryVirtualPointerIndices[Base] = VTTComponents.size(); 465c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne } 475c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 485c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne if (!GenerateDefinition) { 495c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne VTTComponents.push_back(VTTComponent()); 505c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne return; 515c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne } 525c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 535c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne VTTComponents.push_back(VTTComponent(VTableIndex, Base)); 545c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne} 555c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 565c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbournevoid VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) { 575c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne const CXXRecordDecl *RD = Base.getBase(); 585c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : RD->bases()) { 605c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Don't layout virtual bases. 61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (I.isVirtual()) 625c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne continue; 635c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 645c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne const CXXRecordDecl *BaseDecl = 65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl()); 665c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 675c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); 685c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne CharUnits BaseOffset = Base.getBaseOffset() + 695c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne Layout.getBaseClassOffset(BaseDecl); 705c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 715c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Layout the VTT for this base. 725c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false); 735c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne } 745c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne} 755c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 765c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbournevoid 775c551f7aef7db952eca6133366e5afa9e37ab0b7Peter CollingbourneVTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 785c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne bool BaseIsMorallyVirtual, 795c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne uint64_t VTableIndex, 805c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne const CXXRecordDecl *VTableClass, 815c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne VisitedVirtualBasesSetTy &VBases) { 825c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne const CXXRecordDecl *RD = Base.getBase(); 835c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 845c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // We're not interested in bases that don't have virtual bases, and not 855c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // morally virtual bases. 865c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne if (!RD->getNumVBases() && !BaseIsMorallyVirtual) 875c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne return; 885c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : RD->bases()) { 905c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne const CXXRecordDecl *BaseDecl = 91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl()); 925c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 935c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Itanium C++ ABI 2.6.2: 945c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Secondary virtual pointers are present for all bases with either 955c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // virtual bases or virtual function declarations overridden along a 965c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // virtual path. 975c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // 985c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // If the base class is not dynamic, we don't want to add it, nor any 995c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // of its base classes. 1005c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne if (!BaseDecl->isDynamicClass()) 1015c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne continue; 1025c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1035c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual; 1045c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne bool BaseDeclIsNonVirtualPrimaryBase = false; 1055c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne CharUnits BaseOffset; 106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (I.isVirtual()) { 1075c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Ignore virtual bases that we've already visited. 1085c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne if (!VBases.insert(BaseDecl)) 1095c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne continue; 1105c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1115c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 1125c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne BaseDeclIsMorallyVirtual = true; 1135c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne } else { 1145c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); 1155c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1165c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne BaseOffset = Base.getBaseOffset() + 1175c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne Layout.getBaseClassOffset(BaseDecl); 1185c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1195c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne if (!Layout.isPrimaryBaseVirtual() && 1205c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne Layout.getPrimaryBase() == BaseDecl) 1215c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne BaseDeclIsNonVirtualPrimaryBase = true; 1225c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne } 1235c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1245c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Itanium C++ ABI 2.6.2: 1255c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Secondary virtual pointers: for each base class X which (a) has virtual 1265c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // bases or is reachable along a virtual path from D, and (b) is not a 1275c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // non-virtual primary base, the address of the virtual table for X-in-D 1285c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // or an appropriate construction virtual table. 1295c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne if (!BaseDeclIsNonVirtualPrimaryBase && 1305c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) { 1315c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Add the vtable pointer. 1325c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTableIndex, 1335c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne VTableClass); 1345c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne } 1355c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1365c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // And lay out the secondary virtual pointers for the base class. 1375c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset), 1385c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne BaseDeclIsMorallyVirtual, VTableIndex, 1395c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne VTableClass, VBases); 1405c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne } 1415c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne} 1425c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1435c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbournevoid 1445c551f7aef7db952eca6133366e5afa9e37ab0b7Peter CollingbourneVTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 1455c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne uint64_t VTableIndex) { 1465c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne VisitedVirtualBasesSetTy VBases; 1475c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false, 1485c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne VTableIndex, Base.getBase(), VBases); 1495c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne} 1505c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1515c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbournevoid VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD, 1525c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne VisitedVirtualBasesSetTy &VBases) { 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : RD->bases()) { 1545c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne const CXXRecordDecl *BaseDecl = 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl()); 1565c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1575c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Check if this is a virtual base. 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (I.isVirtual()) { 1595c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Check if we've seen this base before. 1605c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne if (!VBases.insert(BaseDecl)) 1615c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne continue; 1625c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1635c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne CharUnits BaseOffset = 1645c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 1655c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1665c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true); 1675c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne } 1685c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1695c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // We only need to layout virtual VTTs for this base if it actually has 1705c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // virtual bases. 1715c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne if (BaseDecl->getNumVBases()) 1725c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne LayoutVirtualVTTs(BaseDecl, VBases); 1735c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne } 1745c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne} 1755c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1765c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbournevoid VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) { 1775c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne const CXXRecordDecl *RD = Base.getBase(); 1785c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1795c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Itanium C++ ABI 2.6.2: 1805c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // An array of virtual table addresses, called the VTT, is declared for 1815c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // each class type that has indirect or direct virtual base classes. 1825c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne if (RD->getNumVBases() == 0) 1835c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne return; 1845c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1855c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne bool IsPrimaryVTT = Base.getBase() == MostDerivedClass; 1865c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1875c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne if (!IsPrimaryVTT) { 1885c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Remember the sub-VTT index. 1895c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne SubVTTIndicies[Base] = VTTComponents.size(); 1905c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne } 1915c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1925c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne uint64_t VTableIndex = VTTVTables.size(); 1935c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne VTTVTables.push_back(VTTVTable(Base, BaseIsVirtual)); 1945c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1955c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Add the primary vtable pointer. 1965c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne AddVTablePointer(Base, VTableIndex, RD); 1975c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 1985c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Add the secondary VTTs. 1995c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne LayoutSecondaryVTTs(Base); 2005c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 2015c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // Add the secondary virtual pointers. 2025c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne LayoutSecondaryVirtualPointers(Base, VTableIndex); 2035c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne 2045c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne // If this is the primary VTT, we want to lay out virtual VTTs as well. 2055c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne if (IsPrimaryVTT) { 2065c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne VisitedVirtualBasesSetTy VBases; 2075c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne LayoutVirtualVTTs(Base.getBase(), VBases); 2085c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne } 2095c551f7aef7db952eca6133366e5afa9e37ab0b7Peter Collingbourne} 210