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