aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-09-18 19:03:04 +0000
committerDouglas Gregor <dgregor@apple.com>2009-09-18 19:03:04 +0000
commit49f40bd0c9c9de5e74727774fec429b47d36303a (patch)
tree4ff8ee97f177b7a7b080e1757932437ec6c1702b /lib/Sema
parent2744a063f1d9c475d76c2276f0b4f0998dfc5d09 (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.cpp68
-rw-r--r--lib/Sema/Sema.h6
-rw-r--r--lib/Sema/SemaCodeComplete.cpp30
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);
+}
+
+