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