summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2013-02-06 23:56:13 +0000
committerGreg Clayton <gclayton@apple.com>2013-02-06 23:56:13 +0000
commitcb9c8cf84cd22b520d13b8b664e8e557507bded7 (patch)
treef6c1963d09a515c89dc40d613dea6c9587479983
parentc3a1d5629acd8e0226fc929330e3234a39e908e1 (diff)
downloadbcm5719-llvm-cb9c8cf84cd22b520d13b8b664e8e557507bded7.tar.gz
bcm5719-llvm-cb9c8cf84cd22b520d13b8b664e8e557507bded7.zip
Be ready for fully qualified hash names in the __apples_types tables.
llvm-svn: 174558
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h73
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp33
2 files changed, 97 insertions, 9 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
index 8ed2e50dcfc..4b8a1fd8a30 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -32,18 +32,21 @@ struct DWARFMappedHash
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)
+ type_flags (0),
+ qualified_name_hash (0)
{
}
- DIEInfo (dw_offset_t o, dw_tag_t t, uint32_t f) :
+ DIEInfo (dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h) :
offset(o),
tag (t),
- type_flags (f)
+ type_flags (f),
+ qualified_name_hash (h)
{
}
@@ -53,6 +56,7 @@ struct DWARFMappedHash
offset = DW_INVALID_OFFSET;
tag = 0;
type_flags = 0;
+ qualified_name_hash = 0;
}
};
@@ -96,6 +100,37 @@ struct DWARFMappedHash
}
}
}
+
+ 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);
+ }
+ }
+ }
+
enum AtomType
{
eAtomTypeNULL = 0u,
@@ -103,7 +138,11 @@ struct DWARFMappedHash
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
+ 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
@@ -196,6 +235,7 @@ struct DWARFMappedHash
case eAtomTypeTag: return "die-tag";
case eAtomTypeNameFlags: return "name-flags";
case eAtomTypeTypeFlags: return "type-flags";
+ case eAtomTypeQualNameHash: return "qualified-name-hash";
}
return "<invalid>";
}
@@ -419,8 +459,13 @@ struct DWARFMappedHash
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:
- return false;
+ // We can always skip atomes we don't know about
break;
}
}
@@ -463,7 +508,11 @@ struct DWARFMappedHash
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;
@@ -797,6 +846,18 @@ struct DWARFMappedHash
}
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();
+ }
+
+ size_t
FindCompleteObjCClassByName (const char *name, DIEArray &die_offsets, bool must_be_implementation)
{
DIEInfoArray die_info_array;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index a5c17e1bb47..f64cdb88986 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -4855,10 +4855,11 @@ SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu,
if (cu == NULL || die == NULL || !type_name)
return type_sp;
+ std::string qualified_name;
+
LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
if (log)
{
- std::string qualified_name;
die->GetQualifiedName(this, cu, qualified_name);
GetObjectFile()->GetModule()->LogMessage (log.get(),
"SymbolFileDWARF::FindDefinitionTypeForDIE(die=0x%8.8x (%s), name='%s')",
@@ -4873,8 +4874,22 @@ SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu,
{
if (m_apple_types_ap.get())
{
- if (m_apple_types_ap->GetHeader().header_data.atoms.size() > 1)
+ const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
+ const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
+ if (has_tag && has_qualified_name_hash)
+ {
+ if (qualified_name.empty())
+ die->GetQualifiedName(this, cu, qualified_name);
+
+ const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name.c_str());
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log.get(),"FindByNameAndTagAndQualifiedNameHash()");
+ m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), die->Tag(), qualified_name_hash, die_offsets);
+ }
+ else if (has_tag > 1)
{
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log.get(),"FindByNameAndTag()");
m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), die->Tag(), die_offsets);
}
else
@@ -5033,8 +5048,20 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &
{
if (m_apple_types_ap.get())
{
- if (m_apple_types_ap->GetHeader().header_data.atoms.size() > 1)
+ const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
+ const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
+ if (has_tag && has_qualified_name_hash)
{
+ const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
+ const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name);
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log.get(),"FindByNameAndTagAndQualifiedNameHash()");
+ m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets);
+ }
+ else if (has_tag)
+ {
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log.get(),"FindByNameAndTag()");
m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets);
}
else
OpenPOWER on IntegriCloud