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