[Lldb-commits] [lldb] r133302 - in /lldb/trunk: include/lldb/Symbol/Block.h source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h source/Symbol/Block.cpp source/Target/StackFrame.cpp

Greg Clayton gclayton at apple.com
Fri Jun 17 15:10:16 PDT 2011


Author: gclayton
Date: Fri Jun 17 17:10:16 2011
New Revision: 133302

URL: http://llvm.org/viewvc/llvm-project?rev=133302&view=rev
Log:
Fixed variable parsing to not parse block variables over and over due to an
issue in the way block variables are marked as parsed. In the DWARF parser we
always parse all blocks for a function at once, so we can mark all blocks as
having all variables parsed and avoid recursive function calls to try and
reparse things that have already been handled.

Fixed an issue with how variables get scoped into blocks. The DWARF parser can
now handle abtract class definitions that contain concrete static variables.
When the concrete instance of the class functions get instantiated, they will
track down the concrete block for the abtract block and add the variable to
each block.


Modified:
    lldb/trunk/include/lldb/Symbol/Block.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
    lldb/trunk/source/Symbol/Block.cpp
    lldb/trunk/source/Target/StackFrame.cpp

Modified: lldb/trunk/include/lldb/Symbol/Block.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Block.h?rev=133302&r1=133301&r2=133302&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/Block.h (original)
+++ lldb/trunk/include/lldb/Symbol/Block.h Fri Jun 17 17:10:16 2011
@@ -281,10 +281,15 @@
     ///     for this block.
     //------------------------------------------------------------------
     lldb::VariableListSP
-    GetVariableList (bool get_child_variables, 
-                     bool can_create);
+    GetBlockVariableList (bool can_create);
 
 
+    uint32_t
+    AppendBlockVariables (bool can_create,
+                          bool get_child_block_variables,
+                          bool stop_if_child_block_is_inlined_function,
+                          VariableList *variable_list);
+                          
     //------------------------------------------------------------------
     /// Appends the variables from this block, and optionally from all
     /// parent blocks, to \a variable_list.
@@ -431,6 +436,9 @@
     bool
     GetStartAddress (Address &addr);
     
+    void
+    SetDidParseVariables (bool b, bool set_children);
+
 protected:
     typedef std::vector<lldb::BlockSP> collection;
     //------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp?rev=133302&r1=133301&r2=133302&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp Fri Jun 17 17:10:16 2011
@@ -263,6 +263,29 @@
     return NULL;    // Not found in any compile units
 }
 
+DWARFDebugInfoEntry*
+DWARFDebugInfo::GetDIEPtrWithCompileUnitHint (dw_offset_t die_offset, DWARFCompileUnit**cu_handle)
+{
+    assert (cu_handle);
+    DWARFDebugInfoEntry* die = NULL;
+    if (*cu_handle)
+        die = (*cu_handle)->GetDIEPtr(die_offset);
+
+    if (die == NULL)
+    {
+        DWARFCompileUnitSP cu_sp (GetCompileUnitContainingDIE(die_offset));
+        if (cu_sp.get())
+        {
+            *cu_handle = cu_sp.get();
+            die = cu_sp->GetDIEPtr(die_offset);
+        }
+    }
+    if (die == NULL)
+        *cu_handle = NULL;
+    return die;
+}
+
+
 const DWARFDebugInfoEntry*
 DWARFDebugInfo::GetDIEPtrContainingOffset(dw_offset_t die_offset, DWARFCompileUnitSP* cu_sp_ptr)
 {

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h?rev=133302&r1=133301&r2=133302&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h Fri Jun 17 17:10:16 2011
@@ -52,6 +52,8 @@
     DWARFCompileUnitSP GetCompileUnitContainingDIE(dw_offset_t die_offset);
 
     DWARFDebugInfoEntry* GetDIEPtr(dw_offset_t die_offset, DWARFCompileUnitSP* cu_sp_ptr);
+    DWARFDebugInfoEntry* GetDIEPtrWithCompileUnitHint (dw_offset_t die_offset, DWARFCompileUnit**cu_handle);
+
     const DWARFDebugInfoEntry* GetDIEPtrContainingOffset(dw_offset_t die_offset, DWARFCompileUnitSP* cu_sp_ptr);
 
     void Dump(lldb_private::Stream *s, const uint32_t die_offset, const uint32_t recurse_depth);

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=133302&r1=133301&r2=133302&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Fri Jun 17 17:10:16 2011
@@ -3983,7 +3983,12 @@
             dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
             assert (func_lo_pc != DW_INVALID_ADDRESS);
 
-            return ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
+            const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
+            
+            // Let all blocks know they have parse all their variables
+            sc.function->GetBlock (false).SetDidParseVariables (true, true);
+
+            return num_variables;
         }
         else if (sc.comp_unit)
         {
@@ -4161,6 +4166,74 @@
     return var_sp;
 }
 
+
+const DWARFDebugInfoEntry *
+SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset, 
+                                                   dw_offset_t spec_block_die_offset,
+                                                   DWARFCompileUnit **result_die_cu_handle)
+{
+    // Give the concrete function die specified by "func_die_offset", find the 
+    // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
+    // to "spec_block_die_offset"
+    DWARFDebugInfo* info = DebugInfo();
+
+    const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
+    if (die)
+    {
+        assert (*result_die_cu_handle);
+        return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
+    }
+    return NULL;
+}
+
+
+const DWARFDebugInfoEntry *
+SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
+                                                  const DWARFDebugInfoEntry *die,
+                                                  dw_offset_t spec_block_die_offset,
+                                                  DWARFCompileUnit **result_die_cu_handle)
+{
+    if (die)
+    {
+        switch (die->Tag())
+        {
+        case DW_TAG_subprogram:
+        case DW_TAG_inlined_subroutine:
+        case DW_TAG_lexical_block:
+            {
+                if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
+                {
+                    *result_die_cu_handle = dwarf_cu;
+                    return die;
+                }
+
+                if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
+                {
+                    *result_die_cu_handle = dwarf_cu;
+                    return die;
+                }
+            }
+            break;
+        }
+
+        // Give the concrete function die specified by "func_die_offset", find the 
+        // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
+        // to "spec_block_die_offset"
+        for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
+        {
+            const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
+                                                                                      child_die,
+                                                                                      spec_block_die_offset,
+                                                                                      result_die_cu_handle);
+            if (result_die)
+                return result_die;
+        }
+    }
+    
+    *result_die_cu_handle = NULL;
+    return NULL;
+}
+
 size_t
 SymbolFileDWARF::ParseVariables
 (
@@ -4176,126 +4249,125 @@
     if (orig_die == NULL)
         return 0;
 
+    VariableListSP variable_list_sp;
+
+    size_t vars_added = 0;
     const DWARFDebugInfoEntry *die = orig_die;
-    const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
-    dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
-    VariableListSP variables;
-    switch (parent_tag)
+    while (die != NULL)
     {
-    case DW_TAG_compile_unit:
-        if (sc.comp_unit != NULL)
+        dw_tag_t tag = die->Tag();
+
+        // Check to see if we have already parsed this variable or constant?
+        if (m_die_to_variable_sp[die])
         {
-            variables = sc.comp_unit->GetVariableList(false);
-            if (variables.get() == NULL)
-            {
-                variables.reset(new VariableList());
-                sc.comp_unit->SetVariableList(variables);
-            }
+            if (cc_variable_list)
+                cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
         }
         else
         {
-            fprintf (stderr, 
-                     "error: parent 0x%8.8x %s with no valid compile unit in symbol context for 0x%8.8x %s.\n",
-                     sc_parent_die->GetOffset(),
-                     DW_TAG_value_to_name (parent_tag),
-                     orig_die->GetOffset(),
-                     DW_TAG_value_to_name (orig_die->Tag()));
-        }
-        break;
-
-    case DW_TAG_subprogram:
-    case DW_TAG_inlined_subroutine:
-    case DW_TAG_lexical_block:
-        if (sc.function != NULL)
-        {
-            // Check to see if we already have parsed the variables for the given scope
-            
-            Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
-            if (block != NULL)
+            // We haven't already parsed it, lets do that now.
+            if ((tag == DW_TAG_variable) ||
+                (tag == DW_TAG_constant) ||
+                (tag == DW_TAG_formal_parameter && sc.function))
             {
-                variables = block->GetVariableList(false, false);
-                if (variables.get() == NULL)
+                if (variable_list_sp.get() == NULL)
                 {
-                    variables.reset(new VariableList());
-                    block->SetVariableList(variables);
+                    const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
+                    dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
+                    switch (parent_tag)
+                    {
+                        case DW_TAG_compile_unit:
+                            if (sc.comp_unit != NULL)
+                            {
+                                variable_list_sp = sc.comp_unit->GetVariableList(false);
+                                if (variable_list_sp.get() == NULL)
+                                {
+                                    variable_list_sp.reset(new VariableList());
+                                    sc.comp_unit->SetVariableList(variable_list_sp);
+                                }
+                            }
+                            else
+                            {
+                                fprintf (stderr, 
+                                         "error: parent 0x%8.8x %s with no valid compile unit in symbol context for 0x%8.8x %s.\n",
+                                         sc_parent_die->GetOffset(),
+                                         DW_TAG_value_to_name (parent_tag),
+                                         orig_die->GetOffset(),
+                                         DW_TAG_value_to_name (orig_die->Tag()));
+                            }
+                            break;
+                            
+                        case DW_TAG_subprogram:
+                        case DW_TAG_inlined_subroutine:
+                        case DW_TAG_lexical_block:
+                            if (sc.function != NULL)
+                            {
+                                // Check to see if we already have parsed the variables for the given scope
+                                
+                                Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
+                                if (block == NULL)
+                                {
+                                    // This must be a specification or abstract origin with 
+                                    // a concrete block couterpart in the current function. We need
+                                    // to find the concrete block so we can correctly add the 
+                                    // variable to it
+                                    DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
+                                    const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(), 
+                                                                                                                      sc_parent_die->GetOffset(), 
+                                                                                                                      &concrete_block_die_cu);
+                                    if (concrete_block_die)
+                                        block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die->GetOffset());
+                                }
+                                
+                                if (block != NULL)
+                                {
+                                    const bool can_create = false;
+                                    variable_list_sp = block->GetBlockVariableList (can_create);
+                                    if (variable_list_sp.get() == NULL)
+                                    {
+                                        variable_list_sp.reset(new VariableList());
+                                        block->SetVariableList(variable_list_sp);
+                                    }
+                                }
+                            }
+                            break;
+                            
+                        default:
+                            fprintf (stderr, 
+                                     "error: didn't find appropriate parent DIE for variable list for 0x%8.8x %s.\n",
+                                     orig_die->GetOffset(),
+                                     DW_TAG_value_to_name (orig_die->Tag()));
+                            break;
+                    }
                 }
-            }
-            else
-            {
-                fprintf (stderr, 
-                         "error: NULL block for 0x%8.8x %s for variable at 0x%8.8x %s\n", 
-                         sc_parent_die->GetOffset(),
-                         DW_TAG_value_to_name (parent_tag),
-                         orig_die->GetOffset(),
-                         DW_TAG_value_to_name (orig_die->Tag()));
-            }
-        }
-        else
-        {
-            fprintf (stderr, 
-                     "error: parent 0x%8.8x %s with no valid function in symbol context for 0x%8.8x %s.\n",
-                     sc_parent_die->GetOffset(),
-                     DW_TAG_value_to_name (parent_tag),
-                     orig_die->GetOffset(),
-                     DW_TAG_value_to_name (orig_die->Tag()));
-        }
-        break;
-
-    default:
-        fprintf (stderr, 
-                 "error: didn't find appropriate parent DIE for variable list for 0x%8.8x %s.\n",
-                 orig_die->GetOffset(),
-                 DW_TAG_value_to_name (orig_die->Tag()));
-        break;
-    }
-
-    // We need to have a variable list at this point that we can add variables to
-    if (variables.get())
-    {
-        size_t vars_added = 0;
-        while (die != NULL)
-        {
-            dw_tag_t tag = die->Tag();
-
-            // Check to see if we have already parsed this variable or constant?
-            if (m_die_to_variable_sp[die])
-            {
-                if (cc_variable_list)
-                    cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
-            }
-            else
-            {
-                // We haven't already parsed it, lets do that now.
-                if ((tag == DW_TAG_variable) ||
-                    (tag == DW_TAG_constant) ||
-                    (tag == DW_TAG_formal_parameter && sc.function))
+                
+                if (variable_list_sp)
                 {
                     VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
                     if (var_sp)
                     {
-                        variables->AddVariableIfUnique (var_sp);
+                        variable_list_sp->AddVariableIfUnique (var_sp);
                         if (cc_variable_list)
                             cc_variable_list->AddVariableIfUnique (var_sp);
                         ++vars_added;
                     }
                 }
             }
+        }
 
-            bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
+        bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
 
-            if (!skip_children && parse_children && die->HasChildren())
-            {
-                vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
-            }
-
-            if (parse_siblings)
-                die = die->GetSibling();
-            else
-                die = NULL;
+        if (!skip_children && parse_children && die->HasChildren())
+        {
+            vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
         }
-        return vars_added;
+
+        if (parse_siblings)
+            die = die->GetSibling();
+        else
+            die = NULL;
     }
-    return 0;
+    return vars_added;
 }
 
 //------------------------------------------------------------------

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=133302&r1=133301&r2=133302&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Fri Jun 17 17:10:16 2011
@@ -311,6 +311,17 @@
                                 m_debug_map_symfile = debug_map_symfile;
                             }
 
+    const DWARFDebugInfoEntry *
+                            FindBlockContainingSpecification (dw_offset_t func_die_offset, 
+                                                              dw_offset_t spec_block_die_offset,
+                                                              DWARFCompileUnit **dwarf_cu_handle);
+
+    const DWARFDebugInfoEntry *
+                            FindBlockContainingSpecification (DWARFCompileUnit* dwarf_cu,
+                                                              const DWARFDebugInfoEntry *die,
+                                                              dw_offset_t spec_block_die_offset,
+                                                              DWARFCompileUnit **dwarf_cu_handle);
+
     clang::NamespaceDecl *
     ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die);
     

Modified: lldb/trunk/source/Symbol/Block.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Block.cpp?rev=133302&r1=133301&r2=133302&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Block.cpp (original)
+++ lldb/trunk/source/Symbol/Block.cpp Fri Jun 17 17:10:16 2011
@@ -455,9 +455,8 @@
 
 
 VariableListSP
-Block::GetVariableList (bool get_child_variables, bool can_create)
+Block::GetBlockVariableList (bool can_create)
 {
-    VariableListSP variable_list_sp;
     if (m_parsed_block_variables == false)
     {
         if (m_variable_list_sp.get() == NULL && can_create)
@@ -469,31 +468,40 @@
             sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
         }
     }
+    return m_variable_list_sp;
+}
 
-    if (m_variable_list_sp.get())
+uint32_t
+Block::AppendBlockVariables (bool can_create,
+                             bool get_child_block_variables,
+                             bool stop_if_child_block_is_inlined_function,
+                             VariableList *variable_list)
+{
+    uint32_t num_variables_added = 0;
+    VariableList *block_var_list = GetBlockVariableList (can_create).get();
+    if (block_var_list)
     {
-        variable_list_sp.reset(new VariableList());
-        if (variable_list_sp.get())
-            variable_list_sp->AddVariables(m_variable_list_sp.get());
-
-        if (get_child_variables)
-        {
-            for (Block *child_block = GetFirstChild(); 
-                 child_block != NULL; 
-                 child_block = child_block->GetSibling())
-            {   
-                if (child_block->GetInlinedFunctionInfo() == NULL)
-                {
-                    VariableListSP child_block_variable_list(child_block->GetVariableList(get_child_variables, can_create));
-                    if (child_block_variable_list.get())
-                        variable_list_sp->AddVariables(child_block_variable_list.get());
-                }
-                
+        num_variables_added += block_var_list->GetSize();
+        variable_list->AddVariables (block_var_list);
+    }
+    
+    if (get_child_block_variables)
+    {
+        for (Block *child_block = GetFirstChild(); 
+             child_block != NULL; 
+             child_block = child_block->GetSibling())
+        {   
+            if (stop_if_child_block_is_inlined_function == false || 
+                child_block->GetInlinedFunctionInfo() == NULL)
+            {
+                num_variables_added += child_block->AppendBlockVariables (can_create,
+                                                                          get_child_block_variables,
+                                                                          stop_if_child_block_is_inlined_function,
+                                                                          variable_list);
             }
         }
     }
-
-    return variable_list_sp;
+    return num_variables_added;
 }
 
 uint32_t
@@ -506,7 +514,7 @@
 )
 {
     uint32_t num_variables_added = 0;
-    VariableListSP variable_list_sp(GetVariableList(false, can_create));
+    VariableListSP variable_list_sp(GetBlockVariableList(can_create));
 
     bool is_inlined_function = GetInlinedFunctionInfo() != NULL;
     if (variable_list_sp.get())
@@ -538,3 +546,15 @@
             child_block->SetBlockInfoHasBeenParsed (b, true);
     }
 }
+
+void
+Block::SetDidParseVariables (bool b, bool set_children)
+{
+    m_parsed_block_variables = b;
+    if (set_children)
+    {
+        for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
+            child_block->SetDidParseVariables (b, true);
+    }
+}
+

Modified: lldb/trunk/source/Target/StackFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=133302&r1=133301&r2=133302&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrame.cpp (original)
+++ lldb/trunk/source/Target/StackFrame.cpp Fri Jun 17 17:10:16 2011
@@ -460,7 +460,9 @@
         {
             const bool get_child_variables = true;
             const bool can_create = true;
-            m_variable_list_sp = frame_block->GetVariableList (get_child_variables, can_create);
+            const bool stop_if_child_block_is_inlined_function = true;
+            m_variable_list_sp.reset(new VariableList());
+            frame_block->AppendBlockVariables(can_create, get_child_variables, stop_if_child_block_is_inlined_function, m_variable_list_sp.get());
         }
     }
     





More information about the lldb-commits mailing list