| //===- CXXInheritance.cpp - C++ Inheritance -------------------------------===// | 
 | // | 
 | //                     The LLVM Compiler Infrastructure | 
 | // | 
 | // This file is distributed under the University of Illinois Open Source | 
 | // License. See LICENSE.TXT for details. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | // | 
 | // This file provides routines that help analyzing C++ inheritance hierarchies. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #include "clang/AST/CXXInheritance.h" | 
 | #include "clang/AST/ASTContext.h" | 
 | #include "clang/AST/Decl.h" | 
 | #include "clang/AST/DeclBase.h" | 
 | #include "clang/AST/DeclCXX.h" | 
 | #include "clang/AST/DeclTemplate.h" | 
 | #include "clang/AST/RecordLayout.h" | 
 | #include "clang/AST/TemplateName.h" | 
 | #include "clang/AST/Type.h" | 
 | #include "clang/Basic/LLVM.h" | 
 | #include "llvm/ADT/DenseMap.h" | 
 | #include "llvm/ADT/STLExtras.h" | 
 | #include "llvm/ADT/SetVector.h" | 
 | #include "llvm/ADT/SmallVector.h" | 
 | #include "llvm/ADT/iterator_range.h" | 
 | #include "llvm/Support/Casting.h" | 
 | #include <algorithm> | 
 | #include <utility> | 
 | #include <cassert> | 
 | #include <vector> | 
 |  | 
 | using namespace clang; | 
 |  | 
 | /// Computes the set of declarations referenced by these base | 
 | /// paths. | 
 | void CXXBasePaths::ComputeDeclsFound() { | 
 |   assert(NumDeclsFound == 0 && !DeclsFound && | 
 |          "Already computed the set of declarations"); | 
 |  | 
 |   llvm::SmallSetVector<NamedDecl *, 8> Decls; | 
 |   for (paths_iterator Path = begin(), PathEnd = end(); Path != PathEnd; ++Path) | 
 |     Decls.insert(Path->Decls.front()); | 
 |  | 
 |   NumDeclsFound = Decls.size(); | 
 |   DeclsFound = llvm::make_unique<NamedDecl *[]>(NumDeclsFound); | 
 |   std::copy(Decls.begin(), Decls.end(), DeclsFound.get()); | 
 | } | 
 |  | 
 | CXXBasePaths::decl_range CXXBasePaths::found_decls() { | 
 |   if (NumDeclsFound == 0) | 
 |     ComputeDeclsFound(); | 
 |  | 
 |   return decl_range(decl_iterator(DeclsFound.get()), | 
 |                     decl_iterator(DeclsFound.get() + NumDeclsFound)); | 
 | } | 
 |  | 
 | /// isAmbiguous - Determines whether the set of paths provided is | 
 | /// ambiguous, i.e., there are two or more paths that refer to | 
 | /// different base class subobjects of the same type. BaseType must be | 
 | /// an unqualified, canonical class type. | 
 | bool CXXBasePaths::isAmbiguous(CanQualType BaseType) { | 
 |   BaseType = BaseType.getUnqualifiedType(); | 
 |   IsVirtBaseAndNumberNonVirtBases Subobjects = ClassSubobjects[BaseType]; | 
 |   return Subobjects.NumberOfNonVirtBases + (Subobjects.IsVirtBase ? 1 : 0) > 1; | 
 | } | 
 |  | 
 | /// clear - Clear out all prior path information. | 
 | void CXXBasePaths::clear() { | 
 |   Paths.clear(); | 
 |   ClassSubobjects.clear(); | 
 |   VisitedDependentRecords.clear(); | 
 |   ScratchPath.clear(); | 
 |   DetectedVirtual = nullptr; | 
 | } | 
 |  | 
 | /// Swaps the contents of this CXXBasePaths structure with the | 
 | /// contents of Other. | 
 | void CXXBasePaths::swap(CXXBasePaths &Other) { | 
 |   std::swap(Origin, Other.Origin); | 
 |   Paths.swap(Other.Paths); | 
 |   ClassSubobjects.swap(Other.ClassSubobjects); | 
 |   VisitedDependentRecords.swap(Other.VisitedDependentRecords); | 
 |   std::swap(FindAmbiguities, Other.FindAmbiguities); | 
 |   std::swap(RecordPaths, Other.RecordPaths); | 
 |   std::swap(DetectVirtual, Other.DetectVirtual); | 
 |   std::swap(DetectedVirtual, Other.DetectedVirtual); | 
 | } | 
 |  | 
 | bool CXXRecordDecl::isDerivedFrom(const CXXRecordDecl *Base) const { | 
 |   CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false, | 
 |                      /*DetectVirtual=*/false); | 
 |   return isDerivedFrom(Base, Paths); | 
 | } | 
 |  | 
 | bool CXXRecordDecl::isDerivedFrom(const CXXRecordDecl *Base, | 
 |                                   CXXBasePaths &Paths) const { | 
 |   if (getCanonicalDecl() == Base->getCanonicalDecl()) | 
 |     return false; | 
 |  | 
 |   Paths.setOrigin(const_cast<CXXRecordDecl*>(this)); | 
 |  | 
 |   const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl(); | 
 |   return lookupInBases( | 
 |       [BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { | 
 |         return FindBaseClass(Specifier, Path, BaseDecl); | 
 |       }, | 
 |       Paths); | 
 | } | 
 |  | 
 | bool CXXRecordDecl::isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const { | 
 |   if (!getNumVBases()) | 
 |     return false; | 
 |  | 
 |   CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false, | 
 |                      /*DetectVirtual=*/false); | 
 |  | 
 |   if (getCanonicalDecl() == Base->getCanonicalDecl()) | 
 |     return false; | 
 |  | 
 |   Paths.setOrigin(const_cast<CXXRecordDecl*>(this)); | 
 |  | 
 |   const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl(); | 
 |   return lookupInBases( | 
 |       [BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { | 
 |         return FindVirtualBaseClass(Specifier, Path, BaseDecl); | 
 |       }, | 
 |       Paths); | 
 | } | 
 |  | 
 | bool CXXRecordDecl::isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const { | 
 |   const CXXRecordDecl *TargetDecl = Base->getCanonicalDecl(); | 
 |   return forallBases([TargetDecl](const CXXRecordDecl *Base) { | 
 |     return Base->getCanonicalDecl() != TargetDecl; | 
 |   }); | 
 | } | 
 |  | 
 | bool | 
 | CXXRecordDecl::isCurrentInstantiation(const DeclContext *CurContext) const { | 
 |   assert(isDependentContext()); | 
 |  | 
 |   for (; !CurContext->isFileContext(); CurContext = CurContext->getParent()) | 
 |     if (CurContext->Equals(this)) | 
 |       return true; | 
 |  | 
 |   return false; | 
 | } | 
 |  | 
 | bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches, | 
 |                                 bool AllowShortCircuit) const { | 
 |   SmallVector<const CXXRecordDecl*, 8> Queue; | 
 |  | 
 |   const CXXRecordDecl *Record = this; | 
 |   bool AllMatches = true; | 
 |   while (true) { | 
 |     for (const auto &I : Record->bases()) { | 
 |       const RecordType *Ty = I.getType()->getAs<RecordType>(); | 
 |       if (!Ty) { | 
 |         if (AllowShortCircuit) return false; | 
 |         AllMatches = false; | 
 |         continue; | 
 |       } | 
 |  | 
 |       CXXRecordDecl *Base = | 
 |             cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition()); | 
 |       if (!Base || | 
 |           (Base->isDependentContext() && | 
 |            !Base->isCurrentInstantiation(Record))) { | 
 |         if (AllowShortCircuit) return false; | 
 |         AllMatches = false; | 
 |         continue; | 
 |       } | 
 |  | 
 |       Queue.push_back(Base); | 
 |       if (!BaseMatches(Base)) { | 
 |         if (AllowShortCircuit) return false; | 
 |         AllMatches = false; | 
 |         continue; | 
 |       } | 
 |     } | 
 |  | 
 |     if (Queue.empty()) | 
 |       break; | 
 |     Record = Queue.pop_back_val(); // not actually a queue. | 
 |   } | 
 |  | 
 |   return AllMatches; | 
 | } | 
 |  | 
 | bool CXXBasePaths::lookupInBases(ASTContext &Context, | 
 |                                  const CXXRecordDecl *Record, | 
 |                                  CXXRecordDecl::BaseMatchesCallback BaseMatches, | 
 |                                  bool LookupInDependent) { | 
 |   bool FoundPath = false; | 
 |  | 
 |   // The access of the path down to this record. | 
 |   AccessSpecifier AccessToHere = ScratchPath.Access; | 
 |   bool IsFirstStep = ScratchPath.empty(); | 
 |  | 
 |   for (const auto &BaseSpec : Record->bases()) { | 
 |     // Find the record of the base class subobjects for this type. | 
 |     QualType BaseType = | 
 |         Context.getCanonicalType(BaseSpec.getType()).getUnqualifiedType(); | 
 |  | 
 |     // C++ [temp.dep]p3: | 
 |     //   In the definition of a class template or a member of a class template, | 
 |     //   if a base class of the class template depends on a template-parameter, | 
 |     //   the base class scope is not examined during unqualified name lookup | 
 |     //   either at the point of definition of the class template or member or | 
 |     //   during an instantiation of the class tem- plate or member. | 
 |     if (!LookupInDependent && BaseType->isDependentType()) | 
 |       continue; | 
 |  | 
 |     // Determine whether we need to visit this base class at all, | 
 |     // updating the count of subobjects appropriately. | 
 |     IsVirtBaseAndNumberNonVirtBases &Subobjects = ClassSubobjects[BaseType]; | 
 |     bool VisitBase = true; | 
 |     bool SetVirtual = false; | 
 |     if (BaseSpec.isVirtual()) { | 
 |       VisitBase = !Subobjects.IsVirtBase; | 
 |       Subobjects.IsVirtBase = true; | 
 |       if (isDetectingVirtual() && DetectedVirtual == nullptr) { | 
 |         // If this is the first virtual we find, remember it. If it turns out | 
 |         // there is no base path here, we'll reset it later. | 
 |         DetectedVirtual = BaseType->getAs<RecordType>(); | 
 |         SetVirtual = true; | 
 |       } | 
 |     } else { | 
 |       ++Subobjects.NumberOfNonVirtBases; | 
 |     } | 
 |     if (isRecordingPaths()) { | 
 |       // Add this base specifier to the current path. | 
 |       CXXBasePathElement Element; | 
 |       Element.Base = &BaseSpec; | 
 |       Element.Class = Record; | 
 |       if (BaseSpec.isVirtual()) | 
 |         Element.SubobjectNumber = 0; | 
 |       else | 
 |         Element.SubobjectNumber = Subobjects.NumberOfNonVirtBases; | 
 |       ScratchPath.push_back(Element); | 
 |  | 
 |       // Calculate the "top-down" access to this base class. | 
 |       // The spec actually describes this bottom-up, but top-down is | 
 |       // equivalent because the definition works out as follows: | 
 |       // 1. Write down the access along each step in the inheritance | 
 |       //    chain, followed by the access of the decl itself. | 
 |       //    For example, in | 
 |       //      class A { public: int foo; }; | 
 |       //      class B : protected A {}; | 
 |       //      class C : public B {}; | 
 |       //      class D : private C {}; | 
 |       //    we would write: | 
 |       //      private public protected public | 
 |       // 2. If 'private' appears anywhere except far-left, access is denied. | 
 |       // 3. Otherwise, overall access is determined by the most restrictive | 
 |       //    access in the sequence. | 
 |       if (IsFirstStep) | 
 |         ScratchPath.Access = BaseSpec.getAccessSpecifier(); | 
 |       else | 
 |         ScratchPath.Access = CXXRecordDecl::MergeAccess(AccessToHere, | 
 |                                                  BaseSpec.getAccessSpecifier()); | 
 |     } | 
 |  | 
 |     // Track whether there's a path involving this specific base. | 
 |     bool FoundPathThroughBase = false; | 
 |  | 
 |     if (BaseMatches(&BaseSpec, ScratchPath)) { | 
 |       // We've found a path that terminates at this base. | 
 |       FoundPath = FoundPathThroughBase = true; | 
 |       if (isRecordingPaths()) { | 
 |         // We have a path. Make a copy of it before moving on. | 
 |         Paths.push_back(ScratchPath); | 
 |       } else if (!isFindingAmbiguities()) { | 
 |         // We found a path and we don't care about ambiguities; | 
 |         // return immediately. | 
 |         return FoundPath; | 
 |       } | 
 |     } else if (VisitBase) { | 
 |       CXXRecordDecl *BaseRecord; | 
 |       if (LookupInDependent) { | 
 |         BaseRecord = nullptr; | 
 |         const TemplateSpecializationType *TST = | 
 |             BaseSpec.getType()->getAs<TemplateSpecializationType>(); | 
 |         if (!TST) { | 
 |           if (auto *RT = BaseSpec.getType()->getAs<RecordType>()) | 
 |             BaseRecord = cast<CXXRecordDecl>(RT->getDecl()); | 
 |         } else { | 
 |           TemplateName TN = TST->getTemplateName(); | 
 |           if (auto *TD = | 
 |                   dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl())) | 
 |             BaseRecord = TD->getTemplatedDecl(); | 
 |         } | 
 |         if (BaseRecord) { | 
 |           if (!BaseRecord->hasDefinition() || | 
 |               VisitedDependentRecords.count(BaseRecord)) { | 
 |             BaseRecord = nullptr; | 
 |           } else { | 
 |             VisitedDependentRecords.insert(BaseRecord); | 
 |           } | 
 |         } | 
 |       } else { | 
 |         BaseRecord = cast<CXXRecordDecl>( | 
 |             BaseSpec.getType()->castAs<RecordType>()->getDecl()); | 
 |       } | 
 |       if (BaseRecord && | 
 |           lookupInBases(Context, BaseRecord, BaseMatches, LookupInDependent)) { | 
 |         // C++ [class.member.lookup]p2: | 
 |         //   A member name f in one sub-object B hides a member name f in | 
 |         //   a sub-object A if A is a base class sub-object of B. Any | 
 |         //   declarations that are so hidden are eliminated from | 
 |         //   consideration. | 
 |  | 
 |         // There is a path to a base class that meets the criteria. If we're | 
 |         // not collecting paths or finding ambiguities, we're done. | 
 |         FoundPath = FoundPathThroughBase = true; | 
 |         if (!isFindingAmbiguities()) | 
 |           return FoundPath; | 
 |       } | 
 |     } | 
 |  | 
 |     // Pop this base specifier off the current path (if we're | 
 |     // collecting paths). | 
 |     if (isRecordingPaths()) { | 
 |       ScratchPath.pop_back(); | 
 |     } | 
 |  | 
 |     // If we set a virtual earlier, and this isn't a path, forget it again. | 
 |     if (SetVirtual && !FoundPathThroughBase) { | 
 |       DetectedVirtual = nullptr; | 
 |     } | 
 |   } | 
 |  | 
 |   // Reset the scratch path access. | 
 |   ScratchPath.Access = AccessToHere; | 
 |  | 
 |   return FoundPath; | 
 | } | 
 |  | 
 | bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches, | 
 |                                   CXXBasePaths &Paths, | 
 |                                   bool LookupInDependent) const { | 
 |   // If we didn't find anything, report that. | 
 |   if (!Paths.lookupInBases(getASTContext(), this, BaseMatches, | 
 |                            LookupInDependent)) | 
 |     return false; | 
 |  | 
 |   // If we're not recording paths or we won't ever find ambiguities, | 
 |   // we're done. | 
 |   if (!Paths.isRecordingPaths() || !Paths.isFindingAmbiguities()) | 
 |     return true; | 
 |  | 
 |   // C++ [class.member.lookup]p6: | 
 |   //   When virtual base classes are used, a hidden declaration can be | 
 |   //   reached along a path through the sub-object lattice that does | 
 |   //   not pass through the hiding declaration. This is not an | 
 |   //   ambiguity. The identical use with nonvirtual base classes is an | 
 |   //   ambiguity; in that case there is no unique instance of the name | 
 |   //   that hides all the others. | 
 |   // | 
 |   // FIXME: This is an O(N^2) algorithm, but DPG doesn't see an easy | 
 |   // way to make it any faster. | 
 |   Paths.Paths.remove_if([&Paths](const CXXBasePath &Path) { | 
 |     for (const CXXBasePathElement &PE : Path) { | 
 |       if (!PE.Base->isVirtual()) | 
 |         continue; | 
 |  | 
 |       CXXRecordDecl *VBase = nullptr; | 
 |       if (const RecordType *Record = PE.Base->getType()->getAs<RecordType>()) | 
 |         VBase = cast<CXXRecordDecl>(Record->getDecl()); | 
 |       if (!VBase) | 
 |         break; | 
 |  | 
 |       // The declaration(s) we found along this path were found in a | 
 |       // subobject of a virtual base. Check whether this virtual | 
 |       // base is a subobject of any other path; if so, then the | 
 |       // declaration in this path are hidden by that patch. | 
 |       for (const CXXBasePath &HidingP : Paths) { | 
 |         CXXRecordDecl *HidingClass = nullptr; | 
 |         if (const RecordType *Record = | 
 |                 HidingP.back().Base->getType()->getAs<RecordType>()) | 
 |           HidingClass = cast<CXXRecordDecl>(Record->getDecl()); | 
 |         if (!HidingClass) | 
 |           break; | 
 |  | 
 |         if (HidingClass->isVirtuallyDerivedFrom(VBase)) | 
 |           return true; | 
 |       } | 
 |     } | 
 |     return false; | 
 |   }); | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier, | 
 |                                   CXXBasePath &Path, | 
 |                                   const CXXRecordDecl *BaseRecord) { | 
 |   assert(BaseRecord->getCanonicalDecl() == BaseRecord && | 
 |          "User data for FindBaseClass is not canonical!"); | 
 |   return Specifier->getType()->castAs<RecordType>()->getDecl() | 
 |             ->getCanonicalDecl() == BaseRecord; | 
 | } | 
 |  | 
 | bool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier, | 
 |                                          CXXBasePath &Path, | 
 |                                          const CXXRecordDecl *BaseRecord) { | 
 |   assert(BaseRecord->getCanonicalDecl() == BaseRecord && | 
 |          "User data for FindBaseClass is not canonical!"); | 
 |   return Specifier->isVirtual() && | 
 |          Specifier->getType()->castAs<RecordType>()->getDecl() | 
 |             ->getCanonicalDecl() == BaseRecord; | 
 | } | 
 |  | 
 | bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier, | 
 |                                   CXXBasePath &Path, | 
 |                                   DeclarationName Name) { | 
 |   RecordDecl *BaseRecord = | 
 |     Specifier->getType()->castAs<RecordType>()->getDecl(); | 
 |  | 
 |   for (Path.Decls = BaseRecord->lookup(Name); | 
 |        !Path.Decls.empty(); | 
 |        Path.Decls = Path.Decls.slice(1)) { | 
 |     if (Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag)) | 
 |       return true; | 
 |   } | 
 |  | 
 |   return false; | 
 | } | 
 |  | 
 | static bool findOrdinaryMember(RecordDecl *BaseRecord, CXXBasePath &Path, | 
 |                                DeclarationName Name) { | 
 |   const unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | | 
 |                         Decl::IDNS_Member; | 
 |   for (Path.Decls = BaseRecord->lookup(Name); | 
 |        !Path.Decls.empty(); | 
 |        Path.Decls = Path.Decls.slice(1)) { | 
 |     if (Path.Decls.front()->isInIdentifierNamespace(IDNS)) | 
 |       return true; | 
 |   } | 
 |  | 
 |   return false; | 
 | } | 
 |  | 
 | bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier, | 
 |                                        CXXBasePath &Path, | 
 |                                        DeclarationName Name) { | 
 |   RecordDecl *BaseRecord = | 
 |       Specifier->getType()->castAs<RecordType>()->getDecl(); | 
 |   return findOrdinaryMember(BaseRecord, Path, Name); | 
 | } | 
 |  | 
 | bool CXXRecordDecl::FindOrdinaryMemberInDependentClasses( | 
 |     const CXXBaseSpecifier *Specifier, CXXBasePath &Path, | 
 |     DeclarationName Name) { | 
 |   const TemplateSpecializationType *TST = | 
 |       Specifier->getType()->getAs<TemplateSpecializationType>(); | 
 |   if (!TST) { | 
 |     auto *RT = Specifier->getType()->getAs<RecordType>(); | 
 |     if (!RT) | 
 |       return false; | 
 |     return findOrdinaryMember(RT->getDecl(), Path, Name); | 
 |   } | 
 |   TemplateName TN = TST->getTemplateName(); | 
 |   const auto *TD = dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl()); | 
 |   if (!TD) | 
 |     return false; | 
 |   CXXRecordDecl *RD = TD->getTemplatedDecl(); | 
 |   if (!RD) | 
 |     return false; | 
 |   return findOrdinaryMember(RD, Path, Name); | 
 | } | 
 |  | 
 | bool CXXRecordDecl::FindOMPReductionMember(const CXXBaseSpecifier *Specifier, | 
 |                                            CXXBasePath &Path, | 
 |                                            DeclarationName Name) { | 
 |   RecordDecl *BaseRecord = | 
 |       Specifier->getType()->castAs<RecordType>()->getDecl(); | 
 |  | 
 |   for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty(); | 
 |        Path.Decls = Path.Decls.slice(1)) { | 
 |     if (Path.Decls.front()->isInIdentifierNamespace(IDNS_OMPReduction)) | 
 |       return true; | 
 |   } | 
 |  | 
 |   return false; | 
 | } | 
 |  | 
 | bool CXXRecordDecl:: | 
 | FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier, | 
 |                               CXXBasePath &Path, | 
 |                               DeclarationName Name) { | 
 |   RecordDecl *BaseRecord = | 
 |     Specifier->getType()->castAs<RecordType>()->getDecl(); | 
 |  | 
 |   for (Path.Decls = BaseRecord->lookup(Name); | 
 |        !Path.Decls.empty(); | 
 |        Path.Decls = Path.Decls.slice(1)) { | 
 |     // FIXME: Refactor the "is it a nested-name-specifier?" check | 
 |     if (isa<TypedefNameDecl>(Path.Decls.front()) || | 
 |         Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag)) | 
 |       return true; | 
 |   } | 
 |  | 
 |   return false; | 
 | } | 
 |  | 
 | std::vector<const NamedDecl *> CXXRecordDecl::lookupDependentName( | 
 |     const DeclarationName &Name, | 
 |     llvm::function_ref<bool(const NamedDecl *ND)> Filter) { | 
 |   std::vector<const NamedDecl *> Results; | 
 |   // Lookup in the class. | 
 |   DeclContext::lookup_result DirectResult = lookup(Name); | 
 |   if (!DirectResult.empty()) { | 
 |     for (const NamedDecl *ND : DirectResult) { | 
 |       if (Filter(ND)) | 
 |         Results.push_back(ND); | 
 |     } | 
 |     return Results; | 
 |   } | 
 |   // Perform lookup into our base classes. | 
 |   CXXBasePaths Paths; | 
 |   Paths.setOrigin(this); | 
 |   if (!lookupInBases( | 
 |           [&](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { | 
 |             return CXXRecordDecl::FindOrdinaryMemberInDependentClasses( | 
 |                 Specifier, Path, Name); | 
 |           }, | 
 |           Paths, /*LookupInDependent=*/true)) | 
 |     return Results; | 
 |   for (const NamedDecl *ND : Paths.front().Decls) { | 
 |     if (Filter(ND)) | 
 |       Results.push_back(ND); | 
 |   } | 
 |   return Results; | 
 | } | 
 |  | 
 | void OverridingMethods::add(unsigned OverriddenSubobject, | 
 |                             UniqueVirtualMethod Overriding) { | 
 |   SmallVectorImpl<UniqueVirtualMethod> &SubobjectOverrides | 
 |     = Overrides[OverriddenSubobject]; | 
 |   if (std::find(SubobjectOverrides.begin(), SubobjectOverrides.end(), | 
 |                 Overriding) == SubobjectOverrides.end()) | 
 |     SubobjectOverrides.push_back(Overriding); | 
 | } | 
 |  | 
 | void OverridingMethods::add(const OverridingMethods &Other) { | 
 |   for (const_iterator I = Other.begin(), IE = Other.end(); I != IE; ++I) { | 
 |     for (overriding_const_iterator M = I->second.begin(), | 
 |                                 MEnd = I->second.end(); | 
 |          M != MEnd; | 
 |          ++M) | 
 |       add(I->first, *M); | 
 |   } | 
 | } | 
 |  | 
 | void OverridingMethods::replaceAll(UniqueVirtualMethod Overriding) { | 
 |   for (iterator I = begin(), IEnd = end(); I != IEnd; ++I) { | 
 |     I->second.clear(); | 
 |     I->second.push_back(Overriding); | 
 |   } | 
 | } | 
 |  | 
 | namespace { | 
 |  | 
 | class FinalOverriderCollector { | 
 |   /// The number of subobjects of a given class type that | 
 |   /// occur within the class hierarchy. | 
 |   llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCount; | 
 |  | 
 |   /// Overriders for each virtual base subobject. | 
 |   llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *> VirtualOverriders; | 
 |  | 
 |   CXXFinalOverriderMap FinalOverriders; | 
 |  | 
 | public: | 
 |   ~FinalOverriderCollector(); | 
 |  | 
 |   void Collect(const CXXRecordDecl *RD, bool VirtualBase, | 
 |                const CXXRecordDecl *InVirtualSubobject, | 
 |                CXXFinalOverriderMap &Overriders); | 
 | }; | 
 |  | 
 | } // namespace | 
 |  | 
 | void FinalOverriderCollector::Collect(const CXXRecordDecl *RD, | 
 |                                       bool VirtualBase, | 
 |                                       const CXXRecordDecl *InVirtualSubobject, | 
 |                                       CXXFinalOverriderMap &Overriders) { | 
 |   unsigned SubobjectNumber = 0; | 
 |   if (!VirtualBase) | 
 |     SubobjectNumber | 
 |       = ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())]; | 
 |  | 
 |   for (const auto &Base : RD->bases()) { | 
 |     if (const RecordType *RT = Base.getType()->getAs<RecordType>()) { | 
 |       const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(RT->getDecl()); | 
 |       if (!BaseDecl->isPolymorphic()) | 
 |         continue; | 
 |  | 
 |       if (Overriders.empty() && !Base.isVirtual()) { | 
 |         // There are no other overriders of virtual member functions, | 
 |         // so let the base class fill in our overriders for us. | 
 |         Collect(BaseDecl, false, InVirtualSubobject, Overriders); | 
 |         continue; | 
 |       } | 
 |  | 
 |       // Collect all of the overridders from the base class subobject | 
 |       // and merge them into the set of overridders for this class. | 
 |       // For virtual base classes, populate or use the cached virtual | 
 |       // overrides so that we do not walk the virtual base class (and | 
 |       // its base classes) more than once. | 
 |       CXXFinalOverriderMap ComputedBaseOverriders; | 
 |       CXXFinalOverriderMap *BaseOverriders = &ComputedBaseOverriders; | 
 |       if (Base.isVirtual()) { | 
 |         CXXFinalOverriderMap *&MyVirtualOverriders = VirtualOverriders[BaseDecl]; | 
 |         BaseOverriders = MyVirtualOverriders; | 
 |         if (!MyVirtualOverriders) { | 
 |           MyVirtualOverriders = new CXXFinalOverriderMap; | 
 |  | 
 |           // Collect may cause VirtualOverriders to reallocate, invalidating the | 
 |           // MyVirtualOverriders reference. Set BaseOverriders to the right | 
 |           // value now. | 
 |           BaseOverriders = MyVirtualOverriders; | 
 |  | 
 |           Collect(BaseDecl, true, BaseDecl, *MyVirtualOverriders); | 
 |         } | 
 |       } else | 
 |         Collect(BaseDecl, false, InVirtualSubobject, ComputedBaseOverriders); | 
 |  | 
 |       // Merge the overriders from this base class into our own set of | 
 |       // overriders. | 
 |       for (CXXFinalOverriderMap::iterator OM = BaseOverriders->begin(), | 
 |                                OMEnd = BaseOverriders->end(); | 
 |            OM != OMEnd; | 
 |            ++OM) { | 
 |         const CXXMethodDecl *CanonOM = OM->first->getCanonicalDecl(); | 
 |         Overriders[CanonOM].add(OM->second); | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   for (auto *M : RD->methods()) { | 
 |     // We only care about virtual methods. | 
 |     if (!M->isVirtual()) | 
 |       continue; | 
 |  | 
 |     CXXMethodDecl *CanonM = M->getCanonicalDecl(); | 
 |     using OverriddenMethodsRange = | 
 |         llvm::iterator_range<CXXMethodDecl::method_iterator>; | 
 |     OverriddenMethodsRange OverriddenMethods = CanonM->overridden_methods(); | 
 |  | 
 |     if (OverriddenMethods.begin() == OverriddenMethods.end()) { | 
 |       // This is a new virtual function that does not override any | 
 |       // other virtual function. Add it to the map of virtual | 
 |       // functions for which we are tracking overridders. | 
 |  | 
 |       // C++ [class.virtual]p2: | 
 |       //   For convenience we say that any virtual function overrides itself. | 
 |       Overriders[CanonM].add(SubobjectNumber, | 
 |                              UniqueVirtualMethod(CanonM, SubobjectNumber, | 
 |                                                  InVirtualSubobject)); | 
 |       continue; | 
 |     } | 
 |  | 
 |     // This virtual method overrides other virtual methods, so it does | 
 |     // not add any new slots into the set of overriders. Instead, we | 
 |     // replace entries in the set of overriders with the new | 
 |     // overrider. To do so, we dig down to the original virtual | 
 |     // functions using data recursion and update all of the methods it | 
 |     // overrides. | 
 |     SmallVector<OverriddenMethodsRange, 4> Stack(1, OverriddenMethods); | 
 |     while (!Stack.empty()) { | 
 |       for (const CXXMethodDecl *OM : Stack.pop_back_val()) { | 
 |         const CXXMethodDecl *CanonOM = OM->getCanonicalDecl(); | 
 |  | 
 |         // C++ [class.virtual]p2: | 
 |         //   A virtual member function C::vf of a class object S is | 
 |         //   a final overrider unless the most derived class (1.8) | 
 |         //   of which S is a base class subobject (if any) declares | 
 |         //   or inherits another member function that overrides vf. | 
 |         // | 
 |         // Treating this object like the most derived class, we | 
 |         // replace any overrides from base classes with this | 
 |         // overriding virtual function. | 
 |         Overriders[CanonOM].replaceAll( | 
 |                                UniqueVirtualMethod(CanonM, SubobjectNumber, | 
 |                                                    InVirtualSubobject)); | 
 |  | 
 |         auto OverriddenMethods = CanonOM->overridden_methods(); | 
 |         if (OverriddenMethods.begin() == OverriddenMethods.end()) | 
 |           continue; | 
 |  | 
 |         // Continue recursion to the methods that this virtual method | 
 |         // overrides. | 
 |         Stack.push_back(OverriddenMethods); | 
 |       } | 
 |     } | 
 |  | 
 |     // C++ [class.virtual]p2: | 
 |     //   For convenience we say that any virtual function overrides itself. | 
 |     Overriders[CanonM].add(SubobjectNumber, | 
 |                            UniqueVirtualMethod(CanonM, SubobjectNumber, | 
 |                                                InVirtualSubobject)); | 
 |   } | 
 | } | 
 |  | 
 | FinalOverriderCollector::~FinalOverriderCollector() { | 
 |   for (llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *>::iterator | 
 |          VO = VirtualOverriders.begin(), VOEnd = VirtualOverriders.end(); | 
 |        VO != VOEnd; | 
 |        ++VO) | 
 |     delete VO->second; | 
 | } | 
 |  | 
 | void | 
 | CXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap &FinalOverriders) const { | 
 |   FinalOverriderCollector Collector; | 
 |   Collector.Collect(this, false, nullptr, FinalOverriders); | 
 |  | 
 |   // Weed out any final overriders that come from virtual base class | 
 |   // subobjects that were hidden by other subobjects along any path. | 
 |   // This is the final-overrider variant of C++ [class.member.lookup]p10. | 
 |   for (auto &OM : FinalOverriders) { | 
 |     for (auto &SO : OM.second) { | 
 |       SmallVectorImpl<UniqueVirtualMethod> &Overriding = SO.second; | 
 |       if (Overriding.size() < 2) | 
 |         continue; | 
 |  | 
 |       auto IsHidden = [&Overriding](const UniqueVirtualMethod &M) { | 
 |         if (!M.InVirtualSubobject) | 
 |           return false; | 
 |  | 
 |         // We have an overriding method in a virtual base class | 
 |         // subobject (or non-virtual base class subobject thereof); | 
 |         // determine whether there exists an other overriding method | 
 |         // in a base class subobject that hides the virtual base class | 
 |         // subobject. | 
 |         for (const UniqueVirtualMethod &OP : Overriding) | 
 |           if (&M != &OP && | 
 |               OP.Method->getParent()->isVirtuallyDerivedFrom( | 
 |                   M.InVirtualSubobject)) | 
 |             return true; | 
 |         return false; | 
 |       }; | 
 |  | 
 |       Overriding.erase( | 
 |           std::remove_if(Overriding.begin(), Overriding.end(), IsHidden), | 
 |           Overriding.end()); | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | static void | 
 | AddIndirectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context, | 
 |                         CXXIndirectPrimaryBaseSet& Bases) { | 
 |   // If the record has a virtual primary base class, add it to our set. | 
 |   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); | 
 |   if (Layout.isPrimaryBaseVirtual()) | 
 |     Bases.insert(Layout.getPrimaryBase()); | 
 |  | 
 |   for (const auto &I : RD->bases()) { | 
 |     assert(!I.getType()->isDependentType() && | 
 |            "Cannot get indirect primary bases for class with dependent bases."); | 
 |  | 
 |     const CXXRecordDecl *BaseDecl = | 
 |       cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); | 
 |  | 
 |     // Only bases with virtual bases participate in computing the | 
 |     // indirect primary virtual base classes. | 
 |     if (BaseDecl->getNumVBases()) | 
 |       AddIndirectPrimaryBases(BaseDecl, Context, Bases); | 
 |   } | 
 |  | 
 | } | 
 |  | 
 | void | 
 | CXXRecordDecl::getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const { | 
 |   ASTContext &Context = getASTContext(); | 
 |  | 
 |   if (!getNumVBases()) | 
 |     return; | 
 |  | 
 |   for (const auto &I : bases()) { | 
 |     assert(!I.getType()->isDependentType() && | 
 |            "Cannot get indirect primary bases for class with dependent bases."); | 
 |  | 
 |     const CXXRecordDecl *BaseDecl = | 
 |       cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); | 
 |  | 
 |     // Only bases with virtual bases participate in computing the | 
 |     // indirect primary virtual base classes. | 
 |     if (BaseDecl->getNumVBases()) | 
 |       AddIndirectPrimaryBases(BaseDecl, Context, Bases); | 
 |   } | 
 | } |