[Lldb-commits] [lldb] r247746 - Search variables based on clang::DeclContext and clang::Decl tree

Paul Herman via lldb-commits lldb-commits at lists.llvm.org
Tue Sep 15 16:44:17 PDT 2015


Author: paulherman
Date: Tue Sep 15 18:44:17 2015
New Revision: 247746

URL: http://llvm.org/viewvc/llvm-project?rev=247746&view=rev
Log:
Search variables based on clang::DeclContext and clang::Decl tree

Summary: SymbolFileDWARF now creates VarDecl and BlockDecl and adds them to the Decl tree. Then, in ClangExpressionDeclMap it uses the Decl tree to search for a variable. This fixes lots of variable scoping problems.

Reviewers: sivachandra, chaoren, spyffe, clayborg

Subscribers: tberghammer, jingham, lldb-commits

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

Added:
    lldb/trunk/include/lldb/Symbol/CompilerDecl.h
    lldb/trunk/source/Symbol/CompilerDecl.cpp
Modified:
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/include/lldb/Symbol/CompilerDeclContext.h
    lldb/trunk/include/lldb/Symbol/GoASTContext.h
    lldb/trunk/include/lldb/Symbol/SymbolFile.h
    lldb/trunk/include/lldb/Symbol/TypeSystem.h
    lldb/trunk/include/lldb/Symbol/Variable.h
    lldb/trunk/include/lldb/lldb-forward.h
    lldb/trunk/source/Expression/ClangASTSource.cpp
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
    lldb/trunk/source/Symbol/CMakeLists.txt
    lldb/trunk/source/Symbol/ClangASTContext.cpp
    lldb/trunk/source/Symbol/CompilerDeclContext.cpp
    lldb/trunk/source/Symbol/Variable.cpp
    lldb/trunk/test/lang/cpp/nsimport/TestCppNsImport.py
    lldb/trunk/test/lang/cpp/nsimport/main.cpp

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Tue Sep 15 18:44:17 2015
@@ -507,8 +507,23 @@ public:
                      llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets);
 
     //----------------------------------------------------------------------
+    // CompilerDecl override functions
+    //----------------------------------------------------------------------
+    lldb::VariableSP
+    DeclGetVariable (void *opaque_decl) override;
+
+    void
+    DeclLinkToObject (void *opaque_decl, std::shared_ptr<void> object) override;
+    
+    ConstString
+    DeclGetName (void *opaque_decl) override;
+
+    //----------------------------------------------------------------------
     // CompilerDeclContext override functions
     //----------------------------------------------------------------------
+    
+    std::vector<void *>
+    DeclContextFindDeclByName (void *opaque_decl_ctx, ConstString name);
 
     bool
     DeclContextIsStructUnionOrClass (void *opaque_decl_ctx) override;
@@ -1070,6 +1085,17 @@ public:
                             int tag_decl_kind,
                             const ClangASTContext::TemplateParameterInfos &template_param_infos);
 
+    clang::BlockDecl *
+    CreateBlockDeclaration (clang::DeclContext *ctx);
+
+    clang::UsingDirectiveDecl *
+    CreateUsingDirectiveDeclaration (clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl);
+
+    clang::UsingDecl *
+    CreateUsingDeclaration (clang::DeclContext *current_decl_ctx, clang::NamedDecl *target);
+
+    clang::VarDecl *
+    CreateVariableDeclaration (clang::DeclContext *decl_context, const char *name, clang::QualType type);
 protected:
     static clang::QualType
     GetQualType (void *type)
@@ -1110,6 +1136,7 @@ protected:
     uint32_t                                        m_pointer_byte_size;
     bool                                            m_ast_owned;
     bool                                            m_can_evaluate_expressions;
+    std::map<void *, std::shared_ptr<void>>         m_decl_objects;
 
 private:
     //------------------------------------------------------------------

Added: lldb/trunk/include/lldb/Symbol/CompilerDecl.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/CompilerDecl.h?rev=247746&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Symbol/CompilerDecl.h (added)
+++ lldb/trunk/include/lldb/Symbol/CompilerDecl.h Tue Sep 15 18:44:17 2015
@@ -0,0 +1,116 @@
+//===-- CompilerDecl.h ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CompilerDecl_h_
+#define liblldb_CompilerDecl_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ConstString.h"
+
+namespace lldb_private {
+
+class CompilerDecl
+{
+public:
+    //----------------------------------------------------------------------
+    // Constructors and Destructors
+    //----------------------------------------------------------------------
+    CompilerDecl () :
+        m_type_system  (nullptr),
+        m_opaque_decl (nullptr)
+    {
+    }
+
+    CompilerDecl (TypeSystem *type_system, void *decl) :
+        m_type_system (type_system),
+        m_opaque_decl (decl)
+    {
+    }
+
+    ~CompilerDecl ()
+    {
+    }
+
+    //----------------------------------------------------------------------
+    // Tests
+    //----------------------------------------------------------------------
+
+    explicit operator bool () const
+    {
+        return IsValid ();
+    }
+    
+    bool
+    operator < (const CompilerDecl &rhs) const
+    {
+        if (m_type_system == rhs.m_type_system)
+            return m_opaque_decl < rhs.m_opaque_decl;
+        return m_type_system < rhs.m_type_system;
+    }
+
+    bool
+    IsValid () const
+    {
+        return m_type_system != nullptr && m_opaque_decl != nullptr;
+    }
+
+    bool
+    IsClang () const;
+
+    //----------------------------------------------------------------------
+    // Object linked to the decl
+    //----------------------------------------------------------------------
+    lldb::VariableSP
+    GetAsVariable ();
+
+    //----------------------------------------------------------------------
+    // Accessors
+    //----------------------------------------------------------------------
+    
+    TypeSystem *
+    GetTypeSystem() const
+    {
+        return m_type_system;
+    }
+    
+    void *
+    GetOpaqueDecl() const
+    {
+        return m_opaque_decl;
+    }
+
+    void
+    SetDecl (TypeSystem* type_system, void* decl)
+    {
+        m_type_system = type_system;
+        m_opaque_decl = decl;
+    }
+
+    void
+    Clear()
+    {
+        m_type_system = nullptr;
+        m_opaque_decl = nullptr;
+    }
+
+    ConstString
+    GetName () const;
+
+private:
+    TypeSystem *m_type_system;
+    void *m_opaque_decl;
+};
+    
+bool operator == (const CompilerDecl &lhs, const CompilerDecl &rhs);
+bool operator != (const CompilerDecl &lhs, const CompilerDecl &rhs);
+
+    
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_CompilerDecl_h_

Modified: lldb/trunk/include/lldb/Symbol/CompilerDeclContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/CompilerDeclContext.h?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/CompilerDeclContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/CompilerDeclContext.h Tue Sep 15 18:44:17 2015
@@ -50,7 +50,7 @@ public:
     operator < (const CompilerDeclContext &rhs) const
     {
         if (m_type_system == rhs.m_type_system)
-            return m_type_system < rhs.m_type_system;
+            return m_opaque_decl_ctx < rhs.m_opaque_decl_ctx;
         return m_type_system < rhs.m_type_system;
     }
 
@@ -63,6 +63,9 @@ public:
     bool
     IsClang () const;
 
+    std::vector<CompilerDecl>
+    FindDeclByName (ConstString name);
+
     //----------------------------------------------------------------------
     /// Checks if this decl context represents a method of a class.
     ///

Modified: lldb/trunk/include/lldb/Symbol/GoASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/GoASTContext.h?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/GoASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/GoASTContext.h Tue Sep 15 18:44:17 2015
@@ -44,8 +44,34 @@ class GoASTContext : public TypeSystem
     }
 
     //----------------------------------------------------------------------
+    // CompilerDecl functions
+    //----------------------------------------------------------------------
+    virtual ConstString
+    DeclGetName (void *opaque_decl) override
+    {
+        return ConstString();
+    }
+
+    virtual lldb::VariableSP
+    DeclGetVariable (void *opaque_decl) override
+    {
+        return lldb::VariableSP();
+    }
+
+    virtual void
+    DeclLinkToObject (void *opaque_decl, std::shared_ptr<void> object) override
+    {
+    }
+
+    //----------------------------------------------------------------------
     // CompilerDeclContext functions
     //----------------------------------------------------------------------
+    
+    virtual std::vector<void *>
+    DeclContextFindDeclByName (void *opaque_decl_ctx, ConstString name) override
+    {
+        return std::vector<void *>();
+    }
 
     virtual bool
     DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override

Modified: lldb/trunk/include/lldb/Symbol/SymbolFile.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolFile.h?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/SymbolFile.h (original)
+++ lldb/trunk/include/lldb/Symbol/SymbolFile.h Tue Sep 15 18:44:17 2015
@@ -13,6 +13,7 @@
 #include "lldb/lldb-private.h"
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/Symbol/CompilerType.h"
+#include "lldb/Symbol/CompilerDecl.h"
 #include "lldb/Symbol/CompilerDeclContext.h"
 
 #include "lldb/Symbol/Type.h"
@@ -130,6 +131,7 @@ public:
     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 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(); }
     virtual uint32_t        ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) = 0;

Modified: lldb/trunk/include/lldb/Symbol/TypeSystem.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/TypeSystem.h?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/TypeSystem.h (original)
+++ lldb/trunk/include/lldb/Symbol/TypeSystem.h Tue Sep 15 18:44:17 2015
@@ -98,8 +98,23 @@ public:
     }
 
     //----------------------------------------------------------------------
+    // CompilerDecl functions
+    //----------------------------------------------------------------------
+    virtual ConstString
+    DeclGetName (void *opaque_decl) = 0;
+
+    virtual lldb::VariableSP
+    DeclGetVariable (void *opaque_decl) = 0;
+
+    virtual void
+    DeclLinkToObject (void *opaque_decl, std::shared_ptr<void> object) = 0;
+
+    //----------------------------------------------------------------------
     // CompilerDeclContext functions
     //----------------------------------------------------------------------
+    
+    virtual std::vector<void *>
+    DeclContextFindDeclByName (void *opaque_decl_ctx, ConstString name) = 0;
 
     virtual bool
     DeclContextIsStructUnionOrClass (void *opaque_decl_ctx) = 0;

Modified: lldb/trunk/include/lldb/Symbol/Variable.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Variable.h?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/Variable.h (original)
+++ lldb/trunk/include/lldb/Symbol/Variable.h Tue Sep 15 18:44:17 2015
@@ -1,4 +1,5 @@
-//===-- Variable.h ----------------------------------------------*- C++ -*-===//
+//===-- Variable.h ----------------------------------------------*- C++
+//-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -10,6 +11,7 @@
 #ifndef liblldb_Variable_h_
 #define liblldb_Variable_h_
 
+#include <memory>
 #include <vector>
 
 #include "lldb/lldb-private.h"
@@ -21,7 +23,8 @@
 
 namespace lldb_private {
 
-class Variable : public UserID
+class Variable : public UserID,
+    public std::enable_shared_from_this<Variable>
 {
 public:
     //------------------------------------------------------------------
@@ -59,6 +62,9 @@ public:
     ConstString
     GetName() const;
 
+    ConstString
+    GetUnqualifiedName() const;
+
     SymbolContextScope *
     GetSymbolContextScope() const
     {
@@ -167,6 +173,11 @@ public:
                   StringList &matches,
                   bool &word_complete);
 
+    CompilerDeclContext
+    GetDeclContext ();
+
+    CompilerDecl
+    GetDecl ();
 protected:
     ConstString m_name;                 // The basename of the variable (no namespaces)
     Mangled m_mangled;                  // The mangled name of the variable

Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Tue Sep 15 18:44:17 2015
@@ -61,6 +61,7 @@ class   CommandObject;
 class   CommandReturnObject;
 class   Communication;
 class   CompactUnwindInfo;
+class   CompilerDecl;
 class   CompilerDeclContext;
 class   CompilerType;
 class   CompileUnit;

Modified: lldb/trunk/source/Expression/ClangASTSource.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangASTSource.cpp?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangASTSource.cpp (original)
+++ lldb/trunk/source/Expression/ClangASTSource.cpp Tue Sep 15 18:44:17 2015
@@ -514,7 +514,7 @@ ClangASTSource::FindExternalLexicalDecls
                 else
                     log->Printf("  FELD[%d] Adding lexical %sDecl %s", current_id, decl->getDeclKindName(), ast_dumper.GetCString());
             }
-
+            
             Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, original_ctx, decl);
 
             if (!copied_decl)

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Tue Sep 15 18:44:17 2015
@@ -28,6 +28,7 @@
 #include "lldb/Expression/Materializer.h"
 #include "lldb/Host/Endian.h"
 #include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/CompilerDecl.h"
 #include "lldb/Symbol/CompilerDeclContext.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/Function.h"
@@ -1035,6 +1036,9 @@ ClangExpressionDeclMap::FindExternalVisi
     // doesn't start with our phony prefix of '$'
     Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
     StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
+    SymbolContext sym_ctx;
+    if (frame != nullptr)
+        sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
     if (name_unique_cstr[0] == '$' && !namespace_decl)
     {
         static ConstString g_lldb_class_name ("$__lldb_class");
@@ -1046,7 +1050,6 @@ ClangExpressionDeclMap::FindExternalVisi
             if (frame == NULL)
                 return;
 
-            SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
 
             // Find the block that defines the function represented by "sym_ctx"
             Block *function_block = sym_ctx.GetFunctionBlock();
@@ -1352,24 +1355,30 @@ ClangExpressionDeclMap::FindExternalVisi
 
         if (frame && !namespace_decl)
         {
-            valobj = frame->GetValueForVariableExpressionPath(name_unique_cstr,
-                                                              eNoDynamicValues,
-                                                              StackFrame::eExpressionPathOptionCheckPtrVsMember |
-                                                              StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
-                                                              StackFrame::eExpressionPathOptionsNoSyntheticChildren |
-                                                              StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
-                                                              var,
-                                                              err);
+            CompilerDeclContext compiler_decl_context = sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext() : CompilerDeclContext();
 
-            // If we found a variable in scope, no need to pull up function names
-            if (err.Success() && var)
+            if (compiler_decl_context)
             {
-                AddOneVariable(context, var, valobj, current_id);
-                context.m_found.variable = true;
-                return;
+                // Make sure that the variables are parsed so that we have the declarations
+                VariableListSP vars = frame->GetInScopeVariableList(true);
+                for (size_t i = 0; i < vars->GetSize(); i++)
+                    vars->GetVariableAtIndex(i)->GetDecl();
+
+                // Search for declarations matching the name
+                std::vector<CompilerDecl> found_decls = compiler_decl_context.FindDeclByName(name);
+                for (CompilerDecl decl : found_decls)
+                {
+                    var = decl.GetAsVariable();
+                    if (var)
+                    {
+                        valobj = ValueObjectVariable::Create(frame, var);
+                        AddOneVariable(context, var, valobj, current_id);
+                        context.m_found.variable = true;
+                        return;
+                    }
+                }
             }
         }
-
         if (target)
         {
             var = FindGlobalVariable (*target,

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h Tue Sep 15 18:44:17 2015
@@ -12,6 +12,7 @@
 
 #include "DWARFDefines.h"
 #include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/CompilerDecl.h"
 #include "lldb/Symbol/CompilerDeclContext.h"
 
 class DWARFDIE;
@@ -27,7 +28,6 @@ public:
                         lldb_private::Log *log,
                         bool *type_is_new_ptr) = 0;
 
-
     virtual lldb_private::Function *
     ParseFunctionFromDWARF (const lldb_private::SymbolContext& sc,
                             const DWARFDIE &die) = 0;
@@ -37,12 +37,14 @@ public:
                            lldb_private::Type *type,
                            lldb_private::CompilerType &clang_type) = 0;
 
+    virtual lldb_private::CompilerDecl
+    GetDeclForUIDFromDWARF (const DWARFDIE &die) = 0;
+
     virtual lldb_private::CompilerDeclContext
     GetDeclContextForUIDFromDWARF (const DWARFDIE &die) = 0;
 
     virtual lldb_private::CompilerDeclContext
     GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die) = 0;
-
 };
 
 #endif  // SymbolFileDWARF_DWARFASTParser_h_

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp Tue Sep 15 18:44:17 2015
@@ -111,7 +111,6 @@ struct BitfieldInfo
     }
 };
 
-
 TypeSP
 DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
                                          const DWARFDIE &die,
@@ -2040,6 +2039,15 @@ DWARFASTParserClang::CompleteTypeFromDWA
     return false;
 }
 
+CompilerDecl
+DWARFASTParserClang::GetDeclForUIDFromDWARF (const DWARFDIE &die)
+{
+    clang::Decl *clang_decl = GetClangDeclForDIE(die);
+    if (clang_decl != nullptr)
+        return CompilerDecl(&m_ast, clang_decl);
+    return CompilerDecl();
+}
+
 CompilerDeclContext
 DWARFASTParserClang::GetDeclContextForUIDFromDWARF (const DWARFDIE &die)
 {
@@ -2202,7 +2210,6 @@ protected:
 };
 #endif
 
-
 Function *
 DWARFASTParserClang::ParseFunctionFromDWARF (const SymbolContext& sc,
                                              const DWARFDIE &die)
@@ -3175,6 +3182,101 @@ DWARFASTParserClang::ParseChildArrayInfo
     }
 }
 
+Type *
+DWARFASTParserClang::GetTypeForDIE (const DWARFDIE &die)
+{
+    if (die)
+    {
+        SymbolFileDWARF *dwarf = die.GetDWARF();
+        DWARFAttributes attributes;
+        const size_t num_attributes = die.GetAttributes(attributes);
+        if (num_attributes > 0)
+        {
+            DWARFFormValue type_die_form;
+            for (size_t i = 0; i < num_attributes; ++i)
+            {
+                dw_attr_t attr = attributes.AttributeAtIndex(i);
+                DWARFFormValue form_value;
+                
+                if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value))
+                    return dwarf->ResolveTypeUID(DIERef(form_value).GetUID());
+            }
+        }
+    }
+
+    return nullptr;
+}
+
+clang::Decl *
+DWARFASTParserClang::GetClangDeclForDIE (const DWARFDIE &die)
+{
+    if (!die)
+        return nullptr;
+
+    clang::Decl *decl = m_die_to_decl[die.GetDIE()];
+    if (decl != nullptr)
+        return decl;
+
+    switch (die.Tag())
+    {
+        case DW_TAG_variable:
+        case DW_TAG_constant:
+        case DW_TAG_formal_parameter:
+        {
+            SymbolFileDWARF *dwarf = die.GetDWARF();
+            Type *type = GetTypeForDIE(die);
+            const char *name = die.GetName();
+            clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
+            decl = m_ast.CreateVariableDeclaration(
+                decl_context,
+                name,
+                ClangASTContext::GetQualType(type->GetForwardCompilerType()));
+            break;
+        }
+        case DW_TAG_imported_declaration:
+        {
+            SymbolFileDWARF *dwarf = die.GetDWARF();
+            lldb::user_id_t imported_uid = die.GetAttributeValueAsReference(DW_AT_import, DW_INVALID_OFFSET);
+
+            if (dwarf->UserIDMatches(imported_uid))
+            {
+                CompilerDecl imported_decl = dwarf->GetDeclForUID(imported_uid);
+                if (imported_decl)
+                {
+                    clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
+                    if (clang::NamedDecl *clang_imported_decl = llvm::dyn_cast<clang::NamedDecl>((clang::Decl *)imported_decl.GetOpaqueDecl()))
+                        decl = m_ast.CreateUsingDeclaration(decl_context, clang_imported_decl); 
+                }
+            }
+            break;
+        }
+        case DW_TAG_imported_module:
+        {
+            SymbolFileDWARF *dwarf = die.GetDWARF();
+            lldb::user_id_t imported_uid = die.GetAttributeValueAsReference(DW_AT_import, DW_INVALID_OFFSET);
+
+            if (dwarf->UserIDMatches(imported_uid))
+            {
+                CompilerDeclContext imported_decl = dwarf->GetDeclContextForUID(imported_uid);
+                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);
+                }
+            }
+            break;
+        }
+        default:
+            break;
+    }
+
+    m_die_to_decl[die.GetDIE()] = decl;
+    m_decl_to_die[decl].insert(die.GetDIE());
+
+    return decl;
+}
+
 clang::DeclContext *
 DWARFASTParserClang::GetClangDeclContextForDIE (const DWARFDIE &die)
 {
@@ -3197,6 +3299,11 @@ DWARFASTParserClang::GetClangDeclContext
                 try_parsing_type = false;
                 break;
 
+            case DW_TAG_lexical_block:
+                decl_ctx = (clang::DeclContext *)ResolveBlockDIE(die);
+                try_parsing_type = false;
+                break;
+
             default:
                 break;
         }
@@ -3217,6 +3324,28 @@ DWARFASTParserClang::GetClangDeclContext
     return nullptr;
 }
 
+clang::BlockDecl *
+DWARFASTParserClang::ResolveBlockDIE (const DWARFDIE &die)
+{
+    if (die && die.Tag() == DW_TAG_lexical_block)
+    {
+        clang::BlockDecl *decl = llvm::cast_or_null<clang::BlockDecl>(m_die_to_decl_ctx[die.GetDIE()]);
+        
+        if (!decl)
+        {
+            DWARFDIE decl_context_die;
+            clang::DeclContext *decl_context = GetClangDeclContextContainingDIE(die, &decl_context_die);
+            decl = m_ast.CreateBlockDeclaration(decl_context);
+
+            if (decl)
+                LinkDeclContextToDIE((clang::DeclContext *)decl, die);
+        }
+
+        return decl;
+    }
+    return nullptr;
+}
+
 clang::NamespaceDecl *
 DWARFASTParserClang::ResolveNamespaceDIE (const DWARFDIE &die)
 {
@@ -3285,10 +3414,6 @@ DWARFASTParserClang::GetClangDeclContext
     return m_ast.GetTranslationUnitDecl();
 }
 
-
-
-
-
 clang::DeclContext *
 DWARFASTParserClang::GetCachedClangDeclContextForDIE (const DWARFDIE &die)
 {

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h Tue Sep 15 18:44:17 2015
@@ -48,6 +48,9 @@ public:
                            lldb_private::Type *type,
                            lldb_private::CompilerType &clang_type) override;
 
+    virtual lldb_private::CompilerDecl
+    GetDeclForUIDFromDWARF (const DWARFDIE &die) override;
+
     virtual lldb_private::CompilerDeclContext
     GetDeclContextForUIDFromDWARF (const DWARFDIE &die) override;
 
@@ -83,6 +86,9 @@ protected:
         llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets;
     };
 
+    clang::BlockDecl *
+    ResolveBlockDIE (const DWARFDIE &die);
+
     clang::NamespaceDecl *
     ResolveNamespaceDIE (const DWARFDIE &die);
 
@@ -136,6 +142,12 @@ protected:
                            uint32_t enumerator_byte_size,
                            const DWARFDIE &parent_die);
 
+    lldb_private::Type *
+    GetTypeForDIE (const DWARFDIE &die);
+
+    clang::Decl *
+    GetClangDeclForDIE (const DWARFDIE &die);
+
     clang::DeclContext *
     GetClangDeclContextForDIE (const DWARFDIE &die);
 
@@ -156,11 +168,18 @@ protected:
     LinkDeclContextToDIE (clang::DeclContext *decl_ctx,
                           const DWARFDIE &die);
 
+    void
+    LinkDeclToDIE (clang::Decl *decl, const DWARFDIE &die);
+
     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 DWARFDebugInfoEntry *, clang::Decl *> DIEToDeclMap;
+    typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
 
     lldb_private::ClangASTContext &m_ast;
+    DIEToDeclMap m_die_to_decl;
+    DeclToDIEMap m_decl_to_die;
     DIEToDeclContextMap m_die_to_decl_ctx;
     DeclContextToDIEMap m_decl_ctx_to_die;
     RecordDeclToLayoutMap m_record_decl_to_layout_map;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h Tue Sep 15 18:44:17 2015
@@ -51,6 +51,12 @@ class DWARFASTParserGo : public DWARFAST
         return lldb_private::CompilerDeclContext();
     }
 
+    virtual lldb_private::CompilerDecl
+    GetDeclForUIDFromDWARF (const DWARFDIE &die) override
+    {
+        return lldb_private::CompilerDecl();
+    }
+
   private:
     size_t ParseChildParameters(const lldb_private::SymbolContext &sc, const DWARFDIE &parent_die, bool &is_variadic,
                                 std::vector<lldb_private::CompilerType> &function_param_types);

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Tue Sep 15 18:44:17 2015
@@ -48,6 +48,8 @@
 #include "lldb/Interpreter/OptionValueProperties.h"
 
 #include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/CompilerDecl.h"
+#include "lldb/Symbol/CompilerDeclContext.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/LineTable.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -1391,6 +1393,26 @@ SymbolFileDWARF::ClassOrStructIsVirtual
     return false;
 }
 
+CompilerDecl
+SymbolFileDWARF::GetDeclForUID (lldb::user_id_t type_uid)
+{
+    if (UserIDMatches(type_uid))
+    {
+        DWARFDebugInfo* debug_info = DebugInfo();
+        if (debug_info)
+        {
+            DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
+            if (die)
+            {
+                DWARFASTParser *dwarf_ast = die.GetDWARFParser();
+                if (dwarf_ast)
+                    return dwarf_ast->GetDeclForUIDFromDWARF(die);
+            }
+        }
+    }
+    return CompilerDecl();
+}
+
 CompilerDeclContext
 SymbolFileDWARF::GetDeclContextForUID (lldb::user_id_t type_uid)
 {
@@ -3057,6 +3079,8 @@ SymbolFileDWARF::GetDeclContextDIEContai
                     case DW_TAG_structure_type:
                     case DW_TAG_union_type:
                     case DW_TAG_class_type:
+                    case DW_TAG_lexical_block:
+                    case DW_TAG_subprogram:
                         return die;
                         
                     default:
@@ -3741,6 +3765,7 @@ SymbolFileDWARF::ParseVariableDIE
     {
         DWARFAttributes attributes;
         const size_t num_attributes = die.GetAttributes(attributes);
+        DWARFDIE spec_die;
         if (num_attributes > 0)
         {
             const char *name = NULL;
@@ -3862,7 +3887,13 @@ SymbolFileDWARF::ParseVariableDIE
                             }
                         }
                         break;
-
+                    case DW_AT_specification:
+                    {
+                        DWARFDebugInfo* debug_info = DebugInfo();
+                        if (debug_info)
+                            spec_die = debug_info->GetDIE(DIERef(form_value));
+                        break;
+                    }
                     case DW_AT_artificial:      is_artificial = form_value.Boolean(); break;
                     case DW_AT_accessibility:   break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
                     case DW_AT_declaration:
@@ -3874,7 +3905,6 @@ SymbolFileDWARF::ParseVariableDIE
                     default:
                     case DW_AT_abstract_origin:
                     case DW_AT_sibling:
-                    case DW_AT_specification:
                         break;
                     }
                 }
@@ -4078,6 +4108,8 @@ SymbolFileDWARF::ParseVariableDIE
         // (missing location due to optimization, etc)) so we don't re-parse
         // this DIE over and over later...
         GetDIEToVariable()[die.GetDIE()] = var_sp;
+        if (spec_die)
+            GetDIEToVariable()[spec_die.GetDIE()] = var_sp;
     }
     return var_sp;
 }

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Tue Sep 15 18:44:17 2015
@@ -152,6 +152,9 @@ public:
     ResolveType (const DWARFDIE &die,
                  bool assert_not_being_parsed = true);
 
+    lldb_private::CompilerDecl
+    GetDeclForUID (lldb::user_id_t uid) override;
+
     lldb_private::CompilerDeclContext
     GetDeclContextForUID (lldb::user_id_t uid) override;
 

Modified: lldb/trunk/source/Symbol/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/CMakeLists.txt?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/CMakeLists.txt (original)
+++ lldb/trunk/source/Symbol/CMakeLists.txt Tue Sep 15 18:44:17 2015
@@ -4,6 +4,7 @@ add_lldb_library(lldbSymbol
   ClangASTImporter.cpp
   ClangExternalASTSourceCallbacks.cpp
   ClangExternalASTSourceCommon.cpp
+  CompilerDecl.cpp
   CompilerDeclContext.cpp
   CompilerType.cpp
   CompileUnit.cpp

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Tue Sep 15 18:44:17 2015
@@ -1756,6 +1756,82 @@ ClangASTContext::GetUniqueNamespaceDecla
 }
 
 
+clang::BlockDecl *
+ClangASTContext::CreateBlockDeclaration (clang::DeclContext *ctx)
+{
+    if (ctx != nullptr)
+    {
+        clang::BlockDecl *decl = clang::BlockDecl::Create(*getASTContext(), ctx, clang::SourceLocation());
+        ctx->addDecl(decl);
+        return decl;
+    }
+    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::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(*getASTContext(),
+            decl_ctx,
+            clang::SourceLocation(),
+            clang::SourceLocation(),
+            clang::NestedNameSpecifierLoc(),
+            clang::SourceLocation(),
+            ns_decl,
+            GetTranslationUnitDecl(getASTContext()));
+        decl_ctx->addDecl(using_decl);
+        return using_decl;
+    }
+    return nullptr;
+}
+
+clang::UsingDecl *
+ClangASTContext::CreateUsingDeclaration (clang::DeclContext *current_decl_ctx, clang::NamedDecl *target)
+{
+    if (current_decl_ctx != nullptr && target != nullptr)
+    {
+        clang::UsingDecl *using_decl = clang::UsingDecl::Create(*getASTContext(),
+            current_decl_ctx,
+            clang::SourceLocation(),
+            clang::NestedNameSpecifierLoc(),
+            clang::DeclarationNameInfo(),
+            false);
+        clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(*getASTContext(),
+            current_decl_ctx,
+            clang::SourceLocation(),
+            using_decl,
+            target);
+        using_decl->addShadowDecl(shadow_decl);
+        current_decl_ctx->addDecl(using_decl);
+        return using_decl;
+    }
+    return nullptr;
+}
+
+clang::VarDecl *
+ClangASTContext::CreateVariableDeclaration (clang::DeclContext *decl_context, const char *name, clang::QualType type)
+{
+    if (decl_context != nullptr)
+    {
+        clang::VarDecl *var_decl = clang::VarDecl::Create(*getASTContext(),
+            decl_context,
+            clang::SourceLocation(),
+            clang::SourceLocation(),
+            name && name[0] ? &getASTContext()->Idents.getOwn(name) : nullptr,
+            type,
+            nullptr,
+            clang::SC_None);
+        var_decl->setAccess(clang::AS_public);
+        decl_context->addDecl(var_decl);
+        decl_context->makeDeclVisibleInContext(var_decl);
+        return var_decl;
+    }
+    return nullptr;
+}
+
 #pragma mark Function Types
 
 FunctionDecl *
@@ -8818,9 +8894,94 @@ ClangASTContext::LayoutRecordType(void *
 }
 
 //----------------------------------------------------------------------
+// CompilerDecl override functions
+//----------------------------------------------------------------------
+lldb::VariableSP
+ClangASTContext::DeclGetVariable (void *opaque_decl)
+{
+    if (llvm::dyn_cast<clang::VarDecl>((clang::Decl *)opaque_decl))
+    {
+        auto decl_search_it = m_decl_objects.find(opaque_decl);
+        if (decl_search_it != m_decl_objects.end())
+            return std::static_pointer_cast<Variable>(decl_search_it->second);
+    }
+    return VariableSP();
+}
+
+void
+ClangASTContext::DeclLinkToObject (void *opaque_decl, std::shared_ptr<void> object)
+{
+    if (m_decl_objects.find(opaque_decl) == m_decl_objects.end())
+        m_decl_objects.insert(std::make_pair(opaque_decl, object));
+}
+
+ConstString
+ClangASTContext::DeclGetName (void *opaque_decl)
+{
+    if (opaque_decl)
+    {
+        clang::NamedDecl *nd = llvm::dyn_cast<NamedDecl>((clang::Decl*)opaque_decl);
+        if (nd != nullptr)
+            return ConstString(nd->getName());
+    }
+    return ConstString();
+}
+
+//----------------------------------------------------------------------
 // CompilerDeclContext functions
 //----------------------------------------------------------------------
 
+std::vector<void *>
+ClangASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name)
+{
+    std::vector<void *> found_decls;
+    if (opaque_decl_ctx)
+    {
+        DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx;
+        std::set<DeclContext *> searched;
+        std::multimap<DeclContext *, DeclContext *> search_queue;
+
+        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);
+                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))
+                    {
+                        clang::DeclContext *from = ud->getCommonAncestor();
+                        if (searched.find(ud->getNominatedNamespace()) == searched.end())
+                            search_queue.insert(std::make_pair(from, ud->getNominatedNamespace()));
+                    }
+                    else if (clang::UsingDecl *ud = llvm::dyn_cast<clang::UsingDecl>(child))
+                    {
+                        for (clang::UsingShadowDecl *usd : ud->shadows())
+                        {
+                            clang::Decl *target = usd->getTargetDecl();
+                            if (clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(target))
+                            {
+                                IdentifierInfo *ii = nd->getIdentifier();
+                                if (ii != nullptr && ii->getName().equals(name.AsCString(nullptr)))
+                                    found_decls.push_back(nd);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return found_decls;
+}
+
 bool
 ClangASTContext::DeclContextIsStructUnionOrClass (void *opaque_decl_ctx)
 {

Added: lldb/trunk/source/Symbol/CompilerDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/CompilerDecl.cpp?rev=247746&view=auto
==============================================================================
--- lldb/trunk/source/Symbol/CompilerDecl.cpp (added)
+++ lldb/trunk/source/Symbol/CompilerDecl.cpp Tue Sep 15 18:44:17 2015
@@ -0,0 +1,46 @@
+//===-- CompilerDecl.cpp ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Symbol/CompilerDecl.h"
+#include "lldb/Symbol/CompilerDeclContext.h"
+#include "lldb/Symbol/TypeSystem.h"
+
+using namespace lldb_private;
+
+bool
+CompilerDecl::IsClang () const
+{
+    return IsValid() && m_type_system->getKind() == TypeSystem::eKindClang;
+}
+
+ConstString
+CompilerDecl::GetName() const
+{
+    return m_type_system->DeclGetName(m_opaque_decl);
+}
+
+lldb::VariableSP
+CompilerDecl::GetAsVariable ()
+{
+    return m_type_system->DeclGetVariable(m_opaque_decl);
+}
+
+bool
+lldb_private::operator == (const lldb_private::CompilerDecl &lhs, const lldb_private::CompilerDecl &rhs)
+{
+    return lhs.GetTypeSystem() == rhs.GetTypeSystem() && lhs.GetOpaqueDecl() == rhs.GetOpaqueDecl();
+}
+
+
+bool
+lldb_private::operator != (const lldb_private::CompilerDecl &lhs, const lldb_private::CompilerDecl &rhs)
+{
+    return lhs.GetTypeSystem() != rhs.GetTypeSystem() || lhs.GetOpaqueDecl() != rhs.GetOpaqueDecl();
+}
+

Modified: lldb/trunk/source/Symbol/CompilerDeclContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/CompilerDeclContext.cpp?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/CompilerDeclContext.cpp (original)
+++ lldb/trunk/source/Symbol/CompilerDeclContext.cpp Tue Sep 15 18:44:17 2015
@@ -8,10 +8,25 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Symbol/CompilerDeclContext.h"
+#include "lldb/Symbol/CompilerDecl.h"
 #include "lldb/Symbol/TypeSystem.h"
+#include <vector>
 
 using namespace lldb_private;
 
+std::vector<CompilerDecl>
+CompilerDeclContext::FindDeclByName (ConstString name)
+{
+    std::vector<CompilerDecl> found_decls;
+    if (IsValid())
+    {
+        std::vector<void *> found_opaque_decls = m_type_system->DeclContextFindDeclByName(m_opaque_decl_ctx, name);
+        for (void *opaque_decl : found_opaque_decls)
+            found_decls.push_back(CompilerDecl(m_type_system, opaque_decl));
+    }
+    return found_decls;
+}
+
 bool
 CompilerDeclContext::IsClang () const
 {

Modified: lldb/trunk/source/Symbol/Variable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Variable.cpp?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Variable.cpp (original)
+++ lldb/trunk/source/Symbol/Variable.cpp Tue Sep 15 18:44:17 2015
@@ -15,9 +15,12 @@
 #include "lldb/Core/ValueObject.h"
 #include "lldb/Core/ValueObjectVariable.h"
 #include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/CompilerDecl.h"
+#include "lldb/Symbol/CompilerDeclContext.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/Type.h"
 #include "lldb/Symbol/VariableList.h"
 #include "lldb/Target/ABI.h"
@@ -89,6 +92,13 @@ Variable::GetName() const
     return m_name;
 }
 
+ConstString
+Variable::GetUnqualifiedName() const
+{
+    return m_name;
+}
+
+
 bool
 Variable::NameMatches (const ConstString &name) const
 {
@@ -230,6 +240,22 @@ Variable::MemorySize() const
     return sizeof(Variable);
 }
 
+CompilerDeclContext
+Variable::GetDeclContext ()
+{
+    Type *type = GetType();
+    return type->GetSymbolFile()->GetDeclContextContainingUID(GetID());
+}
+
+CompilerDecl
+Variable::GetDecl ()
+{
+    Type *type = GetType();
+    CompilerDecl decl = type->GetSymbolFile()->GetDeclForUID(GetID());
+    if (decl)
+        decl.GetTypeSystem()->DeclLinkToObject(decl.GetOpaqueDecl(), shared_from_this());
+    return decl;
+}
 
 void
 Variable::CalculateSymbolContext (SymbolContext *sc)

Modified: lldb/trunk/test/lang/cpp/nsimport/TestCppNsImport.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/nsimport/TestCppNsImport.py?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/test/lang/cpp/nsimport/TestCppNsImport.py (original)
+++ lldb/trunk/test/lang/cpp/nsimport/TestCppNsImport.py Tue Sep 15 18:44:17 2015
@@ -16,6 +16,8 @@ class TestCppNsImport(TestBase):
         self.buildDsym()
         self.check()
 
+    # This test is expected to fail because DW_TAG_imported_declaration and DW_TAG_imported_module are not parsed in SymbolFileDWARF
+    @expectedFailureAll
     @dwarf_test
     def test_with_dwarf_and_run_command(self):
         """Tests imported namespaces in C++."""
@@ -45,6 +47,8 @@ class TestCppNsImport(TestBase):
         # Break on main function
         break_0 = target.BreakpointCreateBySourceRegex("// break 0", src_file_spec)
         self.assertTrue(break_0.IsValid() and break_0.GetNumLocations() >= 1, VALID_BREAKPOINT)
+        break_1 = target.BreakpointCreateBySourceRegex("// break 1", src_file_spec)
+        self.assertTrue(break_1.IsValid() and break_1.GetNumLocations() >= 1, VALID_BREAKPOINT)
 
         # Launch the process
         args = None
@@ -72,6 +76,35 @@ class TestCppNsImport(TestBase):
         test_result = frame.EvaluateExpression("anon")
         self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 2, "anon = 2")
 
+        test_result = frame.EvaluateExpression("global")
+        self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 4, "global = 4")
+
+        test_result = frame.EvaluateExpression("fun_var")
+        self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 9, "fun_var = 9")
+
+        test_result = frame.EvaluateExpression("not_imported")
+        self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 35, "not_imported = 35")
+
+        test_result = frame.EvaluateExpression("imported")
+        self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 99, "imported = 99")
+
+        test_result = frame.EvaluateExpression("single")
+        self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 3, "single = 3")
+
+        # Continue to second breakpoint
+        process.Continue()
+
+        # Get the thread of the process
+        self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
+        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+
+        # Get current fream of the thread at the breakpoint
+        frame = thread.GetSelectedFrame()
+
+        # Test function inside namespace
+        test_result = frame.EvaluateExpression("fun_var")
+        self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 5, "fun_var = 5")
+        
 
 if __name__ == '__main__':
     import atexit

Modified: lldb/trunk/test/lang/cpp/nsimport/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/nsimport/main.cpp?rev=247746&r1=247745&r2=247746&view=diff
==============================================================================
--- lldb/trunk/test/lang/cpp/nsimport/main.cpp (original)
+++ lldb/trunk/test/lang/cpp/nsimport/main.cpp Tue Sep 15 18:44:17 2015
@@ -16,13 +16,57 @@ namespace Nested
     }
 }
 
-using namespace N;
-using namespace Nested;
+namespace Global
+{
+    int global;
+}
+
+namespace Fun
+{
+    int fun_var;
+    int fun()
+    {
+        fun_var = 5;
+        return 0; // break 1
+    }
+}
+
+namespace Single
+{
+    int single = 3;
+}
+
+namespace NotImportedBefore
+{
+    int not_imported = 45;
+}
+
+using namespace Global;
+
+int not_imported = 35;
+int fun_var = 9;
+
+namespace NotImportedAfter
+{
+    int not_imported = 55;
+}
+
+namespace Imported
+{
+    int imported = 99;
+}
+
+int imported = 89;
 
 int main()
 {
+    using namespace N;
+    using namespace Nested;
+    using namespace Imported;
+    using Single::single;
     n = 1;
     anon = 2;
     nested = 3;
-    return 0; // break 0
+    global = 4;
+    return Fun::fun(); // break 0
 }




More information about the lldb-commits mailing list