diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF')
4 files changed, 313 insertions, 86 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index bb0182c6855..c1848f6ee9f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -179,7 +179,8 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) : m_namespace_index(), m_indexed (false), m_is_external_ast_source (false), - m_ranges() + m_ranges()//, + //m_unique_ast_type_map () { } @@ -3168,101 +3169,134 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, } } - DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr); - - int tag_decl_kind = -1; - AccessType default_accessibility = eAccessNone; - if (tag == DW_TAG_structure_type) - { - tag_decl_kind = clang::TTK_Struct; - default_accessibility = eAccessPublic; - } - else if (tag == DW_TAG_union_type) - { - tag_decl_kind = clang::TTK_Union; - default_accessibility = eAccessPublic; - } - else if (tag == DW_TAG_class_type) +// UniqueDWARFASTType unique_ast_entry; +// if (decl.IsValid()) +// { +// if (m_unique_ast_type_map.Find (type_name_const_str, +// die, +// decl, +// unique_ast_entry)) +// { +// // We have already parsed this type or from another +// // compile unit. GCC loves to use the "one definition +// // rule" which can result in multiple definitions +// // of the same class over and over in each compile +// // unit. +// type_sp = unique_ast_entry.m_type_sp; +// } +// } +// +// if (type_sp) +// { +// m_die_to_type[die] = type_sp.get(); +// +// } +// else { - tag_decl_kind = clang::TTK_Class; - default_accessibility = eAccessPrivate; - } + DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr); + int tag_decl_kind = -1; + AccessType default_accessibility = eAccessNone; + if (tag == DW_TAG_structure_type) + { + tag_decl_kind = clang::TTK_Struct; + default_accessibility = eAccessPublic; + } + else if (tag == DW_TAG_union_type) + { + tag_decl_kind = clang::TTK_Union; + default_accessibility = eAccessPublic; + } + else if (tag == DW_TAG_class_type) + { + tag_decl_kind = clang::TTK_Class; + default_accessibility = eAccessPrivate; + } - if (is_forward_declaration) - { - // We have a forward declaration to a type and we need - // to try and find a full declaration. We look in the - // current type index just in case we have a forward - // declaration followed by an actual declarations in the - // DWARF. If this fails, we need to look elsewhere... - - type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); - if (!type_sp && m_debug_map_symfile) + if (is_forward_declaration) { - // We weren't able to find a full declaration in - // this DWARF, see if we have a declaration anywhere - // else... - type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); - } + // We have a forward declaration to a type and we need + // to try and find a full declaration. We look in the + // current type index just in case we have a forward + // declaration followed by an actual declarations in the + // DWARF. If this fails, we need to look elsewhere... + + type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); - if (type_sp) + if (!type_sp && m_debug_map_symfile) + { + // We weren't able to find a full declaration in + // this DWARF, see if we have a declaration anywhere + // else... + type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); + } + + if (type_sp) + { + // We found a real definition for this type elsewhere + // so lets use it and cache the fact that we found + // a complete type for this die + m_die_to_type[die] = type_sp.get(); + return type_sp; + } + } + assert (tag_decl_kind != -1); + bool clang_type_was_created = false; + clang_type = m_forward_decl_die_to_clang_type.lookup (die); + if (clang_type == NULL) { - // We found a real definition for this type elsewhere - // so lets use it and cache the fact that we found - // a complete type for this die - m_die_to_type[die] = type_sp.get(); - return type_sp; + clang_type_was_created = true; + clang_type = ast.CreateRecordType (type_name_cstr, + tag_decl_kind, + GetClangDeclContextForDIE (dwarf_cu, die), + class_language); } - } - assert (tag_decl_kind != -1); - bool clang_type_was_created = false; - clang_type = m_forward_decl_die_to_clang_type.lookup (die); - if (clang_type == NULL) - { - clang_type_was_created = true; - clang_type = ast.CreateRecordType (type_name_cstr, - tag_decl_kind, - GetClangDeclContextForDIE (dwarf_cu, die), - class_language); - } - // Store a forward declaration to this class type in case any - // parameters in any class methods need it for the clang - // types for function prototypes. - m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type); - type_sp.reset (new Type (die->GetOffset(), - this, - type_name_const_str, - byte_size, - NULL, - LLDB_INVALID_UID, - Type::eEncodingIsUID, - &decl, - clang_type, - Type::eResolveStateForward)); - - m_die_to_type[die] = type_sp.get(); + // Store a forward declaration to this class type in case any + // parameters in any class methods need it for the clang + // types for function prototypes. + m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type); + type_sp.reset (new Type (die->GetOffset(), + this, + type_name_const_str, + byte_size, + NULL, + LLDB_INVALID_UID, + Type::eEncodingIsUID, + &decl, + clang_type, + Type::eResolveStateForward)); - if (die->HasChildren() == false && is_forward_declaration == false) - { - // No children for this struct/union/class, lets finish it - ast.StartTagDeclarationDefinition (clang_type); - ast.CompleteTagDeclarationDefinition (clang_type); - } - else if (clang_type_was_created) - { - // Leave this as a forward declaration until we need - // to know the details of the type. lldb_private::Type - // will automatically call the SymbolFile virtual function - // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)" - // When the definition needs to be defined. - m_forward_decl_die_to_clang_type[die] = clang_type; - m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die; - ClangASTContext::SetHasExternalStorage (clang_type, true); + m_die_to_type[die] = type_sp.get(); + + // Add our type to the unique type map so we don't + // end up creating many copies of the same type over + // and over in the ASTContext for our module +// unique_ast_entry.m_type_sp = type_sp; +// unique_ast_entry.m_die = die; +// unique_ast_entry.m_declaration = decl; +// m_unique_ast_type_map.Insert (type_name_const_str, +// unique_ast_entry); + + if (die->HasChildren() == false && is_forward_declaration == false) + { + // No children for this struct/union/class, lets finish it + ast.StartTagDeclarationDefinition (clang_type); + ast.CompleteTagDeclarationDefinition (clang_type); + } + else if (clang_type_was_created) + { + // Leave this as a forward declaration until we need + // to know the details of the type. lldb_private::Type + // will automatically call the SymbolFile virtual function + // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)" + // When the definition needs to be defined. + m_forward_decl_die_to_clang_type[die] = clang_type; + m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die; + ClangASTContext::SetHasExternalStorage (clang_type, true); + } } - } break; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index d0d51b17572..b46b5c95133 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -32,6 +32,7 @@ // Project includes #include "DWARFDefines.h" #include "NameToDIE.h" +//#include "UniqueDWARFASTType.h" //---------------------------------------------------------------------- @@ -350,7 +351,7 @@ protected: m_is_external_ast_source:1; std::auto_ptr<DWARFDebugRanges> m_ranges; - +// UniqueDWARFASTTypeMap m_unique_ast_type_map; typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> DIEToDeclContextMap; typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr; typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> DIEToVariableSP; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp new file mode 100644 index 00000000000..446cfeb2ab0 --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp @@ -0,0 +1,41 @@ +//===-- UniqueDWARFASTType.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "UniqueDWARFASTType.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Symbol/Declaration.h" + +#include "DWARFDebugInfoEntry.h" + +bool +UniqueDWARFASTTypeList::Find +( + const DWARFDebugInfoEntry *die, + const lldb_private::Declaration &decl, + UniqueDWARFASTType &entry +) const +{ + collection::const_iterator pos, end = m_collection.end(); + for (pos = m_collection.begin(); pos != end; ++pos) + { + if (pos->m_die->Tag() == die->Tag()) + { + if (pos->m_declaration == decl) + { + entry = *pos; + return true; + } + } + } + return false; +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h new file mode 100644 index 00000000000..53de120f7a5 --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h @@ -0,0 +1,151 @@ +//===-- UniqueDWARFASTType.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_UniqueDWARFASTType_h_ +#define lldb_UniqueDWARFASTType_h_ + +// C Includes +// C++ Includes +#include <vector> + +// Other libraries and framework includes +#include "llvm/ADT/DenseMap.h" + +// Project includes +#include "lldb/Symbol/Declaration.h" + +class DWARFCompileUnit; +class DWARFDebugInfoEntry; +class SymbolFileDWARF; + +class UniqueDWARFASTType +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + UniqueDWARFASTType () : + m_type_sp (), + m_die (NULL), + m_declaration () + { + } + + UniqueDWARFASTType (lldb::TypeSP &type_sp, + DWARFDebugInfoEntry *die, + const lldb_private::Declaration &decl) : + m_type_sp (type_sp), + m_die (die), + m_declaration (decl) + { + } + + UniqueDWARFASTType (const UniqueDWARFASTType &rhs) : + m_type_sp (rhs.m_type_sp), + m_die (rhs.m_die), + m_declaration (rhs.m_declaration) + { + } + + ~UniqueDWARFASTType() + { + } + + UniqueDWARFASTType & + operator= (const UniqueDWARFASTType &rhs) + { + if (this != &rhs) + { + m_type_sp = rhs.m_type_sp; + m_die = rhs.m_die; + m_declaration = rhs.m_declaration; + } + return *this; + } + + lldb::TypeSP m_type_sp; + const DWARFDebugInfoEntry *m_die; + lldb_private::Declaration m_declaration; +}; + +class UniqueDWARFASTTypeList +{ +public: + UniqueDWARFASTTypeList () : + m_collection() + { + } + + ~UniqueDWARFASTTypeList () + { + } + + uint32_t + GetSize() + { + return (uint32_t)m_collection.size(); + } + + void + Append (const UniqueDWARFASTType &entry) + { + m_collection.push_back (entry); + } + + bool + Find (const DWARFDebugInfoEntry *die, + const lldb_private::Declaration &decl, + UniqueDWARFASTType &entry) const; + +protected: + typedef std::vector<UniqueDWARFASTType> collection; + collection m_collection; +}; + +class UniqueDWARFASTTypeMap +{ +public: + UniqueDWARFASTTypeMap () : + m_collection () + { + } + + ~UniqueDWARFASTTypeMap () + { + } + + void + Insert (const lldb_private::ConstString &name, + const UniqueDWARFASTType &entry) + { + m_collection[name.GetCString()].Append (entry); + } + + bool + Find (const lldb_private::ConstString &name, + const DWARFDebugInfoEntry *die, + const lldb_private::Declaration &decl, + UniqueDWARFASTType &entry) const + { + const char *unique_name_cstr = name.GetCString(); + collection::const_iterator pos = m_collection.find (unique_name_cstr); + if (pos != m_collection.end()) + { + return pos->second.Find (die, decl, entry); + } + return false; + } + +protected: + // A unique name string should be used + typedef llvm::DenseMap<const char *, UniqueDWARFASTTypeList> collection; + collection m_collection; +}; + +#endif // lldb_UniqueDWARFASTType_h_ |

