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