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