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 struct ItaniumThunkInfoComparator { 1911 bool operator() (const ThunkInfo &LHS, const ThunkInfo &RHS) { 1912 assert(LHS.Method == 0); 1913 assert(RHS.Method == 0); 1914 1915 if (LHS.This != RHS.This) 1916 return LHS.This < RHS.This; 1917 1918 if (LHS.Return != RHS.Return) 1919 return LHS.Return < RHS.Return; 1920 1921 return false; 1922 } 1923 }; 1924 1925 /// dumpLayout - Dump the vtable layout. 1926 void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { 1927 // FIXME: write more tests that actually use the dumpLayout output to prevent 1928 // ItaniumVTableBuilder regressions. 1929 1930 if (isBuildingConstructorVTable()) { 1931 Out << "Construction vtable for ('"; 1932 MostDerivedClass->printQualifiedName(Out); 1933 Out << "', "; 1934 Out << MostDerivedClassOffset.getQuantity() << ") in '"; 1935 LayoutClass->printQualifiedName(Out); 1936 } else { 1937 Out << "Vtable for '"; 1938 MostDerivedClass->printQualifiedName(Out); 1939 } 1940 Out << "' (" << Components.size() << " entries).\n"; 1941 1942 // Iterate through the address points and insert them into a new map where 1943 // they are keyed by the index and not the base object. 1944 // Since an address point can be shared by multiple subobjects, we use an 1945 // STL multimap. 1946 std::multimap<uint64_t, BaseSubobject> AddressPointsByIndex; 1947 for (AddressPointsMapTy::const_iterator I = AddressPoints.begin(), 1948 E = AddressPoints.end(); I != E; ++I) { 1949 const BaseSubobject& Base = I->first; 1950 uint64_t Index = I->second; 1951 1952 AddressPointsByIndex.insert(std::make_pair(Index, Base)); 1953 } 1954 1955 for (unsigned I = 0, E = Components.size(); I != E; ++I) { 1956 uint64_t Index = I; 1957 1958 Out << llvm::format("%4d | ", I); 1959 1960 const VTableComponent &Component = Components[I]; 1961 1962 // Dump the component. 1963 switch (Component.getKind()) { 1964 1965 case VTableComponent::CK_VCallOffset: 1966 Out << "vcall_offset (" 1967 << Component.getVCallOffset().getQuantity() 1968 << ")"; 1969 break; 1970 1971 case VTableComponent::CK_VBaseOffset: 1972 Out << "vbase_offset (" 1973 << Component.getVBaseOffset().getQuantity() 1974 << ")"; 1975 break; 1976 1977 case VTableComponent::CK_OffsetToTop: 1978 Out << "offset_to_top (" 1979 << Component.getOffsetToTop().getQuantity() 1980 << ")"; 1981 break; 1982 1983 case VTableComponent::CK_RTTI: 1984 Component.getRTTIDecl()->printQualifiedName(Out); 1985 Out << " RTTI"; 1986 break; 1987 1988 case VTableComponent::CK_FunctionPointer: { 1989 const CXXMethodDecl *MD = Component.getFunctionDecl(); 1990 1991 std::string Str = 1992 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 1993 MD); 1994 Out << Str; 1995 if (MD->isPure()) 1996 Out << " [pure]"; 1997 1998 if (MD->isDeleted()) 1999 Out << " [deleted]"; 2000 2001 ThunkInfo Thunk = VTableThunks.lookup(I); 2002 if (!Thunk.isEmpty()) { 2003 // If this function pointer has a return adjustment, dump it. 2004 if (!Thunk.Return.isEmpty()) { 2005 Out << "\n [return adjustment: "; 2006 Out << Thunk.Return.NonVirtual << " non-virtual"; 2007 2008 if (Thunk.Return.Virtual.Itanium.VBaseOffsetOffset) { 2009 Out << ", " << Thunk.Return.Virtual.Itanium.VBaseOffsetOffset; 2010 Out << " vbase offset offset"; 2011 } 2012 2013 Out << ']'; 2014 } 2015 2016 // If this function pointer has a 'this' pointer adjustment, dump it. 2017 if (!Thunk.This.isEmpty()) { 2018 Out << "\n [this adjustment: "; 2019 Out << Thunk.This.NonVirtual << " non-virtual"; 2020 2021 if (Thunk.This.Virtual.Itanium.VCallOffsetOffset) { 2022 Out << ", " << Thunk.This.Virtual.Itanium.VCallOffsetOffset; 2023 Out << " vcall offset offset"; 2024 } 2025 2026 Out << ']'; 2027 } 2028 } 2029 2030 break; 2031 } 2032 2033 case VTableComponent::CK_CompleteDtorPointer: 2034 case VTableComponent::CK_DeletingDtorPointer: { 2035 bool IsComplete = 2036 Component.getKind() == VTableComponent::CK_CompleteDtorPointer; 2037 2038 const CXXDestructorDecl *DD = Component.getDestructorDecl(); 2039 2040 DD->printQualifiedName(Out); 2041 if (IsComplete) 2042 Out << "() [complete]"; 2043 else 2044 Out << "() [deleting]"; 2045 2046 if (DD->isPure()) 2047 Out << " [pure]"; 2048 2049 ThunkInfo Thunk = VTableThunks.lookup(I); 2050 if (!Thunk.isEmpty()) { 2051 // If this destructor has a 'this' pointer adjustment, dump it. 2052 if (!Thunk.This.isEmpty()) { 2053 Out << "\n [this adjustment: "; 2054 Out << Thunk.This.NonVirtual << " non-virtual"; 2055 2056 if (Thunk.This.Virtual.Itanium.VCallOffsetOffset) { 2057 Out << ", " << Thunk.This.Virtual.Itanium.VCallOffsetOffset; 2058 Out << " vcall offset offset"; 2059 } 2060 2061 Out << ']'; 2062 } 2063 } 2064 2065 break; 2066 } 2067 2068 case VTableComponent::CK_UnusedFunctionPointer: { 2069 const CXXMethodDecl *MD = Component.getUnusedFunctionDecl(); 2070 2071 std::string Str = 2072 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2073 MD); 2074 Out << "[unused] " << Str; 2075 if (MD->isPure()) 2076 Out << " [pure]"; 2077 } 2078 2079 } 2080 2081 Out << '\n'; 2082 2083 // Dump the next address point. 2084 uint64_t NextIndex = Index + 1; 2085 if (AddressPointsByIndex.count(NextIndex)) { 2086 if (AddressPointsByIndex.count(NextIndex) == 1) { 2087 const BaseSubobject &Base = 2088 AddressPointsByIndex.find(NextIndex)->second; 2089 2090 Out << " -- ("; 2091 Base.getBase()->printQualifiedName(Out); 2092 Out << ", " << Base.getBaseOffset().getQuantity(); 2093 Out << ") vtable address --\n"; 2094 } else { 2095 CharUnits BaseOffset = 2096 AddressPointsByIndex.lower_bound(NextIndex)->second.getBaseOffset(); 2097 2098 // We store the class names in a set to get a stable order. 2099 std::set<std::string> ClassNames; 2100 for (std::multimap<uint64_t, BaseSubobject>::const_iterator I = 2101 AddressPointsByIndex.lower_bound(NextIndex), E = 2102 AddressPointsByIndex.upper_bound(NextIndex); I != E; ++I) { 2103 assert(I->second.getBaseOffset() == BaseOffset && 2104 "Invalid base offset!"); 2105 const CXXRecordDecl *RD = I->second.getBase(); 2106 ClassNames.insert(RD->getQualifiedNameAsString()); 2107 } 2108 2109 for (std::set<std::string>::const_iterator I = ClassNames.begin(), 2110 E = ClassNames.end(); I != E; ++I) { 2111 Out << " -- (" << *I; 2112 Out << ", " << BaseOffset.getQuantity() << ") vtable address --\n"; 2113 } 2114 } 2115 } 2116 } 2117 2118 Out << '\n'; 2119 2120 if (isBuildingConstructorVTable()) 2121 return; 2122 2123 if (MostDerivedClass->getNumVBases()) { 2124 // We store the virtual base class names and their offsets in a map to get 2125 // a stable order. 2126 2127 std::map<std::string, CharUnits> ClassNamesAndOffsets; 2128 for (VBaseOffsetOffsetsMapTy::const_iterator I = VBaseOffsetOffsets.begin(), 2129 E = VBaseOffsetOffsets.end(); I != E; ++I) { 2130 std::string ClassName = I->first->getQualifiedNameAsString(); 2131 CharUnits OffsetOffset = I->second; 2132 ClassNamesAndOffsets.insert( 2133 std::make_pair(ClassName, OffsetOffset)); 2134 } 2135 2136 Out << "Virtual base offset offsets for '"; 2137 MostDerivedClass->printQualifiedName(Out); 2138 Out << "' ("; 2139 Out << ClassNamesAndOffsets.size(); 2140 Out << (ClassNamesAndOffsets.size() == 1 ? " entry" : " entries") << ").\n"; 2141 2142 for (std::map<std::string, CharUnits>::const_iterator I = 2143 ClassNamesAndOffsets.begin(), E = ClassNamesAndOffsets.end(); 2144 I != E; ++I) 2145 Out << " " << I->first << " | " << I->second.getQuantity() << '\n'; 2146 2147 Out << "\n"; 2148 } 2149 2150 if (!Thunks.empty()) { 2151 // We store the method names in a map to get a stable order. 2152 std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls; 2153 2154 for (ThunksMapTy::const_iterator I = Thunks.begin(), E = Thunks.end(); 2155 I != E; ++I) { 2156 const CXXMethodDecl *MD = I->first; 2157 std::string MethodName = 2158 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2159 MD); 2160 2161 MethodNamesAndDecls.insert(std::make_pair(MethodName, MD)); 2162 } 2163 2164 for (std::map<std::string, const CXXMethodDecl *>::const_iterator I = 2165 MethodNamesAndDecls.begin(), E = MethodNamesAndDecls.end(); 2166 I != E; ++I) { 2167 const std::string &MethodName = I->first; 2168 const CXXMethodDecl *MD = I->second; 2169 2170 ThunkInfoVectorTy ThunksVector = Thunks[MD]; 2171 std::sort(ThunksVector.begin(), ThunksVector.end(), 2172 ItaniumThunkInfoComparator()); 2173 2174 Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size(); 2175 Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n"; 2176 2177 for (unsigned I = 0, E = ThunksVector.size(); I != E; ++I) { 2178 const ThunkInfo &Thunk = ThunksVector[I]; 2179 2180 Out << llvm::format("%4d | ", I); 2181 2182 // If this function pointer has a return pointer adjustment, dump it. 2183 if (!Thunk.Return.isEmpty()) { 2184 Out << "return adjustment: " << Thunk.Return.NonVirtual; 2185 Out << " non-virtual"; 2186 if (Thunk.Return.Virtual.Itanium.VBaseOffsetOffset) { 2187 Out << ", " << Thunk.Return.Virtual.Itanium.VBaseOffsetOffset; 2188 Out << " vbase offset offset"; 2189 } 2190 2191 if (!Thunk.This.isEmpty()) 2192 Out << "\n "; 2193 } 2194 2195 // If this function pointer has a 'this' pointer adjustment, dump it. 2196 if (!Thunk.This.isEmpty()) { 2197 Out << "this adjustment: "; 2198 Out << Thunk.This.NonVirtual << " non-virtual"; 2199 2200 if (Thunk.This.Virtual.Itanium.VCallOffsetOffset) { 2201 Out << ", " << Thunk.This.Virtual.Itanium.VCallOffsetOffset; 2202 Out << " vcall offset offset"; 2203 } 2204 } 2205 2206 Out << '\n'; 2207 } 2208 2209 Out << '\n'; 2210 } 2211 } 2212 2213 // Compute the vtable indices for all the member functions. 2214 // Store them in a map keyed by the index so we'll get a sorted table. 2215 std::map<uint64_t, std::string> IndicesMap; 2216 2217 for (CXXRecordDecl::method_iterator i = MostDerivedClass->method_begin(), 2218 e = MostDerivedClass->method_end(); i != e; ++i) { 2219 const CXXMethodDecl *MD = *i; 2220 2221 // We only want virtual member functions. 2222 if (!MD->isVirtual()) 2223 continue; 2224 2225 std::string MethodName = 2226 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2227 MD); 2228 2229 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 2230 GlobalDecl GD(DD, Dtor_Complete); 2231 assert(MethodVTableIndices.count(GD)); 2232 uint64_t VTableIndex = MethodVTableIndices[GD]; 2233 IndicesMap[VTableIndex] = MethodName + " [complete]"; 2234 IndicesMap[VTableIndex + 1] = MethodName + " [deleting]"; 2235 } else { 2236 assert(MethodVTableIndices.count(MD)); 2237 IndicesMap[MethodVTableIndices[MD]] = MethodName; 2238 } 2239 } 2240 2241 // Print the vtable indices for all the member functions. 2242 if (!IndicesMap.empty()) { 2243 Out << "VTable indices for '"; 2244 MostDerivedClass->printQualifiedName(Out); 2245 Out << "' (" << IndicesMap.size() << " entries).\n"; 2246 2247 for (std::map<uint64_t, std::string>::const_iterator I = IndicesMap.begin(), 2248 E = IndicesMap.end(); I != E; ++I) { 2249 uint64_t VTableIndex = I->first; 2250 const std::string &MethodName = I->second; 2251 2252 Out << llvm::format("%4" PRIu64 " | ", VTableIndex) << MethodName 2253 << '\n'; 2254 } 2255 } 2256 2257 Out << '\n'; 2258 } 2259 2260 struct VTableThunksComparator { 2261 bool operator()(const VTableLayout::VTableThunkTy &LHS, 2262 const VTableLayout::VTableThunkTy &RHS) { 2263 if (LHS.first == RHS.first) { 2264 assert(LHS.second == RHS.second && 2265 "Different thunks should have unique indices!"); 2266 } 2267 return LHS.first < RHS.first; 2268 } 2269 }; 2270 } 2271 2272 VTableLayout::VTableLayout(uint64_t NumVTableComponents, 2273 const VTableComponent *VTableComponents, 2274 uint64_t NumVTableThunks, 2275 const VTableThunkTy *VTableThunks, 2276 const AddressPointsMapTy &AddressPoints, 2277 bool IsMicrosoftABI) 2278 : NumVTableComponents(NumVTableComponents), 2279 VTableComponents(new VTableComponent[NumVTableComponents]), 2280 NumVTableThunks(NumVTableThunks), 2281 VTableThunks(new VTableThunkTy[NumVTableThunks]), 2282 AddressPoints(AddressPoints), 2283 IsMicrosoftABI(IsMicrosoftABI) { 2284 std::copy(VTableComponents, VTableComponents+NumVTableComponents, 2285 this->VTableComponents.get()); 2286 std::copy(VTableThunks, VTableThunks+NumVTableThunks, 2287 this->VTableThunks.get()); 2288 std::sort(this->VTableThunks.get(), 2289 this->VTableThunks.get() + NumVTableThunks, 2290 VTableThunksComparator()); 2291 } 2292 2293 VTableLayout::~VTableLayout() { } 2294 2295 ItaniumVTableContext::ItaniumVTableContext(ASTContext &Context) 2296 : VTableContextBase(/*MS=*/false) {} 2297 2298 ItaniumVTableContext::~ItaniumVTableContext() { 2299 llvm::DeleteContainerSeconds(VTableLayouts); 2300 } 2301 2302 uint64_t ItaniumVTableContext::getMethodVTableIndex(GlobalDecl GD) { 2303 MethodVTableIndicesTy::iterator I = MethodVTableIndices.find(GD); 2304 if (I != MethodVTableIndices.end()) 2305 return I->second; 2306 2307 const CXXRecordDecl *RD = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 2308 2309 computeVTableRelatedInformation(RD); 2310 2311 I = MethodVTableIndices.find(GD); 2312 assert(I != MethodVTableIndices.end() && "Did not find index!"); 2313 return I->second; 2314 } 2315 2316 CharUnits 2317 ItaniumVTableContext::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, 2318 const CXXRecordDecl *VBase) { 2319 ClassPairTy ClassPair(RD, VBase); 2320 2321 VirtualBaseClassOffsetOffsetsMapTy::iterator I = 2322 VirtualBaseClassOffsetOffsets.find(ClassPair); 2323 if (I != VirtualBaseClassOffsetOffsets.end()) 2324 return I->second; 2325 2326 VCallAndVBaseOffsetBuilder Builder(RD, RD, /*FinalOverriders=*/0, 2327 BaseSubobject(RD, CharUnits::Zero()), 2328 /*BaseIsVirtual=*/false, 2329 /*OffsetInLayoutClass=*/CharUnits::Zero()); 2330 2331 for (VCallAndVBaseOffsetBuilder::VBaseOffsetOffsetsMapTy::const_iterator I = 2332 Builder.getVBaseOffsetOffsets().begin(), 2333 E = Builder.getVBaseOffsetOffsets().end(); I != E; ++I) { 2334 // Insert all types. 2335 ClassPairTy ClassPair(RD, I->first); 2336 2337 VirtualBaseClassOffsetOffsets.insert( 2338 std::make_pair(ClassPair, I->second)); 2339 } 2340 2341 I = VirtualBaseClassOffsetOffsets.find(ClassPair); 2342 assert(I != VirtualBaseClassOffsetOffsets.end() && "Did not find index!"); 2343 2344 return I->second; 2345 } 2346 2347 static VTableLayout *CreateVTableLayout(const ItaniumVTableBuilder &Builder) { 2348 SmallVector<VTableLayout::VTableThunkTy, 1> 2349 VTableThunks(Builder.vtable_thunks_begin(), Builder.vtable_thunks_end()); 2350 2351 return new VTableLayout(Builder.getNumVTableComponents(), 2352 Builder.vtable_component_begin(), 2353 VTableThunks.size(), 2354 VTableThunks.data(), 2355 Builder.getAddressPoints(), 2356 /*IsMicrosoftABI=*/false); 2357 } 2358 2359 void 2360 ItaniumVTableContext::computeVTableRelatedInformation(const CXXRecordDecl *RD) { 2361 const VTableLayout *&Entry = VTableLayouts[RD]; 2362 2363 // Check if we've computed this information before. 2364 if (Entry) 2365 return; 2366 2367 ItaniumVTableBuilder Builder(*this, RD, CharUnits::Zero(), 2368 /*MostDerivedClassIsVirtual=*/0, RD); 2369 Entry = CreateVTableLayout(Builder); 2370 2371 MethodVTableIndices.insert(Builder.vtable_indices_begin(), 2372 Builder.vtable_indices_end()); 2373 2374 // Add the known thunks. 2375 Thunks.insert(Builder.thunks_begin(), Builder.thunks_end()); 2376 2377 // If we don't have the vbase information for this class, insert it. 2378 // getVirtualBaseOffsetOffset will compute it separately without computing 2379 // the rest of the vtable related information. 2380 if (!RD->getNumVBases()) 2381 return; 2382 2383 const CXXRecordDecl *VBase = 2384 RD->vbases_begin()->getType()->getAsCXXRecordDecl(); 2385 2386 if (VirtualBaseClassOffsetOffsets.count(std::make_pair(RD, VBase))) 2387 return; 2388 2389 for (ItaniumVTableBuilder::VBaseOffsetOffsetsMapTy::const_iterator 2390 I = Builder.getVBaseOffsetOffsets().begin(), 2391 E = Builder.getVBaseOffsetOffsets().end(); 2392 I != E; ++I) { 2393 // Insert all types. 2394 ClassPairTy ClassPair(RD, I->first); 2395 2396 VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I->second)); 2397 } 2398 } 2399 2400 VTableLayout *ItaniumVTableContext::createConstructionVTableLayout( 2401 const CXXRecordDecl *MostDerivedClass, CharUnits MostDerivedClassOffset, 2402 bool MostDerivedClassIsVirtual, const CXXRecordDecl *LayoutClass) { 2403 ItaniumVTableBuilder Builder(*this, MostDerivedClass, MostDerivedClassOffset, 2404 MostDerivedClassIsVirtual, LayoutClass); 2405 return CreateVTableLayout(Builder); 2406 } 2407 2408 namespace { 2409 2410 // Vtables in the Microsoft ABI are different from the Itanium ABI. 2411 // 2412 // The main differences are: 2413 // 1. Separate vftable and vbtable. 2414 // 2415 // 2. Each subobject with a vfptr gets its own vftable rather than an address 2416 // point in a single vtable shared between all the subobjects. 2417 // Each vftable is represented by a separate section and virtual calls 2418 // must be done using the vftable which has a slot for the function to be 2419 // called. 2420 // 2421 // 3. Virtual method definitions expect their 'this' parameter to point to the 2422 // first vfptr whose table provides a compatible overridden method. In many 2423 // cases, this permits the original vf-table entry to directly call 2424 // the method instead of passing through a thunk. 2425 // 2426 // A compatible overridden method is one which does not have a non-trivial 2427 // covariant-return adjustment. 2428 // 2429 // The first vfptr is the one with the lowest offset in the complete-object 2430 // layout of the defining class, and the method definition will subtract 2431 // that constant offset from the parameter value to get the real 'this' 2432 // value. Therefore, if the offset isn't really constant (e.g. if a virtual 2433 // function defined in a virtual base is overridden in a more derived 2434 // virtual base and these bases have a reverse order in the complete 2435 // object), the vf-table may require a this-adjustment thunk. 2436 // 2437 // 4. vftables do not contain new entries for overrides that merely require 2438 // this-adjustment. Together with #3, this keeps vf-tables smaller and 2439 // eliminates the need for this-adjustment thunks in many cases, at the cost 2440 // of often requiring redundant work to adjust the "this" pointer. 2441 // 2442 // 5. Instead of VTT and constructor vtables, vbtables and vtordisps are used. 2443 // Vtordisps are emitted into the class layout if a class has 2444 // a) a user-defined ctor/dtor 2445 // and 2446 // b) a method overriding a method in a virtual base. 2447 2448 class VFTableBuilder { 2449 public: 2450 typedef MicrosoftVTableContext::MethodVFTableLocation MethodVFTableLocation; 2451 2452 typedef llvm::DenseMap<GlobalDecl, MethodVFTableLocation> 2453 MethodVFTableLocationsTy; 2454 2455 private: 2456 /// VTables - Global vtable information. 2457 MicrosoftVTableContext &VTables; 2458 2459 /// Context - The ASTContext which we will use for layout information. 2460 ASTContext &Context; 2461 2462 /// MostDerivedClass - The most derived class for which we're building this 2463 /// vtable. 2464 const CXXRecordDecl *MostDerivedClass; 2465 2466 const ASTRecordLayout &MostDerivedClassLayout; 2467 2468 VFPtrInfo WhichVFPtr; 2469 2470 /// FinalOverriders - The final overriders of the most derived class. 2471 const FinalOverriders Overriders; 2472 2473 /// Components - The components of the vftable being built. 2474 SmallVector<VTableComponent, 64> Components; 2475 2476 MethodVFTableLocationsTy MethodVFTableLocations; 2477 2478 /// MethodInfo - Contains information about a method in a vtable. 2479 /// (Used for computing 'this' pointer adjustment thunks. 2480 struct MethodInfo { 2481 /// VBTableIndex - The nonzero index in the vbtable that 2482 /// this method's base has, or zero. 2483 const uint64_t VBTableIndex; 2484 2485 /// VFTableIndex - The index in the vftable that this method has. 2486 const uint64_t VFTableIndex; 2487 2488 /// Shadowed - Indicates if this vftable slot is shadowed by 2489 /// a slot for a covariant-return override. If so, it shouldn't be printed 2490 /// or used for vcalls in the most derived class. 2491 bool Shadowed; 2492 2493 MethodInfo(uint64_t VBTableIndex, uint64_t VFTableIndex) 2494 : VBTableIndex(VBTableIndex), VFTableIndex(VFTableIndex), 2495 Shadowed(false) {} 2496 2497 MethodInfo() : VBTableIndex(0), VFTableIndex(0), Shadowed(false) {} 2498 }; 2499 2500 typedef llvm::DenseMap<const CXXMethodDecl *, MethodInfo> MethodInfoMapTy; 2501 2502 /// MethodInfoMap - The information for all methods in the vftable we're 2503 /// currently building. 2504 MethodInfoMapTy MethodInfoMap; 2505 2506 typedef llvm::DenseMap<uint64_t, ThunkInfo> VTableThunksMapTy; 2507 2508 /// VTableThunks - The thunks by vftable index in the vftable currently being 2509 /// built. 2510 VTableThunksMapTy VTableThunks; 2511 2512 typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; 2513 typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy; 2514 2515 /// Thunks - A map that contains all the thunks needed for all methods in the 2516 /// most derived class for which the vftable is currently being built. 2517 ThunksMapTy Thunks; 2518 2519 /// AddThunk - Add a thunk for the given method. 2520 void AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk) { 2521 SmallVector<ThunkInfo, 1> &ThunksVector = Thunks[MD]; 2522 2523 // Check if we have this thunk already. 2524 if (std::find(ThunksVector.begin(), ThunksVector.end(), Thunk) != 2525 ThunksVector.end()) 2526 return; 2527 2528 ThunksVector.push_back(Thunk); 2529 } 2530 2531 /// ComputeThisOffset - Returns the 'this' argument offset for the given 2532 /// method in the given subobject, relative to the beginning of the 2533 /// MostDerivedClass. 2534 CharUnits ComputeThisOffset(const CXXMethodDecl *MD, 2535 BaseSubobject Base, 2536 FinalOverriders::OverriderInfo Overrider); 2537 2538 void CalculateVtordispAdjustment(FinalOverriders::OverriderInfo Overrider, 2539 CharUnits ThisOffset, ThisAdjustment &TA); 2540 2541 /// AddMethod - Add a single virtual member function to the vftable 2542 /// components vector. 2543 void AddMethod(const CXXMethodDecl *MD, ThunkInfo TI) { 2544 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 2545 assert(TI.Return.isEmpty() && 2546 "Destructor can't have return adjustment!"); 2547 Components.push_back(VTableComponent::MakeDeletingDtor(DD)); 2548 } else { 2549 if (!TI.isEmpty()) 2550 VTableThunks[Components.size()] = TI; 2551 Components.push_back(VTableComponent::MakeFunction(MD)); 2552 } 2553 } 2554 2555 bool NeedsReturnAdjustingThunk(const CXXMethodDecl *MD); 2556 2557 /// AddMethods - Add the methods of this base subobject and the relevant 2558 /// subbases to the vftable we're currently laying out. 2559 void AddMethods(BaseSubobject Base, unsigned BaseDepth, 2560 const CXXRecordDecl *LastVBase, 2561 BasesSetVectorTy &VisitedBases); 2562 2563 void LayoutVFTable() { 2564 // FIXME: add support for RTTI when we have proper LLVM support for symbols 2565 // pointing to the middle of a section. 2566 2567 BasesSetVectorTy VisitedBases; 2568 AddMethods(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 0, 0, 2569 VisitedBases); 2570 2571 assert(MethodVFTableLocations.empty()); 2572 for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(), 2573 E = MethodInfoMap.end(); I != E; ++I) { 2574 const CXXMethodDecl *MD = I->first; 2575 const MethodInfo &MI = I->second; 2576 // Skip the methods that the MostDerivedClass didn't override 2577 // and the entries shadowed by return adjusting thunks. 2578 if (MD->getParent() != MostDerivedClass || MI.Shadowed) 2579 continue; 2580 MethodVFTableLocation Loc(MI.VBTableIndex, WhichVFPtr.LastVBase, 2581 WhichVFPtr.VFPtrOffset, MI.VFTableIndex); 2582 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 2583 MethodVFTableLocations[GlobalDecl(DD, Dtor_Deleting)] = Loc; 2584 } else { 2585 MethodVFTableLocations[MD] = Loc; 2586 } 2587 } 2588 } 2589 2590 void ErrorUnsupported(StringRef Feature, SourceLocation Location) { 2591 clang::DiagnosticsEngine &Diags = Context.getDiagnostics(); 2592 unsigned DiagID = Diags.getCustomDiagID( 2593 DiagnosticsEngine::Error, "v-table layout for %0 is not supported yet"); 2594 Diags.Report(Context.getFullLoc(Location), DiagID) << Feature; 2595 } 2596 2597 public: 2598 VFTableBuilder(MicrosoftVTableContext &VTables, 2599 const CXXRecordDecl *MostDerivedClass, VFPtrInfo Which) 2600 : VTables(VTables), 2601 Context(MostDerivedClass->getASTContext()), 2602 MostDerivedClass(MostDerivedClass), 2603 MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)), 2604 WhichVFPtr(Which), 2605 Overriders(MostDerivedClass, CharUnits(), MostDerivedClass) { 2606 LayoutVFTable(); 2607 2608 if (Context.getLangOpts().DumpVTableLayouts) 2609 dumpLayout(llvm::outs()); 2610 } 2611 2612 uint64_t getNumThunks() const { return Thunks.size(); } 2613 2614 ThunksMapTy::const_iterator thunks_begin() const { return Thunks.begin(); } 2615 2616 ThunksMapTy::const_iterator thunks_end() const { return Thunks.end(); } 2617 2618 MethodVFTableLocationsTy::const_iterator vtable_indices_begin() const { 2619 return MethodVFTableLocations.begin(); 2620 } 2621 2622 MethodVFTableLocationsTy::const_iterator vtable_indices_end() const { 2623 return MethodVFTableLocations.end(); 2624 } 2625 2626 uint64_t getNumVTableComponents() const { return Components.size(); } 2627 2628 const VTableComponent *vtable_component_begin() const { 2629 return Components.begin(); 2630 } 2631 2632 const VTableComponent *vtable_component_end() const { 2633 return Components.end(); 2634 } 2635 2636 VTableThunksMapTy::const_iterator vtable_thunks_begin() const { 2637 return VTableThunks.begin(); 2638 } 2639 2640 VTableThunksMapTy::const_iterator vtable_thunks_end() const { 2641 return VTableThunks.end(); 2642 } 2643 2644 void dumpLayout(raw_ostream &); 2645 }; 2646 2647 } // end namespace 2648 2649 /// InitialOverriddenDefinitionCollector - Finds the set of least derived bases 2650 /// that define the given method. 2651 struct InitialOverriddenDefinitionCollector { 2652 BasesSetVectorTy Bases; 2653 OverriddenMethodsSetTy VisitedOverriddenMethods; 2654 2655 bool visit(const CXXMethodDecl *OverriddenMD) { 2656 if (OverriddenMD->size_overridden_methods() == 0) 2657 Bases.insert(OverriddenMD->getParent()); 2658 // Don't recurse on this method if we've already collected it. 2659 return VisitedOverriddenMethods.insert(OverriddenMD); 2660 } 2661 }; 2662 2663 static bool BaseInSet(const CXXBaseSpecifier *Specifier, 2664 CXXBasePath &Path, void *BasesSet) { 2665 BasesSetVectorTy *Bases = (BasesSetVectorTy *)BasesSet; 2666 return Bases->count(Specifier->getType()->getAsCXXRecordDecl()); 2667 } 2668 2669 CharUnits 2670 VFTableBuilder::ComputeThisOffset(const CXXMethodDecl *MD, 2671 BaseSubobject Base, 2672 FinalOverriders::OverriderInfo Overrider) { 2673 InitialOverriddenDefinitionCollector Collector; 2674 visitAllOverriddenMethods(MD, Collector); 2675 2676 CXXBasePaths Paths; 2677 Base.getBase()->lookupInBases(BaseInSet, &Collector.Bases, Paths); 2678 2679 // This will hold the smallest this offset among overridees of MD. 2680 // This implies that an offset of a non-virtual base will dominate an offset 2681 // of a virtual base to potentially reduce the number of thunks required 2682 // in the derived classes that inherit this method. 2683 CharUnits Ret; 2684 bool First = true; 2685 2686 for (CXXBasePaths::paths_iterator I = Paths.begin(), E = Paths.end(); 2687 I != E; ++I) { 2688 const CXXBasePath &Path = (*I); 2689 CharUnits ThisOffset = Base.getBaseOffset(); 2690 CharUnits LastVBaseOffset; 2691 2692 // For each path from the overrider to the parents of the overridden methods, 2693 // traverse the path, calculating the this offset in the most derived class. 2694 for (int J = 0, F = Path.size(); J != F; ++J) { 2695 const CXXBasePathElement &Element = Path[J]; 2696 QualType CurTy = Element.Base->getType(); 2697 const CXXRecordDecl *PrevRD = Element.Class, 2698 *CurRD = CurTy->getAsCXXRecordDecl(); 2699 const ASTRecordLayout &Layout = Context.getASTRecordLayout(PrevRD); 2700 2701 if (Element.Base->isVirtual()) { 2702 LastVBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(CurRD); 2703 if (Overrider.Method->getParent() == PrevRD) { 2704 // This one's interesting. If the final overrider is in a vbase B of the 2705 // most derived class and it overrides a method of the B's own vbase A, 2706 // it uses A* as "this". In its prologue, it can cast A* to B* with 2707 // a static offset. This offset is used regardless of the actual 2708 // offset of A from B in the most derived class, requiring an 2709 // this-adjusting thunk in the vftable if A and B are laid out 2710 // differently in the most derived class. 2711 ThisOffset += Layout.getVBaseClassOffset(CurRD); 2712 } else { 2713 ThisOffset = LastVBaseOffset; 2714 } 2715 } else { 2716 ThisOffset += Layout.getBaseClassOffset(CurRD); 2717 } 2718 } 2719 2720 if (isa<CXXDestructorDecl>(MD)) { 2721 if (LastVBaseOffset.isZero()) { 2722 // If a "Base" class has at least one non-virtual base with a virtual 2723 // destructor, the "Base" virtual destructor will take the address 2724 // of the "Base" subobject as the "this" argument. 2725 return Base.getBaseOffset(); 2726 } else { 2727 // A virtual destructor of a virtual base takes the address of the 2728 // virtual base subobject as the "this" argument. 2729 return LastVBaseOffset; 2730 } 2731 } 2732 2733 if (Ret > ThisOffset || First) { 2734 First = false; 2735 Ret = ThisOffset; 2736 } 2737 } 2738 2739 assert(!First && "Method not found in the given subobject?"); 2740 return Ret; 2741 } 2742 2743 void VFTableBuilder::CalculateVtordispAdjustment( 2744 FinalOverriders::OverriderInfo Overrider, CharUnits ThisOffset, 2745 ThisAdjustment &TA) { 2746 const ASTRecordLayout::VBaseOffsetsMapTy &VBaseMap = 2747 MostDerivedClassLayout.getVBaseOffsetsMap(); 2748 const ASTRecordLayout::VBaseOffsetsMapTy::const_iterator &VBaseMapEntry = 2749 VBaseMap.find(WhichVFPtr.LastVBase); 2750 assert(VBaseMapEntry != VBaseMap.end()); 2751 2752 // Check if we need a vtordisp adjustment at all. 2753 if (!VBaseMapEntry->second.hasVtorDisp()) 2754 return; 2755 2756 CharUnits VFPtrVBaseOffset = VBaseMapEntry->second.VBaseOffset; 2757 // The implicit vtordisp field is located right before the vbase. 2758 TA.Virtual.Microsoft.VtordispOffset = 2759 (VFPtrVBaseOffset - WhichVFPtr.VFPtrFullOffset).getQuantity() - 4; 2760 2761 // If the final overrider is defined in either: 2762 // - the most derived class or its non-virtual base or 2763 // - the same vbase as the initial declaration, 2764 // a simple vtordisp thunk will suffice. 2765 const CXXRecordDecl *OverriderRD = Overrider.Method->getParent(); 2766 if (OverriderRD == MostDerivedClass) 2767 return; 2768 2769 const CXXRecordDecl *OverriderVBase = 2770 ComputeBaseOffset(Context, OverriderRD, MostDerivedClass).VirtualBase; 2771 if (!OverriderVBase || OverriderVBase == WhichVFPtr.LastVBase) 2772 return; 2773 2774 // Otherwise, we need to do use the dynamic offset of the final overrider 2775 // in order to get "this" adjustment right. 2776 TA.Virtual.Microsoft.VBPtrOffset = 2777 (VFPtrVBaseOffset + WhichVFPtr.VFPtrOffset - 2778 MostDerivedClassLayout.getVBPtrOffset()).getQuantity(); 2779 TA.Virtual.Microsoft.VBOffsetOffset = 2780 Context.getTypeSizeInChars(Context.IntTy).getQuantity() * 2781 VTables.getVBTableIndex(MostDerivedClass, OverriderVBase); 2782 2783 TA.NonVirtual = (ThisOffset - Overrider.Offset).getQuantity(); 2784 } 2785 2786 static void GroupNewVirtualOverloads( 2787 const CXXRecordDecl *RD, 2788 SmallVector<const CXXMethodDecl *, 10> &VirtualMethods) { 2789 // Put the virtual methods into VirtualMethods in the proper order: 2790 // 1) Group overloads by declaration name. New groups are added to the 2791 // vftable in the order of their first declarations in this class 2792 // (including overrides). 2793 // 2) In each group, new overloads appear in the reverse order of declaration. 2794 typedef SmallVector<const CXXMethodDecl *, 1> MethodGroup; 2795 SmallVector<MethodGroup, 10> Groups; 2796 typedef llvm::DenseMap<DeclarationName, unsigned> VisitedGroupIndicesTy; 2797 VisitedGroupIndicesTy VisitedGroupIndices; 2798 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 2799 E = RD->method_end(); I != E; ++I) { 2800 const CXXMethodDecl *MD = *I; 2801 if (!MD->isVirtual()) 2802 continue; 2803 2804 VisitedGroupIndicesTy::iterator J; 2805 bool Inserted; 2806 llvm::tie(J, Inserted) = VisitedGroupIndices.insert( 2807 std::make_pair(MD->getDeclName(), Groups.size())); 2808 if (Inserted) 2809 Groups.push_back(MethodGroup(1, MD)); 2810 else 2811 Groups[J->second].push_back(MD); 2812 } 2813 2814 for (unsigned I = 0, E = Groups.size(); I != E; ++I) 2815 VirtualMethods.append(Groups[I].rbegin(), Groups[I].rend()); 2816 } 2817 2818 /// We need a return adjusting thunk for this method if its return type is 2819 /// not trivially convertible to the return type of any of its overridden 2820 /// methods. 2821 bool VFTableBuilder::NeedsReturnAdjustingThunk(const CXXMethodDecl *MD) { 2822 OverriddenMethodsSetTy OverriddenMethods; 2823 ComputeAllOverriddenMethods(MD, OverriddenMethods); 2824 for (OverriddenMethodsSetTy::iterator I = OverriddenMethods.begin(), 2825 E = OverriddenMethods.end(); 2826 I != E; ++I) { 2827 const CXXMethodDecl *OverriddenMD = *I; 2828 BaseOffset Adjustment = 2829 ComputeReturnAdjustmentBaseOffset(Context, MD, OverriddenMD); 2830 if (!Adjustment.isEmpty()) 2831 return true; 2832 } 2833 return false; 2834 } 2835 2836 void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth, 2837 const CXXRecordDecl *LastVBase, 2838 BasesSetVectorTy &VisitedBases) { 2839 const CXXRecordDecl *RD = Base.getBase(); 2840 if (!RD->isPolymorphic()) 2841 return; 2842 2843 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 2844 2845 // See if this class expands a vftable of the base we look at, which is either 2846 // the one defined by the vfptr base path or the primary base of the current class. 2847 const CXXRecordDecl *NextBase = 0, *NextLastVBase = LastVBase; 2848 CharUnits NextBaseOffset; 2849 if (BaseDepth < WhichVFPtr.PathToBaseWithVFPtr.size()) { 2850 NextBase = WhichVFPtr.PathToBaseWithVFPtr[BaseDepth]; 2851 if (Layout.getVBaseOffsetsMap().count(NextBase)) { 2852 NextLastVBase = NextBase; 2853 NextBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(NextBase); 2854 } else { 2855 NextBaseOffset = 2856 Base.getBaseOffset() + Layout.getBaseClassOffset(NextBase); 2857 } 2858 } else if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 2859 assert(!Layout.isPrimaryBaseVirtual() && 2860 "No primary virtual bases in this ABI"); 2861 NextBase = PrimaryBase; 2862 NextBaseOffset = Base.getBaseOffset(); 2863 } 2864 2865 if (NextBase) { 2866 AddMethods(BaseSubobject(NextBase, NextBaseOffset), BaseDepth + 1, 2867 NextLastVBase, VisitedBases); 2868 if (!VisitedBases.insert(NextBase)) 2869 llvm_unreachable("Found a duplicate primary base!"); 2870 } 2871 2872 SmallVector<const CXXMethodDecl*, 10> VirtualMethods; 2873 // Put virtual methods in the proper order. 2874 GroupNewVirtualOverloads(RD, VirtualMethods); 2875 2876 // Now go through all virtual member functions and add them to the current 2877 // vftable. This is done by 2878 // - replacing overridden methods in their existing slots, as long as they 2879 // don't require return adjustment; calculating This adjustment if needed. 2880 // - adding new slots for methods of the current base not present in any 2881 // sub-bases; 2882 // - adding new slots for methods that require Return adjustment. 2883 // We keep track of the methods visited in the sub-bases in MethodInfoMap. 2884 for (unsigned I = 0, E = VirtualMethods.size(); I != E; ++I) { 2885 const CXXMethodDecl *MD = VirtualMethods[I]; 2886 2887 FinalOverriders::OverriderInfo Overrider = 2888 Overriders.getOverrider(MD, Base.getBaseOffset()); 2889 ThisAdjustment ThisAdjustmentOffset; 2890 bool ForceThunk = false; 2891 2892 // Check if this virtual member function overrides 2893 // a method in one of the visited bases. 2894 if (const CXXMethodDecl *OverriddenMD = 2895 FindNearestOverriddenMethod(MD, VisitedBases)) { 2896 MethodInfoMapTy::iterator OverriddenMDIterator = 2897 MethodInfoMap.find(OverriddenMD); 2898 2899 // If the overridden method went to a different vftable, skip it. 2900 if (OverriddenMDIterator == MethodInfoMap.end()) 2901 continue; 2902 2903 MethodInfo &OverriddenMethodInfo = OverriddenMDIterator->second; 2904 2905 // Create a this-adjusting thunk if needed. 2906 CharUnits TI = ComputeThisOffset(MD, Base, Overrider); 2907 if (TI != WhichVFPtr.VFPtrFullOffset) { 2908 ThisAdjustmentOffset.NonVirtual = 2909 (TI - WhichVFPtr.VFPtrFullOffset).getQuantity(); 2910 } 2911 2912 if (WhichVFPtr.LastVBase) 2913 CalculateVtordispAdjustment(Overrider, TI, ThisAdjustmentOffset); 2914 2915 if (!ThisAdjustmentOffset.isEmpty()) { 2916 VTableThunks[OverriddenMethodInfo.VFTableIndex].This = 2917 ThisAdjustmentOffset; 2918 AddThunk(MD, VTableThunks[OverriddenMethodInfo.VFTableIndex]); 2919 } 2920 2921 if (!NeedsReturnAdjustingThunk(MD)) { 2922 // No return adjustment needed - just replace the overridden method info 2923 // with the current info. 2924 MethodInfo MI(OverriddenMethodInfo.VBTableIndex, 2925 OverriddenMethodInfo.VFTableIndex); 2926 MethodInfoMap.erase(OverriddenMDIterator); 2927 2928 assert(!MethodInfoMap.count(MD) && 2929 "Should not have method info for this method yet!"); 2930 MethodInfoMap.insert(std::make_pair(MD, MI)); 2931 continue; 2932 } 2933 2934 // In case we need a return adjustment, we'll add a new slot for 2935 // the overrider and put a return-adjusting thunk where the overridden 2936 // method was in the vftable. 2937 // For now, just mark the overriden method as shadowed by a new slot. 2938 OverriddenMethodInfo.Shadowed = true; 2939 ForceThunk = true; 2940 2941 // Also apply this adjustment to the shadowed slots. 2942 if (!ThisAdjustmentOffset.isEmpty()) { 2943 // FIXME: this is O(N^2), can be O(N). 2944 const CXXMethodDecl *SubOverride = OverriddenMD; 2945 while ((SubOverride = 2946 FindNearestOverriddenMethod(SubOverride, VisitedBases))) { 2947 MethodInfoMapTy::iterator SubOverrideIterator = 2948 MethodInfoMap.find(SubOverride); 2949 if (SubOverrideIterator == MethodInfoMap.end()) 2950 break; 2951 MethodInfo &SubOverrideMI = SubOverrideIterator->second; 2952 assert(SubOverrideMI.Shadowed); 2953 VTableThunks[SubOverrideMI.VFTableIndex].This = 2954 ThisAdjustmentOffset; 2955 AddThunk(MD, VTableThunks[SubOverrideMI.VFTableIndex]); 2956 } 2957 } 2958 } else if (Base.getBaseOffset() != WhichVFPtr.VFPtrFullOffset || 2959 MD->size_overridden_methods()) { 2960 // Skip methods that don't belong to the vftable of the current class, 2961 // e.g. each method that wasn't seen in any of the visited sub-bases 2962 // but overrides multiple methods of other sub-bases. 2963 continue; 2964 } 2965 2966 // If we got here, MD is a method not seen in any of the sub-bases or 2967 // it requires return adjustment. Insert the method info for this method. 2968 unsigned VBIndex = 2969 LastVBase ? VTables.getVBTableIndex(MostDerivedClass, LastVBase) : 0; 2970 MethodInfo MI(VBIndex, Components.size()); 2971 2972 assert(!MethodInfoMap.count(MD) && 2973 "Should not have method info for this method yet!"); 2974 MethodInfoMap.insert(std::make_pair(MD, MI)); 2975 2976 const CXXMethodDecl *OverriderMD = Overrider.Method; 2977 2978 // Check if this overrider needs a return adjustment. 2979 // We don't want to do this for pure virtual member functions. 2980 BaseOffset ReturnAdjustmentOffset; 2981 ReturnAdjustment ReturnAdjustment; 2982 if (!OverriderMD->isPure()) { 2983 ReturnAdjustmentOffset = 2984 ComputeReturnAdjustmentBaseOffset(Context, OverriderMD, MD); 2985 } 2986 if (!ReturnAdjustmentOffset.isEmpty()) { 2987 ForceThunk = true; 2988 ReturnAdjustment.NonVirtual = 2989 ReturnAdjustmentOffset.NonVirtualOffset.getQuantity(); 2990 if (ReturnAdjustmentOffset.VirtualBase) { 2991 const ASTRecordLayout &DerivedLayout = 2992 Context.getASTRecordLayout(ReturnAdjustmentOffset.DerivedClass); 2993 ReturnAdjustment.Virtual.Microsoft.VBPtrOffset = 2994 DerivedLayout.getVBPtrOffset().getQuantity(); 2995 ReturnAdjustment.Virtual.Microsoft.VBIndex = 2996 VTables.getVBTableIndex(ReturnAdjustmentOffset.DerivedClass, 2997 ReturnAdjustmentOffset.VirtualBase); 2998 } 2999 } 3000 3001 AddMethod(OverriderMD, ThunkInfo(ThisAdjustmentOffset, ReturnAdjustment, 3002 ForceThunk ? MD : 0)); 3003 } 3004 } 3005 3006 static void PrintBasePath(const VFPtrInfo::BasePath &Path, raw_ostream &Out) { 3007 for (VFPtrInfo::BasePath::const_reverse_iterator I = Path.rbegin(), 3008 E = Path.rend(); I != E; ++I) { 3009 Out << "'"; 3010 (*I)->printQualifiedName(Out); 3011 Out << "' in "; 3012 } 3013 } 3014 3015 namespace { 3016 struct MicrosoftThunkInfoStableSortComparator { 3017 bool operator() (const ThunkInfo &LHS, const ThunkInfo &RHS) { 3018 if (LHS.This != RHS.This) 3019 return LHS.This < RHS.This; 3020 3021 if (LHS.Return != RHS.Return) 3022 return LHS.Return < RHS.Return; 3023 3024 // Keep different thunks with the same adjustments in the order they 3025 // were put into the vector. 3026 return false; 3027 } 3028 }; 3029 } 3030 3031 static void dumpMicrosoftThunkAdjustment(const ThunkInfo &TI, raw_ostream &Out, 3032 bool ContinueFirstLine) { 3033 const ReturnAdjustment &R = TI.Return; 3034 bool Multiline = false; 3035 const char *LinePrefix = "\n "; 3036 if (!R.isEmpty()) { 3037 if (!ContinueFirstLine) 3038 Out << LinePrefix; 3039 Out << "[return adjustment: "; 3040 if (R.Virtual.Microsoft.VBPtrOffset) 3041 Out << "vbptr at offset " << R.Virtual.Microsoft.VBPtrOffset << ", "; 3042 if (R.Virtual.Microsoft.VBIndex) 3043 Out << "vbase #" << R.Virtual.Microsoft.VBIndex << ", "; 3044 Out << R.NonVirtual << " non-virtual]"; 3045 Multiline = true; 3046 } 3047 3048 const ThisAdjustment &T = TI.This; 3049 if (!T.isEmpty()) { 3050 if (Multiline || !ContinueFirstLine) 3051 Out << LinePrefix; 3052 Out << "[this adjustment: "; 3053 if (!TI.This.Virtual.isEmpty()) { 3054 assert(T.Virtual.Microsoft.VtordispOffset < 0); 3055 Out << "vtordisp at " << T.Virtual.Microsoft.VtordispOffset << ", "; 3056 if (T.Virtual.Microsoft.VBPtrOffset) { 3057 Out << "vbptr at " << T.Virtual.Microsoft.VBPtrOffset 3058 << " to the left, "; 3059 assert(T.Virtual.Microsoft.VBOffsetOffset > 0); 3060 Out << LinePrefix << " vboffset at " 3061 << T.Virtual.Microsoft.VBOffsetOffset << " in the vbtable, "; 3062 } 3063 } 3064 Out << T.NonVirtual << " non-virtual]"; 3065 } 3066 } 3067 3068 void VFTableBuilder::dumpLayout(raw_ostream &Out) { 3069 Out << "VFTable for "; 3070 PrintBasePath(WhichVFPtr.PathToBaseWithVFPtr, Out); 3071 Out << "'"; 3072 MostDerivedClass->printQualifiedName(Out); 3073 Out << "' (" << Components.size() << " entries).\n"; 3074 3075 for (unsigned I = 0, E = Components.size(); I != E; ++I) { 3076 Out << llvm::format("%4d | ", I); 3077 3078 const VTableComponent &Component = Components[I]; 3079 3080 // Dump the component. 3081 switch (Component.getKind()) { 3082 case VTableComponent::CK_RTTI: 3083 Component.getRTTIDecl()->printQualifiedName(Out); 3084 Out << " RTTI"; 3085 break; 3086 3087 case VTableComponent::CK_FunctionPointer: { 3088 const CXXMethodDecl *MD = Component.getFunctionDecl(); 3089 3090 // FIXME: Figure out how to print the real thunk type, since they can 3091 // differ in the return type. 3092 std::string Str = PredefinedExpr::ComputeName( 3093 PredefinedExpr::PrettyFunctionNoVirtual, MD); 3094 Out << Str; 3095 if (MD->isPure()) 3096 Out << " [pure]"; 3097 3098 if (MD->isDeleted()) { 3099 ErrorUnsupported("deleted methods", MD->getLocation()); 3100 Out << " [deleted]"; 3101 } 3102 3103 ThunkInfo Thunk = VTableThunks.lookup(I); 3104 if (!Thunk.isEmpty()) 3105 dumpMicrosoftThunkAdjustment(Thunk, Out, /*ContinueFirstLine=*/false); 3106 3107 break; 3108 } 3109 3110 case VTableComponent::CK_DeletingDtorPointer: { 3111 const CXXDestructorDecl *DD = Component.getDestructorDecl(); 3112 3113 DD->printQualifiedName(Out); 3114 Out << "() [scalar deleting]"; 3115 3116 if (DD->isPure()) 3117 Out << " [pure]"; 3118 3119 ThunkInfo Thunk = VTableThunks.lookup(I); 3120 if (!Thunk.isEmpty()) { 3121 assert(Thunk.Return.isEmpty() && 3122 "No return adjustment needed for destructors!"); 3123 dumpMicrosoftThunkAdjustment(Thunk, Out, /*ContinueFirstLine=*/false); 3124 } 3125 3126 break; 3127 } 3128 3129 default: 3130 DiagnosticsEngine &Diags = Context.getDiagnostics(); 3131 unsigned DiagID = Diags.getCustomDiagID( 3132 DiagnosticsEngine::Error, 3133 "Unexpected vftable component type %0 for component number %1"); 3134 Diags.Report(MostDerivedClass->getLocation(), DiagID) 3135 << I << Component.getKind(); 3136 } 3137 3138 Out << '\n'; 3139 } 3140 3141 Out << '\n'; 3142 3143 if (!Thunks.empty()) { 3144 // We store the method names in a map to get a stable order. 3145 std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls; 3146 3147 for (ThunksMapTy::const_iterator I = Thunks.begin(), E = Thunks.end(); 3148 I != E; ++I) { 3149 const CXXMethodDecl *MD = I->first; 3150 std::string MethodName = PredefinedExpr::ComputeName( 3151 PredefinedExpr::PrettyFunctionNoVirtual, MD); 3152 3153 MethodNamesAndDecls.insert(std::make_pair(MethodName, MD)); 3154 } 3155 3156 for (std::map<std::string, const CXXMethodDecl *>::const_iterator 3157 I = MethodNamesAndDecls.begin(), 3158 E = MethodNamesAndDecls.end(); 3159 I != E; ++I) { 3160 const std::string &MethodName = I->first; 3161 const CXXMethodDecl *MD = I->second; 3162 3163 ThunkInfoVectorTy ThunksVector = Thunks[MD]; 3164 std::stable_sort(ThunksVector.begin(), ThunksVector.end(), 3165 MicrosoftThunkInfoStableSortComparator()); 3166 3167 Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size(); 3168 Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n"; 3169 3170 for (unsigned I = 0, E = ThunksVector.size(); I != E; ++I) { 3171 const ThunkInfo &Thunk = ThunksVector[I]; 3172 3173 Out << llvm::format("%4d | ", I); 3174 dumpMicrosoftThunkAdjustment(Thunk, Out, /*ContinueFirstLine=*/true); 3175 Out << '\n'; 3176 } 3177 3178 Out << '\n'; 3179 } 3180 } 3181 } 3182 3183 static bool setsIntersect(const llvm::SmallPtrSet<const CXXRecordDecl *, 4> &A, 3184 const llvm::ArrayRef<const CXXRecordDecl *> &B) { 3185 for (llvm::ArrayRef<const CXXRecordDecl *>::iterator I = B.begin(), 3186 E = B.end(); 3187 I != E; ++I) { 3188 if (A.count(*I)) 3189 return true; 3190 } 3191 return false; 3192 } 3193 3194 static bool rebucketPaths(VBTableVector &Paths); 3195 3196 /// Produces MSVC-compatible vbtable data. The symbols produced by this 3197 /// algorithm match those produced by MSVC 2012 and newer, which is different 3198 /// from MSVC 2010. 3199 /// 3200 /// MSVC 2012 appears to minimize the vbtable names using the following 3201 /// algorithm. First, walk the class hierarchy in the usual order, depth first, 3202 /// left to right, to find all of the subobjects which contain a vbptr field. 3203 /// Visiting each class node yields a list of inheritance paths to vbptrs. Each 3204 /// record with a vbptr creates an initially empty path. 3205 /// 3206 /// To combine paths from child nodes, the paths are compared to check for 3207 /// ambiguity. Paths are "ambiguous" if multiple paths have the same set of 3208 /// components in the same order. Each group of ambiguous paths is extended by 3209 /// appending the class of the base from which it came. If the current class 3210 /// node produced an ambiguous path, its path is extended with the current class. 3211 /// After extending paths, MSVC again checks for ambiguity, and extends any 3212 /// ambiguous path which wasn't already extended. Because each node yields an 3213 /// unambiguous set of paths, MSVC doesn't need to extend any path more than once 3214 /// to produce an unambiguous set of paths. 3215 /// 3216 /// TODO: Presumably vftables use the same algorithm. 3217 void 3218 MicrosoftVTableContext::computeVBTablePaths(const CXXRecordDecl *RD, 3219 VBTableVector &Paths) { 3220 assert(Paths.empty()); 3221 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 3222 3223 // Base case: this subobject has its own vbptr. 3224 if (Layout.hasOwnVBPtr()) 3225 Paths.push_back(new VBTableInfo(RD)); 3226 3227 // Recursive case: get all the vbtables from our bases and remove anything 3228 // that shares a virtual base. 3229 llvm::SmallPtrSet<const CXXRecordDecl*, 4> VBasesSeen; 3230 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 3231 E = RD->bases_end(); 3232 I != E; ++I) { 3233 const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl(); 3234 if (I->isVirtual() && VBasesSeen.count(Base)) 3235 continue; 3236 3237 const VBTableVector &BasePaths = enumerateVBTables(Base); 3238 3239 for (VBTableVector::const_iterator II = BasePaths.begin(), 3240 EE = BasePaths.end(); 3241 II != EE; ++II) { 3242 VBTableInfo *BasePath = *II; 3243 3244 // Don't include the path if it goes through a virtual base that we've 3245 // already included. 3246 if (setsIntersect(VBasesSeen, BasePath->ContainingVBases)) 3247 continue; 3248 3249 // Copy the path and adjust it as necessary. 3250 VBTableInfo *P = new VBTableInfo(*BasePath); 3251 3252 // We mangle Base into the path if the path would've been ambiguous and it 3253 // wasn't already extended with Base. 3254 if (P->MangledPath.empty() || P->MangledPath.back() != Base) 3255 P->NextBaseToMangle = Base; 3256 3257 // Keep track of which derived class ultimately uses the vbtable, and what 3258 // the full adjustment is from the MDC to this vbtable. The adjustment is 3259 // captured by an optional vbase and a non-virtual offset. 3260 if (Base == Layout.getBaseSharingVBPtr()) 3261 P->ReusingBase = RD; 3262 if (I->isVirtual()) 3263 P->ContainingVBases.push_back(Base); 3264 else if (P->ContainingVBases.empty()) 3265 P->NonVirtualOffset += Layout.getBaseClassOffset(Base); 3266 3267 Paths.push_back(P); 3268 } 3269 3270 // After visiting any direct base, we've transitively visited all of its 3271 // morally virtual bases. 3272 for (CXXRecordDecl::base_class_const_iterator II = Base->vbases_begin(), 3273 EE = Base->vbases_end(); 3274 II != EE; ++II) 3275 VBasesSeen.insert(II->getType()->getAsCXXRecordDecl()); 3276 } 3277 3278 // Sort the paths into buckets, and if any of them are ambiguous, extend all 3279 // paths in ambiguous buckets. 3280 bool Changed = true; 3281 while (Changed) 3282 Changed = rebucketPaths(Paths); 3283 } 3284 3285 static bool pathCompare(const VBTableInfo *LHS, const VBTableInfo *RHS) { 3286 return LHS->MangledPath < RHS->MangledPath; 3287 } 3288 3289 static bool extendPath(VBTableInfo *P) { 3290 if (P->NextBaseToMangle) { 3291 P->MangledPath.push_back(P->NextBaseToMangle); 3292 P->NextBaseToMangle = 0; // Prevent the path from being extended twice. 3293 return true; 3294 } 3295 return false; 3296 } 3297 3298 static bool rebucketPaths(VBTableVector &Paths) { 3299 // What we're essentially doing here is bucketing together ambiguous paths. 3300 // Any bucket with more than one path in it gets extended by NextBase, which 3301 // is usually the direct base of the inherited the vbptr. This code uses a 3302 // sorted vector to implement a multiset to form the buckets. Note that the 3303 // ordering is based on pointers, but it doesn't change our output order. The 3304 // current algorithm is designed to match MSVC 2012's names. 3305 VBTableVector PathsSorted(Paths); 3306 std::sort(PathsSorted.begin(), PathsSorted.end(), pathCompare); 3307 bool Changed = false; 3308 for (size_t I = 0, E = PathsSorted.size(); I != E;) { 3309 // Scan forward to find the end of the bucket. 3310 size_t BucketStart = I; 3311 do { 3312 ++I; 3313 } while (I != E && PathsSorted[BucketStart]->MangledPath == 3314 PathsSorted[I]->MangledPath); 3315 3316 // If this bucket has multiple paths, extend them all. 3317 if (I - BucketStart > 1) { 3318 for (size_t II = BucketStart; II != I; ++II) 3319 Changed |= extendPath(PathsSorted[II]); 3320 assert(Changed && "no paths were extended to fix ambiguity"); 3321 } 3322 } 3323 return Changed; 3324 } 3325 3326 MicrosoftVTableContext::~MicrosoftVTableContext() { 3327 llvm::DeleteContainerSeconds(VFTableLayouts); 3328 llvm::DeleteContainerSeconds(VBaseInfo); 3329 } 3330 3331 void MicrosoftVTableContext::enumerateVFPtrs( 3332 const CXXRecordDecl *MostDerivedClass, 3333 const ASTRecordLayout &MostDerivedClassLayout, BaseSubobject Base, 3334 const CXXRecordDecl *LastVBase, 3335 const VFPtrInfo::BasePath &PathFromCompleteClass, 3336 BasesSetVectorTy &VisitedVBases, 3337 VFPtrListTy &Result) { 3338 const CXXRecordDecl *CurrentClass = Base.getBase(); 3339 CharUnits OffsetInCompleteClass = Base.getBaseOffset(); 3340 const ASTRecordLayout &CurrentClassLayout = 3341 Context.getASTRecordLayout(CurrentClass); 3342 3343 if (CurrentClassLayout.hasOwnVFPtr()) { 3344 if (LastVBase) { 3345 uint64_t VBIndex = getVBTableIndex(MostDerivedClass, LastVBase); 3346 assert(VBIndex > 0 && "vbases must have vbindex!"); 3347 CharUnits VFPtrOffset = 3348 OffsetInCompleteClass - 3349 MostDerivedClassLayout.getVBaseClassOffset(LastVBase); 3350 Result.push_back(VFPtrInfo(VBIndex, LastVBase, VFPtrOffset, 3351 PathFromCompleteClass, OffsetInCompleteClass)); 3352 } else { 3353 Result.push_back(VFPtrInfo(OffsetInCompleteClass, PathFromCompleteClass)); 3354 } 3355 } 3356 3357 for (CXXRecordDecl::base_class_const_iterator I = CurrentClass->bases_begin(), 3358 E = CurrentClass->bases_end(); I != E; ++I) { 3359 const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl(); 3360 3361 CharUnits NextBaseOffset; 3362 const CXXRecordDecl *NextLastVBase; 3363 if (I->isVirtual()) { 3364 if (!VisitedVBases.insert(BaseDecl)) 3365 continue; 3366 NextBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 3367 NextLastVBase = BaseDecl; 3368 } else { 3369 NextBaseOffset = OffsetInCompleteClass + 3370 CurrentClassLayout.getBaseClassOffset(BaseDecl); 3371 NextLastVBase = LastVBase; 3372 } 3373 3374 VFPtrInfo::BasePath NewPath = PathFromCompleteClass; 3375 NewPath.push_back(BaseDecl); 3376 BaseSubobject NextBase(BaseDecl, NextBaseOffset); 3377 3378 enumerateVFPtrs(MostDerivedClass, MostDerivedClassLayout, NextBase, 3379 NextLastVBase, NewPath, VisitedVBases, Result); 3380 } 3381 } 3382 3383 /// CalculatePathToMangle - Calculate the subset of records that should be used 3384 /// to mangle the vftable for the given vfptr. 3385 /// Should only be called if a class has multiple vftables. 3386 static void 3387 CalculatePathToMangle(const CXXRecordDecl *RD, VFPtrInfo &VFPtr) { 3388 // FIXME: In some rare cases this code produces a slightly incorrect mangling. 3389 // It's very likely that the vbtable mangling code can be adjusted to mangle 3390 // both vftables and vbtables correctly. 3391 3392 VFPtrInfo::BasePath &FullPath = VFPtr.PathToBaseWithVFPtr; 3393 if (FullPath.empty()) { 3394 // Mangle the class's own vftable. 3395 assert(RD->getNumVBases() && 3396 "Something's wrong: if the most derived " 3397 "class has more than one vftable, it can only have its own " 3398 "vftable if it has vbases"); 3399 VFPtr.PathToMangle.push_back(RD); 3400 return; 3401 } 3402 3403 unsigned Begin = 0; 3404 3405 // First, skip all the bases before the vbase. 3406 if (VFPtr.LastVBase) { 3407 while (FullPath[Begin] != VFPtr.LastVBase) { 3408 Begin++; 3409 assert(Begin < FullPath.size()); 3410 } 3411 } 3412 3413 // Then, put the rest of the base path in the reverse order. 3414 for (unsigned I = FullPath.size(); I != Begin; --I) { 3415 const CXXRecordDecl *CurBase = FullPath[I - 1], 3416 *ItsBase = (I == 1) ? RD : FullPath[I - 2]; 3417 bool BaseIsVirtual = false; 3418 for (CXXRecordDecl::base_class_const_iterator J = ItsBase->bases_begin(), 3419 F = ItsBase->bases_end(); J != F; ++J) { 3420 if (J->getType()->getAsCXXRecordDecl() == CurBase) { 3421 BaseIsVirtual = J->isVirtual(); 3422 break; 3423 } 3424 } 3425 3426 // Should skip the current base if it is a non-virtual base with no siblings. 3427 if (BaseIsVirtual || ItsBase->getNumBases() != 1) 3428 VFPtr.PathToMangle.push_back(CurBase); 3429 } 3430 } 3431 3432 void MicrosoftVTableContext::enumerateVFPtrs( 3433 const CXXRecordDecl *ForClass, 3434 MicrosoftVTableContext::VFPtrListTy &Result) { 3435 Result.clear(); 3436 const ASTRecordLayout &ClassLayout = Context.getASTRecordLayout(ForClass); 3437 BasesSetVectorTy VisitedVBases; 3438 enumerateVFPtrs(ForClass, ClassLayout, 3439 BaseSubobject(ForClass, CharUnits::Zero()), 0, 3440 VFPtrInfo::BasePath(), VisitedVBases, Result); 3441 if (Result.size() > 1) { 3442 for (unsigned I = 0, E = Result.size(); I != E; ++I) 3443 CalculatePathToMangle(ForClass, Result[I]); 3444 } 3445 } 3446 3447 void MicrosoftVTableContext::computeVTableRelatedInformation( 3448 const CXXRecordDecl *RD) { 3449 assert(RD->isDynamicClass()); 3450 3451 // Check if we've computed this information before. 3452 if (VFPtrLocations.count(RD)) 3453 return; 3454 3455 const VTableLayout::AddressPointsMapTy EmptyAddressPointsMap; 3456 3457 VFPtrListTy &VFPtrs = VFPtrLocations[RD]; 3458 enumerateVFPtrs(RD, VFPtrs); 3459 3460 MethodVFTableLocationsTy NewMethodLocations; 3461 for (VFPtrListTy::iterator I = VFPtrs.begin(), E = VFPtrs.end(); 3462 I != E; ++I) { 3463 VFTableBuilder Builder(*this, RD, *I); 3464 3465 VFTableIdTy id(RD, I->VFPtrFullOffset); 3466 assert(VFTableLayouts.count(id) == 0); 3467 SmallVector<VTableLayout::VTableThunkTy, 1> VTableThunks( 3468 Builder.vtable_thunks_begin(), Builder.vtable_thunks_end()); 3469 VFTableLayouts[id] = new VTableLayout( 3470 Builder.getNumVTableComponents(), Builder.vtable_component_begin(), 3471 VTableThunks.size(), VTableThunks.data(), EmptyAddressPointsMap, true); 3472 NewMethodLocations.insert(Builder.vtable_indices_begin(), 3473 Builder.vtable_indices_end()); 3474 Thunks.insert(Builder.thunks_begin(), Builder.thunks_end()); 3475 } 3476 3477 MethodVFTableLocations.insert(NewMethodLocations.begin(), 3478 NewMethodLocations.end()); 3479 if (Context.getLangOpts().DumpVTableLayouts) 3480 dumpMethodLocations(RD, NewMethodLocations, llvm::outs()); 3481 } 3482 3483 void MicrosoftVTableContext::dumpMethodLocations( 3484 const CXXRecordDecl *RD, const MethodVFTableLocationsTy &NewMethods, 3485 raw_ostream &Out) { 3486 // Compute the vtable indices for all the member functions. 3487 // Store them in a map keyed by the location so we'll get a sorted table. 3488 std::map<MethodVFTableLocation, std::string> IndicesMap; 3489 bool HasNonzeroOffset = false; 3490 3491 for (MethodVFTableLocationsTy::const_iterator I = NewMethods.begin(), 3492 E = NewMethods.end(); I != E; ++I) { 3493 const CXXMethodDecl *MD = cast<const CXXMethodDecl>(I->first.getDecl()); 3494 assert(MD->isVirtual()); 3495 3496 std::string MethodName = PredefinedExpr::ComputeName( 3497 PredefinedExpr::PrettyFunctionNoVirtual, MD); 3498 3499 if (isa<CXXDestructorDecl>(MD)) { 3500 IndicesMap[I->second] = MethodName + " [scalar deleting]"; 3501 } else { 3502 IndicesMap[I->second] = MethodName; 3503 } 3504 3505 if (!I->second.VFPtrOffset.isZero() || I->second.VBTableIndex != 0) 3506 HasNonzeroOffset = true; 3507 } 3508 3509 // Print the vtable indices for all the member functions. 3510 if (!IndicesMap.empty()) { 3511 Out << "VFTable indices for "; 3512 Out << "'"; 3513 RD->printQualifiedName(Out); 3514 Out << "' (" << IndicesMap.size() << " entries).\n"; 3515 3516 CharUnits LastVFPtrOffset = CharUnits::fromQuantity(-1); 3517 uint64_t LastVBIndex = 0; 3518 for (std::map<MethodVFTableLocation, std::string>::const_iterator 3519 I = IndicesMap.begin(), 3520 E = IndicesMap.end(); 3521 I != E; ++I) { 3522 CharUnits VFPtrOffset = I->first.VFPtrOffset; 3523 uint64_t VBIndex = I->first.VBTableIndex; 3524 if (HasNonzeroOffset && 3525 (VFPtrOffset != LastVFPtrOffset || VBIndex != LastVBIndex)) { 3526 assert(VBIndex > LastVBIndex || VFPtrOffset > LastVFPtrOffset); 3527 Out << " -- accessible via "; 3528 if (VBIndex) 3529 Out << "vbtable index " << VBIndex << ", "; 3530 Out << "vfptr at offset " << VFPtrOffset.getQuantity() << " --\n"; 3531 LastVFPtrOffset = VFPtrOffset; 3532 LastVBIndex = VBIndex; 3533 } 3534 3535 uint64_t VTableIndex = I->first.Index; 3536 const std::string &MethodName = I->second; 3537 Out << llvm::format("%4" PRIu64 " | ", VTableIndex) << MethodName << '\n'; 3538 } 3539 Out << '\n'; 3540 } 3541 } 3542 3543 const VirtualBaseInfo *MicrosoftVTableContext::computeVBTableRelatedInformation( 3544 const CXXRecordDecl *RD) { 3545 VirtualBaseInfo *VBI; 3546 3547 { 3548 // Get or create a VBI for RD. Don't hold a reference to the DenseMap cell, 3549 // as it may be modified and rehashed under us. 3550 VirtualBaseInfo *&Entry = VBaseInfo[RD]; 3551 if (Entry) 3552 return Entry; 3553 Entry = VBI = new VirtualBaseInfo(); 3554 } 3555 3556 computeVBTablePaths(RD, VBI->VBTables); 3557 3558 // First, see if the Derived class shared the vbptr with a non-virtual base. 3559 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 3560 if (const CXXRecordDecl *VBPtrBase = Layout.getBaseSharingVBPtr()) { 3561 // If the Derived class shares the vbptr with a non-virtual base, the shared 3562 // virtual bases come first so that the layout is the same. 3563 const VirtualBaseInfo *BaseInfo = 3564 computeVBTableRelatedInformation(VBPtrBase); 3565 VBI->VBTableIndices.insert(BaseInfo->VBTableIndices.begin(), 3566 BaseInfo->VBTableIndices.end()); 3567 } 3568 3569 // New vbases are added to the end of the vbtable. 3570 // Skip the self entry and vbases visited in the non-virtual base, if any. 3571 unsigned VBTableIndex = 1 + VBI->VBTableIndices.size(); 3572 for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 3573 E = RD->vbases_end(); 3574 I != E; ++I) { 3575 const CXXRecordDecl *CurVBase = I->getType()->getAsCXXRecordDecl(); 3576 if (!VBI->VBTableIndices.count(CurVBase)) 3577 VBI->VBTableIndices[CurVBase] = VBTableIndex++; 3578 } 3579 3580 return VBI; 3581 } 3582 3583 unsigned MicrosoftVTableContext::getVBTableIndex(const CXXRecordDecl *Derived, 3584 const CXXRecordDecl *VBase) { 3585 const VirtualBaseInfo *VBInfo = computeVBTableRelatedInformation(Derived); 3586 assert(VBInfo->VBTableIndices.count(VBase)); 3587 return VBInfo->VBTableIndices.find(VBase)->second; 3588 } 3589 3590 const VBTableVector & 3591 MicrosoftVTableContext::enumerateVBTables(const CXXRecordDecl *RD) { 3592 return computeVBTableRelatedInformation(RD)->VBTables; 3593 } 3594 3595 const MicrosoftVTableContext::VFPtrListTy & 3596 MicrosoftVTableContext::getVFPtrOffsets(const CXXRecordDecl *RD) { 3597 computeVTableRelatedInformation(RD); 3598 3599 assert(VFPtrLocations.count(RD) && "Couldn't find vfptr locations"); 3600 return VFPtrLocations[RD]; 3601 } 3602 3603 const VTableLayout & 3604 MicrosoftVTableContext::getVFTableLayout(const CXXRecordDecl *RD, 3605 CharUnits VFPtrOffset) { 3606 computeVTableRelatedInformation(RD); 3607 3608 VFTableIdTy id(RD, VFPtrOffset); 3609 assert(VFTableLayouts.count(id) && "Couldn't find a VFTable at this offset"); 3610 return *VFTableLayouts[id]; 3611 } 3612 3613 const MicrosoftVTableContext::MethodVFTableLocation & 3614 MicrosoftVTableContext::getMethodVFTableLocation(GlobalDecl GD) { 3615 assert(cast<CXXMethodDecl>(GD.getDecl())->isVirtual() && 3616 "Only use this method for virtual methods or dtors"); 3617 if (isa<CXXDestructorDecl>(GD.getDecl())) 3618 assert(GD.getDtorType() == Dtor_Deleting); 3619 3620 MethodVFTableLocationsTy::iterator I = MethodVFTableLocations.find(GD); 3621 if (I != MethodVFTableLocations.end()) 3622 return I->second; 3623 3624 const CXXRecordDecl *RD = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 3625 3626 computeVTableRelatedInformation(RD); 3627 3628 I = MethodVFTableLocations.find(GD); 3629 assert(I != MethodVFTableLocations.end() && "Did not find index!"); 3630 return I->second; 3631 } 3632