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