From 89b7702c9a64e12093ed34fc02dc3cfbb6eb133a Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 3 Mar 2010 02:18:00 +0000 Subject: [PATCH] Refactor CXXRecordDecl::lookupInBases() to push the recursion down a level. No functionality change, and it obeys access control this time. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97634 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/CXXInheritance.h | 7 +++- lib/AST/CXXInheritance.cpp | 62 +++++++++++++++++------------- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index 79a3022ee0..c89e5e4b16 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -16,6 +16,7 @@ #include "clang/AST/DeclarationName.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/Type.h" #include "clang/AST/TypeOrdering.h" #include "llvm/ADT/SmallVector.h" @@ -159,7 +160,11 @@ class CXXBasePaths { friend class CXXRecordDecl; void ComputeDeclsFound(); - + + bool lookupInBases(ASTContext &Context, + const CXXRecordDecl *Record, + CXXRecordDecl::BaseMatchesCallback *BaseMatches, + void *UserData); public: typedef std::list::iterator paths_iterator; typedef std::list::const_iterator const_paths_iterator; diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp index 99f908caea..8615df4e79 100644 --- a/lib/AST/CXXInheritance.cpp +++ b/lib/AST/CXXInheritance.cpp @@ -140,18 +140,20 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches, return AllMatches; } -bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches, - void *UserData, - CXXBasePaths &Paths) const { +bool CXXBasePaths::lookupInBases(ASTContext &Context, + const CXXRecordDecl *Record, + CXXRecordDecl::BaseMatchesCallback *BaseMatches, + void *UserData) { bool FoundPath = false; // The access of the path down to this record. - AccessSpecifier AccessToHere = Paths.ScratchPath.Access; - bool IsFirstStep = Paths.ScratchPath.empty(); + AccessSpecifier AccessToHere = ScratchPath.Access; + bool IsFirstStep = ScratchPath.empty(); - ASTContext &Context = getASTContext(); - for (base_class_const_iterator BaseSpec = bases_begin(), - BaseSpecEnd = bases_end(); BaseSpec != BaseSpecEnd; ++BaseSpec) { + for (CXXRecordDecl::base_class_const_iterator BaseSpec = Record->bases_begin(), + BaseSpecEnd = Record->bases_end(); + BaseSpec != BaseSpecEnd; + ++BaseSpec) { // Find the record of the base class subobjects for this type. QualType BaseType = Context.getCanonicalType(BaseSpec->getType()) .getUnqualifiedType(); @@ -167,31 +169,31 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches, // Determine whether we need to visit this base class at all, // updating the count of subobjects appropriately. - std::pair& Subobjects = Paths.ClassSubobjects[BaseType]; + std::pair& Subobjects = ClassSubobjects[BaseType]; bool VisitBase = true; bool SetVirtual = false; if (BaseSpec->isVirtual()) { VisitBase = !Subobjects.first; Subobjects.first = true; - if (Paths.isDetectingVirtual() && Paths.DetectedVirtual == 0) { + if (isDetectingVirtual() && DetectedVirtual == 0) { // 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. - Paths.DetectedVirtual = BaseType->getAs(); + DetectedVirtual = BaseType->getAs(); SetVirtual = true; } } else ++Subobjects.second; - if (Paths.isRecordingPaths()) { + if (isRecordingPaths()) { // Add this base specifier to the current path. CXXBasePathElement Element; Element.Base = &*BaseSpec; - Element.Class = this; + Element.Class = Record; if (BaseSpec->isVirtual()) Element.SubobjectNumber = 0; else Element.SubobjectNumber = Subobjects.second; - Paths.ScratchPath.push_back(Element); + ScratchPath.push_back(Element); // Calculate the "top-down" access to this base class. // The spec actually describes this bottom-up, but top-down is @@ -209,22 +211,22 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches, // 3. Otherwise, overall access is determined by the most restrictive // access in the sequence. if (IsFirstStep) - Paths.ScratchPath.Access = BaseSpec->getAccessSpecifier(); + ScratchPath.Access = BaseSpec->getAccessSpecifier(); else - Paths.ScratchPath.Access - = MergeAccess(AccessToHere, BaseSpec->getAccessSpecifier()); + ScratchPath.Access = CXXRecordDecl::MergeAccess(AccessToHere, + BaseSpec->getAccessSpecifier()); } // Track whether there's a path involving this specific base. bool FoundPathThroughBase = false; - if (BaseMatches(BaseSpec, Paths.ScratchPath, UserData)) { + if (BaseMatches(BaseSpec, ScratchPath, UserData)) { // We've found a path that terminates at this base. FoundPath = FoundPathThroughBase = true; - if (Paths.isRecordingPaths()) { + if (isRecordingPaths()) { // We have a path. Make a copy of it before moving on. - Paths.Paths.push_back(Paths.ScratchPath); - } else if (!Paths.isFindingAmbiguities()) { + Paths.push_back(ScratchPath); + } else if (!isFindingAmbiguities()) { // We found a path and we don't care about ambiguities; // return immediately. return FoundPath; @@ -233,7 +235,7 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches, CXXRecordDecl *BaseRecord = cast(BaseSpec->getType()->getAs() ->getDecl()); - if (BaseRecord->lookupInBases(BaseMatches, UserData, Paths)) { + if (lookupInBases(Context, BaseRecord, BaseMatches, UserData)) { // 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 @@ -243,29 +245,35 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches, // 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 (!Paths.isFindingAmbiguities()) + if (!isFindingAmbiguities()) return FoundPath; } } // Pop this base specifier off the current path (if we're // collecting paths). - if (Paths.isRecordingPaths()) { - Paths.ScratchPath.pop_back(); + if (isRecordingPaths()) { + ScratchPath.pop_back(); } // If we set a virtual earlier, and this isn't a path, forget it again. if (SetVirtual && !FoundPathThroughBase) { - Paths.DetectedVirtual = 0; + DetectedVirtual = 0; } } // Reset the scratch path access. - Paths.ScratchPath.Access = AccessToHere; + ScratchPath.Access = AccessToHere; return FoundPath; } +bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches, + void *UserData, + CXXBasePaths &Paths) const { + return Paths.lookupInBases(getASTContext(), this, BaseMatches, UserData); +} + bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier, CXXBasePath &Path, void *BaseRecord) { -- 2.40.0