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