1 //===------ CXXInheritance.cpp - C++ Inheritance ----------------*- C++ -*-===// 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 file provides routines that help analyzing C++ inheritance hierarchies. 11 // 12 //===----------------------------------------------------------------------===// 13 #include "clang/AST/CXXInheritance.h" 14 #include "clang/AST/ASTContext.h" 15 #include "clang/AST/DeclCXX.h" 16 #include "clang/AST/RecordLayout.h" 17 #include "llvm/ADT/SetVector.h" 18 #include <algorithm> 19 #include <set> 20 21 using namespace clang; 22 23 /// \brief Computes the set of declarations referenced by these base 24 /// paths. 25 void CXXBasePaths::ComputeDeclsFound() { 26 assert(NumDeclsFound == 0 && !DeclsFound && 27 "Already computed the set of declarations"); 28 29 llvm::SetVector<NamedDecl *, SmallVector<NamedDecl *, 8> > Decls; 30 for (paths_iterator Path = begin(), PathEnd = end(); Path != PathEnd; ++Path) 31 Decls.insert(Path->Decls.front()); 32 33 NumDeclsFound = Decls.size(); 34 DeclsFound = llvm::make_unique<NamedDecl *[]>(NumDeclsFound); 35 std::copy(Decls.begin(), Decls.end(), DeclsFound.get()); 36 } 37 38 CXXBasePaths::decl_range CXXBasePaths::found_decls() { 39 if (NumDeclsFound == 0) 40 ComputeDeclsFound(); 41 42 return decl_range(decl_iterator(DeclsFound.get()), 43 decl_iterator(DeclsFound.get() + NumDeclsFound)); 44 } 45 46 /// isAmbiguous - Determines whether the set of paths provided is 47 /// ambiguous, i.e., there are two or more paths that refer to 48 /// different base class subobjects of the same type. BaseType must be 49 /// an unqualified, canonical class type. 50 bool CXXBasePaths::isAmbiguous(CanQualType BaseType) { 51 BaseType = BaseType.getUnqualifiedType(); 52 std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType]; 53 return Subobjects.second + (Subobjects.first? 1 : 0) > 1; 54 } 55 56 /// clear - Clear out all prior path information. 57 void CXXBasePaths::clear() { 58 Paths.clear(); 59 ClassSubobjects.clear(); 60 ScratchPath.clear(); 61 DetectedVirtual = nullptr; 62 } 63 64 /// @brief Swaps the contents of this CXXBasePaths structure with the 65 /// contents of Other. 66 void CXXBasePaths::swap(CXXBasePaths &Other) { 67 std::swap(Origin, Other.Origin); 68 Paths.swap(Other.Paths); 69 ClassSubobjects.swap(Other.ClassSubobjects); 70 std::swap(FindAmbiguities, Other.FindAmbiguities); 71 std::swap(RecordPaths, Other.RecordPaths); 72 std::swap(DetectVirtual, Other.DetectVirtual); 73 std::swap(DetectedVirtual, Other.DetectedVirtual); 74 } 75 76 bool CXXRecordDecl::isDerivedFrom(const CXXRecordDecl *Base) const { 77 CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false, 78 /*DetectVirtual=*/false); 79 return isDerivedFrom(Base, Paths); 80 } 81 82 bool CXXRecordDecl::isDerivedFrom(const CXXRecordDecl *Base, 83 CXXBasePaths &Paths) const { 84 if (getCanonicalDecl() == Base->getCanonicalDecl()) 85 return false; 86 87 Paths.setOrigin(const_cast<CXXRecordDecl*>(this)); 88 89 const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl(); 90 // FIXME: Capturing 'this' is a workaround for name lookup bugs in GCC 4.7. 91 return lookupInBases( 92 [this, BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { 93 return FindBaseClass(Specifier, Path, BaseDecl); 94 }, 95 Paths); 96 } 97 98 bool CXXRecordDecl::isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const { 99 if (!getNumVBases()) 100 return false; 101 102 CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false, 103 /*DetectVirtual=*/false); 104 105 if (getCanonicalDecl() == Base->getCanonicalDecl()) 106 return false; 107 108 Paths.setOrigin(const_cast<CXXRecordDecl*>(this)); 109 110 const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl(); 111 // FIXME: Capturing 'this' is a workaround for name lookup bugs in GCC 4.7. 112 return lookupInBases( 113 [this, BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { 114 return FindVirtualBaseClass(Specifier, Path, BaseDecl); 115 }, 116 Paths); 117 } 118 119 bool CXXRecordDecl::isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const { 120 const CXXRecordDecl *TargetDecl = Base->getCanonicalDecl(); 121 return forallBases([TargetDecl](const CXXRecordDecl *Base) { 122 return Base->getCanonicalDecl() != TargetDecl; 123 }); 124 } 125 126 bool 127 CXXRecordDecl::isCurrentInstantiation(const DeclContext *CurContext) const { 128 assert(isDependentContext()); 129 130 for (; !CurContext->isFileContext(); CurContext = CurContext->getParent()) 131 if (CurContext->Equals(this)) 132 return true; 133 134 return false; 135 } 136 137 bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches, 138 bool AllowShortCircuit) const { 139 SmallVector<const CXXRecordDecl*, 8> Queue; 140 llvm::SmallPtrSet<const CXXRecordDecl*, 8> Enqueued; 141 142 const CXXRecordDecl *Record = this; 143 bool AllMatches = true; 144 while (true) { 145 for (const auto &I : Record->bases()) { 146 const RecordType *Ty = I.getType()->getAs<RecordType>(); 147 if (!Ty) { 148 if (AllowShortCircuit) return false; 149 AllMatches = false; 150 continue; 151 } 152 153 CXXRecordDecl *Base = 154 cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition()); 155 if (!Base || 156 (Base->isDependentContext() && 157 !Base->isCurrentInstantiation(Record))) { 158 if (AllowShortCircuit) return false; 159 AllMatches = false; 160 continue; 161 } 162 163 if (Enqueued.insert(Base).second) { 164 Queue.push_back(Base); 165 if (!BaseMatches(Base)) { 166 if (AllowShortCircuit) return false; 167 AllMatches = false; 168 continue; 169 } 170 } 171 } 172 173 if (Queue.empty()) 174 break; 175 Record = Queue.pop_back_val(); // not actually a queue. 176 } 177 178 return AllMatches; 179 } 180 181 bool CXXBasePaths::lookupInBases( 182 ASTContext &Context, const CXXRecordDecl *Record, 183 CXXRecordDecl::BaseMatchesCallback BaseMatches) { 184 bool FoundPath = false; 185 186 // The access of the path down to this record. 187 AccessSpecifier AccessToHere = ScratchPath.Access; 188 bool IsFirstStep = ScratchPath.empty(); 189 190 for (const auto &BaseSpec : Record->bases()) { 191 // Find the record of the base class subobjects for this type. 192 QualType BaseType = 193 Context.getCanonicalType(BaseSpec.getType()).getUnqualifiedType(); 194 195 // C++ [temp.dep]p3: 196 // In the definition of a class template or a member of a class template, 197 // if a base class of the class template depends on a template-parameter, 198 // the base class scope is not examined during unqualified name lookup 199 // either at the point of definition of the class template or member or 200 // during an instantiation of the class tem- plate or member. 201 if (BaseType->isDependentType()) 202 continue; 203 204 // Determine whether we need to visit this base class at all, 205 // updating the count of subobjects appropriately. 206 std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType]; 207 bool VisitBase = true; 208 bool SetVirtual = false; 209 if (BaseSpec.isVirtual()) { 210 VisitBase = !Subobjects.first; 211 Subobjects.first = true; 212 if (isDetectingVirtual() && DetectedVirtual == nullptr) { 213 // If this is the first virtual we find, remember it. If it turns out 214 // there is no base path here, we'll reset it later. 215 DetectedVirtual = BaseType->getAs<RecordType>(); 216 SetVirtual = true; 217 } 218 } else 219 ++Subobjects.second; 220 221 if (isRecordingPaths()) { 222 // Add this base specifier to the current path. 223 CXXBasePathElement Element; 224 Element.Base = &BaseSpec; 225 Element.Class = Record; 226 if (BaseSpec.isVirtual()) 227 Element.SubobjectNumber = 0; 228 else 229 Element.SubobjectNumber = Subobjects.second; 230 ScratchPath.push_back(Element); 231 232 // Calculate the "top-down" access to this base class. 233 // The spec actually describes this bottom-up, but top-down is 234 // equivalent because the definition works out as follows: 235 // 1. Write down the access along each step in the inheritance 236 // chain, followed by the access of the decl itself. 237 // For example, in 238 // class A { public: int foo; }; 239 // class B : protected A {}; 240 // class C : public B {}; 241 // class D : private C {}; 242 // we would write: 243 // private public protected public 244 // 2. If 'private' appears anywhere except far-left, access is denied. 245 // 3. Otherwise, overall access is determined by the most restrictive 246 // access in the sequence. 247 if (IsFirstStep) 248 ScratchPath.Access = BaseSpec.getAccessSpecifier(); 249 else 250 ScratchPath.Access = CXXRecordDecl::MergeAccess(AccessToHere, 251 BaseSpec.getAccessSpecifier()); 252 } 253 254 // Track whether there's a path involving this specific base. 255 bool FoundPathThroughBase = false; 256 257 if (BaseMatches(&BaseSpec, ScratchPath)) { 258 // We've found a path that terminates at this base. 259 FoundPath = FoundPathThroughBase = true; 260 if (isRecordingPaths()) { 261 // We have a path. Make a copy of it before moving on. 262 Paths.push_back(ScratchPath); 263 } else if (!isFindingAmbiguities()) { 264 // We found a path and we don't care about ambiguities; 265 // return immediately. 266 return FoundPath; 267 } 268 } else if (VisitBase) { 269 CXXRecordDecl *BaseRecord 270 = cast<CXXRecordDecl>(BaseSpec.getType()->castAs<RecordType>() 271 ->getDecl()); 272 if (lookupInBases(Context, BaseRecord, BaseMatches)) { 273 // C++ [class.member.lookup]p2: 274 // A member name f in one sub-object B hides a member name f in 275 // a sub-object A if A is a base class sub-object of B. Any 276 // declarations that are so hidden are eliminated from 277 // consideration. 278 279 // There is a path to a base class that meets the criteria. If we're 280 // not collecting paths or finding ambiguities, we're done. 281 FoundPath = FoundPathThroughBase = true; 282 if (!isFindingAmbiguities()) 283 return FoundPath; 284 } 285 } 286 287 // Pop this base specifier off the current path (if we're 288 // collecting paths). 289 if (isRecordingPaths()) { 290 ScratchPath.pop_back(); 291 } 292 293 // If we set a virtual earlier, and this isn't a path, forget it again. 294 if (SetVirtual && !FoundPathThroughBase) { 295 DetectedVirtual = nullptr; 296 } 297 } 298 299 // Reset the scratch path access. 300 ScratchPath.Access = AccessToHere; 301 302 return FoundPath; 303 } 304 305 bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches, 306 CXXBasePaths &Paths) const { 307 // If we didn't find anything, report that. 308 if (!Paths.lookupInBases(getASTContext(), this, BaseMatches)) 309 return false; 310 311 // If we're not recording paths or we won't ever find ambiguities, 312 // we're done. 313 if (!Paths.isRecordingPaths() || !Paths.isFindingAmbiguities()) 314 return true; 315 316 // C++ [class.member.lookup]p6: 317 // When virtual base classes are used, a hidden declaration can be 318 // reached along a path through the sub-object lattice that does 319 // not pass through the hiding declaration. This is not an 320 // ambiguity. The identical use with nonvirtual base classes is an 321 // ambiguity; in that case there is no unique instance of the name 322 // that hides all the others. 323 // 324 // FIXME: This is an O(N^2) algorithm, but DPG doesn't see an easy 325 // way to make it any faster. 326 Paths.Paths.remove_if([&Paths](const CXXBasePath &Path) { 327 for (const CXXBasePathElement &PE : Path) { 328 if (!PE.Base->isVirtual()) 329 continue; 330 331 CXXRecordDecl *VBase = nullptr; 332 if (const RecordType *Record = PE.Base->getType()->getAs<RecordType>()) 333 VBase = cast<CXXRecordDecl>(Record->getDecl()); 334 if (!VBase) 335 break; 336 337 // The declaration(s) we found along this path were found in a 338 // subobject of a virtual base. Check whether this virtual 339 // base is a subobject of any other path; if so, then the 340 // declaration in this path are hidden by that patch. 341 for (const CXXBasePath &HidingP : Paths) { 342 CXXRecordDecl *HidingClass = nullptr; 343 if (const RecordType *Record = 344 HidingP.back().Base->getType()->getAs<RecordType>()) 345 HidingClass = cast<CXXRecordDecl>(Record->getDecl()); 346 if (!HidingClass) 347 break; 348 349 if (HidingClass->isVirtuallyDerivedFrom(VBase)) 350 return true; 351 } 352 } 353 return false; 354 }); 355 356 return true; 357 } 358 359 bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier, 360 CXXBasePath &Path, 361 const CXXRecordDecl *BaseRecord) { 362 assert(BaseRecord->getCanonicalDecl() == BaseRecord && 363 "User data for FindBaseClass is not canonical!"); 364 return Specifier->getType()->castAs<RecordType>()->getDecl() 365 ->getCanonicalDecl() == BaseRecord; 366 } 367 368 bool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier, 369 CXXBasePath &Path, 370 const CXXRecordDecl *BaseRecord) { 371 assert(BaseRecord->getCanonicalDecl() == BaseRecord && 372 "User data for FindBaseClass is not canonical!"); 373 return Specifier->isVirtual() && 374 Specifier->getType()->castAs<RecordType>()->getDecl() 375 ->getCanonicalDecl() == BaseRecord; 376 } 377 378 bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier, 379 CXXBasePath &Path, 380 DeclarationName Name) { 381 RecordDecl *BaseRecord = 382 Specifier->getType()->castAs<RecordType>()->getDecl(); 383 384 for (Path.Decls = BaseRecord->lookup(Name); 385 !Path.Decls.empty(); 386 Path.Decls = Path.Decls.slice(1)) { 387 if (Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag)) 388 return true; 389 } 390 391 return false; 392 } 393 394 bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier, 395 CXXBasePath &Path, 396 DeclarationName Name) { 397 RecordDecl *BaseRecord = 398 Specifier->getType()->castAs<RecordType>()->getDecl(); 399 400 const unsigned IDNS = IDNS_Ordinary | IDNS_Tag | IDNS_Member; 401 for (Path.Decls = BaseRecord->lookup(Name); 402 !Path.Decls.empty(); 403 Path.Decls = Path.Decls.slice(1)) { 404 if (Path.Decls.front()->isInIdentifierNamespace(IDNS)) 405 return true; 406 } 407 408 return false; 409 } 410 411 bool CXXRecordDecl::FindOMPReductionMember(const CXXBaseSpecifier *Specifier, 412 CXXBasePath &Path, 413 DeclarationName Name) { 414 RecordDecl *BaseRecord = 415 Specifier->getType()->castAs<RecordType>()->getDecl(); 416 417 for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty(); 418 Path.Decls = Path.Decls.slice(1)) { 419 if (Path.Decls.front()->isInIdentifierNamespace(IDNS_OMPReduction)) 420 return true; 421 } 422 423 return false; 424 } 425 426 bool CXXRecordDecl:: 427 FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier, 428 CXXBasePath &Path, 429 DeclarationName Name) { 430 RecordDecl *BaseRecord = 431 Specifier->getType()->castAs<RecordType>()->getDecl(); 432 433 for (Path.Decls = BaseRecord->lookup(Name); 434 !Path.Decls.empty(); 435 Path.Decls = Path.Decls.slice(1)) { 436 // FIXME: Refactor the "is it a nested-name-specifier?" check 437 if (isa<TypedefNameDecl>(Path.Decls.front()) || 438 Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag)) 439 return true; 440 } 441 442 return false; 443 } 444 445 void OverridingMethods::add(unsigned OverriddenSubobject, 446 UniqueVirtualMethod Overriding) { 447 SmallVectorImpl<UniqueVirtualMethod> &SubobjectOverrides 448 = Overrides[OverriddenSubobject]; 449 if (std::find(SubobjectOverrides.begin(), SubobjectOverrides.end(), 450 Overriding) == SubobjectOverrides.end()) 451 SubobjectOverrides.push_back(Overriding); 452 } 453 454 void OverridingMethods::add(const OverridingMethods &Other) { 455 for (const_iterator I = Other.begin(), IE = Other.end(); I != IE; ++I) { 456 for (overriding_const_iterator M = I->second.begin(), 457 MEnd = I->second.end(); 458 M != MEnd; 459 ++M) 460 add(I->first, *M); 461 } 462 } 463 464 void OverridingMethods::replaceAll(UniqueVirtualMethod Overriding) { 465 for (iterator I = begin(), IEnd = end(); I != IEnd; ++I) { 466 I->second.clear(); 467 I->second.push_back(Overriding); 468 } 469 } 470 471 472 namespace { 473 class FinalOverriderCollector { 474 /// \brief The number of subobjects of a given class type that 475 /// occur within the class hierarchy. 476 llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCount; 477 478 /// \brief Overriders for each virtual base subobject. 479 llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *> VirtualOverriders; 480 481 CXXFinalOverriderMap FinalOverriders; 482 483 public: 484 ~FinalOverriderCollector(); 485 486 void Collect(const CXXRecordDecl *RD, bool VirtualBase, 487 const CXXRecordDecl *InVirtualSubobject, 488 CXXFinalOverriderMap &Overriders); 489 }; 490 } 491 492 void FinalOverriderCollector::Collect(const CXXRecordDecl *RD, 493 bool VirtualBase, 494 const CXXRecordDecl *InVirtualSubobject, 495 CXXFinalOverriderMap &Overriders) { 496 unsigned SubobjectNumber = 0; 497 if (!VirtualBase) 498 SubobjectNumber 499 = ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())]; 500 501 for (const auto &Base : RD->bases()) { 502 if (const RecordType *RT = Base.getType()->getAs<RecordType>()) { 503 const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(RT->getDecl()); 504 if (!BaseDecl->isPolymorphic()) 505 continue; 506 507 if (Overriders.empty() && !Base.isVirtual()) { 508 // There are no other overriders of virtual member functions, 509 // so let the base class fill in our overriders for us. 510 Collect(BaseDecl, false, InVirtualSubobject, Overriders); 511 continue; 512 } 513 514 // Collect all of the overridders from the base class subobject 515 // and merge them into the set of overridders for this class. 516 // For virtual base classes, populate or use the cached virtual 517 // overrides so that we do not walk the virtual base class (and 518 // its base classes) more than once. 519 CXXFinalOverriderMap ComputedBaseOverriders; 520 CXXFinalOverriderMap *BaseOverriders = &ComputedBaseOverriders; 521 if (Base.isVirtual()) { 522 CXXFinalOverriderMap *&MyVirtualOverriders = VirtualOverriders[BaseDecl]; 523 BaseOverriders = MyVirtualOverriders; 524 if (!MyVirtualOverriders) { 525 MyVirtualOverriders = new CXXFinalOverriderMap; 526 527 // Collect may cause VirtualOverriders to reallocate, invalidating the 528 // MyVirtualOverriders reference. Set BaseOverriders to the right 529 // value now. 530 BaseOverriders = MyVirtualOverriders; 531 532 Collect(BaseDecl, true, BaseDecl, *MyVirtualOverriders); 533 } 534 } else 535 Collect(BaseDecl, false, InVirtualSubobject, ComputedBaseOverriders); 536 537 // Merge the overriders from this base class into our own set of 538 // overriders. 539 for (CXXFinalOverriderMap::iterator OM = BaseOverriders->begin(), 540 OMEnd = BaseOverriders->end(); 541 OM != OMEnd; 542 ++OM) { 543 const CXXMethodDecl *CanonOM 544 = cast<CXXMethodDecl>(OM->first->getCanonicalDecl()); 545 Overriders[CanonOM].add(OM->second); 546 } 547 } 548 } 549 550 for (auto *M : RD->methods()) { 551 // We only care about virtual methods. 552 if (!M->isVirtual()) 553 continue; 554 555 CXXMethodDecl *CanonM = cast<CXXMethodDecl>(M->getCanonicalDecl()); 556 557 if (CanonM->begin_overridden_methods() 558 == CanonM->end_overridden_methods()) { 559 // This is a new virtual function that does not override any 560 // other virtual function. Add it to the map of virtual 561 // functions for which we are tracking overridders. 562 563 // C++ [class.virtual]p2: 564 // For convenience we say that any virtual function overrides itself. 565 Overriders[CanonM].add(SubobjectNumber, 566 UniqueVirtualMethod(CanonM, SubobjectNumber, 567 InVirtualSubobject)); 568 continue; 569 } 570 571 // This virtual method overrides other virtual methods, so it does 572 // not add any new slots into the set of overriders. Instead, we 573 // replace entries in the set of overriders with the new 574 // overrider. To do so, we dig down to the original virtual 575 // functions using data recursion and update all of the methods it 576 // overrides. 577 typedef llvm::iterator_range<CXXMethodDecl::method_iterator> 578 OverriddenMethods; 579 SmallVector<OverriddenMethods, 4> Stack; 580 Stack.push_back(llvm::make_range(CanonM->begin_overridden_methods(), 581 CanonM->end_overridden_methods())); 582 while (!Stack.empty()) { 583 for (const CXXMethodDecl *OM : Stack.pop_back_val()) { 584 const CXXMethodDecl *CanonOM = OM->getCanonicalDecl(); 585 586 // C++ [class.virtual]p2: 587 // A virtual member function C::vf of a class object S is 588 // a final overrider unless the most derived class (1.8) 589 // of which S is a base class subobject (if any) declares 590 // or inherits another member function that overrides vf. 591 // 592 // Treating this object like the most derived class, we 593 // replace any overrides from base classes with this 594 // overriding virtual function. 595 Overriders[CanonOM].replaceAll( 596 UniqueVirtualMethod(CanonM, SubobjectNumber, 597 InVirtualSubobject)); 598 599 if (CanonOM->begin_overridden_methods() 600 == CanonOM->end_overridden_methods()) 601 continue; 602 603 // Continue recursion to the methods that this virtual method 604 // overrides. 605 Stack.push_back(llvm::make_range(CanonOM->begin_overridden_methods(), 606 CanonOM->end_overridden_methods())); 607 } 608 } 609 610 // C++ [class.virtual]p2: 611 // For convenience we say that any virtual function overrides itself. 612 Overriders[CanonM].add(SubobjectNumber, 613 UniqueVirtualMethod(CanonM, SubobjectNumber, 614 InVirtualSubobject)); 615 } 616 } 617 618 FinalOverriderCollector::~FinalOverriderCollector() { 619 for (llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *>::iterator 620 VO = VirtualOverriders.begin(), VOEnd = VirtualOverriders.end(); 621 VO != VOEnd; 622 ++VO) 623 delete VO->second; 624 } 625 626 void 627 CXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap &FinalOverriders) const { 628 FinalOverriderCollector Collector; 629 Collector.Collect(this, false, nullptr, FinalOverriders); 630 631 // Weed out any final overriders that come from virtual base class 632 // subobjects that were hidden by other subobjects along any path. 633 // This is the final-overrider variant of C++ [class.member.lookup]p10. 634 for (auto &OM : FinalOverriders) { 635 for (auto &SO : OM.second) { 636 SmallVectorImpl<UniqueVirtualMethod> &Overriding = SO.second; 637 if (Overriding.size() < 2) 638 continue; 639 640 auto IsHidden = [&Overriding](const UniqueVirtualMethod &M) { 641 if (!M.InVirtualSubobject) 642 return false; 643 644 // We have an overriding method in a virtual base class 645 // subobject (or non-virtual base class subobject thereof); 646 // determine whether there exists an other overriding method 647 // in a base class subobject that hides the virtual base class 648 // subobject. 649 for (const UniqueVirtualMethod &OP : Overriding) 650 if (&M != &OP && 651 OP.Method->getParent()->isVirtuallyDerivedFrom( 652 M.InVirtualSubobject)) 653 return true; 654 return false; 655 }; 656 657 Overriding.erase( 658 std::remove_if(Overriding.begin(), Overriding.end(), IsHidden), 659 Overriding.end()); 660 } 661 } 662 } 663 664 static void 665 AddIndirectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context, 666 CXXIndirectPrimaryBaseSet& Bases) { 667 // If the record has a virtual primary base class, add it to our set. 668 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 669 if (Layout.isPrimaryBaseVirtual()) 670 Bases.insert(Layout.getPrimaryBase()); 671 672 for (const auto &I : RD->bases()) { 673 assert(!I.getType()->isDependentType() && 674 "Cannot get indirect primary bases for class with dependent bases."); 675 676 const CXXRecordDecl *BaseDecl = 677 cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 678 679 // Only bases with virtual bases participate in computing the 680 // indirect primary virtual base classes. 681 if (BaseDecl->getNumVBases()) 682 AddIndirectPrimaryBases(BaseDecl, Context, Bases); 683 } 684 685 } 686 687 void 688 CXXRecordDecl::getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const { 689 ASTContext &Context = getASTContext(); 690 691 if (!getNumVBases()) 692 return; 693 694 for (const auto &I : bases()) { 695 assert(!I.getType()->isDependentType() && 696 "Cannot get indirect primary bases for class with dependent bases."); 697 698 const CXXRecordDecl *BaseDecl = 699 cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 700 701 // Only bases with virtual bases participate in computing the 702 // indirect primary virtual base classes. 703 if (BaseDecl->getNumVBases()) 704 AddIndirectPrimaryBases(BaseDecl, Context, Bases); 705 } 706 } 707