clang API Documentation
00001 //===--- CGVtable.cpp - Emit LLVM Code for C++ vtables --------------------===// 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 virtual tables. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "CodeGenModule.h" 00015 #include "CodeGenFunction.h" 00016 #include "clang/AST/CXXInheritance.h" 00017 #include "clang/AST/RecordLayout.h" 00018 #include "llvm/ADT/DenseSet.h" 00019 #include "llvm/ADT/SetVector.h" 00020 #include "llvm/Support/Compiler.h" 00021 #include "llvm/Support/Format.h" 00022 #include <cstdio> 00023 00024 using namespace clang; 00025 using namespace CodeGen; 00026 00027 namespace { 00028 00029 /// BaseOffset - Represents an offset from a derived class to a direct or 00030 /// indirect base class. 00031 struct BaseOffset { 00032 /// DerivedClass - The derived class. 00033 const CXXRecordDecl *DerivedClass; 00034 00035 /// VirtualBase - If the path from the derived class to the base class 00036 /// involves a virtual base class, this holds its declaration. 00037 const CXXRecordDecl *VirtualBase; 00038 00039 /// NonVirtualOffset - The offset from the derived class to the base class. 00040 /// (Or the offset from the virtual base class to the base class, if the 00041 /// path from the derived class to the base class involves a virtual base 00042 /// class. 00043 int64_t NonVirtualOffset; 00044 00045 BaseOffset() : DerivedClass(0), VirtualBase(0), NonVirtualOffset(0) { } 00046 BaseOffset(const CXXRecordDecl *DerivedClass, 00047 const CXXRecordDecl *VirtualBase, int64_t NonVirtualOffset) 00048 : DerivedClass(DerivedClass), VirtualBase(VirtualBase), 00049 NonVirtualOffset(NonVirtualOffset) { } 00050 00051 bool isEmpty() const { return !NonVirtualOffset && !VirtualBase; } 00052 }; 00053 00054 /// FinalOverriders - Contains the final overrider member functions for all 00055 /// member functions in the base subobjects of a class. 00056 class FinalOverriders { 00057 public: 00058 /// OverriderInfo - Information about a final overrider. 00059 struct OverriderInfo { 00060 /// Method - The method decl of the overrider. 00061 const CXXMethodDecl *Method; 00062 00063 /// Offset - the base offset of the overrider in the layout class. 00064 uint64_t Offset; 00065 00066 OverriderInfo() : Method(0), Offset(0) { } 00067 }; 00068 00069 private: 00070 /// MostDerivedClass - The most derived class for which the final overriders 00071 /// are stored. 00072 const CXXRecordDecl *MostDerivedClass; 00073 00074 /// MostDerivedClassOffset - If we're building final overriders for a 00075 /// construction vtable, this holds the offset from the layout class to the 00076 /// most derived class. 00077 const uint64_t MostDerivedClassOffset; 00078 00079 /// LayoutClass - The class we're using for layout information. Will be 00080 /// different than the most derived class if the final overriders are for a 00081 /// construction vtable. 00082 const CXXRecordDecl *LayoutClass; 00083 00084 ASTContext &Context; 00085 00086 /// MostDerivedClassLayout - the AST record layout of the most derived class. 00087 const ASTRecordLayout &MostDerivedClassLayout; 00088 00089 /// BaseSubobjectMethodPairTy - Uniquely identifies a member function 00090 /// in a base subobject. 00091 typedef std::pair<BaseSubobject, const CXXMethodDecl *> 00092 BaseSubobjectMethodPairTy; 00093 00094 typedef llvm::DenseMap<BaseSubobjectMethodPairTy, 00095 OverriderInfo> OverridersMapTy; 00096 00097 /// OverridersMap - The final overriders for all virtual member functions of 00098 /// all the base subobjects of the most derived class. 00099 OverridersMapTy OverridersMap; 00100 00101 /// VisitedVirtualBases - A set of all the visited virtual bases, used to 00102 /// avoid visiting virtual bases more than once. 00103 llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; 00104 00105 typedef llvm::DenseMap<BaseSubobjectMethodPairTy, BaseOffset> 00106 AdjustmentOffsetsMapTy; 00107 00108 /// ReturnAdjustments - Holds return adjustments for all the overriders that 00109 /// need to perform return value adjustments. 00110 AdjustmentOffsetsMapTy ReturnAdjustments; 00111 00112 // FIXME: We might be able to get away with making this a SmallSet. 00113 typedef llvm::SmallSetVector<uint64_t, 2> OffsetSetVectorTy; 00114 00115 /// SubobjectOffsetsMapTy - This map is used for keeping track of all the 00116 /// base subobject offsets that a single class declaration might refer to. 00117 /// 00118 /// For example, in: 00119 /// 00120 /// struct A { virtual void f(); }; 00121 /// struct B1 : A { }; 00122 /// struct B2 : A { }; 00123 /// struct C : B1, B2 { virtual void f(); }; 00124 /// 00125 /// when we determine that C::f() overrides A::f(), we need to update the 00126 /// overriders map for both A-in-B1 and A-in-B2 and the subobject offsets map 00127 /// will have the subobject offsets for both A copies. 00128 typedef llvm::DenseMap<const CXXRecordDecl *, OffsetSetVectorTy> 00129 SubobjectOffsetsMapTy; 00130 00131 /// ComputeFinalOverriders - Compute the final overriders for a given base 00132 /// subobject (and all its direct and indirect bases). 00133 void ComputeFinalOverriders(BaseSubobject Base, 00134 bool BaseSubobjectIsVisitedVBase, 00135 uint64_t OffsetInLayoutClass, 00136 SubobjectOffsetsMapTy &Offsets); 00137 00138 /// AddOverriders - Add the final overriders for this base subobject to the 00139 /// map of final overriders. 00140 void AddOverriders(BaseSubobject Base,uint64_t OffsetInLayoutClass, 00141 SubobjectOffsetsMapTy &Offsets); 00142 00143 /// PropagateOverrider - Propagate the NewMD overrider to all the functions 00144 /// that OldMD overrides. For example, if we have: 00145 /// 00146 /// struct A { virtual void f(); }; 00147 /// struct B : A { virtual void f(); }; 00148 /// struct C : B { virtual void f(); }; 00149 /// 00150 /// and we want to override B::f with C::f, we also need to override A::f with 00151 /// C::f. 00152 void PropagateOverrider(const CXXMethodDecl *OldMD, 00153 BaseSubobject NewBase, 00154 uint64_t OverriderOffsetInLayoutClass, 00155 const CXXMethodDecl *NewMD, 00156 SubobjectOffsetsMapTy &Offsets); 00157 00158 static void MergeSubobjectOffsets(const SubobjectOffsetsMapTy &NewOffsets, 00159 SubobjectOffsetsMapTy &Offsets); 00160 00161 public: 00162 FinalOverriders(const CXXRecordDecl *MostDerivedClass, 00163 uint64_t MostDerivedClassOffset, 00164 const CXXRecordDecl *LayoutClass); 00165 00166 /// getOverrider - Get the final overrider for the given method declaration in 00167 /// the given base subobject. 00168 OverriderInfo getOverrider(BaseSubobject Base, 00169 const CXXMethodDecl *MD) const { 00170 assert(OverridersMap.count(std::make_pair(Base, MD)) && 00171 "Did not find overrider!"); 00172 00173 return OverridersMap.lookup(std::make_pair(Base, MD)); 00174 } 00175 00176 /// getReturnAdjustmentOffset - Get the return adjustment offset for the 00177 /// method decl in the given base subobject. Returns an empty base offset if 00178 /// no adjustment is needed. 00179 BaseOffset getReturnAdjustmentOffset(BaseSubobject Base, 00180 const CXXMethodDecl *MD) const { 00181 return ReturnAdjustments.lookup(std::make_pair(Base, MD)); 00182 } 00183 00184 /// dump - dump the final overriders. 00185 void dump() { 00186 assert(VisitedVirtualBases.empty() && 00187 "Visited virtual bases aren't empty!"); 00188 dump(llvm::errs(), BaseSubobject(MostDerivedClass, 0)); 00189 VisitedVirtualBases.clear(); 00190 } 00191 00192 /// dump - dump the final overriders for a base subobject, and all its direct 00193 /// and indirect base subobjects. 00194 void dump(llvm::raw_ostream &Out, BaseSubobject Base); 00195 }; 00196 00197 #define DUMP_OVERRIDERS 0 00198 00199 FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass, 00200 uint64_t MostDerivedClassOffset, 00201 const CXXRecordDecl *LayoutClass) 00202 : MostDerivedClass(MostDerivedClass), 00203 MostDerivedClassOffset(MostDerivedClassOffset), LayoutClass(LayoutClass), 00204 Context(MostDerivedClass->getASTContext()), 00205 MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)) { 00206 00207 // Compute the final overriders. 00208 SubobjectOffsetsMapTy Offsets; 00209 ComputeFinalOverriders(BaseSubobject(MostDerivedClass, 0), 00210 /*BaseSubobjectIsVisitedVBase=*/false, 00211 MostDerivedClassOffset, Offsets); 00212 VisitedVirtualBases.clear(); 00213 00214 #if DUMP_OVERRIDERS 00215 // And dump them (for now). 00216 dump(); 00217 00218 // Also dump the base offsets (for now). 00219 for (SubobjectOffsetsMapTy::const_iterator I = Offsets.begin(), 00220 E = Offsets.end(); I != E; ++I) { 00221 const OffsetSetVectorTy& OffsetSetVector = I->second; 00222 00223 llvm::errs() << "Base offsets for "; 00224 llvm::errs() << I->first->getQualifiedNameAsString() << '\n'; 00225 00226 for (unsigned I = 0, E = OffsetSetVector.size(); I != E; ++I) 00227 llvm::errs() << " " << I << " - " << OffsetSetVector[I] / 8 << '\n'; 00228 } 00229 #endif 00230 } 00231 00232 void FinalOverriders::AddOverriders(BaseSubobject Base, 00233 uint64_t OffsetInLayoutClass, 00234 SubobjectOffsetsMapTy &Offsets) { 00235 const CXXRecordDecl *RD = Base.getBase(); 00236 00237 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 00238 E = RD->method_end(); I != E; ++I) { 00239 const CXXMethodDecl *MD = *I; 00240 00241 if (!MD->isVirtual()) 00242 continue; 00243 00244 // First, propagate the overrider. 00245 PropagateOverrider(MD, Base, OffsetInLayoutClass, MD, Offsets); 00246 00247 // Add the overrider as the final overrider of itself. 00248 OverriderInfo& Overrider = OverridersMap[std::make_pair(Base, MD)]; 00249 assert(!Overrider.Method && "Overrider should not exist yet!"); 00250 00251 Overrider.Offset = OffsetInLayoutClass; 00252 Overrider.Method = MD; 00253 } 00254 } 00255 00256 static BaseOffset ComputeBaseOffset(ASTContext &Context, 00257 const CXXRecordDecl *DerivedRD, 00258 const CXXBasePath &Path) { 00259 int64_t NonVirtualOffset = 0; 00260 00261 unsigned NonVirtualStart = 0; 00262 const CXXRecordDecl *VirtualBase = 0; 00263 00264 // First, look for the virtual base class. 00265 for (unsigned I = 0, E = Path.size(); I != E; ++I) { 00266 const CXXBasePathElement &Element = Path[I]; 00267 00268 if (Element.Base->isVirtual()) { 00269 // FIXME: Can we break when we find the first virtual base? 00270 // (If we can't, can't we just iterate over the path in reverse order?) 00271 NonVirtualStart = I + 1; 00272 QualType VBaseType = Element.Base->getType(); 00273 VirtualBase = 00274 cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl()); 00275 } 00276 } 00277 00278 // Now compute the non-virtual offset. 00279 for (unsigned I = NonVirtualStart, E = Path.size(); I != E; ++I) { 00280 const CXXBasePathElement &Element = Path[I]; 00281 00282 // Check the base class offset. 00283 const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class); 00284 00285 const RecordType *BaseType = Element.Base->getType()->getAs<RecordType>(); 00286 const CXXRecordDecl *Base = cast<CXXRecordDecl>(BaseType->getDecl()); 00287 00288 NonVirtualOffset += Layout.getBaseClassOffset(Base); 00289 } 00290 00291 // FIXME: This should probably use CharUnits or something. Maybe we should 00292 // even change the base offsets in ASTRecordLayout to be specified in 00293 // CharUnits. 00294 return BaseOffset(DerivedRD, VirtualBase, NonVirtualOffset / 8); 00295 00296 } 00297 00298 static BaseOffset ComputeBaseOffset(ASTContext &Context, 00299 const CXXRecordDecl *BaseRD, 00300 const CXXRecordDecl *DerivedRD) { 00301 CXXBasePaths Paths(/*FindAmbiguities=*/false, 00302 /*RecordPaths=*/true, /*DetectVirtual=*/false); 00303 00304 if (!const_cast<CXXRecordDecl *>(DerivedRD)-> 00305 isDerivedFrom(const_cast<CXXRecordDecl *>(BaseRD), Paths)) { 00306 assert(false && "Class must be derived from the passed in base class!"); 00307 return BaseOffset(); 00308 } 00309 00310 return ComputeBaseOffset(Context, DerivedRD, Paths.front()); 00311 } 00312 00313 static BaseOffset 00314 ComputeReturnAdjustmentBaseOffset(ASTContext &Context, 00315 const CXXMethodDecl *DerivedMD, 00316 const CXXMethodDecl *BaseMD) { 00317 const FunctionType *BaseFT = BaseMD->getType()->getAs<FunctionType>(); 00318 const FunctionType *DerivedFT = DerivedMD->getType()->getAs<FunctionType>(); 00319 00320 // Canonicalize the return types. 00321 CanQualType CanDerivedReturnType = 00322 Context.getCanonicalType(DerivedFT->getResultType()); 00323 CanQualType CanBaseReturnType = 00324 Context.getCanonicalType(BaseFT->getResultType()); 00325 00326 assert(CanDerivedReturnType->getTypeClass() == 00327 CanBaseReturnType->getTypeClass() && 00328 "Types must have same type class!"); 00329 00330 if (CanDerivedReturnType == CanBaseReturnType) { 00331 // No adjustment needed. 00332 return BaseOffset(); 00333 } 00334 00335 if (isa<ReferenceType>(CanDerivedReturnType)) { 00336 CanDerivedReturnType = 00337 CanDerivedReturnType->getAs<ReferenceType>()->getPointeeType(); 00338 CanBaseReturnType = 00339 CanBaseReturnType->getAs<ReferenceType>()->getPointeeType(); 00340 } else if (isa<PointerType>(CanDerivedReturnType)) { 00341 CanDerivedReturnType = 00342 CanDerivedReturnType->getAs<PointerType>()->getPointeeType(); 00343 CanBaseReturnType = 00344 CanBaseReturnType->getAs<PointerType>()->getPointeeType(); 00345 } else { 00346 assert(false && "Unexpected return type!"); 00347 } 00348 00349 // We need to compare unqualified types here; consider 00350 // const T *Base::foo(); 00351 // T *Derived::foo(); 00352 if (CanDerivedReturnType.getUnqualifiedType() == 00353 CanBaseReturnType.getUnqualifiedType()) { 00354 // No adjustment needed. 00355 return BaseOffset(); 00356 } 00357 00358 const CXXRecordDecl *DerivedRD = 00359 cast<CXXRecordDecl>(cast<RecordType>(CanDerivedReturnType)->getDecl()); 00360 00361 const CXXRecordDecl *BaseRD = 00362 cast<CXXRecordDecl>(cast<RecordType>(CanBaseReturnType)->getDecl()); 00363 00364 return ComputeBaseOffset(Context, BaseRD, DerivedRD); 00365 } 00366 00367 void FinalOverriders::PropagateOverrider(const CXXMethodDecl *OldMD, 00368 BaseSubobject NewBase, 00369 uint64_t OverriderOffsetInLayoutClass, 00370 const CXXMethodDecl *NewMD, 00371 SubobjectOffsetsMapTy &Offsets) { 00372 for (CXXMethodDecl::method_iterator I = OldMD->begin_overridden_methods(), 00373 E = OldMD->end_overridden_methods(); I != E; ++I) { 00374 const CXXMethodDecl *OverriddenMD = *I; 00375 const CXXRecordDecl *OverriddenRD = OverriddenMD->getParent(); 00376 00377 // We want to override OverriddenMD in all subobjects, for example: 00378 // 00379 /// struct A { virtual void f(); }; 00380 /// struct B1 : A { }; 00381 /// struct B2 : A { }; 00382 /// struct C : B1, B2 { virtual void f(); }; 00383 /// 00384 /// When overriding A::f with C::f we need to do so in both A subobjects. 00385 const OffsetSetVectorTy &OffsetVector = Offsets[OverriddenRD]; 00386 00387 // Go through all the subobjects. 00388 for (unsigned I = 0, E = OffsetVector.size(); I != E; ++I) { 00389 uint64_t Offset = OffsetVector[I]; 00390 00391 BaseSubobject OverriddenSubobject = BaseSubobject(OverriddenRD, Offset); 00392 BaseSubobjectMethodPairTy SubobjectAndMethod = 00393 std::make_pair(OverriddenSubobject, OverriddenMD); 00394 00395 OverriderInfo &Overrider = OverridersMap[SubobjectAndMethod]; 00396 00397 assert(Overrider.Method && "Did not find existing overrider!"); 00398 00399 // Check if we need return adjustments or base adjustments. 00400 // (We don't want to do this for pure virtual member functions). 00401 if (!NewMD->isPure()) { 00402 // Get the return adjustment base offset. 00403 BaseOffset ReturnBaseOffset = 00404 ComputeReturnAdjustmentBaseOffset(Context, NewMD, OverriddenMD); 00405 00406 if (!ReturnBaseOffset.isEmpty()) { 00407 // Store the return adjustment base offset. 00408 ReturnAdjustments[SubobjectAndMethod] = ReturnBaseOffset; 00409 } 00410 } 00411 00412 // Set the new overrider. 00413 Overrider.Offset = OverriderOffsetInLayoutClass; 00414 Overrider.Method = NewMD; 00415 00416 // And propagate it further. 00417 PropagateOverrider(OverriddenMD, NewBase, OverriderOffsetInLayoutClass, 00418 NewMD, Offsets); 00419 } 00420 } 00421 } 00422 00423 void 00424 FinalOverriders::MergeSubobjectOffsets(const SubobjectOffsetsMapTy &NewOffsets, 00425 SubobjectOffsetsMapTy &Offsets) { 00426 // Iterate over the new offsets. 00427 for (SubobjectOffsetsMapTy::const_iterator I = NewOffsets.begin(), 00428 E = NewOffsets.end(); I != E; ++I) { 00429 const CXXRecordDecl *NewRD = I->first; 00430 const OffsetSetVectorTy& NewOffsetVector = I->second; 00431 00432 OffsetSetVectorTy &OffsetVector = Offsets[NewRD]; 00433 00434 // Merge the new offsets set vector into the old. 00435 OffsetVector.insert(NewOffsetVector.begin(), NewOffsetVector.end()); 00436 } 00437 } 00438 00439 void FinalOverriders::ComputeFinalOverriders(BaseSubobject Base, 00440 bool BaseSubobjectIsVisitedVBase, 00441 uint64_t OffsetInLayoutClass, 00442 SubobjectOffsetsMapTy &Offsets) { 00443 const CXXRecordDecl *RD = Base.getBase(); 00444 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 00445 00446 SubobjectOffsetsMapTy NewOffsets; 00447 00448 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 00449 E = RD->bases_end(); I != E; ++I) { 00450 const CXXRecordDecl *BaseDecl = 00451 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 00452 00453 // Ignore bases that don't have any virtual member functions. 00454 if (!BaseDecl->isPolymorphic()) 00455 continue; 00456 00457 bool IsVisitedVirtualBase = BaseSubobjectIsVisitedVBase; 00458 uint64_t BaseOffset; 00459 uint64_t BaseOffsetInLayoutClass; 00460 if (I->isVirtual()) { 00461 if (!VisitedVirtualBases.insert(BaseDecl)) 00462 IsVisitedVirtualBase = true; 00463 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 00464 00465 const ASTRecordLayout &LayoutClassLayout = 00466 Context.getASTRecordLayout(LayoutClass); 00467 BaseOffsetInLayoutClass = 00468 LayoutClassLayout.getVBaseClassOffset(BaseDecl); 00469 } else { 00470 BaseOffset = Layout.getBaseClassOffset(BaseDecl) + Base.getBaseOffset(); 00471 BaseOffsetInLayoutClass = Layout.getBaseClassOffset(BaseDecl) + 00472 OffsetInLayoutClass; 00473 } 00474 00475 // Compute the final overriders for this base. 00476 // We always want to compute the final overriders, even if the base is a 00477 // visited virtual base. Consider: 00478 // 00479 // struct A { 00480 // virtual void f(); 00481 // virtual void g(); 00482 // }; 00483 // 00484 // struct B : virtual A { 00485 // void f(); 00486 // }; 00487 // 00488 // struct C : virtual A { 00489 // void g (); 00490 // }; 00491 // 00492 // struct D : B, C { }; 00493 // 00494 // Here, we still want to compute the overriders for A as a base of C, 00495 // because otherwise we'll miss that C::g overrides A::f. 00496 ComputeFinalOverriders(BaseSubobject(BaseDecl, BaseOffset), 00497 IsVisitedVirtualBase, BaseOffsetInLayoutClass, 00498 NewOffsets); 00499 } 00500 00501 /// Now add the overriders for this particular subobject. 00502 /// (We don't want to do this more than once for a virtual base). 00503 if (!BaseSubobjectIsVisitedVBase) 00504 AddOverriders(Base, OffsetInLayoutClass, NewOffsets); 00505 00506 // And merge the newly discovered subobject offsets. 00507 MergeSubobjectOffsets(NewOffsets, Offsets); 00508 00509 /// Finally, add the offset for our own subobject. 00510 Offsets[RD].insert(Base.getBaseOffset()); 00511 } 00512 00513 void FinalOverriders::dump(llvm::raw_ostream &Out, BaseSubobject Base) { 00514 const CXXRecordDecl *RD = Base.getBase(); 00515 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 00516 00517 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 00518 E = RD->bases_end(); I != E; ++I) { 00519 const CXXRecordDecl *BaseDecl = 00520 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 00521 00522 // Ignore bases that don't have any virtual member functions. 00523 if (!BaseDecl->isPolymorphic()) 00524 continue; 00525 00526 uint64_t BaseOffset; 00527 if (I->isVirtual()) { 00528 if (!VisitedVirtualBases.insert(BaseDecl)) { 00529 // We've visited this base before. 00530 continue; 00531 } 00532 00533 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 00534 } else { 00535 BaseOffset = Layout.getBaseClassOffset(BaseDecl) + 00536 Base.getBaseOffset(); 00537 } 00538 00539 dump(Out, BaseSubobject(BaseDecl, BaseOffset)); 00540 } 00541 00542 Out << "Final overriders for (" << RD->getQualifiedNameAsString() << ", "; 00543 Out << Base.getBaseOffset() / 8 << ")\n"; 00544 00545 // Now dump the overriders for this base subobject. 00546 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 00547 E = RD->method_end(); I != E; ++I) { 00548 const CXXMethodDecl *MD = *I; 00549 00550 if (!MD->isVirtual()) 00551 continue; 00552 00553 OverriderInfo Overrider = getOverrider(Base, MD); 00554 00555 Out << " " << MD->getQualifiedNameAsString() << " - ("; 00556 Out << Overrider.Method->getQualifiedNameAsString(); 00557 Out << ", " << ", " << Overrider.Offset / 8 << ')'; 00558 00559 AdjustmentOffsetsMapTy::const_iterator AI = 00560 ReturnAdjustments.find(std::make_pair(Base, MD)); 00561 if (AI != ReturnAdjustments.end()) { 00562 const BaseOffset &Offset = AI->second; 00563 00564 Out << " [ret-adj: "; 00565 if (Offset.VirtualBase) 00566 Out << Offset.VirtualBase->getQualifiedNameAsString() << " vbase, "; 00567 00568 Out << Offset.NonVirtualOffset << " nv]"; 00569 } 00570 00571 Out << "\n"; 00572 } 00573 } 00574 00575 /// VtableComponent - Represents a single component in a vtable. 00576 class VtableComponent { 00577 public: 00578 enum Kind { 00579 CK_VCallOffset, 00580 CK_VBaseOffset, 00581 CK_OffsetToTop, 00582 CK_RTTI, 00583 CK_FunctionPointer, 00584 00585 /// CK_CompleteDtorPointer - A pointer to the complete destructor. 00586 CK_CompleteDtorPointer, 00587 00588 /// CK_DeletingDtorPointer - A pointer to the deleting destructor. 00589 CK_DeletingDtorPointer, 00590 00591 /// CK_UnusedFunctionPointer - In some cases, a vtable function pointer 00592 /// will end up never being called. Such vtable function pointers are 00593 /// represented as a CK_UnusedFunctionPointer. 00594 CK_UnusedFunctionPointer 00595 }; 00596 00597 static VtableComponent MakeVCallOffset(int64_t Offset) { 00598 return VtableComponent(CK_VCallOffset, Offset); 00599 } 00600 00601 static VtableComponent MakeVBaseOffset(int64_t Offset) { 00602 return VtableComponent(CK_VBaseOffset, Offset); 00603 } 00604 00605 static VtableComponent MakeOffsetToTop(int64_t Offset) { 00606 return VtableComponent(CK_OffsetToTop, Offset); 00607 } 00608 00609 static VtableComponent MakeRTTI(const CXXRecordDecl *RD) { 00610 return VtableComponent(CK_RTTI, reinterpret_cast<uintptr_t>(RD)); 00611 } 00612 00613 static VtableComponent MakeFunction(const CXXMethodDecl *MD) { 00614 assert(!isa<CXXDestructorDecl>(MD) && 00615 "Don't use MakeFunction with destructors!"); 00616 00617 return VtableComponent(CK_FunctionPointer, 00618 reinterpret_cast<uintptr_t>(MD)); 00619 } 00620 00621 static VtableComponent MakeCompleteDtor(const CXXDestructorDecl *DD) { 00622 return VtableComponent(CK_CompleteDtorPointer, 00623 reinterpret_cast<uintptr_t>(DD)); 00624 } 00625 00626 static VtableComponent MakeDeletingDtor(const CXXDestructorDecl *DD) { 00627 return VtableComponent(CK_DeletingDtorPointer, 00628 reinterpret_cast<uintptr_t>(DD)); 00629 } 00630 00631 static VtableComponent MakeUnusedFunction(const CXXMethodDecl *MD) { 00632 assert(!isa<CXXDestructorDecl>(MD) && 00633 "Don't use MakeUnusedFunction with destructors!"); 00634 return VtableComponent(CK_UnusedFunctionPointer, 00635 reinterpret_cast<uintptr_t>(MD)); 00636 } 00637 00638 /// getKind - Get the kind of this vtable component. 00639 Kind getKind() const { 00640 return (Kind)(Value & 0x7); 00641 } 00642 00643 int64_t getVCallOffset() const { 00644 assert(getKind() == CK_VCallOffset && "Invalid component kind!"); 00645 00646 return getOffset(); 00647 } 00648 00649 int64_t getVBaseOffset() const { 00650 assert(getKind() == CK_VBaseOffset && "Invalid component kind!"); 00651 00652 return getOffset(); 00653 } 00654 00655 int64_t getOffsetToTop() const { 00656 assert(getKind() == CK_OffsetToTop && "Invalid component kind!"); 00657 00658 return getOffset(); 00659 } 00660 00661 const CXXRecordDecl *getRTTIDecl() const { 00662 assert(getKind() == CK_RTTI && "Invalid component kind!"); 00663 00664 return reinterpret_cast<CXXRecordDecl *>(getPointer()); 00665 } 00666 00667 const CXXMethodDecl *getFunctionDecl() const { 00668 assert(getKind() == CK_FunctionPointer); 00669 00670 return reinterpret_cast<CXXMethodDecl *>(getPointer()); 00671 } 00672 00673 const CXXDestructorDecl *getDestructorDecl() const { 00674 assert((getKind() == CK_CompleteDtorPointer || 00675 getKind() == CK_DeletingDtorPointer) && "Invalid component kind!"); 00676 00677 return reinterpret_cast<CXXDestructorDecl *>(getPointer()); 00678 } 00679 00680 const CXXMethodDecl *getUnusedFunctionDecl() const { 00681 assert(getKind() == CK_UnusedFunctionPointer); 00682 00683 return reinterpret_cast<CXXMethodDecl *>(getPointer()); 00684 } 00685 00686 private: 00687 VtableComponent(Kind ComponentKind, int64_t Offset) { 00688 assert((ComponentKind == CK_VCallOffset || 00689 ComponentKind == CK_VBaseOffset || 00690 ComponentKind == CK_OffsetToTop) && "Invalid component kind!"); 00691 assert(Offset <= ((1LL << 56) - 1) && "Offset is too big!"); 00692 00693 Value = ((Offset << 3) | ComponentKind); 00694 } 00695 00696 VtableComponent(Kind ComponentKind, uintptr_t Ptr) { 00697 assert((ComponentKind == CK_RTTI || 00698 ComponentKind == CK_FunctionPointer || 00699 ComponentKind == CK_CompleteDtorPointer || 00700 ComponentKind == CK_DeletingDtorPointer || 00701 ComponentKind == CK_UnusedFunctionPointer) && 00702 "Invalid component kind!"); 00703 00704 assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!"); 00705 00706 Value = Ptr | ComponentKind; 00707 } 00708 00709 int64_t getOffset() const { 00710 assert((getKind() == CK_VCallOffset || getKind() == CK_VBaseOffset || 00711 getKind() == CK_OffsetToTop) && "Invalid component kind!"); 00712 00713 return Value >> 3; 00714 } 00715 00716 uintptr_t getPointer() const { 00717 assert((getKind() == CK_RTTI || 00718 getKind() == CK_FunctionPointer || 00719 getKind() == CK_CompleteDtorPointer || 00720 getKind() == CK_DeletingDtorPointer || 00721 getKind() == CK_UnusedFunctionPointer) && 00722 "Invalid component kind!"); 00723 00724 return static_cast<uintptr_t>(Value & ~7ULL); 00725 } 00726 00727 /// The kind is stored in the lower 3 bits of the value. For offsets, we 00728 /// make use of the facts that classes can't be larger than 2^55 bytes, 00729 /// so we store the offset in the lower part of the 61 bytes that remain. 00730 /// (The reason that we're not simply using a PointerIntPair here is that we 00731 /// need the offsets to be 64-bit, even when on a 32-bit machine). 00732 int64_t Value; 00733 }; 00734 00735 /// VCallOffsetMap - Keeps track of vcall offsets when building a vtable. 00736 struct VCallOffsetMap { 00737 00738 typedef std::pair<const CXXMethodDecl *, int64_t> MethodAndOffsetPairTy; 00739 00740 /// Offsets - Keeps track of methods and their offsets. 00741 // FIXME: This should be a real map and not a vector. 00742 llvm::SmallVector<MethodAndOffsetPairTy, 16> Offsets; 00743 00744 /// MethodsCanShareVCallOffset - Returns whether two virtual member functions 00745 /// can share the same vcall offset. 00746 static bool MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, 00747 const CXXMethodDecl *RHS); 00748 00749 public: 00750 /// AddVCallOffset - Adds a vcall offset to the map. Returns true if the 00751 /// add was successful, or false if there was already a member function with 00752 /// the same signature in the map. 00753 bool AddVCallOffset(const CXXMethodDecl *MD, int64_t OffsetOffset); 00754 00755 /// getVCallOffsetOffset - Returns the vcall offset offset (relative to the 00756 /// vtable address point) for the given virtual member function. 00757 int64_t getVCallOffsetOffset(const CXXMethodDecl *MD); 00758 00759 // empty - Return whether the offset map is empty or not. 00760 bool empty() const { return Offsets.empty(); } 00761 }; 00762 00763 static bool HasSameVirtualSignature(const CXXMethodDecl *LHS, 00764 const CXXMethodDecl *RHS) { 00765 ASTContext &C = LHS->getASTContext(); // TODO: thread this down 00766 CanQual<FunctionProtoType> 00767 LT = C.getCanonicalType(LHS->getType()).getAs<FunctionProtoType>(), 00768 RT = C.getCanonicalType(RHS->getType()).getAs<FunctionProtoType>(); 00769 00770 // Fast-path matches in the canonical types. 00771 if (LT == RT) return true; 00772 00773 // Force the signatures to match. We can't rely on the overrides 00774 // list here because there isn't necessarily an inheritance 00775 // relationship between the two methods. 00776 if (LT.getQualifiers() != RT.getQualifiers() || 00777 LT->getNumArgs() != RT->getNumArgs()) 00778 return false; 00779 for (unsigned I = 0, E = LT->getNumArgs(); I != E; ++I) 00780 if (LT->getArgType(I) != RT->getArgType(I)) 00781 return false; 00782 return true; 00783 } 00784 00785 bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, 00786 const CXXMethodDecl *RHS) { 00787 assert(LHS->isVirtual() && "LHS must be virtual!"); 00788 assert(RHS->isVirtual() && "LHS must be virtual!"); 00789 00790 // A destructor can share a vcall offset with another destructor. 00791 if (isa<CXXDestructorDecl>(LHS)) 00792 return isa<CXXDestructorDecl>(RHS); 00793 00794 // FIXME: We need to check more things here. 00795 00796 // The methods must have the same name. 00797 DeclarationName LHSName = LHS->getDeclName(); 00798 DeclarationName RHSName = RHS->getDeclName(); 00799 if (LHSName != RHSName) 00800 return false; 00801 00802 // And the same signatures. 00803 return HasSameVirtualSignature(LHS, RHS); 00804 } 00805 00806 bool VCallOffsetMap::AddVCallOffset(const CXXMethodDecl *MD, 00807 int64_t OffsetOffset) { 00808 // Check if we can reuse an offset. 00809 for (unsigned I = 0, E = Offsets.size(); I != E; ++I) { 00810 if (MethodsCanShareVCallOffset(Offsets[I].first, MD)) 00811 return false; 00812 } 00813 00814 // Add the offset. 00815 Offsets.push_back(MethodAndOffsetPairTy(MD, OffsetOffset)); 00816 return true; 00817 } 00818 00819 int64_t VCallOffsetMap::getVCallOffsetOffset(const CXXMethodDecl *MD) { 00820 // Look for an offset. 00821 for (unsigned I = 0, E = Offsets.size(); I != E; ++I) { 00822 if (MethodsCanShareVCallOffset(Offsets[I].first, MD)) 00823 return Offsets[I].second; 00824 } 00825 00826 assert(false && "Should always find a vcall offset offset!"); 00827 return 0; 00828 } 00829 00830 /// VCallAndVBaseOffsetBuilder - Class for building vcall and vbase offsets. 00831 class VCallAndVBaseOffsetBuilder { 00832 public: 00833 typedef llvm::DenseMap<const CXXRecordDecl *, int64_t> 00834 VBaseOffsetOffsetsMapTy; 00835 00836 private: 00837 /// MostDerivedClass - The most derived class for which we're building vcall 00838 /// and vbase offsets. 00839 const CXXRecordDecl *MostDerivedClass; 00840 00841 /// LayoutClass - The class we're using for layout information. Will be 00842 /// different than the most derived class if we're building a construction 00843 /// vtable. 00844 const CXXRecordDecl *LayoutClass; 00845 00846 /// Context - The ASTContext which we will use for layout information. 00847 ASTContext &Context; 00848 00849 /// Components - vcall and vbase offset components 00850 typedef llvm::SmallVector<VtableComponent, 64> VtableComponentVectorTy; 00851 VtableComponentVectorTy Components; 00852 00853 /// VisitedVirtualBases - Visited virtual bases. 00854 llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; 00855 00856 /// VCallOffsets - Keeps track of vcall offsets. 00857 VCallOffsetMap VCallOffsets; 00858 00859 00860 /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets, 00861 /// relative to the address point. 00862 VBaseOffsetOffsetsMapTy VBaseOffsetOffsets; 00863 00864 /// FinalOverriders - The final overriders of the most derived class. 00865 /// (Can be null when we're not building a vtable of the most derived class). 00866 const FinalOverriders *Overriders; 00867 00868 /// AddVCallAndVBaseOffsets - Add vcall offsets and vbase offsets for the 00869 /// given base subobject. 00870 void AddVCallAndVBaseOffsets(BaseSubobject Base, bool BaseIsVirtual, 00871 uint64_t RealBaseOffset); 00872 00873 /// AddVCallOffsets - Add vcall offsets for the given base subobject. 00874 void AddVCallOffsets(BaseSubobject Base, uint64_t VBaseOffset); 00875 00876 /// AddVBaseOffsets - Add vbase offsets for the given class. 00877 void AddVBaseOffsets(const CXXRecordDecl *Base, uint64_t OffsetInLayoutClass); 00878 00879 /// getCurrentOffsetOffset - Get the current vcall or vbase offset offset in 00880 /// bytes, relative to the vtable address point. 00881 int64_t getCurrentOffsetOffset() const; 00882 00883 public: 00884 VCallAndVBaseOffsetBuilder(const CXXRecordDecl *MostDerivedClass, 00885 const CXXRecordDecl *LayoutClass, 00886 const FinalOverriders *Overriders, 00887 BaseSubobject Base, bool BaseIsVirtual, 00888 uint64_t OffsetInLayoutClass) 00889 : MostDerivedClass(MostDerivedClass), LayoutClass(LayoutClass), 00890 Context(MostDerivedClass->getASTContext()), Overriders(Overriders) { 00891 00892 // Add vcall and vbase offsets. 00893 AddVCallAndVBaseOffsets(Base, BaseIsVirtual, OffsetInLayoutClass); 00894 } 00895 00896 /// Methods for iterating over the components. 00897 typedef VtableComponentVectorTy::const_reverse_iterator const_iterator; 00898 const_iterator components_begin() const { return Components.rbegin(); } 00899 const_iterator components_end() const { return Components.rend(); } 00900 00901 const VCallOffsetMap &getVCallOffsets() const { return VCallOffsets; } 00902 const VBaseOffsetOffsetsMapTy &getVBaseOffsetOffsets() const { 00903 return VBaseOffsetOffsets; 00904 } 00905 }; 00906 00907 void 00908 VCallAndVBaseOffsetBuilder::AddVCallAndVBaseOffsets(BaseSubobject Base, 00909 bool BaseIsVirtual, 00910 uint64_t RealBaseOffset) { 00911 const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base.getBase()); 00912 00913 // Itanium C++ ABI 2.5.2: 00914 // ..in classes sharing a virtual table with a primary base class, the vcall 00915 // and vbase offsets added by the derived class all come before the vcall 00916 // and vbase offsets required by the base class, so that the latter may be 00917 // laid out as required by the base class without regard to additions from 00918 // the derived class(es). 00919 00920 // (Since we're emitting the vcall and vbase offsets in reverse order, we'll 00921 // emit them for the primary base first). 00922 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 00923 bool PrimaryBaseIsVirtual = Layout.getPrimaryBaseWasVirtual(); 00924 00925 uint64_t PrimaryBaseOffset; 00926 00927 // Get the base offset of the primary base. 00928 if (PrimaryBaseIsVirtual) { 00929 assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 && 00930 "Primary vbase should have a zero offset!"); 00931 00932 const ASTRecordLayout &MostDerivedClassLayout = 00933 Context.getASTRecordLayout(MostDerivedClass); 00934 00935 PrimaryBaseOffset = 00936 MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); 00937 } else { 00938 assert(Layout.getBaseClassOffset(PrimaryBase) == 0 && 00939 "Primary base should have a zero offset!"); 00940 00941 PrimaryBaseOffset = Base.getBaseOffset(); 00942 } 00943 00944 AddVCallAndVBaseOffsets(BaseSubobject(PrimaryBase, PrimaryBaseOffset), 00945 PrimaryBaseIsVirtual, RealBaseOffset); 00946 } 00947 00948 AddVBaseOffsets(Base.getBase(), RealBaseOffset); 00949 00950 // We only want to add vcall offsets for virtual bases. 00951 if (BaseIsVirtual) 00952 AddVCallOffsets(Base, RealBaseOffset); 00953 } 00954 00955 int64_t VCallAndVBaseOffsetBuilder::getCurrentOffsetOffset() const { 00956 // OffsetIndex is the index of this vcall or vbase offset, relative to the 00957 // vtable address point. (We subtract 3 to account for the information just 00958 // above the address point, the RTTI info, the offset to top, and the 00959 // vcall offset itself). 00960 int64_t OffsetIndex = -(int64_t)(3 + Components.size()); 00961 00962 // FIXME: We shouldn't use / 8 here. 00963 int64_t OffsetOffset = OffsetIndex * 00964 (int64_t)Context.Target.getPointerWidth(0) / 8; 00965 00966 return OffsetOffset; 00967 } 00968 00969 void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, 00970 uint64_t VBaseOffset) { 00971 const CXXRecordDecl *RD = Base.getBase(); 00972 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 00973 00974 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 00975 00976 // Handle the primary base first. 00977 if (PrimaryBase) { 00978 uint64_t PrimaryBaseOffset; 00979 00980 // Get the base offset of the primary base. 00981 if (Layout.getPrimaryBaseWasVirtual()) { 00982 assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 && 00983 "Primary vbase should have a zero offset!"); 00984 00985 const ASTRecordLayout &MostDerivedClassLayout = 00986 Context.getASTRecordLayout(MostDerivedClass); 00987 00988 PrimaryBaseOffset = 00989 MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); 00990 } else { 00991 assert(Layout.getBaseClassOffset(PrimaryBase) == 0 && 00992 "Primary base should have a zero offset!"); 00993 00994 PrimaryBaseOffset = Base.getBaseOffset(); 00995 } 00996 00997 AddVCallOffsets(BaseSubobject(PrimaryBase, PrimaryBaseOffset), 00998 VBaseOffset); 00999 } 01000 01001 // Add the vcall offsets. 01002 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 01003 E = RD->method_end(); I != E; ++I) { 01004 const CXXMethodDecl *MD = *I; 01005 01006 if (!MD->isVirtual()) 01007 continue; 01008 01009 int64_t OffsetOffset = getCurrentOffsetOffset(); 01010 01011 // Don't add a vcall offset if we already have one for this member function 01012 // signature. 01013 if (!VCallOffsets.AddVCallOffset(MD, OffsetOffset)) 01014 continue; 01015 01016 int64_t Offset = 0; 01017 01018 if (Overriders) { 01019 // Get the final overrider. 01020 FinalOverriders::OverriderInfo Overrider = 01021 Overriders->getOverrider(Base, MD); 01022 01023 /// The vcall offset is the offset from the virtual base to the object 01024 /// where the function was overridden. 01025 // FIXME: We should not use / 8 here. 01026 Offset = (int64_t)(Overrider.Offset - VBaseOffset) / 8; 01027 } 01028 01029 Components.push_back(VtableComponent::MakeVCallOffset(Offset)); 01030 } 01031 01032 // And iterate over all non-virtual bases (ignoring the primary base). 01033 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 01034 E = RD->bases_end(); I != E; ++I) { 01035 01036 if (I->isVirtual()) 01037 continue; 01038 01039 const CXXRecordDecl *BaseDecl = 01040 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 01041 if (BaseDecl == PrimaryBase) 01042 continue; 01043 01044 // Get the base offset of this base. 01045 uint64_t BaseOffset = Base.getBaseOffset() + 01046 Layout.getBaseClassOffset(BaseDecl); 01047 01048 AddVCallOffsets(BaseSubobject(BaseDecl, BaseOffset), VBaseOffset); 01049 } 01050 } 01051 01052 void VCallAndVBaseOffsetBuilder::AddVBaseOffsets(const CXXRecordDecl *RD, 01053 uint64_t OffsetInLayoutClass) { 01054 const ASTRecordLayout &LayoutClassLayout = 01055 Context.getASTRecordLayout(LayoutClass); 01056 01057 // Add vbase offsets. 01058 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 01059 E = RD->bases_end(); I != E; ++I) { 01060 const CXXRecordDecl *BaseDecl = 01061 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 01062 01063 // Check if this is a virtual base that we haven't visited before. 01064 if (I->isVirtual() && VisitedVirtualBases.insert(BaseDecl)) { 01065 // FIXME: We shouldn't use / 8 here. 01066 int64_t Offset = 01067 (int64_t)(LayoutClassLayout.getVBaseClassOffset(BaseDecl) - 01068 OffsetInLayoutClass) / 8; 01069 01070 // Add the vbase offset offset. 01071 assert(!VBaseOffsetOffsets.count(BaseDecl) && 01072 "vbase offset offset already exists!"); 01073 01074 int64_t VBaseOffsetOffset = getCurrentOffsetOffset(); 01075 VBaseOffsetOffsets.insert(std::make_pair(BaseDecl, VBaseOffsetOffset)); 01076 01077 Components.push_back(VtableComponent::MakeVBaseOffset(Offset)); 01078 } 01079 01080 // Check the base class looking for more vbase offsets. 01081 AddVBaseOffsets(BaseDecl, OffsetInLayoutClass); 01082 } 01083 } 01084 01085 /// VtableBuilder - Class for building vtable layout information. 01086 class VtableBuilder { 01087 public: 01088 /// PrimaryBasesSetVectorTy - A set vector of direct and indirect 01089 /// primary bases. 01090 typedef llvm::SmallSetVector<const CXXRecordDecl *, 8> 01091 PrimaryBasesSetVectorTy; 01092 01093 private: 01094 /// VtableInfo - Global vtable information. 01095 CGVtableInfo &VtableInfo; 01096 01097 /// MostDerivedClass - The most derived class for which we're building this 01098 /// vtable. 01099 const CXXRecordDecl *MostDerivedClass; 01100 01101 /// MostDerivedClassOffset - If we're building a construction vtable, this 01102 /// holds the offset from the layout class to the most derived class. 01103 const uint64_t MostDerivedClassOffset; 01104 01105 /// MostDerivedClassIsVirtual - Whether the most derived class is a virtual 01106 /// base. (This only makes sense when building a construction vtable). 01107 bool MostDerivedClassIsVirtual; 01108 01109 /// LayoutClass - The class we're using for layout information. Will be 01110 /// different than the most derived class if we're building a construction 01111 /// vtable. 01112 const CXXRecordDecl *LayoutClass; 01113 01114 /// Context - The ASTContext which we will use for layout information. 01115 ASTContext &Context; 01116 01117 /// FinalOverriders - The final overriders of the most derived class. 01118 const FinalOverriders Overriders; 01119 01120 /// VCallOffsetsForVBases - Keeps track of vcall offsets for the virtual 01121 /// bases in this vtable. 01122 llvm::DenseMap<const CXXRecordDecl *, VCallOffsetMap> VCallOffsetsForVBases; 01123 01124 typedef llvm::DenseMap<const CXXRecordDecl *, int64_t> 01125 VBaseOffsetOffsetsMapTy; 01126 01127 /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets for 01128 /// the most derived class. 01129 VBaseOffsetOffsetsMapTy VBaseOffsetOffsets; 01130 01131 /// Components - The components of the vtable being built. 01132 llvm::SmallVector<VtableComponent, 64> Components; 01133 01134 /// AddressPoints - Address points for the vtable being built. 01135 CGVtableInfo::AddressPointsMapTy AddressPoints; 01136 01137 /// ReturnAdjustment - A return adjustment. 01138 struct ReturnAdjustment { 01139 /// NonVirtual - The non-virtual adjustment from the derived object to its 01140 /// nearest virtual base. 01141 int64_t NonVirtual; 01142 01143 /// VBaseOffsetOffset - The offset (in bytes), relative to the address point 01144 /// of the virtual base class offset. 01145 int64_t VBaseOffsetOffset; 01146 01147 ReturnAdjustment() : NonVirtual(0), VBaseOffsetOffset(0) { } 01148 01149 bool isEmpty() const { return !NonVirtual && !VBaseOffsetOffset; } 01150 }; 01151 01152 /// MethodInfo - Contains information about a method in a vtable. 01153 /// (Used for computing 'this' pointer adjustment thunks. 01154 struct MethodInfo { 01155 /// BaseOffset - The base offset of this method. 01156 const uint64_t BaseOffset; 01157 01158 /// BaseOffsetInLayoutClass - The base offset in the layout class of this 01159 /// method. 01160 const uint64_t BaseOffsetInLayoutClass; 01161 01162 /// VtableIndex - The index in the vtable that this method has. 01163 /// (For destructors, this is the index of the complete destructor). 01164 const uint64_t VtableIndex; 01165 01166 MethodInfo(uint64_t BaseOffset, uint64_t BaseOffsetInLayoutClass, 01167 uint64_t VtableIndex) 01168 : BaseOffset(BaseOffset), 01169 BaseOffsetInLayoutClass(BaseOffsetInLayoutClass), 01170 VtableIndex(VtableIndex) { } 01171 01172 MethodInfo() : BaseOffset(0), BaseOffsetInLayoutClass(0), VtableIndex(0) { } 01173 }; 01174 01175 typedef llvm::DenseMap<const CXXMethodDecl *, MethodInfo> MethodInfoMapTy; 01176 01177 /// MethodInfoMap - The information for all methods in the vtable we're 01178 /// currently building. 01179 MethodInfoMapTy MethodInfoMap; 01180 01181 /// ThisAdjustment - A 'this' pointer adjustment thunk. 01182 struct ThisAdjustment { 01183 /// NonVirtual - The non-virtual adjustment from the derived object to its 01184 /// nearest virtual base. 01185 int64_t NonVirtual; 01186 01187 /// VCallOffsetOffset - The offset (in bytes), relative to the address point, 01188 /// of the virtual call offset. 01189 int64_t VCallOffsetOffset; 01190 01191 ThisAdjustment() : NonVirtual(0), VCallOffsetOffset(0) { } 01192 01193 bool isEmpty() const { return !NonVirtual && !VCallOffsetOffset; } 01194 }; 01195 01196 /// ThunkInfo - The 'this' pointer adjustment as well as an optional return 01197 /// adjustment for a thunk. 01198 struct ThunkInfo { 01199 /// This - The 'this' pointer adjustment. 01200 ThisAdjustment This; 01201 01202 /// Return - The return adjustment. 01203 ReturnAdjustment Return; 01204 01205 ThunkInfo() { } 01206 01207 ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return) 01208 : This(This), Return(Return) { } 01209 01210 bool isEmpty() const { return This.isEmpty() && Return.isEmpty(); } 01211 }; 01212 01213 typedef llvm::DenseMap<uint64_t, ThunkInfo> ThunksInfoMapTy; 01214 01215 /// Thunks - The thunks by vtable index in the vtable currently being built. 01216 ThunksInfoMapTy Thunks; 01217 01218 /// ComputeThisAdjustments - Compute the 'this' pointer adjustments for the 01219 /// part of the vtable we're currently building. 01220 void ComputeThisAdjustments(); 01221 01222 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; 01223 01224 /// PrimaryVirtualBases - All known virtual bases who are a primary base of 01225 /// some other base. 01226 VisitedVirtualBasesSetTy PrimaryVirtualBases; 01227 01228 /// ComputeReturnAdjustment - Compute the return adjustment given a return 01229 /// adjustment base offset. 01230 ReturnAdjustment ComputeReturnAdjustment(BaseOffset Offset); 01231 01232 /// ComputeThisAdjustmentBaseOffset - Compute the base offset for adjusting 01233 /// the 'this' pointer from the base subobject to the derived subobject. 01234 BaseOffset ComputeThisAdjustmentBaseOffset(BaseSubobject Base, 01235 BaseSubobject Derived) const; 01236 01237 /// ComputeThisAdjustment - Compute the 'this' pointer adjustment for the 01238 /// given virtual member function, its offset in the layout class and its 01239 /// final overrider. 01240 ThisAdjustment 01241 ComputeThisAdjustment(const CXXMethodDecl *MD, 01242 uint64_t BaseOffsetInLayoutClass, 01243 FinalOverriders::OverriderInfo Overrider); 01244 01245 /// AddMethod - Add a single virtual member function to the vtable 01246 /// components vector. 01247 void AddMethod(const CXXMethodDecl *MD, ReturnAdjustment ReturnAdjustment); 01248 01249 /// IsOverriderUsed - Returns whether the overrider will ever be used in this 01250 /// part of the vtable. 01251 /// 01252 /// Itanium C++ ABI 2.5.2: 01253 /// 01254 /// struct A { virtual void f(); }; 01255 /// struct B : virtual public A { int i; }; 01256 /// struct C : virtual public A { int j; }; 01257 /// struct D : public B, public C {}; 01258 /// 01259 /// When B and C are declared, A is a primary base in each case, so although 01260 /// vcall offsets are allocated in the A-in-B and A-in-C vtables, no this 01261 /// adjustment is required and no thunk is generated. However, inside D 01262 /// objects, A is no longer a primary base of C, so if we allowed calls to 01263 /// C::f() to use the copy of A's vtable in the C subobject, we would need 01264 /// to adjust this from C* to B::A*, which would require a third-party 01265 /// thunk. Since we require that a call to C::f() first convert to A*, 01266 /// C-in-D's copy of A's vtable is never referenced, so this is not 01267 /// necessary. 01268 bool IsOverriderUsed(const CXXMethodDecl *Overrider, 01269 uint64_t BaseOffsetInLayoutClass, 01270 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 01271 uint64_t FirstBaseOffsetInLayoutClass) const; 01272 01273 01274 /// AddMethods - Add the methods of this base subobject and all its 01275 /// primary bases to the vtable components vector. 01276 void AddMethods(BaseSubobject Base, uint64_t BaseOffsetInLayoutClass, 01277 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 01278 uint64_t FirstBaseOffsetInLayoutClass, 01279 PrimaryBasesSetVectorTy &PrimaryBases); 01280 01281 // LayoutVtable - Layout the vtable for the given base class, including its 01282 // secondary vtables and any vtables for virtual bases. 01283 void LayoutVtable(); 01284 01285 /// LayoutPrimaryAndSecondaryVtables - Layout the primary vtable for the 01286 /// given base subobject, as well as all its secondary vtables. 01287 void LayoutPrimaryAndSecondaryVtables(BaseSubobject Base, 01288 bool BaseIsVirtual, 01289 uint64_t OffsetInLayoutClass); 01290 01291 /// LayoutSecondaryVtables - Layout the secondary vtables for the given base 01292 /// subobject. 01293 /// 01294 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base 01295 /// or a direct or indirect base of a virtual base. 01296 void LayoutSecondaryVtables(BaseSubobject Base, bool BaseIsMorallyVirtual, 01297 uint64_t OffsetInLayoutClass); 01298 01299 /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this 01300 /// class hierarchy. 01301 void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, 01302 uint64_t OffsetInLayoutClass, 01303 VisitedVirtualBasesSetTy &VBases); 01304 01305 /// LayoutVtablesForVirtualBases - Layout vtables for all virtual bases of the 01306 /// given base (excluding any primary bases). 01307 void LayoutVtablesForVirtualBases(const CXXRecordDecl *RD, 01308 VisitedVirtualBasesSetTy &VBases); 01309 01310 /// isBuildingConstructionVtable - Return whether this vtable builder is 01311 /// building a construction vtable. 01312 bool isBuildingConstructorVtable() const { 01313 return MostDerivedClass != LayoutClass; 01314 } 01315 01316 public: 01317 VtableBuilder(CGVtableInfo &VtableInfo, const CXXRecordDecl *MostDerivedClass, 01318 uint64_t MostDerivedClassOffset, bool MostDerivedClassIsVirtual, 01319 const CXXRecordDecl *LayoutClass) 01320 : VtableInfo(VtableInfo), MostDerivedClass(MostDerivedClass), 01321 MostDerivedClassOffset(MostDerivedClassOffset), 01322 MostDerivedClassIsVirtual(MostDerivedClassIsVirtual), 01323 LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()), 01324 Overriders(MostDerivedClass, MostDerivedClassOffset, LayoutClass) { 01325 01326 LayoutVtable(); 01327 } 01328 01329 /// dumpLayout - Dump the vtable layout. 01330 void dumpLayout(llvm::raw_ostream&); 01331 }; 01332 01333 /// OverridesMethodInBases - Checks whether whether this virtual member 01334 /// function overrides a member function in any of the given bases. 01335 /// Returns the overridden member function, or null if none was found. 01336 static const CXXMethodDecl * 01337 OverridesMethodInBases(const CXXMethodDecl *MD, 01338 VtableBuilder::PrimaryBasesSetVectorTy &Bases) { 01339 for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), 01340 E = MD->end_overridden_methods(); I != E; ++I) { 01341 const CXXMethodDecl *OverriddenMD = *I; 01342 const CXXRecordDecl *OverriddenRD = OverriddenMD->getParent(); 01343 assert(OverriddenMD->isCanonicalDecl() && 01344 "Should have the canonical decl of the overridden RD!"); 01345 01346 if (Bases.count(OverriddenRD)) 01347 return OverriddenMD; 01348 } 01349 01350 return 0; 01351 } 01352 01353 void VtableBuilder::ComputeThisAdjustments() { 01354 // Now go through the method info map and see if any of the methods need 01355 // 'this' pointer adjustments. 01356 for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(), 01357 E = MethodInfoMap.end(); I != E; ++I) { 01358 const CXXMethodDecl *MD = I->first; 01359 const MethodInfo &MethodInfo = I->second; 01360 01361 // Ignore adjustments for unused function pointers. 01362 uint64_t VtableIndex = MethodInfo.VtableIndex; 01363 if (Components[VtableIndex].getKind() == 01364 VtableComponent::CK_UnusedFunctionPointer) 01365 continue; 01366 01367 // Get the final overrider for this method. 01368 FinalOverriders::OverriderInfo Overrider = 01369 Overriders.getOverrider(BaseSubobject(MD->getParent(), 01370 MethodInfo.BaseOffset), MD); 01371 01372 ThisAdjustment ThisAdjustment = 01373 ComputeThisAdjustment(MD, MethodInfo.BaseOffsetInLayoutClass, Overrider); 01374 01375 if (ThisAdjustment.isEmpty()) 01376 continue; 01377 01378 // Add it. 01379 Thunks[VtableIndex].This = ThisAdjustment; 01380 01381 if (isa<CXXDestructorDecl>(MD)) { 01382 // Add an adjustment for the deleting destructor as well. 01383 Thunks[VtableIndex + 1].This = ThisAdjustment; 01384 } 01385 } 01386 01387 /// Clear the method info map. 01388 MethodInfoMap.clear(); 01389 } 01390 01391 VtableBuilder::ReturnAdjustment 01392 VtableBuilder::ComputeReturnAdjustment(BaseOffset Offset) { 01393 ReturnAdjustment Adjustment; 01394 01395 if (!Offset.isEmpty()) { 01396 if (Offset.VirtualBase) { 01397 // Get the virtual base offset offset. 01398 if (Offset.DerivedClass == MostDerivedClass) { 01399 // We can get the offset offset directly from our map. 01400 Adjustment.VBaseOffsetOffset = 01401 VBaseOffsetOffsets.lookup(Offset.VirtualBase); 01402 } else { 01403 Adjustment.VBaseOffsetOffset = 01404 VtableInfo.getVirtualBaseOffsetOffset(Offset.DerivedClass, 01405 Offset.VirtualBase); 01406 } 01407 01408 // FIXME: Once the assert in getVirtualBaseOffsetOffset is back again, 01409 // we can get rid of this assert. 01410 assert(Adjustment.VBaseOffsetOffset != 0 && 01411 "Invalid vbase offset offset!"); 01412 } 01413 01414 Adjustment.NonVirtual = Offset.NonVirtualOffset; 01415 } 01416 01417 return Adjustment; 01418 } 01419 01420 BaseOffset 01421 VtableBuilder::ComputeThisAdjustmentBaseOffset(BaseSubobject Base, 01422 BaseSubobject Derived) const { 01423 const CXXRecordDecl *BaseRD = Base.getBase(); 01424 const CXXRecordDecl *DerivedRD = Derived.getBase(); 01425 01426 CXXBasePaths Paths(/*FindAmbiguities=*/true, 01427 /*RecordPaths=*/true, /*DetectVirtual=*/true); 01428 01429 if (!const_cast<CXXRecordDecl *>(DerivedRD)-> 01430 isDerivedFrom(const_cast<CXXRecordDecl *>(BaseRD), Paths)) { 01431 assert(false && "Class must be derived from the passed in base class!"); 01432 return BaseOffset(); 01433 } 01434 01435 // We have to go through all the paths, and see which one leads us to the 01436 // right base subobject. 01437 for (CXXBasePaths::const_paths_iterator I = Paths.begin(), E = Paths.end(); 01438 I != E; ++I) { 01439 BaseOffset Offset = ComputeBaseOffset(Context, DerivedRD, *I); 01440 01441 // FIXME: Should not use * 8 here. 01442 uint64_t OffsetToBaseSubobject = Offset.NonVirtualOffset * 8; 01443 01444 if (Offset.VirtualBase) { 01445 // If we have a virtual base class, the non-virtual offset is relative 01446 // to the virtual base class offset. 01447 const ASTRecordLayout &LayoutClassLayout = 01448 Context.getASTRecordLayout(LayoutClass); 01449 01450 /// Get the virtual base offset, relative to the most derived class 01451 /// layout. 01452 OffsetToBaseSubobject += 01453 LayoutClassLayout.getVBaseClassOffset(Offset.VirtualBase); 01454 } else { 01455 // Otherwise, the non-virtual offset is relative to the derived class 01456 // offset. 01457 OffsetToBaseSubobject += Derived.getBaseOffset(); 01458 } 01459 01460 // Check if this path gives us the right base subobject. 01461 if (OffsetToBaseSubobject == Base.getBaseOffset()) { 01462 // Since we're going from the base class _to_ the derived class, we'll 01463 // invert the non-virtual offset here. 01464 Offset.NonVirtualOffset = -Offset.NonVirtualOffset; 01465 return Offset; 01466 } 01467 } 01468 01469 return BaseOffset(); 01470 } 01471 01472 VtableBuilder::ThisAdjustment 01473 VtableBuilder::ComputeThisAdjustment(const CXXMethodDecl *MD, 01474 uint64_t BaseOffsetInLayoutClass, 01475 FinalOverriders::OverriderInfo Overrider) { 01476 // Check if we need an adjustment at all. 01477 if (BaseOffsetInLayoutClass == Overrider.Offset) 01478 return ThisAdjustment(); 01479 01480 // Ignore adjustments for pure virtual member functions. 01481 if (Overrider.Method->isPure()) 01482 return ThisAdjustment(); 01483 01484 BaseSubobject OverriddenBaseSubobject(MD->getParent(), 01485 BaseOffsetInLayoutClass); 01486 01487 BaseSubobject OverriderBaseSubobject(Overrider.Method->getParent(), 01488 Overrider.Offset); 01489 01490 // Compute the adjustment offset. 01491 BaseOffset Offset = ComputeThisAdjustmentBaseOffset(OverriddenBaseSubobject, 01492 OverriderBaseSubobject); 01493 if (Offset.isEmpty()) 01494 return ThisAdjustment(); 01495 01496 ThisAdjustment Adjustment; 01497 01498 if (Offset.VirtualBase) { 01499 // Get the vcall offset map for this virtual base. 01500 VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Offset.VirtualBase]; 01501 01502 if (VCallOffsets.empty()) { 01503 // We don't have vcall offsets for this virtual base, go ahead and 01504 // build them. 01505 VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClass, 01506 /*FinalOverriders=*/0, 01507 BaseSubobject(Offset.VirtualBase, 0), 01508 /*BaseIsVirtual=*/true, 01509 /*OffsetInLayoutClass=*/0); 01510 01511 VCallOffsets = Builder.getVCallOffsets(); 01512 } 01513 01514 Adjustment.VCallOffsetOffset = VCallOffsets.getVCallOffsetOffset(MD); 01515 } 01516 01517 // Set the non-virtual part of the adjustment. 01518 Adjustment.NonVirtual = Offset.NonVirtualOffset; 01519 01520 return Adjustment; 01521 } 01522 01523 void 01524 VtableBuilder::AddMethod(const CXXMethodDecl *MD, 01525 ReturnAdjustment ReturnAdjustment) { 01526 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 01527 assert(ReturnAdjustment.isEmpty() && 01528 "Destructor can't have return adjustment!"); 01529 01530 // Add both the complete destructor and the deleting destructor. 01531 Components.push_back(VtableComponent::MakeCompleteDtor(DD)); 01532 Components.push_back(VtableComponent::MakeDeletingDtor(DD)); 01533 } else { 01534 // Add the return adjustment if necessary. 01535 if (!ReturnAdjustment.isEmpty()) 01536 Thunks[Components.size()].Return = ReturnAdjustment; 01537 01538 // Add the function. 01539 Components.push_back(VtableComponent::MakeFunction(MD)); 01540 } 01541 } 01542 01543 /// OverridesIndirectMethodInBase - Return whether the given member function 01544 /// overrides any methods in the set of given bases. 01545 /// Unlike OverridesMethodInBase, this checks "overriders of overriders". 01546 /// For example, if we have: 01547 /// 01548 /// struct A { virtual void f(); } 01549 /// struct B : A { virtual void f(); } 01550 /// struct C : B { virtual void f(); } 01551 /// 01552 /// OverridesIndirectMethodInBase will return true if given C::f as the method 01553 /// and { A } as the set of bases. 01554 static bool 01555 OverridesIndirectMethodInBases(const CXXMethodDecl *MD, 01556 VtableBuilder::PrimaryBasesSetVectorTy &Bases) { 01557 for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), 01558 E = MD->end_overridden_methods(); I != E; ++I) { 01559 const CXXMethodDecl *OverriddenMD = *I; 01560 const CXXRecordDecl *OverriddenRD = OverriddenMD->getParent(); 01561 assert(OverriddenMD->isCanonicalDecl() && 01562 "Should have the canonical decl of the overridden RD!"); 01563 01564 if (Bases.count(OverriddenRD)) 01565 return true; 01566 01567 // Check "indirect overriders". 01568 if (OverridesIndirectMethodInBases(OverriddenMD, Bases)) 01569 return true; 01570 } 01571 01572 return false; 01573 } 01574 01575 bool 01576 VtableBuilder::IsOverriderUsed(const CXXMethodDecl *Overrider, 01577 uint64_t BaseOffsetInLayoutClass, 01578 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 01579 uint64_t FirstBaseOffsetInLayoutClass) const { 01580 // If the base and the first base in the primary base chain have the same 01581 // offsets, then this overrider will be used. 01582 if (BaseOffsetInLayoutClass == FirstBaseOffsetInLayoutClass) 01583 return true; 01584 01585 // We know now that Base (or a direct or indirect base of it) is a primary 01586 // base in part of the class hierarchy, but not a primary base in the most 01587 // derived class. 01588 01589 // If the overrider is the first base in the primary base chain, we know 01590 // that the overrider will be used. 01591 if (Overrider->getParent() == FirstBaseInPrimaryBaseChain) 01592 return true; 01593 01594 VtableBuilder::PrimaryBasesSetVectorTy PrimaryBases; 01595 01596 const CXXRecordDecl *RD = FirstBaseInPrimaryBaseChain; 01597 PrimaryBases.insert(RD); 01598 01599 // Now traverse the base chain, starting with the first base, until we find 01600 // the base that is no longer a primary base. 01601 while (true) { 01602 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 01603 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 01604 01605 if (!PrimaryBase) 01606 break; 01607 01608 if (Layout.getPrimaryBaseWasVirtual()) { 01609 assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 && 01610 "Primary base should always be at offset 0!"); 01611 01612 const ASTRecordLayout &LayoutClassLayout = 01613 Context.getASTRecordLayout(LayoutClass); 01614 01615 // Now check if this is the primary base that is not a primary base in the 01616 // most derived class. 01617 if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) != 01618 FirstBaseOffsetInLayoutClass) { 01619 // We found it, stop walking the chain. 01620 break; 01621 } 01622 } else { 01623 assert(Layout.getBaseClassOffset(PrimaryBase) == 0 && 01624 "Primary base should always be at offset 0!"); 01625 } 01626 01627 if (!PrimaryBases.insert(PrimaryBase)) 01628 assert(false && "Found a duplicate primary base!"); 01629 01630 RD = PrimaryBase; 01631 } 01632 01633 // If the final overrider is an override of one of the primary bases, 01634 // then we know that it will be used. 01635 return OverridesIndirectMethodInBases(Overrider, PrimaryBases); 01636 } 01637 01638 /// FindNearestOverriddenMethod - Given a method, returns the overridden method 01639 /// from the nearest base. Returns null if no method was found. 01640 static const CXXMethodDecl * 01641 FindNearestOverriddenMethod(const CXXMethodDecl *MD, 01642 VtableBuilder::PrimaryBasesSetVectorTy &Bases) { 01643 for (int I = Bases.size(), E = 0; I != E; --I) { 01644 const CXXRecordDecl *PrimaryBase = Bases[I - 1]; 01645 01646 // Now check the overriden methods. 01647 for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), 01648 E = MD->end_overridden_methods(); I != E; ++I) { 01649 const CXXMethodDecl *OverriddenMD = *I; 01650 01651 // We found our overridden method. 01652 if (OverriddenMD->getParent() == PrimaryBase) 01653 return OverriddenMD; 01654 } 01655 } 01656 01657 return 0; 01658 } 01659 01660 void 01661 VtableBuilder::AddMethods(BaseSubobject Base, uint64_t BaseOffsetInLayoutClass, 01662 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 01663 uint64_t FirstBaseOffsetInLayoutClass, 01664 PrimaryBasesSetVectorTy &PrimaryBases) { 01665 const CXXRecordDecl *RD = Base.getBase(); 01666 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 01667 01668 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 01669 uint64_t PrimaryBaseOffset; 01670 uint64_t PrimaryBaseOffsetInLayoutClass; 01671 if (Layout.getPrimaryBaseWasVirtual()) { 01672 assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 && 01673 "Primary vbase should have a zero offset!"); 01674 01675 const ASTRecordLayout &MostDerivedClassLayout = 01676 Context.getASTRecordLayout(MostDerivedClass); 01677 01678 PrimaryBaseOffset = 01679 MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); 01680 01681 const ASTRecordLayout &LayoutClassLayout = 01682 Context.getASTRecordLayout(LayoutClass); 01683 01684 PrimaryBaseOffsetInLayoutClass = 01685 LayoutClassLayout.getVBaseClassOffset(PrimaryBase); 01686 } else { 01687 assert(Layout.getBaseClassOffset(PrimaryBase) == 0 && 01688 "Primary base should have a zero offset!"); 01689 01690 PrimaryBaseOffset = Base.getBaseOffset(); 01691 PrimaryBaseOffsetInLayoutClass = BaseOffsetInLayoutClass; 01692 } 01693 01694 AddMethods(BaseSubobject(PrimaryBase, PrimaryBaseOffset), 01695 PrimaryBaseOffsetInLayoutClass, FirstBaseInPrimaryBaseChain, 01696 FirstBaseOffsetInLayoutClass, PrimaryBases); 01697 01698 if (!PrimaryBases.insert(PrimaryBase)) 01699 assert(false && "Found a duplicate primary base!"); 01700 } 01701 01702 // Now go through all virtual member functions and add them. 01703 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 01704 E = RD->method_end(); I != E; ++I) { 01705 const CXXMethodDecl *MD = *I; 01706 01707 if (!MD->isVirtual()) 01708 continue; 01709 01710 // Get the final overrider. 01711 FinalOverriders::OverriderInfo Overrider = 01712 Overriders.getOverrider(Base, MD); 01713 01714 // Check if this virtual member function overrides a method in a primary 01715 // base. If this is the case, and the return type doesn't require adjustment 01716 // then we can just use the member function from the primary base. 01717 if (const CXXMethodDecl *OverriddenMD = 01718 FindNearestOverriddenMethod(MD, PrimaryBases)) { 01719 if (ComputeReturnAdjustmentBaseOffset(Context, MD, 01720 OverriddenMD).isEmpty()) { 01721 // Replace the method info of the overridden method with our own 01722 // method. 01723 assert(MethodInfoMap.count(OverriddenMD) && 01724 "Did not find the overridden method!"); 01725 MethodInfo &OverriddenMethodInfo = MethodInfoMap[OverriddenMD]; 01726 01727 MethodInfo MethodInfo(Base.getBaseOffset(), 01728 BaseOffsetInLayoutClass, 01729 OverriddenMethodInfo.VtableIndex); 01730 01731 assert(!MethodInfoMap.count(MD) && 01732 "Should not have method info for this method yet!"); 01733 01734 MethodInfoMap.insert(std::make_pair(MD, MethodInfo)); 01735 MethodInfoMap.erase(OverriddenMD); 01736 continue; 01737 } 01738 } 01739 01740 // Insert the method info for this method. 01741 MethodInfo MethodInfo(Base.getBaseOffset(), BaseOffsetInLayoutClass, 01742 Components.size()); 01743 01744 assert(!MethodInfoMap.count(MD) && 01745 "Should not have method info for this method yet!"); 01746 MethodInfoMap.insert(std::make_pair(MD, MethodInfo)); 01747 01748 // Check if this overrider is going to be used. 01749 const CXXMethodDecl *OverriderMD = Overrider.Method; 01750 if (!IsOverriderUsed(OverriderMD, BaseOffsetInLayoutClass, 01751 FirstBaseInPrimaryBaseChain, 01752 FirstBaseOffsetInLayoutClass)) { 01753 Components.push_back(VtableComponent::MakeUnusedFunction(OverriderMD)); 01754 continue; 01755 } 01756 01757 // Check if this overrider needs a return adjustment. 01758 BaseOffset ReturnAdjustmentOffset = 01759 Overriders.getReturnAdjustmentOffset(Base, MD); 01760 01761 ReturnAdjustment ReturnAdjustment = 01762 ComputeReturnAdjustment(ReturnAdjustmentOffset); 01763 01764 AddMethod(Overrider.Method, ReturnAdjustment); 01765 } 01766 } 01767 01768 void VtableBuilder::LayoutVtable() { 01769 LayoutPrimaryAndSecondaryVtables(BaseSubobject(MostDerivedClass, 0), 01770 MostDerivedClassIsVirtual, 01771 MostDerivedClassOffset); 01772 01773 VisitedVirtualBasesSetTy VBases; 01774 01775 // Determine the primary virtual bases. 01776 DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset, 01777 VBases); 01778 VBases.clear(); 01779 01780 LayoutVtablesForVirtualBases(MostDerivedClass, VBases); 01781 } 01782 01783 void 01784 VtableBuilder::LayoutPrimaryAndSecondaryVtables(BaseSubobject Base, 01785 bool BaseIsVirtual, 01786 uint64_t OffsetInLayoutClass) { 01787 assert(Base.getBase()->isDynamicClass() && "class does not have a vtable!"); 01788 01789 // Add vcall and vbase offsets for this vtable. 01790 VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, LayoutClass, &Overriders, 01791 Base, BaseIsVirtual, OffsetInLayoutClass); 01792 Components.append(Builder.components_begin(), Builder.components_end()); 01793 01794 // Check if we need to add these vcall offsets. 01795 if (BaseIsVirtual && !Builder.getVCallOffsets().empty()) { 01796 VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Base.getBase()]; 01797 01798 if (VCallOffsets.empty()) 01799 VCallOffsets = Builder.getVCallOffsets(); 01800 } 01801 01802 // If we're laying out the most derived class we want to keep track of the 01803 // virtual base class offset offsets. 01804 if (Base.getBase() == MostDerivedClass) 01805 VBaseOffsetOffsets = Builder.getVBaseOffsetOffsets(); 01806 01807 // Add the offset to top. 01808 // FIXME: We should not use / 8 here. 01809 int64_t OffsetToTop = -(int64_t)(OffsetInLayoutClass - 01810 MostDerivedClassOffset) / 8; 01811 Components.push_back(VtableComponent::MakeOffsetToTop(OffsetToTop)); 01812 01813 // Next, add the RTTI. 01814 Components.push_back(VtableComponent::MakeRTTI(MostDerivedClass)); 01815 01816 uint64_t AddressPoint = Components.size(); 01817 01818 // Now go through all virtual member functions and add them. 01819 PrimaryBasesSetVectorTy PrimaryBases; 01820 AddMethods(Base, OffsetInLayoutClass, Base.getBase(), OffsetInLayoutClass, 01821 PrimaryBases); 01822 01823 // Compute 'this' pointer adjustments. 01824 ComputeThisAdjustments(); 01825 01826 // Record the address point. 01827 AddressPoints.insert(std::make_pair(BaseSubobject(Base.getBase(), 01828 OffsetInLayoutClass), 01829 AddressPoint)); 01830 01831 // Record the address points for all primary bases. 01832 for (PrimaryBasesSetVectorTy::const_iterator I = PrimaryBases.begin(), 01833 E = PrimaryBases.end(); I != E; ++I) { 01834 const CXXRecordDecl *BaseDecl = *I; 01835 01836 // We know that all the primary bases have the same offset as the base 01837 // subobject. 01838 BaseSubobject PrimaryBase(BaseDecl, OffsetInLayoutClass); 01839 AddressPoints.insert(std::make_pair(PrimaryBase, AddressPoint)); 01840 } 01841 01842 bool BaseIsMorallyVirtual = BaseIsVirtual; 01843 if (isBuildingConstructorVtable() && Base.getBase() == MostDerivedClass) 01844 BaseIsMorallyVirtual = false; 01845 01846 // Layout secondary vtables. 01847 LayoutSecondaryVtables(Base, BaseIsMorallyVirtual, OffsetInLayoutClass); 01848 } 01849 01850 void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base, 01851 bool BaseIsMorallyVirtual, 01852 uint64_t OffsetInLayoutClass) { 01853 // Itanium C++ ABI 2.5.2: 01854 // Following the primary virtual table of a derived class are secondary 01855 // virtual tables for each of its proper base classes, except any primary 01856 // base(s) with which it shares its primary virtual table. 01857 01858 const CXXRecordDecl *RD = Base.getBase(); 01859 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 01860 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 01861 01862 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 01863 E = RD->bases_end(); I != E; ++I) { 01864 // Ignore virtual bases, we'll emit them later. 01865 if (I->isVirtual()) 01866 continue; 01867 01868 const CXXRecordDecl *BaseDecl = 01869 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 01870 01871 // Ignore bases that don't have a vtable. 01872 if (!BaseDecl->isDynamicClass()) 01873 continue; 01874 01875 if (isBuildingConstructorVtable()) { 01876 // Itanium C++ ABI 2.6.4: 01877 // Some of the base class subobjects may not need construction virtual 01878 // tables, which will therefore not be present in the construction 01879 // virtual table group, even though the subobject virtual tables are 01880 // present in the main virtual table group for the complete object. 01881 if (!BaseIsMorallyVirtual && !BaseDecl->getNumVBases()) 01882 continue; 01883 } 01884 01885 // Get the base offset of this base. 01886 uint64_t RelativeBaseOffset = Layout.getBaseClassOffset(BaseDecl); 01887 uint64_t BaseOffset = Base.getBaseOffset() + RelativeBaseOffset; 01888 01889 uint64_t BaseOffsetInLayoutClass = OffsetInLayoutClass + RelativeBaseOffset; 01890 01891 // Don't emit a secondary vtable for a primary base. We might however want 01892 // to emit secondary vtables for other bases of this base. 01893 if (BaseDecl == PrimaryBase) { 01894 LayoutSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset), 01895 BaseIsMorallyVirtual, BaseOffsetInLayoutClass); 01896 continue; 01897 } 01898 01899 // Layout the primary vtable (and any secondary vtables) for this base. 01900 LayoutPrimaryAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset), 01901 /*BaseIsVirtual=*/false, 01902 BaseOffsetInLayoutClass); 01903 } 01904 } 01905 01906 void 01907 VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, 01908 uint64_t OffsetInLayoutClass, 01909 VisitedVirtualBasesSetTy &VBases) { 01910 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 01911 01912 // Check if this base has a primary base. 01913 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 01914 01915 // Check if it's virtual. 01916 if (Layout.getPrimaryBaseWasVirtual()) { 01917 bool IsPrimaryVirtualBase = true; 01918 01919 if (isBuildingConstructorVtable()) { 01920 // Check if the base is actually a primary base in the class we use for 01921 // layout. 01922 const ASTRecordLayout &LayoutClassLayout = 01923 Context.getASTRecordLayout(LayoutClass); 01924 01925 uint64_t PrimaryBaseOffsetInLayoutClass = 01926 LayoutClassLayout.getVBaseClassOffset(PrimaryBase); 01927 01928 // We know that the base is not a primary base in the layout class if 01929 // the base offsets are different. 01930 if (PrimaryBaseOffsetInLayoutClass != OffsetInLayoutClass) 01931 IsPrimaryVirtualBase = false; 01932 } 01933 01934 if (IsPrimaryVirtualBase) 01935 PrimaryVirtualBases.insert(PrimaryBase); 01936 } 01937 } 01938 01939 // Traverse bases, looking for more primary virtual bases. 01940 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 01941 E = RD->bases_end(); I != E; ++I) { 01942 const CXXRecordDecl *BaseDecl = 01943 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 01944 01945 uint64_t BaseOffsetInLayoutClass; 01946 01947 if (I->isVirtual()) { 01948 if (!VBases.insert(BaseDecl)) 01949 continue; 01950 01951 const ASTRecordLayout &LayoutClassLayout = 01952 Context.getASTRecordLayout(LayoutClass); 01953 01954 BaseOffsetInLayoutClass = LayoutClassLayout.getVBaseClassOffset(BaseDecl); 01955 } else { 01956 BaseOffsetInLayoutClass = 01957 OffsetInLayoutClass + Layout.getBaseClassOffset(BaseDecl); 01958 } 01959 01960 DeterminePrimaryVirtualBases(BaseDecl, BaseOffsetInLayoutClass, VBases); 01961 } 01962 } 01963 01964 void 01965 VtableBuilder::LayoutVtablesForVirtualBases(const CXXRecordDecl *RD, 01966 VisitedVirtualBasesSetTy &VBases) { 01967 // Itanium C++ ABI 2.5.2: 01968 // Then come the virtual base virtual tables, also in inheritance graph 01969 // order, and again excluding primary bases (which share virtual tables with 01970 // the classes for which they are primary). 01971 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 01972 E = RD->bases_end(); I != E; ++I) { 01973 const CXXRecordDecl *BaseDecl = 01974 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 01975 01976 // Check if this base needs a vtable. (If it's virtual, not a primary base 01977 // of some other class, and we haven't visited it before). 01978 if (I->isVirtual() && BaseDecl->isDynamicClass() && 01979 !PrimaryVirtualBases.count(BaseDecl) && VBases.insert(BaseDecl)) { 01980 const ASTRecordLayout &MostDerivedClassLayout = 01981 Context.getASTRecordLayout(MostDerivedClass); 01982 uint64_t BaseOffset = 01983 MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 01984 01985 const ASTRecordLayout &LayoutClassLayout = 01986 Context.getASTRecordLayout(LayoutClass); 01987 uint64_t BaseOffsetInLayoutClass = 01988 LayoutClassLayout.getVBaseClassOffset(BaseDecl); 01989 01990 LayoutPrimaryAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset), 01991 /*BaseIsVirtual=*/true, 01992 BaseOffsetInLayoutClass); 01993 } 01994 01995 // We only need to check the base for virtual base vtables if it actually 01996 // has virtual bases. 01997 if (BaseDecl->getNumVBases()) 01998 LayoutVtablesForVirtualBases(BaseDecl, VBases); 01999 } 02000 } 02001 02002 /// dumpLayout - Dump the vtable layout. 02003 void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) { 02004 02005 if (isBuildingConstructorVtable()) { 02006 Out << "Construction vtable for ('"; 02007 Out << MostDerivedClass->getQualifiedNameAsString() << "', "; 02008 // FIXME: Don't use / 8 . 02009 Out << MostDerivedClassOffset / 8 << ") in '"; 02010 Out << LayoutClass->getQualifiedNameAsString(); 02011 } else { 02012 Out << "Vtable for '"; 02013 Out << MostDerivedClass->getQualifiedNameAsString(); 02014 } 02015 Out << "' (" << Components.size() << " entries).\n"; 02016 02017 // Iterate through the address points and insert them into a new map where 02018 // they are keyed by the index and not the base object. 02019 // Since an address point can be shared by multiple subobjects, we use an 02020 // STL multimap. 02021 std::multimap<uint64_t, BaseSubobject> AddressPointsByIndex; 02022 for (CGVtableInfo::AddressPointsMapTy::const_iterator I = 02023 AddressPoints.begin(), E = AddressPoints.end(); I != E; ++I) { 02024 const BaseSubobject& Base = I->first; 02025 uint64_t Index = I->second; 02026 02027 AddressPointsByIndex.insert(std::make_pair(Index, Base)); 02028 } 02029 02030 for (unsigned I = 0, E = Components.size(); I != E; ++I) { 02031 uint64_t Index = I; 02032 02033 Out << llvm::format("%4d | ", I); 02034 02035 const VtableComponent &Component = Components[I]; 02036 02037 // Dump the component. 02038 switch (Component.getKind()) { 02039 02040 case VtableComponent::CK_VCallOffset: 02041 Out << "vcall_offset (" << Component.getVCallOffset() << ")"; 02042 break; 02043 02044 case VtableComponent::CK_VBaseOffset: 02045 Out << "vbase_offset (" << Component.getVBaseOffset() << ")"; 02046 break; 02047 02048 case VtableComponent::CK_OffsetToTop: 02049 Out << "offset_to_top (" << Component.getOffsetToTop() << ")"; 02050 break; 02051 02052 case VtableComponent::CK_RTTI: 02053 Out << Component.getRTTIDecl()->getQualifiedNameAsString() << " RTTI"; 02054 break; 02055 02056 case VtableComponent::CK_FunctionPointer: { 02057 const CXXMethodDecl *MD = Component.getFunctionDecl(); 02058 02059 std::string Str = 02060 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 02061 MD); 02062 Out << Str; 02063 if (MD->isPure()) 02064 Out << " [pure]"; 02065 02066 ThunkInfo Thunk = Thunks.lookup(I); 02067 if (!Thunk.isEmpty()) { 02068 // If this function pointer has a return adjustment, dump it. 02069 if (!Thunk.Return.isEmpty()) { 02070 Out << "\n [return adjustment: "; 02071 Out << Thunk.Return.NonVirtual << " non-virtual"; 02072 02073 if (Thunk.Return.VBaseOffsetOffset) { 02074 Out << ", " << Thunk.Return.VBaseOffsetOffset; 02075 Out << " vbase offset offset"; 02076 } 02077 02078 Out << ']'; 02079 } 02080 02081 // If this function pointer has a 'this' pointer adjustment, dump it. 02082 if (!Thunk.This.isEmpty()) { 02083 Out << "\n [this adjustment: "; 02084 Out << Thunk.This.NonVirtual << " non-virtual"; 02085 02086 if (Thunk.This.VCallOffsetOffset) { 02087 Out << ", " << Thunk.This.VCallOffsetOffset; 02088 Out << " vcall offset offset"; 02089 } 02090 02091 Out << ']'; 02092 } 02093 } 02094 02095 break; 02096 } 02097 02098 case VtableComponent::CK_CompleteDtorPointer: 02099 case VtableComponent::CK_DeletingDtorPointer: { 02100 bool IsComplete = 02101 Component.getKind() == VtableComponent::CK_CompleteDtorPointer; 02102 02103 const CXXDestructorDecl *DD = Component.getDestructorDecl(); 02104 02105 Out << DD->getQualifiedNameAsString(); 02106 if (IsComplete) 02107 Out << "() [complete]"; 02108 else 02109 Out << "() [deleting]"; 02110 02111 if (DD->isPure()) 02112 Out << " [pure]"; 02113 02114 ThunkInfo Thunk = Thunks.lookup(I); 02115 if (!Thunk.isEmpty()) { 02116 // If this destructor has a 'this' pointer adjustment, dump it. 02117 if (!Thunk.This.isEmpty()) { 02118 Out << "\n [this adjustment: "; 02119 Out << Thunk.This.NonVirtual << " non-virtual"; 02120 02121 if (Thunk.This.VCallOffsetOffset) { 02122 Out << ", " << Thunk.This.VCallOffsetOffset; 02123 Out << " vcall offset offset"; 02124 } 02125 02126 Out << ']'; 02127 } 02128 } 02129 02130 break; 02131 } 02132 02133 case VtableComponent::CK_UnusedFunctionPointer: { 02134 const CXXMethodDecl *MD = Component.getUnusedFunctionDecl(); 02135 02136 std::string Str = 02137 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 02138 MD); 02139 Out << "[unused] " << Str; 02140 if (MD->isPure()) 02141 Out << " [pure]"; 02142 } 02143 02144 } 02145 02146 Out << '\n'; 02147 02148 // Dump the next address point. 02149 uint64_t NextIndex = Index + 1; 02150 if (AddressPointsByIndex.count(NextIndex)) { 02151 if (AddressPointsByIndex.count(NextIndex) == 1) { 02152 const BaseSubobject &Base = 02153 AddressPointsByIndex.find(NextIndex)->second; 02154 02155 // FIXME: Instead of dividing by 8, we should be using CharUnits. 02156 Out << " -- (" << Base.getBase()->getQualifiedNameAsString(); 02157 Out << ", " << Base.getBaseOffset() / 8 << ") vtable address --\n"; 02158 } else { 02159 uint64_t BaseOffset = 02160 AddressPointsByIndex.lower_bound(NextIndex)->second.getBaseOffset(); 02161 02162 // We store the class names in a set to get a stable order. 02163 std::set<std::string> ClassNames; 02164 for (std::multimap<uint64_t, BaseSubobject>::const_iterator I = 02165 AddressPointsByIndex.lower_bound(NextIndex), E = 02166 AddressPointsByIndex.upper_bound(NextIndex); I != E; ++I) { 02167 assert(I->second.getBaseOffset() == BaseOffset && 02168 "Invalid base offset!"); 02169 const CXXRecordDecl *RD = I->second.getBase(); 02170 ClassNames.insert(RD->getQualifiedNameAsString()); 02171 } 02172 02173 for (std::set<std::string>::const_iterator I = ClassNames.begin(), 02174 E = ClassNames.end(); I != E; ++I) { 02175 // FIXME: Instead of dividing by 8, we should be using CharUnits. 02176 Out << " -- (" << *I; 02177 Out << ", " << BaseOffset / 8 << ") vtable address --\n"; 02178 } 02179 } 02180 } 02181 } 02182 02183 Out << '\n'; 02184 02185 if (!isBuildingConstructorVtable() && MostDerivedClass->getNumVBases()) { 02186 Out << "Virtual base offset offsets for '"; 02187 Out << MostDerivedClass->getQualifiedNameAsString() << "'.\n"; 02188 02189 // We store the virtual base class names and their offsets in a map to get 02190 // a stable order. 02191 std::map<std::string, int64_t> ClassNamesAndOffsets; 02192 02193 for (VBaseOffsetOffsetsMapTy::const_iterator I = VBaseOffsetOffsets.begin(), 02194 E = VBaseOffsetOffsets.end(); I != E; ++I) { 02195 std::string ClassName = I->first->getQualifiedNameAsString(); 02196 int64_t OffsetOffset = I->second; 02197 ClassNamesAndOffsets.insert(std::make_pair(ClassName, OffsetOffset)); 02198 } 02199 02200 for (std::map<std::string, int64_t>::const_iterator I = 02201 ClassNamesAndOffsets.begin(), E = ClassNamesAndOffsets.end(); 02202 I != E; ++I) 02203 Out << " " << I->first << " | " << I->second << '\n'; 02204 02205 Out << "\n"; 02206 } 02207 } 02208 02209 } 02210 02211 namespace { 02212 class OldVtableBuilder { 02213 public: 02214 /// Index_t - Vtable index type. 02215 typedef uint64_t Index_t; 02216 typedef std::vector<std::pair<GlobalDecl, 02217 std::pair<GlobalDecl, ThunkAdjustment> > > 02218 SavedAdjustmentsVectorTy; 02219 private: 02220 02221 // VtableComponents - The components of the vtable being built. 02222 typedef llvm::SmallVector<llvm::Constant *, 64> VtableComponentsVectorTy; 02223 VtableComponentsVectorTy VtableComponents; 02224 02225 const bool BuildVtable; 02226 02227 llvm::Type *Ptr8Ty; 02228 02229 /// MostDerivedClass - The most derived class that this vtable is being 02230 /// built for. 02231 const CXXRecordDecl *MostDerivedClass; 02232 02233 /// LayoutClass - The most derived class used for virtual base layout 02234 /// information. 02235 const CXXRecordDecl *LayoutClass; 02236 /// LayoutOffset - The offset for Class in LayoutClass. 02237 uint64_t LayoutOffset; 02238 /// BLayout - Layout for the most derived class that this vtable is being 02239 /// built for. 02240 const ASTRecordLayout &BLayout; 02241 llvm::SmallSet<const CXXRecordDecl *, 32> IndirectPrimary; 02242 llvm::SmallSet<const CXXRecordDecl *, 32> SeenVBase; 02243 llvm::Constant *rtti; 02244 llvm::LLVMContext &VMContext; 02245 CodeGenModule &CGM; // Per-module state. 02246 02247 llvm::DenseMap<const CXXMethodDecl *, Index_t> VCall; 02248 llvm::DenseMap<GlobalDecl, Index_t> VCallOffset; 02249 llvm::DenseMap<GlobalDecl, Index_t> VCallOffsetForVCall; 02250 // This is the offset to the nearest virtual base 02251 llvm::DenseMap<const CXXMethodDecl *, Index_t> NonVirtualOffset; 02252 llvm::DenseMap<const CXXRecordDecl *, Index_t> VBIndex; 02253 02254 /// PureVirtualFunction - Points to __cxa_pure_virtual. 02255 llvm::Constant *PureVirtualFn; 02256 02257 /// VtableMethods - A data structure for keeping track of methods in a vtable. 02258 /// Can add methods, override methods and iterate in vtable order. 02259 class VtableMethods { 02260 // MethodToIndexMap - Maps from a global decl to the index it has in the 02261 // Methods vector. 02262 llvm::DenseMap<GlobalDecl, uint64_t> MethodToIndexMap; 02263 02264 /// Methods - The methods, in vtable order. 02265 typedef llvm::SmallVector<GlobalDecl, 16> MethodsVectorTy; 02266 MethodsVectorTy Methods; 02267 MethodsVectorTy OrigMethods; 02268 02269 public: 02270 /// AddMethod - Add a method to the vtable methods. 02271 void AddMethod(GlobalDecl GD) { 02272 assert(!MethodToIndexMap.count(GD) && 02273 "Method has already been added!"); 02274 02275 MethodToIndexMap[GD] = Methods.size(); 02276 Methods.push_back(GD); 02277 OrigMethods.push_back(GD); 02278 } 02279 02280 /// OverrideMethod - Replace a method with another. 02281 void OverrideMethod(GlobalDecl OverriddenGD, GlobalDecl GD) { 02282 llvm::DenseMap<GlobalDecl, uint64_t>::iterator i 02283 = MethodToIndexMap.find(OverriddenGD); 02284 assert(i != MethodToIndexMap.end() && "Did not find entry!"); 02285 02286 // Get the index of the old decl. 02287 uint64_t Index = i->second; 02288 02289 // Replace the old decl with the new decl. 02290 Methods[Index] = GD; 02291 02292 // And add the new. 02293 MethodToIndexMap[GD] = Index; 02294 } 02295 02296 /// getIndex - Gives the index of a passed in GlobalDecl. Returns false if 02297 /// the index couldn't be found. 02298 bool getIndex(GlobalDecl GD, uint64_t &Index) const { 02299 llvm::DenseMap<GlobalDecl, uint64_t>::const_iterator i 02300 = MethodToIndexMap.find(GD); 02301 02302 if (i == MethodToIndexMap.end()) 02303 return false; 02304 02305 Index = i->second; 02306 return true; 02307 } 02308 02309 GlobalDecl getOrigMethod(uint64_t Index) const { 02310 return OrigMethods[Index]; 02311 } 02312 02313 MethodsVectorTy::size_type size() const { 02314 return Methods.size(); 02315 } 02316 02317 void clear() { 02318 MethodToIndexMap.clear(); 02319 Methods.clear(); 02320 OrigMethods.clear(); 02321 } 02322 02323 GlobalDecl operator[](uint64_t Index) const { 02324 return Methods[Index]; 02325 } 02326 }; 02327 02328 /// Methods - The vtable methods we're currently building. 02329 VtableMethods Methods; 02330 02331 /// ThisAdjustments - For a given index in the vtable, contains the 'this' 02332 /// pointer adjustment needed for a method. 02333 typedef llvm::DenseMap<uint64_t, ThunkAdjustment> ThisAdjustmentsMapTy; 02334 ThisAdjustmentsMapTy ThisAdjustments; 02335 02336 SavedAdjustmentsVectorTy SavedAdjustments; 02337 02338 /// BaseReturnTypes - Contains the base return types of methods who have been 02339 /// overridden with methods whose return types require adjustment. Used for 02340 /// generating covariant thunk information. 02341 typedef llvm::DenseMap<uint64_t, CanQualType> BaseReturnTypesMapTy; 02342 BaseReturnTypesMapTy BaseReturnTypes; 02343 02344 std::vector<Index_t> VCalls; 02345 02346 typedef std::pair<const CXXRecordDecl *, uint64_t> CtorVtable_t; 02347 // subAddressPoints - Used to hold the AddressPoints (offsets) into the built 02348 // vtable for use in computing the initializers for the VTT. 02349 llvm::DenseMap<CtorVtable_t, int64_t> &subAddressPoints; 02350 02351 /// AddressPoints - Address points for this vtable. 02352 CGVtableInfo::AddressPointsMapTy& AddressPoints; 02353 02354 typedef CXXRecordDecl::method_iterator method_iter; 02355 const uint32_t LLVMPointerWidth; 02356 Index_t extra; 02357 typedef std::vector<std::pair<const CXXRecordDecl *, int64_t> > Path_t; 02358 static llvm::DenseMap<CtorVtable_t, int64_t>& 02359 AllocAddressPoint(CodeGenModule &cgm, const CXXRecordDecl *l, 02360 const CXXRecordDecl *c) { 02361 CGVtableInfo::AddrMap_t *&oref = cgm.getVtableInfo().AddressPoints[l]; 02362 if (oref == 0) 02363 oref = new CGVtableInfo::AddrMap_t; 02364 02365 llvm::DenseMap<CtorVtable_t, int64_t> *&ref = (*oref)[c]; 02366 if (ref == 0) 02367 ref = new llvm::DenseMap<CtorVtable_t, int64_t>; 02368 return *ref; 02369 } 02370 02371 bool DclIsSame(const FunctionDecl *New, const FunctionDecl *Old) { 02372 FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate(); 02373 FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate(); 02374 02375 // C++ [temp.fct]p2: 02376 // A function template can be overloaded with other function templates 02377 // and with normal (non-template) functions. 02378 if ((OldTemplate == 0) != (NewTemplate == 0)) 02379 return false; 02380 02381 // Is the function New an overload of the function Old? 02382 QualType OldQType = CGM.getContext().getCanonicalType(Old->getType()); 02383 QualType NewQType = CGM.getContext().getCanonicalType(New->getType()); 02384 02385 // Compare the signatures (C++ 1.3.10) of the two functions to 02386 // determine whether they are overloads. If we find any mismatch 02387 // in the signature, they are overloads. 02388 02389 // If either of these functions is a K&R-style function (no 02390 // prototype), then we consider them to have matching signatures. 02391 if (isa<FunctionNoProtoType>(OldQType.getTypePtr()) || 02392 isa<FunctionNoProtoType>(NewQType.getTypePtr())) 02393 return true; 02394 02395 FunctionProtoType* OldType = cast<FunctionProtoType>(OldQType); 02396 FunctionProtoType* NewType = cast<FunctionProtoType>(NewQType); 02397 02398 // The signature of a function includes the types of its 02399 // parameters (C++ 1.3.10), which includes the presence or absence 02400 // of the ellipsis; see C++ DR 357). 02401 if (OldQType != NewQType && 02402 (OldType->getNumArgs() != NewType->getNumArgs() || 02403 OldType->isVariadic() != NewType->isVariadic() || 02404 !std::equal(OldType->arg_type_begin(), OldType->arg_type_end(), 02405 NewType->arg_type_begin()))) 02406 return false; 02407 02408 #if 0 02409 // C++ [temp.over.link]p4: 02410 // The signature of a function template consists of its function 02411 // signature, its return type and its template parameter list. The names 02412 // of the template parameters are significant only for establishing the 02413 // relationship between the template parameters and the rest of the 02414 // signature. 02415 // 02416 // We check the return type and template parameter lists for function 02417 // templates first; the remaining checks follow. 02418 if (NewTemplate && 02419 (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), 02420 OldTemplate->getTemplateParameters(), 02421 TPL_TemplateMatch) || 02422 OldType->getResultType() != NewType->getResultType())) 02423 return false; 02424 #endif 02425 02426 // If the function is a class member, its signature includes the 02427 // cv-qualifiers (if any) on the function itself. 02428 // 02429 // As part of this, also check whether one of the member functions 02430 // is static, in which case they are not overloads (C++ 02431 // 13.1p2). While not part of the definition of the signature, 02432 // this check is important to determine whether these functions 02433 // can be overloaded. 02434 const CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old); 02435 const CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New); 02436 if (OldMethod && NewMethod && 02437 !OldMethod->isStatic() && !NewMethod->isStatic() && 02438 OldMethod->getTypeQualifiers() != NewMethod->getTypeQualifiers()) 02439 return false; 02440 02441 // The signatures match; this is not an overload. 02442 return true; 02443 } 02444 02445 typedef llvm::DenseMap<const CXXMethodDecl *, const CXXMethodDecl*> 02446 ForwardUnique_t; 02447 ForwardUnique_t ForwardUnique; 02448 llvm::DenseMap<const CXXMethodDecl*, const CXXMethodDecl*> UniqueOverrider; 02449 02450 void BuildUniqueOverrider(const CXXMethodDecl *U, const CXXMethodDecl *MD) { 02451 const CXXMethodDecl *PrevU = UniqueOverrider[MD]; 02452 assert(U && "no unique overrider"); 02453 if (PrevU == U) 02454 return; 02455 if (PrevU != U && PrevU != 0) { 02456 // If already set, note the two sets as the same 02457 if (0) 02458 printf("%s::%s same as %s::%s\n", 02459 PrevU->getParent()->getNameAsString().c_str(), 02460 PrevU->getNameAsString().c_str(), 02461 U->getParent()->getNameAsString().c_str(), 02462 U->getNameAsString().c_str()); 02463 ForwardUnique[PrevU] = U; 02464 return; 02465 } 02466 02467 // Not set, set it now 02468 if (0) 02469 printf("marking %s::%s %p override as %s::%s\n", 02470 MD->getParent()->getNameAsString().c_str(), 02471 MD->getNameAsString().c_str(), 02472 (void*)MD, 02473 U->getParent()->getNameAsString().c_str(), 02474 U->getNameAsString().c_str()); 02475 UniqueOverrider[MD] = U; 02476 02477 for (CXXMethodDecl::method_iterator mi = MD->begin_overridden_methods(), 02478 me = MD->end_overridden_methods(); mi != me; ++mi) { 02479 BuildUniqueOverrider(U, *mi); 02480 } 02481 } 02482 02483 void BuildUniqueOverriders(const CXXRecordDecl *RD) { 02484 if (0) printf("walking %s\n", RD->getNameAsCString()); 02485 for (CXXRecordDecl::method_iterator i = RD->method_begin(), 02486 e = RD->method_end(); i != e; ++i) { 02487 const CXXMethodDecl *MD = *i; 02488 if (!MD->isVirtual()) 02489 continue; 02490 02491 if (UniqueOverrider[MD] == 0) { 02492 // Only set this, if it hasn't been set yet. 02493 BuildUniqueOverrider(MD, MD); 02494 if (0) 02495 printf("top set is %s::%s %p\n", 02496 MD->getParent()->getNameAsString().c_str(), 02497 MD->getNameAsString().c_str(), 02498 (void*)MD); 02499 ForwardUnique[MD] = MD; 02500 } 02501 } 02502 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 02503 e = RD->bases_end(); i != e; ++i) { 02504 const CXXRecordDecl *Base = 02505 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 02506 BuildUniqueOverriders(Base); 02507 } 02508 } 02509 02510 static int DclCmp(const void *p1, const void *p2) { 02511 const CXXMethodDecl *MD1 = *(const CXXMethodDecl *const *)p1; 02512 const CXXMethodDecl *MD2 = *(const CXXMethodDecl *const *)p2; 02513 02514 return (DeclarationName::compare(MD1->getDeclName(), MD2->getDeclName())); 02515 } 02516 02517 void MergeForwarding() { 02518 typedef llvm::SmallVector<const CXXMethodDecl *, 100> A_t; 02519 A_t A; 02520 for (ForwardUnique_t::iterator I = ForwardUnique.begin(), 02521 E = ForwardUnique.end(); I != E; ++I) { 02522 if (I->first == I->second) 02523 // Only add the roots of all trees 02524 A.push_back(I->first); 02525 } 02526 llvm::array_pod_sort(A.begin(), A.end(), DclCmp); 02527 for (A_t::iterator I = A.begin(), 02528 E = A.end(); I != E; ++I) { 02529 A_t::iterator J = I; 02530 while (++J != E && DclCmp(I, J) == 0) 02531 if (DclIsSame(*I, *J)) { 02532 if (0) printf("connecting %s\n", (*I)->getNameAsString().c_str()); 02533 ForwardUnique[*J] = *I; 02534 } 02535 } 02536 } 02537 02538 const CXXMethodDecl *getUnique(const CXXMethodDecl *MD) { 02539 const CXXMethodDecl *U = UniqueOverrider[MD]; 02540 assert(U && "unique overrider not found"); 02541 while (ForwardUnique.count(U)) { 02542 const CXXMethodDecl *NU = ForwardUnique[U]; 02543 if (NU == U) break; 02544 U = NU; 02545 } 02546 return U; 02547 } 02548 02549 GlobalDecl getUnique(GlobalDecl GD) { 02550 const CXXMethodDecl *Unique = getUnique(cast<CXXMethodDecl>(GD.getDecl())); 02551 02552 if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Unique)) 02553 return GlobalDecl(CD, GD.getCtorType()); 02554 02555 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(Unique)) 02556 return GlobalDecl(DD, GD.getDtorType()); 02557 02558 return Unique; 02559 } 02560 02561 /// getPureVirtualFn - Return the __cxa_pure_virtual function. 02562 llvm::Constant* getPureVirtualFn() { 02563 if (!PureVirtualFn) { 02564 const llvm::FunctionType *Ty = 02565 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 02566 /*isVarArg=*/false); 02567 PureVirtualFn = wrap(CGM.CreateRuntimeFunction(Ty, "__cxa_pure_virtual")); 02568 } 02569 02570 return PureVirtualFn; 02571 } 02572 02573 public: 02574 OldVtableBuilder(const CXXRecordDecl *MostDerivedClass, 02575 const CXXRecordDecl *l, uint64_t lo, CodeGenModule &cgm, 02576 bool build, CGVtableInfo::AddressPointsMapTy& AddressPoints) 02577 : BuildVtable(build), MostDerivedClass(MostDerivedClass), LayoutClass(l), 02578 LayoutOffset(lo), BLayout(cgm.getContext().getASTRecordLayout(l)), 02579 rtti(0), VMContext(cgm.getModule().getContext()),CGM(cgm), 02580 PureVirtualFn(0), 02581 subAddressPoints(AllocAddressPoint(cgm, l, MostDerivedClass)), 02582 AddressPoints(AddressPoints), 02583 LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)) 02584 { 02585 Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); 02586 if (BuildVtable) { 02587 QualType ClassType = CGM.getContext().getTagDeclType(MostDerivedClass); 02588 rtti = CGM.GetAddrOfRTTIDescriptor(ClassType); 02589 } 02590 BuildUniqueOverriders(MostDerivedClass); 02591 MergeForwarding(); 02592 } 02593 02594 // getVtableComponents - Returns a reference to the vtable components. 02595 const VtableComponentsVectorTy &getVtableComponents() const { 02596 return VtableComponents; 02597 } 02598 02599 llvm::DenseMap<const CXXRecordDecl *, uint64_t> &getVBIndex() 02600 { return VBIndex; } 02601 02602 SavedAdjustmentsVectorTy &getSavedAdjustments() 02603 { return SavedAdjustments; } 02604 02605 llvm::Constant *wrap(Index_t i) { 02606 llvm::Constant *m; 02607 m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), i); 02608 return llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty); 02609 } 02610 02611 llvm::Constant *wrap(llvm::Constant *m) { 02612 return llvm::ConstantExpr::getBitCast(m, Ptr8Ty); 02613 } 02614 02615 //#define D1(x) 02616 #define D1(X) do { if (getenv("CLANG_VTABLE_DEBUG")) { X; } } while (0) 02617 02618 void GenerateVBaseOffsets(const CXXRecordDecl *RD, uint64_t Offset, 02619 bool updateVBIndex, Index_t current_vbindex) { 02620 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 02621 e = RD->bases_end(); i != e; ++i) { 02622 const CXXRecordDecl *Base = 02623 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 02624 Index_t next_vbindex = current_vbindex; 02625 if (i->isVirtual() && !SeenVBase.count(Base)) { 02626 SeenVBase.insert(Base); 02627 if (updateVBIndex) { 02628 next_vbindex = (ssize_t)(-(VCalls.size()*LLVMPointerWidth/8) 02629 - 3*LLVMPointerWidth/8); 02630 VBIndex[Base] = next_vbindex; 02631 } 02632 int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8; 02633 VCalls.push_back((0?700:0) + BaseOffset); 02634 D1(printf(" vbase for %s at %d delta %d most derived %s\n", 02635 Base->getNameAsCString(), 02636 (int)-VCalls.size()-3, (int)BaseOffset, 02637 MostDerivedClass->getNameAsCString())); 02638 } 02639 // We also record offsets for non-virtual bases to closest enclosing 02640 // virtual base. We do this so that we don't have to search 02641 // for the nearst virtual base class when generating thunks. 02642 if (updateVBIndex && VBIndex.count(Base) == 0) 02643 VBIndex[Base] = next_vbindex; 02644 GenerateVBaseOffsets(Base, Offset, updateVBIndex, next_vbindex); 02645 } 02646 } 02647 02648 void StartNewTable() { 02649 SeenVBase.clear(); 02650 } 02651 02652 Index_t getNVOffset_1(const CXXRecordDecl *D, const CXXRecordDecl *B, 02653 Index_t Offset = 0) { 02654 02655 if (B == D) 02656 return Offset; 02657 02658 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(D); 02659 for (CXXRecordDecl::base_class_const_iterator i = D->bases_begin(), 02660 e = D->bases_end(); i != e; ++i) { 02661 const CXXRecordDecl *Base = 02662 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 02663 int64_t BaseOffset = 0; 02664 if (!i->isVirtual()) 02665 BaseOffset = Offset + Layout.getBaseClassOffset(Base); 02666 int64_t o = getNVOffset_1(Base, B, BaseOffset); 02667 if (o >= 0) 02668 return o; 02669 } 02670 02671 return -1; 02672 } 02673 02674 /// getNVOffset - Returns the non-virtual offset for the given (B) base of the 02675 /// derived class D. 02676 Index_t getNVOffset(QualType qB, QualType qD) { 02677 qD = qD->getPointeeType(); 02678 qB = qB->getPointeeType(); 02679 CXXRecordDecl *D = cast<CXXRecordDecl>(qD->getAs<RecordType>()->getDecl()); 02680 CXXRecordDecl *B = cast<CXXRecordDecl>(qB->getAs<RecordType>()->getDecl()); 02681 int64_t o = getNVOffset_1(D, B); 02682 if (o >= 0) 02683 return o; 02684 02685 assert(false && "FIXME: non-virtual base not found"); 02686 return 0; 02687 } 02688 02689 /// getVbaseOffset - Returns the index into the vtable for the virtual base 02690 /// offset for the given (B) virtual base of the derived class D. 02691 Index_t getVbaseOffset(QualType qB, QualType qD) { 02692 qD = qD->getPointeeType(); 02693 qB = qB->getPointeeType(); 02694 CXXRecordDecl *D = cast<CXXRecordDecl>(qD->getAs<RecordType>()->getDecl()); 02695 CXXRecordDecl *B = cast<CXXRecordDecl>(qB->getAs<RecordType>()->getDecl()); 02696 if (D != MostDerivedClass) 02697 return CGM.getVtableInfo().getVirtualBaseOffsetOffset(D, B); 02698 llvm::DenseMap<const CXXRecordDecl *, Index_t>::iterator i; 02699 i = VBIndex.find(B); 02700 if (i != VBIndex.end()) 02701 return i->second; 02702 02703 assert(false && "FIXME: Base not found"); 02704 return 0; 02705 } 02706 02707 bool OverrideMethod(GlobalDecl GD, bool MorallyVirtual, 02708 Index_t OverrideOffset, Index_t Offset, 02709 int64_t CurrentVBaseOffset); 02710 02711 /// AppendMethods - Append the current methods to the vtable. 02712 void AppendMethodsToVtable(); 02713 02714 llvm::Constant *WrapAddrOf(GlobalDecl GD) { 02715 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 02716 02717 const llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVtable(MD); 02718 02719 return wrap(CGM.GetAddrOfFunction(GD, Ty)); 02720 } 02721 02722 void OverrideMethods(Path_t *Path, bool MorallyVirtual, int64_t Offset, 02723 int64_t CurrentVBaseOffset) { 02724 for (Path_t::reverse_iterator i = Path->rbegin(), 02725 e = Path->rend(); i != e; ++i) { 02726 const CXXRecordDecl *RD = i->first; 02727 int64_t OverrideOffset = i->second; 02728 for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; 02729 ++mi) { 02730 const CXXMethodDecl *MD = *mi; 02731 02732 if (!MD->isVirtual()) 02733 continue; 02734 02735 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 02736 // Override both the complete and the deleting destructor. 02737 GlobalDecl CompDtor(DD, Dtor_Complete); 02738 OverrideMethod(CompDtor, MorallyVirtual, OverrideOffset, Offset, 02739 CurrentVBaseOffset); 02740 02741 GlobalDecl DeletingDtor(DD, Dtor_Deleting); 02742 OverrideMethod(DeletingDtor, MorallyVirtual, OverrideOffset, Offset, 02743 CurrentVBaseOffset); 02744 } else { 02745 OverrideMethod(MD, MorallyVirtual, OverrideOffset, Offset, 02746 CurrentVBaseOffset); 02747 } 02748 } 02749 } 02750 } 02751 02752 void AddMethod(const GlobalDecl GD, bool MorallyVirtual, Index_t Offset, 02753 int64_t CurrentVBaseOffset) { 02754 // If we can find a previously allocated slot for this, reuse it. 02755 if (OverrideMethod(GD, MorallyVirtual, Offset, Offset, 02756 CurrentVBaseOffset)) 02757 return; 02758 02759 D1(printf(" vfn for %s at %d\n", 02760 dyn_cast<CXXMethodDecl>(GD.getDecl())->getNameAsString().c_str(), 02761 (int)Methods.size())); 02762 02763 // We didn't find an entry in the vtable that we could use, add a new 02764 // entry. 02765 Methods.AddMethod(GD); 02766 02767 VCallOffset[GD] = Offset/8 - CurrentVBaseOffset/8; 02768 02769 if (MorallyVirtual) { 02770 GlobalDecl UGD = getUnique(GD); 02771 const CXXMethodDecl *UMD = cast<CXXMethodDecl>(UGD.getDecl()); 02772 02773 assert(UMD && "final overrider not found"); 02774 02775 Index_t &idx = VCall[UMD]; 02776 // Allocate the first one, after that, we reuse the previous one. 02777 if (idx == 0) { 02778 VCallOffsetForVCall[UGD] = Offset/8; 02779 NonVirtualOffset[UMD] = Offset/8 - CurrentVBaseOffset/8; 02780 idx = VCalls.size()+1; 02781 VCalls.push_back(Offset/8 - CurrentVBaseOffset/8); 02782 D1(printf(" vcall for %s at %d with delta %d\n", 02783 dyn_cast<CXXMethodDecl>(GD.getDecl())->getNameAsString().c_str(), 02784 (int)-VCalls.size()-3, (int)VCalls[idx-1])); 02785 } 02786 } 02787 } 02788 02789 void AddMethods(const CXXRecordDecl *RD, bool MorallyVirtual, 02790 Index_t Offset, int64_t CurrentVBaseOffset) { 02791 for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; 02792 ++mi) { 02793 const CXXMethodDecl *MD = *mi; 02794 if (!MD->isVirtual()) 02795 continue; 02796 02797 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 02798 // For destructors, add both the complete and the deleting destructor 02799 // to the vtable. 02800 AddMethod(GlobalDecl(DD, Dtor_Complete), MorallyVirtual, Offset, 02801 CurrentVBaseOffset); 02802 AddMethod(GlobalDecl(DD, Dtor_Deleting), MorallyVirtual, Offset, 02803 CurrentVBaseOffset); 02804 } else 02805 AddMethod(MD, MorallyVirtual, Offset, CurrentVBaseOffset); 02806 } 02807 } 02808 02809 void NonVirtualBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout, 02810 const CXXRecordDecl *PrimaryBase, 02811 bool PrimaryBaseWasVirtual, bool MorallyVirtual, 02812 int64_t Offset, int64_t CurrentVBaseOffset, 02813 Path_t *Path) { 02814 Path->push_back(std::make_pair(RD, Offset)); 02815 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 02816 e = RD->bases_end(); i != e; ++i) { 02817 if (i->isVirtual()) 02818 continue; 02819 const CXXRecordDecl *Base = 02820 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 02821 uint64_t o = Offset + Layout.getBaseClassOffset(Base); 02822 StartNewTable(); 02823 GenerateVtableForBase(Base, o, MorallyVirtual, false, 02824 true, Base == PrimaryBase && !PrimaryBaseWasVirtual, 02825 CurrentVBaseOffset, Path); 02826 } 02827 Path->pop_back(); 02828 } 02829 02830 // #define D(X) do { X; } while (0) 02831 #define D(X) 02832 02833 void insertVCalls(int InsertionPoint) { 02834 D1(printf("============= combining vbase/vcall\n")); 02835 D(VCalls.insert(VCalls.begin(), 673)); 02836 D(VCalls.push_back(672)); 02837 02838 VtableComponents.insert(VtableComponents.begin() + InsertionPoint, 02839 VCalls.size(), 0); 02840 if (BuildVtable) { 02841 // The vcalls come first... 02842 for (std::vector<Index_t>::reverse_iterator i = VCalls.rbegin(), 02843 e = VCalls.rend(); 02844 i != e; ++i) 02845 VtableComponents[InsertionPoint++] = wrap((0?600:0) + *i); 02846 } 02847 VCalls.clear(); 02848 VCall.clear(); 02849 VCallOffsetForVCall.clear(); 02850 VCallOffset.clear(); 02851 NonVirtualOffset.clear(); 02852 } 02853 02854 void AddAddressPoints(const CXXRecordDecl *RD, uint64_t Offset, 02855 Index_t AddressPoint) { 02856 D1(printf("XXX address point for %s in %s layout %s at offset %d is %d\n", 02857 RD->getNameAsCString(), MostDerivedClass->getNameAsCString(), 02858 LayoutClass->getNameAsCString(), (int)Offset, (int)AddressPoint)); 02859 subAddressPoints[std::make_pair(RD, Offset)] = AddressPoint; 02860 AddressPoints[BaseSubobject(RD, Offset)] = AddressPoint; 02861 02862 // Now also add the address point for all our primary bases. 02863 while (1) { 02864 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); 02865 RD = Layout.getPrimaryBase(); 02866 const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual(); 02867 // FIXME: Double check this. 02868 if (RD == 0) 02869 break; 02870 if (PrimaryBaseWasVirtual && 02871 BLayout.getVBaseClassOffset(RD) != Offset) 02872 break; 02873 D1(printf("XXX address point for %s in %s layout %s at offset %d is %d\n", 02874 RD->getNameAsCString(), MostDerivedClass->getNameAsCString(), 02875 LayoutClass->getNameAsCString(), (int)Offset, (int)AddressPoint)); 02876 subAddressPoints[std::make_pair(RD, Offset)] = AddressPoint; 02877 AddressPoints[BaseSubobject(RD, Offset)] = AddressPoint; 02878 } 02879 } 02880 02881 02882 void FinishGenerateVtable(const CXXRecordDecl *RD, 02883 const ASTRecordLayout &Layout, 02884 const CXXRecordDecl *PrimaryBase, 02885 bool ForNPNVBases, bool WasPrimaryBase, 02886 bool PrimaryBaseWasVirtual, 02887 bool MorallyVirtual, int64_t Offset, 02888 bool ForVirtualBase, int64_t CurrentVBaseOffset, 02889 Path_t *Path) { 02890 bool alloc = false; 02891 if (Path == 0) { 02892 alloc = true; 02893 Path = new Path_t; 02894 } 02895 02896 StartNewTable(); 02897 extra = 0; 02898 Index_t AddressPoint = 0; 02899 int VCallInsertionPoint = 0; 02900 if (!ForNPNVBases || !WasPrimaryBase) { 02901 bool DeferVCalls = MorallyVirtual || ForVirtualBase; 02902 VCallInsertionPoint = VtableComponents.size(); 02903 if (!DeferVCalls) { 02904 insertVCalls(VCallInsertionPoint); 02905 } else 02906 // FIXME: just for extra, or for all uses of VCalls.size post this? 02907 extra = -VCalls.size(); 02908 02909 // Add the offset to top. 02910 VtableComponents.push_back(BuildVtable ? wrap(-((Offset-LayoutOffset)/8)) : 0); 02911 02912 // Add the RTTI information. 02913 VtableComponents.push_back(rtti); 02914 02915 AddressPoint = VtableComponents.size(); 02916 02917 AppendMethodsToVtable(); 02918 } 02919 02920 // and then the non-virtual bases. 02921 NonVirtualBases(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual, 02922 MorallyVirtual, Offset, CurrentVBaseOffset, Path); 02923 02924 if (ForVirtualBase) { 02925 // FIXME: We're adding to VCalls in callers, we need to do the overrides 02926 // in the inner part, so that we know the complete set of vcalls during 02927 // the build and don't have to insert into methods. Saving out the 02928 // AddressPoint here, would need to be fixed, if we didn't do that. Also 02929 // retroactively adding vcalls for overrides later wind up in the wrong 02930 // place, the vcall slot has to be alloted during the walk of the base 02931 // when the function is first introduces. 02932 AddressPoint += VCalls.size(); 02933 insertVCalls(VCallInsertionPoint); 02934 } 02935 02936 if (!ForNPNVBases || !WasPrimaryBase) 02937 AddAddressPoints(RD, Offset, AddressPoint); 02938 02939 if (alloc) { 02940 delete Path; 02941 } 02942 } 02943 02944 void Primaries(const CXXRecordDecl *RD, bool MorallyVirtual, int64_t Offset, 02945 bool updateVBIndex, Index_t current_vbindex, 02946 int64_t CurrentVBaseOffset) { 02947 if (!RD->isDynamicClass()) 02948 return; 02949 02950 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); 02951 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 02952 const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual(); 02953 02954 // vtables are composed from the chain of primaries. 02955 if (PrimaryBase && !PrimaryBaseWasVirtual) { 02956 D1(printf(" doing primaries for %s most derived %s\n", 02957 RD->getNameAsCString(), MostDerivedClass->getNameAsCString())); 02958 Primaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual, Offset, 02959 updateVBIndex, current_vbindex, CurrentVBaseOffset); 02960 } 02961 02962 D1(printf(" doing vcall entries for %s most derived %s\n", 02963 RD->getNameAsCString(), MostDerivedClass->getNameAsCString())); 02964 02965 // And add the virtuals for the class to the primary vtable. 02966 AddMethods(RD, MorallyVirtual, Offset, CurrentVBaseOffset); 02967 } 02968 02969 void VBPrimaries(const CXXRecordDecl *RD, bool MorallyVirtual, int64_t Offset, 02970 bool updateVBIndex, Index_t current_vbindex, 02971 bool RDisVirtualBase, int64_t CurrentVBaseOffset, 02972 bool bottom) { 02973 if (!RD->isDynamicClass()) 02974 return; 02975 02976 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); 02977 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 02978 const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual(); 02979 02980 // vtables are composed from the chain of primaries. 02981 if (PrimaryBase) { 02982 int BaseCurrentVBaseOffset = CurrentVBaseOffset; 02983 if (PrimaryBaseWasVirtual) { 02984 IndirectPrimary.insert(PrimaryBase); 02985 BaseCurrentVBaseOffset = BLayout.getVBaseClassOffset(PrimaryBase); 02986 } 02987 02988 D1(printf(" doing primaries for %s most derived %s\n", 02989 RD->getNameAsCString(), MostDerivedClass->getNameAsCString())); 02990 02991 VBPrimaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual, Offset, 02992 updateVBIndex, current_vbindex, PrimaryBaseWasVirtual, 02993 BaseCurrentVBaseOffset, false); 02994 } 02995 02996 D1(printf(" doing vbase entries for %s most derived %s\n", 02997 RD->getNameAsCString(), MostDerivedClass->getNameAsCString())); 02998 GenerateVBaseOffsets(RD, Offset, updateVBIndex, current_vbindex); 02999 03000 if (RDisVirtualBase || bottom) { 03001 Primaries(RD, MorallyVirtual, Offset, updateVBIndex, current_vbindex, 03002 CurrentVBaseOffset); 03003 } 03004 } 03005 03006 void GenerateVtableForBase(const CXXRecordDecl *RD, int64_t Offset = 0, 03007 bool MorallyVirtual = false, 03008 bool ForVirtualBase = false, 03009 bool ForNPNVBases = false, 03010 bool WasPrimaryBase = true, 03011 int CurrentVBaseOffset = 0, 03012 Path_t *Path = 0) { 03013 if (!RD->isDynamicClass()) 03014 return; 03015 03016 // Construction vtable don't need parts that have no virtual bases and 03017 // aren't morally virtual. 03018 if ((LayoutClass != MostDerivedClass) && 03019 RD->getNumVBases() == 0 && !MorallyVirtual) 03020 return; 03021 03022 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); 03023 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 03024 const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual(); 03025 03026 extra = 0; 03027 D1(printf("building entries for base %s most derived %s\n", 03028 RD->getNameAsCString(), MostDerivedClass->getNameAsCString())); 03029 03030 if (ForVirtualBase) 03031 extra = VCalls.size(); 03032 03033 if (!ForNPNVBases || !WasPrimaryBase) { 03034 VBPrimaries(RD, MorallyVirtual, Offset, !ForVirtualBase, 0, 03035 ForVirtualBase, CurrentVBaseOffset, true); 03036 03037 if (Path) 03038 OverrideMethods(Path, MorallyVirtual, Offset, CurrentVBaseOffset); 03039 } 03040 03041 FinishGenerateVtable(RD, Layout, PrimaryBase, ForNPNVBases, WasPrimaryBase, 03042 PrimaryBaseWasVirtual, MorallyVirtual, Offset, 03043 ForVirtualBase, CurrentVBaseOffset, Path); 03044 } 03045 03046 void GenerateVtableForVBases(const CXXRecordDecl *RD, 03047 int64_t Offset = 0, 03048 Path_t *Path = 0) { 03049 bool alloc = false; 03050 if (Path == 0) { 03051 alloc = true; 03052 Path = new Path_t; 03053 } 03054 // FIXME: We also need to override using all paths to a virtual base, 03055 // right now, we just process the first path 03056 Path->push_back(std::make_pair(RD, Offset)); 03057 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 03058 e = RD->bases_end(); i != e; ++i) { 03059 const CXXRecordDecl *Base = 03060 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 03061 if (i->isVirtual() && !IndirectPrimary.count(Base)) { 03062 // Mark it so we don't output it twice. 03063 IndirectPrimary.insert(Base); 03064 StartNewTable(); 03065 VCall.clear(); 03066 int64_t BaseOffset = BLayout.getVBaseClassOffset(Base); 03067 int64_t CurrentVBaseOffset = BaseOffset; 03068 D1(printf("vtable %s virtual base %s\n", 03069 MostDerivedClass->getNameAsCString(), Base->getNameAsCString())); 03070 GenerateVtableForBase(Base, BaseOffset, true, true, false, 03071 true, CurrentVBaseOffset, Path); 03072 } 03073 int64_t BaseOffset; 03074 if (i->isVirtual()) 03075 BaseOffset = BLayout.getVBaseClassOffset(Base); 03076 else { 03077 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); 03078 BaseOffset = Offset + Layout.getBaseClassOffset(Base); 03079 } 03080 03081 if (Base->getNumVBases()) { 03082 GenerateVtableForVBases(Base, BaseOffset, Path); 03083 } 03084 } 03085 Path->pop_back(); 03086 if (alloc) 03087 delete Path; 03088 } 03089 }; 03090 } // end anonymous namespace 03091 03092 bool OldVtableBuilder::OverrideMethod(GlobalDecl GD, bool MorallyVirtual, 03093 Index_t OverrideOffset, Index_t Offset, 03094 int64_t CurrentVBaseOffset) { 03095 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 03096 03097 const bool isPure = MD->isPure(); 03098 03099 // FIXME: Should OverrideOffset's be Offset? 03100 03101 for (CXXMethodDecl::method_iterator mi = MD->begin_overridden_methods(), 03102 e = MD->end_overridden_methods(); mi != e; ++mi) { 03103 GlobalDecl OGD; 03104 GlobalDecl OGD2; 03105 03106 const CXXMethodDecl *OMD = *mi; 03107 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(OMD)) 03108 OGD = GlobalDecl(DD, GD.getDtorType()); 03109 else 03110 OGD = OMD; 03111 03112 // Check whether this is the method being overridden in this section of 03113 // the vtable. 03114 uint64_t Index; 03115 if (!Methods.getIndex(OGD, Index)) 03116 continue; 03117 03118 OGD2 = OGD; 03119 03120 // Get the original method, which we should be computing thunks, etc, 03121 // against. 03122 OGD = Methods.getOrigMethod(Index); 03123 OMD = cast<CXXMethodDecl>(OGD.getDecl()); 03124 03125 QualType ReturnType = 03126 MD->getType()->getAs<FunctionType>()->getResultType(); 03127 QualType OverriddenReturnType = 03128 OMD->getType()->getAs<FunctionType>()->getResultType(); 03129 03130 // Check if we need a return type adjustment. 03131 if (!ComputeReturnAdjustmentBaseOffset(CGM.getContext(), MD, 03132 OMD).isEmpty()) { 03133 CanQualType &BaseReturnType = BaseReturnTypes[Index]; 03134 03135 // Insert the base return type. 03136 if (BaseReturnType.isNull()) 03137 BaseReturnType = 03138 CGM.getContext().getCanonicalType(OverriddenReturnType); 03139 } 03140 03141 Methods.OverrideMethod(OGD, GD); 03142 03143 GlobalDecl UGD = getUnique(GD); 03144 const CXXMethodDecl *UMD = cast<CXXMethodDecl>(UGD.getDecl()); 03145 assert(UGD.getDecl() && "unique overrider not found"); 03146 assert(UGD == getUnique(OGD) && "unique overrider not unique"); 03147 03148 ThisAdjustments.erase(Index); 03149 if (MorallyVirtual || VCall.count(UMD)) { 03150 03151 Index_t &idx = VCall[UMD]; 03152 if (idx == 0) { 03153 VCallOffset[GD] = VCallOffset[OGD]; 03154 // NonVirtualOffset[UMD] = CurrentVBaseOffset/8 - OverrideOffset/8; 03155 NonVirtualOffset[UMD] = VCallOffset[OGD]; 03156 VCallOffsetForVCall[UMD] = OverrideOffset/8; 03157 idx = VCalls.size()+1; 03158 VCalls.push_back(OverrideOffset/8 - CurrentVBaseOffset/8); 03159 D1(printf(" vcall for %s at %d with delta %d most derived %s\n", 03160 MD->getNameAsString().c_str(), (int)-idx-3, 03161 (int)VCalls[idx-1], MostDerivedClass->getNameAsCString())); 03162 } else { 03163 VCallOffset[GD] = NonVirtualOffset[UMD]; 03164 VCalls[idx-1] = -VCallOffsetForVCall[UGD] + OverrideOffset/8; 03165 D1(printf(" vcall patch for %s at %d with delta %d most derived %s\n", 03166 MD->getNameAsString().c_str(), (int)-idx-3, 03167 (int)VCalls[idx-1], MostDerivedClass->getNameAsCString())); 03168 } 03169 int64_t NonVirtualAdjustment = -VCallOffset[OGD]; 03170 QualType DerivedType = MD->getThisType(CGM.getContext()); 03171 QualType BaseType = cast<const CXXMethodDecl>(OGD.getDecl())->getThisType(CGM.getContext()); 03172 int64_t NonVirtualAdjustment2 = -(getNVOffset(BaseType, DerivedType)/8); 03173 if (NonVirtualAdjustment2 != NonVirtualAdjustment) { 03174 NonVirtualAdjustment = NonVirtualAdjustment2; 03175 } 03176 int64_t VirtualAdjustment = 03177 -((idx + extra + 2) * LLVMPointerWidth / 8); 03178 03179 // Optimize out virtual adjustments of 0. 03180 if (VCalls[idx-1] == 0) 03181 VirtualAdjustment = 0; 03182 03183 ThunkAdjustment ThisAdjustment(NonVirtualAdjustment, 03184 VirtualAdjustment); 03185 03186 if (!isPure && !ThisAdjustment.isEmpty()) { 03187 ThisAdjustments[Index] = ThisAdjustment; 03188 SavedAdjustments.push_back( 03189 std::make_pair(GD, std::make_pair(OGD, ThisAdjustment))); 03190 } 03191 return true; 03192 } 03193 03194 VCallOffset[GD] = VCallOffset[OGD2] - OverrideOffset/8; 03195 03196 int64_t NonVirtualAdjustment = -VCallOffset[GD]; 03197 QualType DerivedType = MD->getThisType(CGM.getContext()); 03198 QualType BaseType = cast<const CXXMethodDecl>(OGD.getDecl())->getThisType(CGM.getContext()); 03199 int64_t NonVirtualAdjustment2 = -(getNVOffset(BaseType, DerivedType)/8); 03200 if (NonVirtualAdjustment2 != NonVirtualAdjustment) { 03201 NonVirtualAdjustment = NonVirtualAdjustment2; 03202 } 03203 03204 if (NonVirtualAdjustment) { 03205 ThunkAdjustment ThisAdjustment(NonVirtualAdjustment, 0); 03206 03207 if (!isPure) { 03208 ThisAdjustments[Index] = ThisAdjustment; 03209 SavedAdjustments.push_back( 03210 std::make_pair(GD, std::make_pair(OGD, ThisAdjustment))); 03211 } 03212 } 03213 return true; 03214 } 03215 03216 return false; 03217 } 03218 03219 void OldVtableBuilder::AppendMethodsToVtable() { 03220 if (!BuildVtable) { 03221 VtableComponents.insert(VtableComponents.end(), Methods.size(), 03222 (llvm::Constant *)0); 03223 ThisAdjustments.clear(); 03224 BaseReturnTypes.clear(); 03225 Methods.clear(); 03226 return; 03227 } 03228 03229 // Reserve room in the vtable for our new methods. 03230 VtableComponents.reserve(VtableComponents.size() + Methods.size()); 03231 03232 for (unsigned i = 0, e = Methods.size(); i != e; ++i) { 03233 GlobalDecl GD = Methods[i]; 03234 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 03235 03236 // Get the 'this' pointer adjustment. 03237 ThunkAdjustment ThisAdjustment = ThisAdjustments.lookup(i); 03238 03239 // Construct the return type adjustment. 03240 ThunkAdjustment ReturnAdjustment; 03241 03242 QualType BaseReturnType = BaseReturnTypes.lookup(i); 03243 if (!BaseReturnType.isNull() && !MD->isPure()) { 03244 QualType DerivedType = 03245 MD->getType()->getAs<FunctionType>()->getResultType(); 03246 03247 int64_t NonVirtualAdjustment = 03248 getNVOffset(BaseReturnType, DerivedType) / 8; 03249 03250 int64_t VirtualAdjustment = 03251 getVbaseOffset(BaseReturnType, DerivedType); 03252 03253 ReturnAdjustment = ThunkAdjustment(NonVirtualAdjustment, 03254 VirtualAdjustment); 03255 } 03256 03257 llvm::Constant *Method = 0; 03258 if (!ReturnAdjustment.isEmpty()) { 03259 // Build a covariant thunk. 03260 CovariantThunkAdjustment Adjustment(ThisAdjustment, ReturnAdjustment); 03261 Method = wrap(CGM.GetAddrOfCovariantThunk(GD, Adjustment)); 03262 } else if (!ThisAdjustment.isEmpty()) { 03263 // Build a "regular" thunk. 03264 Method = wrap(CGM.GetAddrOfThunk(GD, ThisAdjustment)); 03265 } else if (MD->isPure()) { 03266 // We have a pure virtual method. 03267 Method = getPureVirtualFn(); 03268 } else { 03269 // We have a good old regular method. 03270 Method = WrapAddrOf(GD); 03271 } 03272 03273 // Add the method to the vtable. 03274 VtableComponents.push_back(Method); 03275 } 03276 03277 03278 ThisAdjustments.clear(); 03279 BaseReturnTypes.clear(); 03280 03281 Methods.clear(); 03282 } 03283 03284 void CGVtableInfo::ComputeMethodVtableIndices(const CXXRecordDecl *RD) { 03285 03286 // Itanium C++ ABI 2.5.2: 03287 // The order of the virtual function pointers in a virtual table is the 03288 // order of declaration of the corresponding member functions in the class. 03289 // 03290 // There is an entry for any virtual function declared in a class, 03291 // whether it is a new function or overrides a base class function, 03292 // unless it overrides a function from the primary base, and conversion 03293 // between their return types does not require an adjustment. 03294 03295 int64_t CurrentIndex = 0; 03296 03297 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); 03298 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 03299 03300 if (PrimaryBase) { 03301 assert(PrimaryBase->isDefinition() && 03302 "Should have the definition decl of the primary base!"); 03303 03304 // Since the record decl shares its vtable pointer with the primary base 03305 // we need to start counting at the end of the primary base's vtable. 03306 CurrentIndex = getNumVirtualFunctionPointers(PrimaryBase); 03307 } 03308 03309 // Collect all the primary bases, so we can check whether methods override 03310 // a method from the base. 03311 VtableBuilder::PrimaryBasesSetVectorTy PrimaryBases; 03312 for (ASTRecordLayout::primary_base_info_iterator 03313 I = Layout.primary_base_begin(), E = Layout.primary_base_end(); 03314 I != E; ++I) 03315 PrimaryBases.insert((*I).getBase()); 03316 03317 const CXXDestructorDecl *ImplicitVirtualDtor = 0; 03318 03319 for (CXXRecordDecl::method_iterator i = RD->method_begin(), 03320 e = RD->method_end(); i != e; ++i) { 03321 const CXXMethodDecl *MD = *i; 03322 03323 // We only want virtual methods. 03324 if (!MD->isVirtual()) 03325 continue; 03326 03327 // Check if this method overrides a method in the primary base. 03328 if (const CXXMethodDecl *OverriddenMD = 03329 OverridesMethodInBases(MD, PrimaryBases)) { 03330 // Check if converting from the return type of the method to the 03331 // return type of the overridden method requires conversion. 03332 if (ComputeReturnAdjustmentBaseOffset(CGM.getContext(), MD, 03333 OverriddenMD).isEmpty()) { 03334 // This index is shared between the index in the vtable of the primary 03335 // base class. 03336 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 03337 const CXXDestructorDecl *OverriddenDD = 03338 cast<CXXDestructorDecl>(OverriddenMD); 03339 03340 // Add both the complete and deleting entries. 03341 MethodVtableIndices[GlobalDecl(DD, Dtor_Complete)] = 03342 getMethodVtableIndex(GlobalDecl(OverriddenDD, Dtor_Complete)); 03343 MethodVtableIndices[GlobalDecl(DD, Dtor_Deleting)] = 03344 getMethodVtableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting)); 03345 } else { 03346 MethodVtableIndices[MD] = getMethodVtableIndex(OverriddenMD); 03347 } 03348 03349 // We don't need to add an entry for this method. 03350 continue; 03351 } 03352 } 03353 03354 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 03355 if (MD->isImplicit()) { 03356 assert(!ImplicitVirtualDtor && 03357 "Did already see an implicit virtual dtor!"); 03358 ImplicitVirtualDtor = DD; 03359 continue; 03360 } 03361 03362 // Add the complete dtor. 03363 MethodVtableIndices[GlobalDecl(DD, Dtor_Complete)] = CurrentIndex++; 03364 03365 // Add the deleting dtor. 03366 MethodVtableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++; 03367 } else { 03368 // Add the entry. 03369 MethodVtableIndices[MD] = CurrentIndex++; 03370 } 03371 } 03372 03373 if (ImplicitVirtualDtor) { 03374 // Itanium C++ ABI 2.5.2: 03375 // If a class has an implicitly-defined virtual destructor, 03376 // its entries come after the declared virtual function pointers. 03377 03378 // Add the complete dtor. 03379 MethodVtableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Complete)] = 03380 CurrentIndex++; 03381 03382 // Add the deleting dtor. 03383 MethodVtableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Deleting)] = 03384 CurrentIndex++; 03385 } 03386 03387 NumVirtualFunctionPointers[RD] = CurrentIndex; 03388 } 03389 03390 uint64_t CGVtableInfo::getNumVirtualFunctionPointers(const CXXRecordDecl *RD) { 03391 llvm::DenseMap<const CXXRecordDecl *, uint64_t>::iterator I = 03392 NumVirtualFunctionPointers.find(RD); 03393 if (I != NumVirtualFunctionPointers.end()) 03394 return I->second; 03395 03396 ComputeMethodVtableIndices(RD); 03397 03398 I = NumVirtualFunctionPointers.find(RD); 03399 assert(I != NumVirtualFunctionPointers.end() && "Did not find entry!"); 03400 return I->second; 03401 } 03402 03403 uint64_t CGVtableInfo::getMethodVtableIndex(GlobalDecl GD) { 03404 MethodVtableIndicesTy::iterator I = MethodVtableIndices.find(GD); 03405 if (I != MethodVtableIndices.end()) 03406 return I->second; 03407 03408 const CXXRecordDecl *RD = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 03409 03410 ComputeMethodVtableIndices(RD); 03411 03412 I = MethodVtableIndices.find(GD); 03413 assert(I != MethodVtableIndices.end() && "Did not find index!"); 03414 return I->second; 03415 } 03416 03417 CGVtableInfo::AdjustmentVectorTy* 03418 CGVtableInfo::getAdjustments(GlobalDecl GD) { 03419 SavedAdjustmentsTy::iterator I = SavedAdjustments.find(GD); 03420 if (I != SavedAdjustments.end()) 03421 return &I->second; 03422 03423 const CXXRecordDecl *RD = cast<CXXRecordDecl>(GD.getDecl()->getDeclContext()); 03424 if (!SavedAdjustmentRecords.insert(RD).second) 03425 return 0; 03426 03427 AddressPointsMapTy AddressPoints; 03428 OldVtableBuilder b(RD, RD, 0, CGM, false, AddressPoints); 03429 D1(printf("vtable %s\n", RD->getNameAsCString())); 03430 b.GenerateVtableForBase(RD); 03431 b.GenerateVtableForVBases(RD); 03432 03433 for (OldVtableBuilder::SavedAdjustmentsVectorTy::iterator 03434 i = b.getSavedAdjustments().begin(), 03435 e = b.getSavedAdjustments().end(); i != e; i++) 03436 SavedAdjustments[i->first].push_back(i->second); 03437 03438 I = SavedAdjustments.find(GD); 03439 if (I != SavedAdjustments.end()) 03440 return &I->second; 03441 03442 return 0; 03443 } 03444 03445 int64_t CGVtableInfo::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, 03446 const CXXRecordDecl *VBase) { 03447 ClassPairTy ClassPair(RD, VBase); 03448 03449 VirtualBaseClassOffsetOffsetsMapTy::iterator I = 03450 VirtualBaseClassOffsetOffsets.find(ClassPair); 03451 if (I != VirtualBaseClassOffsetOffsets.end()) 03452 return I->second; 03453 03454 VCallAndVBaseOffsetBuilder Builder(RD, RD, /*FinalOverriders=*/0, 03455 BaseSubobject(RD, 0), 03456 /*BaseIsVirtual=*/false, 03457 /*OffsetInLayoutClass=*/0); 03458 03459 03460 for (VCallAndVBaseOffsetBuilder::VBaseOffsetOffsetsMapTy::const_iterator I = 03461 Builder.getVBaseOffsetOffsets().begin(), 03462 E = Builder.getVBaseOffsetOffsets().end(); I != E; ++I) { 03463 // Insert all types. 03464 ClassPairTy ClassPair(RD, I->first); 03465 03466 VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I->second)); 03467 } 03468 03469 I = VirtualBaseClassOffsetOffsets.find(ClassPair); 03470 03471 // FIXME: The assertion below assertion currently fails with the old vtable 03472 /// layout code if there is a non-virtual thunk adjustment in a vtable. 03473 // Once the new layout is in place, this return should be removed. 03474 if (I == VirtualBaseClassOffsetOffsets.end()) 03475 return 0; 03476 03477 assert(I != VirtualBaseClassOffsetOffsets.end() && "Did not find index!"); 03478 03479 return I->second; 03480 } 03481 03482 uint64_t CGVtableInfo::getVtableAddressPoint(const CXXRecordDecl *RD) { 03483 uint64_t AddressPoint = 03484 (*(*(CGM.getVtableInfo().AddressPoints[RD]))[RD])[std::make_pair(RD, 0)]; 03485 03486 return AddressPoint; 03487 } 03488 03489 llvm::GlobalVariable * 03490 CGVtableInfo::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, 03491 bool GenerateDefinition, 03492 const CXXRecordDecl *LayoutClass, 03493 const CXXRecordDecl *RD, uint64_t Offset, 03494 bool IsVirtual, 03495 AddressPointsMapTy& AddressPoints) { 03496 if (GenerateDefinition) { 03497 if (LayoutClass == RD) { 03498 assert(!IsVirtual && 03499 "Can only have a virtual base in construction vtables!"); 03500 assert(!Offset && 03501 "Can only have a base offset in construction vtables!"); 03502 } 03503 03504 VtableBuilder Builder(*this, RD, Offset, 03505 /*MostDerivedClassIsVirtual=*/IsVirtual, 03506 LayoutClass); 03507 03508 if (CGM.getLangOptions().DumpVtableLayouts) 03509 Builder.dumpLayout(llvm::errs()); 03510 } 03511 03512 llvm::SmallString<256> OutName; 03513 if (LayoutClass != RD) 03514 CGM.getMangleContext().mangleCXXCtorVtable(LayoutClass, Offset / 8, 03515 RD, OutName); 03516 else 03517 CGM.getMangleContext().mangleCXXVtable(RD, OutName); 03518 llvm::StringRef Name = OutName.str(); 03519 03520 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 03521 if (GV == 0 || CGM.getVtableInfo().AddressPoints[LayoutClass] == 0 || 03522 GV->isDeclaration()) { 03523 OldVtableBuilder b(RD, LayoutClass, Offset, CGM, GenerateDefinition, 03524 AddressPoints); 03525 03526 D1(printf("vtable %s\n", RD->getNameAsCString())); 03527 // First comes the vtables for all the non-virtual bases... 03528 b.GenerateVtableForBase(RD, Offset); 03529 03530 // then the vtables for all the virtual bases. 03531 b.GenerateVtableForVBases(RD, Offset); 03532 03533 llvm::Constant *Init = 0; 03534 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 03535 llvm::ArrayType *ArrayType = 03536 llvm::ArrayType::get(Int8PtrTy, b.getVtableComponents().size()); 03537 03538 if (GenerateDefinition) 03539 Init = llvm::ConstantArray::get(ArrayType, &b.getVtableComponents()[0], 03540 b.getVtableComponents().size()); 03541 03542 llvm::GlobalVariable *OGV = GV; 03543 03544 GV = new llvm::GlobalVariable(CGM.getModule(), ArrayType, 03545 /*isConstant=*/true, Linkage, Init, Name); 03546 CGM.setGlobalVisibility(GV, RD); 03547 03548 if (OGV) { 03549 GV->takeName(OGV); 03550 llvm::Constant *NewPtr = 03551 llvm::ConstantExpr::getBitCast(GV, OGV->getType()); 03552 OGV->replaceAllUsesWith(NewPtr); 03553 OGV->eraseFromParent(); 03554 } 03555 } 03556 03557 return GV; 03558 } 03559 03560 void CGVtableInfo::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, 03561 const CXXRecordDecl *RD) { 03562 llvm::GlobalVariable *&Vtable = Vtables[RD]; 03563 if (Vtable) { 03564 assert(Vtable->getInitializer() && "Vtable doesn't have a definition!"); 03565 return; 03566 } 03567 03568 AddressPointsMapTy AddressPoints; 03569 Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0, 03570 /*IsVirtual=*/false, 03571 AddressPoints); 03572 GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD); 03573 03574 for (CXXRecordDecl::method_iterator i = RD->method_begin(), 03575 e = RD->method_end(); i != e; ++i) { 03576 if (!(*i)->isVirtual()) 03577 continue; 03578 if(!(*i)->hasInlineBody() && !(*i)->isImplicit()) 03579 continue; 03580 03581 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(*i)) { 03582 CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Complete)); 03583 CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Deleting)); 03584 } else { 03585 CGM.BuildThunksForVirtual(GlobalDecl(*i)); 03586 } 03587 } 03588 } 03589 03590 llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) { 03591 llvm::GlobalVariable *Vtable = Vtables.lookup(RD); 03592 03593 if (!Vtable) { 03594 AddressPointsMapTy AddressPoints; 03595 Vtable = GenerateVtable(llvm::GlobalValue::ExternalLinkage, 03596 /*GenerateDefinition=*/false, RD, RD, 0, 03597 /*IsVirtual=*/false, AddressPoints); 03598 } 03599 03600 return Vtable; 03601 } 03602 03603 void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) { 03604 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 03605 const CXXRecordDecl *RD = MD->getParent(); 03606 03607 // If the class doesn't have a vtable we don't need to emit one. 03608 if (!RD->isDynamicClass()) 03609 return; 03610 03611 // Get the key function. 03612 const CXXMethodDecl *KeyFunction = CGM.getContext().getKeyFunction(RD); 03613 03614 if (KeyFunction) { 03615 // We don't have the right key function. 03616 if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl()) 03617 return; 03618 } 03619 03620 if (Vtables.count(RD)) 03621 return; 03622 03623 TemplateSpecializationKind kind = RD->getTemplateSpecializationKind(); 03624 if (kind == TSK_ImplicitInstantiation) 03625 CGM.DeferredVtables.push_back(RD); 03626 else 03627 GenerateClassData(CGM.getVtableLinkage(RD), RD); 03628 }