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