diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/CodeCompleteConsumer.cpp | 68 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 30 |
3 files changed, 102 insertions, 2 deletions
diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp index 2deaedcf098..fd187c5ef9f 100644 --- a/clang/lib/Sema/CodeCompleteConsumer.cpp +++ b/clang/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/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 2952c843f45..8bec9d54f5d 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index bfee4d8b767..50b8ffd1f49 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/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); +} + + |