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/Support/Format.h" 20 #include "llvm/Support/raw_ostream.h" 21 #include <algorithm> 22 #include <cstdio> 23 24 using namespace clang; 25 26 #define DUMP_OVERRIDERS 0 27 28 namespace { 29 30 /// BaseOffset - Represents an offset from a derived class to a direct or 31 /// indirect base class. 32 struct BaseOffset { 33 /// DerivedClass - The derived class. 34 const CXXRecordDecl *DerivedClass; 35 36 /// VirtualBase - If the path from the derived class to the base class 37 /// involves virtual base classes, this holds the declaration of the last 38 /// virtual base in this path (i.e. closest to the base class). 39 const CXXRecordDecl *VirtualBase; 40 41 /// NonVirtualOffset - The offset from the derived class to the base class. 42 /// (Or the offset from the virtual base class to the base class, if the 43 /// path from the derived class to the base class involves a virtual base 44 /// class. 45 CharUnits NonVirtualOffset; 46 47 BaseOffset() : DerivedClass(0), VirtualBase(0), 48 NonVirtualOffset(CharUnits::Zero()) { } 49 BaseOffset(const CXXRecordDecl *DerivedClass, 50 const CXXRecordDecl *VirtualBase, CharUnits NonVirtualOffset) 51 : DerivedClass(DerivedClass), VirtualBase(VirtualBase), 52 NonVirtualOffset(NonVirtualOffset) { } 53 54 bool isEmpty() const { return NonVirtualOffset.isZero() && !VirtualBase; } 55 }; 56 57 /// FinalOverriders - Contains the final overrider member functions for all 58 /// member functions in the base subobjects of a class. 59 class FinalOverriders { 60 public: 61 /// OverriderInfo - Information about a final overrider. 62 struct OverriderInfo { 63 /// Method - The method decl of the overrider. 64 const CXXMethodDecl *Method; 65 66 /// Offset - the base offset of the overrider in the layout class. 67 CharUnits Offset; 68 69 OverriderInfo() : Method(0), Offset(CharUnits::Zero()) { } 70 }; 71 72 private: 73 /// MostDerivedClass - The most derived class for which the final overriders 74 /// are stored. 75 const CXXRecordDecl *MostDerivedClass; 76 77 /// MostDerivedClassOffset - If we're building final overriders for a 78 /// construction vtable, this holds the offset from the layout class to the 79 /// most derived class. 80 const CharUnits MostDerivedClassOffset; 81 82 /// LayoutClass - The class we're using for layout information. Will be 83 /// different than the most derived class if the final overriders are for a 84 /// construction vtable. 85 const CXXRecordDecl *LayoutClass; 86 87 ASTContext &Context; 88 89 /// MostDerivedClassLayout - the AST record layout of the most derived class. 90 const ASTRecordLayout &MostDerivedClassLayout; 91 92 /// MethodBaseOffsetPairTy - Uniquely identifies a member function 93 /// in a base subobject. 94 typedef std::pair<const CXXMethodDecl *, CharUnits> MethodBaseOffsetPairTy; 95 96 typedef llvm::DenseMap<MethodBaseOffsetPairTy, 97 OverriderInfo> OverridersMapTy; 98 99 /// OverridersMap - The final overriders for all virtual member functions of 100 /// all the base subobjects of the most derived class. 101 OverridersMapTy OverridersMap; 102 103 /// SubobjectsToOffsetsMapTy - A mapping from a base subobject (represented 104 /// as a record decl and a subobject number) and its offsets in the most 105 /// derived class as well as the layout class. 106 typedef llvm::DenseMap<std::pair<const CXXRecordDecl *, unsigned>, 107 CharUnits> SubobjectOffsetMapTy; 108 109 typedef llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCountMapTy; 110 111 /// ComputeBaseOffsets - Compute the offsets for all base subobjects of the 112 /// given base. 113 void ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual, 114 CharUnits OffsetInLayoutClass, 115 SubobjectOffsetMapTy &SubobjectOffsets, 116 SubobjectOffsetMapTy &SubobjectLayoutClassOffsets, 117 SubobjectCountMapTy &SubobjectCounts); 118 119 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; 120 121 /// dump - dump the final overriders for a base subobject, and all its direct 122 /// and indirect base subobjects. 123 void dump(raw_ostream &Out, BaseSubobject Base, 124 VisitedVirtualBasesSetTy& VisitedVirtualBases); 125 126 public: 127 FinalOverriders(const CXXRecordDecl *MostDerivedClass, 128 CharUnits MostDerivedClassOffset, 129 const CXXRecordDecl *LayoutClass); 130 131 /// getOverrider - Get the final overrider for the given method declaration in 132 /// the subobject with the given base offset. 133 OverriderInfo getOverrider(const CXXMethodDecl *MD, 134 CharUnits BaseOffset) const { 135 assert(OverridersMap.count(std::make_pair(MD, BaseOffset)) && 136 "Did not find overrider!"); 137 138 return OverridersMap.lookup(std::make_pair(MD, BaseOffset)); 139 } 140 141 /// dump - dump the final overriders. 142 void dump() { 143 VisitedVirtualBasesSetTy VisitedVirtualBases; 144 dump(llvm::errs(), BaseSubobject(MostDerivedClass, CharUnits::Zero()), 145 VisitedVirtualBases); 146 } 147 148 }; 149 150 FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass, 151 CharUnits MostDerivedClassOffset, 152 const CXXRecordDecl *LayoutClass) 153 : MostDerivedClass(MostDerivedClass), 154 MostDerivedClassOffset(MostDerivedClassOffset), LayoutClass(LayoutClass), 155 Context(MostDerivedClass->getASTContext()), 156 MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)) { 157 158 // Compute base offsets. 159 SubobjectOffsetMapTy SubobjectOffsets; 160 SubobjectOffsetMapTy SubobjectLayoutClassOffsets; 161 SubobjectCountMapTy SubobjectCounts; 162 ComputeBaseOffsets(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 163 /*IsVirtual=*/false, 164 MostDerivedClassOffset, 165 SubobjectOffsets, SubobjectLayoutClassOffsets, 166 SubobjectCounts); 167 168 // Get the final overriders. 169 CXXFinalOverriderMap FinalOverriders; 170 MostDerivedClass->getFinalOverriders(FinalOverriders); 171 172 for (CXXFinalOverriderMap::const_iterator I = FinalOverriders.begin(), 173 E = FinalOverriders.end(); I != E; ++I) { 174 const CXXMethodDecl *MD = I->first; 175 const OverridingMethods& Methods = I->second; 176 177 for (OverridingMethods::const_iterator I = Methods.begin(), 178 E = Methods.end(); I != E; ++I) { 179 unsigned SubobjectNumber = I->first; 180 assert(SubobjectOffsets.count(std::make_pair(MD->getParent(), 181 SubobjectNumber)) && 182 "Did not find subobject offset!"); 183 184 CharUnits BaseOffset = SubobjectOffsets[std::make_pair(MD->getParent(), 185 SubobjectNumber)]; 186 187 assert(I->second.size() == 1 && "Final overrider is not unique!"); 188 const UniqueVirtualMethod &Method = I->second.front(); 189 190 const CXXRecordDecl *OverriderRD = Method.Method->getParent(); 191 assert(SubobjectLayoutClassOffsets.count( 192 std::make_pair(OverriderRD, Method.Subobject)) 193 && "Did not find subobject offset!"); 194 CharUnits OverriderOffset = 195 SubobjectLayoutClassOffsets[std::make_pair(OverriderRD, 196 Method.Subobject)]; 197 198 OverriderInfo& Overrider = OverridersMap[std::make_pair(MD, BaseOffset)]; 199 assert(!Overrider.Method && "Overrider should not exist yet!"); 200 201 Overrider.Offset = OverriderOffset; 202 Overrider.Method = Method.Method; 203 } 204 } 205 206 #if DUMP_OVERRIDERS 207 // And dump them (for now). 208 dump(); 209 #endif 210 } 211 212 static BaseOffset ComputeBaseOffset(ASTContext &Context, 213 const CXXRecordDecl *DerivedRD, 214 const CXXBasePath &Path) { 215 CharUnits NonVirtualOffset = CharUnits::Zero(); 216 217 unsigned NonVirtualStart = 0; 218 const CXXRecordDecl *VirtualBase = 0; 219 220 // First, look for the virtual base class. 221 for (int I = Path.size(), E = 0; I != E; --I) { 222 const CXXBasePathElement &Element = Path[I - 1]; 223 224 if (Element.Base->isVirtual()) { 225 NonVirtualStart = I; 226 QualType VBaseType = Element.Base->getType(); 227 VirtualBase = 228 cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl()); 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 RecordType *BaseType = Element.Base->getType()->getAs<RecordType>(); 241 const CXXRecordDecl *Base = cast<CXXRecordDecl>(BaseType->getDecl()); 242 243 NonVirtualOffset += Layout.getBaseClassOffset(Base); 244 } 245 246 // FIXME: This should probably use CharUnits or something. Maybe we should 247 // even change the base offsets in ASTRecordLayout to be specified in 248 // CharUnits. 249 return BaseOffset(DerivedRD, VirtualBase, NonVirtualOffset); 250 251 } 252 253 static BaseOffset ComputeBaseOffset(ASTContext &Context, 254 const CXXRecordDecl *BaseRD, 255 const CXXRecordDecl *DerivedRD) { 256 CXXBasePaths Paths(/*FindAmbiguities=*/false, 257 /*RecordPaths=*/true, /*DetectVirtual=*/false); 258 259 if (!DerivedRD->isDerivedFrom(BaseRD, Paths)) 260 llvm_unreachable("Class must be derived from the passed in base class!"); 261 262 return ComputeBaseOffset(Context, DerivedRD, Paths.front()); 263 } 264 265 static BaseOffset 266 ComputeReturnAdjustmentBaseOffset(ASTContext &Context, 267 const CXXMethodDecl *DerivedMD, 268 const CXXMethodDecl *BaseMD) { 269 const FunctionType *BaseFT = BaseMD->getType()->getAs<FunctionType>(); 270 const FunctionType *DerivedFT = DerivedMD->getType()->getAs<FunctionType>(); 271 272 // Canonicalize the return types. 273 CanQualType CanDerivedReturnType = 274 Context.getCanonicalType(DerivedFT->getResultType()); 275 CanQualType CanBaseReturnType = 276 Context.getCanonicalType(BaseFT->getResultType()); 277 278 assert(CanDerivedReturnType->getTypeClass() == 279 CanBaseReturnType->getTypeClass() && 280 "Types must have same type class!"); 281 282 if (CanDerivedReturnType == CanBaseReturnType) { 283 // No adjustment needed. 284 return BaseOffset(); 285 } 286 287 if (isa<ReferenceType>(CanDerivedReturnType)) { 288 CanDerivedReturnType = 289 CanDerivedReturnType->getAs<ReferenceType>()->getPointeeType(); 290 CanBaseReturnType = 291 CanBaseReturnType->getAs<ReferenceType>()->getPointeeType(); 292 } else if (isa<PointerType>(CanDerivedReturnType)) { 293 CanDerivedReturnType = 294 CanDerivedReturnType->getAs<PointerType>()->getPointeeType(); 295 CanBaseReturnType = 296 CanBaseReturnType->getAs<PointerType>()->getPointeeType(); 297 } else { 298 llvm_unreachable("Unexpected return type!"); 299 } 300 301 // We need to compare unqualified types here; consider 302 // const T *Base::foo(); 303 // T *Derived::foo(); 304 if (CanDerivedReturnType.getUnqualifiedType() == 305 CanBaseReturnType.getUnqualifiedType()) { 306 // No adjustment needed. 307 return BaseOffset(); 308 } 309 310 const CXXRecordDecl *DerivedRD = 311 cast<CXXRecordDecl>(cast<RecordType>(CanDerivedReturnType)->getDecl()); 312 313 const CXXRecordDecl *BaseRD = 314 cast<CXXRecordDecl>(cast<RecordType>(CanBaseReturnType)->getDecl()); 315 316 return ComputeBaseOffset(Context, BaseRD, DerivedRD); 317 } 318 319 void 320 FinalOverriders::ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual, 321 CharUnits OffsetInLayoutClass, 322 SubobjectOffsetMapTy &SubobjectOffsets, 323 SubobjectOffsetMapTy &SubobjectLayoutClassOffsets, 324 SubobjectCountMapTy &SubobjectCounts) { 325 const CXXRecordDecl *RD = Base.getBase(); 326 327 unsigned SubobjectNumber = 0; 328 if (!IsVirtual) 329 SubobjectNumber = ++SubobjectCounts[RD]; 330 331 // Set up the subobject to offset mapping. 332 assert(!SubobjectOffsets.count(std::make_pair(RD, SubobjectNumber)) 333 && "Subobject offset already exists!"); 334 assert(!SubobjectLayoutClassOffsets.count(std::make_pair(RD, SubobjectNumber)) 335 && "Subobject offset already exists!"); 336 337 SubobjectOffsets[std::make_pair(RD, SubobjectNumber)] = Base.getBaseOffset(); 338 SubobjectLayoutClassOffsets[std::make_pair(RD, SubobjectNumber)] = 339 OffsetInLayoutClass; 340 341 // Traverse our bases. 342 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 343 E = RD->bases_end(); I != E; ++I) { 344 const CXXRecordDecl *BaseDecl = 345 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 346 347 CharUnits BaseOffset; 348 CharUnits BaseOffsetInLayoutClass; 349 if (I->isVirtual()) { 350 // Check if we've visited this virtual base before. 351 if (SubobjectOffsets.count(std::make_pair(BaseDecl, 0))) 352 continue; 353 354 const ASTRecordLayout &LayoutClassLayout = 355 Context.getASTRecordLayout(LayoutClass); 356 357 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 358 BaseOffsetInLayoutClass = 359 LayoutClassLayout.getVBaseClassOffset(BaseDecl); 360 } else { 361 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 362 CharUnits Offset = Layout.getBaseClassOffset(BaseDecl); 363 364 BaseOffset = Base.getBaseOffset() + Offset; 365 BaseOffsetInLayoutClass = OffsetInLayoutClass + Offset; 366 } 367 368 ComputeBaseOffsets(BaseSubobject(BaseDecl, BaseOffset), 369 I->isVirtual(), BaseOffsetInLayoutClass, 370 SubobjectOffsets, SubobjectLayoutClassOffsets, 371 SubobjectCounts); 372 } 373 } 374 375 void FinalOverriders::dump(raw_ostream &Out, BaseSubobject Base, 376 VisitedVirtualBasesSetTy &VisitedVirtualBases) { 377 const CXXRecordDecl *RD = Base.getBase(); 378 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 379 380 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 381 E = RD->bases_end(); I != E; ++I) { 382 const CXXRecordDecl *BaseDecl = 383 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 384 385 // Ignore bases that don't have any virtual member functions. 386 if (!BaseDecl->isPolymorphic()) 387 continue; 388 389 CharUnits BaseOffset; 390 if (I->isVirtual()) { 391 if (!VisitedVirtualBases.insert(BaseDecl)) { 392 // We've visited this base before. 393 continue; 394 } 395 396 BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 397 } else { 398 BaseOffset = Layout.getBaseClassOffset(BaseDecl) + Base.getBaseOffset(); 399 } 400 401 dump(Out, BaseSubobject(BaseDecl, BaseOffset), VisitedVirtualBases); 402 } 403 404 Out << "Final overriders for (" << RD->getQualifiedNameAsString() << ", "; 405 Out << Base.getBaseOffset().getQuantity() << ")\n"; 406 407 // Now dump the overriders for this base subobject. 408 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 409 E = RD->method_end(); I != E; ++I) { 410 const CXXMethodDecl *MD = *I; 411 412 if (!MD->isVirtual()) 413 continue; 414 415 OverriderInfo Overrider = getOverrider(MD, Base.getBaseOffset()); 416 417 Out << " " << MD->getQualifiedNameAsString() << " - ("; 418 Out << Overrider.Method->getQualifiedNameAsString(); 419 Out << ", " << Overrider.Offset.getQuantity() << ')'; 420 421 BaseOffset Offset; 422 if (!Overrider.Method->isPure()) 423 Offset = ComputeReturnAdjustmentBaseOffset(Context, Overrider.Method, MD); 424 425 if (!Offset.isEmpty()) { 426 Out << " [ret-adj: "; 427 if (Offset.VirtualBase) 428 Out << Offset.VirtualBase->getQualifiedNameAsString() << " vbase, "; 429 430 Out << Offset.NonVirtualOffset.getQuantity() << " nv]"; 431 } 432 433 Out << "\n"; 434 } 435 } 436 437 /// VCallOffsetMap - Keeps track of vcall offsets when building a vtable. 438 struct VCallOffsetMap { 439 440 typedef std::pair<const CXXMethodDecl *, CharUnits> MethodAndOffsetPairTy; 441 442 /// Offsets - Keeps track of methods and their offsets. 443 // FIXME: This should be a real map and not a vector. 444 SmallVector<MethodAndOffsetPairTy, 16> Offsets; 445 446 /// MethodsCanShareVCallOffset - Returns whether two virtual member functions 447 /// can share the same vcall offset. 448 static bool MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, 449 const CXXMethodDecl *RHS); 450 451 public: 452 /// AddVCallOffset - Adds a vcall offset to the map. Returns true if the 453 /// add was successful, or false if there was already a member function with 454 /// the same signature in the map. 455 bool AddVCallOffset(const CXXMethodDecl *MD, CharUnits OffsetOffset); 456 457 /// getVCallOffsetOffset - Returns the vcall offset offset (relative to the 458 /// vtable address point) for the given virtual member function. 459 CharUnits getVCallOffsetOffset(const CXXMethodDecl *MD); 460 461 // empty - Return whether the offset map is empty or not. 462 bool empty() const { return Offsets.empty(); } 463 }; 464 465 static bool HasSameVirtualSignature(const CXXMethodDecl *LHS, 466 const CXXMethodDecl *RHS) { 467 const FunctionProtoType *LT = 468 cast<FunctionProtoType>(LHS->getType().getCanonicalType()); 469 const FunctionProtoType *RT = 470 cast<FunctionProtoType>(RHS->getType().getCanonicalType()); 471 472 // Fast-path matches in the canonical types. 473 if (LT == RT) return true; 474 475 // Force the signatures to match. We can't rely on the overrides 476 // list here because there isn't necessarily an inheritance 477 // relationship between the two methods. 478 if (LT->getTypeQuals() != RT->getTypeQuals() || 479 LT->getNumArgs() != RT->getNumArgs()) 480 return false; 481 for (unsigned I = 0, E = LT->getNumArgs(); I != E; ++I) 482 if (LT->getArgType(I) != RT->getArgType(I)) 483 return false; 484 return true; 485 } 486 487 bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, 488 const CXXMethodDecl *RHS) { 489 assert(LHS->isVirtual() && "LHS must be virtual!"); 490 assert(RHS->isVirtual() && "LHS must be virtual!"); 491 492 // A destructor can share a vcall offset with another destructor. 493 if (isa<CXXDestructorDecl>(LHS)) 494 return isa<CXXDestructorDecl>(RHS); 495 496 // FIXME: We need to check more things here. 497 498 // The methods must have the same name. 499 DeclarationName LHSName = LHS->getDeclName(); 500 DeclarationName RHSName = RHS->getDeclName(); 501 if (LHSName != RHSName) 502 return false; 503 504 // And the same signatures. 505 return HasSameVirtualSignature(LHS, RHS); 506 } 507 508 bool VCallOffsetMap::AddVCallOffset(const CXXMethodDecl *MD, 509 CharUnits OffsetOffset) { 510 // Check if we can reuse an offset. 511 for (unsigned I = 0, E = Offsets.size(); I != E; ++I) { 512 if (MethodsCanShareVCallOffset(Offsets[I].first, MD)) 513 return false; 514 } 515 516 // Add the offset. 517 Offsets.push_back(MethodAndOffsetPairTy(MD, OffsetOffset)); 518 return true; 519 } 520 521 CharUnits VCallOffsetMap::getVCallOffsetOffset(const CXXMethodDecl *MD) { 522 // Look for an offset. 523 for (unsigned I = 0, E = Offsets.size(); I != E; ++I) { 524 if (MethodsCanShareVCallOffset(Offsets[I].first, MD)) 525 return Offsets[I].second; 526 } 527 528 llvm_unreachable("Should always find a vcall offset offset!"); 529 } 530 531 /// VCallAndVBaseOffsetBuilder - Class for building vcall and vbase offsets. 532 class VCallAndVBaseOffsetBuilder { 533 public: 534 typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> 535 VBaseOffsetOffsetsMapTy; 536 537 private: 538 /// MostDerivedClass - The most derived class for which we're building vcall 539 /// and vbase offsets. 540 const CXXRecordDecl *MostDerivedClass; 541 542 /// LayoutClass - The class we're using for layout information. Will be 543 /// different than the most derived class if we're building a construction 544 /// vtable. 545 const CXXRecordDecl *LayoutClass; 546 547 /// Context - The ASTContext which we will use for layout information. 548 ASTContext &Context; 549 550 /// Components - vcall and vbase offset components 551 typedef SmallVector<VTableComponent, 64> VTableComponentVectorTy; 552 VTableComponentVectorTy Components; 553 554 /// VisitedVirtualBases - Visited virtual bases. 555 llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; 556 557 /// VCallOffsets - Keeps track of vcall offsets. 558 VCallOffsetMap VCallOffsets; 559 560 561 /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets, 562 /// relative to the address point. 563 VBaseOffsetOffsetsMapTy VBaseOffsetOffsets; 564 565 /// FinalOverriders - The final overriders of the most derived class. 566 /// (Can be null when we're not building a vtable of the most derived class). 567 const FinalOverriders *Overriders; 568 569 /// AddVCallAndVBaseOffsets - Add vcall offsets and vbase offsets for the 570 /// given base subobject. 571 void AddVCallAndVBaseOffsets(BaseSubobject Base, bool BaseIsVirtual, 572 CharUnits RealBaseOffset); 573 574 /// AddVCallOffsets - Add vcall offsets for the given base subobject. 575 void AddVCallOffsets(BaseSubobject Base, CharUnits VBaseOffset); 576 577 /// AddVBaseOffsets - Add vbase offsets for the given class. 578 void AddVBaseOffsets(const CXXRecordDecl *Base, 579 CharUnits OffsetInLayoutClass); 580 581 /// getCurrentOffsetOffset - Get the current vcall or vbase offset offset in 582 /// chars, relative to the vtable address point. 583 CharUnits getCurrentOffsetOffset() const; 584 585 public: 586 VCallAndVBaseOffsetBuilder(const CXXRecordDecl *MostDerivedClass, 587 const CXXRecordDecl *LayoutClass, 588 const FinalOverriders *Overriders, 589 BaseSubobject Base, bool BaseIsVirtual, 590 CharUnits OffsetInLayoutClass) 591 : MostDerivedClass(MostDerivedClass), LayoutClass(LayoutClass), 592 Context(MostDerivedClass->getASTContext()), Overriders(Overriders) { 593 594 // Add vcall and vbase offsets. 595 AddVCallAndVBaseOffsets(Base, BaseIsVirtual, OffsetInLayoutClass); 596 } 597 598 /// Methods for iterating over the components. 599 typedef VTableComponentVectorTy::const_reverse_iterator const_iterator; 600 const_iterator components_begin() const { return Components.rbegin(); } 601 const_iterator components_end() const { return Components.rend(); } 602 603 const VCallOffsetMap &getVCallOffsets() const { return VCallOffsets; } 604 const VBaseOffsetOffsetsMapTy &getVBaseOffsetOffsets() const { 605 return VBaseOffsetOffsets; 606 } 607 }; 608 609 void 610 VCallAndVBaseOffsetBuilder::AddVCallAndVBaseOffsets(BaseSubobject Base, 611 bool BaseIsVirtual, 612 CharUnits RealBaseOffset) { 613 const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base.getBase()); 614 615 // Itanium C++ ABI 2.5.2: 616 // ..in classes sharing a virtual table with a primary base class, the vcall 617 // and vbase offsets added by the derived class all come before the vcall 618 // and vbase offsets required by the base class, so that the latter may be 619 // laid out as required by the base class without regard to additions from 620 // the derived class(es). 621 622 // (Since we're emitting the vcall and vbase offsets in reverse order, we'll 623 // emit them for the primary base first). 624 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 625 bool PrimaryBaseIsVirtual = Layout.isPrimaryBaseVirtual(); 626 627 CharUnits PrimaryBaseOffset; 628 629 // Get the base offset of the primary base. 630 if (PrimaryBaseIsVirtual) { 631 assert(Layout.getVBaseClassOffset(PrimaryBase).isZero() && 632 "Primary vbase should have a zero offset!"); 633 634 const ASTRecordLayout &MostDerivedClassLayout = 635 Context.getASTRecordLayout(MostDerivedClass); 636 637 PrimaryBaseOffset = 638 MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); 639 } else { 640 assert(Layout.getBaseClassOffset(PrimaryBase).isZero() && 641 "Primary base should have a zero offset!"); 642 643 PrimaryBaseOffset = Base.getBaseOffset(); 644 } 645 646 AddVCallAndVBaseOffsets( 647 BaseSubobject(PrimaryBase,PrimaryBaseOffset), 648 PrimaryBaseIsVirtual, RealBaseOffset); 649 } 650 651 AddVBaseOffsets(Base.getBase(), RealBaseOffset); 652 653 // We only want to add vcall offsets for virtual bases. 654 if (BaseIsVirtual) 655 AddVCallOffsets(Base, RealBaseOffset); 656 } 657 658 CharUnits VCallAndVBaseOffsetBuilder::getCurrentOffsetOffset() const { 659 // OffsetIndex is the index of this vcall or vbase offset, relative to the 660 // vtable address point. (We subtract 3 to account for the information just 661 // above the address point, the RTTI info, the offset to top, and the 662 // vcall offset itself). 663 int64_t OffsetIndex = -(int64_t)(3 + Components.size()); 664 665 CharUnits PointerWidth = 666 Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); 667 CharUnits OffsetOffset = PointerWidth * OffsetIndex; 668 return OffsetOffset; 669 } 670 671 void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, 672 CharUnits VBaseOffset) { 673 const CXXRecordDecl *RD = Base.getBase(); 674 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 675 676 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 677 678 // Handle the primary base first. 679 // We only want to add vcall offsets if the base is non-virtual; a virtual 680 // primary base will have its vcall and vbase offsets emitted already. 681 if (PrimaryBase && !Layout.isPrimaryBaseVirtual()) { 682 // Get the base offset of the primary base. 683 assert(Layout.getBaseClassOffset(PrimaryBase).isZero() && 684 "Primary base should have a zero offset!"); 685 686 AddVCallOffsets(BaseSubobject(PrimaryBase, Base.getBaseOffset()), 687 VBaseOffset); 688 } 689 690 // Add the vcall offsets. 691 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 692 E = RD->method_end(); I != E; ++I) { 693 const CXXMethodDecl *MD = *I; 694 695 if (!MD->isVirtual()) 696 continue; 697 698 CharUnits OffsetOffset = getCurrentOffsetOffset(); 699 700 // Don't add a vcall offset if we already have one for this member function 701 // signature. 702 if (!VCallOffsets.AddVCallOffset(MD, OffsetOffset)) 703 continue; 704 705 CharUnits Offset = CharUnits::Zero(); 706 707 if (Overriders) { 708 // Get the final overrider. 709 FinalOverriders::OverriderInfo Overrider = 710 Overriders->getOverrider(MD, Base.getBaseOffset()); 711 712 /// The vcall offset is the offset from the virtual base to the object 713 /// where the function was overridden. 714 Offset = Overrider.Offset - VBaseOffset; 715 } 716 717 Components.push_back( 718 VTableComponent::MakeVCallOffset(Offset)); 719 } 720 721 // And iterate over all non-virtual bases (ignoring the primary base). 722 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 723 E = RD->bases_end(); I != E; ++I) { 724 725 if (I->isVirtual()) 726 continue; 727 728 const CXXRecordDecl *BaseDecl = 729 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 730 if (BaseDecl == PrimaryBase) 731 continue; 732 733 // Get the base offset of this base. 734 CharUnits BaseOffset = Base.getBaseOffset() + 735 Layout.getBaseClassOffset(BaseDecl); 736 737 AddVCallOffsets(BaseSubobject(BaseDecl, BaseOffset), 738 VBaseOffset); 739 } 740 } 741 742 void 743 VCallAndVBaseOffsetBuilder::AddVBaseOffsets(const CXXRecordDecl *RD, 744 CharUnits OffsetInLayoutClass) { 745 const ASTRecordLayout &LayoutClassLayout = 746 Context.getASTRecordLayout(LayoutClass); 747 748 // Add vbase offsets. 749 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 750 E = RD->bases_end(); I != E; ++I) { 751 const CXXRecordDecl *BaseDecl = 752 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 753 754 // Check if this is a virtual base that we haven't visited before. 755 if (I->isVirtual() && VisitedVirtualBases.insert(BaseDecl)) { 756 CharUnits Offset = 757 LayoutClassLayout.getVBaseClassOffset(BaseDecl) - OffsetInLayoutClass; 758 759 // Add the vbase offset offset. 760 assert(!VBaseOffsetOffsets.count(BaseDecl) && 761 "vbase offset offset already exists!"); 762 763 CharUnits VBaseOffsetOffset = getCurrentOffsetOffset(); 764 VBaseOffsetOffsets.insert( 765 std::make_pair(BaseDecl, VBaseOffsetOffset)); 766 767 Components.push_back( 768 VTableComponent::MakeVBaseOffset(Offset)); 769 } 770 771 // Check the base class looking for more vbase offsets. 772 AddVBaseOffsets(BaseDecl, OffsetInLayoutClass); 773 } 774 } 775 776 /// VTableBuilder - Class for building vtable layout information. 777 class VTableBuilder { 778 public: 779 /// PrimaryBasesSetVectorTy - A set vector of direct and indirect 780 /// primary bases. 781 typedef llvm::SmallSetVector<const CXXRecordDecl *, 8> 782 PrimaryBasesSetVectorTy; 783 784 typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> 785 VBaseOffsetOffsetsMapTy; 786 787 typedef llvm::DenseMap<BaseSubobject, uint64_t> 788 AddressPointsMapTy; 789 790 typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy; 791 792 private: 793 /// VTables - Global vtable information. 794 VTableContext &VTables; 795 796 /// MostDerivedClass - The most derived class for which we're building this 797 /// vtable. 798 const CXXRecordDecl *MostDerivedClass; 799 800 /// MostDerivedClassOffset - If we're building a construction vtable, this 801 /// holds the offset from the layout class to the most derived class. 802 const CharUnits MostDerivedClassOffset; 803 804 /// MostDerivedClassIsVirtual - Whether the most derived class is a virtual 805 /// base. (This only makes sense when building a construction vtable). 806 bool MostDerivedClassIsVirtual; 807 808 /// LayoutClass - The class we're using for layout information. Will be 809 /// different than the most derived class if we're building a construction 810 /// vtable. 811 const CXXRecordDecl *LayoutClass; 812 813 /// Context - The ASTContext which we will use for layout information. 814 ASTContext &Context; 815 816 /// FinalOverriders - The final overriders of the most derived class. 817 const FinalOverriders Overriders; 818 819 /// VCallOffsetsForVBases - Keeps track of vcall offsets for the virtual 820 /// bases in this vtable. 821 llvm::DenseMap<const CXXRecordDecl *, VCallOffsetMap> VCallOffsetsForVBases; 822 823 /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets for 824 /// the most derived class. 825 VBaseOffsetOffsetsMapTy VBaseOffsetOffsets; 826 827 /// Components - The components of the vtable being built. 828 SmallVector<VTableComponent, 64> Components; 829 830 /// AddressPoints - Address points for the vtable being built. 831 AddressPointsMapTy AddressPoints; 832 833 /// MethodInfo - Contains information about a method in a vtable. 834 /// (Used for computing 'this' pointer adjustment thunks. 835 struct MethodInfo { 836 /// BaseOffset - The base offset of this method. 837 const CharUnits BaseOffset; 838 839 /// BaseOffsetInLayoutClass - The base offset in the layout class of this 840 /// method. 841 const CharUnits BaseOffsetInLayoutClass; 842 843 /// VTableIndex - The index in the vtable that this method has. 844 /// (For destructors, this is the index of the complete destructor). 845 const uint64_t VTableIndex; 846 847 MethodInfo(CharUnits BaseOffset, CharUnits BaseOffsetInLayoutClass, 848 uint64_t VTableIndex) 849 : BaseOffset(BaseOffset), 850 BaseOffsetInLayoutClass(BaseOffsetInLayoutClass), 851 VTableIndex(VTableIndex) { } 852 853 MethodInfo() 854 : BaseOffset(CharUnits::Zero()), 855 BaseOffsetInLayoutClass(CharUnits::Zero()), 856 VTableIndex(0) { } 857 }; 858 859 typedef llvm::DenseMap<const CXXMethodDecl *, MethodInfo> MethodInfoMapTy; 860 861 /// MethodInfoMap - The information for all methods in the vtable we're 862 /// currently building. 863 MethodInfoMapTy MethodInfoMap; 864 865 /// MethodVTableIndices - Contains the index (relative to the vtable address 866 /// point) where the function pointer for a virtual function is stored. 867 MethodVTableIndicesTy MethodVTableIndices; 868 869 typedef llvm::DenseMap<uint64_t, ThunkInfo> VTableThunksMapTy; 870 871 /// VTableThunks - The thunks by vtable index in the vtable currently being 872 /// built. 873 VTableThunksMapTy VTableThunks; 874 875 typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; 876 typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy; 877 878 /// Thunks - A map that contains all the thunks needed for all methods in the 879 /// most derived class for which the vtable is currently being built. 880 ThunksMapTy Thunks; 881 882 /// AddThunk - Add a thunk for the given method. 883 void AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk); 884 885 /// ComputeThisAdjustments - Compute the 'this' pointer adjustments for the 886 /// part of the vtable we're currently building. 887 void ComputeThisAdjustments(); 888 889 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; 890 891 /// PrimaryVirtualBases - All known virtual bases who are a primary base of 892 /// some other base. 893 VisitedVirtualBasesSetTy PrimaryVirtualBases; 894 895 /// ComputeReturnAdjustment - Compute the return adjustment given a return 896 /// adjustment base offset. 897 ReturnAdjustment ComputeReturnAdjustment(BaseOffset Offset); 898 899 /// ComputeThisAdjustmentBaseOffset - Compute the base offset for adjusting 900 /// the 'this' pointer from the base subobject to the derived subobject. 901 BaseOffset ComputeThisAdjustmentBaseOffset(BaseSubobject Base, 902 BaseSubobject Derived) const; 903 904 /// ComputeThisAdjustment - Compute the 'this' pointer adjustment for the 905 /// given virtual member function, its offset in the layout class and its 906 /// final overrider. 907 ThisAdjustment 908 ComputeThisAdjustment(const CXXMethodDecl *MD, 909 CharUnits BaseOffsetInLayoutClass, 910 FinalOverriders::OverriderInfo Overrider); 911 912 /// AddMethod - Add a single virtual member function to the vtable 913 /// components vector. 914 void AddMethod(const CXXMethodDecl *MD, ReturnAdjustment ReturnAdjustment); 915 916 /// IsOverriderUsed - Returns whether the overrider will ever be used in this 917 /// part of the vtable. 918 /// 919 /// Itanium C++ ABI 2.5.2: 920 /// 921 /// struct A { virtual void f(); }; 922 /// struct B : virtual public A { int i; }; 923 /// struct C : virtual public A { int j; }; 924 /// struct D : public B, public C {}; 925 /// 926 /// When B and C are declared, A is a primary base in each case, so although 927 /// vcall offsets are allocated in the A-in-B and A-in-C vtables, no this 928 /// adjustment is required and no thunk is generated. However, inside D 929 /// objects, A is no longer a primary base of C, so if we allowed calls to 930 /// C::f() to use the copy of A's vtable in the C subobject, we would need 931 /// to adjust this from C* to B::A*, which would require a third-party 932 /// thunk. Since we require that a call to C::f() first convert to A*, 933 /// C-in-D's copy of A's vtable is never referenced, so this is not 934 /// necessary. 935 bool IsOverriderUsed(const CXXMethodDecl *Overrider, 936 CharUnits BaseOffsetInLayoutClass, 937 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 938 CharUnits FirstBaseOffsetInLayoutClass) const; 939 940 941 /// AddMethods - Add the methods of this base subobject and all its 942 /// primary bases to the vtable components vector. 943 void AddMethods(BaseSubobject Base, CharUnits BaseOffsetInLayoutClass, 944 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 945 CharUnits FirstBaseOffsetInLayoutClass, 946 PrimaryBasesSetVectorTy &PrimaryBases); 947 948 // LayoutVTable - Layout the vtable for the given base class, including its 949 // secondary vtables and any vtables for virtual bases. 950 void LayoutVTable(); 951 952 /// LayoutPrimaryAndSecondaryVTables - Layout the primary vtable for the 953 /// given base subobject, as well as all its secondary vtables. 954 /// 955 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base 956 /// or a direct or indirect base of a virtual base. 957 /// 958 /// \param BaseIsVirtualInLayoutClass - Whether the base subobject is virtual 959 /// in the layout class. 960 void LayoutPrimaryAndSecondaryVTables(BaseSubobject Base, 961 bool BaseIsMorallyVirtual, 962 bool BaseIsVirtualInLayoutClass, 963 CharUnits OffsetInLayoutClass); 964 965 /// LayoutSecondaryVTables - Layout the secondary vtables for the given base 966 /// subobject. 967 /// 968 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base 969 /// or a direct or indirect base of a virtual base. 970 void LayoutSecondaryVTables(BaseSubobject Base, bool BaseIsMorallyVirtual, 971 CharUnits OffsetInLayoutClass); 972 973 /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this 974 /// class hierarchy. 975 void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, 976 CharUnits OffsetInLayoutClass, 977 VisitedVirtualBasesSetTy &VBases); 978 979 /// LayoutVTablesForVirtualBases - Layout vtables for all virtual bases of the 980 /// given base (excluding any primary bases). 981 void LayoutVTablesForVirtualBases(const CXXRecordDecl *RD, 982 VisitedVirtualBasesSetTy &VBases); 983 984 /// isBuildingConstructionVTable - Return whether this vtable builder is 985 /// building a construction vtable. 986 bool isBuildingConstructorVTable() const { 987 return MostDerivedClass != LayoutClass; 988 } 989 990 public: 991 VTableBuilder(VTableContext &VTables, const CXXRecordDecl *MostDerivedClass, 992 CharUnits MostDerivedClassOffset, 993 bool MostDerivedClassIsVirtual, const 994 CXXRecordDecl *LayoutClass) 995 : VTables(VTables), MostDerivedClass(MostDerivedClass), 996 MostDerivedClassOffset(MostDerivedClassOffset), 997 MostDerivedClassIsVirtual(MostDerivedClassIsVirtual), 998 LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()), 999 Overriders(MostDerivedClass, MostDerivedClassOffset, LayoutClass) { 1000 1001 LayoutVTable(); 1002 1003 if (Context.getLangOpts().DumpVTableLayouts) 1004 dumpLayout(llvm::errs()); 1005 } 1006 1007 bool isMicrosoftABI() const { 1008 return VTables.isMicrosoftABI(); 1009 } 1010 1011 uint64_t getNumThunks() const { 1012 return Thunks.size(); 1013 } 1014 1015 ThunksMapTy::const_iterator thunks_begin() const { 1016 return Thunks.begin(); 1017 } 1018 1019 ThunksMapTy::const_iterator thunks_end() const { 1020 return Thunks.end(); 1021 } 1022 1023 const VBaseOffsetOffsetsMapTy &getVBaseOffsetOffsets() const { 1024 return VBaseOffsetOffsets; 1025 } 1026 1027 const AddressPointsMapTy &getAddressPoints() const { 1028 return AddressPoints; 1029 } 1030 1031 MethodVTableIndicesTy::const_iterator vtable_indices_begin() const { 1032 return MethodVTableIndices.begin(); 1033 } 1034 1035 MethodVTableIndicesTy::const_iterator vtable_indices_end() const { 1036 return MethodVTableIndices.end(); 1037 } 1038 1039 /// getNumVTableComponents - Return the number of components in the vtable 1040 /// currently built. 1041 uint64_t getNumVTableComponents() const { 1042 return Components.size(); 1043 } 1044 1045 const VTableComponent *vtable_component_begin() const { 1046 return Components.begin(); 1047 } 1048 1049 const VTableComponent *vtable_component_end() const { 1050 return Components.end(); 1051 } 1052 1053 AddressPointsMapTy::const_iterator address_points_begin() const { 1054 return AddressPoints.begin(); 1055 } 1056 1057 AddressPointsMapTy::const_iterator address_points_end() const { 1058 return AddressPoints.end(); 1059 } 1060 1061 VTableThunksMapTy::const_iterator vtable_thunks_begin() const { 1062 return VTableThunks.begin(); 1063 } 1064 1065 VTableThunksMapTy::const_iterator vtable_thunks_end() const { 1066 return VTableThunks.end(); 1067 } 1068 1069 /// dumpLayout - Dump the vtable layout. 1070 void dumpLayout(raw_ostream&); 1071 }; 1072 1073 void VTableBuilder::AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk) { 1074 assert(!isBuildingConstructorVTable() && 1075 "Can't add thunks for construction vtable"); 1076 1077 SmallVector<ThunkInfo, 1> &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 /// ComputeAllOverriddenMethods - Given a method decl, will return a set of all 1090 /// the overridden methods that the function decl overrides. 1091 static void 1092 ComputeAllOverriddenMethods(const CXXMethodDecl *MD, 1093 OverriddenMethodsSetTy& OverriddenMethods) { 1094 assert(MD->isVirtual() && "Method is not virtual!"); 1095 1096 for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), 1097 E = MD->end_overridden_methods(); I != E; ++I) { 1098 const CXXMethodDecl *OverriddenMD = *I; 1099 1100 OverriddenMethods.insert(OverriddenMD); 1101 1102 ComputeAllOverriddenMethods(OverriddenMD, OverriddenMethods); 1103 } 1104 } 1105 1106 void VTableBuilder::ComputeThisAdjustments() { 1107 // Now go through the method info map and see if any of the methods need 1108 // 'this' pointer adjustments. 1109 for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(), 1110 E = MethodInfoMap.end(); I != E; ++I) { 1111 const CXXMethodDecl *MD = I->first; 1112 const MethodInfo &MethodInfo = I->second; 1113 1114 // Ignore adjustments for unused function pointers. 1115 uint64_t VTableIndex = MethodInfo.VTableIndex; 1116 if (Components[VTableIndex].getKind() == 1117 VTableComponent::CK_UnusedFunctionPointer) 1118 continue; 1119 1120 // Get the final overrider for this method. 1121 FinalOverriders::OverriderInfo Overrider = 1122 Overriders.getOverrider(MD, MethodInfo.BaseOffset); 1123 1124 // Check if we need an adjustment at all. 1125 if (MethodInfo.BaseOffsetInLayoutClass == Overrider.Offset) { 1126 // When a return thunk is needed by a derived class that overrides a 1127 // virtual base, gcc uses a virtual 'this' adjustment as well. 1128 // While the thunk itself might be needed by vtables in subclasses or 1129 // in construction vtables, there doesn't seem to be a reason for using 1130 // the thunk in this vtable. Still, we do so to match gcc. 1131 if (VTableThunks.lookup(VTableIndex).Return.isEmpty()) 1132 continue; 1133 } 1134 1135 ThisAdjustment ThisAdjustment = 1136 ComputeThisAdjustment(MD, MethodInfo.BaseOffsetInLayoutClass, Overrider); 1137 1138 if (ThisAdjustment.isEmpty()) 1139 continue; 1140 1141 // Add it. 1142 VTableThunks[VTableIndex].This = ThisAdjustment; 1143 1144 if (isa<CXXDestructorDecl>(MD)) { 1145 // Add an adjustment for the deleting destructor as well. 1146 VTableThunks[VTableIndex + 1].This = ThisAdjustment; 1147 } 1148 } 1149 1150 /// Clear the method info map. 1151 MethodInfoMap.clear(); 1152 1153 if (isBuildingConstructorVTable()) { 1154 // We don't need to store thunk information for construction vtables. 1155 return; 1156 } 1157 1158 for (VTableThunksMapTy::const_iterator I = VTableThunks.begin(), 1159 E = VTableThunks.end(); I != E; ++I) { 1160 const VTableComponent &Component = Components[I->first]; 1161 const ThunkInfo &Thunk = I->second; 1162 const CXXMethodDecl *MD; 1163 1164 switch (Component.getKind()) { 1165 default: 1166 llvm_unreachable("Unexpected vtable component kind!"); 1167 case VTableComponent::CK_FunctionPointer: 1168 MD = Component.getFunctionDecl(); 1169 break; 1170 case VTableComponent::CK_CompleteDtorPointer: 1171 MD = Component.getDestructorDecl(); 1172 break; 1173 case VTableComponent::CK_DeletingDtorPointer: 1174 // We've already added the thunk when we saw the complete dtor pointer. 1175 // FIXME: check how this works in the Microsoft ABI 1176 // while working on the multiple inheritance patch. 1177 continue; 1178 } 1179 1180 if (MD->getParent() == MostDerivedClass) 1181 AddThunk(MD, Thunk); 1182 } 1183 } 1184 1185 ReturnAdjustment VTableBuilder::ComputeReturnAdjustment(BaseOffset Offset) { 1186 ReturnAdjustment Adjustment; 1187 1188 if (!Offset.isEmpty()) { 1189 if (Offset.VirtualBase) { 1190 // Get the virtual base offset offset. 1191 if (Offset.DerivedClass == MostDerivedClass) { 1192 // We can get the offset offset directly from our map. 1193 Adjustment.VBaseOffsetOffset = 1194 VBaseOffsetOffsets.lookup(Offset.VirtualBase).getQuantity(); 1195 } else { 1196 Adjustment.VBaseOffsetOffset = 1197 VTables.getVirtualBaseOffsetOffset(Offset.DerivedClass, 1198 Offset.VirtualBase).getQuantity(); 1199 } 1200 } 1201 1202 Adjustment.NonVirtual = Offset.NonVirtualOffset.getQuantity(); 1203 } 1204 1205 return Adjustment; 1206 } 1207 1208 BaseOffset 1209 VTableBuilder::ComputeThisAdjustmentBaseOffset(BaseSubobject Base, 1210 BaseSubobject Derived) const { 1211 const CXXRecordDecl *BaseRD = Base.getBase(); 1212 const CXXRecordDecl *DerivedRD = Derived.getBase(); 1213 1214 CXXBasePaths Paths(/*FindAmbiguities=*/true, 1215 /*RecordPaths=*/true, /*DetectVirtual=*/true); 1216 1217 if (!DerivedRD->isDerivedFrom(BaseRD, Paths)) 1218 llvm_unreachable("Class must be derived from the passed in base class!"); 1219 1220 // We have to go through all the paths, and see which one leads us to the 1221 // right base subobject. 1222 for (CXXBasePaths::const_paths_iterator I = Paths.begin(), E = Paths.end(); 1223 I != E; ++I) { 1224 BaseOffset Offset = ComputeBaseOffset(Context, DerivedRD, *I); 1225 1226 CharUnits OffsetToBaseSubobject = Offset.NonVirtualOffset; 1227 1228 if (Offset.VirtualBase) { 1229 // If we have a virtual base class, the non-virtual offset is relative 1230 // to the virtual base class offset. 1231 const ASTRecordLayout &LayoutClassLayout = 1232 Context.getASTRecordLayout(LayoutClass); 1233 1234 /// Get the virtual base offset, relative to the most derived class 1235 /// layout. 1236 OffsetToBaseSubobject += 1237 LayoutClassLayout.getVBaseClassOffset(Offset.VirtualBase); 1238 } else { 1239 // Otherwise, the non-virtual offset is relative to the derived class 1240 // offset. 1241 OffsetToBaseSubobject += Derived.getBaseOffset(); 1242 } 1243 1244 // Check if this path gives us the right base subobject. 1245 if (OffsetToBaseSubobject == Base.getBaseOffset()) { 1246 // Since we're going from the base class _to_ the derived class, we'll 1247 // invert the non-virtual offset here. 1248 Offset.NonVirtualOffset = -Offset.NonVirtualOffset; 1249 return Offset; 1250 } 1251 } 1252 1253 return BaseOffset(); 1254 } 1255 1256 ThisAdjustment 1257 VTableBuilder::ComputeThisAdjustment(const CXXMethodDecl *MD, 1258 CharUnits BaseOffsetInLayoutClass, 1259 FinalOverriders::OverriderInfo Overrider) { 1260 // Ignore adjustments for pure virtual member functions. 1261 if (Overrider.Method->isPure()) 1262 return ThisAdjustment(); 1263 1264 BaseSubobject OverriddenBaseSubobject(MD->getParent(), 1265 BaseOffsetInLayoutClass); 1266 1267 BaseSubobject OverriderBaseSubobject(Overrider.Method->getParent(), 1268 Overrider.Offset); 1269 1270 // Compute the adjustment offset. 1271 BaseOffset Offset = ComputeThisAdjustmentBaseOffset(OverriddenBaseSubobject, 1272 OverriderBaseSubobject); 1273 if (Offset.isEmpty()) 1274 return ThisAdjustment(); 1275 1276 ThisAdjustment Adjustment; 1277 1278 if (Offset.VirtualBase) { 1279 // Get the vcall offset map for this virtual base. 1280 VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Offset.VirtualBase]; 1281 1282 if (VCallOffsets.empty()) { 1283 // We don't have vcall offsets for this virtual base, go ahead and 1284 // build them. 1285 VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClass, 1286 /*FinalOverriders=*/0, 1287 BaseSubobject(Offset.VirtualBase, 1288 CharUnits::Zero()), 1289 /*BaseIsVirtual=*/true, 1290 /*OffsetInLayoutClass=*/ 1291 CharUnits::Zero()); 1292 1293 VCallOffsets = Builder.getVCallOffsets(); 1294 } 1295 1296 Adjustment.VCallOffsetOffset = 1297 VCallOffsets.getVCallOffsetOffset(MD).getQuantity(); 1298 } 1299 1300 // Set the non-virtual part of the adjustment. 1301 Adjustment.NonVirtual = Offset.NonVirtualOffset.getQuantity(); 1302 1303 return Adjustment; 1304 } 1305 1306 void 1307 VTableBuilder::AddMethod(const CXXMethodDecl *MD, 1308 ReturnAdjustment ReturnAdjustment) { 1309 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 1310 assert(ReturnAdjustment.isEmpty() && 1311 "Destructor can't have return adjustment!"); 1312 1313 // FIXME: Should probably add a layer of abstraction for vtable generation. 1314 if (!isMicrosoftABI()) { 1315 // Add both the complete destructor and the deleting destructor. 1316 Components.push_back(VTableComponent::MakeCompleteDtor(DD)); 1317 Components.push_back(VTableComponent::MakeDeletingDtor(DD)); 1318 } else { 1319 // Add the scalar deleting destructor. 1320 Components.push_back(VTableComponent::MakeDeletingDtor(DD)); 1321 } 1322 } else { 1323 // Add the return adjustment if necessary. 1324 if (!ReturnAdjustment.isEmpty()) 1325 VTableThunks[Components.size()].Return = ReturnAdjustment; 1326 1327 // Add the function. 1328 Components.push_back(VTableComponent::MakeFunction(MD)); 1329 } 1330 } 1331 1332 /// OverridesIndirectMethodInBase - Return whether the given member function 1333 /// overrides any methods in the set of given bases. 1334 /// Unlike OverridesMethodInBase, this checks "overriders of overriders". 1335 /// For example, if we have: 1336 /// 1337 /// struct A { virtual void f(); } 1338 /// struct B : A { virtual void f(); } 1339 /// struct C : B { virtual void f(); } 1340 /// 1341 /// OverridesIndirectMethodInBase will return true if given C::f as the method 1342 /// and { A } as the set of bases. 1343 static bool 1344 OverridesIndirectMethodInBases(const CXXMethodDecl *MD, 1345 VTableBuilder::PrimaryBasesSetVectorTy &Bases) { 1346 if (Bases.count(MD->getParent())) 1347 return true; 1348 1349 for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), 1350 E = MD->end_overridden_methods(); I != E; ++I) { 1351 const CXXMethodDecl *OverriddenMD = *I; 1352 1353 // Check "indirect overriders". 1354 if (OverridesIndirectMethodInBases(OverriddenMD, Bases)) 1355 return true; 1356 } 1357 1358 return false; 1359 } 1360 1361 bool 1362 VTableBuilder::IsOverriderUsed(const CXXMethodDecl *Overrider, 1363 CharUnits BaseOffsetInLayoutClass, 1364 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 1365 CharUnits FirstBaseOffsetInLayoutClass) const { 1366 // If the base and the first base in the primary base chain have the same 1367 // offsets, then this overrider will be used. 1368 if (BaseOffsetInLayoutClass == FirstBaseOffsetInLayoutClass) 1369 return true; 1370 1371 // We know now that Base (or a direct or indirect base of it) is a primary 1372 // base in part of the class hierarchy, but not a primary base in the most 1373 // derived class. 1374 1375 // If the overrider is the first base in the primary base chain, we know 1376 // that the overrider will be used. 1377 if (Overrider->getParent() == FirstBaseInPrimaryBaseChain) 1378 return true; 1379 1380 VTableBuilder::PrimaryBasesSetVectorTy PrimaryBases; 1381 1382 const CXXRecordDecl *RD = FirstBaseInPrimaryBaseChain; 1383 PrimaryBases.insert(RD); 1384 1385 // Now traverse the base chain, starting with the first base, until we find 1386 // the base that is no longer a primary base. 1387 while (true) { 1388 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1389 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 1390 1391 if (!PrimaryBase) 1392 break; 1393 1394 if (Layout.isPrimaryBaseVirtual()) { 1395 assert(Layout.getVBaseClassOffset(PrimaryBase).isZero() && 1396 "Primary base should always be at offset 0!"); 1397 1398 const ASTRecordLayout &LayoutClassLayout = 1399 Context.getASTRecordLayout(LayoutClass); 1400 1401 // Now check if this is the primary base that is not a primary base in the 1402 // most derived class. 1403 if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) != 1404 FirstBaseOffsetInLayoutClass) { 1405 // We found it, stop walking the chain. 1406 break; 1407 } 1408 } else { 1409 assert(Layout.getBaseClassOffset(PrimaryBase).isZero() && 1410 "Primary base should always be at offset 0!"); 1411 } 1412 1413 if (!PrimaryBases.insert(PrimaryBase)) 1414 llvm_unreachable("Found a duplicate primary base!"); 1415 1416 RD = PrimaryBase; 1417 } 1418 1419 // If the final overrider is an override of one of the primary bases, 1420 // then we know that it will be used. 1421 return OverridesIndirectMethodInBases(Overrider, PrimaryBases); 1422 } 1423 1424 /// FindNearestOverriddenMethod - Given a method, returns the overridden method 1425 /// from the nearest base. Returns null if no method was found. 1426 static const CXXMethodDecl * 1427 FindNearestOverriddenMethod(const CXXMethodDecl *MD, 1428 VTableBuilder::PrimaryBasesSetVectorTy &Bases) { 1429 OverriddenMethodsSetTy OverriddenMethods; 1430 ComputeAllOverriddenMethods(MD, OverriddenMethods); 1431 1432 for (int I = Bases.size(), E = 0; I != E; --I) { 1433 const CXXRecordDecl *PrimaryBase = Bases[I - 1]; 1434 1435 // Now check the overriden methods. 1436 for (OverriddenMethodsSetTy::const_iterator I = OverriddenMethods.begin(), 1437 E = OverriddenMethods.end(); I != E; ++I) { 1438 const CXXMethodDecl *OverriddenMD = *I; 1439 1440 // We found our overridden method. 1441 if (OverriddenMD->getParent() == PrimaryBase) 1442 return OverriddenMD; 1443 } 1444 } 1445 1446 return 0; 1447 } 1448 1449 void 1450 VTableBuilder::AddMethods(BaseSubobject Base, CharUnits BaseOffsetInLayoutClass, 1451 const CXXRecordDecl *FirstBaseInPrimaryBaseChain, 1452 CharUnits FirstBaseOffsetInLayoutClass, 1453 PrimaryBasesSetVectorTy &PrimaryBases) { 1454 // Itanium C++ ABI 2.5.2: 1455 // The order of the virtual function pointers in a virtual table is the 1456 // order of declaration of the corresponding member functions in the class. 1457 // 1458 // There is an entry for any virtual function declared in a class, 1459 // whether it is a new function or overrides a base class function, 1460 // unless it overrides a function from the primary base, and conversion 1461 // between their return types does not require an adjustment. 1462 1463 const CXXRecordDecl *RD = Base.getBase(); 1464 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1465 1466 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 1467 CharUnits PrimaryBaseOffset; 1468 CharUnits PrimaryBaseOffsetInLayoutClass; 1469 if (Layout.isPrimaryBaseVirtual()) { 1470 assert(Layout.getVBaseClassOffset(PrimaryBase).isZero() && 1471 "Primary vbase should have a zero offset!"); 1472 1473 const ASTRecordLayout &MostDerivedClassLayout = 1474 Context.getASTRecordLayout(MostDerivedClass); 1475 1476 PrimaryBaseOffset = 1477 MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); 1478 1479 const ASTRecordLayout &LayoutClassLayout = 1480 Context.getASTRecordLayout(LayoutClass); 1481 1482 PrimaryBaseOffsetInLayoutClass = 1483 LayoutClassLayout.getVBaseClassOffset(PrimaryBase); 1484 } else { 1485 assert(Layout.getBaseClassOffset(PrimaryBase).isZero() && 1486 "Primary base should have a zero offset!"); 1487 1488 PrimaryBaseOffset = Base.getBaseOffset(); 1489 PrimaryBaseOffsetInLayoutClass = BaseOffsetInLayoutClass; 1490 } 1491 1492 AddMethods(BaseSubobject(PrimaryBase, PrimaryBaseOffset), 1493 PrimaryBaseOffsetInLayoutClass, FirstBaseInPrimaryBaseChain, 1494 FirstBaseOffsetInLayoutClass, PrimaryBases); 1495 1496 if (!PrimaryBases.insert(PrimaryBase)) 1497 llvm_unreachable("Found a duplicate primary base!"); 1498 } 1499 1500 const CXXDestructorDecl *ImplicitVirtualDtor = 0; 1501 1502 typedef llvm::SmallVector<const CXXMethodDecl *, 8> NewVirtualFunctionsTy; 1503 NewVirtualFunctionsTy NewVirtualFunctions; 1504 1505 // Now go through all virtual member functions and add them. 1506 for (CXXRecordDecl::method_iterator I = RD->method_begin(), 1507 E = RD->method_end(); I != E; ++I) { 1508 const CXXMethodDecl *MD = *I; 1509 1510 if (!MD->isVirtual()) 1511 continue; 1512 1513 // Get the final overrider. 1514 FinalOverriders::OverriderInfo Overrider = 1515 Overriders.getOverrider(MD, Base.getBaseOffset()); 1516 1517 // Check if this virtual member function overrides a method in a primary 1518 // base. If this is the case, and the return type doesn't require adjustment 1519 // then we can just use the member function from the primary base. 1520 if (const CXXMethodDecl *OverriddenMD = 1521 FindNearestOverriddenMethod(MD, PrimaryBases)) { 1522 if (ComputeReturnAdjustmentBaseOffset(Context, MD, 1523 OverriddenMD).isEmpty()) { 1524 // Replace the method info of the overridden method with our own 1525 // method. 1526 assert(MethodInfoMap.count(OverriddenMD) && 1527 "Did not find the overridden method!"); 1528 MethodInfo &OverriddenMethodInfo = MethodInfoMap[OverriddenMD]; 1529 1530 MethodInfo MethodInfo(Base.getBaseOffset(), BaseOffsetInLayoutClass, 1531 OverriddenMethodInfo.VTableIndex); 1532 1533 assert(!MethodInfoMap.count(MD) && 1534 "Should not have method info for this method yet!"); 1535 1536 MethodInfoMap.insert(std::make_pair(MD, MethodInfo)); 1537 MethodInfoMap.erase(OverriddenMD); 1538 1539 // If the overridden method exists in a virtual base class or a direct 1540 // or indirect base class of a virtual base class, we need to emit a 1541 // thunk if we ever have a class hierarchy where the base class is not 1542 // a primary base in the complete object. 1543 if (!isBuildingConstructorVTable() && OverriddenMD != MD) { 1544 // Compute the this adjustment. 1545 ThisAdjustment ThisAdjustment = 1546 ComputeThisAdjustment(OverriddenMD, BaseOffsetInLayoutClass, 1547 Overrider); 1548 1549 if (ThisAdjustment.VCallOffsetOffset && 1550 Overrider.Method->getParent() == MostDerivedClass) { 1551 1552 // There's no return adjustment from OverriddenMD and MD, 1553 // but that doesn't mean there isn't one between MD and 1554 // the final overrider. 1555 BaseOffset ReturnAdjustmentOffset = 1556 ComputeReturnAdjustmentBaseOffset(Context, Overrider.Method, MD); 1557 ReturnAdjustment ReturnAdjustment = 1558 ComputeReturnAdjustment(ReturnAdjustmentOffset); 1559 1560 // This is a virtual thunk for the most derived class, add it. 1561 AddThunk(Overrider.Method, 1562 ThunkInfo(ThisAdjustment, ReturnAdjustment)); 1563 } 1564 } 1565 1566 continue; 1567 } 1568 } 1569 1570 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 1571 if (MD->isImplicit()) { 1572 // Itanium C++ ABI 2.5.2: 1573 // If a class has an implicitly-defined virtual destructor, 1574 // its entries come after the declared virtual function pointers. 1575 1576 assert(!ImplicitVirtualDtor && 1577 "Did already see an implicit virtual dtor!"); 1578 ImplicitVirtualDtor = DD; 1579 continue; 1580 } 1581 } 1582 1583 NewVirtualFunctions.push_back(MD); 1584 } 1585 1586 if (ImplicitVirtualDtor) 1587 NewVirtualFunctions.push_back(ImplicitVirtualDtor); 1588 1589 for (NewVirtualFunctionsTy::const_iterator I = NewVirtualFunctions.begin(), 1590 E = NewVirtualFunctions.end(); I != E; ++I) { 1591 const CXXMethodDecl *MD = *I; 1592 1593 // Get the final overrider. 1594 FinalOverriders::OverriderInfo Overrider = 1595 Overriders.getOverrider(MD, Base.getBaseOffset()); 1596 1597 // Insert the method info for this method. 1598 MethodInfo MethodInfo(Base.getBaseOffset(), BaseOffsetInLayoutClass, 1599 Components.size()); 1600 1601 assert(!MethodInfoMap.count(MD) && 1602 "Should not have method info for this method yet!"); 1603 MethodInfoMap.insert(std::make_pair(MD, MethodInfo)); 1604 1605 // Check if this overrider is going to be used. 1606 const CXXMethodDecl *OverriderMD = Overrider.Method; 1607 if (!IsOverriderUsed(OverriderMD, BaseOffsetInLayoutClass, 1608 FirstBaseInPrimaryBaseChain, 1609 FirstBaseOffsetInLayoutClass)) { 1610 Components.push_back(VTableComponent::MakeUnusedFunction(OverriderMD)); 1611 continue; 1612 } 1613 1614 // Check if this overrider needs a return adjustment. 1615 // We don't want to do this for pure virtual member functions. 1616 BaseOffset ReturnAdjustmentOffset; 1617 if (!OverriderMD->isPure()) { 1618 ReturnAdjustmentOffset = 1619 ComputeReturnAdjustmentBaseOffset(Context, OverriderMD, MD); 1620 } 1621 1622 ReturnAdjustment ReturnAdjustment = 1623 ComputeReturnAdjustment(ReturnAdjustmentOffset); 1624 1625 AddMethod(Overrider.Method, ReturnAdjustment); 1626 } 1627 } 1628 1629 void VTableBuilder::LayoutVTable() { 1630 LayoutPrimaryAndSecondaryVTables(BaseSubobject(MostDerivedClass, 1631 CharUnits::Zero()), 1632 /*BaseIsMorallyVirtual=*/false, 1633 MostDerivedClassIsVirtual, 1634 MostDerivedClassOffset); 1635 1636 VisitedVirtualBasesSetTy VBases; 1637 1638 // Determine the primary virtual bases. 1639 DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset, 1640 VBases); 1641 VBases.clear(); 1642 1643 LayoutVTablesForVirtualBases(MostDerivedClass, VBases); 1644 1645 // -fapple-kext adds an extra entry at end of vtbl. 1646 bool IsAppleKext = Context.getLangOpts().AppleKext; 1647 if (IsAppleKext) 1648 Components.push_back(VTableComponent::MakeVCallOffset(CharUnits::Zero())); 1649 } 1650 1651 void 1652 VTableBuilder::LayoutPrimaryAndSecondaryVTables(BaseSubobject Base, 1653 bool BaseIsMorallyVirtual, 1654 bool BaseIsVirtualInLayoutClass, 1655 CharUnits OffsetInLayoutClass) { 1656 assert(Base.getBase()->isDynamicClass() && "class does not have a vtable!"); 1657 1658 // Add vcall and vbase offsets for this vtable. 1659 VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, LayoutClass, &Overriders, 1660 Base, BaseIsVirtualInLayoutClass, 1661 OffsetInLayoutClass); 1662 Components.append(Builder.components_begin(), Builder.components_end()); 1663 1664 // Check if we need to add these vcall offsets. 1665 if (BaseIsVirtualInLayoutClass && !Builder.getVCallOffsets().empty()) { 1666 VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Base.getBase()]; 1667 1668 if (VCallOffsets.empty()) 1669 VCallOffsets = Builder.getVCallOffsets(); 1670 } 1671 1672 // If we're laying out the most derived class we want to keep track of the 1673 // virtual base class offset offsets. 1674 if (Base.getBase() == MostDerivedClass) 1675 VBaseOffsetOffsets = Builder.getVBaseOffsetOffsets(); 1676 1677 // FIXME: Should probably add a layer of abstraction for vtable generation. 1678 if (!isMicrosoftABI()) { 1679 // Add the offset to top. 1680 CharUnits OffsetToTop = MostDerivedClassOffset - OffsetInLayoutClass; 1681 Components.push_back(VTableComponent::MakeOffsetToTop(OffsetToTop)); 1682 1683 // Next, add the RTTI. 1684 Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass)); 1685 } else { 1686 // FIXME: unclear what to do with RTTI in MS ABI as emitting it anywhere 1687 // breaks the vftable layout. Just skip RTTI for now, can't mangle anyway. 1688 } 1689 1690 uint64_t AddressPoint = Components.size(); 1691 1692 // Now go through all virtual member functions and add them. 1693 PrimaryBasesSetVectorTy PrimaryBases; 1694 AddMethods(Base, OffsetInLayoutClass, 1695 Base.getBase(), OffsetInLayoutClass, 1696 PrimaryBases); 1697 1698 const CXXRecordDecl *RD = Base.getBase(); 1699 if (RD == MostDerivedClass) { 1700 assert(MethodVTableIndices.empty()); 1701 for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(), 1702 E = MethodInfoMap.end(); I != E; ++I) { 1703 const CXXMethodDecl *MD = I->first; 1704 const MethodInfo &MI = I->second; 1705 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 1706 // FIXME: Should probably add a layer of abstraction for vtable generation. 1707 if (!isMicrosoftABI()) { 1708 MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] 1709 = MI.VTableIndex - AddressPoint; 1710 MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] 1711 = MI.VTableIndex + 1 - AddressPoint; 1712 } else { 1713 MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] 1714 = MI.VTableIndex - AddressPoint; 1715 } 1716 } else { 1717 MethodVTableIndices[MD] = MI.VTableIndex - AddressPoint; 1718 } 1719 } 1720 } 1721 1722 // Compute 'this' pointer adjustments. 1723 ComputeThisAdjustments(); 1724 1725 // Add all address points. 1726 while (true) { 1727 AddressPoints.insert(std::make_pair( 1728 BaseSubobject(RD, OffsetInLayoutClass), 1729 AddressPoint)); 1730 1731 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1732 const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 1733 1734 if (!PrimaryBase) 1735 break; 1736 1737 if (Layout.isPrimaryBaseVirtual()) { 1738 // Check if this virtual primary base is a primary base in the layout 1739 // class. If it's not, we don't want to add it. 1740 const ASTRecordLayout &LayoutClassLayout = 1741 Context.getASTRecordLayout(LayoutClass); 1742 1743 if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) != 1744 OffsetInLayoutClass) { 1745 // We don't want to add this class (or any of its primary bases). 1746 break; 1747 } 1748 } 1749 1750 RD = PrimaryBase; 1751 } 1752 1753 // Layout secondary vtables. 1754 LayoutSecondaryVTables(Base, BaseIsMorallyVirtual, OffsetInLayoutClass); 1755 } 1756 1757 void VTableBuilder::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 = 1776 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1777 1778 // Ignore bases that don't have a vtable. 1779 if (!BaseDecl->isDynamicClass()) 1780 continue; 1781 1782 if (isBuildingConstructorVTable()) { 1783 // Itanium C++ ABI 2.6.4: 1784 // Some of the base class subobjects may not need construction virtual 1785 // tables, which will therefore not be present in the construction 1786 // virtual table group, even though the subobject virtual tables are 1787 // present in the main virtual table group for the complete object. 1788 if (!BaseIsMorallyVirtual && !BaseDecl->getNumVBases()) 1789 continue; 1790 } 1791 1792 // Get the base offset of this base. 1793 CharUnits RelativeBaseOffset = Layout.getBaseClassOffset(BaseDecl); 1794 CharUnits BaseOffset = Base.getBaseOffset() + RelativeBaseOffset; 1795 1796 CharUnits BaseOffsetInLayoutClass = 1797 OffsetInLayoutClass + RelativeBaseOffset; 1798 1799 // Don't emit a secondary vtable for a primary base. We might however want 1800 // to emit secondary vtables for other bases of this base. 1801 if (BaseDecl == PrimaryBase) { 1802 LayoutSecondaryVTables(BaseSubobject(BaseDecl, BaseOffset), 1803 BaseIsMorallyVirtual, BaseOffsetInLayoutClass); 1804 continue; 1805 } 1806 1807 // Layout the primary vtable (and any secondary vtables) for this base. 1808 LayoutPrimaryAndSecondaryVTables( 1809 BaseSubobject(BaseDecl, BaseOffset), 1810 BaseIsMorallyVirtual, 1811 /*BaseIsVirtualInLayoutClass=*/false, 1812 BaseOffsetInLayoutClass); 1813 } 1814 } 1815 1816 void 1817 VTableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, 1818 CharUnits OffsetInLayoutClass, 1819 VisitedVirtualBasesSetTy &VBases) { 1820 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1821 1822 // Check if this base has a primary base. 1823 if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { 1824 1825 // Check if it's virtual. 1826 if (Layout.isPrimaryBaseVirtual()) { 1827 bool IsPrimaryVirtualBase = true; 1828 1829 if (isBuildingConstructorVTable()) { 1830 // Check if the base is actually a primary base in the class we use for 1831 // layout. 1832 const ASTRecordLayout &LayoutClassLayout = 1833 Context.getASTRecordLayout(LayoutClass); 1834 1835 CharUnits PrimaryBaseOffsetInLayoutClass = 1836 LayoutClassLayout.getVBaseClassOffset(PrimaryBase); 1837 1838 // We know that the base is not a primary base in the layout class if 1839 // the base offsets are different. 1840 if (PrimaryBaseOffsetInLayoutClass != OffsetInLayoutClass) 1841 IsPrimaryVirtualBase = false; 1842 } 1843 1844 if (IsPrimaryVirtualBase) 1845 PrimaryVirtualBases.insert(PrimaryBase); 1846 } 1847 } 1848 1849 // Traverse bases, looking for more primary virtual bases. 1850 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1851 E = RD->bases_end(); I != E; ++I) { 1852 const CXXRecordDecl *BaseDecl = 1853 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1854 1855 CharUnits BaseOffsetInLayoutClass; 1856 1857 if (I->isVirtual()) { 1858 if (!VBases.insert(BaseDecl)) 1859 continue; 1860 1861 const ASTRecordLayout &LayoutClassLayout = 1862 Context.getASTRecordLayout(LayoutClass); 1863 1864 BaseOffsetInLayoutClass = 1865 LayoutClassLayout.getVBaseClassOffset(BaseDecl); 1866 } else { 1867 BaseOffsetInLayoutClass = 1868 OffsetInLayoutClass + Layout.getBaseClassOffset(BaseDecl); 1869 } 1870 1871 DeterminePrimaryVirtualBases(BaseDecl, BaseOffsetInLayoutClass, VBases); 1872 } 1873 } 1874 1875 void 1876 VTableBuilder::LayoutVTablesForVirtualBases(const CXXRecordDecl *RD, 1877 VisitedVirtualBasesSetTy &VBases) { 1878 // Itanium C++ ABI 2.5.2: 1879 // Then come the virtual base virtual tables, also in inheritance graph 1880 // order, and again excluding primary bases (which share virtual tables with 1881 // the classes for which they are primary). 1882 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1883 E = RD->bases_end(); I != E; ++I) { 1884 const CXXRecordDecl *BaseDecl = 1885 cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1886 1887 // Check if this base needs a vtable. (If it's virtual, not a primary base 1888 // of some other class, and we haven't visited it before). 1889 if (I->isVirtual() && BaseDecl->isDynamicClass() && 1890 !PrimaryVirtualBases.count(BaseDecl) && VBases.insert(BaseDecl)) { 1891 const ASTRecordLayout &MostDerivedClassLayout = 1892 Context.getASTRecordLayout(MostDerivedClass); 1893 CharUnits BaseOffset = 1894 MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); 1895 1896 const ASTRecordLayout &LayoutClassLayout = 1897 Context.getASTRecordLayout(LayoutClass); 1898 CharUnits BaseOffsetInLayoutClass = 1899 LayoutClassLayout.getVBaseClassOffset(BaseDecl); 1900 1901 LayoutPrimaryAndSecondaryVTables( 1902 BaseSubobject(BaseDecl, BaseOffset), 1903 /*BaseIsMorallyVirtual=*/true, 1904 /*BaseIsVirtualInLayoutClass=*/true, 1905 BaseOffsetInLayoutClass); 1906 } 1907 1908 // We only need to check the base for virtual base vtables if it actually 1909 // has virtual bases. 1910 if (BaseDecl->getNumVBases()) 1911 LayoutVTablesForVirtualBases(BaseDecl, VBases); 1912 } 1913 } 1914 1915 /// dumpLayout - Dump the vtable layout. 1916 void VTableBuilder::dumpLayout(raw_ostream& Out) { 1917 1918 if (isBuildingConstructorVTable()) { 1919 Out << "Construction vtable for ('"; 1920 Out << MostDerivedClass->getQualifiedNameAsString() << "', "; 1921 Out << MostDerivedClassOffset.getQuantity() << ") in '"; 1922 Out << LayoutClass->getQualifiedNameAsString(); 1923 } else { 1924 Out << "Vtable for '"; 1925 Out << MostDerivedClass->getQualifiedNameAsString(); 1926 } 1927 Out << "' (" << Components.size() << " entries).\n"; 1928 1929 // Iterate through the address points and insert them into a new map where 1930 // they are keyed by the index and not the base object. 1931 // Since an address point can be shared by multiple subobjects, we use an 1932 // STL multimap. 1933 std::multimap<uint64_t, BaseSubobject> AddressPointsByIndex; 1934 for (AddressPointsMapTy::const_iterator I = AddressPoints.begin(), 1935 E = AddressPoints.end(); I != E; ++I) { 1936 const BaseSubobject& Base = I->first; 1937 uint64_t Index = I->second; 1938 1939 AddressPointsByIndex.insert(std::make_pair(Index, Base)); 1940 } 1941 1942 for (unsigned I = 0, E = Components.size(); I != E; ++I) { 1943 uint64_t Index = I; 1944 1945 Out << llvm::format("%4d | ", I); 1946 1947 const VTableComponent &Component = Components[I]; 1948 1949 // Dump the component. 1950 switch (Component.getKind()) { 1951 1952 case VTableComponent::CK_VCallOffset: 1953 Out << "vcall_offset (" 1954 << Component.getVCallOffset().getQuantity() 1955 << ")"; 1956 break; 1957 1958 case VTableComponent::CK_VBaseOffset: 1959 Out << "vbase_offset (" 1960 << Component.getVBaseOffset().getQuantity() 1961 << ")"; 1962 break; 1963 1964 case VTableComponent::CK_OffsetToTop: 1965 Out << "offset_to_top (" 1966 << Component.getOffsetToTop().getQuantity() 1967 << ")"; 1968 break; 1969 1970 case VTableComponent::CK_RTTI: 1971 Out << Component.getRTTIDecl()->getQualifiedNameAsString() << " RTTI"; 1972 break; 1973 1974 case VTableComponent::CK_FunctionPointer: { 1975 const CXXMethodDecl *MD = Component.getFunctionDecl(); 1976 1977 std::string Str = 1978 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 1979 MD); 1980 Out << Str; 1981 if (MD->isPure()) 1982 Out << " [pure]"; 1983 1984 if (MD->isDeleted()) 1985 Out << " [deleted]"; 1986 1987 ThunkInfo Thunk = VTableThunks.lookup(I); 1988 if (!Thunk.isEmpty()) { 1989 // If this function pointer has a return adjustment, dump it. 1990 if (!Thunk.Return.isEmpty()) { 1991 Out << "\n [return adjustment: "; 1992 Out << Thunk.Return.NonVirtual << " non-virtual"; 1993 1994 if (Thunk.Return.VBaseOffsetOffset) { 1995 Out << ", " << Thunk.Return.VBaseOffsetOffset; 1996 Out << " vbase offset offset"; 1997 } 1998 1999 Out << ']'; 2000 } 2001 2002 // If this function pointer has a 'this' pointer adjustment, dump it. 2003 if (!Thunk.This.isEmpty()) { 2004 Out << "\n [this adjustment: "; 2005 Out << Thunk.This.NonVirtual << " non-virtual"; 2006 2007 if (Thunk.This.VCallOffsetOffset) { 2008 Out << ", " << Thunk.This.VCallOffsetOffset; 2009 Out << " vcall offset offset"; 2010 } 2011 2012 Out << ']'; 2013 } 2014 } 2015 2016 break; 2017 } 2018 2019 case VTableComponent::CK_CompleteDtorPointer: 2020 case VTableComponent::CK_DeletingDtorPointer: { 2021 bool IsComplete = 2022 Component.getKind() == VTableComponent::CK_CompleteDtorPointer; 2023 2024 const CXXDestructorDecl *DD = Component.getDestructorDecl(); 2025 2026 Out << DD->getQualifiedNameAsString(); 2027 if (IsComplete) 2028 Out << "() [complete]"; 2029 else if (isMicrosoftABI()) 2030 Out << "() [scalar deleting]"; 2031 else 2032 Out << "() [deleting]"; 2033 2034 if (DD->isPure()) 2035 Out << " [pure]"; 2036 2037 ThunkInfo Thunk = VTableThunks.lookup(I); 2038 if (!Thunk.isEmpty()) { 2039 // If this destructor has a 'this' pointer adjustment, dump it. 2040 if (!Thunk.This.isEmpty()) { 2041 Out << "\n [this adjustment: "; 2042 Out << Thunk.This.NonVirtual << " non-virtual"; 2043 2044 if (Thunk.This.VCallOffsetOffset) { 2045 Out << ", " << Thunk.This.VCallOffsetOffset; 2046 Out << " vcall offset offset"; 2047 } 2048 2049 Out << ']'; 2050 } 2051 } 2052 2053 break; 2054 } 2055 2056 case VTableComponent::CK_UnusedFunctionPointer: { 2057 const CXXMethodDecl *MD = Component.getUnusedFunctionDecl(); 2058 2059 std::string Str = 2060 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2061 MD); 2062 Out << "[unused] " << Str; 2063 if (MD->isPure()) 2064 Out << " [pure]"; 2065 } 2066 2067 } 2068 2069 Out << '\n'; 2070 2071 // Dump the next address point. 2072 uint64_t NextIndex = Index + 1; 2073 if (AddressPointsByIndex.count(NextIndex)) { 2074 if (AddressPointsByIndex.count(NextIndex) == 1) { 2075 const BaseSubobject &Base = 2076 AddressPointsByIndex.find(NextIndex)->second; 2077 2078 Out << " -- (" << Base.getBase()->getQualifiedNameAsString(); 2079 Out << ", " << Base.getBaseOffset().getQuantity(); 2080 Out << ") vtable address --\n"; 2081 } else { 2082 CharUnits BaseOffset = 2083 AddressPointsByIndex.lower_bound(NextIndex)->second.getBaseOffset(); 2084 2085 // We store the class names in a set to get a stable order. 2086 std::set<std::string> ClassNames; 2087 for (std::multimap<uint64_t, BaseSubobject>::const_iterator I = 2088 AddressPointsByIndex.lower_bound(NextIndex), E = 2089 AddressPointsByIndex.upper_bound(NextIndex); I != E; ++I) { 2090 assert(I->second.getBaseOffset() == BaseOffset && 2091 "Invalid base offset!"); 2092 const CXXRecordDecl *RD = I->second.getBase(); 2093 ClassNames.insert(RD->getQualifiedNameAsString()); 2094 } 2095 2096 for (std::set<std::string>::const_iterator I = ClassNames.begin(), 2097 E = ClassNames.end(); I != E; ++I) { 2098 Out << " -- (" << *I; 2099 Out << ", " << BaseOffset.getQuantity() << ") vtable address --\n"; 2100 } 2101 } 2102 } 2103 } 2104 2105 Out << '\n'; 2106 2107 if (isBuildingConstructorVTable()) 2108 return; 2109 2110 if (MostDerivedClass->getNumVBases()) { 2111 // We store the virtual base class names and their offsets in a map to get 2112 // a stable order. 2113 2114 std::map<std::string, CharUnits> ClassNamesAndOffsets; 2115 for (VBaseOffsetOffsetsMapTy::const_iterator I = VBaseOffsetOffsets.begin(), 2116 E = VBaseOffsetOffsets.end(); I != E; ++I) { 2117 std::string ClassName = I->first->getQualifiedNameAsString(); 2118 CharUnits OffsetOffset = I->second; 2119 ClassNamesAndOffsets.insert( 2120 std::make_pair(ClassName, OffsetOffset)); 2121 } 2122 2123 Out << "Virtual base offset offsets for '"; 2124 Out << MostDerivedClass->getQualifiedNameAsString() << "' ("; 2125 Out << ClassNamesAndOffsets.size(); 2126 Out << (ClassNamesAndOffsets.size() == 1 ? " entry" : " entries") << ").\n"; 2127 2128 for (std::map<std::string, CharUnits>::const_iterator I = 2129 ClassNamesAndOffsets.begin(), E = ClassNamesAndOffsets.end(); 2130 I != E; ++I) 2131 Out << " " << I->first << " | " << I->second.getQuantity() << '\n'; 2132 2133 Out << "\n"; 2134 } 2135 2136 if (!Thunks.empty()) { 2137 // We store the method names in a map to get a stable order. 2138 std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls; 2139 2140 for (ThunksMapTy::const_iterator I = Thunks.begin(), E = Thunks.end(); 2141 I != E; ++I) { 2142 const CXXMethodDecl *MD = I->first; 2143 std::string MethodName = 2144 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2145 MD); 2146 2147 MethodNamesAndDecls.insert(std::make_pair(MethodName, MD)); 2148 } 2149 2150 for (std::map<std::string, const CXXMethodDecl *>::const_iterator I = 2151 MethodNamesAndDecls.begin(), E = MethodNamesAndDecls.end(); 2152 I != E; ++I) { 2153 const std::string &MethodName = I->first; 2154 const CXXMethodDecl *MD = I->second; 2155 2156 ThunkInfoVectorTy ThunksVector = Thunks[MD]; 2157 std::sort(ThunksVector.begin(), ThunksVector.end()); 2158 2159 Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size(); 2160 Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n"; 2161 2162 for (unsigned I = 0, E = ThunksVector.size(); I != E; ++I) { 2163 const ThunkInfo &Thunk = ThunksVector[I]; 2164 2165 Out << llvm::format("%4d | ", I); 2166 2167 // If this function pointer has a return pointer adjustment, dump it. 2168 if (!Thunk.Return.isEmpty()) { 2169 Out << "return adjustment: " << Thunk.This.NonVirtual; 2170 Out << " non-virtual"; 2171 if (Thunk.Return.VBaseOffsetOffset) { 2172 Out << ", " << Thunk.Return.VBaseOffsetOffset; 2173 Out << " vbase offset offset"; 2174 } 2175 2176 if (!Thunk.This.isEmpty()) 2177 Out << "\n "; 2178 } 2179 2180 // If this function pointer has a 'this' pointer adjustment, dump it. 2181 if (!Thunk.This.isEmpty()) { 2182 Out << "this adjustment: "; 2183 Out << Thunk.This.NonVirtual << " non-virtual"; 2184 2185 if (Thunk.This.VCallOffsetOffset) { 2186 Out << ", " << Thunk.This.VCallOffsetOffset; 2187 Out << " vcall offset offset"; 2188 } 2189 } 2190 2191 Out << '\n'; 2192 } 2193 2194 Out << '\n'; 2195 } 2196 } 2197 2198 // Compute the vtable indices for all the member functions. 2199 // Store them in a map keyed by the index so we'll get a sorted table. 2200 std::map<uint64_t, std::string> IndicesMap; 2201 2202 for (CXXRecordDecl::method_iterator i = MostDerivedClass->method_begin(), 2203 e = MostDerivedClass->method_end(); i != e; ++i) { 2204 const CXXMethodDecl *MD = *i; 2205 2206 // We only want virtual member functions. 2207 if (!MD->isVirtual()) 2208 continue; 2209 2210 std::string MethodName = 2211 PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, 2212 MD); 2213 2214 if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { 2215 // FIXME: Should add a layer of abstraction for vtable generation. 2216 if (!isMicrosoftABI()) { 2217 GlobalDecl GD(DD, Dtor_Complete); 2218 assert(MethodVTableIndices.count(GD)); 2219 uint64_t VTableIndex = MethodVTableIndices[GD]; 2220 IndicesMap[VTableIndex] = MethodName + " [complete]"; 2221 IndicesMap[VTableIndex + 1] = MethodName + " [deleting]"; 2222 } else { 2223 GlobalDecl GD(DD, Dtor_Deleting); 2224 assert(MethodVTableIndices.count(GD)); 2225 IndicesMap[MethodVTableIndices[GD]] = MethodName + " [scalar deleting]"; 2226 } 2227 } else { 2228 assert(MethodVTableIndices.count(MD)); 2229 IndicesMap[MethodVTableIndices[MD]] = MethodName; 2230 } 2231 } 2232 2233 // Print the vtable indices for all the member functions. 2234 if (!IndicesMap.empty()) { 2235 Out << "VTable indices for '"; 2236 Out << MostDerivedClass->getQualifiedNameAsString(); 2237 Out << "' (" << IndicesMap.size() << " entries).\n"; 2238 2239 for (std::map<uint64_t, std::string>::const_iterator I = IndicesMap.begin(), 2240 E = IndicesMap.end(); I != E; ++I) { 2241 uint64_t VTableIndex = I->first; 2242 const std::string &MethodName = I->second; 2243 2244 Out << llvm::format("%4" PRIu64 " | ", VTableIndex) << MethodName 2245 << '\n'; 2246 } 2247 } 2248 2249 Out << '\n'; 2250 } 2251 2252 } 2253 2254 VTableLayout::VTableLayout(uint64_t NumVTableComponents, 2255 const VTableComponent *VTableComponents, 2256 uint64_t NumVTableThunks, 2257 const VTableThunkTy *VTableThunks, 2258 const AddressPointsMapTy &AddressPoints, 2259 bool IsMicrosoftABI) 2260 : NumVTableComponents(NumVTableComponents), 2261 VTableComponents(new VTableComponent[NumVTableComponents]), 2262 NumVTableThunks(NumVTableThunks), 2263 VTableThunks(new VTableThunkTy[NumVTableThunks]), 2264 AddressPoints(AddressPoints), 2265 IsMicrosoftABI(IsMicrosoftABI) { 2266 std::copy(VTableComponents, VTableComponents+NumVTableComponents, 2267 this->VTableComponents.get()); 2268 std::copy(VTableThunks, VTableThunks+NumVTableThunks, 2269 this->VTableThunks.get()); 2270 } 2271 2272 VTableLayout::~VTableLayout() { } 2273 2274 VTableContext::VTableContext(ASTContext &Context) 2275 : Context(Context), 2276 IsMicrosoftABI(Context.getTargetInfo().getCXXABI().isMicrosoft()) { 2277 } 2278 2279 VTableContext::~VTableContext() { 2280 llvm::DeleteContainerSeconds(VTableLayouts); 2281 } 2282 2283 uint64_t VTableContext::getMethodVTableIndex(GlobalDecl GD) { 2284 MethodVTableIndicesTy::iterator I = MethodVTableIndices.find(GD); 2285 if (I != MethodVTableIndices.end()) 2286 return I->second; 2287 2288 const CXXRecordDecl *RD = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 2289 2290 ComputeVTableRelatedInformation(RD); 2291 2292 I = MethodVTableIndices.find(GD); 2293 assert(I != MethodVTableIndices.end() && "Did not find index!"); 2294 return I->second; 2295 } 2296 2297 CharUnits 2298 VTableContext::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, 2299 const CXXRecordDecl *VBase) { 2300 ClassPairTy ClassPair(RD, VBase); 2301 2302 VirtualBaseClassOffsetOffsetsMapTy::iterator I = 2303 VirtualBaseClassOffsetOffsets.find(ClassPair); 2304 if (I != VirtualBaseClassOffsetOffsets.end()) 2305 return I->second; 2306 2307 VCallAndVBaseOffsetBuilder Builder(RD, RD, /*FinalOverriders=*/0, 2308 BaseSubobject(RD, CharUnits::Zero()), 2309 /*BaseIsVirtual=*/false, 2310 /*OffsetInLayoutClass=*/CharUnits::Zero()); 2311 2312 for (VCallAndVBaseOffsetBuilder::VBaseOffsetOffsetsMapTy::const_iterator I = 2313 Builder.getVBaseOffsetOffsets().begin(), 2314 E = Builder.getVBaseOffsetOffsets().end(); I != E; ++I) { 2315 // Insert all types. 2316 ClassPairTy ClassPair(RD, I->first); 2317 2318 VirtualBaseClassOffsetOffsets.insert( 2319 std::make_pair(ClassPair, I->second)); 2320 } 2321 2322 I = VirtualBaseClassOffsetOffsets.find(ClassPair); 2323 assert(I != VirtualBaseClassOffsetOffsets.end() && "Did not find index!"); 2324 2325 return I->second; 2326 } 2327 2328 static VTableLayout *CreateVTableLayout(const VTableBuilder &Builder) { 2329 SmallVector<VTableLayout::VTableThunkTy, 1> 2330 VTableThunks(Builder.vtable_thunks_begin(), Builder.vtable_thunks_end()); 2331 std::sort(VTableThunks.begin(), VTableThunks.end()); 2332 2333 return new VTableLayout(Builder.getNumVTableComponents(), 2334 Builder.vtable_component_begin(), 2335 VTableThunks.size(), 2336 VTableThunks.data(), 2337 Builder.getAddressPoints(), 2338 Builder.isMicrosoftABI()); 2339 } 2340 2341 void VTableContext::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) { 2342 const VTableLayout *&Entry = VTableLayouts[RD]; 2343 2344 // Check if we've computed this information before. 2345 if (Entry) 2346 return; 2347 2348 VTableBuilder Builder(*this, RD, CharUnits::Zero(), 2349 /*MostDerivedClassIsVirtual=*/0, RD); 2350 Entry = CreateVTableLayout(Builder); 2351 2352 MethodVTableIndices.insert(Builder.vtable_indices_begin(), 2353 Builder.vtable_indices_end()); 2354 2355 // Add the known thunks. 2356 Thunks.insert(Builder.thunks_begin(), Builder.thunks_end()); 2357 2358 // If we don't have the vbase information for this class, insert it. 2359 // getVirtualBaseOffsetOffset will compute it separately without computing 2360 // the rest of the vtable related information. 2361 if (!RD->getNumVBases()) 2362 return; 2363 2364 const RecordType *VBaseRT = 2365 RD->vbases_begin()->getType()->getAs<RecordType>(); 2366 const CXXRecordDecl *VBase = cast<CXXRecordDecl>(VBaseRT->getDecl()); 2367 2368 if (VirtualBaseClassOffsetOffsets.count(std::make_pair(RD, VBase))) 2369 return; 2370 2371 for (VTableBuilder::VBaseOffsetOffsetsMapTy::const_iterator I = 2372 Builder.getVBaseOffsetOffsets().begin(), 2373 E = Builder.getVBaseOffsetOffsets().end(); I != E; ++I) { 2374 // Insert all types. 2375 ClassPairTy ClassPair(RD, I->first); 2376 2377 VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I->second)); 2378 } 2379 } 2380 2381 void VTableContext::ErrorUnsupported(StringRef Feature, 2382 SourceLocation Location) { 2383 clang::DiagnosticsEngine &Diags = Context.getDiagnostics(); 2384 unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, 2385 "v-table layout for %0 is not supported yet"); 2386 Diags.Report(Context.getFullLoc(Location), DiagID) << Feature; 2387 } 2388 2389 VTableLayout *VTableContext::createConstructionVTableLayout( 2390 const CXXRecordDecl *MostDerivedClass, 2391 CharUnits MostDerivedClassOffset, 2392 bool MostDerivedClassIsVirtual, 2393 const CXXRecordDecl *LayoutClass) { 2394 VTableBuilder Builder(*this, MostDerivedClass, MostDerivedClassOffset, 2395 MostDerivedClassIsVirtual, LayoutClass); 2396 return CreateVTableLayout(Builder); 2397 } 2398