From 5836b010d0a74c8b7be3f2616332cd70d3c87f83 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 18 Sep 2009 18:07:23 +0000 Subject: [PATCH] Don't perform name lookup into a given declaration context more than once during code completion git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82234 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/CodeCompleteConsumer.h | 3 ++ lib/Sema/CodeCompleteConsumer.cpp | 35 ++++++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index ce5707ed3a..a1d07a0fb3 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -198,6 +198,9 @@ public: ResultSet &Results); unsigned CollectMemberLookupResults(DeclContext *Ctx, unsigned InitialRank, ResultSet &Results); + unsigned CollectMemberLookupResults(DeclContext *Ctx, unsigned InitialRank, + llvm::SmallPtrSet &Visited, + ResultSet &Results); //@} /// \name Name lookup predicates diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp index b626847d62..2deaedcf09 100644 --- a/lib/Sema/CodeCompleteConsumer.cpp +++ b/lib/Sema/CodeCompleteConsumer.cpp @@ -320,9 +320,38 @@ unsigned CodeCompleteConsumer::CollectLookupResults(Scope *S, /// /// \returns the next higher rank value, after considering all of the /// names within this declaration context. +unsigned CodeCompleteConsumer::CollectMemberLookupResults(DeclContext *Ctx, + unsigned InitialRank, + ResultSet &Results) { + llvm::SmallPtrSet Visited; + return CollectMemberLookupResults(Ctx, InitialRank, Visited, Results); +} + +/// \brief Collect the results of searching for members within the given +/// declaration context. +/// +/// \param Ctx the declaration context from which we will gather results. +/// +/// \param InitialRank the initial rank given to results in this declaration +/// context. Larger rank values will be used for, e.g., members found in +/// base classes. +/// +/// \param Visited the set of declaration contexts that have already been +/// visited. Declaration contexts will only be visited once. +/// +/// \param Results the result set that will be extended with any results +/// found within this declaration context (and, for a C++ class, its bases). +/// +/// \returns the next higher rank value, after considering all of the +/// names within this declaration context. unsigned CodeCompleteConsumer::CollectMemberLookupResults(DeclContext *Ctx, unsigned InitialRank, + llvm::SmallPtrSet &Visited, ResultSet &Results) { + // Make sure we don't visit the same context twice. + if (!Visited.insert(Ctx->getPrimaryContext())) + return InitialRank; + // Enumerate all of the results in this context. Results.EnterNewScope(); for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx; @@ -352,9 +381,6 @@ unsigned CodeCompleteConsumer::CollectMemberLookupResults(DeclContext *Ctx, if (!Record) continue; - // FIXME: We should keep track of the virtual bases we visit, so - // that we don't visit them more than once. - // FIXME: It would be nice to be able to determine whether referencing // a particular member would be ambiguous. For example, given // @@ -376,7 +402,8 @@ unsigned CodeCompleteConsumer::CollectMemberLookupResults(DeclContext *Ctx, // Collect results from this base class (and its bases). NextRank = std::max(NextRank, CollectMemberLookupResults(Record->getDecl(), - InitialRank + 1, + InitialRank + 1, + Visited, Results)); } } -- 2.50.1