VTableBuilder.cpp revision 263508
1//===--- VTableBuilder.cpp - C++ vtable layout builder --------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This contains code dealing with generation of the layout of virtual tables. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/AST/VTableBuilder.h" 15#include "clang/AST/ASTContext.h" 16#include "clang/AST/CXXInheritance.h" 17#include "clang/AST/RecordLayout.h" 18#include "clang/Basic/TargetInfo.h" 19#include "llvm/Support/Format.h" 20#include "llvm/Support/raw_ostream.h" 21#include <algorithm> 22#include <cstdio> 23 24using namespace clang; 25 26#define DUMP_OVERRIDERS 0 27 28namespace { 29 30/// BaseOffset - Represents an offset from a derived class to a direct or 31/// indirect base class. 32struct BaseOffset { 33 /// DerivedClass - The derived class. 34 const CXXRecordDecl *DerivedClass; 35 36 /// VirtualBase - If the path from the derived class to the base class 37 /// involves virtual base classes, this holds the declaration of the last 38 /// virtual base in this path (i.e. closest to the base class). 39 const CXXRecordDecl *VirtualBase; 40 41 /// NonVirtualOffset - The offset from the derived class to the base class. 42 /// (Or the offset from the virtual base class to the base class, if the 43 /// path from the derived class to the base class involves a virtual base 44 /// class. 45 CharUnits NonVirtualOffset; 46 47 BaseOffset() : DerivedClass(0), VirtualBase(0), 48 NonVirtualOffset(CharUnits::Zero()) { } 49 BaseOffset(const CXXRecordDecl *DerivedClass, 50 const CXXRecordDecl *VirtualBase, CharUnits NonVirtualOffset) 51 : DerivedClass(DerivedClass), VirtualBase(VirtualBase), 52 NonVirtualOffset(NonVirtualOffset) { } 53 54 bool isEmpty() const { return NonVirtualOffset.isZero() && !VirtualBase; } 55}; 56 57/// FinalOverriders - Contains the final overrider member functions for all 58/// member functions in the base subobjects of a class. 59class FinalOverriders { 60public: 61 /// OverriderInfo - Information about a final overrider. 62 struct OverriderInfo { 63 /// Method - The method decl of the overrider. 64 const CXXMethodDecl *Method; 65 66 /// Offset - the base offset of the overrider's parent in the layout class. 67 CharUnits Offset; 68 69 OverriderInfo() : Method(0), Offset(CharUnits::Zero()) { } 70 }; 71 72private: 73 /// MostDerivedClass - The most derived class for which the final overriders 74 /// are stored. 75 const CXXRecordDecl *MostDerivedClass; 76 77 /// MostDerivedClassOffset - If we're building final overriders for a 78 /// construction vtable, this holds the offset from the layout class to the 79 /// most derived class. 80 const CharUnits MostDerivedClassOffset; 81 82 /// LayoutClass - The class we're using for layout information. Will be 83 /// different than the most derived class if the final overriders are for a 84 /// construction vtable. 85 const CXXRecordDecl *LayoutClass; 86 87 ASTContext &Context; 88 89 /// MostDerivedClassLayout - the AST record layout of the most derived class. 90 const ASTRecordLayout &MostDerivedClassLayout; 91 92 /// MethodBaseOffsetPairTy - Uniquely identifies a member function 93 /// in a base subobject. 94 typedef std::pair<const CXXMethodDecl *, CharUnits> MethodBaseOffsetPairTy; 95 96 typedef llvm::DenseMap<MethodBaseOffsetPairTy, 97 OverriderInfo> OverridersMapTy; 98 99 /// OverridersMap - The final overriders for all virtual member functions of 100 /// all the base subobjects of the most derived class. 101 OverridersMapTy OverridersMap; 102 103 /// SubobjectsToOffsetsMapTy - A mapping from a base subobject (represented 104 /// as a record decl and a subobject number) and its offsets in the most 105 /// derived class as well as the layout class. 106 typedef llvm::DenseMap<std::pair<const CXXRecordDecl *, unsigned>, 107 CharUnits> SubobjectOffsetMapTy; 108 109 typedef llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCountMapTy; 110 111 /// ComputeBaseOffsets - Compute the offsets for all base subobjects of the 112 /// given base. 113 void ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual, 114 CharUnits OffsetInLayoutClass, 115 SubobjectOffsetMapTy &SubobjectOffsets, 116 SubobjectOffsetMapTy &SubobjectLayoutClassOffsets, 117 SubobjectCountMapTy &SubobjectCounts); 118 119 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; 120 121 /// dump - dump the final overriders for a base subobject, and all its direct 122 /// and indirect base subobjects. 123 void dump(raw_ostream &Out, BaseSubobject Base, 124 VisitedVirtualBasesSetTy& VisitedVirtualBases); 125 126public: 127 FinalOverriders(const CXXRecordDecl *MostDerivedClass, 128 CharUnits MostDerivedClassOffset, 129 const CXXRecordDecl *LayoutClass); 130 131 /// getOverrider - Get the final overrider for the given method declaration in 132 /// the subobject with the given base offset. 133 OverriderInfo getOverrider(const CXXMethodDecl *MD, 134 CharUnits BaseOffset) const { 135 assert(OverridersMap.count(std::make_pair(MD, BaseOffset)) && 136 "Did not find overrider!"); 137 138 return OverridersMap.lookup(std::make_pair(MD, BaseOffset)); 139 } 140 141 /// dump - dump the final overriders. 142 void dump() { 143 VisitedVirtualBasesSetTy VisitedVirtualBases; 144 dump(llvm::errs(), BaseSubobject(MostDerivedClass, CharUnits::Zero()), 145 VisitedVirtualBases); 146 } 147 148}; 149 150FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass, 151 CharUnits MostDerivedClassOffset, 152 const CXXRecordDecl *LayoutClass) 153 : MostDerivedClass(MostDerivedClass), 154 MostDerivedClassOffset(MostDerivedClassOffset), LayoutClass(LayoutClass), 155 Context(MostDerivedClass->getASTContext()), 156 MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)) { 157 158 // Compute base offsets. 159 SubobjectOffsetMapTy SubobjectOffsets; 160 SubobjectOffsetMapTy SubobjectLayoutClassOffsets; 161 SubobjectCountMapTy SubobjectCounts; 162 ComputeBaseOffsets(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 163 /*IsVirtual=*/false, 164 MostDerivedClassOffset, 165 SubobjectOffsets, SubobjectLayoutClassOffsets, 166 SubobjectCounts); 167 168 // Get the final overriders. 169 CXXFinalOverriderMap FinalOverriders; 170 MostDerivedClass->getFinalOverriders(FinalOverriders); 171 172 for (CXXFinalOverriderMap::const_iterator I = FinalOverriders.begin(), 173 E = FinalOverriders.end(); I != E; ++I) { 174 const CXXMethodDecl *MD = I->first; 175 const OverridingMethods& Methods = I->second; 176 177 for (OverridingMethods::const_iterator I = Methods.begin(), 178 E = Methods.end(); I != E; ++I) { 179 unsigned SubobjectNumber = I->first; 180 assert(SubobjectOffsets.count(std::make_pair(MD->getParent(), 181 SubobjectNumber)) && 182 "Did not find subobject offset!"); 183 184 CharUnits BaseOffset = SubobjectOffsets[std::make_pair(MD->getParent(), 185 SubobjectNumber)]; 186 187 assert(I->second.size() == 1 && "Final overrider is not unique!"); 188 const UniqueVirtualMethod &Method = I->second.front(); 189 190 const CXXRecordDecl *OverriderRD = Method.Method->getParent(); 191 assert(SubobjectLayoutClassOffsets.count( 192 std::make_pair(OverriderRD, Method.Subobject)) 193 && "Did not find subobject offset!"); 194 CharUnits OverriderOffset = 195 SubobjectLayoutClassOffsets[std::make_pair(OverriderRD, 196 Method.Subobject)]; 197 198 OverriderInfo& Overrider = OverridersMap[std::make_pair(MD, BaseOffset)]; 199 assert(!Overrider.Method && "Overrider should not exist yet!"); 200 201 Overrider.Offset = OverriderOffset; 202 Overrider.Method = Method.Method; 203 } 204 } 205 206#if DUMP_OVERRIDERS 207 // And dump them (for now). 208 dump(); 209#endif 210} 211 212static BaseOffset ComputeBaseOffset(ASTContext &Context, 213 const CXXRecordDecl *DerivedRD, 214 const CXXBasePath &Path) { 215 CharUnits NonVirtualOffset = CharUnits::Zero(); 216 217 unsigned NonVirtualStart = 0; 218 const CXXRecordDecl *VirtualBase = 0; 219 220 // First, look for the virtual base class. 221 for (int I = Path.size(), E = 0; I != E; --I) { 222 const CXXBasePathElement &Element = Path[I - 1]; 223 224 if (Element.Base->isVirtual()) { 225 NonVirtualStart = I; 226 QualType VBaseType = Element.Base->getType(); 227 VirtualBase = VBaseType->getAsCXXRecordDecl(); 228 break; 229 } 230 } 231 232 // Now compute the non-virtual offset. 233 for (unsigned I = NonVirtualStart, E = Path.size(); I != E; ++I) { 234 const CXXBasePathElement &Element = Path[I]; 235 236 // Check the base class offset. 237 const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class); 238 239 const CXXRecordDecl *Base = Element.Base->getType()->getAsCXXRecordDecl(); 240 241 NonVirtualOffset += Layout.getBaseClassOffset(Base); 242 } 243 244 // FIXME: This should probably use CharUnits or something. Maybe we should 245 // even change the base offsets in ASTRecordLayout to be specified in 246 // CharUnits. 247 return BaseOffset(DerivedRD, VirtualBase, NonVirtualOffset); 248 249} 250 251static BaseOffset ComputeBaseOffset(ASTContext &Context, 252 const CXXRecordDecl *BaseRD, 253 const CXXRecordDecl *DerivedRD) { 254 CXXBasePaths Paths(/*FindAmbiguities=*/false, 255 /*RecordPaths=*/true, /*DetectVirtual=*/false); 256 257 if (!DerivedRD->isDerivedFrom(BaseRD, Paths)) 258 llvm_unreachable("Class must be derived from the passed in base class!"); 259 260 return ComputeBaseOffset(Context, DerivedRD, Paths.front()); 261} 262 263static BaseOffset 264ComputeReturnAdjustmentBaseOffset(ASTContext &Context, 265 const CXXMethodDecl *DerivedMD, 266 const CXXMethodDecl *BaseMD) { 267 const FunctionType *BaseFT = BaseMD->getType()->getAs<FunctionType>(); 268 const FunctionType *DerivedFT = DerivedMD->getType()->getAs<FunctionType>(); 269 270 // Canonicalize the return types. 271 CanQualType CanDerivedReturnType = 272 Context.getCanonicalType(DerivedFT->getResultType()); 273 CanQualType CanBaseReturnType = 274 Context.getCanonicalType(BaseFT->getResultType()); 275 276 assert(CanDerivedReturnType->getTypeClass() == 277 CanBaseReturnType->getTypeClass() && 278 "Types must have same type class!"); 279 280 if (CanDerivedReturnType == CanBaseReturnType) { 281 // No adjustment needed. 282 return BaseOffset(); 283 } 284 285 if (isa<ReferenceType>(CanDerivedReturnType)) { 286 CanDerivedReturnType = 287 CanDerivedReturnType->getAs<ReferenceType>()->getPointeeType(); 288 CanBaseReturnType = 289 CanBaseReturnType->getAs<ReferenceType>()->getPointeeType(); 290 } else if (isa<PointerType>(CanDerivedReturnType)) { 291 CanDerivedReturnType = 292 CanDerivedReturnType->getAs<PointerType>()->getPointeeType(); 293 CanBaseReturnType = 294 CanBaseReturnType->getAs<PointerType>()->getPointeeType(); 295 } else { 296 llvm_unreachable("Unexpected return type!"); 297 } 298 299 // We need to compare unqualified types here; consider 300 // const T *Base::foo(); 301 // T *Derived::foo(); 302 if (CanDerivedReturnType.getUnqualifiedType() == 303 CanBaseReturnType.getUnqualifiedType()) { 304 // No adjustment needed. 305 return BaseOffset(); 306 } 307 308 const CXXRecordDecl *DerivedRD = 309 cast<CXXRecordDecl>(cast<RecordType>(CanDerivedReturnType)->getDecl()); 310 311 const CXXRecordDecl *BaseRD = 312 cast<CXXRecordDecl>(cast<RecordType>(CanBaseReturnType)->getDecl()); 313 314 return ComputeBaseOffset(Context, BaseRD, DerivedRD); 315} 316 317void 318FinalOverriders::ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual, 319 CharUnits OffsetInLayoutClass, 320 SubobjectOffsetMapTy &SubobjectOffsets, 321 SubobjectOffsetMapTy &SubobjectLayoutClassOffsets, 322 SubobjectCountMapTy &SubobjectCounts) { 323 const CXXRecordDecl *RD = Base.getBase(); 324 325 unsigned SubobjectNumber = 0; 326 if (!IsVirtual) 327 SubobjectNumber = ++SubobjectCounts[RD]; 328 329 // Set up the subobject to offset mapping. 330 assert(!SubobjectOffsets.count(std::make_pair(RD, SubobjectNumber)) 331 && "Subobject offset already exists!"); 332 assert(!SubobjectLayoutClassOffsets.count(std::make_pair(RD, SubobjectNumber)) 333 && "Subobject offset already exists!"); 334 335 SubobjectOffsets[std::make_pair(RD, SubobjectNumber)] = Base.getBaseOffset(); 336 SubobjectLayoutClassOffsets[std::make_pair(RD, SubobjectNumber)] = 337 OffsetInLayoutClass; 338 339 // Traverse our bases. 340 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 341 E = RD->bases_end(); I != E; ++I) { 342 const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl(); 343 344 CharUnits BaseOffset; 345 CharUnits BaseOffsetInLayoutClass; 346 if (I->isVirtual()) { 347 // Check if we've visited this virtual base before. 348 if (SubobjectOffsets.count(std::make_pair(BaseDecl, 0))) 349 continue; 350 351 const ASTRecordLayout &LayoutClassLayout = 352 Context.getASTRecordLayout(LayoutClass); 353 354 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 355 BaseOffsetInLayoutClass = 356 LayoutClassLayout.getVBaseClassOffset(BaseDecl); 357 } else { 358 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 359 CharUnits Offset = Layout.getBaseClassOffset(BaseDecl); 360 361 BaseOffset = Base.getBaseOffset() + Offset; 362 BaseOffsetInLayoutClass = OffsetInLayoutClass + Offset; 363 } 364 365 ComputeBaseOffsets(BaseSubobject(BaseDecl, BaseOffset), 366 I->isVirtual(), BaseOffsetInLayoutClass, 367 SubobjectOffsets, SubobjectLayoutClassOffsets, 368 SubobjectCounts); 369 } 370} 371 372void FinalOverriders::dump(raw_ostream &Out, BaseSubobject Base, 373 VisitedVirtualBasesSetTy &VisitedVirtualBases) { 374 const CXXRecordDecl *RD = Base.getBase(); 375 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 376 377 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 378 E = RD->bases_end(); I != E; ++I) { 379 const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl(); 380 381 // Ignore bases that don't have any virtual member functions. 382 if (!BaseDecl->isPolymorphic()) 383 continue; 384 385 CharUnits BaseOffset; 386 if (I->isVirtual()) { 387 if (!VisitedVirtualBases.insert(BaseDecl)) { 388 // We've visited this base before. 389 continue; 390 } 391 392 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 393 } else { 394 BaseOffset = Layout.getBaseClassOffset(BaseDecl) + Base.getBaseOffset(); 395 } 396 397 dump(Out, BaseSubobject(BaseDecl, BaseOffset), VisitedVirtualBases); 398 } 399 400 Out << "Final overriders for (" << RD->getQualifiedNameAsString() << ", "; 401 Out << Base.getBaseOffset().getQuantity() << ")\n"; 402 403 // Now dump the overriders for this base subobject. 404 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 405 E = RD->method_end(); I != E; ++I) { 406 const CXXMethodDecl *MD = *I; 407 408 if (!MD->isVirtual()) 409 continue; 410 411 OverriderInfo Overrider = getOverrider(MD, Base.getBaseOffset()); 412 413 Out << " " << MD->getQualifiedNameAsString() << " - ("; 414 Out << Overrider.Method->getQualifiedNameAsString(); 415 Out << ", " << Overrider.Offset.getQuantity() << ')'; 416 417 BaseOffset Offset; 418 if (!Overrider.Method->isPure()) 419 Offset = ComputeReturnAdjustmentBaseOffset(Context, Overrider.Method, MD); 420 421 if (!Offset.isEmpty()) { 422 Out << " [ret-adj: "; 423 if (Offset.VirtualBase) 424 Out << Offset.VirtualBase->getQualifiedNameAsString() << " vbase, "; 425 426 Out << Offset.NonVirtualOffset.getQuantity() << " nv]"; 427 } 428 429 Out << "\n"; 430 } 431} 432 433/// VCallOffsetMap - Keeps track of vcall offsets when building a vtable. 434struct VCallOffsetMap { 435 436 typedef std::pair<const CXXMethodDecl *, CharUnits> MethodAndOffsetPairTy; 437 438 /// Offsets - Keeps track of methods and their offsets. 439 // FIXME: This should be a real map and not a vector. 440 SmallVector<MethodAndOffsetPairTy, 16> Offsets; 441 442 /// MethodsCanShareVCallOffset - Returns whether two virtual member functions 443 /// can share the same vcall offset. 444 static bool MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, 445 const CXXMethodDecl *RHS); 446 447public: 448 /// AddVCallOffset - Adds a vcall offset to the map. Returns true if the 449 /// add was successful, or false if there was already a member function with 450 /// the same signature in the map. 451 bool AddVCallOffset(const CXXMethodDecl *MD, CharUnits OffsetOffset); 452 453 /// getVCallOffsetOffset - Returns the vcall offset offset (relative to the 454 /// vtable address point) for the given virtual member function. 455 CharUnits getVCallOffsetOffset(const CXXMethodDecl *MD); 456 457 // empty - Return whether the offset map is empty or not. 458 bool empty() const { return Offsets.empty(); } 459}; 460 461static bool HasSameVirtualSignature(const CXXMethodDecl *LHS, 462 const CXXMethodDecl *RHS) { 463 const FunctionProtoType *LT = 464 cast<FunctionProtoType>(LHS->getType().getCanonicalType()); 465 const FunctionProtoType *RT = 466 cast<FunctionProtoType>(RHS->getType().getCanonicalType()); 467 468 // Fast-path matches in the canonical types. 469 if (LT == RT) return true; 470 471 // Force the signatures to match. We can't rely on the overrides 472 // list here because there isn't necessarily an inheritance 473 // relationship between the two methods. 474 if (LT->getTypeQuals() != RT->getTypeQuals() || 475 LT->getNumArgs() != RT->getNumArgs()) 476 return false; 477 for (unsigned I = 0, E = LT->getNumArgs(); I != E; ++I) 478 if (LT->getArgType(I) != RT->getArgType(I)) 479 return false; 480 return true; 481} 482 483bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, 484 const CXXMethodDecl *RHS) { 485 assert(LHS->isVirtual() && "LHS must be virtual!"); 486 assert(RHS->isVirtual() && "LHS must be virtual!"); 487 488 // A destructor can share a vcall offset with another destructor. 489 if (isa<CXXDestructorDecl>(LHS)) 490 return isa<CXXDestructorDecl>(RHS); 491 492 // FIXME: We need to check more things here. 493 494 // The methods must have the same name. 495 DeclarationName LHSName = LHS->getDeclName(); 496 DeclarationName RHSName = RHS->getDeclName(); 497 if (LHSName != RHSName) 498 return false; 499 500 // And the same signatures. 501 return HasSameVirtualSignature(LHS, RHS); 502} 503 504bool VCallOffsetMap::AddVCallOffset(const CXXMethodDecl *MD, 505 CharUnits OffsetOffset) { 506 // Check if we can reuse an offset. 507 for (unsigned I = 0, E = Offsets.size(); I != E; ++I) { 508 if (MethodsCanShareVCallOffset(Offsets[I].first, MD)) 509 return false; 510 } 511 512 // Add the offset. 513 Offsets.push_back(MethodAndOffsetPairTy(MD, OffsetOffset)); 514 return true; 515} 516 517CharUnits VCallOffsetMap::getVCallOffsetOffset(const CXXMethodDecl *MD) { 518 // Look for an offset. 519 for (unsigned I = 0, E = Offsets.size(); I != E; ++I) { 520 if (MethodsCanShareVCallOffset(Offsets[I].first, MD)) 521 return Offsets[I].second; 522 } 523 524 llvm_unreachable("Should always find a vcall offset offset!"); 525} 526 527/// VCallAndVBaseOffsetBuilder - Class for building vcall and vbase offsets. 528class VCallAndVBaseOffsetBuilder { 529public: 530 typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> 531 VBaseOffsetOffsetsMapTy; 532 533private: 534 /// MostDerivedClass - The most derived class for which we're building vcall 535 /// and vbase offsets. 536 const CXXRecordDecl *MostDerivedClass; 537 538 /// LayoutClass - The class we're using for layout information. Will be 539 /// different than the most derived class if we're building a construction 540 /// vtable. 541 const CXXRecordDecl *LayoutClass; 542 543 /// Context - The ASTContext which we will use for layout information. 544 ASTContext &Context; 545 546 /// Components - vcall and vbase offset components 547 typedef SmallVector<VTableComponent, 64> VTableComponentVectorTy; 548 VTableComponentVectorTy Components; 549 550 /// VisitedVirtualBases - Visited virtual bases. 551 llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; 552 553 /// VCallOffsets - Keeps track of vcall offsets. 554 VCallOffsetMap VCallOffsets; 555 556 557 /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets, 558 /// relative to the address point. 559 VBaseOffsetOffsetsMapTy VBaseOffsetOffsets; 560 561 /// FinalOverriders - The final overriders of the most derived class. 562 /// (Can be null when we're not building a vtable of the most derived class). 563 const FinalOverriders *Overriders; 564 565 /// AddVCallAndVBaseOffsets - Add vcall offsets and vbase offsets for the 566 /// given base subobject. 567 void AddVCallAndVBaseOffsets(BaseSubobject Base, bool BaseIsVirtual, 568 CharUnits RealBaseOffset); 569 570 /// AddVCallOffsets - Add vcall offsets for the given base subobject. 571 void AddVCallOffsets(BaseSubobject Base, CharUnits VBaseOffset); 572 573 /// AddVBaseOffsets - Add vbase offsets for the given class. 574 void AddVBaseOffsets(const CXXRecordDecl *Base, 575 CharUnits OffsetInLayoutClass); 576 577 /// getCurrentOffsetOffset - Get the current vcall or vbase offset offset in 578 /// chars, relative to the vtable address point. 579 CharUnits getCurrentOffsetOffset() const; 580 581public: 582 VCallAndVBaseOffsetBuilder(const CXXRecordDecl *MostDerivedClass, 583 const CXXRecordDecl *LayoutClass, 584 const FinalOverriders *Overriders, 585 BaseSubobject Base, bool BaseIsVirtual, 586 CharUnits OffsetInLayoutClass) 587 : MostDerivedClass(MostDerivedClass), LayoutClass(LayoutClass), 588 Context(MostDerivedClass->getASTContext()), Overriders(Overriders) { 589 590 // Add vcall and vbase offsets. 591 AddVCallAndVBaseOffsets(Base, BaseIsVirtual, OffsetInLayoutClass); 592 } 593 594 /// Methods for iterating over the components. 595 typedef VTableComponentVectorTy::const_reverse_iterator const_iterator; 596 const_iterator components_begin() const { return Components.rbegin(); } 597 const_iterator components_end() const { return Components.rend(); } 598 599 const VCallOffsetMap &getVCallOffsets() const { return VCallOffsets; } 600 const VBaseOffsetOffsetsMapTy &getVBaseOffsetOffsets() const { 601 return VBaseOffsetOffsets; 602 } 603}; 604 605void 606VCallAndVBaseOffsetBuilder::AddVCallAndVBaseOffsets(BaseSubobject Base, 607 bool BaseIsVirtual, 608 CharUnits RealBaseOffset) { 609 const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base.getBase()); 610 611 // Itanium C++ ABI 2.5.2: 612 // ..in classes sharing a virtual table with a primary base class, the vcall 613 // and vbase offsets added by the derived class all come before the vcall 614 // and vbase offsets required by the base class, so that the latter may be 615 // laid out as required by the base class without regard to additions from 616 // the derived class(es). 617 618 // (Since we're emitting the vcall and vbase offsets in reverse order, we'll 619 // emit them for the primary base first). 620 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 621 bool PrimaryBaseIsVirtual = Layout.isPrimaryBaseVirtual(); 622 623 CharUnits PrimaryBaseOffset; 624 625 // Get the base offset of the primary base. 626 if (PrimaryBaseIsVirtual) { 627 assert(Layout.getVBaseClassOffset(PrimaryBase).isZero() && 628 "Primary vbase should have a zero offset!"); 629 630 const ASTRecordLayout &MostDerivedClassLayout = 631 Context.getASTRecordLayout(MostDerivedClass); 632 633 PrimaryBaseOffset = 634 MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); 635 } else { 636 assert(Layout.getBaseClassOffset(PrimaryBase).isZero() && 637 "Primary base should have a zero offset!"); 638 639 PrimaryBaseOffset = Base.getBaseOffset(); 640 } 641 642 AddVCallAndVBaseOffsets( 643 BaseSubobject(PrimaryBase,PrimaryBaseOffset), 644 PrimaryBaseIsVirtual, RealBaseOffset); 645 } 646 647 AddVBaseOffsets(Base.getBase(), RealBaseOffset); 648 649 // We only want to add vcall offsets for virtual bases. 650 if (BaseIsVirtual) 651 AddVCallOffsets(Base, RealBaseOffset); 652} 653 654CharUnits VCallAndVBaseOffsetBuilder::getCurrentOffsetOffset() const { 655 // OffsetIndex is the index of this vcall or vbase offset, relative to the 656 // vtable address point. (We subtract 3 to account for the information just 657 // above the address point, the RTTI info, the offset to top, and the 658 // vcall offset itself). 659 int64_t OffsetIndex = -(int64_t)(3 + Components.size()); 660 661 CharUnits PointerWidth = 662 Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); 663 CharUnits OffsetOffset = PointerWidth * OffsetIndex; 664 return OffsetOffset; 665} 666 667void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, 668 CharUnits VBaseOffset) { 669 const CXXRecordDecl *RD = Base.getBase(); 670 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 671 672 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 673 674 // Handle the primary base first. 675 // We only want to add vcall offsets if the base is non-virtual; a virtual 676 // primary base will have its vcall and vbase offsets emitted already. 677 if (PrimaryBase && !Layout.isPrimaryBaseVirtual()) { 678 // Get the base offset of the primary base. 679 assert(Layout.getBaseClassOffset(PrimaryBase).isZero() && 680 "Primary base should have a zero offset!"); 681 682 AddVCallOffsets(BaseSubobject(PrimaryBase, Base.getBaseOffset()), 683 VBaseOffset); 684 } 685 686 // Add the vcall offsets. 687 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 688 E = RD->method_end(); I != E; ++I) { 689 const CXXMethodDecl *MD = *I; 690 691 if (!MD->isVirtual()) 692 continue; 693 694 CharUnits OffsetOffset = getCurrentOffsetOffset(); 695 696 // Don't add a vcall offset if we already have one for this member function 697 // signature. 698 if (!VCallOffsets.AddVCallOffset(MD, OffsetOffset)) 699 continue; 700 701 CharUnits Offset = CharUnits::Zero(); 702 703 if (Overriders) { 704 // Get the final overrider. 705 FinalOverriders::OverriderInfo Overrider = 706 Overriders->getOverrider(MD, Base.getBaseOffset()); 707 708 /// The vcall offset is the offset from the virtual base to the object 709 /// where the function was overridden. 710 Offset = Overrider.Offset - VBaseOffset; 711 } 712 713 Components.push_back( 714 VTableComponent::MakeVCallOffset(Offset)); 715 } 716 717 // And iterate over all non-virtual bases (ignoring the primary base). 718 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 719 E = RD->bases_end(); I != E; ++I) { 720 721 if (I->isVirtual()) 722 continue; 723 724 const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl(); 725 if (BaseDecl == PrimaryBase) 726 continue; 727 728 // Get the base offset of this base. 729 CharUnits BaseOffset = Base.getBaseOffset() + 730 Layout.getBaseClassOffset(BaseDecl); 731 732 AddVCallOffsets(BaseSubobject(BaseDecl, BaseOffset), 733 VBaseOffset); 734 } 735} 736 737void 738VCallAndVBaseOffsetBuilder::AddVBaseOffsets(const CXXRecordDecl *RD, 739 CharUnits OffsetInLayoutClass) { 740 const ASTRecordLayout &LayoutClassLayout = 741 Context.getASTRecordLayout(LayoutClass); 742 743 // Add vbase offsets. 744 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 745 E = RD->bases_end(); I != E; ++I) { 746 const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl(); 747 748 // Check if this is a virtual base that we haven't visited before. 749 if (I->isVirtual() && VisitedVirtualBases.insert(BaseDecl)) { 750 CharUnits Offset = 751 LayoutClassLayout.getVBaseClassOffset(BaseDecl) - OffsetInLayoutClass; 752 753 // Add the vbase offset offset. 754 assert(!VBaseOffsetOffsets.count(BaseDecl) && 755 "vbase offset offset already exists!"); 756 757 CharUnits VBaseOffsetOffset = getCurrentOffsetOffset(); 758 VBaseOffsetOffsets.insert( 759 std::make_pair(BaseDecl, VBaseOffsetOffset)); 760 761 Components.push_back( 762 VTableComponent::MakeVBaseOffset(Offset)); 763 } 764 765 // Check the base class looking for more vbase offsets. 766 AddVBaseOffsets(BaseDecl, OffsetInLayoutClass); 767 } 768} 769 770/// ItaniumVTableBuilder - Class for building vtable layout information. 771class ItaniumVTableBuilder { 772public: 773 /// PrimaryBasesSetVectorTy - A set vector of direct and indirect 774 /// primary bases. 775 typedef llvm::SmallSetVector<const CXXRecordDecl *, 8> 776 PrimaryBasesSetVectorTy; 777 778 typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> 779 VBaseOffsetOffsetsMapTy; 780 781 typedef llvm::DenseMap<BaseSubobject, uint64_t> 782 AddressPointsMapTy; 783 784 typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy; 785 786private: 787 /// VTables - Global vtable information. 788 ItaniumVTableContext &VTables; 789 790 /// MostDerivedClass - The most derived class for which we're building this 791 /// vtable. 792 const CXXRecordDecl *MostDerivedClass; 793 794 /// MostDerivedClassOffset - If we're building a construction vtable, this 795 /// holds the offset from the layout class to the most derived class. 796 const CharUnits MostDerivedClassOffset; 797 798 /// MostDerivedClassIsVirtual - Whether the most derived class is a virtual 799 /// base. (This only makes sense when building a construction vtable). 800 bool MostDerivedClassIsVirtual; 801 802 /// LayoutClass - The class we're using for layout information. Will be 803 /// different than the most derived class if we're building a construction 804 /// vtable. 805 const CXXRecordDecl *LayoutClass; 806 807 /// Context - The ASTContext which we will use for layout information. 808 ASTContext &Context; 809 810 /// FinalOverriders - The final overriders of the most derived class. 811 const FinalOverriders Overriders; 812 813 /// VCallOffsetsForVBases - Keeps track of vcall offsets for the virtual 814 /// bases in this vtable. 815 llvm::DenseMap<const CXXRecordDecl *, VCallOffsetMap> VCallOffsetsForVBases; 816 817 /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets for 818 /// the most derived class. 819 VBaseOffsetOffsetsMapTy VBaseOffsetOffsets; 820 821 /// Components - The components of the vtable being built. 822 SmallVector<VTableComponent, 64> Components; 823 824 /// AddressPoints - Address points for the vtable being built. 825 AddressPointsMapTy AddressPoints; 826 827 /// MethodInfo - Contains information about a method in a vtable. 828 /// (Used for computing 'this' pointer adjustment thunks. 829 struct MethodInfo { 830 /// BaseOffset - The base offset of this method. 831 const CharUnits BaseOffset; 832 833 /// BaseOffsetInLayoutClass - The base offset in the layout class of this 834 /// method. 835 const CharUnits BaseOffsetInLayoutClass; 836 837 /// VTableIndex - The index in the vtable that this method has. 838 /// (For destructors, this is the index of the complete destructor). 839 const uint64_t VTableIndex; 840 841 MethodInfo(CharUnits BaseOffset, CharUnits BaseOffsetInLayoutClass, 842 uint64_t VTableIndex) 843 : BaseOffset(BaseOffset), 844 BaseOffsetInLayoutClass(BaseOffsetInLayoutClass), 845 VTableIndex(VTableIndex) { } 846 847 MethodInfo() 848 : BaseOffset(CharUnits::Zero()), 849 BaseOffsetInLayoutClass(CharUnits::Zero()), 850 VTableIndex(0) { } 851 }; 852 853 typedef llvm::DenseMap<const CXXMethodDecl *, MethodInfo> MethodInfoMapTy; 854 855 /// MethodInfoMap - The information for all methods in the vtable we're 856 /// currently building. 857 MethodInfoMapTy MethodInfoMap; 858 859 /// MethodVTableIndices - Contains the index (relative to the vtable address 860 /// point) where the function pointer for a virtual function is stored. 861 MethodVTableIndicesTy MethodVTableIndices; 862 863 typedef llvm::DenseMap<uint64_t, ThunkInfo> VTableThunksMapTy; 864 865 /// VTableThunks - The thunks by vtable index in the vtable currently being 866 /// built. 867 VTableThunksMapTy VTableThunks; 868 869 typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; 870 typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy; 871 872 /// Thunks - A map that contains all the thunks needed for all methods in the 873 /// most derived class for which the vtable is currently being built. 874 ThunksMapTy Thunks; 875 876 /// AddThunk - Add a thunk for the given method. 877 void AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk); 878 879 /// ComputeThisAdjustments - Compute the 'this' pointer adjustments for the 880 /// part of the vtable we're currently building. 881 void ComputeThisAdjustments(); 882 883 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; 884 885 /// PrimaryVirtualBases - All known virtual bases who are a primary base of 886 /// some other base. 887 VisitedVirtualBasesSetTy PrimaryVirtualBases; 888 889 /// ComputeReturnAdjustment - Compute the return adjustment given a return 890 /// adjustment base offset. 891 ReturnAdjustment ComputeReturnAdjustment(BaseOffset Offset); 892 893 /// ComputeThisAdjustmentBaseOffset - Compute the base offset for adjusting 894 /// the 'this' pointer from the base subobject to the derived subobject. 895 BaseOffset ComputeThisAdjustmentBaseOffset(BaseSubobject Base, 896 BaseSubobject Derived) const; 897 898 /// ComputeThisAdjustment - Compute the 'this' pointer adjustment for the 899 /// given virtual member function, its offset in the layout class and its 900 /// final overrider. 901 ThisAdjustment 902 ComputeThisAdjustment(const CXXMethodDecl *MD, 903 CharUnits BaseOffsetInLayoutClass, 904 FinalOverriders::OverriderInfo Overrider); 905 906 /// AddMethod - Add a single virtual member function to the vtable 907 /// components vector. 908 void AddMethod(const CXXMethodDecl *MD, ReturnAdjustment ReturnAdjustment); 909 910 /// IsOverriderUsed - Returns whether the overrider will ever be used in this 911 /// part of the vtable. 912 /// 913 /// Itanium C++ ABI 2.5.2: 914 /// 915 /// struct A { virtual void f(); }; 916 /// struct B : virtual public A { int i; }; 917 /// struct C : virtual public A { int j; }; 918 /// struct D : public B, public C {}; 919 /// 920 /// When B and C are declared, A is a primary base in each case, so although 921 /// vcall offsets are allocated in the A-in-B and A-in-C vtables, no this 922 /// adjustment is required and no thunk is generated. However, inside D 923 /// objects, A is no longer a primary base of C, so if we allowed calls to 924 /// C::f() to use the copy of A's vtable in the C subobject, we would need 925 /// to adjust this from C* to B::A*, which would require a third-party 926 /// thunk. Since we require that a call to C::f() first convert to A*, 927 /// C-in-D's copy of A's vtable is never referenced, so this is not 928 /// necessary. 929 bool IsOverriderUsed(const CXXMethodDecl *Overrider, 930 CharUnits BaseOffsetInLayoutClass, 931 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 932 CharUnits FirstBaseOffsetInLayoutClass) const; 933 934 935 /// AddMethods - Add the methods of this base subobject and all its 936 /// primary bases to the vtable components vector. 937 void AddMethods(BaseSubobject Base, CharUnits BaseOffsetInLayoutClass, 938 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 939 CharUnits FirstBaseOffsetInLayoutClass, 940 PrimaryBasesSetVectorTy &PrimaryBases); 941 942 // LayoutVTable - Layout the vtable for the given base class, including its 943 // secondary vtables and any vtables for virtual bases. 944 void LayoutVTable(); 945 946 /// LayoutPrimaryAndSecondaryVTables - Layout the primary vtable for the 947 /// given base subobject, as well as all its secondary vtables. 948 /// 949 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base 950 /// or a direct or indirect base of a virtual base. 951 /// 952 /// \param BaseIsVirtualInLayoutClass - Whether the base subobject is virtual 953 /// in the layout class. 954 void LayoutPrimaryAndSecondaryVTables(BaseSubobject Base, 955 bool BaseIsMorallyVirtual, 956 bool BaseIsVirtualInLayoutClass, 957 CharUnits OffsetInLayoutClass); 958 959 /// LayoutSecondaryVTables - Layout the secondary vtables for the given base 960 /// subobject. 961 /// 962 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base 963 /// or a direct or indirect base of a virtual base. 964 void LayoutSecondaryVTables(BaseSubobject Base, bool BaseIsMorallyVirtual, 965 CharUnits OffsetInLayoutClass); 966 967 /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this 968 /// class hierarchy. 969 void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, 970 CharUnits OffsetInLayoutClass, 971 VisitedVirtualBasesSetTy &VBases); 972 973 /// LayoutVTablesForVirtualBases - Layout vtables for all virtual bases of the 974 /// given base (excluding any primary bases). 975 void LayoutVTablesForVirtualBases(const CXXRecordDecl *RD, 976 VisitedVirtualBasesSetTy &VBases); 977 978 /// isBuildingConstructionVTable - Return whether this vtable builder is 979 /// building a construction vtable. 980 bool isBuildingConstructorVTable() const { 981 return MostDerivedClass != LayoutClass; 982 } 983 984public: 985 ItaniumVTableBuilder(ItaniumVTableContext &VTables, 986 const CXXRecordDecl *MostDerivedClass, 987 CharUnits MostDerivedClassOffset, 988 bool MostDerivedClassIsVirtual, 989 const CXXRecordDecl *LayoutClass) 990 : VTables(VTables), MostDerivedClass(MostDerivedClass), 991 MostDerivedClassOffset(MostDerivedClassOffset), 992 MostDerivedClassIsVirtual(MostDerivedClassIsVirtual), 993 LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()), 994 Overriders(MostDerivedClass, MostDerivedClassOffset, LayoutClass) { 995 assert(!Context.getTargetInfo().getCXXABI().isMicrosoft()); 996 997 LayoutVTable(); 998 999 if (Context.getLangOpts().DumpVTableLayouts) 1000 dumpLayout(llvm::outs()); 1001 } 1002 1003 uint64_t getNumThunks() const { 1004 return Thunks.size(); 1005 } 1006 1007 ThunksMapTy::const_iterator thunks_begin() const { 1008 return Thunks.begin(); 1009 } 1010 1011 ThunksMapTy::const_iterator thunks_end() const { 1012 return Thunks.end(); 1013 } 1014 1015 const VBaseOffsetOffsetsMapTy &getVBaseOffsetOffsets() const { 1016 return VBaseOffsetOffsets; 1017 } 1018 1019 const AddressPointsMapTy &getAddressPoints() const { 1020 return AddressPoints; 1021 } 1022 1023 MethodVTableIndicesTy::const_iterator vtable_indices_begin() const { 1024 return MethodVTableIndices.begin(); 1025 } 1026 1027 MethodVTableIndicesTy::const_iterator vtable_indices_end() const { 1028 return MethodVTableIndices.end(); 1029 } 1030 1031 /// getNumVTableComponents - Return the number of components in the vtable 1032 /// currently built. 1033 uint64_t getNumVTableComponents() const { 1034 return Components.size(); 1035 } 1036 1037 const VTableComponent *vtable_component_begin() const { 1038 return Components.begin(); 1039 } 1040 1041 const VTableComponent *vtable_component_end() const { 1042 return Components.end(); 1043 } 1044 1045 AddressPointsMapTy::const_iterator address_points_begin() const { 1046 return AddressPoints.begin(); 1047 } 1048 1049 AddressPointsMapTy::const_iterator address_points_end() const { 1050 return AddressPoints.end(); 1051 } 1052 1053 VTableThunksMapTy::const_iterator vtable_thunks_begin() const { 1054 return VTableThunks.begin(); 1055 } 1056 1057 VTableThunksMapTy::const_iterator vtable_thunks_end() const { 1058 return VTableThunks.end(); 1059 } 1060 1061 /// dumpLayout - Dump the vtable layout. 1062 void dumpLayout(raw_ostream&); 1063}; 1064 1065void ItaniumVTableBuilder::AddThunk(const CXXMethodDecl *MD, 1066 const ThunkInfo &Thunk) { 1067 assert(!isBuildingConstructorVTable() && 1068 "Can't add thunks for construction vtable"); 1069 1070 SmallVectorImpl<ThunkInfo> &ThunksVector = Thunks[MD]; 1071 1072 // Check if we have this thunk already. 1073 if (std::find(ThunksVector.begin(), ThunksVector.end(), Thunk) != 1074 ThunksVector.end()) 1075 return; 1076 1077 ThunksVector.push_back(Thunk); 1078} 1079 1080typedef llvm::SmallPtrSet<const CXXMethodDecl *, 8> OverriddenMethodsSetTy; 1081 1082/// Visit all the methods overridden by the given method recursively, 1083/// in a depth-first pre-order. The Visitor's visitor method returns a bool 1084/// indicating whether to continue the recursion for the given overridden 1085/// method (i.e. returning false stops the iteration). 1086template <class VisitorTy> 1087static void 1088visitAllOverriddenMethods(const CXXMethodDecl *MD, VisitorTy &Visitor) { 1089 assert(MD->isVirtual() && "Method is not virtual!"); 1090 1091 for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), 1092 E = MD->end_overridden_methods(); I != E; ++I) { 1093 const CXXMethodDecl *OverriddenMD = *I; 1094 if (!Visitor.visit(OverriddenMD)) 1095 continue; 1096 visitAllOverriddenMethods(OverriddenMD, Visitor); 1097 } 1098} 1099 1100namespace { 1101 struct OverriddenMethodsCollector { 1102 OverriddenMethodsSetTy *Methods; 1103 1104 bool visit(const CXXMethodDecl *MD) { 1105 // Don't recurse on this method if we've already collected it. 1106 return Methods->insert(MD); 1107 } 1108 }; 1109} 1110 1111/// ComputeAllOverriddenMethods - Given a method decl, will return a set of all 1112/// the overridden methods that the function decl overrides. 1113static void 1114ComputeAllOverriddenMethods(const CXXMethodDecl *MD, 1115 OverriddenMethodsSetTy& OverriddenMethods) { 1116 OverriddenMethodsCollector Collector = { &OverriddenMethods }; 1117 visitAllOverriddenMethods(MD, Collector); 1118} 1119 1120void ItaniumVTableBuilder::ComputeThisAdjustments() { 1121 // Now go through the method info map and see if any of the methods need 1122 // 'this' pointer adjustments. 1123 for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(), 1124 E = MethodInfoMap.end(); I != E; ++I) { 1125 const CXXMethodDecl *MD = I->first; 1126 const MethodInfo &MethodInfo = I->second; 1127 1128 // Ignore adjustments for unused function pointers. 1129 uint64_t VTableIndex = MethodInfo.VTableIndex; 1130 if (Components[VTableIndex].getKind() == 1131 VTableComponent::CK_UnusedFunctionPointer) 1132 continue; 1133 1134 // Get the final overrider for this method. 1135 FinalOverriders::OverriderInfo Overrider = 1136 Overriders.getOverrider(MD, MethodInfo.BaseOffset); 1137 1138 // Check if we need an adjustment at all. 1139 if (MethodInfo.BaseOffsetInLayoutClass == Overrider.Offset) { 1140 // When a return thunk is needed by a derived class that overrides a 1141 // virtual base, gcc uses a virtual 'this' adjustment as well. 1142 // While the thunk itself might be needed by vtables in subclasses or 1143 // in construction vtables, there doesn't seem to be a reason for using 1144 // the thunk in this vtable. Still, we do so to match gcc. 1145 if (VTableThunks.lookup(VTableIndex).Return.isEmpty()) 1146 continue; 1147 } 1148 1149 ThisAdjustment ThisAdjustment = 1150 ComputeThisAdjustment(MD, MethodInfo.BaseOffsetInLayoutClass, Overrider); 1151 1152 if (ThisAdjustment.isEmpty()) 1153 continue; 1154 1155 // Add it. 1156 VTableThunks[VTableIndex].This = ThisAdjustment; 1157 1158 if (isa<CXXDestructorDecl>(MD)) { 1159 // Add an adjustment for the deleting destructor as well. 1160 VTableThunks[VTableIndex + 1].This = ThisAdjustment; 1161 } 1162 } 1163 1164 /// Clear the method info map. 1165 MethodInfoMap.clear(); 1166 1167 if (isBuildingConstructorVTable()) { 1168 // We don't need to store thunk information for construction vtables. 1169 return; 1170 } 1171 1172 for (VTableThunksMapTy::const_iterator I = VTableThunks.begin(), 1173 E = VTableThunks.end(); I != E; ++I) { 1174 const VTableComponent &Component = Components[I->first]; 1175 const ThunkInfo &Thunk = I->second; 1176 const CXXMethodDecl *MD; 1177 1178 switch (Component.getKind()) { 1179 default: 1180 llvm_unreachable("Unexpected vtable component kind!"); 1181 case VTableComponent::CK_FunctionPointer: 1182 MD = Component.getFunctionDecl(); 1183 break; 1184 case VTableComponent::CK_CompleteDtorPointer: 1185 MD = Component.getDestructorDecl(); 1186 break; 1187 case VTableComponent::CK_DeletingDtorPointer: 1188 // We've already added the thunk when we saw the complete dtor pointer. 1189 continue; 1190 } 1191 1192 if (MD->getParent() == MostDerivedClass) 1193 AddThunk(MD, Thunk); 1194 } 1195} 1196 1197ReturnAdjustment 1198ItaniumVTableBuilder::ComputeReturnAdjustment(BaseOffset Offset) { 1199 ReturnAdjustment Adjustment; 1200 1201 if (!Offset.isEmpty()) { 1202 if (Offset.VirtualBase) { 1203 // Get the virtual base offset offset. 1204 if (Offset.DerivedClass == MostDerivedClass) { 1205 // We can get the offset offset directly from our map. 1206 Adjustment.Virtual.Itanium.VBaseOffsetOffset = 1207 VBaseOffsetOffsets.lookup(Offset.VirtualBase).getQuantity(); 1208 } else { 1209 Adjustment.Virtual.Itanium.VBaseOffsetOffset = 1210 VTables.getVirtualBaseOffsetOffset(Offset.DerivedClass, 1211 Offset.VirtualBase).getQuantity(); 1212 } 1213 } 1214 1215 Adjustment.NonVirtual = Offset.NonVirtualOffset.getQuantity(); 1216 } 1217 1218 return Adjustment; 1219} 1220 1221BaseOffset ItaniumVTableBuilder::ComputeThisAdjustmentBaseOffset( 1222 BaseSubobject Base, BaseSubobject Derived) const { 1223 const CXXRecordDecl *BaseRD = Base.getBase(); 1224 const CXXRecordDecl *DerivedRD = Derived.getBase(); 1225 1226 CXXBasePaths Paths(/*FindAmbiguities=*/true, 1227 /*RecordPaths=*/true, /*DetectVirtual=*/true); 1228 1229 if (!DerivedRD->isDerivedFrom(BaseRD, Paths)) 1230 llvm_unreachable("Class must be derived from the passed in base class!"); 1231 1232 // We have to go through all the paths, and see which one leads us to the 1233 // right base subobject. 1234 for (CXXBasePaths::const_paths_iterator I = Paths.begin(), E = Paths.end(); 1235 I != E; ++I) { 1236 BaseOffset Offset = ComputeBaseOffset(Context, DerivedRD, *I); 1237 1238 CharUnits OffsetToBaseSubobject = Offset.NonVirtualOffset; 1239 1240 if (Offset.VirtualBase) { 1241 // If we have a virtual base class, the non-virtual offset is relative 1242 // to the virtual base class offset. 1243 const ASTRecordLayout &LayoutClassLayout = 1244 Context.getASTRecordLayout(LayoutClass); 1245 1246 /// Get the virtual base offset, relative to the most derived class 1247 /// layout. 1248 OffsetToBaseSubobject += 1249 LayoutClassLayout.getVBaseClassOffset(Offset.VirtualBase); 1250 } else { 1251 // Otherwise, the non-virtual offset is relative to the derived class 1252 // offset. 1253 OffsetToBaseSubobject += Derived.getBaseOffset(); 1254 } 1255 1256 // Check if this path gives us the right base subobject. 1257 if (OffsetToBaseSubobject == Base.getBaseOffset()) { 1258 // Since we're going from the base class _to_ the derived class, we'll 1259 // invert the non-virtual offset here. 1260 Offset.NonVirtualOffset = -Offset.NonVirtualOffset; 1261 return Offset; 1262 } 1263 } 1264 1265 return BaseOffset(); 1266} 1267 1268ThisAdjustment ItaniumVTableBuilder::ComputeThisAdjustment( 1269 const CXXMethodDecl *MD, CharUnits BaseOffsetInLayoutClass, 1270 FinalOverriders::OverriderInfo Overrider) { 1271 // Ignore adjustments for pure virtual member functions. 1272 if (Overrider.Method->isPure()) 1273 return ThisAdjustment(); 1274 1275 BaseSubobject OverriddenBaseSubobject(MD->getParent(), 1276 BaseOffsetInLayoutClass); 1277 1278 BaseSubobject OverriderBaseSubobject(Overrider.Method->getParent(), 1279 Overrider.Offset); 1280 1281 // Compute the adjustment offset. 1282 BaseOffset Offset = ComputeThisAdjustmentBaseOffset(OverriddenBaseSubobject, 1283 OverriderBaseSubobject); 1284 if (Offset.isEmpty()) 1285 return ThisAdjustment(); 1286 1287 ThisAdjustment Adjustment; 1288 1289 if (Offset.VirtualBase) { 1290 // Get the vcall offset map for this virtual base. 1291 VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Offset.VirtualBase]; 1292 1293 if (VCallOffsets.empty()) { 1294 // We don't have vcall offsets for this virtual base, go ahead and 1295 // build them. 1296 VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClass, 1297 /*FinalOverriders=*/0, 1298 BaseSubobject(Offset.VirtualBase, 1299 CharUnits::Zero()), 1300 /*BaseIsVirtual=*/true, 1301 /*OffsetInLayoutClass=*/ 1302 CharUnits::Zero()); 1303 1304 VCallOffsets = Builder.getVCallOffsets(); 1305 } 1306 1307 Adjustment.Virtual.Itanium.VCallOffsetOffset = 1308 VCallOffsets.getVCallOffsetOffset(MD).getQuantity(); 1309 } 1310 1311 // Set the non-virtual part of the adjustment. 1312 Adjustment.NonVirtual = Offset.NonVirtualOffset.getQuantity(); 1313 1314 return Adjustment; 1315} 1316 1317void ItaniumVTableBuilder::AddMethod(const CXXMethodDecl *MD, 1318 ReturnAdjustment ReturnAdjustment) { 1319 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 1320 assert(ReturnAdjustment.isEmpty() && 1321 "Destructor can't have return adjustment!"); 1322 1323 // Add both the complete destructor and the deleting destructor. 1324 Components.push_back(VTableComponent::MakeCompleteDtor(DD)); 1325 Components.push_back(VTableComponent::MakeDeletingDtor(DD)); 1326 } else { 1327 // Add the return adjustment if necessary. 1328 if (!ReturnAdjustment.isEmpty()) 1329 VTableThunks[Components.size()].Return = ReturnAdjustment; 1330 1331 // Add the function. 1332 Components.push_back(VTableComponent::MakeFunction(MD)); 1333 } 1334} 1335 1336/// OverridesIndirectMethodInBase - Return whether the given member function 1337/// overrides any methods in the set of given bases. 1338/// Unlike OverridesMethodInBase, this checks "overriders of overriders". 1339/// For example, if we have: 1340/// 1341/// struct A { virtual void f(); } 1342/// struct B : A { virtual void f(); } 1343/// struct C : B { virtual void f(); } 1344/// 1345/// OverridesIndirectMethodInBase will return true if given C::f as the method 1346/// and { A } as the set of bases. 1347static bool OverridesIndirectMethodInBases( 1348 const CXXMethodDecl *MD, 1349 ItaniumVTableBuilder::PrimaryBasesSetVectorTy &Bases) { 1350 if (Bases.count(MD->getParent())) 1351 return true; 1352 1353 for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), 1354 E = MD->end_overridden_methods(); I != E; ++I) { 1355 const CXXMethodDecl *OverriddenMD = *I; 1356 1357 // Check "indirect overriders". 1358 if (OverridesIndirectMethodInBases(OverriddenMD, Bases)) 1359 return true; 1360 } 1361 1362 return false; 1363} 1364 1365bool ItaniumVTableBuilder::IsOverriderUsed( 1366 const CXXMethodDecl *Overrider, CharUnits BaseOffsetInLayoutClass, 1367 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 1368 CharUnits FirstBaseOffsetInLayoutClass) const { 1369 // If the base and the first base in the primary base chain have the same 1370 // offsets, then this overrider will be used. 1371 if (BaseOffsetInLayoutClass == FirstBaseOffsetInLayoutClass) 1372 return true; 1373 1374 // We know now that Base (or a direct or indirect base of it) is a primary 1375 // base in part of the class hierarchy, but not a primary base in the most 1376 // derived class. 1377 1378 // If the overrider is the first base in the primary base chain, we know 1379 // that the overrider will be used. 1380 if (Overrider->getParent() == FirstBaseInPrimaryBaseChain) 1381 return true; 1382 1383 ItaniumVTableBuilder::PrimaryBasesSetVectorTy PrimaryBases; 1384 1385 const CXXRecordDecl *RD = FirstBaseInPrimaryBaseChain; 1386 PrimaryBases.insert(RD); 1387 1388 // Now traverse the base chain, starting with the first base, until we find 1389 // the base that is no longer a primary base. 1390 while (true) { 1391 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1392 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 1393 1394 if (!PrimaryBase) 1395 break; 1396 1397 if (Layout.isPrimaryBaseVirtual()) { 1398 assert(Layout.getVBaseClassOffset(PrimaryBase).isZero() && 1399 "Primary base should always be at offset 0!"); 1400 1401 const ASTRecordLayout &LayoutClassLayout = 1402 Context.getASTRecordLayout(LayoutClass); 1403 1404 // Now check if this is the primary base that is not a primary base in the 1405 // most derived class. 1406 if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) != 1407 FirstBaseOffsetInLayoutClass) { 1408 // We found it, stop walking the chain. 1409 break; 1410 } 1411 } else { 1412 assert(Layout.getBaseClassOffset(PrimaryBase).isZero() && 1413 "Primary base should always be at offset 0!"); 1414 } 1415 1416 if (!PrimaryBases.insert(PrimaryBase)) 1417 llvm_unreachable("Found a duplicate primary base!"); 1418 1419 RD = PrimaryBase; 1420 } 1421 1422 // If the final overrider is an override of one of the primary bases, 1423 // then we know that it will be used. 1424 return OverridesIndirectMethodInBases(Overrider, PrimaryBases); 1425} 1426 1427typedef llvm::SmallSetVector<const CXXRecordDecl *, 8> BasesSetVectorTy; 1428 1429/// FindNearestOverriddenMethod - Given a method, returns the overridden method 1430/// from the nearest base. Returns null if no method was found. 1431/// The Bases are expected to be sorted in a base-to-derived order. 1432static const CXXMethodDecl * 1433FindNearestOverriddenMethod(const CXXMethodDecl *MD, 1434 BasesSetVectorTy &Bases) { 1435 OverriddenMethodsSetTy OverriddenMethods; 1436 ComputeAllOverriddenMethods(MD, OverriddenMethods); 1437 1438 for (int I = Bases.size(), E = 0; I != E; --I) { 1439 const CXXRecordDecl *PrimaryBase = Bases[I - 1]; 1440 1441 // Now check the overridden methods. 1442 for (OverriddenMethodsSetTy::const_iterator I = OverriddenMethods.begin(), 1443 E = OverriddenMethods.end(); I != E; ++I) { 1444 const CXXMethodDecl *OverriddenMD = *I; 1445 1446 // We found our overridden method. 1447 if (OverriddenMD->getParent() == PrimaryBase) 1448 return OverriddenMD; 1449 } 1450 } 1451 1452 return 0; 1453} 1454 1455void ItaniumVTableBuilder::AddMethods( 1456 BaseSubobject Base, CharUnits BaseOffsetInLayoutClass, 1457 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 1458 CharUnits FirstBaseOffsetInLayoutClass, 1459 PrimaryBasesSetVectorTy &PrimaryBases) { 1460 // Itanium C++ ABI 2.5.2: 1461 // The order of the virtual function pointers in a virtual table is the 1462 // order of declaration of the corresponding member functions in the class. 1463 // 1464 // There is an entry for any virtual function declared in a class, 1465 // whether it is a new function or overrides a base class function, 1466 // unless it overrides a function from the primary base, and conversion 1467 // between their return types does not require an adjustment. 1468 1469 const CXXRecordDecl *RD = Base.getBase(); 1470 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1471 1472 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 1473 CharUnits PrimaryBaseOffset; 1474 CharUnits PrimaryBaseOffsetInLayoutClass; 1475 if (Layout.isPrimaryBaseVirtual()) { 1476 assert(Layout.getVBaseClassOffset(PrimaryBase).isZero() && 1477 "Primary vbase should have a zero offset!"); 1478 1479 const ASTRecordLayout &MostDerivedClassLayout = 1480 Context.getASTRecordLayout(MostDerivedClass); 1481 1482 PrimaryBaseOffset = 1483 MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); 1484 1485 const ASTRecordLayout &LayoutClassLayout = 1486 Context.getASTRecordLayout(LayoutClass); 1487 1488 PrimaryBaseOffsetInLayoutClass = 1489 LayoutClassLayout.getVBaseClassOffset(PrimaryBase); 1490 } else { 1491 assert(Layout.getBaseClassOffset(PrimaryBase).isZero() && 1492 "Primary base should have a zero offset!"); 1493 1494 PrimaryBaseOffset = Base.getBaseOffset(); 1495 PrimaryBaseOffsetInLayoutClass = BaseOffsetInLayoutClass; 1496 } 1497 1498 AddMethods(BaseSubobject(PrimaryBase, PrimaryBaseOffset), 1499 PrimaryBaseOffsetInLayoutClass, FirstBaseInPrimaryBaseChain, 1500 FirstBaseOffsetInLayoutClass, PrimaryBases); 1501 1502 if (!PrimaryBases.insert(PrimaryBase)) 1503 llvm_unreachable("Found a duplicate primary base!"); 1504 } 1505 1506 const CXXDestructorDecl *ImplicitVirtualDtor = 0; 1507 1508 typedef llvm::SmallVector<const CXXMethodDecl *, 8> NewVirtualFunctionsTy; 1509 NewVirtualFunctionsTy NewVirtualFunctions; 1510 1511 // Now go through all virtual member functions and add them. 1512 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 1513 E = RD->method_end(); I != E; ++I) { 1514 const CXXMethodDecl *MD = *I; 1515 1516 if (!MD->isVirtual()) 1517 continue; 1518 1519 // Get the final overrider. 1520 FinalOverriders::OverriderInfo Overrider = 1521 Overriders.getOverrider(MD, Base.getBaseOffset()); 1522 1523 // Check if this virtual member function overrides a method in a primary 1524 // base. If this is the case, and the return type doesn't require adjustment 1525 // then we can just use the member function from the primary base. 1526 if (const CXXMethodDecl *OverriddenMD = 1527 FindNearestOverriddenMethod(MD, PrimaryBases)) { 1528 if (ComputeReturnAdjustmentBaseOffset(Context, MD, 1529 OverriddenMD).isEmpty()) { 1530 // Replace the method info of the overridden method with our own 1531 // method. 1532 assert(MethodInfoMap.count(OverriddenMD) && 1533 "Did not find the overridden method!"); 1534 MethodInfo &OverriddenMethodInfo = MethodInfoMap[OverriddenMD]; 1535 1536 MethodInfo MethodInfo(Base.getBaseOffset(), BaseOffsetInLayoutClass, 1537 OverriddenMethodInfo.VTableIndex); 1538 1539 assert(!MethodInfoMap.count(MD) && 1540 "Should not have method info for this method yet!"); 1541 1542 MethodInfoMap.insert(std::make_pair(MD, MethodInfo)); 1543 MethodInfoMap.erase(OverriddenMD); 1544 1545 // If the overridden method exists in a virtual base class or a direct 1546 // or indirect base class of a virtual base class, we need to emit a 1547 // thunk if we ever have a class hierarchy where the base class is not 1548 // a primary base in the complete object. 1549 if (!isBuildingConstructorVTable() && OverriddenMD != MD) { 1550 // Compute the this adjustment. 1551 ThisAdjustment ThisAdjustment = 1552 ComputeThisAdjustment(OverriddenMD, BaseOffsetInLayoutClass, 1553 Overrider); 1554 1555 if (ThisAdjustment.Virtual.Itanium.VCallOffsetOffset && 1556 Overrider.Method->getParent() == MostDerivedClass) { 1557 1558 // There's no return adjustment from OverriddenMD and MD, 1559 // but that doesn't mean there isn't one between MD and 1560 // the final overrider. 1561 BaseOffset ReturnAdjustmentOffset = 1562 ComputeReturnAdjustmentBaseOffset(Context, Overrider.Method, MD); 1563 ReturnAdjustment ReturnAdjustment = 1564 ComputeReturnAdjustment(ReturnAdjustmentOffset); 1565 1566 // This is a virtual thunk for the most derived class, add it. 1567 AddThunk(Overrider.Method, 1568 ThunkInfo(ThisAdjustment, ReturnAdjustment)); 1569 } 1570 } 1571 1572 continue; 1573 } 1574 } 1575 1576 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 1577 if (MD->isImplicit()) { 1578 // Itanium C++ ABI 2.5.2: 1579 // If a class has an implicitly-defined virtual destructor, 1580 // its entries come after the declared virtual function pointers. 1581 1582 assert(!ImplicitVirtualDtor && 1583 "Did already see an implicit virtual dtor!"); 1584 ImplicitVirtualDtor = DD; 1585 continue; 1586 } 1587 } 1588 1589 NewVirtualFunctions.push_back(MD); 1590 } 1591 1592 if (ImplicitVirtualDtor) 1593 NewVirtualFunctions.push_back(ImplicitVirtualDtor); 1594 1595 for (NewVirtualFunctionsTy::const_iterator I = NewVirtualFunctions.begin(), 1596 E = NewVirtualFunctions.end(); I != E; ++I) { 1597 const CXXMethodDecl *MD = *I; 1598 1599 // Get the final overrider. 1600 FinalOverriders::OverriderInfo Overrider = 1601 Overriders.getOverrider(MD, Base.getBaseOffset()); 1602 1603 // Insert the method info for this method. 1604 MethodInfo MethodInfo(Base.getBaseOffset(), BaseOffsetInLayoutClass, 1605 Components.size()); 1606 1607 assert(!MethodInfoMap.count(MD) && 1608 "Should not have method info for this method yet!"); 1609 MethodInfoMap.insert(std::make_pair(MD, MethodInfo)); 1610 1611 // Check if this overrider is going to be used. 1612 const CXXMethodDecl *OverriderMD = Overrider.Method; 1613 if (!IsOverriderUsed(OverriderMD, BaseOffsetInLayoutClass, 1614 FirstBaseInPrimaryBaseChain, 1615 FirstBaseOffsetInLayoutClass)) { 1616 Components.push_back(VTableComponent::MakeUnusedFunction(OverriderMD)); 1617 continue; 1618 } 1619 1620 // Check if this overrider needs a return adjustment. 1621 // We don't want to do this for pure virtual member functions. 1622 BaseOffset ReturnAdjustmentOffset; 1623 if (!OverriderMD->isPure()) { 1624 ReturnAdjustmentOffset = 1625 ComputeReturnAdjustmentBaseOffset(Context, OverriderMD, MD); 1626 } 1627 1628 ReturnAdjustment ReturnAdjustment = 1629 ComputeReturnAdjustment(ReturnAdjustmentOffset); 1630 1631 AddMethod(Overrider.Method, ReturnAdjustment); 1632 } 1633} 1634 1635void ItaniumVTableBuilder::LayoutVTable() { 1636 LayoutPrimaryAndSecondaryVTables(BaseSubobject(MostDerivedClass, 1637 CharUnits::Zero()), 1638 /*BaseIsMorallyVirtual=*/false, 1639 MostDerivedClassIsVirtual, 1640 MostDerivedClassOffset); 1641 1642 VisitedVirtualBasesSetTy VBases; 1643 1644 // Determine the primary virtual bases. 1645 DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset, 1646 VBases); 1647 VBases.clear(); 1648 1649 LayoutVTablesForVirtualBases(MostDerivedClass, VBases); 1650 1651 // -fapple-kext adds an extra entry at end of vtbl. 1652 bool IsAppleKext = Context.getLangOpts().AppleKext; 1653 if (IsAppleKext) 1654 Components.push_back(VTableComponent::MakeVCallOffset(CharUnits::Zero())); 1655} 1656 1657void ItaniumVTableBuilder::LayoutPrimaryAndSecondaryVTables( 1658 BaseSubobject Base, bool BaseIsMorallyVirtual, 1659 bool BaseIsVirtualInLayoutClass, CharUnits OffsetInLayoutClass) { 1660 assert(Base.getBase()->isDynamicClass() && "class does not have a vtable!"); 1661 1662 // Add vcall and vbase offsets for this vtable. 1663 VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, LayoutClass, &Overriders, 1664 Base, BaseIsVirtualInLayoutClass, 1665 OffsetInLayoutClass); 1666 Components.append(Builder.components_begin(), Builder.components_end()); 1667 1668 // Check if we need to add these vcall offsets. 1669 if (BaseIsVirtualInLayoutClass && !Builder.getVCallOffsets().empty()) { 1670 VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Base.getBase()]; 1671 1672 if (VCallOffsets.empty()) 1673 VCallOffsets = Builder.getVCallOffsets(); 1674 } 1675 1676 // If we're laying out the most derived class we want to keep track of the 1677 // virtual base class offset offsets. 1678 if (Base.getBase() == MostDerivedClass) 1679 VBaseOffsetOffsets = Builder.getVBaseOffsetOffsets(); 1680 1681 // Add the offset to top. 1682 CharUnits OffsetToTop = MostDerivedClassOffset - OffsetInLayoutClass; 1683 Components.push_back(VTableComponent::MakeOffsetToTop(OffsetToTop)); 1684 1685 // Next, add the RTTI. 1686 Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass)); 1687 1688 uint64_t AddressPoint = Components.size(); 1689 1690 // Now go through all virtual member functions and add them. 1691 PrimaryBasesSetVectorTy PrimaryBases; 1692 AddMethods(Base, OffsetInLayoutClass, 1693 Base.getBase(), OffsetInLayoutClass, 1694 PrimaryBases); 1695 1696 const CXXRecordDecl *RD = Base.getBase(); 1697 if (RD == MostDerivedClass) { 1698 assert(MethodVTableIndices.empty()); 1699 for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(), 1700 E = MethodInfoMap.end(); I != E; ++I) { 1701 const CXXMethodDecl *MD = I->first; 1702 const MethodInfo &MI = I->second; 1703 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 1704 MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] 1705 = MI.VTableIndex - AddressPoint; 1706 MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] 1707 = MI.VTableIndex + 1 - AddressPoint; 1708 } else { 1709 MethodVTableIndices[MD] = MI.VTableIndex - AddressPoint; 1710 } 1711 } 1712 } 1713 1714 // Compute 'this' pointer adjustments. 1715 ComputeThisAdjustments(); 1716 1717 // Add all address points. 1718 while (true) { 1719 AddressPoints.insert(std::make_pair( 1720 BaseSubobject(RD, OffsetInLayoutClass), 1721 AddressPoint)); 1722 1723 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1724 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 1725 1726 if (!PrimaryBase) 1727 break; 1728 1729 if (Layout.isPrimaryBaseVirtual()) { 1730 // Check if this virtual primary base is a primary base in the layout 1731 // class. If it's not, we don't want to add it. 1732 const ASTRecordLayout &LayoutClassLayout = 1733 Context.getASTRecordLayout(LayoutClass); 1734 1735 if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) != 1736 OffsetInLayoutClass) { 1737 // We don't want to add this class (or any of its primary bases). 1738 break; 1739 } 1740 } 1741 1742 RD = PrimaryBase; 1743 } 1744 1745 // Layout secondary vtables. 1746 LayoutSecondaryVTables(Base, BaseIsMorallyVirtual, OffsetInLayoutClass); 1747} 1748 1749void 1750ItaniumVTableBuilder::LayoutSecondaryVTables(BaseSubobject Base, 1751 bool BaseIsMorallyVirtual, 1752 CharUnits OffsetInLayoutClass) { 1753 // Itanium C++ ABI 2.5.2: 1754 // Following the primary virtual table of a derived class are secondary 1755 // virtual tables for each of its proper base classes, except any primary 1756 // base(s) with which it shares its primary virtual table. 1757 1758 const CXXRecordDecl *RD = Base.getBase(); 1759 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1760 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 1761 1762 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1763 E = RD->bases_end(); I != E; ++I) { 1764 // Ignore virtual bases, we'll emit them later. 1765 if (I->isVirtual()) 1766 continue; 1767 1768 const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl(); 1769 1770 // Ignore bases that don't have a vtable. 1771 if (!BaseDecl->isDynamicClass()) 1772 continue; 1773 1774 if (isBuildingConstructorVTable()) { 1775 // Itanium C++ ABI 2.6.4: 1776 // Some of the base class subobjects may not need construction virtual 1777 // tables, which will therefore not be present in the construction 1778 // virtual table group, even though the subobject virtual tables are 1779 // present in the main virtual table group for the complete object. 1780 if (!BaseIsMorallyVirtual && !BaseDecl->getNumVBases()) 1781 continue; 1782 } 1783 1784 // Get the base offset of this base. 1785 CharUnits RelativeBaseOffset = Layout.getBaseClassOffset(BaseDecl); 1786 CharUnits BaseOffset = Base.getBaseOffset() + RelativeBaseOffset; 1787 1788 CharUnits BaseOffsetInLayoutClass = 1789 OffsetInLayoutClass + RelativeBaseOffset; 1790 1791 // Don't emit a secondary vtable for a primary base. We might however want 1792 // to emit secondary vtables for other bases of this base. 1793 if (BaseDecl == PrimaryBase) { 1794 LayoutSecondaryVTables(BaseSubobject(BaseDecl, BaseOffset), 1795 BaseIsMorallyVirtual, BaseOffsetInLayoutClass); 1796 continue; 1797 } 1798 1799 // Layout the primary vtable (and any secondary vtables) for this base. 1800 LayoutPrimaryAndSecondaryVTables( 1801 BaseSubobject(BaseDecl, BaseOffset), 1802 BaseIsMorallyVirtual, 1803 /*BaseIsVirtualInLayoutClass=*/false, 1804 BaseOffsetInLayoutClass); 1805 } 1806} 1807 1808void ItaniumVTableBuilder::DeterminePrimaryVirtualBases( 1809 const CXXRecordDecl *RD, CharUnits OffsetInLayoutClass, 1810 VisitedVirtualBasesSetTy &VBases) { 1811 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1812 1813 // Check if this base has a primary base. 1814 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 1815 1816 // Check if it's virtual. 1817 if (Layout.isPrimaryBaseVirtual()) { 1818 bool IsPrimaryVirtualBase = true; 1819 1820 if (isBuildingConstructorVTable()) { 1821 // Check if the base is actually a primary base in the class we use for 1822 // layout. 1823 const ASTRecordLayout &LayoutClassLayout = 1824 Context.getASTRecordLayout(LayoutClass); 1825 1826 CharUnits PrimaryBaseOffsetInLayoutClass = 1827 LayoutClassLayout.getVBaseClassOffset(PrimaryBase); 1828 1829 // We know that the base is not a primary base in the layout class if 1830 // the base offsets are different. 1831 if (PrimaryBaseOffsetInLayoutClass != OffsetInLayoutClass) 1832 IsPrimaryVirtualBase = false; 1833 } 1834 1835 if (IsPrimaryVirtualBase) 1836 PrimaryVirtualBases.insert(PrimaryBase); 1837 } 1838 } 1839 1840 // Traverse bases, looking for more primary virtual bases. 1841 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1842 E = RD->bases_end(); I != E; ++I) { 1843 const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl(); 1844 1845 CharUnits BaseOffsetInLayoutClass; 1846 1847 if (I->isVirtual()) { 1848 if (!VBases.insert(BaseDecl)) 1849 continue; 1850 1851 const ASTRecordLayout &LayoutClassLayout = 1852 Context.getASTRecordLayout(LayoutClass); 1853 1854 BaseOffsetInLayoutClass = 1855 LayoutClassLayout.getVBaseClassOffset(BaseDecl); 1856 } else { 1857 BaseOffsetInLayoutClass = 1858 OffsetInLayoutClass + Layout.getBaseClassOffset(BaseDecl); 1859 } 1860 1861 DeterminePrimaryVirtualBases(BaseDecl, BaseOffsetInLayoutClass, VBases); 1862 } 1863} 1864 1865void ItaniumVTableBuilder::LayoutVTablesForVirtualBases( 1866 const CXXRecordDecl *RD, VisitedVirtualBasesSetTy &VBases) { 1867 // Itanium C++ ABI 2.5.2: 1868 // Then come the virtual base virtual tables, also in inheritance graph 1869 // order, and again excluding primary bases (which share virtual tables with 1870 // the classes for which they are primary). 1871 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1872 E = RD->bases_end(); I != E; ++I) { 1873 const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl(); 1874 1875 // Check if this base needs a vtable. (If it's virtual, not a primary base 1876 // of some other class, and we haven't visited it before). 1877 if (I->isVirtual() && BaseDecl->isDynamicClass() && 1878 !PrimaryVirtualBases.count(BaseDecl) && VBases.insert(BaseDecl)) { 1879 const ASTRecordLayout &MostDerivedClassLayout = 1880 Context.getASTRecordLayout(MostDerivedClass); 1881 CharUnits BaseOffset = 1882 MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 1883 1884 const ASTRecordLayout &LayoutClassLayout = 1885 Context.getASTRecordLayout(LayoutClass); 1886 CharUnits BaseOffsetInLayoutClass = 1887 LayoutClassLayout.getVBaseClassOffset(BaseDecl); 1888 1889 LayoutPrimaryAndSecondaryVTables( 1890 BaseSubobject(BaseDecl, BaseOffset), 1891 /*BaseIsMorallyVirtual=*/true, 1892 /*BaseIsVirtualInLayoutClass=*/true, 1893 BaseOffsetInLayoutClass); 1894 } 1895 1896 // We only need to check the base for virtual base vtables if it actually 1897 // has virtual bases. 1898 if (BaseDecl->getNumVBases()) 1899 LayoutVTablesForVirtualBases(BaseDecl, VBases); 1900 } 1901} 1902 1903struct ItaniumThunkInfoComparator { 1904 bool operator() (const ThunkInfo &LHS, const ThunkInfo &RHS) { 1905 assert(LHS.Method == 0); 1906 assert(RHS.Method == 0); 1907 1908 if (LHS.This != RHS.This) 1909 return LHS.This < RHS.This; 1910 1911 if (LHS.Return != RHS.Return) 1912 return LHS.Return < RHS.Return; 1913 1914 return false; 1915 } 1916}; 1917 1918/// dumpLayout - Dump the vtable layout. 1919void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { 1920 // FIXME: write more tests that actually use the dumpLayout output to prevent 1921 // ItaniumVTableBuilder regressions. 1922 1923 if (isBuildingConstructorVTable()) { 1924 Out << "Construction vtable for ('"; 1925 Out << MostDerivedClass->getQualifiedNameAsString() << "', "; 1926 Out << MostDerivedClassOffset.getQuantity() << ") in '"; 1927 Out << LayoutClass->getQualifiedNameAsString(); 1928 } else { 1929 Out << "Vtable for '"; 1930 Out << MostDerivedClass->getQualifiedNameAsString(); 1931 } 1932 Out << "' (" << Components.size() << " entries).\n"; 1933 1934 // Iterate through the address points and insert them into a new map where 1935 // they are keyed by the index and not the base object. 1936 // Since an address point can be shared by multiple subobjects, we use an 1937 // STL multimap. 1938 std::multimap<uint64_t, BaseSubobject> AddressPointsByIndex; 1939 for (AddressPointsMapTy::const_iterator I = AddressPoints.begin(), 1940 E = AddressPoints.end(); I != E; ++I) { 1941 const BaseSubobject& Base = I->first; 1942 uint64_t Index = I->second; 1943 1944 AddressPointsByIndex.insert(std::make_pair(Index, Base)); 1945 } 1946 1947 for (unsigned I = 0, E = Components.size(); I != E; ++I) { 1948 uint64_t Index = I; 1949 1950 Out << llvm::format("%4d | ", I); 1951 1952 const VTableComponent &Component = Components[I]; 1953 1954 // Dump the component. 1955 switch (Component.getKind()) { 1956 1957 case VTableComponent::CK_VCallOffset: 1958 Out << "vcall_offset (" 1959 << Component.getVCallOffset().getQuantity() 1960 << ")"; 1961 break; 1962 1963 case VTableComponent::CK_VBaseOffset: 1964 Out << "vbase_offset (" 1965 << Component.getVBaseOffset().getQuantity() 1966 << ")"; 1967 break; 1968 1969 case VTableComponent::CK_OffsetToTop: 1970 Out << "offset_to_top (" 1971 << Component.getOffsetToTop().getQuantity() 1972 << ")"; 1973 break; 1974 1975 case VTableComponent::CK_RTTI: 1976 Out << Component.getRTTIDecl()->getQualifiedNameAsString() << " RTTI"; 1977 break; 1978 1979 case VTableComponent::CK_FunctionPointer: { 1980 const CXXMethodDecl *MD = Component.getFunctionDecl(); 1981 1982 std::string Str = 1983 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 1984 MD); 1985 Out << Str; 1986 if (MD->isPure()) 1987 Out << " [pure]"; 1988 1989 if (MD->isDeleted()) 1990 Out << " [deleted]"; 1991 1992 ThunkInfo Thunk = VTableThunks.lookup(I); 1993 if (!Thunk.isEmpty()) { 1994 // If this function pointer has a return adjustment, dump it. 1995 if (!Thunk.Return.isEmpty()) { 1996 Out << "\n [return adjustment: "; 1997 Out << Thunk.Return.NonVirtual << " non-virtual"; 1998 1999 if (Thunk.Return.Virtual.Itanium.VBaseOffsetOffset) { 2000 Out << ", " << Thunk.Return.Virtual.Itanium.VBaseOffsetOffset; 2001 Out << " vbase offset offset"; 2002 } 2003 2004 Out << ']'; 2005 } 2006 2007 // If this function pointer has a 'this' pointer adjustment, dump it. 2008 if (!Thunk.This.isEmpty()) { 2009 Out << "\n [this adjustment: "; 2010 Out << Thunk.This.NonVirtual << " non-virtual"; 2011 2012 if (Thunk.This.Virtual.Itanium.VCallOffsetOffset) { 2013 Out << ", " << Thunk.This.Virtual.Itanium.VCallOffsetOffset; 2014 Out << " vcall offset offset"; 2015 } 2016 2017 Out << ']'; 2018 } 2019 } 2020 2021 break; 2022 } 2023 2024 case VTableComponent::CK_CompleteDtorPointer: 2025 case VTableComponent::CK_DeletingDtorPointer: { 2026 bool IsComplete = 2027 Component.getKind() == VTableComponent::CK_CompleteDtorPointer; 2028 2029 const CXXDestructorDecl *DD = Component.getDestructorDecl(); 2030 2031 Out << DD->getQualifiedNameAsString(); 2032 if (IsComplete) 2033 Out << "() [complete]"; 2034 else 2035 Out << "() [deleting]"; 2036 2037 if (DD->isPure()) 2038 Out << " [pure]"; 2039 2040 ThunkInfo Thunk = VTableThunks.lookup(I); 2041 if (!Thunk.isEmpty()) { 2042 // If this destructor has a 'this' pointer adjustment, dump it. 2043 if (!Thunk.This.isEmpty()) { 2044 Out << "\n [this adjustment: "; 2045 Out << Thunk.This.NonVirtual << " non-virtual"; 2046 2047 if (Thunk.This.Virtual.Itanium.VCallOffsetOffset) { 2048 Out << ", " << Thunk.This.Virtual.Itanium.VCallOffsetOffset; 2049 Out << " vcall offset offset"; 2050 } 2051 2052 Out << ']'; 2053 } 2054 } 2055 2056 break; 2057 } 2058 2059 case VTableComponent::CK_UnusedFunctionPointer: { 2060 const CXXMethodDecl *MD = Component.getUnusedFunctionDecl(); 2061 2062 std::string Str = 2063 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2064 MD); 2065 Out << "[unused] " << Str; 2066 if (MD->isPure()) 2067 Out << " [pure]"; 2068 } 2069 2070 } 2071 2072 Out << '\n'; 2073 2074 // Dump the next address point. 2075 uint64_t NextIndex = Index + 1; 2076 if (AddressPointsByIndex.count(NextIndex)) { 2077 if (AddressPointsByIndex.count(NextIndex) == 1) { 2078 const BaseSubobject &Base = 2079 AddressPointsByIndex.find(NextIndex)->second; 2080 2081 Out << " -- (" << Base.getBase()->getQualifiedNameAsString(); 2082 Out << ", " << Base.getBaseOffset().getQuantity(); 2083 Out << ") vtable address --\n"; 2084 } else { 2085 CharUnits BaseOffset = 2086 AddressPointsByIndex.lower_bound(NextIndex)->second.getBaseOffset(); 2087 2088 // We store the class names in a set to get a stable order. 2089 std::set<std::string> ClassNames; 2090 for (std::multimap<uint64_t, BaseSubobject>::const_iterator I = 2091 AddressPointsByIndex.lower_bound(NextIndex), E = 2092 AddressPointsByIndex.upper_bound(NextIndex); I != E; ++I) { 2093 assert(I->second.getBaseOffset() == BaseOffset && 2094 "Invalid base offset!"); 2095 const CXXRecordDecl *RD = I->second.getBase(); 2096 ClassNames.insert(RD->getQualifiedNameAsString()); 2097 } 2098 2099 for (std::set<std::string>::const_iterator I = ClassNames.begin(), 2100 E = ClassNames.end(); I != E; ++I) { 2101 Out << " -- (" << *I; 2102 Out << ", " << BaseOffset.getQuantity() << ") vtable address --\n"; 2103 } 2104 } 2105 } 2106 } 2107 2108 Out << '\n'; 2109 2110 if (isBuildingConstructorVTable()) 2111 return; 2112 2113 if (MostDerivedClass->getNumVBases()) { 2114 // We store the virtual base class names and their offsets in a map to get 2115 // a stable order. 2116 2117 std::map<std::string, CharUnits> ClassNamesAndOffsets; 2118 for (VBaseOffsetOffsetsMapTy::const_iterator I = VBaseOffsetOffsets.begin(), 2119 E = VBaseOffsetOffsets.end(); I != E; ++I) { 2120 std::string ClassName = I->first->getQualifiedNameAsString(); 2121 CharUnits OffsetOffset = I->second; 2122 ClassNamesAndOffsets.insert( 2123 std::make_pair(ClassName, OffsetOffset)); 2124 } 2125 2126 Out << "Virtual base offset offsets for '"; 2127 Out << MostDerivedClass->getQualifiedNameAsString() << "' ("; 2128 Out << ClassNamesAndOffsets.size(); 2129 Out << (ClassNamesAndOffsets.size() == 1 ? " entry" : " entries") << ").\n"; 2130 2131 for (std::map<std::string, CharUnits>::const_iterator I = 2132 ClassNamesAndOffsets.begin(), E = ClassNamesAndOffsets.end(); 2133 I != E; ++I) 2134 Out << " " << I->first << " | " << I->second.getQuantity() << '\n'; 2135 2136 Out << "\n"; 2137 } 2138 2139 if (!Thunks.empty()) { 2140 // We store the method names in a map to get a stable order. 2141 std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls; 2142 2143 for (ThunksMapTy::const_iterator I = Thunks.begin(), E = Thunks.end(); 2144 I != E; ++I) { 2145 const CXXMethodDecl *MD = I->first; 2146 std::string MethodName = 2147 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2148 MD); 2149 2150 MethodNamesAndDecls.insert(std::make_pair(MethodName, MD)); 2151 } 2152 2153 for (std::map<std::string, const CXXMethodDecl *>::const_iterator I = 2154 MethodNamesAndDecls.begin(), E = MethodNamesAndDecls.end(); 2155 I != E; ++I) { 2156 const std::string &MethodName = I->first; 2157 const CXXMethodDecl *MD = I->second; 2158 2159 ThunkInfoVectorTy ThunksVector = Thunks[MD]; 2160 std::sort(ThunksVector.begin(), ThunksVector.end(), 2161 ItaniumThunkInfoComparator()); 2162 2163 Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size(); 2164 Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n"; 2165 2166 for (unsigned I = 0, E = ThunksVector.size(); I != E; ++I) { 2167 const ThunkInfo &Thunk = ThunksVector[I]; 2168 2169 Out << llvm::format("%4d | ", I); 2170 2171 // If this function pointer has a return pointer adjustment, dump it. 2172 if (!Thunk.Return.isEmpty()) { 2173 Out << "return adjustment: " << Thunk.Return.NonVirtual; 2174 Out << " non-virtual"; 2175 if (Thunk.Return.Virtual.Itanium.VBaseOffsetOffset) { 2176 Out << ", " << Thunk.Return.Virtual.Itanium.VBaseOffsetOffset; 2177 Out << " vbase offset offset"; 2178 } 2179 2180 if (!Thunk.This.isEmpty()) 2181 Out << "\n "; 2182 } 2183 2184 // If this function pointer has a 'this' pointer adjustment, dump it. 2185 if (!Thunk.This.isEmpty()) { 2186 Out << "this adjustment: "; 2187 Out << Thunk.This.NonVirtual << " non-virtual"; 2188 2189 if (Thunk.This.Virtual.Itanium.VCallOffsetOffset) { 2190 Out << ", " << Thunk.This.Virtual.Itanium.VCallOffsetOffset; 2191 Out << " vcall offset offset"; 2192 } 2193 } 2194 2195 Out << '\n'; 2196 } 2197 2198 Out << '\n'; 2199 } 2200 } 2201 2202 // Compute the vtable indices for all the member functions. 2203 // Store them in a map keyed by the index so we'll get a sorted table. 2204 std::map<uint64_t, std::string> IndicesMap; 2205 2206 for (CXXRecordDecl::method_iterator i = MostDerivedClass->method_begin(), 2207 e = MostDerivedClass->method_end(); i != e; ++i) { 2208 const CXXMethodDecl *MD = *i; 2209 2210 // We only want virtual member functions. 2211 if (!MD->isVirtual()) 2212 continue; 2213 2214 std::string MethodName = 2215 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2216 MD); 2217 2218 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 2219 GlobalDecl GD(DD, Dtor_Complete); 2220 assert(MethodVTableIndices.count(GD)); 2221 uint64_t VTableIndex = MethodVTableIndices[GD]; 2222 IndicesMap[VTableIndex] = MethodName + " [complete]"; 2223 IndicesMap[VTableIndex + 1] = MethodName + " [deleting]"; 2224 } else { 2225 assert(MethodVTableIndices.count(MD)); 2226 IndicesMap[MethodVTableIndices[MD]] = MethodName; 2227 } 2228 } 2229 2230 // Print the vtable indices for all the member functions. 2231 if (!IndicesMap.empty()) { 2232 Out << "VTable indices for '"; 2233 Out << MostDerivedClass->getQualifiedNameAsString(); 2234 Out << "' (" << IndicesMap.size() << " entries).\n"; 2235 2236 for (std::map<uint64_t, std::string>::const_iterator I = IndicesMap.begin(), 2237 E = IndicesMap.end(); I != E; ++I) { 2238 uint64_t VTableIndex = I->first; 2239 const std::string &MethodName = I->second; 2240 2241 Out << llvm::format("%4" PRIu64 " | ", VTableIndex) << MethodName 2242 << '\n'; 2243 } 2244 } 2245 2246 Out << '\n'; 2247} 2248 2249struct VTableThunksComparator { 2250 bool operator()(const VTableLayout::VTableThunkTy &LHS, 2251 const VTableLayout::VTableThunkTy &RHS) { 2252 if (LHS.first == RHS.first) { 2253 assert(LHS.second == RHS.second && 2254 "Different thunks should have unique indices!"); 2255 } 2256 return LHS.first < RHS.first; 2257 } 2258}; 2259} 2260 2261VTableLayout::VTableLayout(uint64_t NumVTableComponents, 2262 const VTableComponent *VTableComponents, 2263 uint64_t NumVTableThunks, 2264 const VTableThunkTy *VTableThunks, 2265 const AddressPointsMapTy &AddressPoints, 2266 bool IsMicrosoftABI) 2267 : NumVTableComponents(NumVTableComponents), 2268 VTableComponents(new VTableComponent[NumVTableComponents]), 2269 NumVTableThunks(NumVTableThunks), 2270 VTableThunks(new VTableThunkTy[NumVTableThunks]), 2271 AddressPoints(AddressPoints), 2272 IsMicrosoftABI(IsMicrosoftABI) { 2273 std::copy(VTableComponents, VTableComponents+NumVTableComponents, 2274 this->VTableComponents.get()); 2275 std::copy(VTableThunks, VTableThunks+NumVTableThunks, 2276 this->VTableThunks.get()); 2277 std::sort(this->VTableThunks.get(), 2278 this->VTableThunks.get() + NumVTableThunks, 2279 VTableThunksComparator()); 2280} 2281 2282VTableLayout::~VTableLayout() { } 2283 2284ItaniumVTableContext::ItaniumVTableContext(ASTContext &Context) 2285 : IsMicrosoftABI(Context.getTargetInfo().getCXXABI().isMicrosoft()) { 2286} 2287 2288ItaniumVTableContext::~ItaniumVTableContext() { 2289 llvm::DeleteContainerSeconds(VTableLayouts); 2290} 2291 2292uint64_t ItaniumVTableContext::getMethodVTableIndex(GlobalDecl GD) { 2293 MethodVTableIndicesTy::iterator I = MethodVTableIndices.find(GD); 2294 if (I != MethodVTableIndices.end()) 2295 return I->second; 2296 2297 const CXXRecordDecl *RD = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 2298 2299 computeVTableRelatedInformation(RD); 2300 2301 I = MethodVTableIndices.find(GD); 2302 assert(I != MethodVTableIndices.end() && "Did not find index!"); 2303 return I->second; 2304} 2305 2306CharUnits 2307ItaniumVTableContext::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, 2308 const CXXRecordDecl *VBase) { 2309 ClassPairTy ClassPair(RD, VBase); 2310 2311 VirtualBaseClassOffsetOffsetsMapTy::iterator I = 2312 VirtualBaseClassOffsetOffsets.find(ClassPair); 2313 if (I != VirtualBaseClassOffsetOffsets.end()) 2314 return I->second; 2315 2316 VCallAndVBaseOffsetBuilder Builder(RD, RD, /*FinalOverriders=*/0, 2317 BaseSubobject(RD, CharUnits::Zero()), 2318 /*BaseIsVirtual=*/false, 2319 /*OffsetInLayoutClass=*/CharUnits::Zero()); 2320 2321 for (VCallAndVBaseOffsetBuilder::VBaseOffsetOffsetsMapTy::const_iterator I = 2322 Builder.getVBaseOffsetOffsets().begin(), 2323 E = Builder.getVBaseOffsetOffsets().end(); I != E; ++I) { 2324 // Insert all types. 2325 ClassPairTy ClassPair(RD, I->first); 2326 2327 VirtualBaseClassOffsetOffsets.insert( 2328 std::make_pair(ClassPair, I->second)); 2329 } 2330 2331 I = VirtualBaseClassOffsetOffsets.find(ClassPair); 2332 assert(I != VirtualBaseClassOffsetOffsets.end() && "Did not find index!"); 2333 2334 return I->second; 2335} 2336 2337static VTableLayout *CreateVTableLayout(const ItaniumVTableBuilder &Builder) { 2338 SmallVector<VTableLayout::VTableThunkTy, 1> 2339 VTableThunks(Builder.vtable_thunks_begin(), Builder.vtable_thunks_end()); 2340 2341 return new VTableLayout(Builder.getNumVTableComponents(), 2342 Builder.vtable_component_begin(), 2343 VTableThunks.size(), 2344 VTableThunks.data(), 2345 Builder.getAddressPoints(), 2346 /*IsMicrosoftABI=*/false); 2347} 2348 2349void 2350ItaniumVTableContext::computeVTableRelatedInformation(const CXXRecordDecl *RD) { 2351 assert(!IsMicrosoftABI && "Shouldn't be called in this ABI!"); 2352 2353 const VTableLayout *&Entry = VTableLayouts[RD]; 2354 2355 // Check if we've computed this information before. 2356 if (Entry) 2357 return; 2358 2359 ItaniumVTableBuilder Builder(*this, RD, CharUnits::Zero(), 2360 /*MostDerivedClassIsVirtual=*/0, RD); 2361 Entry = CreateVTableLayout(Builder); 2362 2363 MethodVTableIndices.insert(Builder.vtable_indices_begin(), 2364 Builder.vtable_indices_end()); 2365 2366 // Add the known thunks. 2367 Thunks.insert(Builder.thunks_begin(), Builder.thunks_end()); 2368 2369 // If we don't have the vbase information for this class, insert it. 2370 // getVirtualBaseOffsetOffset will compute it separately without computing 2371 // the rest of the vtable related information. 2372 if (!RD->getNumVBases()) 2373 return; 2374 2375 const CXXRecordDecl *VBase = 2376 RD->vbases_begin()->getType()->getAsCXXRecordDecl(); 2377 2378 if (VirtualBaseClassOffsetOffsets.count(std::make_pair(RD, VBase))) 2379 return; 2380 2381 for (ItaniumVTableBuilder::VBaseOffsetOffsetsMapTy::const_iterator 2382 I = Builder.getVBaseOffsetOffsets().begin(), 2383 E = Builder.getVBaseOffsetOffsets().end(); 2384 I != E; ++I) { 2385 // Insert all types. 2386 ClassPairTy ClassPair(RD, I->first); 2387 2388 VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I->second)); 2389 } 2390} 2391 2392VTableLayout *ItaniumVTableContext::createConstructionVTableLayout( 2393 const CXXRecordDecl *MostDerivedClass, CharUnits MostDerivedClassOffset, 2394 bool MostDerivedClassIsVirtual, const CXXRecordDecl *LayoutClass) { 2395 ItaniumVTableBuilder Builder(*this, MostDerivedClass, MostDerivedClassOffset, 2396 MostDerivedClassIsVirtual, LayoutClass); 2397 return CreateVTableLayout(Builder); 2398} 2399 2400namespace { 2401 2402// Vtables in the Microsoft ABI are different from the Itanium ABI. 2403// 2404// The main differences are: 2405// 1. Separate vftable and vbtable. 2406// 2407// 2. Each subobject with a vfptr gets its own vftable rather than an address 2408// point in a single vtable shared between all the subobjects. 2409// Each vftable is represented by a separate section and virtual calls 2410// must be done using the vftable which has a slot for the function to be 2411// called. 2412// 2413// 3. Virtual method definitions expect their 'this' parameter to point to the 2414// first vfptr whose table provides a compatible overridden method. In many 2415// cases, this permits the original vf-table entry to directly call 2416// the method instead of passing through a thunk. 2417// 2418// A compatible overridden method is one which does not have a non-trivial 2419// covariant-return adjustment. 2420// 2421// The first vfptr is the one with the lowest offset in the complete-object 2422// layout of the defining class, and the method definition will subtract 2423// that constant offset from the parameter value to get the real 'this' 2424// value. Therefore, if the offset isn't really constant (e.g. if a virtual 2425// function defined in a virtual base is overridden in a more derived 2426// virtual base and these bases have a reverse order in the complete 2427// object), the vf-table may require a this-adjustment thunk. 2428// 2429// 4. vftables do not contain new entries for overrides that merely require 2430// this-adjustment. Together with #3, this keeps vf-tables smaller and 2431// eliminates the need for this-adjustment thunks in many cases, at the cost 2432// of often requiring redundant work to adjust the "this" pointer. 2433// 2434// 5. Instead of VTT and constructor vtables, vbtables and vtordisps are used. 2435// Vtordisps are emitted into the class layout if a class has 2436// a) a user-defined ctor/dtor 2437// and 2438// b) a method overriding a method in a virtual base. 2439 2440class VFTableBuilder { 2441public: 2442 typedef MicrosoftVTableContext::MethodVFTableLocation MethodVFTableLocation; 2443 2444 typedef llvm::DenseMap<GlobalDecl, MethodVFTableLocation> 2445 MethodVFTableLocationsTy; 2446 2447private: 2448 /// VTables - Global vtable information. 2449 MicrosoftVTableContext &VTables; 2450 2451 /// Context - The ASTContext which we will use for layout information. 2452 ASTContext &Context; 2453 2454 /// MostDerivedClass - The most derived class for which we're building this 2455 /// vtable. 2456 const CXXRecordDecl *MostDerivedClass; 2457 2458 const ASTRecordLayout &MostDerivedClassLayout; 2459 2460 VFPtrInfo WhichVFPtr; 2461 2462 /// FinalOverriders - The final overriders of the most derived class. 2463 const FinalOverriders Overriders; 2464 2465 /// Components - The components of the vftable being built. 2466 SmallVector<VTableComponent, 64> Components; 2467 2468 MethodVFTableLocationsTy MethodVFTableLocations; 2469 2470 /// MethodInfo - Contains information about a method in a vtable. 2471 /// (Used for computing 'this' pointer adjustment thunks. 2472 struct MethodInfo { 2473 /// VBTableIndex - The nonzero index in the vbtable that 2474 /// this method's base has, or zero. 2475 const uint64_t VBTableIndex; 2476 2477 /// VFTableIndex - The index in the vftable that this method has. 2478 const uint64_t VFTableIndex; 2479 2480 /// Shadowed - Indicates if this vftable slot is shadowed by 2481 /// a slot for a covariant-return override. If so, it shouldn't be printed 2482 /// or used for vcalls in the most derived class. 2483 bool Shadowed; 2484 2485 MethodInfo(uint64_t VBTableIndex, uint64_t VFTableIndex) 2486 : VBTableIndex(VBTableIndex), VFTableIndex(VFTableIndex), 2487 Shadowed(false) {} 2488 2489 MethodInfo() : VBTableIndex(0), VFTableIndex(0), Shadowed(false) {} 2490 }; 2491 2492 typedef llvm::DenseMap<const CXXMethodDecl *, MethodInfo> MethodInfoMapTy; 2493 2494 /// MethodInfoMap - The information for all methods in the vftable we're 2495 /// currently building. 2496 MethodInfoMapTy MethodInfoMap; 2497 2498 typedef llvm::DenseMap<uint64_t, ThunkInfo> VTableThunksMapTy; 2499 2500 /// VTableThunks - The thunks by vftable index in the vftable currently being 2501 /// built. 2502 VTableThunksMapTy VTableThunks; 2503 2504 typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; 2505 typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy; 2506 2507 /// Thunks - A map that contains all the thunks needed for all methods in the 2508 /// most derived class for which the vftable is currently being built. 2509 ThunksMapTy Thunks; 2510 2511 /// AddThunk - Add a thunk for the given method. 2512 void AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk) { 2513 SmallVector<ThunkInfo, 1> &ThunksVector = Thunks[MD]; 2514 2515 // Check if we have this thunk already. 2516 if (std::find(ThunksVector.begin(), ThunksVector.end(), Thunk) != 2517 ThunksVector.end()) 2518 return; 2519 2520 ThunksVector.push_back(Thunk); 2521 } 2522 2523 /// ComputeThisOffset - Returns the 'this' argument offset for the given 2524 /// method in the given subobject, relative to the beginning of the 2525 /// MostDerivedClass. 2526 CharUnits ComputeThisOffset(const CXXMethodDecl *MD, 2527 BaseSubobject Base, 2528 FinalOverriders::OverriderInfo Overrider); 2529 2530 void CalculateVtordispAdjustment(FinalOverriders::OverriderInfo Overrider, 2531 CharUnits ThisOffset, ThisAdjustment &TA); 2532 2533 /// AddMethod - Add a single virtual member function to the vftable 2534 /// components vector. 2535 void AddMethod(const CXXMethodDecl *MD, ThunkInfo TI) { 2536 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 2537 assert(TI.Return.isEmpty() && 2538 "Destructor can't have return adjustment!"); 2539 Components.push_back(VTableComponent::MakeDeletingDtor(DD)); 2540 } else { 2541 if (!TI.isEmpty()) 2542 VTableThunks[Components.size()] = TI; 2543 Components.push_back(VTableComponent::MakeFunction(MD)); 2544 } 2545 } 2546 2547 /// AddMethods - Add the methods of this base subobject and the relevant 2548 /// subbases to the vftable we're currently laying out. 2549 void AddMethods(BaseSubobject Base, unsigned BaseDepth, 2550 const CXXRecordDecl *LastVBase, 2551 BasesSetVectorTy &VisitedBases); 2552 2553 void LayoutVFTable() { 2554 // FIXME: add support for RTTI when we have proper LLVM support for symbols 2555 // pointing to the middle of a section. 2556 2557 BasesSetVectorTy VisitedBases; 2558 AddMethods(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 0, 0, 2559 VisitedBases); 2560 2561 assert(MethodVFTableLocations.empty()); 2562 for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(), 2563 E = MethodInfoMap.end(); I != E; ++I) { 2564 const CXXMethodDecl *MD = I->first; 2565 const MethodInfo &MI = I->second; 2566 // Skip the methods that the MostDerivedClass didn't override 2567 // and the entries shadowed by return adjusting thunks. 2568 if (MD->getParent() != MostDerivedClass || MI.Shadowed) 2569 continue; 2570 MethodVFTableLocation Loc(MI.VBTableIndex, WhichVFPtr.LastVBase, 2571 WhichVFPtr.VFPtrOffset, MI.VFTableIndex); 2572 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 2573 MethodVFTableLocations[GlobalDecl(DD, Dtor_Deleting)] = Loc; 2574 } else { 2575 MethodVFTableLocations[MD] = Loc; 2576 } 2577 } 2578 } 2579 2580 void ErrorUnsupported(StringRef Feature, SourceLocation Location) { 2581 clang::DiagnosticsEngine &Diags = Context.getDiagnostics(); 2582 unsigned DiagID = Diags.getCustomDiagID( 2583 DiagnosticsEngine::Error, "v-table layout for %0 is not supported yet"); 2584 Diags.Report(Context.getFullLoc(Location), DiagID) << Feature; 2585 } 2586 2587public: 2588 VFTableBuilder(MicrosoftVTableContext &VTables, 2589 const CXXRecordDecl *MostDerivedClass, VFPtrInfo Which) 2590 : VTables(VTables), 2591 Context(MostDerivedClass->getASTContext()), 2592 MostDerivedClass(MostDerivedClass), 2593 MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)), 2594 WhichVFPtr(Which), 2595 Overriders(MostDerivedClass, CharUnits(), MostDerivedClass) { 2596 LayoutVFTable(); 2597 2598 if (Context.getLangOpts().DumpVTableLayouts) 2599 dumpLayout(llvm::outs()); 2600 } 2601 2602 uint64_t getNumThunks() const { return Thunks.size(); } 2603 2604 ThunksMapTy::const_iterator thunks_begin() const { return Thunks.begin(); } 2605 2606 ThunksMapTy::const_iterator thunks_end() const { return Thunks.end(); } 2607 2608 MethodVFTableLocationsTy::const_iterator vtable_indices_begin() const { 2609 return MethodVFTableLocations.begin(); 2610 } 2611 2612 MethodVFTableLocationsTy::const_iterator vtable_indices_end() const { 2613 return MethodVFTableLocations.end(); 2614 } 2615 2616 uint64_t getNumVTableComponents() const { return Components.size(); } 2617 2618 const VTableComponent *vtable_component_begin() const { 2619 return Components.begin(); 2620 } 2621 2622 const VTableComponent *vtable_component_end() const { 2623 return Components.end(); 2624 } 2625 2626 VTableThunksMapTy::const_iterator vtable_thunks_begin() const { 2627 return VTableThunks.begin(); 2628 } 2629 2630 VTableThunksMapTy::const_iterator vtable_thunks_end() const { 2631 return VTableThunks.end(); 2632 } 2633 2634 void dumpLayout(raw_ostream &); 2635}; 2636 2637/// InitialOverriddenDefinitionCollector - Finds the set of least derived bases 2638/// that define the given method. 2639struct InitialOverriddenDefinitionCollector { 2640 BasesSetVectorTy Bases; 2641 OverriddenMethodsSetTy VisitedOverriddenMethods; 2642 2643 bool visit(const CXXMethodDecl *OverriddenMD) { 2644 if (OverriddenMD->size_overridden_methods() == 0) 2645 Bases.insert(OverriddenMD->getParent()); 2646 // Don't recurse on this method if we've already collected it. 2647 return VisitedOverriddenMethods.insert(OverriddenMD); 2648 } 2649}; 2650 2651static bool BaseInSet(const CXXBaseSpecifier *Specifier, 2652 CXXBasePath &Path, void *BasesSet) { 2653 BasesSetVectorTy *Bases = (BasesSetVectorTy *)BasesSet; 2654 return Bases->count(Specifier->getType()->getAsCXXRecordDecl()); 2655} 2656 2657CharUnits 2658VFTableBuilder::ComputeThisOffset(const CXXMethodDecl *MD, 2659 BaseSubobject Base, 2660 FinalOverriders::OverriderInfo Overrider) { 2661 InitialOverriddenDefinitionCollector Collector; 2662 visitAllOverriddenMethods(MD, Collector); 2663 2664 CXXBasePaths Paths; 2665 Base.getBase()->lookupInBases(BaseInSet, &Collector.Bases, Paths); 2666 2667 // This will hold the smallest this offset among overridees of MD. 2668 // This implies that an offset of a non-virtual base will dominate an offset 2669 // of a virtual base to potentially reduce the number of thunks required 2670 // in the derived classes that inherit this method. 2671 CharUnits Ret; 2672 bool First = true; 2673 2674 for (CXXBasePaths::paths_iterator I = Paths.begin(), E = Paths.end(); 2675 I != E; ++I) { 2676 const CXXBasePath &Path = (*I); 2677 CharUnits ThisOffset = Base.getBaseOffset(); 2678 CharUnits LastVBaseOffset; 2679 2680 // For each path from the overrider to the parents of the overridden methods, 2681 // traverse the path, calculating the this offset in the most derived class. 2682 for (int J = 0, F = Path.size(); J != F; ++J) { 2683 const CXXBasePathElement &Element = Path[J]; 2684 QualType CurTy = Element.Base->getType(); 2685 const CXXRecordDecl *PrevRD = Element.Class, 2686 *CurRD = CurTy->getAsCXXRecordDecl(); 2687 const ASTRecordLayout &Layout = Context.getASTRecordLayout(PrevRD); 2688 2689 if (Element.Base->isVirtual()) { 2690 LastVBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(CurRD); 2691 if (Overrider.Method->getParent() == PrevRD) { 2692 // This one's interesting. If the final overrider is in a vbase B of the 2693 // most derived class and it overrides a method of the B's own vbase A, 2694 // it uses A* as "this". In its prologue, it can cast A* to B* with 2695 // a static offset. This offset is used regardless of the actual 2696 // offset of A from B in the most derived class, requiring an 2697 // this-adjusting thunk in the vftable if A and B are laid out 2698 // differently in the most derived class. 2699 ThisOffset += Layout.getVBaseClassOffset(CurRD); 2700 } else { 2701 ThisOffset = LastVBaseOffset; 2702 } 2703 } else { 2704 ThisOffset += Layout.getBaseClassOffset(CurRD); 2705 } 2706 } 2707 2708 if (isa<CXXDestructorDecl>(MD)) { 2709 if (LastVBaseOffset.isZero()) { 2710 // If a "Base" class has at least one non-virtual base with a virtual 2711 // destructor, the "Base" virtual destructor will take the address 2712 // of the "Base" subobject as the "this" argument. 2713 return Base.getBaseOffset(); 2714 } else { 2715 // A virtual destructor of a virtual base takes the address of the 2716 // virtual base subobject as the "this" argument. 2717 return LastVBaseOffset; 2718 } 2719 } 2720 2721 if (Ret > ThisOffset || First) { 2722 First = false; 2723 Ret = ThisOffset; 2724 } 2725 } 2726 2727 assert(!First && "Method not found in the given subobject?"); 2728 return Ret; 2729} 2730 2731void VFTableBuilder::CalculateVtordispAdjustment( 2732 FinalOverriders::OverriderInfo Overrider, CharUnits ThisOffset, 2733 ThisAdjustment &TA) { 2734 const ASTRecordLayout::VBaseOffsetsMapTy &VBaseMap = 2735 MostDerivedClassLayout.getVBaseOffsetsMap(); 2736 const ASTRecordLayout::VBaseOffsetsMapTy::const_iterator &VBaseMapEntry = 2737 VBaseMap.find(WhichVFPtr.LastVBase); 2738 assert(VBaseMapEntry != VBaseMap.end()); 2739 2740 // Check if we need a vtordisp adjustment at all. 2741 if (!VBaseMapEntry->second.hasVtorDisp()) 2742 return; 2743 2744 CharUnits VFPtrVBaseOffset = VBaseMapEntry->second.VBaseOffset; 2745 // The implicit vtordisp field is located right before the vbase. 2746 TA.Virtual.Microsoft.VtordispOffset = 2747 (VFPtrVBaseOffset - WhichVFPtr.VFPtrFullOffset).getQuantity() - 4; 2748 2749 // If the final overrider is defined in either: 2750 // - the most derived class or its non-virtual base or 2751 // - the same vbase as the initial declaration, 2752 // a simple vtordisp thunk will suffice. 2753 const CXXRecordDecl *OverriderRD = Overrider.Method->getParent(); 2754 if (OverriderRD == MostDerivedClass) 2755 return; 2756 2757 const CXXRecordDecl *OverriderVBase = 2758 ComputeBaseOffset(Context, OverriderRD, MostDerivedClass).VirtualBase; 2759 if (!OverriderVBase || OverriderVBase == WhichVFPtr.LastVBase) 2760 return; 2761 2762 // Otherwise, we need to do use the dynamic offset of the final overrider 2763 // in order to get "this" adjustment right. 2764 TA.Virtual.Microsoft.VBPtrOffset = 2765 (VFPtrVBaseOffset + WhichVFPtr.VFPtrOffset - 2766 MostDerivedClassLayout.getVBPtrOffset()).getQuantity(); 2767 TA.Virtual.Microsoft.VBOffsetOffset = 2768 Context.getTypeSizeInChars(Context.IntTy).getQuantity() * 2769 VTables.getVBTableIndex(MostDerivedClass, OverriderVBase); 2770 2771 TA.NonVirtual = (ThisOffset - Overrider.Offset).getQuantity(); 2772} 2773 2774static void GroupNewVirtualOverloads( 2775 const CXXRecordDecl *RD, 2776 SmallVector<const CXXMethodDecl *, 10> &VirtualMethods) { 2777 // Put the virtual methods into VirtualMethods in the proper order: 2778 // 1) Group overloads by declaration name. New groups are added to the 2779 // vftable in the order of their first declarations in this class 2780 // (including overrides). 2781 // 2) In each group, new overloads appear in the reverse order of declaration. 2782 typedef SmallVector<const CXXMethodDecl *, 1> MethodGroup; 2783 SmallVector<MethodGroup, 10> Groups; 2784 typedef llvm::DenseMap<DeclarationName, unsigned> VisitedGroupIndicesTy; 2785 VisitedGroupIndicesTy VisitedGroupIndices; 2786 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 2787 E = RD->method_end(); I != E; ++I) { 2788 const CXXMethodDecl *MD = *I; 2789 if (!MD->isVirtual()) 2790 continue; 2791 2792 VisitedGroupIndicesTy::iterator J; 2793 bool Inserted; 2794 llvm::tie(J, Inserted) = VisitedGroupIndices.insert( 2795 std::make_pair(MD->getDeclName(), Groups.size())); 2796 if (Inserted) 2797 Groups.push_back(MethodGroup(1, MD)); 2798 else 2799 Groups[J->second].push_back(MD); 2800 } 2801 2802 for (unsigned I = 0, E = Groups.size(); I != E; ++I) 2803 VirtualMethods.append(Groups[I].rbegin(), Groups[I].rend()); 2804} 2805 2806void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth, 2807 const CXXRecordDecl *LastVBase, 2808 BasesSetVectorTy &VisitedBases) { 2809 const CXXRecordDecl *RD = Base.getBase(); 2810 if (!RD->isPolymorphic()) 2811 return; 2812 2813 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 2814 2815 // See if this class expands a vftable of the base we look at, which is either 2816 // the one defined by the vfptr base path or the primary base of the current class. 2817 const CXXRecordDecl *NextBase = 0, *NextLastVBase = LastVBase; 2818 CharUnits NextBaseOffset; 2819 if (BaseDepth < WhichVFPtr.PathToBaseWithVFPtr.size()) { 2820 NextBase = WhichVFPtr.PathToBaseWithVFPtr[BaseDepth]; 2821 if (Layout.getVBaseOffsetsMap().count(NextBase)) { 2822 NextLastVBase = NextBase; 2823 NextBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(NextBase); 2824 } else { 2825 NextBaseOffset = 2826 Base.getBaseOffset() + Layout.getBaseClassOffset(NextBase); 2827 } 2828 } else if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 2829 assert(!Layout.isPrimaryBaseVirtual() && 2830 "No primary virtual bases in this ABI"); 2831 NextBase = PrimaryBase; 2832 NextBaseOffset = Base.getBaseOffset(); 2833 } 2834 2835 if (NextBase) { 2836 AddMethods(BaseSubobject(NextBase, NextBaseOffset), BaseDepth + 1, 2837 NextLastVBase, VisitedBases); 2838 if (!VisitedBases.insert(NextBase)) 2839 llvm_unreachable("Found a duplicate primary base!"); 2840 } 2841 2842 SmallVector<const CXXMethodDecl*, 10> VirtualMethods; 2843 // Put virtual methods in the proper order. 2844 GroupNewVirtualOverloads(RD, VirtualMethods); 2845 2846 // Now go through all virtual member functions and add them to the current 2847 // vftable. This is done by 2848 // - replacing overridden methods in their existing slots, as long as they 2849 // don't require return adjustment; calculating This adjustment if needed. 2850 // - adding new slots for methods of the current base not present in any 2851 // sub-bases; 2852 // - adding new slots for methods that require Return adjustment. 2853 // We keep track of the methods visited in the sub-bases in MethodInfoMap. 2854 for (unsigned I = 0, E = VirtualMethods.size(); I != E; ++I) { 2855 const CXXMethodDecl *MD = VirtualMethods[I]; 2856 2857 FinalOverriders::OverriderInfo Overrider = 2858 Overriders.getOverrider(MD, Base.getBaseOffset()); 2859 ThisAdjustment ThisAdjustmentOffset; 2860 bool ForceThunk = false; 2861 2862 // Check if this virtual member function overrides 2863 // a method in one of the visited bases. 2864 if (const CXXMethodDecl *OverriddenMD = 2865 FindNearestOverriddenMethod(MD, VisitedBases)) { 2866 MethodInfoMapTy::iterator OverriddenMDIterator = 2867 MethodInfoMap.find(OverriddenMD); 2868 2869 // If the overridden method went to a different vftable, skip it. 2870 if (OverriddenMDIterator == MethodInfoMap.end()) 2871 continue; 2872 2873 MethodInfo &OverriddenMethodInfo = OverriddenMDIterator->second; 2874 2875 // Create a this-adjusting thunk if needed. 2876 CharUnits TI = ComputeThisOffset(MD, Base, Overrider); 2877 if (TI != WhichVFPtr.VFPtrFullOffset) { 2878 ThisAdjustmentOffset.NonVirtual = 2879 (TI - WhichVFPtr.VFPtrFullOffset).getQuantity(); 2880 } 2881 2882 if (WhichVFPtr.LastVBase) 2883 CalculateVtordispAdjustment(Overrider, TI, ThisAdjustmentOffset); 2884 2885 if (!ThisAdjustmentOffset.isEmpty()) { 2886 VTableThunks[OverriddenMethodInfo.VFTableIndex].This = 2887 ThisAdjustmentOffset; 2888 AddThunk(MD, VTableThunks[OverriddenMethodInfo.VFTableIndex]); 2889 } 2890 2891 if (MD->getResultType() == OverriddenMD->getResultType()) { 2892 // No return adjustment needed - just replace the overridden method info 2893 // with the current info. 2894 MethodInfo MI(OverriddenMethodInfo.VBTableIndex, 2895 OverriddenMethodInfo.VFTableIndex); 2896 MethodInfoMap.erase(OverriddenMDIterator); 2897 2898 assert(!MethodInfoMap.count(MD) && 2899 "Should not have method info for this method yet!"); 2900 MethodInfoMap.insert(std::make_pair(MD, MI)); 2901 continue; 2902 } else { 2903 // In case we need a return adjustment, we'll add a new slot for 2904 // the overrider and put a return-adjusting thunk where the overridden 2905 // method was in the vftable. 2906 // For now, just mark the overriden method as shadowed by a new slot. 2907 OverriddenMethodInfo.Shadowed = true; 2908 ForceThunk = true; 2909 2910 // Also apply this adjustment to the shadowed slots. 2911 if (!ThisAdjustmentOffset.isEmpty()) { 2912 // FIXME: this is O(N^2), can be O(N). 2913 const CXXMethodDecl *SubOverride = OverriddenMD; 2914 while ((SubOverride = 2915 FindNearestOverriddenMethod(SubOverride, VisitedBases))) { 2916 MethodInfoMapTy::iterator SubOverrideIterator = 2917 MethodInfoMap.find(SubOverride); 2918 if (SubOverrideIterator == MethodInfoMap.end()) 2919 break; 2920 MethodInfo &SubOverrideMI = SubOverrideIterator->second; 2921 assert(SubOverrideMI.Shadowed); 2922 VTableThunks[SubOverrideMI.VFTableIndex].This = 2923 ThisAdjustmentOffset; 2924 AddThunk(MD, VTableThunks[SubOverrideMI.VFTableIndex]); 2925 } 2926 } 2927 } 2928 } else if (Base.getBaseOffset() != WhichVFPtr.VFPtrFullOffset || 2929 MD->size_overridden_methods()) { 2930 // Skip methods that don't belong to the vftable of the current class, 2931 // e.g. each method that wasn't seen in any of the visited sub-bases 2932 // but overrides multiple methods of other sub-bases. 2933 continue; 2934 } 2935 2936 // If we got here, MD is a method not seen in any of the sub-bases or 2937 // it requires return adjustment. Insert the method info for this method. 2938 unsigned VBIndex = 2939 LastVBase ? VTables.getVBTableIndex(MostDerivedClass, LastVBase) : 0; 2940 MethodInfo MI(VBIndex, Components.size()); 2941 2942 assert(!MethodInfoMap.count(MD) && 2943 "Should not have method info for this method yet!"); 2944 MethodInfoMap.insert(std::make_pair(MD, MI)); 2945 2946 const CXXMethodDecl *OverriderMD = Overrider.Method; 2947 2948 // Check if this overrider needs a return adjustment. 2949 // We don't want to do this for pure virtual member functions. 2950 BaseOffset ReturnAdjustmentOffset; 2951 ReturnAdjustment ReturnAdjustment; 2952 if (!OverriderMD->isPure()) { 2953 ReturnAdjustmentOffset = 2954 ComputeReturnAdjustmentBaseOffset(Context, OverriderMD, MD); 2955 } 2956 if (!ReturnAdjustmentOffset.isEmpty()) { 2957 ForceThunk = true; 2958 ReturnAdjustment.NonVirtual = 2959 ReturnAdjustmentOffset.NonVirtualOffset.getQuantity(); 2960 if (ReturnAdjustmentOffset.VirtualBase) { 2961 const ASTRecordLayout &DerivedLayout = 2962 Context.getASTRecordLayout(ReturnAdjustmentOffset.DerivedClass); 2963 ReturnAdjustment.Virtual.Microsoft.VBPtrOffset = 2964 DerivedLayout.getVBPtrOffset().getQuantity(); 2965 ReturnAdjustment.Virtual.Microsoft.VBIndex = 2966 VTables.getVBTableIndex(ReturnAdjustmentOffset.DerivedClass, 2967 ReturnAdjustmentOffset.VirtualBase); 2968 } 2969 } 2970 2971 AddMethod(OverriderMD, ThunkInfo(ThisAdjustmentOffset, ReturnAdjustment, 2972 ForceThunk ? MD : 0)); 2973 } 2974} 2975 2976void PrintBasePath(const VFPtrInfo::BasePath &Path, raw_ostream &Out) { 2977 for (VFPtrInfo::BasePath::const_reverse_iterator I = Path.rbegin(), 2978 E = Path.rend(); I != E; ++I) { 2979 Out << "'" << (*I)->getQualifiedNameAsString() << "' in "; 2980 } 2981} 2982 2983struct MicrosoftThunkInfoStableSortComparator { 2984 bool operator() (const ThunkInfo &LHS, const ThunkInfo &RHS) { 2985 if (LHS.This != RHS.This) 2986 return LHS.This < RHS.This; 2987 2988 if (LHS.Return != RHS.Return) 2989 return LHS.Return < RHS.Return; 2990 2991 // Keep different thunks with the same adjustments in the order they 2992 // were put into the vector. 2993 return false; 2994 } 2995}; 2996 2997static void dumpMicrosoftThunkAdjustment(const ThunkInfo &TI, raw_ostream &Out, 2998 bool ContinueFirstLine) { 2999 const ReturnAdjustment &R = TI.Return; 3000 bool Multiline = false; 3001 const char *LinePrefix = "\n "; 3002 if (!R.isEmpty()) { 3003 if (!ContinueFirstLine) 3004 Out << LinePrefix; 3005 Out << "[return adjustment: "; 3006 if (R.Virtual.Microsoft.VBPtrOffset) 3007 Out << "vbptr at offset " << R.Virtual.Microsoft.VBPtrOffset << ", "; 3008 if (R.Virtual.Microsoft.VBIndex) 3009 Out << "vbase #" << R.Virtual.Microsoft.VBIndex << ", "; 3010 Out << R.NonVirtual << " non-virtual]"; 3011 Multiline = true; 3012 } 3013 3014 const ThisAdjustment &T = TI.This; 3015 if (!T.isEmpty()) { 3016 if (Multiline || !ContinueFirstLine) 3017 Out << LinePrefix; 3018 Out << "[this adjustment: "; 3019 if (!TI.This.Virtual.isEmpty()) { 3020 assert(T.Virtual.Microsoft.VtordispOffset < 0); 3021 Out << "vtordisp at " << T.Virtual.Microsoft.VtordispOffset << ", "; 3022 if (T.Virtual.Microsoft.VBPtrOffset) { 3023 Out << "vbptr at " << T.Virtual.Microsoft.VBPtrOffset 3024 << " to the left, "; 3025 assert(T.Virtual.Microsoft.VBOffsetOffset > 0); 3026 Out << LinePrefix << " vboffset at " 3027 << T.Virtual.Microsoft.VBOffsetOffset << " in the vbtable, "; 3028 } 3029 } 3030 Out << T.NonVirtual << " non-virtual]"; 3031 } 3032} 3033 3034void VFTableBuilder::dumpLayout(raw_ostream &Out) { 3035 Out << "VFTable for "; 3036 PrintBasePath(WhichVFPtr.PathToBaseWithVFPtr, Out); 3037 Out << "'" << MostDerivedClass->getQualifiedNameAsString(); 3038 Out << "' (" << Components.size() << " entries).\n"; 3039 3040 for (unsigned I = 0, E = Components.size(); I != E; ++I) { 3041 Out << llvm::format("%4d | ", I); 3042 3043 const VTableComponent &Component = Components[I]; 3044 3045 // Dump the component. 3046 switch (Component.getKind()) { 3047 case VTableComponent::CK_RTTI: 3048 Out << Component.getRTTIDecl()->getQualifiedNameAsString() << " RTTI"; 3049 break; 3050 3051 case VTableComponent::CK_FunctionPointer: { 3052 const CXXMethodDecl *MD = Component.getFunctionDecl(); 3053 3054 std::string Str = PredefinedExpr::ComputeName( 3055 PredefinedExpr::PrettyFunctionNoVirtual, MD); 3056 Out << Str; 3057 if (MD->isPure()) 3058 Out << " [pure]"; 3059 3060 if (MD->isDeleted()) { 3061 ErrorUnsupported("deleted methods", MD->getLocation()); 3062 Out << " [deleted]"; 3063 } 3064 3065 ThunkInfo Thunk = VTableThunks.lookup(I); 3066 if (!Thunk.isEmpty()) 3067 dumpMicrosoftThunkAdjustment(Thunk, Out, /*ContinueFirstLine=*/false); 3068 3069 break; 3070 } 3071 3072 case VTableComponent::CK_DeletingDtorPointer: { 3073 const CXXDestructorDecl *DD = Component.getDestructorDecl(); 3074 3075 Out << DD->getQualifiedNameAsString(); 3076 Out << "() [scalar deleting]"; 3077 3078 if (DD->isPure()) 3079 Out << " [pure]"; 3080 3081 ThunkInfo Thunk = VTableThunks.lookup(I); 3082 if (!Thunk.isEmpty()) { 3083 assert(Thunk.Return.isEmpty() && 3084 "No return adjustment needed for destructors!"); 3085 dumpMicrosoftThunkAdjustment(Thunk, Out, /*ContinueFirstLine=*/false); 3086 } 3087 3088 break; 3089 } 3090 3091 default: 3092 DiagnosticsEngine &Diags = Context.getDiagnostics(); 3093 unsigned DiagID = Diags.getCustomDiagID( 3094 DiagnosticsEngine::Error, 3095 "Unexpected vftable component type %0 for component number %1"); 3096 Diags.Report(MostDerivedClass->getLocation(), DiagID) 3097 << I << Component.getKind(); 3098 } 3099 3100 Out << '\n'; 3101 } 3102 3103 Out << '\n'; 3104 3105 if (!Thunks.empty()) { 3106 // We store the method names in a map to get a stable order. 3107 std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls; 3108 3109 for (ThunksMapTy::const_iterator I = Thunks.begin(), E = Thunks.end(); 3110 I != E; ++I) { 3111 const CXXMethodDecl *MD = I->first; 3112 std::string MethodName = PredefinedExpr::ComputeName( 3113 PredefinedExpr::PrettyFunctionNoVirtual, MD); 3114 3115 MethodNamesAndDecls.insert(std::make_pair(MethodName, MD)); 3116 } 3117 3118 for (std::map<std::string, const CXXMethodDecl *>::const_iterator 3119 I = MethodNamesAndDecls.begin(), 3120 E = MethodNamesAndDecls.end(); 3121 I != E; ++I) { 3122 const std::string &MethodName = I->first; 3123 const CXXMethodDecl *MD = I->second; 3124 3125 ThunkInfoVectorTy ThunksVector = Thunks[MD]; 3126 std::stable_sort(ThunksVector.begin(), ThunksVector.end(), 3127 MicrosoftThunkInfoStableSortComparator()); 3128 3129 Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size(); 3130 Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n"; 3131 3132 for (unsigned I = 0, E = ThunksVector.size(); I != E; ++I) { 3133 const ThunkInfo &Thunk = ThunksVector[I]; 3134 3135 Out << llvm::format("%4d | ", I); 3136 dumpMicrosoftThunkAdjustment(Thunk, Out, /*ContinueFirstLine=*/true); 3137 Out << '\n'; 3138 } 3139 3140 Out << '\n'; 3141 } 3142 } 3143} 3144} 3145 3146void MicrosoftVTableContext::enumerateVFPtrs( 3147 const CXXRecordDecl *MostDerivedClass, 3148 const ASTRecordLayout &MostDerivedClassLayout, BaseSubobject Base, 3149 const CXXRecordDecl *LastVBase, 3150 const VFPtrInfo::BasePath &PathFromCompleteClass, 3151 BasesSetVectorTy &VisitedVBases, 3152 VFPtrListTy &Result) { 3153 const CXXRecordDecl *CurrentClass = Base.getBase(); 3154 CharUnits OffsetInCompleteClass = Base.getBaseOffset(); 3155 const ASTRecordLayout &CurrentClassLayout = 3156 Context.getASTRecordLayout(CurrentClass); 3157 3158 if (CurrentClassLayout.hasOwnVFPtr()) { 3159 if (LastVBase) { 3160 uint64_t VBIndex = getVBTableIndex(MostDerivedClass, LastVBase); 3161 assert(VBIndex > 0 && "vbases must have vbindex!"); 3162 CharUnits VFPtrOffset = 3163 OffsetInCompleteClass - 3164 MostDerivedClassLayout.getVBaseClassOffset(LastVBase); 3165 Result.push_back(VFPtrInfo(VBIndex, LastVBase, VFPtrOffset, 3166 PathFromCompleteClass, OffsetInCompleteClass)); 3167 } else { 3168 Result.push_back(VFPtrInfo(OffsetInCompleteClass, PathFromCompleteClass)); 3169 } 3170 } 3171 3172 for (CXXRecordDecl::base_class_const_iterator I = CurrentClass->bases_begin(), 3173 E = CurrentClass->bases_end(); I != E; ++I) { 3174 const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl(); 3175 3176 CharUnits NextBaseOffset; 3177 const CXXRecordDecl *NextLastVBase; 3178 if (I->isVirtual()) { 3179 if (!VisitedVBases.insert(BaseDecl)) 3180 continue; 3181 NextBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 3182 NextLastVBase = BaseDecl; 3183 } else { 3184 NextBaseOffset = OffsetInCompleteClass + 3185 CurrentClassLayout.getBaseClassOffset(BaseDecl); 3186 NextLastVBase = LastVBase; 3187 } 3188 3189 VFPtrInfo::BasePath NewPath = PathFromCompleteClass; 3190 NewPath.push_back(BaseDecl); 3191 BaseSubobject NextBase(BaseDecl, NextBaseOffset); 3192 3193 enumerateVFPtrs(MostDerivedClass, MostDerivedClassLayout, NextBase, 3194 NextLastVBase, NewPath, VisitedVBases, Result); 3195 } 3196} 3197 3198/// CalculatePathToMangle - Calculate the subset of records that should be used 3199/// to mangle the vftable for the given vfptr. 3200/// Should only be called if a class has multiple vftables. 3201static void 3202CalculatePathToMangle(const CXXRecordDecl *RD, VFPtrInfo &VFPtr) { 3203 // FIXME: In some rare cases this code produces a slightly incorrect mangling. 3204 // It's very likely that the vbtable mangling code can be adjusted to mangle 3205 // both vftables and vbtables correctly. 3206 3207 VFPtrInfo::BasePath &FullPath = VFPtr.PathToBaseWithVFPtr; 3208 if (FullPath.empty()) { 3209 // Mangle the class's own vftable. 3210 assert(RD->getNumVBases() && 3211 "Something's wrong: if the most derived " 3212 "class has more than one vftable, it can only have its own " 3213 "vftable if it has vbases"); 3214 VFPtr.PathToMangle.push_back(RD); 3215 return; 3216 } 3217 3218 unsigned Begin = 0; 3219 3220 // First, skip all the bases before the vbase. 3221 if (VFPtr.LastVBase) { 3222 while (FullPath[Begin] != VFPtr.LastVBase) { 3223 Begin++; 3224 assert(Begin < FullPath.size()); 3225 } 3226 } 3227 3228 // Then, put the rest of the base path in the reverse order. 3229 for (unsigned I = FullPath.size(); I != Begin; --I) { 3230 const CXXRecordDecl *CurBase = FullPath[I - 1], 3231 *ItsBase = (I == 1) ? RD : FullPath[I - 2]; 3232 bool BaseIsVirtual = false; 3233 for (CXXRecordDecl::base_class_const_iterator J = ItsBase->bases_begin(), 3234 F = ItsBase->bases_end(); J != F; ++J) { 3235 if (J->getType()->getAsCXXRecordDecl() == CurBase) { 3236 BaseIsVirtual = J->isVirtual(); 3237 break; 3238 } 3239 } 3240 3241 // Should skip the current base if it is a non-virtual base with no siblings. 3242 if (BaseIsVirtual || ItsBase->getNumBases() != 1) 3243 VFPtr.PathToMangle.push_back(CurBase); 3244 } 3245} 3246 3247void MicrosoftVTableContext::enumerateVFPtrs( 3248 const CXXRecordDecl *ForClass, 3249 MicrosoftVTableContext::VFPtrListTy &Result) { 3250 Result.clear(); 3251 const ASTRecordLayout &ClassLayout = Context.getASTRecordLayout(ForClass); 3252 BasesSetVectorTy VisitedVBases; 3253 enumerateVFPtrs(ForClass, ClassLayout, 3254 BaseSubobject(ForClass, CharUnits::Zero()), 0, 3255 VFPtrInfo::BasePath(), VisitedVBases, Result); 3256 if (Result.size() > 1) { 3257 for (unsigned I = 0, E = Result.size(); I != E; ++I) 3258 CalculatePathToMangle(ForClass, Result[I]); 3259 } 3260} 3261 3262void MicrosoftVTableContext::computeVTableRelatedInformation( 3263 const CXXRecordDecl *RD) { 3264 assert(RD->isDynamicClass()); 3265 3266 // Check if we've computed this information before. 3267 if (VFPtrLocations.count(RD)) 3268 return; 3269 3270 const VTableLayout::AddressPointsMapTy EmptyAddressPointsMap; 3271 3272 VFPtrListTy &VFPtrs = VFPtrLocations[RD]; 3273 enumerateVFPtrs(RD, VFPtrs); 3274 3275 MethodVFTableLocationsTy NewMethodLocations; 3276 for (VFPtrListTy::iterator I = VFPtrs.begin(), E = VFPtrs.end(); 3277 I != E; ++I) { 3278 VFTableBuilder Builder(*this, RD, *I); 3279 3280 VFTableIdTy id(RD, I->VFPtrFullOffset); 3281 assert(VFTableLayouts.count(id) == 0); 3282 SmallVector<VTableLayout::VTableThunkTy, 1> VTableThunks( 3283 Builder.vtable_thunks_begin(), Builder.vtable_thunks_end()); 3284 VFTableLayouts[id] = new VTableLayout( 3285 Builder.getNumVTableComponents(), Builder.vtable_component_begin(), 3286 VTableThunks.size(), VTableThunks.data(), EmptyAddressPointsMap, true); 3287 NewMethodLocations.insert(Builder.vtable_indices_begin(), 3288 Builder.vtable_indices_end()); 3289 Thunks.insert(Builder.thunks_begin(), Builder.thunks_end()); 3290 } 3291 3292 MethodVFTableLocations.insert(NewMethodLocations.begin(), 3293 NewMethodLocations.end()); 3294 if (Context.getLangOpts().DumpVTableLayouts) 3295 dumpMethodLocations(RD, NewMethodLocations, llvm::outs()); 3296} 3297 3298void MicrosoftVTableContext::dumpMethodLocations( 3299 const CXXRecordDecl *RD, const MethodVFTableLocationsTy &NewMethods, 3300 raw_ostream &Out) { 3301 // Compute the vtable indices for all the member functions. 3302 // Store them in a map keyed by the location so we'll get a sorted table. 3303 std::map<MethodVFTableLocation, std::string> IndicesMap; 3304 bool HasNonzeroOffset = false; 3305 3306 for (MethodVFTableLocationsTy::const_iterator I = NewMethods.begin(), 3307 E = NewMethods.end(); I != E; ++I) { 3308 const CXXMethodDecl *MD = cast<const CXXMethodDecl>(I->first.getDecl()); 3309 assert(MD->isVirtual()); 3310 3311 std::string MethodName = PredefinedExpr::ComputeName( 3312 PredefinedExpr::PrettyFunctionNoVirtual, MD); 3313 3314 if (isa<CXXDestructorDecl>(MD)) { 3315 IndicesMap[I->second] = MethodName + " [scalar deleting]"; 3316 } else { 3317 IndicesMap[I->second] = MethodName; 3318 } 3319 3320 if (!I->second.VFPtrOffset.isZero() || I->second.VBTableIndex != 0) 3321 HasNonzeroOffset = true; 3322 } 3323 3324 // Print the vtable indices for all the member functions. 3325 if (!IndicesMap.empty()) { 3326 Out << "VFTable indices for "; 3327 Out << "'" << RD->getQualifiedNameAsString(); 3328 Out << "' (" << IndicesMap.size() << " entries).\n"; 3329 3330 CharUnits LastVFPtrOffset = CharUnits::fromQuantity(-1); 3331 uint64_t LastVBIndex = 0; 3332 for (std::map<MethodVFTableLocation, std::string>::const_iterator 3333 I = IndicesMap.begin(), 3334 E = IndicesMap.end(); 3335 I != E; ++I) { 3336 CharUnits VFPtrOffset = I->first.VFPtrOffset; 3337 uint64_t VBIndex = I->first.VBTableIndex; 3338 if (HasNonzeroOffset && 3339 (VFPtrOffset != LastVFPtrOffset || VBIndex != LastVBIndex)) { 3340 assert(VBIndex > LastVBIndex || VFPtrOffset > LastVFPtrOffset); 3341 Out << " -- accessible via "; 3342 if (VBIndex) 3343 Out << "vbtable index " << VBIndex << ", "; 3344 Out << "vfptr at offset " << VFPtrOffset.getQuantity() << " --\n"; 3345 LastVFPtrOffset = VFPtrOffset; 3346 LastVBIndex = VBIndex; 3347 } 3348 3349 uint64_t VTableIndex = I->first.Index; 3350 const std::string &MethodName = I->second; 3351 Out << llvm::format("%4" PRIu64 " | ", VTableIndex) << MethodName << '\n'; 3352 } 3353 Out << '\n'; 3354 } 3355} 3356 3357void MicrosoftVTableContext::computeVBTableRelatedInformation( 3358 const CXXRecordDecl *RD) { 3359 if (ComputedVBTableIndices.count(RD)) 3360 return; 3361 ComputedVBTableIndices.insert(RD); 3362 3363 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 3364 BasesSetVectorTy VisitedBases; 3365 3366 // First, see if the Derived class shared the vbptr with a non-virtual base. 3367 if (const CXXRecordDecl *VBPtrBase = Layout.getBaseSharingVBPtr()) { 3368 // If the Derived class shares the vbptr with a non-virtual base, 3369 // it inherits its vbase indices. 3370 computeVBTableRelatedInformation(VBPtrBase); 3371 for (CXXRecordDecl::base_class_const_iterator I = VBPtrBase->vbases_begin(), 3372 E = VBPtrBase->vbases_end(); I != E; ++I) { 3373 const CXXRecordDecl *SubVBase = I->getType()->getAsCXXRecordDecl(); 3374 assert(VBTableIndices.count(ClassPairTy(VBPtrBase, SubVBase))); 3375 VBTableIndices[ClassPairTy(RD, SubVBase)] = 3376 VBTableIndices[ClassPairTy(VBPtrBase, SubVBase)]; 3377 VisitedBases.insert(SubVBase); 3378 } 3379 } 3380 3381 // New vbases are added to the end of the vbtable. 3382 // Skip the self entry and vbases visited in the non-virtual base, if any. 3383 unsigned VBTableIndex = 1 + VisitedBases.size(); 3384 for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 3385 E = RD->vbases_end(); I != E; ++I) { 3386 const CXXRecordDecl *CurVBase = I->getType()->getAsCXXRecordDecl(); 3387 if (VisitedBases.insert(CurVBase)) 3388 VBTableIndices[ClassPairTy(RD, CurVBase)] = VBTableIndex++; 3389 } 3390} 3391 3392const MicrosoftVTableContext::VFPtrListTy & 3393MicrosoftVTableContext::getVFPtrOffsets(const CXXRecordDecl *RD) { 3394 computeVTableRelatedInformation(RD); 3395 3396 assert(VFPtrLocations.count(RD) && "Couldn't find vfptr locations"); 3397 return VFPtrLocations[RD]; 3398} 3399 3400const VTableLayout & 3401MicrosoftVTableContext::getVFTableLayout(const CXXRecordDecl *RD, 3402 CharUnits VFPtrOffset) { 3403 computeVTableRelatedInformation(RD); 3404 3405 VFTableIdTy id(RD, VFPtrOffset); 3406 assert(VFTableLayouts.count(id) && "Couldn't find a VFTable at this offset"); 3407 return *VFTableLayouts[id]; 3408} 3409 3410const MicrosoftVTableContext::MethodVFTableLocation & 3411MicrosoftVTableContext::getMethodVFTableLocation(GlobalDecl GD) { 3412 assert(cast<CXXMethodDecl>(GD.getDecl())->isVirtual() && 3413 "Only use this method for virtual methods or dtors"); 3414 if (isa<CXXDestructorDecl>(GD.getDecl())) 3415 assert(GD.getDtorType() == Dtor_Deleting); 3416 3417 MethodVFTableLocationsTy::iterator I = MethodVFTableLocations.find(GD); 3418 if (I != MethodVFTableLocations.end()) 3419 return I->second; 3420 3421 const CXXRecordDecl *RD = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 3422 3423 computeVTableRelatedInformation(RD); 3424 3425 I = MethodVFTableLocations.find(GD); 3426 assert(I != MethodVFTableLocations.end() && "Did not find index!"); 3427 return I->second; 3428} 3429