clang API Documentation
00001 //===--- VTTBuilder.cpp - C++ VTT layout builder --------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This contains code dealing with generation of the layout of virtual table 00011 // tables (VTT). 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "clang/AST/VTTBuilder.h" 00016 #include "clang/AST/ASTContext.h" 00017 #include "clang/AST/CXXInheritance.h" 00018 #include "clang/AST/RecordLayout.h" 00019 #include "clang/Basic/TargetInfo.h" 00020 #include "llvm/Support/Format.h" 00021 #include <algorithm> 00022 #include <cstdio> 00023 00024 using namespace clang; 00025 00026 #define DUMP_OVERRIDERS 0 00027 00028 VTTBuilder::VTTBuilder(ASTContext &Ctx, 00029 const CXXRecordDecl *MostDerivedClass, 00030 bool GenerateDefinition) 00031 : Ctx(Ctx), MostDerivedClass(MostDerivedClass), 00032 MostDerivedClassLayout(Ctx.getASTRecordLayout(MostDerivedClass)), 00033 GenerateDefinition(GenerateDefinition) { 00034 // Lay out this VTT. 00035 LayoutVTT(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 00036 /*BaseIsVirtual=*/false); 00037 } 00038 00039 void VTTBuilder::AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex, 00040 const CXXRecordDecl *VTableClass) { 00041 // Store the vtable pointer index if we're generating the primary VTT. 00042 if (VTableClass == MostDerivedClass) { 00043 assert(!SecondaryVirtualPointerIndices.count(Base) && 00044 "A virtual pointer index already exists for this base subobject!"); 00045 SecondaryVirtualPointerIndices[Base] = VTTComponents.size(); 00046 } 00047 00048 if (!GenerateDefinition) { 00049 VTTComponents.push_back(VTTComponent()); 00050 return; 00051 } 00052 00053 VTTComponents.push_back(VTTComponent(VTableIndex, Base)); 00054 } 00055 00056 void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) { 00057 const CXXRecordDecl *RD = Base.getBase(); 00058 00059 for (const auto &I : RD->bases()) { 00060 // Don't layout virtual bases. 00061 if (I.isVirtual()) 00062 continue; 00063 00064 const CXXRecordDecl *BaseDecl = 00065 cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl()); 00066 00067 const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); 00068 CharUnits BaseOffset = Base.getBaseOffset() + 00069 Layout.getBaseClassOffset(BaseDecl); 00070 00071 // Layout the VTT for this base. 00072 LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false); 00073 } 00074 } 00075 00076 void 00077 VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 00078 bool BaseIsMorallyVirtual, 00079 uint64_t VTableIndex, 00080 const CXXRecordDecl *VTableClass, 00081 VisitedVirtualBasesSetTy &VBases) { 00082 const CXXRecordDecl *RD = Base.getBase(); 00083 00084 // We're not interested in bases that don't have virtual bases, and not 00085 // morally virtual bases. 00086 if (!RD->getNumVBases() && !BaseIsMorallyVirtual) 00087 return; 00088 00089 for (const auto &I : RD->bases()) { 00090 const CXXRecordDecl *BaseDecl = 00091 cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl()); 00092 00093 // Itanium C++ ABI 2.6.2: 00094 // Secondary virtual pointers are present for all bases with either 00095 // virtual bases or virtual function declarations overridden along a 00096 // virtual path. 00097 // 00098 // If the base class is not dynamic, we don't want to add it, nor any 00099 // of its base classes. 00100 if (!BaseDecl->isDynamicClass()) 00101 continue; 00102 00103 bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual; 00104 bool BaseDeclIsNonVirtualPrimaryBase = false; 00105 CharUnits BaseOffset; 00106 if (I.isVirtual()) { 00107 // Ignore virtual bases that we've already visited. 00108 if (!VBases.insert(BaseDecl)) 00109 continue; 00110 00111 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 00112 BaseDeclIsMorallyVirtual = true; 00113 } else { 00114 const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); 00115 00116 BaseOffset = Base.getBaseOffset() + 00117 Layout.getBaseClassOffset(BaseDecl); 00118 00119 if (!Layout.isPrimaryBaseVirtual() && 00120 Layout.getPrimaryBase() == BaseDecl) 00121 BaseDeclIsNonVirtualPrimaryBase = true; 00122 } 00123 00124 // Itanium C++ ABI 2.6.2: 00125 // Secondary virtual pointers: for each base class X which (a) has virtual 00126 // bases or is reachable along a virtual path from D, and (b) is not a 00127 // non-virtual primary base, the address of the virtual table for X-in-D 00128 // or an appropriate construction virtual table. 00129 if (!BaseDeclIsNonVirtualPrimaryBase && 00130 (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) { 00131 // Add the vtable pointer. 00132 AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTableIndex, 00133 VTableClass); 00134 } 00135 00136 // And lay out the secondary virtual pointers for the base class. 00137 LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset), 00138 BaseDeclIsMorallyVirtual, VTableIndex, 00139 VTableClass, VBases); 00140 } 00141 } 00142 00143 void 00144 VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 00145 uint64_t VTableIndex) { 00146 VisitedVirtualBasesSetTy VBases; 00147 LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false, 00148 VTableIndex, Base.getBase(), VBases); 00149 } 00150 00151 void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD, 00152 VisitedVirtualBasesSetTy &VBases) { 00153 for (const auto &I : RD->bases()) { 00154 const CXXRecordDecl *BaseDecl = 00155 cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl()); 00156 00157 // Check if this is a virtual base. 00158 if (I.isVirtual()) { 00159 // Check if we've seen this base before. 00160 if (!VBases.insert(BaseDecl)) 00161 continue; 00162 00163 CharUnits BaseOffset = 00164 MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 00165 00166 LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true); 00167 } 00168 00169 // We only need to layout virtual VTTs for this base if it actually has 00170 // virtual bases. 00171 if (BaseDecl->getNumVBases()) 00172 LayoutVirtualVTTs(BaseDecl, VBases); 00173 } 00174 } 00175 00176 void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) { 00177 const CXXRecordDecl *RD = Base.getBase(); 00178 00179 // Itanium C++ ABI 2.6.2: 00180 // An array of virtual table addresses, called the VTT, is declared for 00181 // each class type that has indirect or direct virtual base classes. 00182 if (RD->getNumVBases() == 0) 00183 return; 00184 00185 bool IsPrimaryVTT = Base.getBase() == MostDerivedClass; 00186 00187 if (!IsPrimaryVTT) { 00188 // Remember the sub-VTT index. 00189 SubVTTIndicies[Base] = VTTComponents.size(); 00190 } 00191 00192 uint64_t VTableIndex = VTTVTables.size(); 00193 VTTVTables.push_back(VTTVTable(Base, BaseIsVirtual)); 00194 00195 // Add the primary vtable pointer. 00196 AddVTablePointer(Base, VTableIndex, RD); 00197 00198 // Add the secondary VTTs. 00199 LayoutSecondaryVTTs(Base); 00200 00201 // Add the secondary virtual pointers. 00202 LayoutSecondaryVirtualPointers(Base, VTableIndex); 00203 00204 // If this is the primary VTT, we want to lay out virtual VTTs as well. 00205 if (IsPrimaryVTT) { 00206 VisitedVirtualBasesSetTy VBases; 00207 LayoutVirtualVTTs(Base.getBase(), VBases); 00208 } 00209 }