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