paulherman updated this revision to Diff 34911.
paulherman added a comment.

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

Rebased the patch.


http://reviews.llvm.org/D12897

Files:
  include/lldb/Symbol/SymbolFile.h
  source/Expression/ClangExpressionDeclMap.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
  source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  source/Symbol/ClangASTContext.cpp
  test/lang/cpp/nsimport/TestCppNsImport.py

Index: test/lang/cpp/nsimport/TestCppNsImport.py
===================================================================
--- test/lang/cpp/nsimport/TestCppNsImport.py
+++ test/lang/cpp/nsimport/TestCppNsImport.py
@@ -80,18 +80,21 @@
         test_result = frame.EvaluateExpression("fun_var")
         self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 9, "fun_var = 9")
 
+        test_result = frame.EvaluateExpression("Fun::fun_var")
+        self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 0, "Fun::fun_var = 0")
+
         test_result = frame.EvaluateExpression("not_imported")
         self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 35, "not_imported = 35")
 
-        # Disabled the "imported" test since it isn't valid. It should actually test for ambiguity
-        #test_result = frame.EvaluateExpression("imported")
-        #self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 99, "imported = 99")
-
-        test_result = frame.EvaluateExpression("::imported")
-        self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 89, "::imported = 89")
+        # Currently there is no way to distinguish between "::imported" and "imported" in ClangExpressionDeclMap so this fails
+        #test_result = frame.EvaluateExpression("::imported")
+        #self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 89, "::imported = 89")
 
         test_result = frame.EvaluateExpression("Imported::imported")
         self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 99, "Imported::imported = 99")
+        
+        test_result = frame.EvaluateExpression("imported")
+        self.assertTrue(test_result.IsValid() and test_result.GetError().Fail(), "imported is ambiguous")
 
         test_result = frame.EvaluateExpression("single")
         self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 3, "single = 3")
Index: source/Symbol/ClangASTContext.cpp
===================================================================
--- source/Symbol/ClangASTContext.cpp
+++ 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,20 +1750,37 @@
     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(),
             clang::SourceLocation(),
             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,23 +8865,20 @@
         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())
         {
             search_queue.insert(std::make_pair(decl_context, decl_context));
 
             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);
+                    }
                 }
             }
         }
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -162,6 +162,10 @@
     lldb_private::CompilerDeclContext
     GetDeclContextContainingUID (lldb::user_id_t uid) override;
 
+    void
+    ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx) override;
+    
+
     uint32_t
     ResolveSymbolContext (const lldb_private::Address& so_addr,
                           uint32_t resolve_scope,
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1392,6 +1392,18 @@
     return false;
 }
 
+void
+SymbolFileDWARF::ParseDeclsForContext (CompilerDeclContext decl_ctx)
+{
+    TypeSystem *type_system = decl_ctx.GetTypeSystem();
+    DWARFASTParser *ast_parser = type_system->GetDWARFParser();
+    std::vector<DWARFDIE> decl_ctx_die_list = ast_parser->GetDIEForDeclContext(decl_ctx);
+
+    for (DWARFDIE decl_ctx_die : decl_ctx_die_list)
+        for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl; decl = decl.GetSibling())
+            ast_parser->GetDeclForUIDFromDWARF(decl);
+}
+
 CompilerDecl
 SymbolFileDWARF::GetDeclForUID (lldb::user_id_t type_uid)
 {
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
@@ -12,6 +12,7 @@
 
 #include "DWARFDefines.h"
 #include "DWARFASTParser.h"
+#include "DWARFDIE.h"
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -57,6 +58,12 @@
         return lldb_private::CompilerDecl();
     }
 
+    virtual std::vector<DWARFDIE>
+    GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context) override
+    {
+        return std::vector<DWARFDIE>();
+    }
+
   private:
     size_t ParseChildParameters(const lldb_private::SymbolContext &sc, const DWARFDIE &parent_die, bool &is_variadic,
                                 std::vector<lldb_private::CompilerType> &function_param_types);
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -51,6 +51,9 @@
     virtual lldb_private::CompilerDecl
     GetDeclForUIDFromDWARF (const DWARFDIE &die) override;
 
+    virtual std::vector<DWARFDIE>
+    GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context) override;
+
     virtual lldb_private::CompilerDeclContext
     GetDeclContextForUIDFromDWARF (const DWARFDIE &die) override;
 
@@ -173,7 +176,8 @@
 
     typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
     typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> DIEToDeclContextMap;
-    typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet> DeclContextToDIEMap;
+    //typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet> DeclContextToDIEMap;
+    typedef std::multimap<const clang::DeclContext *, const DWARFDIE> DeclContextToDIEMap;
     typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *> DIEToDeclMap;
     typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
 
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -35,6 +35,9 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 
+#include <map>
+#include <vector>
+
 //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
 
 #ifdef ENABLE_DEBUG_PRINTF
@@ -2039,6 +2042,15 @@
     return false;
 }
 
+std::vector<DWARFDIE>
+DWARFASTParserClang::GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context) 
+{
+    std::vector<DWARFDIE> result;
+    for (auto it = m_decl_ctx_to_die.find((clang::DeclContext *)decl_context.GetOpaqueDeclContext()); it != m_decl_ctx_to_die.end(); it++)
+        result.push_back(it->second);
+    return result;
+}
+
 CompilerDecl
 DWARFASTParserClang::GetDeclForUIDFromDWARF (const DWARFDIE &die)
 {
@@ -3213,6 +3225,9 @@
     if (!die)
         return nullptr;
 
+    if (die.GetReferencedDIE(DW_AT_specification))
+        return GetClangDeclForDIE(die.GetReferencedDIE(DW_AT_specification));
+
     clang::Decl *decl = m_die_to_decl[die.GetDIE()];
     if (decl != nullptr)
         return decl;
@@ -3261,8 +3276,8 @@
                 if (imported_decl)
                 {
                     clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
-                    if (clang::NamespaceDecl *clang_imported_decl = llvm::dyn_cast<clang::NamespaceDecl>((clang::DeclContext *)imported_decl.GetOpaqueDeclContext()))
-                        decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, clang_imported_decl);
+                    if (clang::NamespaceDecl *ns_decl = ClangASTContext::DeclContextGetAsNamespaceDecl(imported_decl))
+                        decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl);
                 }
             }
             break;
@@ -3431,7 +3446,8 @@
 {
     m_die_to_decl_ctx[die.GetDIE()] = decl_ctx;
     // There can be many DIEs for a single decl context
-    m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE());
+    //m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE());
+    m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die));
 }
 
 bool
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -45,6 +45,9 @@
 
     virtual lldb_private::CompilerDeclContext
     GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die) = 0;
+
+    virtual std::vector<DWARFDIE>
+    GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context) = 0;
 };
 
 #endif  // SymbolFileDWARF_DWARFASTParser_h_
Index: source/Expression/ClangExpressionDeclMap.cpp
===================================================================
--- source/Expression/ClangExpressionDeclMap.cpp
+++ source/Expression/ClangExpressionDeclMap.cpp
@@ -1351,7 +1351,6 @@
     {
         ValueObjectSP valobj;
         VariableSP var;
-        Error err;
 
         if (frame && !namespace_decl)
         {
@@ -1366,17 +1365,21 @@
 
                 // Search for declarations matching the name
                 std::vector<CompilerDecl> found_decls = compiler_decl_context.FindDeclByName(name);
+                
+                bool variable_found = false;
                 for (CompilerDecl decl : found_decls)
                 {
                     var = decl.GetAsVariable();
                     if (var)
                     {
+                        variable_found = true;
                         valobj = ValueObjectVariable::Create(frame, var);
                         AddOneVariable(context, var, valobj, current_id);
                         context.m_found.variable = true;
-                        return;
                     }
                 }
+                if (variable_found)
+                    return;
             }
         }
         if (target)
Index: include/lldb/Symbol/SymbolFile.h
===================================================================
--- include/lldb/Symbol/SymbolFile.h
+++ include/lldb/Symbol/SymbolFile.h
@@ -131,6 +131,7 @@
     virtual size_t          ParseVariablesForContext (const SymbolContext& sc) = 0;
     virtual Type*           ResolveTypeUID (lldb::user_id_t type_uid) = 0;
     virtual bool            CompleteType (CompilerType &clang_type) = 0;
+    virtual void            ParseDeclsForContext (CompilerDeclContext decl_ctx) {}
     virtual CompilerDecl    GetDeclForUID (lldb::user_id_t uid) { return CompilerDecl(); }
     virtual CompilerDeclContext GetDeclContextForUID (lldb::user_id_t uid) { return CompilerDeclContext(); }
     virtual CompilerDeclContext GetDeclContextContainingUID (lldb::user_id_t uid) { return CompilerDeclContext(); }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to