clang API Documentation
00001 //===--- CGVTT.cpp - Emit LLVM Code for C++ VTTs --------------------------===// 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 C++ code generation of VTTs (vtable tables). 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "CodeGenModule.h" 00015 #include "clang/AST/RecordLayout.h" 00016 using namespace clang; 00017 using namespace CodeGen; 00018 00019 #define D1(x) 00020 00021 namespace { 00022 00023 /// VTT builder - Class for building VTT layout information. 00024 class VTTBuilder { 00025 00026 CodeGenModule &CGM; 00027 00028 /// MostDerivedClass - The most derived class for which we're building this 00029 /// vtable. 00030 const CXXRecordDecl *MostDerivedClass; 00031 00032 typedef llvm::SmallVector<llvm::Constant *, 64> VTTComponentsVectorTy; 00033 00034 /// VTTComponents - The VTT components. 00035 VTTComponentsVectorTy VTTComponents; 00036 00037 /// MostDerivedClassLayout - the AST record layout of the most derived class. 00038 const ASTRecordLayout &MostDerivedClassLayout; 00039 00040 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; 00041 00042 typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy; 00043 00044 /// SubVTTIndicies - The sub-VTT indices for the bases of the most derived 00045 /// class. 00046 llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies; 00047 00048 /// SecondaryVirtualPointerIndices - The secondary virtual pointer indices of 00049 /// all subobjects of the most derived class. 00050 llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices; 00051 00052 /// GenerateDefinition - Whether the VTT builder should generate LLVM IR for 00053 /// the VTT. 00054 bool GenerateDefinition; 00055 00056 /// GetAddrOfVTable - Returns the address of the vtable for the base class in 00057 /// the given vtable class. 00058 /// 00059 /// \param AddressPoints - If the returned vtable is a construction vtable, 00060 /// this will hold the address points for it. 00061 llvm::Constant *GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual, 00062 AddressPointsMapTy& AddressPoints); 00063 00064 /// AddVTablePointer - Add a vtable pointer to the VTT currently being built. 00065 /// 00066 /// \param AddressPoints - If the vtable is a construction vtable, this has 00067 /// the address points for it. 00068 void AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable, 00069 const CXXRecordDecl *VTableClass, 00070 const AddressPointsMapTy& AddressPoints); 00071 00072 /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base 00073 /// subobject. 00074 void LayoutSecondaryVTTs(BaseSubobject Base); 00075 00076 /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers 00077 /// for the given base subobject. 00078 /// 00079 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base 00080 /// or a direct or indirect base of a virtual base. 00081 /// 00082 /// \param AddressPoints - If the vtable is a construction vtable, this has 00083 /// the address points for it. 00084 void LayoutSecondaryVirtualPointers(BaseSubobject Base, 00085 bool BaseIsMorallyVirtual, 00086 llvm::Constant *VTable, 00087 const CXXRecordDecl *VTableClass, 00088 const AddressPointsMapTy& AddressPoints, 00089 VisitedVirtualBasesSetTy &VBases); 00090 00091 /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers 00092 /// for the given base subobject. 00093 /// 00094 /// \param AddressPoints - If the vtable is a construction vtable, this has 00095 /// the address points for it. 00096 void LayoutSecondaryVirtualPointers(BaseSubobject Base, 00097 llvm::Constant *VTable, 00098 const AddressPointsMapTy& AddressPoints); 00099 00100 /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the 00101 /// given record decl. 00102 void LayoutVirtualVTTs(const CXXRecordDecl *RD, 00103 VisitedVirtualBasesSetTy &VBases); 00104 00105 /// LayoutVTT - Will lay out the VTT for the given subobject, including any 00106 /// secondary VTTs, secondary virtual pointers and virtual VTTs. 00107 void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual); 00108 00109 public: 00110 VTTBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerivedClass, 00111 bool GenerateDefinition); 00112 00113 // getVTTComponents - Returns a reference to the VTT components. 00114 const VTTComponentsVectorTy &getVTTComponents() const { 00115 return VTTComponents; 00116 } 00117 00118 /// getSubVTTIndicies - Returns a reference to the sub-VTT indices. 00119 const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const { 00120 return SubVTTIndicies; 00121 } 00122 00123 /// getSecondaryVirtualPointerIndices - Returns a reference to the secondary 00124 /// virtual pointer indices. 00125 const llvm::DenseMap<BaseSubobject, uint64_t> & 00126 getSecondaryVirtualPointerIndices() const { 00127 return SecondaryVirtualPointerIndices; 00128 } 00129 00130 }; 00131 00132 VTTBuilder::VTTBuilder(CodeGenModule &CGM, 00133 const CXXRecordDecl *MostDerivedClass, 00134 bool GenerateDefinition) 00135 : CGM(CGM), MostDerivedClass(MostDerivedClass), 00136 MostDerivedClassLayout(CGM.getContext().getASTRecordLayout(MostDerivedClass)), 00137 GenerateDefinition(GenerateDefinition) { 00138 00139 // Lay out this VTT. 00140 LayoutVTT(BaseSubobject(MostDerivedClass, 0), /*BaseIsVirtual=*/false); 00141 } 00142 00143 llvm::Constant * 00144 VTTBuilder::GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual, 00145 AddressPointsMapTy& AddressPoints) { 00146 if (!GenerateDefinition) 00147 return 0; 00148 00149 if (Base.getBase() == MostDerivedClass) { 00150 assert(Base.getBaseOffset() == 0 && 00151 "Most derived class vtable must have a zero offset!"); 00152 // This is a regular vtable. 00153 return CGM.getVTables().GetAddrOfVTable(MostDerivedClass); 00154 } 00155 00156 return CGM.getVTables().GenerateConstructionVTable(MostDerivedClass, 00157 Base, BaseIsVirtual, 00158 AddressPoints); 00159 } 00160 00161 void VTTBuilder::AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable, 00162 const CXXRecordDecl *VTableClass, 00163 const AddressPointsMapTy& AddressPoints) { 00164 // Store the vtable pointer index if we're generating the primary VTT. 00165 if (VTableClass == MostDerivedClass) { 00166 assert(!SecondaryVirtualPointerIndices.count(Base) && 00167 "A virtual pointer index already exists for this base subobject!"); 00168 SecondaryVirtualPointerIndices[Base] = VTTComponents.size(); 00169 } 00170 00171 if (!GenerateDefinition) { 00172 VTTComponents.push_back(0); 00173 return; 00174 } 00175 00176 uint64_t AddressPoint; 00177 if (VTableClass != MostDerivedClass) { 00178 // The vtable is a construction vtable, look in the construction vtable 00179 // address points. 00180 AddressPoint = AddressPoints.lookup(Base); 00181 assert(AddressPoint != 0 && "Did not find ctor vtable address point!"); 00182 } else { 00183 // Just get the address point for the regular vtable. 00184 AddressPoint = CGM.getVTables().getAddressPoint(Base, VTableClass); 00185 assert(AddressPoint != 0 && "Did not find vtable address point!"); 00186 } 00187 00188 if (!AddressPoint) AddressPoint = 0; 00189 00190 llvm::Value *Idxs[] = { 00191 llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0), 00192 llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()), 00193 AddressPoint) 00194 }; 00195 00196 llvm::Constant *Init = 00197 llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Idxs, 2); 00198 00199 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 00200 Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy); 00201 00202 VTTComponents.push_back(Init); 00203 } 00204 00205 void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) { 00206 const CXXRecordDecl *RD = Base.getBase(); 00207 00208 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 00209 E = RD->bases_end(); I != E; ++I) { 00210 00211 // Don't layout virtual bases. 00212 if (I->isVirtual()) 00213 continue; 00214 00215 const CXXRecordDecl *BaseDecl = 00216 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 00217 00218 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); 00219 uint64_t BaseOffset = Base.getBaseOffset() + 00220 Layout.getBaseClassOffset(BaseDecl); 00221 00222 // Layout the VTT for this base. 00223 LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false); 00224 } 00225 } 00226 00227 void 00228 VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 00229 bool BaseIsMorallyVirtual, 00230 llvm::Constant *VTable, 00231 const CXXRecordDecl *VTableClass, 00232 const AddressPointsMapTy& AddressPoints, 00233 VisitedVirtualBasesSetTy &VBases) { 00234 const CXXRecordDecl *RD = Base.getBase(); 00235 00236 // We're not interested in bases that don't have virtual bases, and not 00237 // morally virtual bases. 00238 if (!RD->getNumVBases() && !BaseIsMorallyVirtual) 00239 return; 00240 00241 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 00242 E = RD->bases_end(); I != E; ++I) { 00243 const CXXRecordDecl *BaseDecl = 00244 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 00245 00246 // Itanium C++ ABI 2.6.2: 00247 // Secondary virtual pointers are present for all bases with either 00248 // virtual bases or virtual function declarations overridden along a 00249 // virtual path. 00250 // 00251 // If the base class is not dynamic, we don't want to add it, nor any 00252 // of its base classes. 00253 if (!BaseDecl->isDynamicClass()) 00254 continue; 00255 00256 bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual; 00257 bool BaseDeclIsNonVirtualPrimaryBase = false; 00258 uint64_t BaseOffset; 00259 if (I->isVirtual()) { 00260 // Ignore virtual bases that we've already visited. 00261 if (!VBases.insert(BaseDecl)) 00262 continue; 00263 00264 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 00265 BaseDeclIsMorallyVirtual = true; 00266 } else { 00267 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); 00268 00269 BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl); 00270 00271 if (!Layout.getPrimaryBaseWasVirtual() && 00272 Layout.getPrimaryBase() == BaseDecl) 00273 BaseDeclIsNonVirtualPrimaryBase = true; 00274 } 00275 00276 // Itanium C++ ABI 2.6.2: 00277 // Secondary virtual pointers: for each base class X which (a) has virtual 00278 // bases or is reachable along a virtual path from D, and (b) is not a 00279 // non-virtual primary base, the address of the virtual table for X-in-D 00280 // or an appropriate construction virtual table. 00281 if (!BaseDeclIsNonVirtualPrimaryBase && 00282 (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) { 00283 // Add the vtable pointer. 00284 AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTable, VTableClass, 00285 AddressPoints); 00286 } 00287 00288 // And lay out the secondary virtual pointers for the base class. 00289 LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset), 00290 BaseDeclIsMorallyVirtual, VTable, 00291 VTableClass, AddressPoints, VBases); 00292 } 00293 } 00294 00295 void 00296 VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 00297 llvm::Constant *VTable, 00298 const AddressPointsMapTy& AddressPoints) { 00299 VisitedVirtualBasesSetTy VBases; 00300 LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false, 00301 VTable, Base.getBase(), AddressPoints, VBases); 00302 } 00303 00304 void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD, 00305 VisitedVirtualBasesSetTy &VBases) { 00306 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 00307 E = RD->bases_end(); I != E; ++I) { 00308 const CXXRecordDecl *BaseDecl = 00309 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 00310 00311 // Check if this is a virtual base. 00312 if (I->isVirtual()) { 00313 // Check if we've seen this base before. 00314 if (!VBases.insert(BaseDecl)) 00315 continue; 00316 00317 uint64_t BaseOffset = 00318 MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 00319 00320 LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true); 00321 } 00322 00323 // We only need to layout virtual VTTs for this base if it actually has 00324 // virtual bases. 00325 if (BaseDecl->getNumVBases()) 00326 LayoutVirtualVTTs(BaseDecl, VBases); 00327 } 00328 } 00329 00330 void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) { 00331 const CXXRecordDecl *RD = Base.getBase(); 00332 00333 // Itanium C++ ABI 2.6.2: 00334 // An array of virtual table addresses, called the VTT, is declared for 00335 // each class type that has indirect or direct virtual base classes. 00336 if (RD->getNumVBases() == 0) 00337 return; 00338 00339 bool IsPrimaryVTT = Base.getBase() == MostDerivedClass; 00340 00341 if (!IsPrimaryVTT) { 00342 // Remember the sub-VTT index. 00343 SubVTTIndicies[Base] = VTTComponents.size(); 00344 } 00345 00346 AddressPointsMapTy AddressPoints; 00347 llvm::Constant *VTable = GetAddrOfVTable(Base, BaseIsVirtual, AddressPoints); 00348 00349 // Add the primary vtable pointer. 00350 AddVTablePointer(Base, VTable, RD, AddressPoints); 00351 00352 // Add the secondary VTTs. 00353 LayoutSecondaryVTTs(Base); 00354 00355 // Add the secondary virtual pointers. 00356 LayoutSecondaryVirtualPointers(Base, VTable, AddressPoints); 00357 00358 // If this is the primary VTT, we want to lay out virtual VTTs as well. 00359 if (IsPrimaryVTT) { 00360 VisitedVirtualBasesSetTy VBases; 00361 LayoutVirtualVTTs(Base.getBase(), VBases); 00362 } 00363 } 00364 00365 } 00366 00367 llvm::GlobalVariable * 00368 CodeGenVTables::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage, 00369 bool GenerateDefinition, 00370 const CXXRecordDecl *RD) { 00371 // Only classes that have virtual bases need a VTT. 00372 if (RD->getNumVBases() == 0) 00373 return 0; 00374 00375 llvm::SmallString<256> OutName; 00376 CGM.getMangleContext().mangleCXXVTT(RD, OutName); 00377 llvm::StringRef Name = OutName.str(); 00378 00379 D1(printf("vtt %s\n", RD->getNameAsCString())); 00380 00381 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 00382 if (GV == 0 || GV->isDeclaration()) { 00383 const llvm::Type *Int8PtrTy = 00384 llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 00385 00386 VTTBuilder Builder(CGM, RD, GenerateDefinition); 00387 00388 const llvm::ArrayType *Type = 00389 llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size()); 00390 00391 llvm::Constant *Init = 0; 00392 if (GenerateDefinition) 00393 Init = llvm::ConstantArray::get(Type, Builder.getVTTComponents().data(), 00394 Builder.getVTTComponents().size()); 00395 00396 llvm::GlobalVariable *OldGV = GV; 00397 GV = new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true, 00398 Linkage, Init, Name); 00399 CGM.setGlobalVisibility(GV, RD); 00400 00401 if (OldGV) { 00402 GV->takeName(OldGV); 00403 llvm::Constant *NewPtr = 00404 llvm::ConstantExpr::getBitCast(GV, OldGV->getType()); 00405 OldGV->replaceAllUsesWith(NewPtr); 00406 OldGV->eraseFromParent(); 00407 } 00408 } 00409 00410 return GV; 00411 } 00412 00413 llvm::GlobalVariable *CodeGenVTables::getVTT(const CXXRecordDecl *RD) { 00414 return GenerateVTT(llvm::GlobalValue::ExternalLinkage, 00415 /*GenerateDefinition=*/false, RD); 00416 } 00417 00418 bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) { 00419 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 00420 00421 // We don't have any virtual bases, just return early. 00422 if (!MD->getParent()->getNumVBases()) 00423 return false; 00424 00425 // Check if we have a base constructor. 00426 if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base) 00427 return true; 00428 00429 // Check if we have a base destructor. 00430 if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) 00431 return true; 00432 00433 return false; 00434 } 00435 00436 uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD, 00437 BaseSubobject Base) { 00438 BaseSubobjectPairTy ClassSubobjectPair(RD, Base); 00439 00440 SubVTTIndiciesMapTy::iterator I = SubVTTIndicies.find(ClassSubobjectPair); 00441 if (I != SubVTTIndicies.end()) 00442 return I->second; 00443 00444 VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false); 00445 00446 for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I = 00447 Builder.getSubVTTIndicies().begin(), 00448 E = Builder.getSubVTTIndicies().end(); I != E; ++I) { 00449 // Insert all indices. 00450 BaseSubobjectPairTy ClassSubobjectPair(RD, I->first); 00451 00452 SubVTTIndicies.insert(std::make_pair(ClassSubobjectPair, I->second)); 00453 } 00454 00455 I = SubVTTIndicies.find(ClassSubobjectPair); 00456 assert(I != SubVTTIndicies.end() && "Did not find index!"); 00457 00458 return I->second; 00459 } 00460 00461 uint64_t 00462 CodeGenVTables::getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD, 00463 BaseSubobject Base) { 00464 SecondaryVirtualPointerIndicesMapTy::iterator I = 00465 SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base)); 00466 00467 if (I != SecondaryVirtualPointerIndices.end()) 00468 return I->second; 00469 00470 VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false); 00471 00472 // Insert all secondary vpointer indices. 00473 for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I = 00474 Builder.getSecondaryVirtualPointerIndices().begin(), 00475 E = Builder.getSecondaryVirtualPointerIndices().end(); I != E; ++I) { 00476 std::pair<const CXXRecordDecl *, BaseSubobject> Pair = 00477 std::make_pair(RD, I->first); 00478 00479 SecondaryVirtualPointerIndices.insert(std::make_pair(Pair, I->second)); 00480 } 00481 00482 I = SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base)); 00483 assert(I != SecondaryVirtualPointerIndices.end() && "Did not find index!"); 00484 00485 return I->second; 00486 } 00487