diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-09-18 19:03:04 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-09-18 19:03:04 +0000 |
commit | 49f40bd0c9c9de5e74727774fec429b47d36303a (patch) | |
tree | 4ff8ee97f177b7a7b080e1757932437ec6c1702b /lib/Sema | |
parent | 2744a063f1d9c475d76c2276f0b4f0998dfc5d09 (diff) |
Introduce four new code-completion hooks for C++:
- after "using", show anything that can be a nested-name-specifier.
- after "using namespace", show any visible namespaces or namespace aliases
- after "namespace", show any namespace definitions in the current scope
- after "namespace identifier = ", show any visible namespaces or
namespace aliases
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82251 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/CodeCompleteConsumer.cpp | 68 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 6 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 30 |
3 files changed, 102 insertions, 2 deletions
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp index 2deaedcf09..fd187c5ef9 100644 --- a/lib/Sema/CodeCompleteConsumer.cpp +++ b/lib/Sema/CodeCompleteConsumer.cpp @@ -118,6 +118,63 @@ CodeCompleteConsumer::CodeCompleteQualifiedId(Scope *S, ProcessCodeCompleteResults(Results.data(), Results.size()); } +void CodeCompleteConsumer::CodeCompleteUsing(Scope *S) { + ResultSet Results(*this, &CodeCompleteConsumer::IsNestedNameSpecifier); + + // If we aren't in class scope, we could see the "namespace" keyword. + if (!S->isClassScope()) + Results.MaybeAddResult(Result("namespace", 0)); + + // After "using", we can see anything that would start a + // nested-name-specifier. + CollectLookupResults(S, 0, Results); + + ProcessCodeCompleteResults(Results.data(), Results.size()); +} + +void CodeCompleteConsumer::CodeCompleteUsingDirective(Scope *S) { + // After "using namespace", we expect to see a namespace name or namespace + // alias. + ResultSet Results(*this, &CodeCompleteConsumer::IsNamespaceOrAlias); + CollectLookupResults(S, 0, Results); + ProcessCodeCompleteResults(Results.data(), Results.size()); +} + +void CodeCompleteConsumer::CodeCompleteNamespaceDecl(Scope *S) { + ResultSet Results(*this, &CodeCompleteConsumer::IsNamespace); + DeclContext *Ctx = (DeclContext *)S->getEntity(); + if (!S->getParent()) + Ctx = getSema().Context.getTranslationUnitDecl(); + + if (Ctx && Ctx->isFileContext()) { + // We only want to see those namespaces that have already been defined + // within this scope, because its likely that the user is creating an + // extended namespace declaration. Keep track of the most recent + // definition of each namespace. + std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest; + for (DeclContext::specific_decl_iterator<NamespaceDecl> + NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end()); + NS != NSEnd; ++NS) + OrigToLatest[NS->getOriginalNamespace()] = *NS; + + // Add the most recent definition (or extended definition) of each + // namespace to the list of results. + for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator + NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end(); + NS != NSEnd; ++NS) + Results.MaybeAddResult(Result(NS->second, 0)); + } + + ProcessCodeCompleteResults(Results.data(), Results.size()); +} + +void CodeCompleteConsumer::CodeCompleteNamespaceAliasDecl(Scope *S) { + // After "namespace", we expect to see a namespace or alias. + ResultSet Results(*this, &CodeCompleteConsumer::IsNamespaceOrAlias); + CollectLookupResults(S, 0, Results); + ProcessCodeCompleteResults(Results.data(), Results.size()); +} + void CodeCompleteConsumer::ResultSet::MaybeAddResult(Result R) { if (R.Kind != Result::RK_Declaration) { // For non-declaration results, just add the result. @@ -454,6 +511,17 @@ bool CodeCompleteConsumer::IsUnion(NamedDecl *ND) const { return false; } +/// \brief Determines whether the given declaration is a namespace. +bool CodeCompleteConsumer::IsNamespace(NamedDecl *ND) const { + return isa<NamespaceDecl>(ND); +} + +/// \brief Determines whether the given declaration is a namespace or +/// namespace alias. +bool CodeCompleteConsumer::IsNamespaceOrAlias(NamedDecl *ND) const { + return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND); +} + namespace { struct VISIBILITY_HIDDEN SortCodeCompleteResult { typedef CodeCompleteConsumer::Result Result; diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 2952c843f4..8bec9d54f5 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -3635,11 +3635,13 @@ public: virtual void CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *Base, SourceLocation OpLoc, bool IsArrow); - virtual void CodeCompleteTag(Scope *S, unsigned TagSpec); - virtual void CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS, bool EnteringContext); + virtual void CodeCompleteUsing(Scope *S); + virtual void CodeCompleteUsingDirective(Scope *S); + virtual void CodeCompleteNamespaceDecl(Scope *S); + virtual void CodeCompleteNamespaceAliasDecl(Scope *S); //@} //===--------------------------------------------------------------------===// diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index bfee4d8b76..50b8ffd1f4 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -72,3 +72,33 @@ void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS, (NestedNameSpecifier *)SS.getScopeRep(), EnteringContext); } + +void Sema::CodeCompleteUsing(Scope *S) { + if (!CodeCompleter) + return; + + CodeCompleter->CodeCompleteUsing(S); +} + +void Sema::CodeCompleteUsingDirective(Scope *S) { + if (!CodeCompleter) + return; + + CodeCompleter->CodeCompleteUsingDirective(S); +} + +void Sema::CodeCompleteNamespaceDecl(Scope *S) { + if (!CodeCompleter) + return; + + CodeCompleter->CodeCompleteNamespaceDecl(S); +} + +void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) { + if (!CodeCompleter) + return; + + CodeCompleter->CodeCompleteNamespaceAliasDecl(S); +} + + |