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