Add using directives to the clang::DeclContext and fix decls for variables inside namespaces

Summary: Supports the parsing of the "using namespace XXX" and "using XXX::XXX" directives. Added ambiguity errors when it two decls with the same name are encountered (see comments in TestCppNsImport). Fixes using directives being duplicated for anonymous namespaces. Fixes GetDeclForUID for specification DIEs.

Reviewers: sivachandra, chaoren, clayborg

Subscribers: lldb-commits

Differential Revision: http://reviews.llvm.org/D12897

llvm-svn: 247836
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 97a5a7f..712c5dd 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -1730,24 +1730,6 @@
                 // BAD!!!
             }
         }
-        
-
-        if (namespace_decl)
-        {
-            // If we make it here, we are creating the anonymous namespace decl
-            // for the first time, so we need to do the using directive magic
-            // like SEMA does
-            UsingDirectiveDecl* using_directive_decl = UsingDirectiveDecl::Create (*ast, 
-                                                                                   decl_ctx, 
-                                                                                   SourceLocation(),
-                                                                                   SourceLocation(),
-                                                                                   NestedNameSpecifierLoc(),
-                                                                                   SourceLocation(),
-                                                                                   namespace_decl,
-                                                                                   decl_ctx);
-            using_directive_decl->setImplicit();
-            decl_ctx->addDecl(using_directive_decl);
-        }
     }
 #ifdef LLDB_CONFIGURATION_DEBUG
     VerifyDecl(namespace_decl);
@@ -1768,12 +1750,29 @@
     return nullptr;
 }
 
+clang::DeclContext *
+FindLCABetweenDecls(clang::DeclContext *left, clang::DeclContext *right, clang::DeclContext *root)
+{
+    if (root == nullptr)
+        return nullptr;
+
+    std::set<clang::DeclContext *> path_left;
+    for (clang::DeclContext *d = left; d != nullptr; d = d->getParent())
+        path_left.insert(d);
+
+    for (clang::DeclContext *d = right; d != nullptr; d = d->getParent())
+        if (path_left.find(d) != path_left.end())
+            return d;
+
+    return nullptr;
+}
+
 clang::UsingDirectiveDecl *
 ClangASTContext::CreateUsingDirectiveDeclaration (clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl)
 {
     if (decl_ctx != nullptr && ns_decl != nullptr)
     {
-        // TODO: run LCA between decl_tx and ns_decl
+        clang::TranslationUnitDecl *translation_unit = (clang::TranslationUnitDecl *)GetTranslationUnitDecl(getASTContext());
         clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(*getASTContext(),
             decl_ctx,
             clang::SourceLocation(),
@@ -1781,7 +1780,7 @@
             clang::NestedNameSpecifierLoc(),
             clang::SourceLocation(),
             ns_decl,
-            GetTranslationUnitDecl(getASTContext()));
+            FindLCABetweenDecls(decl_ctx, ns_decl, translation_unit));
         decl_ctx->addDecl(using_decl);
         return using_decl;
     }
@@ -1826,7 +1825,6 @@
             clang::SC_None);
         var_decl->setAccess(clang::AS_public);
         decl_context->addDecl(var_decl);
-        decl_context->makeDeclVisibleInContext(var_decl);
         return var_decl;
     }
     return nullptr;
@@ -8867,6 +8865,7 @@
         DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx;
         std::set<DeclContext *> searched;
         std::multimap<DeclContext *, DeclContext *> search_queue;
+        SymbolFile *symbol_file = GetSymbolFile();
 
         for (clang::DeclContext *decl_context = root_decl_ctx; decl_context != nullptr && found_decls.empty(); decl_context = decl_context->getParent())
         {
@@ -8875,15 +8874,11 @@
             for (auto it = search_queue.find(decl_context); it != search_queue.end(); it++)
             {
                 searched.insert(it->second);
+                symbol_file->ParseDeclsForContext(CompilerDeclContext(this, it->second));
+
                 for (clang::Decl *child : it->second->decls())
                 {
-                    if (clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(child))
-                    {
-                        IdentifierInfo *ii = nd->getIdentifier();
-                        if (ii != nullptr && ii->getName().equals(name.AsCString(nullptr)))
-                            found_decls.push_back(nd);
-                    }
-                    else if (clang::UsingDirectiveDecl *ud = llvm::dyn_cast<clang::UsingDirectiveDecl>(child))
+                    if (clang::UsingDirectiveDecl *ud = llvm::dyn_cast<clang::UsingDirectiveDecl>(child))
                     {
                         clang::DeclContext *from = ud->getCommonAncestor();
                         if (searched.find(ud->getNominatedNamespace()) == searched.end())
@@ -8902,6 +8897,12 @@
                             }
                         }
                     }
+                    else if (clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(child))
+                    {
+                        IdentifierInfo *ii = nd->getIdentifier();
+                        if (ii != nullptr && ii->getName().equals(name.AsCString(nullptr)))
+                            found_decls.push_back(nd);
+                    }
                 }
             }
         }