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