[Lldb-commits] [lldb] r247131 - Code cleanup in preparation of adding split dwarf support

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Wed Sep 9 03:20:36 PDT 2015


Author: tberghammer
Date: Wed Sep  9 05:20:36 2015
New Revision: 247131

URL: http://llvm.org/viewvc/llvm-project?rev=247131&view=rev
Log:
Code cleanup in preparation of adding split dwarf support

* Remove some unused code
* Remove usage of DWARFDebugInfoEntry::Attributes where usage isn't
  reasonable
* Cleanup DWARFMappedHash with separating it to header and implementation
  file and fixing the visibility of the functions

Differential revision: http://reviews.llvm.org/D12374

Added:
    lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
Modified:
    lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt?rev=247131&r1=247130&r2=247131&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt Wed Sep  9 05:20:36 2015
@@ -22,6 +22,7 @@ add_lldb_library(lldbPluginSymbolFileDWA
   DWARFFormValue.cpp
   DWARFLocationDescription.cpp
   DWARFLocationList.cpp
+  HashedNameToDIE.cpp
   LogChannelDWARF.cpp
   NameToDIE.cpp
   SymbolFileDWARF.cpp

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp?rev=247131&r1=247130&r2=247131&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp Wed Sep  9 05:20:36 2015
@@ -569,46 +569,6 @@ DWARFCompileUnit::GetDIE (dw_offset_t di
     return DWARFDIE(); // Not found
 }
 
-//----------------------------------------------------------------------
-// GetDIEPtrContainingOffset()
-//
-// Get the DIE (Debug Information Entry) that contains the specified
-// .debug_info offset.
-//----------------------------------------------------------------------
-DWARFDIE
-DWARFCompileUnit::GetDIEContainingOffset(dw_offset_t die_offset)
-{
-    if (die_offset != DW_INVALID_OFFSET)
-    {
-        if (ContainsDIEOffset(die_offset))
-        {
-
-            ExtractDIEsIfNeeded (false);
-            DWARFDebugInfoEntry::iterator end = m_die_array.end();
-            DWARFDebugInfoEntry::iterator pos = lower_bound(m_die_array.begin(), end, die_offset, CompareDIEOffset);
-            if (pos != end)
-            {
-                if (die_offset >= (*pos).GetOffset())
-                {
-                    DWARFDebugInfoEntry::iterator next = pos + 1;
-                    if (next != end)
-                    {
-                        if (die_offset < (*next).GetOffset())
-                            return DWARFDIE(this, &(*pos));
-                    }
-                }
-            }
-        }
-        else
-        {
-            return m_dwarf2Data->DebugInfo()->GetDIEContainingOffset (die_offset);
-        }
-    }
-    return DWARFDIE(); // Not found
-}
-
-
-
 size_t
 DWARFCompileUnit::AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& dies, uint32_t depth) const
 {

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h?rev=247131&r1=247130&r2=247131&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h Wed Sep  9 05:20:36 2015
@@ -106,9 +106,6 @@ public:
     DWARFDIE
     GetDIE (dw_offset_t die_offset);
 
-    DWARFDIE
-    GetDIEContainingOffset (dw_offset_t die_offset);
-
     static uint8_t
     GetAddressByteSize(const DWARFCompileUnit* cu);
 

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=247131&r1=247130&r2=247131&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp Wed Sep  9 05:20:36 2015
@@ -295,17 +295,6 @@ DWARFDebugInfo::GetDIE(dw_offset_t die_o
     return DWARFDIE();    // Not found
 }
 
-DWARFDIE
-DWARFDebugInfo::GetDIEContainingOffset (dw_offset_t die_offset)
-{
-    DWARFCompileUnit *cu = GetCompileUnitContainingDIE(die_offset);
-    if (cu)
-        return cu->GetDIEContainingOffset (die_offset);
-
-    return DWARFDIE();    // Not found
-
-}
-
 //----------------------------------------------------------------------
 // Parse
 //

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h?rev=247131&r1=247130&r2=247131&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h Wed Sep  9 05:20:36 2015
@@ -57,23 +57,6 @@ public:
     typedef offset_collection::iterator         offset_collection_iterator;
     typedef offset_collection::const_iterator   offset_collection_const_iterator;
 
-    struct CompareState
-    {
-        CompareState() :
-            die_offset_pairs()
-        {
-            assert(sizeof(dw_offset_t)*2 == sizeof(uint64_t));
-        }
-
-        bool AddTypePair(dw_offset_t a, dw_offset_t b)
-        {
-            uint64_t a_b_offsets = (uint64_t)a << 32 | (uint64_t)b;
-            // Return true if this type was inserted, false otherwise
-            return die_offset_pairs.insert(a_b_offsets).second;
-        }
-        std::set< uint64_t > die_offset_pairs;
-    };
-
                 DWARFDebugInfoEntry():
                     m_offset        (DW_INVALID_OFFSET),
                     m_parent_idx    (0),
@@ -225,22 +208,6 @@ public:
                     const DWARFAttributes& attributes,
                     std::string &storage) const;
 
-//    static int  Compare(
-//                    SymbolFileDWARF* dwarf2Data,
-//                    dw_offset_t a_die_offset,
-//                    dw_offset_t b_die_offset,
-//                    CompareState &compare_state,
-//                    bool compare_siblings,
-//                    bool compare_children);
-//
-//    static int Compare(
-//                    SymbolFileDWARF* dwarf2Data,
-//                    DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die,
-//                    DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die,
-//                    CompareState &compare_state,
-//                    bool compare_siblings,
-//                    bool compare_children);
-
     static bool OffsetLessThan (
                     const DWARFDebugInfoEntry& a,
                     const DWARFDebugInfoEntry& b);

Added: lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp?rev=247131&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp (added)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp Wed Sep  9 05:20:36 2015
@@ -0,0 +1,741 @@
+//===-- HashedNameToDIE.cpp -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "HashedNameToDIE.h"
+
+void
+DWARFMappedHash::ExtractDIEArray (const DIEInfoArray &die_info_array, DIEArray &die_offsets)
+{
+    const size_t count = die_info_array.size();
+    for (size_t i=0; i<count; ++i)
+        die_offsets.push_back (die_info_array[i].offset);
+}
+
+void
+DWARFMappedHash::ExtractDIEArray (const DIEInfoArray &die_info_array,
+                                  const dw_tag_t tag,
+                                  DIEArray &die_offsets)
+{
+    if (tag == 0)
+    {
+        ExtractDIEArray (die_info_array, die_offsets);
+    }
+    else
+    {
+        const size_t count = die_info_array.size();
+        for (size_t i=0; i<count; ++i)
+        {
+            const dw_tag_t die_tag = die_info_array[i].tag;
+            bool tag_matches = die_tag == 0 || tag == die_tag;
+            if (!tag_matches)
+            {
+                if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
+                    tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
+            }
+            if (tag_matches)
+                die_offsets.push_back (die_info_array[i].offset);
+        }
+    }
+}
+
+void
+DWARFMappedHash::ExtractDIEArray (const DIEInfoArray &die_info_array,
+                                  const dw_tag_t tag,
+                                  const uint32_t qualified_name_hash,
+                                  DIEArray &die_offsets)
+{
+    if (tag == 0)
+    {
+        ExtractDIEArray (die_info_array, die_offsets);
+    }
+    else
+    {
+        const size_t count = die_info_array.size();
+        for (size_t i=0; i<count; ++i)
+        {
+            if (qualified_name_hash != die_info_array[i].qualified_name_hash)
+                continue;
+            const dw_tag_t die_tag = die_info_array[i].tag;
+            bool tag_matches = die_tag == 0 || tag == die_tag;
+            if (!tag_matches)
+            {
+                if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
+                    tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
+            }
+            if (tag_matches)
+                die_offsets.push_back (die_info_array[i].offset);
+        }
+    }
+}
+
+void
+DWARFMappedHash::ExtractClassOrStructDIEArray (const DIEInfoArray &die_info_array,
+                                               bool return_implementation_only_if_available,
+                                               DIEArray &die_offsets)
+{
+    const size_t count = die_info_array.size();
+    for (size_t i=0; i<count; ++i)
+    {
+        const dw_tag_t die_tag = die_info_array[i].tag;
+        if (die_tag == 0 || die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
+        {
+            if (die_info_array[i].type_flags & eTypeFlagClassIsImplementation)
+            {
+                if (return_implementation_only_if_available)
+                {
+                    // We found the one true definition for this class, so
+                    // only return that
+                    die_offsets.clear();                        
+                    die_offsets.push_back (die_info_array[i].offset);
+                    return;
+                }
+                else
+                {
+                    // Put the one true definition as the first entry so it
+                    // matches first
+                    die_offsets.insert (die_offsets.begin(), die_info_array[i].offset);
+                }
+            }
+            else
+            {
+                die_offsets.push_back (die_info_array[i].offset);
+            }
+        }
+    }
+}
+
+void
+DWARFMappedHash::ExtractTypesFromDIEArray (const DIEInfoArray &die_info_array,
+                                           uint32_t type_flag_mask,
+                                           uint32_t type_flag_value,
+                                           DIEArray &die_offsets)
+{
+    const size_t count = die_info_array.size();
+    for (size_t i=0; i<count; ++i)
+    {
+        if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value)
+            die_offsets.push_back (die_info_array[i].offset);
+    }
+}
+
+const char *
+DWARFMappedHash::GetAtomTypeName (uint16_t atom)
+{
+    switch (atom)
+    {
+        case eAtomTypeNULL:         return "NULL";
+        case eAtomTypeDIEOffset:    return "die-offset";
+        case eAtomTypeCUOffset:     return "cu-offset";
+        case eAtomTypeTag:          return "die-tag";
+        case eAtomTypeNameFlags:    return "name-flags";
+        case eAtomTypeTypeFlags:    return "type-flags";
+        case eAtomTypeQualNameHash: return "qualified-name-hash";
+    }
+    return "<invalid>";
+}
+
+DWARFMappedHash::DIEInfo::DIEInfo () :
+    offset (DW_INVALID_OFFSET),
+    tag (0),
+    type_flags (0),
+    qualified_name_hash (0)
+{
+}
+
+DWARFMappedHash::DIEInfo::DIEInfo (dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h) :
+    offset (o),
+    tag (t),
+    type_flags (f),
+    qualified_name_hash (h)
+{
+}
+
+DWARFMappedHash::Prologue::Prologue (dw_offset_t _die_base_offset) :
+    die_base_offset (_die_base_offset),
+    atoms(),
+    atom_mask (0),
+    min_hash_data_byte_size(0),
+    hash_data_has_fixed_byte_size(true)
+{
+    // Define an array of DIE offsets by first defining an array, 
+    // and then define the atom type for the array, in this case
+    // we have an array of DIE offsets
+    AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4);
+}
+
+void
+DWARFMappedHash::Prologue::ClearAtoms ()
+{
+    hash_data_has_fixed_byte_size = true;
+    min_hash_data_byte_size = 0;
+    atom_mask = 0;
+    atoms.clear();
+}
+
+bool
+DWARFMappedHash::Prologue::ContainsAtom (AtomType atom_type) const
+{
+    return (atom_mask & (1u << atom_type)) != 0;
+}
+
+void
+DWARFMappedHash::Prologue::Clear ()
+{
+    die_base_offset = 0;
+    ClearAtoms ();
+}
+
+void
+DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form)
+{
+    atoms.push_back ({type, form});
+    atom_mask |= 1u << type;
+    switch (form)
+    {
+        case DW_FORM_indirect:
+        case DW_FORM_exprloc:
+        case DW_FORM_flag_present:
+        case DW_FORM_ref_sig8:
+            assert (!"Unhandled atom form");
+            break;
+
+        case DW_FORM_string:
+        case DW_FORM_block:
+        case DW_FORM_block1:
+        case DW_FORM_sdata:
+        case DW_FORM_udata:
+        case DW_FORM_ref_udata:
+        case DW_FORM_GNU_addr_index:
+        case DW_FORM_GNU_str_index:
+            hash_data_has_fixed_byte_size = false;
+            // Fall through to the cases below...
+        case DW_FORM_flag:
+        case DW_FORM_data1:
+        case DW_FORM_ref1:
+        case DW_FORM_sec_offset:
+            min_hash_data_byte_size += 1; 
+            break;
+
+        case DW_FORM_block2:
+            hash_data_has_fixed_byte_size = false;
+            // Fall through to the cases below...
+        case DW_FORM_data2: 
+        case DW_FORM_ref2:
+            min_hash_data_byte_size += 2; 
+            break;
+
+        case DW_FORM_block4: 
+            hash_data_has_fixed_byte_size = false;
+            // Fall through to the cases below...
+        case DW_FORM_data4:
+        case DW_FORM_ref4:
+        case DW_FORM_addr:
+        case DW_FORM_ref_addr:
+        case DW_FORM_strp:
+            min_hash_data_byte_size += 4; 
+            break;
+
+        case DW_FORM_data8:
+        case DW_FORM_ref8:
+            min_hash_data_byte_size += 8; 
+            break;
+            
+    }
+}
+
+lldb::offset_t
+DWARFMappedHash::Prologue::Read (const lldb_private::DataExtractor &data,
+      lldb::offset_t offset)
+{
+    ClearAtoms ();
+    
+    die_base_offset = data.GetU32 (&offset);
+    
+    const uint32_t atom_count = data.GetU32 (&offset);
+    if (atom_count == 0x00060003u)
+    {
+        // Old format, deal with contents of old pre-release format
+        while (data.GetU32(&offset))
+            /* do nothing */;
+
+        // Hardcode to the only known value for now.
+        AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4);
+    }
+    else
+    {
+        for (uint32_t i=0; i<atom_count; ++i)
+        {
+            AtomType type = (AtomType)data.GetU16 (&offset);
+            dw_form_t form = (dw_form_t)data.GetU16 (&offset);                    
+            AppendAtom (type, form);
+        }
+    }
+    return offset;
+}
+
+size_t
+DWARFMappedHash::Prologue::GetByteSize () const
+{
+    // Add an extra count to the atoms size for the zero termination Atom that gets
+    // written to disk
+    return sizeof(die_base_offset) + sizeof(uint32_t) + atoms.size() * sizeof(Atom);
+}
+
+size_t
+DWARFMappedHash::Prologue::GetMinimumHashDataByteSize () const
+{
+    return min_hash_data_byte_size;
+}
+
+bool
+DWARFMappedHash::Prologue::HashDataHasFixedByteSize() const
+{
+    return hash_data_has_fixed_byte_size;
+}
+
+size_t
+DWARFMappedHash::Header::GetByteSize (const HeaderData &header_data)
+{
+    return header_data.GetByteSize();
+}
+
+lldb::offset_t
+DWARFMappedHash::Header::Read (lldb_private::DataExtractor &data, lldb::offset_t offset)
+{
+    offset = MappedHash::Header<Prologue>::Read (data, offset);
+    if (offset != UINT32_MAX)
+    {
+        offset = header_data.Read (data, offset);
+    }
+    return offset;
+}
+
+bool
+DWARFMappedHash::Header::Read (const lldb_private::DWARFDataExtractor &data, 
+                               lldb::offset_t *offset_ptr, 
+                               DIEInfo &hash_data) const
+{
+    const size_t num_atoms = header_data.atoms.size();
+    if (num_atoms == 0)
+        return false;
+    
+    for (size_t i=0; i<num_atoms; ++i)
+    {
+        DWARFFormValue form_value (NULL, header_data.atoms[i].form);
+        
+        if (!form_value.ExtractValue(data, offset_ptr))
+            return false;
+        
+        switch (header_data.atoms[i].type)
+        {
+            case eAtomTypeDIEOffset:    // DIE offset, check form for encoding
+                hash_data.offset = (dw_offset_t)form_value.Reference (header_data.die_base_offset);
+                break;
+
+            case eAtomTypeTag:          // DW_TAG value for the DIE
+                hash_data.tag = (dw_tag_t)form_value.Unsigned ();
+                
+            case eAtomTypeTypeFlags:    // Flags from enum TypeFlags
+                hash_data.type_flags = (uint32_t)form_value.Unsigned ();
+                break;
+
+            case eAtomTypeQualNameHash:    // Flags from enum TypeFlags
+                hash_data.qualified_name_hash = form_value.Unsigned ();
+                break;
+
+            default:
+                // We can always skip atoms we don't know about
+                break;
+        }
+    }
+    return true;
+}
+
+void
+DWARFMappedHash::Header::Dump (lldb_private::Stream& strm, const DIEInfo &hash_data) const
+{
+    const size_t num_atoms = header_data.atoms.size();
+    for (size_t i=0; i<num_atoms; ++i)
+    {
+        if (i > 0)
+            strm.PutCString (", ");
+        
+        DWARFFormValue form_value (NULL, header_data.atoms[i].form);
+        switch (header_data.atoms[i].type)
+        {
+            case eAtomTypeDIEOffset:    // DIE offset, check form for encoding
+                strm.Printf ("{0x%8.8x}", hash_data.offset);
+                break;
+
+            case eAtomTypeTag:          // DW_TAG value for the DIE
+                {
+                    const char *tag_cstr = lldb_private::DW_TAG_value_to_name (hash_data.tag);
+                    if (tag_cstr)
+                        strm.PutCString (tag_cstr);
+                    else
+                        strm.Printf ("DW_TAG_(0x%4.4x)", hash_data.tag);
+                }
+                break;
+
+            case eAtomTypeTypeFlags:    // Flags from enum TypeFlags
+                strm.Printf ("0x%2.2x", hash_data.type_flags);
+                if (hash_data.type_flags)
+                {
+                    strm.PutCString (" (");
+                    if (hash_data.type_flags & eTypeFlagClassIsImplementation)
+                        strm.PutCString (" implementation");
+                    strm.PutCString (" )");
+                }
+                break;
+
+            case eAtomTypeQualNameHash:    // Flags from enum TypeFlags
+                strm.Printf ("0x%8.8x", hash_data.qualified_name_hash);
+                break;
+
+            default:
+                strm.Printf ("AtomType(0x%x)", header_data.atoms[i].type);
+                break;
+        }
+    }
+}
+
+DWARFMappedHash::MemoryTable::MemoryTable (lldb_private::DWARFDataExtractor &table_data, 
+                                           const lldb_private::DWARFDataExtractor &string_table,
+                                           const char *name) :
+    MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray> (table_data),
+    m_data (table_data),
+    m_string_table (string_table),
+    m_name (name)
+{
+}
+
+const char *
+DWARFMappedHash::MemoryTable::GetStringForKeyType (KeyType key) const
+{
+    // The key in the DWARF table is the .debug_str offset for the string
+    return m_string_table.PeekCStr (key);
+}
+
+bool
+DWARFMappedHash::MemoryTable::ReadHashData (uint32_t hash_data_offset, HashData &hash_data) const
+{
+    lldb::offset_t offset = hash_data_offset;
+    offset += 4; // Skip string table offset that contains offset of hash name in .debug_str
+    const uint32_t count = m_data.GetU32 (&offset);
+    if (count > 0)
+    {
+        hash_data.resize(count);
+        for (uint32_t i=0; i<count; ++i)
+        {
+            if (!m_header.Read(m_data, &offset, hash_data[i]))
+                return false;
+        }
+    }
+    else
+        hash_data.clear();
+    return true;
+}
+
+DWARFMappedHash::MemoryTable::Result
+DWARFMappedHash::MemoryTable::GetHashDataForName (const char *name,
+                                                  lldb::offset_t* hash_data_offset_ptr,
+                                                  Pair &pair) const
+{
+    pair.key = m_data.GetU32 (hash_data_offset_ptr);
+    pair.value.clear();
+
+    // If the key is zero, this terminates our chain of HashData objects
+    // for this hash value.
+    if (pair.key == 0)
+        return eResultEndOfHashData;
+
+    // There definitely should be a string for this string offset, if
+    // there isn't, there is something wrong, return and error
+    const char *strp_cstr = m_string_table.PeekCStr (pair.key);
+    if (strp_cstr == NULL)
+    {
+        *hash_data_offset_ptr = UINT32_MAX;
+        return eResultError;
+    }
+
+    const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
+    const size_t min_total_hash_data_size = count * m_header.header_data.GetMinimumHashDataByteSize();
+    if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size))
+    {
+        // We have at least one HashData entry, and we have enough
+        // data to parse at least "count" HashData entries.
+        
+        // First make sure the entire C string matches...
+        const bool match = strcmp (name, strp_cstr) == 0;
+        
+        if (!match && m_header.header_data.HashDataHasFixedByteSize())
+        {
+            // If the string doesn't match and we have fixed size data,
+            // we can just add the total byte size of all HashData objects
+            // to the hash data offset and be done...
+            *hash_data_offset_ptr += min_total_hash_data_size;
+        }
+        else
+        {
+            // If the string does match, or we don't have fixed size data
+            // then we need to read the hash data as a stream. If the
+            // string matches we also append all HashData objects to the
+            // value array.
+            for (uint32_t i=0; i<count; ++i)
+            {
+                DIEInfo die_info;
+                if (m_header.Read(m_data, hash_data_offset_ptr, die_info))
+                {
+                    // Only happened if the HashData of the string matched...
+                    if (match)
+                        pair.value.push_back (die_info);
+                }
+                else
+                {
+                    // Something went wrong while reading the data
+                    *hash_data_offset_ptr = UINT32_MAX;
+                    return eResultError;
+                }
+            }
+        }
+        // Return the correct response depending on if the string matched
+        // or not...
+        if (match)
+            return eResultKeyMatch;     // The key (cstring) matches and we have lookup results!
+        else
+            return eResultKeyMismatch;  // The key doesn't match, this function will get called 
+                                        // again for the next key/value or the key terminator
+                                        // which in our case is a zero .debug_str offset.
+    }
+    else
+    {
+        *hash_data_offset_ptr = UINT32_MAX;
+        return eResultError;
+    }
+}
+
+DWARFMappedHash::MemoryTable::Result
+DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression (
+        const lldb_private::RegularExpression& regex,
+        lldb::offset_t* hash_data_offset_ptr, 
+        Pair &pair) const
+{
+    pair.key = m_data.GetU32 (hash_data_offset_ptr);
+    // If the key is zero, this terminates our chain of HashData objects
+    // for this hash value.
+    if (pair.key == 0)
+        return eResultEndOfHashData;
+    
+    // There definitely should be a string for this string offset, if
+    // there isn't, there is something wrong, return and error
+    const char *strp_cstr = m_string_table.PeekCStr (pair.key);
+    if (strp_cstr == NULL)
+        return eResultError;
+    
+    const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
+    const size_t min_total_hash_data_size = count * m_header.header_data.GetMinimumHashDataByteSize();
+    if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size))
+    {
+        const bool match = regex.Execute(strp_cstr);
+        
+        if (!match && m_header.header_data.HashDataHasFixedByteSize())
+        {
+            // If the regex doesn't match and we have fixed size data,
+            // we can just add the total byte size of all HashData objects
+            // to the hash data offset and be done...
+            *hash_data_offset_ptr += min_total_hash_data_size;
+        }
+        else
+        {
+            // If the string does match, or we don't have fixed size data
+            // then we need to read the hash data as a stream. If the
+            // string matches we also append all HashData objects to the
+            // value array.
+            for (uint32_t i=0; i<count; ++i)
+            {
+                DIEInfo die_info;
+                if (m_header.Read(m_data, hash_data_offset_ptr, die_info))
+                {
+                    // Only happened if the HashData of the string matched...
+                    if (match)
+                        pair.value.push_back (die_info);
+                }
+                else
+                {
+                    // Something went wrong while reading the data
+                    *hash_data_offset_ptr = UINT32_MAX;
+                    return eResultError;
+                }
+            }
+        }
+        // Return the correct response depending on if the string matched
+        // or not...
+        if (match)
+            return eResultKeyMatch;     // The key (cstring) matches and we have lookup results!
+        else
+            return eResultKeyMismatch;  // The key doesn't match, this function will get called 
+                                        // again for the next key/value or the key terminator
+                                        // which in our case is a zero .debug_str offset.
+    }
+    else
+    {
+        *hash_data_offset_ptr = UINT32_MAX;
+        return eResultError;
+    }
+}
+
+size_t
+DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex (
+        const lldb_private::RegularExpression& regex, 
+        DIEInfoArray &die_info_array) const
+{
+    const uint32_t hash_count = m_header.hashes_count;
+    Pair pair;
+    for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
+    {
+        lldb::offset_t hash_data_offset = GetHashDataOffset (offset_idx);
+        while (hash_data_offset != UINT32_MAX)
+        {
+            const lldb::offset_t prev_hash_data_offset = hash_data_offset;
+            Result hash_result = AppendHashDataForRegularExpression (regex, &hash_data_offset, pair);
+            if (prev_hash_data_offset == hash_data_offset)
+                break;
+
+            // Check the result of getting our hash data
+            switch (hash_result)
+            {
+                case eResultKeyMatch:
+                case eResultKeyMismatch:
+                    // Whether we matches or not, it doesn't matter, we
+                    // keep looking.
+                    break;
+                    
+                case eResultEndOfHashData:
+                case eResultError:
+                    hash_data_offset = UINT32_MAX;
+                    break;
+            }
+        }
+    }
+    die_info_array.swap (pair.value);
+    return die_info_array.size();
+}
+
+size_t
+DWARFMappedHash::MemoryTable::AppendAllDIEsInRange (const uint32_t die_offset_start, 
+                                                    const uint32_t die_offset_end, 
+                                                    DIEInfoArray &die_info_array) const
+{
+    const uint32_t hash_count = m_header.hashes_count;
+    for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
+    {
+        bool done = false;
+        lldb::offset_t hash_data_offset = GetHashDataOffset (offset_idx);
+        while (!done && hash_data_offset != UINT32_MAX)
+        {
+            KeyType key = m_data.GetU32 (&hash_data_offset);
+            // If the key is zero, this terminates our chain of HashData objects
+            // for this hash value.
+            if (key == 0)
+                break;
+            
+            const uint32_t count = m_data.GetU32 (&hash_data_offset);
+            for (uint32_t i=0; i<count; ++i)
+            {
+                DIEInfo die_info;
+                if (m_header.Read(m_data, &hash_data_offset, die_info))
+                {
+                    if (die_info.offset == 0)
+                        done = true;
+                    if (die_offset_start <= die_info.offset && die_info.offset < die_offset_end)
+                        die_info_array.push_back(die_info);
+                }
+            }
+        }
+    }
+    return die_info_array.size();
+}
+
+size_t
+DWARFMappedHash::MemoryTable::FindByName (const char *name, DIEArray &die_offsets)
+{
+    DIEInfoArray die_info_array;
+    if (FindByName(name, die_info_array))
+        DWARFMappedHash::ExtractDIEArray (die_info_array, die_offsets);
+    return die_info_array.size();
+}
+
+size_t
+DWARFMappedHash::MemoryTable::FindByNameAndTag (const char *name,
+                                                const dw_tag_t tag,
+                                                DIEArray &die_offsets)
+{
+    DIEInfoArray die_info_array;
+    if (FindByName(name, die_info_array))
+        DWARFMappedHash::ExtractDIEArray (die_info_array, tag, die_offsets);
+    return die_info_array.size();
+}
+
+size_t
+DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash (const char *name,
+                                                                    const dw_tag_t tag,
+                                                                    const uint32_t qualified_name_hash,
+                                                                    DIEArray &die_offsets)
+{
+    DIEInfoArray die_info_array;
+    if (FindByName(name, die_info_array))
+        DWARFMappedHash::ExtractDIEArray (die_info_array, tag, qualified_name_hash, die_offsets);
+    return die_info_array.size();
+}
+
+size_t
+DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName (const char *name,
+                                                           DIEArray &die_offsets,
+                                                           bool must_be_implementation)
+{
+    DIEInfoArray die_info_array;
+    if (FindByName(name, die_info_array))
+    {
+        if (must_be_implementation && GetHeader().header_data.ContainsAtom (eAtomTypeTypeFlags))
+        {
+            // If we have two atoms, then we have the DIE offset and
+            // the type flags so we can find the objective C class
+            // efficiently.
+            DWARFMappedHash::ExtractTypesFromDIEArray (die_info_array, 
+                                                       UINT32_MAX,
+                                                       eTypeFlagClassIsImplementation,
+                                                       die_offsets);
+        }
+        else
+        {
+            // We don't only want the one true definition, so try and see
+            // what we can find, and only return class or struct DIEs.
+            // If we do have the full implementation, then return it alone,
+            // else return all possible matches.
+            const bool return_implementation_only_if_available = true;
+            DWARFMappedHash::ExtractClassOrStructDIEArray (die_info_array, 
+                                                           return_implementation_only_if_available,
+                                                           die_offsets);
+        }
+    }
+    return die_offsets.size();
+}
+
+size_t 
+DWARFMappedHash::MemoryTable::FindByName (const char *name, DIEInfoArray &die_info_array)
+{
+    Pair kv_pair;
+    size_t old_size = die_info_array.size();
+    if (Find (name, kv_pair))
+    {
+        die_info_array.swap(kv_pair.value);
+        return die_info_array.size() - old_size;
+    }
+    return 0;
+}

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h?rev=247131&r1=247130&r2=247131&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h Wed Sep  9 05:20:36 2015
@@ -12,134 +12,36 @@
 
 #include <vector>
 
-#include "DWARFDefines.h"
-#include "DWARFFormValue.h"
-
 #include "lldb/lldb-defines.h"
 #include "lldb/Core/dwarf.h"
 #include "lldb/Core/RegularExpression.h"
 #include "lldb/Core/MappedHash.h"
 
-struct DWARFMappedHash
-{
-    struct DIEInfo
-    {
-        dw_offset_t offset;  // The DIE offset
-        dw_tag_t tag;
-        uint32_t type_flags; // Any flags for this DIEInfo
-        uint32_t qualified_name_hash; // A 32 bit hash of the fully qualified name
-
-        DIEInfo () :
-            offset (DW_INVALID_OFFSET),
-            tag (0),
-            type_flags (0),
-            qualified_name_hash (0)
-        {
-        }
-
-        DIEInfo (dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h) :
-            offset(o),
-            tag (t),
-            type_flags (f),
-            qualified_name_hash (h)
-        {
-        }
-        
-        void
-        Clear()
-        {
-            offset = DW_INVALID_OFFSET;
-            tag = 0;
-            type_flags = 0;
-            qualified_name_hash = 0;
-        }            
-    };
-    
-    typedef std::vector<DIEInfo> DIEInfoArray;
-    typedef std::vector<uint32_t> DIEArray;
-    
-    static void
-    ExtractDIEArray (const DIEInfoArray &die_info_array,
-                     DIEArray &die_offsets)
-    {
-        const size_t count = die_info_array.size();
-        for (size_t i=0; i<count; ++i)
-        {
-            die_offsets.push_back (die_info_array[i].offset);
-        }
-    }
-
-    static void
-    ExtractDIEArray (const DIEInfoArray &die_info_array,
-                     const dw_tag_t tag,
-                     DIEArray &die_offsets)
-    {
-        if (tag == 0)
-        {
-            ExtractDIEArray (die_info_array, die_offsets);
-        }
-        else
-        {
-            const size_t count = die_info_array.size();
-            for (size_t i=0; i<count; ++i)
-            {
-                const dw_tag_t die_tag = die_info_array[i].tag;
-                bool tag_matches = die_tag == 0 || tag == die_tag;
-                if (!tag_matches)
-                {
-                    if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
-                        tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
-                }
-                if (tag_matches)
-                    die_offsets.push_back (die_info_array[i].offset);
-            }
-        }
-    }
+#include "DWARFDefines.h"
+#include "DWARFFormValue.h"
+#include "NameToDIE.h"
 
-    static void
-    ExtractDIEArray (const DIEInfoArray &die_info_array,
-                     const dw_tag_t tag,
-                     const uint32_t qualified_name_hash,
-                     DIEArray &die_offsets)
-    {
-        if (tag == 0)
-        {
-            ExtractDIEArray (die_info_array, die_offsets);
-        }
-        else
-        {
-            const size_t count = die_info_array.size();
-            for (size_t i=0; i<count; ++i)
-            {
-                if (qualified_name_hash != die_info_array[i].qualified_name_hash)
-                    continue;
-                const dw_tag_t die_tag = die_info_array[i].tag;
-                bool tag_matches = die_tag == 0 || tag == die_tag;
-                if (!tag_matches)
-                {
-                    if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
-                        tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
-                }
-                if (tag_matches)
-                    die_offsets.push_back (die_info_array[i].offset);
-            }
-        }
-    }
+class SymbolFileDWARF;
+class DWARFCompileUnit;
+class DWARFDebugInfoEntry;
 
-    enum AtomType
+class DWARFMappedHash
+{
+public:
+    enum AtomType : uint16_t
     {
-        eAtomTypeNULL       = 0u,
-        eAtomTypeDIEOffset  = 1u,   // DIE offset, check form for encoding
-        eAtomTypeCUOffset   = 2u,   // DIE offset of the compiler unit header that contains the item in question
-        eAtomTypeTag        = 3u,   // DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2
-        eAtomTypeNameFlags  = 4u,   // Flags from enum NameFlags
-        eAtomTypeTypeFlags  = 5u,   // Flags from enum TypeFlags,
+        eAtomTypeNULL         = 0u,
+        eAtomTypeDIEOffset    = 1u, // DIE offset, check form for encoding
+        eAtomTypeCUOffset     = 2u, // DIE offset of the compiler unit header that contains the item in question
+        eAtomTypeTag          = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2
+        eAtomTypeNameFlags    = 4u, // Flags from enum NameFlags
+        eAtomTypeTypeFlags    = 5u, // Flags from enum TypeFlags,
         eAtomTypeQualNameHash = 6u  // A 32 bit hash of the full qualified name (since all hash entries are basename only)
                                     // For example a type like "std::vector<int>::iterator" would have a name of "iterator"
                                     // and a 32 bit hash for "std::vector<int>::iterator" to allow us to not have to pull
                                     // in debug info for a type when we know the fully qualified name.
     };
-    
+
     // Bit definitions for the eAtomTypeTypeFlags flags
     enum TypeFlags
     {
@@ -147,719 +49,172 @@ struct DWARFMappedHash
         // @implementation for class
         eTypeFlagClassIsImplementation  = ( 1u << 1 )
     };
-    
 
-    static void
-    ExtractClassOrStructDIEArray (const DIEInfoArray &die_info_array,
-                                  bool return_implementation_only_if_available,
-                                  DIEArray &die_offsets)
+    struct DIEInfo
     {
-        const size_t count = die_info_array.size();
-        for (size_t i=0; i<count; ++i)
-        {
-            const dw_tag_t die_tag = die_info_array[i].tag;
-            if (die_tag == 0 || die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
-            {
-                if (die_info_array[i].type_flags & eTypeFlagClassIsImplementation)
-                {
-                    if (return_implementation_only_if_available)
-                    {
-                        // We found the one true definition for this class, so
-                        // only return that
-                        die_offsets.clear();                        
-                        die_offsets.push_back (die_info_array[i].offset);
-                        return;
-                    }
-                    else
-                    {
-                        // Put the one true definition as the first entry so it
-                        // matches first
-                        die_offsets.insert (die_offsets.begin(), die_info_array[i].offset);
-                    }
-                }
-                else
-                {
-                    die_offsets.push_back (die_info_array[i].offset);
-                }
-            }
-        }
-    }
+        dw_offset_t offset;  // The DIE offset
+        dw_tag_t tag;
+        uint32_t type_flags; // Any flags for this DIEInfo
+        uint32_t qualified_name_hash; // A 32 bit hash of the fully qualified name
 
-    static void
-    ExtractTypesFromDIEArray (const DIEInfoArray &die_info_array,
-                              uint32_t type_flag_mask,
-                              uint32_t type_flag_value,
-                              DIEArray &die_offsets)
-    {
-        const size_t count = die_info_array.size();
-        for (size_t i=0; i<count; ++i)
-        {
-            if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value)
-                die_offsets.push_back (die_info_array[i].offset);
-        }
-    }
+        DIEInfo ();
+        DIEInfo (dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h);
+    };
 
     struct Atom
     {
-        uint16_t type;
+        AtomType type;
         dw_form_t form;
-        
-        Atom (uint16_t t = eAtomTypeNULL, dw_form_t f = 0) :
-            type (t),
-            form (f)
-        {
-        }
     };
-    
+
+    typedef std::vector<DIEInfo> DIEInfoArray;
     typedef std::vector<Atom> AtomArray;
 
-    static const char *
-    GetAtomTypeName (uint16_t atom)
-    {
-        switch (atom)
-        {
-            case eAtomTypeNULL:         return "NULL";
-            case eAtomTypeDIEOffset:    return "die-offset";
-            case eAtomTypeCUOffset:     return "cu-offset";
-            case eAtomTypeTag:          return "die-tag";
-            case eAtomTypeNameFlags:    return "name-flags";
-            case eAtomTypeTypeFlags:    return "type-flags";
-            case eAtomTypeQualNameHash: return "qualified-name-hash";
-        }
-        return "<invalid>";
-    }
-    struct Prologue
+    class Prologue
     {
-        // DIE offset base so die offsets in hash_data can be CU relative
-        dw_offset_t die_base_offset;
-        AtomArray atoms;
-        uint32_t atom_mask;
-        size_t min_hash_data_byte_size;
-        bool hash_data_has_fixed_byte_size;
-        
-        Prologue (dw_offset_t _die_base_offset = 0) :
-            die_base_offset (_die_base_offset),
-            atoms(),
-            atom_mask (0),
-            min_hash_data_byte_size(0),
-            hash_data_has_fixed_byte_size(true)
-        {
-            // Define an array of DIE offsets by first defining an array, 
-            // and then define the atom type for the array, in this case
-            // we have an array of DIE offsets
-            AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4);
-        }
-        
-        virtual ~Prologue()
-        {
-        }
+    public:
+        Prologue (dw_offset_t _die_base_offset = 0);
 
         void
-        ClearAtoms ()
-        {
-            hash_data_has_fixed_byte_size = true;
-            min_hash_data_byte_size = 0;
-            atom_mask = 0;
-            atoms.clear();
-        }
+        ClearAtoms ();
 
         bool
-        ContainsAtom (AtomType atom_type) const
-        {
-            return (atom_mask & (1u << atom_type)) != 0;
-        }
-
-        virtual void
-        Clear ()
-        {
-            die_base_offset = 0;
-            ClearAtoms ();
-        }
-        
+        ContainsAtom (AtomType atom_type) const;
+
         void
-        AppendAtom (AtomType type, dw_form_t form)
-        {
-            atoms.push_back (Atom(type, form));
-            atom_mask |= 1u << type;
-            switch (form)
-            {
-                case DW_FORM_indirect:
-                case DW_FORM_exprloc:
-                case DW_FORM_flag_present:
-                case DW_FORM_ref_sig8:
-                    assert (!"Unhandled atom form");
-                    break;
-
-                case DW_FORM_string:
-                case DW_FORM_block:
-                case DW_FORM_block1:
-                case DW_FORM_sdata:
-                case DW_FORM_udata:
-                case DW_FORM_ref_udata:
-                case DW_FORM_GNU_addr_index:
-                case DW_FORM_GNU_str_index:
-                    hash_data_has_fixed_byte_size = false;
-                    // Fall through to the cases below...
-                case DW_FORM_flag:
-                case DW_FORM_data1:
-                case DW_FORM_ref1:
-                case DW_FORM_sec_offset:
-                    min_hash_data_byte_size += 1; 
-                    break;
-
-                case DW_FORM_block2:
-                    hash_data_has_fixed_byte_size = false;
-                    // Fall through to the cases below...
-                case DW_FORM_data2: 
-                case DW_FORM_ref2:
-                    min_hash_data_byte_size += 2; 
-                    break;
-
-                case DW_FORM_block4: 
-                    hash_data_has_fixed_byte_size = false;
-                    // Fall through to the cases below...
-                case DW_FORM_data4:
-                case DW_FORM_ref4:
-                case DW_FORM_addr:
-                case DW_FORM_ref_addr:
-                case DW_FORM_strp:
-                    min_hash_data_byte_size += 4; 
-                    break;
-
-                case DW_FORM_data8:
-                case DW_FORM_ref8:
-                    min_hash_data_byte_size += 8; 
-                    break;
-                    
-            }
-        }
-        
-//        void
-//        Dump (std::ostream* ostrm_ptr);        
-        
+        Clear ();
+
+        void
+        AppendAtom (AtomType type, dw_form_t form);
+
         lldb::offset_t
-        Read (const lldb_private::DataExtractor &data,
-              lldb::offset_t offset)
-        {
-            ClearAtoms ();
-            
-            die_base_offset = data.GetU32 (&offset);
-            
-            const uint32_t atom_count = data.GetU32 (&offset);
-            if (atom_count == 0x00060003u)
-            {
-                // Old format, deal with contents of old pre-release format
-                while (data.GetU32(&offset))
-                    /* do nothing */;
-
-                // Hardcode to the only known value for now.
-                AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4);
-            }
-            else
-            {
-                for (uint32_t i=0; i<atom_count; ++i)
-                {
-                    AtomType type = (AtomType)data.GetU16 (&offset);
-                    dw_form_t form = (dw_form_t)data.GetU16 (&offset);                    
-                    AppendAtom (type, form);
-                }
-            }
-            return offset;
-        }
-        
-//        virtual void
-//        Write (BinaryStreamBuf &s);
-        
+        Read (const lldb_private::DataExtractor &data, lldb::offset_t offset);
+
         size_t
-        GetByteSize () const
-        {
-            // Add an extra count to the atoms size for the zero termination Atom that gets
-            // written to disk
-            return sizeof(die_base_offset) + sizeof(uint32_t) + atoms.size() * sizeof(Atom);
-        }
-        
+        GetByteSize () const;
+
         size_t
-        GetMinimumHashDataByteSize () const
-        {
-            return min_hash_data_byte_size;
-        }
+        GetMinimumHashDataByteSize () const;
 
         bool
-        HashDataHasFixedByteSize() const
-        {
-            return hash_data_has_fixed_byte_size;
-        }
+        HashDataHasFixedByteSize() const;
+
+        // DIE offset base so die offsets in hash_data can be CU relative
+        dw_offset_t die_base_offset;
+        AtomArray atoms;
+        uint32_t atom_mask;
+        size_t min_hash_data_byte_size;
+        bool hash_data_has_fixed_byte_size;
     };
     
-    struct Header : public MappedHash::Header<Prologue>
+    class Header : public MappedHash::Header<Prologue>
     {
-        Header (dw_offset_t _die_base_offset = 0)
-        {
-        }
-        
-        virtual 
-        ~Header()
-        {
-        }
-
-        virtual size_t
-        GetByteSize (const HeaderData &header_data)
-        {
-            return header_data.GetByteSize();
-        }
-
-        //        virtual void
-        //        Dump (std::ostream* ostrm_ptr);        
-        //        
-        virtual lldb::offset_t
-        Read (lldb_private::DataExtractor &data, lldb::offset_t offset)
-        {
-            offset = MappedHash::Header<Prologue>::Read (data, offset);
-            if (offset != UINT32_MAX)
-            {
-                offset = header_data.Read (data, offset);
-            }
-            return offset;
-        }
-        
+    public:
+        size_t
+        GetByteSize (const HeaderData &header_data) override;
+
+        lldb::offset_t
+        Read (lldb_private::DataExtractor &data, lldb::offset_t offset) override;
+
         bool
         Read (const lldb_private::DWARFDataExtractor &data, 
               lldb::offset_t *offset_ptr, 
-              DIEInfo &hash_data) const
-        {
-            const size_t num_atoms = header_data.atoms.size();
-            if (num_atoms == 0)
-                return false;
-            
-            for (size_t i=0; i<num_atoms; ++i)
-            {
-                DWARFFormValue form_value (NULL, header_data.atoms[i].form);
-                
-                if (!form_value.ExtractValue(data, offset_ptr))
-                    return false;
-                
-                switch (header_data.atoms[i].type)
-                {
-                    case eAtomTypeDIEOffset:    // DIE offset, check form for encoding
-                        hash_data.offset = (dw_offset_t)form_value.Reference (header_data.die_base_offset);
-                        break;
-
-                    case eAtomTypeTag:          // DW_TAG value for the DIE
-                        hash_data.tag = (dw_tag_t)form_value.Unsigned ();
-                        
-                    case eAtomTypeTypeFlags:    // Flags from enum TypeFlags
-                        hash_data.type_flags = (uint32_t)form_value.Unsigned ();
-                        break;
-
-                    case eAtomTypeQualNameHash:    // Flags from enum TypeFlags
-                        hash_data.qualified_name_hash = form_value.Unsigned ();
-                        break;
-
-                    default:
-                        // We can always skip atoms we don't know about
-                        break;
-                }
-            }
-            return true;
-        }
-        
+              DIEInfo &hash_data) const;
+
         void
-        Dump (lldb_private::Stream& strm, const DIEInfo &hash_data) const
-        {
-            const size_t num_atoms = header_data.atoms.size();
-            for (size_t i=0; i<num_atoms; ++i)
-            {
-                if (i > 0)
-                    strm.PutCString (", ");
-                
-                DWARFFormValue form_value (NULL, header_data.atoms[i].form);
-                switch (header_data.atoms[i].type)
-                {
-                    case eAtomTypeDIEOffset:    // DIE offset, check form for encoding
-                        strm.Printf ("{0x%8.8x}", hash_data.offset);
-                        break;
-
-                    case eAtomTypeTag:          // DW_TAG value for the DIE
-                        {
-                            const char *tag_cstr = lldb_private::DW_TAG_value_to_name (hash_data.tag);
-                            if (tag_cstr)
-                                strm.PutCString (tag_cstr);
-                            else
-                                strm.Printf ("DW_TAG_(0x%4.4x)", hash_data.tag);
-                        }
-                        break;
-
-                    case eAtomTypeTypeFlags:    // Flags from enum TypeFlags
-                        strm.Printf ("0x%2.2x", hash_data.type_flags);
-                        if (hash_data.type_flags)
-                        {
-                            strm.PutCString (" (");
-                            if (hash_data.type_flags & eTypeFlagClassIsImplementation)
-                                strm.PutCString (" implementation");
-                            strm.PutCString (" )");
-                        }
-                        break;
-
-                    case eAtomTypeQualNameHash:    // Flags from enum TypeFlags
-                        strm.Printf ("0x%8.8x", hash_data.qualified_name_hash);
-                        break;
-
-                    default:
-                        strm.Printf ("AtomType(0x%x)", header_data.atoms[i].type);
-                        break;
-                }
-            }
-        }
+        Dump (lldb_private::Stream& strm, const DIEInfo &hash_data) const;
     };
-    
+
     // A class for reading and using a saved hash table from a block of data
     // in memory
     class MemoryTable : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header, DIEInfoArray>
     {
     public:
-        
         MemoryTable (lldb_private::DWARFDataExtractor &table_data, 
                      const lldb_private::DWARFDataExtractor &string_table,
-                     const char *name) :
-            MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray> (table_data),
-            m_data (table_data),
-            m_string_table (string_table),
-            m_name (name)
-        {
-        }
-    
-        virtual 
-        ~MemoryTable ()
-        {
-        }
-
-        virtual const char *
-        GetStringForKeyType (KeyType key) const
-        {
-            // The key in the DWARF table is the .debug_str offset for the string
-            return m_string_table.PeekCStr (key);
-        }
-        
-        virtual bool
-        ReadHashData (uint32_t hash_data_offset,
-                      HashData &hash_data) const
-        {
-            lldb::offset_t offset = hash_data_offset;
-            offset += 4; // Skip string table offset that contains offset of hash name in .debug_str
-            const uint32_t count = m_data.GetU32 (&offset);
-            if (count > 0)
-            {
-                hash_data.resize(count);
-                for (uint32_t i=0; i<count; ++i)
-                {
-                    if (!m_header.Read(m_data, &offset, hash_data[i]))
-                        return false;
-                }
-            }
-            else
-                hash_data.clear();
-            return true;
-        }
+                     const char *name);
 
-        virtual Result
-        GetHashDataForName (const char *name,
-                            lldb::offset_t* hash_data_offset_ptr,
-                            Pair &pair) const
-        {
-            pair.key = m_data.GetU32 (hash_data_offset_ptr);
-            pair.value.clear();
-
-            // If the key is zero, this terminates our chain of HashData objects
-            // for this hash value.
-            if (pair.key == 0)
-                return eResultEndOfHashData;
-
-            // There definitely should be a string for this string offset, if
-            // there isn't, there is something wrong, return and error
-            const char *strp_cstr = m_string_table.PeekCStr (pair.key);
-            if (strp_cstr == NULL)
-            {
-                *hash_data_offset_ptr = UINT32_MAX;
-                return eResultError;
-            }
-
-            const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
-            const size_t min_total_hash_data_size = count * m_header.header_data.GetMinimumHashDataByteSize();
-            if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size))
-            {
-                // We have at least one HashData entry, and we have enough
-                // data to parse at least "count" HashData entries.
-                
-                // First make sure the entire C string matches...
-                const bool match = strcmp (name, strp_cstr) == 0;
-                
-                if (!match && m_header.header_data.HashDataHasFixedByteSize())
-                {
-                    // If the string doesn't match and we have fixed size data,
-                    // we can just add the total byte size of all HashData objects
-                    // to the hash data offset and be done...
-                    *hash_data_offset_ptr += min_total_hash_data_size;
-                }
-                else
-                {
-                    // If the string does match, or we don't have fixed size data
-                    // then we need to read the hash data as a stream. If the
-                    // string matches we also append all HashData objects to the
-                    // value array.
-                    for (uint32_t i=0; i<count; ++i)
-                    {
-                        DIEInfo die_info;
-                        if (m_header.Read(m_data, hash_data_offset_ptr, die_info))
-                        {
-                            // Only happened if the HashData of the string matched...
-                            if (match)
-                                pair.value.push_back (die_info);
-                        }
-                        else
-                        {
-                            // Something went wrong while reading the data
-                            *hash_data_offset_ptr = UINT32_MAX;
-                            return eResultError;
-                        }
-                    }
-                }
-                // Return the correct response depending on if the string matched
-                // or not...
-                if (match)
-                    return eResultKeyMatch;     // The key (cstring) matches and we have lookup results!
-                else
-                    return eResultKeyMismatch;  // The key doesn't match, this function will get called 
-                                                // again for the next key/value or the key terminator
-                                                // which in our case is a zero .debug_str offset.
-            }
-            else
-            {
-                *hash_data_offset_ptr = UINT32_MAX;
-                return eResultError;
-            }
-        }
-
-        virtual Result
-        AppendHashDataForRegularExpression (const lldb_private::RegularExpression& regex,
-                                            lldb::offset_t* hash_data_offset_ptr, 
-                                            Pair &pair) const
-        {
-            pair.key = m_data.GetU32 (hash_data_offset_ptr);
-            // If the key is zero, this terminates our chain of HashData objects
-            // for this hash value.
-            if (pair.key == 0)
-                return eResultEndOfHashData;
-            
-            // There definitely should be a string for this string offset, if
-            // there isn't, there is something wrong, return and error
-            const char *strp_cstr = m_string_table.PeekCStr (pair.key);
-            if (strp_cstr == NULL)
-                return eResultError;
-            
-            const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
-            const size_t min_total_hash_data_size = count * m_header.header_data.GetMinimumHashDataByteSize();
-            if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size))
-            {
-                const bool match = regex.Execute(strp_cstr);
-                
-                if (!match && m_header.header_data.HashDataHasFixedByteSize())
-                {
-                    // If the regex doesn't match and we have fixed size data,
-                    // we can just add the total byte size of all HashData objects
-                    // to the hash data offset and be done...
-                    *hash_data_offset_ptr += min_total_hash_data_size;
-                }
-                else
-                {
-                    // If the string does match, or we don't have fixed size data
-                    // then we need to read the hash data as a stream. If the
-                    // string matches we also append all HashData objects to the
-                    // value array.
-                    for (uint32_t i=0; i<count; ++i)
-                    {
-                        DIEInfo die_info;
-                        if (m_header.Read(m_data, hash_data_offset_ptr, die_info))
-                        {
-                            // Only happened if the HashData of the string matched...
-                            if (match)
-                                pair.value.push_back (die_info);
-                        }
-                        else
-                        {
-                            // Something went wrong while reading the data
-                            *hash_data_offset_ptr = UINT32_MAX;
-                            return eResultError;
-                        }
-                    }
-                }
-                // Return the correct response depending on if the string matched
-                // or not...
-                if (match)
-                    return eResultKeyMatch;     // The key (cstring) matches and we have lookup results!
-                else
-                    return eResultKeyMismatch;  // The key doesn't match, this function will get called 
-                                                // again for the next key/value or the key terminator
-                                                // which in our case is a zero .debug_str offset.
-            }
-            else
-            {
-                *hash_data_offset_ptr = UINT32_MAX;
-                return eResultError;
-            }
-        }
+        const char *
+        GetStringForKeyType (KeyType key) const override;
+        
+        bool
+        ReadHashData (uint32_t hash_data_offset, HashData &hash_data) const override;
 
         size_t
         AppendAllDIEsThatMatchingRegex (const lldb_private::RegularExpression& regex, 
-                                        DIEInfoArray &die_info_array) const
-        {
-            const uint32_t hash_count = m_header.hashes_count;
-            Pair pair;
-            for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
-            {
-                lldb::offset_t hash_data_offset = GetHashDataOffset (offset_idx);
-                while (hash_data_offset != UINT32_MAX)
-                {
-                    const lldb::offset_t prev_hash_data_offset = hash_data_offset;
-                    Result hash_result = AppendHashDataForRegularExpression (regex, &hash_data_offset, pair);
-                    if (prev_hash_data_offset == hash_data_offset)
-                        break;
-
-                    // Check the result of getting our hash data
-                    switch (hash_result)
-                    {
-                        case eResultKeyMatch:
-                        case eResultKeyMismatch:
-                            // Whether we matches or not, it doesn't matter, we
-                            // keep looking.
-                            break;
-                            
-                        case eResultEndOfHashData:
-                        case eResultError:
-                            hash_data_offset = UINT32_MAX;
-                            break;
-                    }
-                }
-            }
-            die_info_array.swap (pair.value);
-            return die_info_array.size();
-        }
-        
+                                        DIEInfoArray &die_info_array) const;
+
         size_t
         AppendAllDIEsInRange (const uint32_t die_offset_start, 
                               const uint32_t die_offset_end, 
-                              DIEInfoArray &die_info_array) const
-        {
-            const uint32_t hash_count = m_header.hashes_count;
-            for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
-            {
-                bool done = false;
-                lldb::offset_t hash_data_offset = GetHashDataOffset (offset_idx);
-                while (!done && hash_data_offset != UINT32_MAX)
-                {
-                    KeyType key = m_data.GetU32 (&hash_data_offset);
-                    // If the key is zero, this terminates our chain of HashData objects
-                    // for this hash value.
-                    if (key == 0)
-                        break;
-                    
-                    const uint32_t count = m_data.GetU32 (&hash_data_offset);
-                    for (uint32_t i=0; i<count; ++i)
-                    {
-                        DIEInfo die_info;
-                        if (m_header.Read(m_data, &hash_data_offset, die_info))
-                        {
-                            if (die_info.offset == 0)
-                                done = true;
-                            if (die_offset_start <= die_info.offset && die_info.offset < die_offset_end)
-                                die_info_array.push_back(die_info);
-                        }
-                    }
-                }
-            }
-            return die_info_array.size();
-        }
+                              DIEInfoArray &die_info_array) const;
 
         size_t
-        FindByName (const char *name, DIEArray &die_offsets)
-        {
-            DIEInfoArray die_info_array;
-            if (FindByName(name, die_info_array))
-                DWARFMappedHash::ExtractDIEArray (die_info_array, die_offsets);
-            return die_info_array.size();
-        }
+        FindByName (const char *name, DIEArray &die_offsets);
 
         size_t
-        FindByNameAndTag (const char *name, 
-                          const dw_tag_t tag, 
-                          DIEArray &die_offsets)
-        {
-            DIEInfoArray die_info_array;
-            if (FindByName(name, die_info_array))
-                DWARFMappedHash::ExtractDIEArray (die_info_array, tag, die_offsets);
-            return die_info_array.size();
-        }
+        FindByNameAndTag (const char *name, const dw_tag_t tag, DIEArray &die_offsets);
 
         size_t
         FindByNameAndTagAndQualifiedNameHash (const char *name,
                                               const dw_tag_t tag,
                                               const uint32_t qualified_name_hash,
-                                              DIEArray &die_offsets)
-        {
-            DIEInfoArray die_info_array;
-            if (FindByName(name, die_info_array))
-                DWARFMappedHash::ExtractDIEArray (die_info_array, tag, qualified_name_hash, die_offsets);
-            return die_info_array.size();
-        }
+                                              DIEArray &die_offsets);
 
         size_t
-        FindCompleteObjCClassByName (const char *name, DIEArray &die_offsets, bool must_be_implementation)
-        {
-            DIEInfoArray die_info_array;
-            if (FindByName(name, die_info_array))
-            {
-                if (must_be_implementation && GetHeader().header_data.ContainsAtom (eAtomTypeTypeFlags))
-                {
-                    // If we have two atoms, then we have the DIE offset and
-                    // the type flags so we can find the objective C class
-                    // efficiently.
-                    DWARFMappedHash::ExtractTypesFromDIEArray (die_info_array, 
-                                                               UINT32_MAX,
-                                                               eTypeFlagClassIsImplementation,
-                                                               die_offsets);
-                }
-                else
-                {
-                    // We don't only want the one true definition, so try and see
-                    // what we can find, and only return class or struct DIEs.
-                    // If we do have the full implementation, then return it alone,
-                    // else return all possible matches.
-                    const bool return_implementation_only_if_available = true;
-                    DWARFMappedHash::ExtractClassOrStructDIEArray (die_info_array, 
-                                                                   return_implementation_only_if_available,
-                                                                   die_offsets);
-                }
-            }
-            return die_offsets.size();
-        }
+        FindCompleteObjCClassByName (const char *name,
+                                     DIEArray &die_offsets,
+                                     bool must_be_implementation);
 
-        size_t 
-        FindByName (const char *name, DIEInfoArray &die_info_array)
-        {
-            Pair kv_pair;
-            size_t old_size = die_info_array.size();
-            if (Find (name, kv_pair))
-            {
-                die_info_array.swap(kv_pair.value);
-                return die_info_array.size() - old_size;
-            }
-            return 0;
-        }
-        
     protected:
+        Result
+        AppendHashDataForRegularExpression (const lldb_private::RegularExpression& regex,
+                                            lldb::offset_t* hash_data_offset_ptr, 
+                                            Pair &pair) const;
+
+        size_t 
+        FindByName (const char *name, DIEInfoArray &die_info_array);
+
+        Result
+        GetHashDataForName (const char *name,
+                            lldb::offset_t* hash_data_offset_ptr,
+                            Pair &pair) const;
+
         const lldb_private::DWARFDataExtractor &m_data;
         const lldb_private::DWARFDataExtractor &m_string_table;
         std::string m_name;
     };
+
+    static void
+    ExtractDIEArray (const DIEInfoArray &die_info_array, DIEArray &die_offsets);
+
+protected:
+    static void
+    ExtractDIEArray (const DIEInfoArray &die_info_array,
+                     const dw_tag_t tag,
+                     DIEArray &die_offsets);
+
+    static void
+    ExtractDIEArray (const DIEInfoArray &die_info_array,
+                     const dw_tag_t tag,
+                     const uint32_t qualified_name_hash,
+                     DIEArray &die_offsets);
+
+    
+
+    static void
+    ExtractClassOrStructDIEArray (const DIEInfoArray &die_info_array,
+                                  bool return_implementation_only_if_available,
+                                  DIEArray &die_offsets);
+
+    static void
+    ExtractTypesFromDIEArray (const DIEInfoArray &die_info_array,
+                              uint32_t type_flag_mask,
+                              uint32_t type_flag_value,
+                              DIEArray &die_offsets);
+
+    static const char *
+    GetAtomTypeName (uint16_t atom);
 };
 
 

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=247131&r1=247130&r2=247131&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Wed Sep  9 05:20:36 2015
@@ -1526,13 +1526,9 @@ SymbolFileDWARF::CompleteType (CompilerT
                                                                   dwarf_die.GetTagAsCString(),
                                                                   type->GetName().AsCString());
     assert (clang_type);
-    DWARFAttributes attributes;
-
-
     DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
     if (dwarf_ast)
         return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, clang_type);
-
     return false;
 }
 




More information about the lldb-commits mailing list