Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -33,6 +33,9 @@ class DWARFUnit { friend class DWARFCompileUnit; + using die_iterator_range = + llvm::iterator_range; + public: virtual ~DWARFUnit(); @@ -134,11 +137,6 @@ bool Supports_unnamed_objc_bitfields(); - void Index(NameToDIE &func_basenames, NameToDIE &func_fullnames, - NameToDIE &func_methods, NameToDIE &func_selectors, - NameToDIE &objc_class_selectors, NameToDIE &globals, - NameToDIE &types, NameToDIE &namespaces); - SymbolFileDWARF *GetSymbolFileDWARF() const; DWARFProducer GetProducer(); @@ -161,6 +159,11 @@ dw_offset_t GetBaseObjOffset() const; + die_iterator_range dies() { + ExtractDIEsIfNeeded(false); + return die_iterator_range(m_die_array.begin(), m_die_array.end()); + } + protected: DWARFUnit(SymbolFileDWARF *dwarf); @@ -190,14 +193,6 @@ // in the main object file dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET; - static void - IndexPrivate(DWARFUnit *dwarf_cu, const lldb::LanguageType cu_language, - const DWARFFormValue::FixedFormSizes &fixed_form_sizes, - const dw_offset_t cu_offset, NameToDIE &func_basenames, - NameToDIE &func_fullnames, NameToDIE &func_methods, - NameToDIE &func_selectors, NameToDIE &objc_class_selectors, - NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces); - // Offset of the initial length field. dw_offset_t m_offset; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -9,20 +9,18 @@ #include "DWARFUnit.h" -#include "Plugins/Language/ObjC/ObjCLanguage.h" #include "lldb/Core/Module.h" #include "lldb/Host/StringConvert.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" #include "DWARFDIECollection.h" -#include "DWARFDebugAbbrev.h" #include "DWARFDebugAranges.h" #include "DWARFDebugInfo.h" #include "LogChannelDWARF.h" -#include "NameToDIE.h" #include "SymbolFileDWARFDebugMap.h" #include "SymbolFileDWARFDwo.h" @@ -627,332 +625,6 @@ dw_offset_t DWARFUnit::GetBaseObjOffset() const { return m_base_obj_offset; } -void DWARFUnit::Index(NameToDIE &func_basenames, NameToDIE &func_fullnames, - NameToDIE &func_methods, NameToDIE &func_selectors, - NameToDIE &objc_class_selectors, NameToDIE &globals, - NameToDIE &types, NameToDIE &namespaces) { - assert(!m_dwarf->GetBaseCompileUnit() && - "DWARFUnit associated with .dwo or .dwp " - "should not be indexed directly"); - - Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); - - if (log) { - m_dwarf->GetObjectFile()->GetModule()->LogMessage( - log, "DWARFUnit::Index() for compile unit at .debug_info[0x%8.8x]", - GetOffset()); - } - - const LanguageType cu_language = GetLanguageType(); - DWARFFormValue::FixedFormSizes fixed_form_sizes = - DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(), - IsDWARF64()); - - IndexPrivate(this, cu_language, fixed_form_sizes, GetOffset(), func_basenames, - func_fullnames, func_methods, func_selectors, - objc_class_selectors, globals, types, namespaces); - - SymbolFileDWARFDwo *dwo_symbol_file = GetDwoSymbolFile(); - if (dwo_symbol_file) { - IndexPrivate( - dwo_symbol_file->GetCompileUnit(), cu_language, fixed_form_sizes, - GetOffset(), func_basenames, func_fullnames, func_methods, - func_selectors, objc_class_selectors, globals, types, namespaces); - } -} - -void DWARFUnit::IndexPrivate( - DWARFUnit *dwarf_cu, const LanguageType cu_language, - const DWARFFormValue::FixedFormSizes &fixed_form_sizes, - const dw_offset_t cu_offset, NameToDIE &func_basenames, - NameToDIE &func_fullnames, NameToDIE &func_methods, - NameToDIE &func_selectors, NameToDIE &objc_class_selectors, - NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces) { - DWARFDebugInfoEntry::const_iterator pos; - DWARFDebugInfoEntry::const_iterator begin = dwarf_cu->m_die_array.begin(); - DWARFDebugInfoEntry::const_iterator end = dwarf_cu->m_die_array.end(); - for (pos = begin; pos != end; ++pos) { - const DWARFDebugInfoEntry &die = *pos; - - const dw_tag_t tag = die.Tag(); - - switch (tag) { - case DW_TAG_array_type: - case DW_TAG_base_type: - case DW_TAG_class_type: - case DW_TAG_constant: - case DW_TAG_enumeration_type: - case DW_TAG_inlined_subroutine: - case DW_TAG_namespace: - case DW_TAG_string_type: - case DW_TAG_structure_type: - case DW_TAG_subprogram: - case DW_TAG_subroutine_type: - case DW_TAG_typedef: - case DW_TAG_union_type: - case DW_TAG_unspecified_type: - case DW_TAG_variable: - break; - - default: - continue; - } - - DWARFAttributes attributes; - const char *name = NULL; - const char *mangled_cstr = NULL; - bool is_declaration = false; - // bool is_artificial = false; - bool has_address = false; - bool has_location_or_const_value = false; - bool is_global_or_static_variable = false; - - DWARFFormValue specification_die_form; - const size_t num_attributes = - die.GetAttributes(dwarf_cu, fixed_form_sizes, attributes); - if (num_attributes > 0) { - for (uint32_t i = 0; i < num_attributes; ++i) { - dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - switch (attr) { - case DW_AT_name: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - name = form_value.AsCString(); - break; - - case DW_AT_declaration: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - is_declaration = form_value.Unsigned() != 0; - break; - - // case DW_AT_artificial: - // if (attributes.ExtractFormValueAtIndex(i, - // form_value)) - // is_artificial = form_value.Unsigned() != 0; - // break; - - case DW_AT_MIPS_linkage_name: - case DW_AT_linkage_name: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - mangled_cstr = form_value.AsCString(); - break; - - case DW_AT_low_pc: - case DW_AT_high_pc: - case DW_AT_ranges: - has_address = true; - break; - - case DW_AT_entry_pc: - has_address = true; - break; - - case DW_AT_location: - case DW_AT_const_value: - has_location_or_const_value = true; - if (tag == DW_TAG_variable) { - const DWARFDebugInfoEntry *parent_die = die.GetParent(); - while (parent_die != NULL) { - switch (parent_die->Tag()) { - case DW_TAG_subprogram: - case DW_TAG_lexical_block: - case DW_TAG_inlined_subroutine: - // Even if this is a function level static, we don't add it. We - // could theoretically add these if we wanted to by - // introspecting into the DW_AT_location and seeing if the - // location describes a hard coded address, but we don't want - // the performance penalty of that right now. - is_global_or_static_variable = false; - // if (attributes.ExtractFormValueAtIndex(dwarf, i, - // form_value)) { - // // If we have valid block data, then we have location - // // expression bytesthat are fixed (not a location list). - // const uint8_t *block_data = form_value.BlockData(); - // if (block_data) { - // uint32_t block_length = form_value.Unsigned(); - // if (block_length == 1 + - // attributes.CompileUnitAtIndex(i)->GetAddressByteSize()) { - // if (block_data[0] == DW_OP_addr) - // add_die = true; - // } - // } - // } - parent_die = NULL; // Terminate the while loop. - break; - - case DW_TAG_compile_unit: - case DW_TAG_partial_unit: - is_global_or_static_variable = true; - parent_die = NULL; // Terminate the while loop. - break; - - default: - parent_die = - parent_die->GetParent(); // Keep going in the while loop. - break; - } - } - } - break; - - case DW_AT_specification: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - specification_die_form = form_value; - break; - } - } - } - - switch (tag) { - case DW_TAG_subprogram: - if (has_address) { - if (name) { - ObjCLanguage::MethodName objc_method(name, true); - if (objc_method.IsValid(true)) { - ConstString objc_class_name_with_category( - objc_method.GetClassNameWithCategory()); - ConstString objc_selector_name(objc_method.GetSelector()); - ConstString objc_fullname_no_category_name( - objc_method.GetFullNameWithoutCategory(true)); - ConstString objc_class_name_no_category(objc_method.GetClassName()); - func_fullnames.Insert(ConstString(name), - DIERef(cu_offset, die.GetOffset())); - if (objc_class_name_with_category) - objc_class_selectors.Insert(objc_class_name_with_category, - DIERef(cu_offset, die.GetOffset())); - if (objc_class_name_no_category && - objc_class_name_no_category != objc_class_name_with_category) - objc_class_selectors.Insert(objc_class_name_no_category, - DIERef(cu_offset, die.GetOffset())); - if (objc_selector_name) - func_selectors.Insert(objc_selector_name, - DIERef(cu_offset, die.GetOffset())); - if (objc_fullname_no_category_name) - func_fullnames.Insert(objc_fullname_no_category_name, - DIERef(cu_offset, die.GetOffset())); - } - // If we have a mangled name, then the DW_AT_name attribute is - // usually the method name without the class or any parameters - const DWARFDebugInfoEntry *parent = die.GetParent(); - bool is_method = false; - if (parent) { - dw_tag_t parent_tag = parent->Tag(); - if (parent_tag == DW_TAG_class_type || - parent_tag == DW_TAG_structure_type) { - is_method = true; - } else { - if (specification_die_form.IsValid()) { - DWARFDIE specification_die = - dwarf_cu->GetSymbolFileDWARF()->DebugInfo()->GetDIE( - DIERef(specification_die_form)); - if (specification_die.GetParent().IsStructOrClass()) - is_method = true; - } - } - } - - if (is_method) - func_methods.Insert(ConstString(name), - DIERef(cu_offset, die.GetOffset())); - else - func_basenames.Insert(ConstString(name), - DIERef(cu_offset, die.GetOffset())); - - if (!is_method && !mangled_cstr && !objc_method.IsValid(true)) - func_fullnames.Insert(ConstString(name), - DIERef(cu_offset, die.GetOffset())); - } - if (mangled_cstr) { - // Make sure our mangled name isn't the same string table entry as - // our name. If it starts with '_', then it is ok, else compare the - // string to make sure it isn't the same and we don't end up with - // duplicate entries - if (name && name != mangled_cstr && - ((mangled_cstr[0] == '_') || - (::strcmp(name, mangled_cstr) != 0))) { - func_fullnames.Insert(ConstString(mangled_cstr), - DIERef(cu_offset, die.GetOffset())); - } - } - } - break; - - case DW_TAG_inlined_subroutine: - if (has_address) { - if (name) - func_basenames.Insert(ConstString(name), - DIERef(cu_offset, die.GetOffset())); - if (mangled_cstr) { - // Make sure our mangled name isn't the same string table entry as - // our name. If it starts with '_', then it is ok, else compare the - // string to make sure it isn't the same and we don't end up with - // duplicate entries - if (name && name != mangled_cstr && - ((mangled_cstr[0] == '_') || - (::strcmp(name, mangled_cstr) != 0))) { - func_fullnames.Insert(ConstString(mangled_cstr), - DIERef(cu_offset, die.GetOffset())); - } - } else - func_fullnames.Insert(ConstString(name), - DIERef(cu_offset, die.GetOffset())); - } - break; - - case DW_TAG_array_type: - case DW_TAG_base_type: - case DW_TAG_class_type: - case DW_TAG_constant: - case DW_TAG_enumeration_type: - case DW_TAG_string_type: - case DW_TAG_structure_type: - case DW_TAG_subroutine_type: - case DW_TAG_typedef: - case DW_TAG_union_type: - case DW_TAG_unspecified_type: - if (name && !is_declaration) - types.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset())); - if (mangled_cstr && !is_declaration) - types.Insert(ConstString(mangled_cstr), - DIERef(cu_offset, die.GetOffset())); - break; - - case DW_TAG_namespace: - if (name) - namespaces.Insert(ConstString(name), - DIERef(cu_offset, die.GetOffset())); - break; - - case DW_TAG_variable: - if (name && has_location_or_const_value && is_global_or_static_variable) { - globals.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset())); - // Be sure to include variables by their mangled and demangled names if - // they have any since a variable can have a basename "i", a mangled - // named "_ZN12_GLOBAL__N_11iE" and a demangled mangled name - // "(anonymous namespace)::i"... - - // Make sure our mangled name isn't the same string table entry as our - // name. If it starts with '_', then it is ok, else compare the string - // to make sure it isn't the same and we don't end up with duplicate - // entries - if (mangled_cstr && name != mangled_cstr && - ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) { - Mangled mangled(ConstString(mangled_cstr), true); - globals.Insert(mangled.GetMangledName(), - DIERef(cu_offset, die.GetOffset())); - ConstString demangled = mangled.GetDemangledName(cu_language); - if (demangled) - globals.Insert(demangled, DIERef(cu_offset, die.GetOffset())); - } - } - break; - - default: - continue; - } - } -} - const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() { if (m_func_aranges_ap.get() == NULL) { m_func_aranges_ap.reset(new DWARFDebugAranges()); Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h @@ -53,6 +53,18 @@ private: void Index(); + void IndexUnit(DWARFUnit &unit, NameToDIE &func_basenames, + NameToDIE &func_fullnames, NameToDIE &func_methods, + NameToDIE &func_selectors, NameToDIE &objc_class_selectors, + NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces); + + static void + IndexUnitImpl(DWARFUnit &unit, const lldb::LanguageType cu_language, + const DWARFFormValue::FixedFormSizes &fixed_form_sizes, + const dw_offset_t cu_offset, NameToDIE &func_basenames, + NameToDIE &func_fullnames, NameToDIE &func_methods, + NameToDIE &func_selectors, NameToDIE &objc_class_selectors, + NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces); /// Non-null value means we haven't built the index yet. DWARFDebugInfo *m_debug_info; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -8,8 +8,11 @@ //===----------------------------------------------------------------------===// #include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h" +#include "Plugins/Language/ObjC/ObjCLanguage.h" #include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h" #include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h" +#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h" +#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h" #include "lldb/Core/Module.h" #include "lldb/Host/TaskPool.h" #include "lldb/Symbol/ObjectFile.h" @@ -48,10 +51,10 @@ auto parser_fn = [&](size_t cu_idx) { DWARFUnit *dwarf_cu = debug_info.GetCompileUnitAtIndex(cu_idx); if (dwarf_cu) { - dwarf_cu->Index(function_basenames[cu_idx], function_fullnames[cu_idx], - function_methods[cu_idx], function_selectors[cu_idx], - objc_class_selectors[cu_idx], globals[cu_idx], - types[cu_idx], namespaces[cu_idx]); + IndexUnit(*dwarf_cu, function_basenames[cu_idx], + function_fullnames[cu_idx], function_methods[cu_idx], + function_selectors[cu_idx], objc_class_selectors[cu_idx], + globals[cu_idx], types[cu_idx], namespaces[cu_idx]); } }; @@ -108,6 +111,324 @@ } } +void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, NameToDIE &func_basenames, + NameToDIE &func_fullnames, + NameToDIE &func_methods, + NameToDIE &func_selectors, + NameToDIE &objc_class_selectors, + NameToDIE &globals, NameToDIE &types, + NameToDIE &namespaces) { + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS); + + if (log) { + m_module.LogMessage( + log, "ManualDWARFIndex::IndexUnit for compile unit at .debug_info[0x%8.8x]", + unit.GetOffset()); + } + + const LanguageType cu_language = unit.GetLanguageType(); + DWARFFormValue::FixedFormSizes fixed_form_sizes = unit.GetFixedFormSizes(); + + IndexUnitImpl(unit, cu_language, fixed_form_sizes, unit.GetOffset(), + func_basenames, func_fullnames, func_methods, func_selectors, + objc_class_selectors, globals, types, namespaces); + + SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile(); + if (dwo_symbol_file && dwo_symbol_file->GetCompileUnit()) { + IndexUnitImpl(*dwo_symbol_file->GetCompileUnit(), cu_language, + fixed_form_sizes, unit.GetOffset(), func_basenames, + func_fullnames, func_methods, func_selectors, + objc_class_selectors, globals, types, namespaces); + } +} + +void ManualDWARFIndex::IndexUnitImpl( + DWARFUnit &unit, const LanguageType cu_language, + const DWARFFormValue::FixedFormSizes &fixed_form_sizes, + const dw_offset_t cu_offset, NameToDIE &func_basenames, + NameToDIE &func_fullnames, NameToDIE &func_methods, + NameToDIE &func_selectors, NameToDIE &objc_class_selectors, + NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces) { + for (const DWARFDebugInfoEntry &die : unit.dies()) { + const dw_tag_t tag = die.Tag(); + + switch (tag) { + case DW_TAG_array_type: + case DW_TAG_base_type: + case DW_TAG_class_type: + case DW_TAG_constant: + case DW_TAG_enumeration_type: + case DW_TAG_inlined_subroutine: + case DW_TAG_namespace: + case DW_TAG_string_type: + case DW_TAG_structure_type: + case DW_TAG_subprogram: + case DW_TAG_subroutine_type: + case DW_TAG_typedef: + case DW_TAG_union_type: + case DW_TAG_unspecified_type: + case DW_TAG_variable: + break; + + default: + continue; + } + + DWARFAttributes attributes; + const char *name = NULL; + const char *mangled_cstr = NULL; + bool is_declaration = false; + // bool is_artificial = false; + bool has_address = false; + bool has_location_or_const_value = false; + bool is_global_or_static_variable = false; + + DWARFFormValue specification_die_form; + const size_t num_attributes = + die.GetAttributes(&unit, fixed_form_sizes, attributes); + if (num_attributes > 0) { + for (uint32_t i = 0; i < num_attributes; ++i) { + dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + switch (attr) { + case DW_AT_name: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + name = form_value.AsCString(); + break; + + case DW_AT_declaration: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + is_declaration = form_value.Unsigned() != 0; + break; + + // case DW_AT_artificial: + // if (attributes.ExtractFormValueAtIndex(i, + // form_value)) + // is_artificial = form_value.Unsigned() != 0; + // break; + + case DW_AT_MIPS_linkage_name: + case DW_AT_linkage_name: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + mangled_cstr = form_value.AsCString(); + break; + + case DW_AT_low_pc: + case DW_AT_high_pc: + case DW_AT_ranges: + has_address = true; + break; + + case DW_AT_entry_pc: + has_address = true; + break; + + case DW_AT_location: + case DW_AT_const_value: + has_location_or_const_value = true; + if (tag == DW_TAG_variable) { + const DWARFDebugInfoEntry *parent_die = die.GetParent(); + while (parent_die != NULL) { + switch (parent_die->Tag()) { + case DW_TAG_subprogram: + case DW_TAG_lexical_block: + case DW_TAG_inlined_subroutine: + // Even if this is a function level static, we don't add it. We + // could theoretically add these if we wanted to by + // introspecting into the DW_AT_location and seeing if the + // location describes a hard coded address, but we don't want + // the performance penalty of that right now. + is_global_or_static_variable = false; + // if (attributes.ExtractFormValueAtIndex(dwarf, i, + // form_value)) { + // // If we have valid block data, then we have location + // // expression bytesthat are fixed (not a location list). + // const uint8_t *block_data = form_value.BlockData(); + // if (block_data) { + // uint32_t block_length = form_value.Unsigned(); + // if (block_length == 1 + + // attributes.CompileUnitAtIndex(i)->GetAddressByteSize()) { + // if (block_data[0] == DW_OP_addr) + // add_die = true; + // } + // } + // } + parent_die = NULL; // Terminate the while loop. + break; + + case DW_TAG_compile_unit: + case DW_TAG_partial_unit: + is_global_or_static_variable = true; + parent_die = NULL; // Terminate the while loop. + break; + + default: + parent_die = + parent_die->GetParent(); // Keep going in the while loop. + break; + } + } + } + break; + + case DW_AT_specification: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + specification_die_form = form_value; + break; + } + } + } + + switch (tag) { + case DW_TAG_subprogram: + if (has_address) { + if (name) { + ObjCLanguage::MethodName objc_method(name, true); + if (objc_method.IsValid(true)) { + ConstString objc_class_name_with_category( + objc_method.GetClassNameWithCategory()); + ConstString objc_selector_name(objc_method.GetSelector()); + ConstString objc_fullname_no_category_name( + objc_method.GetFullNameWithoutCategory(true)); + ConstString objc_class_name_no_category(objc_method.GetClassName()); + func_fullnames.Insert(ConstString(name), + DIERef(cu_offset, die.GetOffset())); + if (objc_class_name_with_category) + objc_class_selectors.Insert(objc_class_name_with_category, + DIERef(cu_offset, die.GetOffset())); + if (objc_class_name_no_category && + objc_class_name_no_category != objc_class_name_with_category) + objc_class_selectors.Insert(objc_class_name_no_category, + DIERef(cu_offset, die.GetOffset())); + if (objc_selector_name) + func_selectors.Insert(objc_selector_name, + DIERef(cu_offset, die.GetOffset())); + if (objc_fullname_no_category_name) + func_fullnames.Insert(objc_fullname_no_category_name, + DIERef(cu_offset, die.GetOffset())); + } + // If we have a mangled name, then the DW_AT_name attribute is + // usually the method name without the class or any parameters + const DWARFDebugInfoEntry *parent = die.GetParent(); + bool is_method = false; + if (parent) { + dw_tag_t parent_tag = parent->Tag(); + if (parent_tag == DW_TAG_class_type || + parent_tag == DW_TAG_structure_type) { + is_method = true; + } else { + if (specification_die_form.IsValid()) { + DWARFDIE specification_die = + unit.GetSymbolFileDWARF()->DebugInfo()->GetDIE( + DIERef(specification_die_form)); + if (specification_die.GetParent().IsStructOrClass()) + is_method = true; + } + } + } + + if (is_method) + func_methods.Insert(ConstString(name), + DIERef(cu_offset, die.GetOffset())); + else + func_basenames.Insert(ConstString(name), + DIERef(cu_offset, die.GetOffset())); + + if (!is_method && !mangled_cstr && !objc_method.IsValid(true)) + func_fullnames.Insert(ConstString(name), + DIERef(cu_offset, die.GetOffset())); + } + if (mangled_cstr) { + // Make sure our mangled name isn't the same string table entry as + // our name. If it starts with '_', then it is ok, else compare the + // string to make sure it isn't the same and we don't end up with + // duplicate entries + if (name && name != mangled_cstr && + ((mangled_cstr[0] == '_') || + (::strcmp(name, mangled_cstr) != 0))) { + func_fullnames.Insert(ConstString(mangled_cstr), + DIERef(cu_offset, die.GetOffset())); + } + } + } + break; + + case DW_TAG_inlined_subroutine: + if (has_address) { + if (name) + func_basenames.Insert(ConstString(name), + DIERef(cu_offset, die.GetOffset())); + if (mangled_cstr) { + // Make sure our mangled name isn't the same string table entry as + // our name. If it starts with '_', then it is ok, else compare the + // string to make sure it isn't the same and we don't end up with + // duplicate entries + if (name && name != mangled_cstr && + ((mangled_cstr[0] == '_') || + (::strcmp(name, mangled_cstr) != 0))) { + func_fullnames.Insert(ConstString(mangled_cstr), + DIERef(cu_offset, die.GetOffset())); + } + } else + func_fullnames.Insert(ConstString(name), + DIERef(cu_offset, die.GetOffset())); + } + break; + + case DW_TAG_array_type: + case DW_TAG_base_type: + case DW_TAG_class_type: + case DW_TAG_constant: + case DW_TAG_enumeration_type: + case DW_TAG_string_type: + case DW_TAG_structure_type: + case DW_TAG_subroutine_type: + case DW_TAG_typedef: + case DW_TAG_union_type: + case DW_TAG_unspecified_type: + if (name && !is_declaration) + types.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset())); + if (mangled_cstr && !is_declaration) + types.Insert(ConstString(mangled_cstr), + DIERef(cu_offset, die.GetOffset())); + break; + + case DW_TAG_namespace: + if (name) + namespaces.Insert(ConstString(name), + DIERef(cu_offset, die.GetOffset())); + break; + + case DW_TAG_variable: + if (name && has_location_or_const_value && is_global_or_static_variable) { + globals.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset())); + // Be sure to include variables by their mangled and demangled names if + // they have any since a variable can have a basename "i", a mangled + // named "_ZN12_GLOBAL__N_11iE" and a demangled mangled name + // "(anonymous namespace)::i"... + + // Make sure our mangled name isn't the same string table entry as our + // name. If it starts with '_', then it is ok, else compare the string + // to make sure it isn't the same and we don't end up with duplicate + // entries + if (mangled_cstr && name != mangled_cstr && + ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) { + Mangled mangled(ConstString(mangled_cstr), true); + globals.Insert(mangled.GetMangledName(), + DIERef(cu_offset, die.GetOffset())); + ConstString demangled = mangled.GetDemangledName(cu_language); + if (demangled) + globals.Insert(demangled, DIERef(cu_offset, die.GetOffset())); + } + } + break; + + default: + continue; + } + } +} + void ManualDWARFIndex::GetGlobalVariables(ConstString name, DIEArray &offsets) { Index(); m_globals.Find(name, offsets);