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

llvm-svn: 82251
diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp
index 2deaedc..fd187c5 100644
--- a/clang/lib/Sema/CodeCompleteConsumer.cpp
+++ b/clang/lib/Sema/CodeCompleteConsumer.cpp
@@ -118,6 +118,63 @@
   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 @@
   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;