diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-08-16 21:18:39 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-08-16 21:18:39 +0000 |
commit | 5f808c2bfe2f95c984029d76deb4aaebcad30cbc (patch) | |
tree | 02011ccbb7cd5c8fc779281d6d3d919a073b55be /lib/Frontend/ASTUnit.cpp | |
parent | d5addb48398241e1f63c114d860dfe30346258e8 (diff) |
Implement name hiding of cached global code-completion results.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111184 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/ASTUnit.cpp')
-rw-r--r-- | lib/Frontend/ASTUnit.cpp | 84 |
1 files changed, 81 insertions, 3 deletions
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 2c827e41da..f8dea65d54 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -1435,15 +1435,85 @@ namespace { }; } +/// \brief Helper function that computes which global names are hidden by the +/// local code-completion results. +void CalculateHiddenNames(const CodeCompletionContext &Context, + CodeCompleteConsumer::Result *Results, + unsigned NumResults, + ASTContext &Ctx, + llvm::StringSet<> &HiddenNames) { + bool OnlyTagNames = false; + switch (Context.getKind()) { + case CodeCompletionContext::CCC_Other: + case CodeCompletionContext::CCC_TopLevel: + case CodeCompletionContext::CCC_ObjCInterface: + case CodeCompletionContext::CCC_ObjCImplementation: + case CodeCompletionContext::CCC_ObjCIvarList: + case CodeCompletionContext::CCC_ClassStructUnion: + case CodeCompletionContext::CCC_Statement: + case CodeCompletionContext::CCC_Expression: + case CodeCompletionContext::CCC_ObjCMessageReceiver: + case CodeCompletionContext::CCC_MemberAccess: + case CodeCompletionContext::CCC_Namespace: + case CodeCompletionContext::CCC_Type: + break; + + case CodeCompletionContext::CCC_EnumTag: + case CodeCompletionContext::CCC_UnionTag: + case CodeCompletionContext::CCC_ClassOrStructTag: + OnlyTagNames = true; + break; + + case CodeCompletionContext::CCC_ObjCProtocolName: + // If we're just looking for protocol names, nothing can hide them. + return; + } + + typedef CodeCompleteConsumer::Result Result; + for (unsigned I = 0; I != NumResults; ++I) { + if (Results[I].Kind != Result::RK_Declaration) + continue; + + unsigned IDNS + = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace(); + + bool Hiding = false; + if (OnlyTagNames) + Hiding = (IDNS & Decl::IDNS_Tag); + else { + unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member | + Decl::IDNS_Namespace | Decl::IDNS_Ordinary | + Decl::IDNS_NonMemberOperator); + if (Ctx.getLangOptions().CPlusPlus) + HiddenIDNS |= Decl::IDNS_Tag; + Hiding = (IDNS & HiddenIDNS); + } + + if (!Hiding) + continue; + + DeclarationName Name = Results[I].Declaration->getDeclName(); + if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo()) + HiddenNames.insert(Identifier->getName()); + else + HiddenNames.insert(Name.getAsString()); + } +} + + void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context, Result *Results, unsigned NumResults) { // Merge the results we were given with the results we cached. bool AddedResult = false; - unsigned InContexts = - (Context.getKind() == CodeCompletionContext::CCC_Other? NormalContexts - : (1 << (Context.getKind() - 1))); + unsigned InContexts + = (Context.getKind() == CodeCompletionContext::CCC_Other? NormalContexts + : (1 << (Context.getKind() - 1))); + + // Contains the set of names that are hidden by "local" completion results. + llvm::StringSet<> HiddenNames; + typedef CodeCompleteConsumer::Result Result; llvm::SmallVector<Result, 8> AllResults; for (ASTUnit::cached_completion_iterator @@ -1457,10 +1527,18 @@ void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S, // If we haven't added any results previously, do so now. if (!AddedResult) { + CalculateHiddenNames(Context, Results, NumResults, S.Context, + HiddenNames); AllResults.insert(AllResults.end(), Results, Results + NumResults); AddedResult = true; } + // Determine whether this global completion result is hidden by a local + // completion result. If so, skip it. + if (C->Kind != CXCursor_MacroDefinition && + HiddenNames.count(C->Completion->getTypedText())) + continue; + // Adjust priority based on similar type classes. unsigned Priority = C->Priority; if (!Context.getPreferredType().isNull()) { |