diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /lldb/source/Plugins/SymbolFile | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'lldb/source/Plugins/SymbolFile')
100 files changed, 2983 insertions, 3794 deletions
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp index b2c4d0883341..eeec7296747e 100644 --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFileBreakpad.cpp ----------------------------------*- C++ -*-===// +//===-- SymbolFileBreakpad.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,6 +25,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::breakpad; +LLDB_PLUGIN_DEFINE(SymbolFileBreakpad) + char SymbolFileBreakpad::ID; class SymbolFileBreakpad::LineIterator { @@ -292,7 +294,7 @@ uint32_t SymbolFileBreakpad::ResolveSymbolContext( } void SymbolFileBreakpad::FindFunctions( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) { // TODO @@ -305,7 +307,7 @@ void SymbolFileBreakpad::FindFunctions(const RegularExpression ®ex, } void SymbolFileBreakpad::FindTypes( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {} @@ -406,20 +408,25 @@ GetRule(llvm::StringRef &unwind_rules) { } static const RegisterInfo * -ResolveRegister(const SymbolFile::RegisterInfoResolver &resolver, +ResolveRegister(const llvm::Triple &triple, + const SymbolFile::RegisterInfoResolver &resolver, llvm::StringRef name) { - if (name.consume_front("$")) - return resolver.ResolveName(name); - - return nullptr; + if (triple.isX86() || triple.isMIPS()) { + // X86 and MIPS registers have '$' in front of their register names. Arm and + // AArch64 don't. + if (!name.consume_front("$")) + return nullptr; + } + return resolver.ResolveName(name); } static const RegisterInfo * -ResolveRegisterOrRA(const SymbolFile::RegisterInfoResolver &resolver, +ResolveRegisterOrRA(const llvm::Triple &triple, + const SymbolFile::RegisterInfoResolver &resolver, llvm::StringRef name) { if (name == ".ra") return resolver.ResolveNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); - return ResolveRegister(resolver, name); + return ResolveRegister(triple, resolver, name); } llvm::ArrayRef<uint8_t> SymbolFileBreakpad::SaveAsDWARF(postfix::Node &node) { @@ -438,6 +445,7 @@ bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules, Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); llvm::BumpPtrAllocator node_alloc; + llvm::Triple triple = m_objfile_sp->GetArchitecture().GetTriple(); while (auto rule = GetRule(unwind_rules)) { node_alloc.Reset(); llvm::StringRef lhs = rule->first; @@ -453,7 +461,8 @@ bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules, if (name == ".cfa" && lhs != ".cfa") return postfix::MakeNode<postfix::InitialValueNode>(node_alloc); - if (const RegisterInfo *info = ResolveRegister(resolver, name)) { + if (const RegisterInfo *info = + ResolveRegister(triple, resolver, name)) { return postfix::MakeNode<postfix::RegisterNode>( node_alloc, info->kinds[eRegisterKindLLDB]); } @@ -468,7 +477,8 @@ bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules, llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*rhs); if (lhs == ".cfa") { row.GetCFAValue().SetIsDWARFExpression(saved.data(), saved.size()); - } else if (const RegisterInfo *info = ResolveRegisterOrRA(resolver, lhs)) { + } else if (const RegisterInfo *info = + ResolveRegisterOrRA(triple, resolver, lhs)) { UnwindPlan::Row::RegisterLocation loc; loc.SetIsDWARFExpression(saved.data(), saved.size()); row.SetRegisterInfo(info->kinds[eRegisterKindLLDB], loc); @@ -572,6 +582,7 @@ SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark, return nullptr; } auto it = program.begin(); + llvm::Triple triple = m_objfile_sp->GetArchitecture().GetTriple(); const auto &symbol_resolver = [&](postfix::SymbolNode &symbol) -> postfix::Node * { llvm::StringRef name = symbol.GetName(); @@ -579,7 +590,7 @@ SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark, if (rule.first == name) return rule.second; } - if (const RegisterInfo *info = ResolveRegister(resolver, name)) + if (const RegisterInfo *info = ResolveRegister(triple, resolver, name)) return postfix::MakeNode<postfix::RegisterNode>( node_alloc, info->kinds[eRegisterKindLLDB]); return nullptr; @@ -609,7 +620,7 @@ SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark, // Now process the rest of the assignments. for (++it; it != program.end(); ++it) { - const RegisterInfo *info = ResolveRegister(resolver, it->first); + const RegisterInfo *info = ResolveRegister(triple, resolver, it->first); // It is not an error if the resolution fails because the program may // contain temporary variables. if (!info) @@ -694,18 +705,18 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu, "How did we create compile units without a base address?"); SupportFileMap map; - data.line_table_up = std::make_unique<LineTable>(&cu); - std::unique_ptr<LineSequence> line_seq_up( - data.line_table_up->CreateLineSequenceContainer()); + std::vector<std::unique_ptr<LineSequence>> sequences; + std::unique_ptr<LineSequence> line_seq_up = + LineTable::CreateLineSequenceContainer(); llvm::Optional<addr_t> next_addr; auto finish_sequence = [&]() { - data.line_table_up->AppendLineEntryToSequence( + LineTable::AppendLineEntryToSequence( line_seq_up.get(), *next_addr, /*line*/ 0, /*column*/ 0, /*file_idx*/ 0, /*is_start_of_statement*/ false, /*is_start_of_basic_block*/ false, /*is_prologue_end*/ false, /*is_epilogue_begin*/ false, /*is_terminal_entry*/ true); - data.line_table_up->InsertSequence(line_seq_up.get()); - line_seq_up->Clear(); + sequences.push_back(std::move(line_seq_up)); + line_seq_up = LineTable::CreateLineSequenceContainer(); }; LineIterator It(*m_objfile_sp, Record::Func, data.bookmark), @@ -722,7 +733,7 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu, // Discontiguous entries. Finish off the previous sequence and reset. finish_sequence(); } - data.line_table_up->AppendLineEntryToSequence( + LineTable::AppendLineEntryToSequence( line_seq_up.get(), record->Address, record->LineNum, /*column*/ 0, map[record->FileNum], /*is_start_of_statement*/ true, /*is_start_of_basic_block*/ false, /*is_prologue_end*/ false, @@ -731,6 +742,7 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu, } if (next_addr) finish_sequence(); + data.line_table_up = std::make_unique<LineTable>(&cu, std::move(sequences)); data.support_files = map.translate(cu.GetPrimaryFile(), *m_files); } diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h index de271224a65d..90dbcc77627a 100644 --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H -#define LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H #include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h" #include "lldb/Core/FileSpecList.h" @@ -82,7 +82,7 @@ public: size_t ParseBlocksRecursive(Function &func) override { return 0; } void FindGlobalVariables(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) override {} @@ -110,14 +110,14 @@ public: TypeList &type_list) override {} void FindFunctions(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) override; void FindFunctions(const RegularExpression ®ex, bool include_inlines, SymbolContextList &sc_list) override; - void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx, + void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) override; @@ -135,7 +135,7 @@ public: CompilerDeclContext FindNamespace(ConstString name, - const CompilerDeclContext *parent_decl_ctx) override { + const CompilerDeclContext &parent_decl_ctx) override { return CompilerDeclContext(); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp index 0a5073b8cd9e..33ab11a3ca40 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp @@ -1,4 +1,4 @@ -//===-- AppleDWARFIndex.cpp ------------------------------------*- C++ -*-===// +//===-- AppleDWARFIndex.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -52,54 +52,70 @@ std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create( return nullptr; } -void AppleDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) { - if (m_apple_names_up) - m_apple_names_up->FindByName(basename.GetStringRef(), offsets); +void AppleDWARFIndex::GetGlobalVariables( + ConstString basename, llvm::function_ref<bool(DWARFDIE die)> callback) { + if (!m_apple_names_up) + return; + m_apple_names_up->FindByName( + basename.GetStringRef(), + DIERefCallback(callback, basename.GetStringRef())); } -void AppleDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) { +void AppleDWARFIndex::GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref<bool(DWARFDIE die)> callback) { if (!m_apple_names_up) return; DWARFMappedHash::DIEInfoArray hash_data; - if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data)) - DWARFMappedHash::ExtractDIEArray(hash_data, offsets); + m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data); + // This is not really the DIE name. + DWARFMappedHash::ExtractDIEArray(hash_data, + DIERefCallback(callback, regex.GetText())); } -void AppleDWARFIndex::GetGlobalVariables(const DWARFUnit &cu, - DIEArray &offsets) { +void AppleDWARFIndex::GetGlobalVariables( + const DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) { if (!m_apple_names_up) return; DWARFMappedHash::DIEInfoArray hash_data; - if (m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(), - cu.GetNextUnitOffset(), hash_data)) - DWARFMappedHash::ExtractDIEArray(hash_data, offsets); + m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(), cu.GetNextUnitOffset(), + hash_data); + DWARFMappedHash::ExtractDIEArray(hash_data, DIERefCallback(callback)); } -void AppleDWARFIndex::GetObjCMethods(ConstString class_name, - DIEArray &offsets) { - if (m_apple_objc_up) - m_apple_objc_up->FindByName(class_name.GetStringRef(), offsets); +void AppleDWARFIndex::GetObjCMethods( + ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) { + if (!m_apple_objc_up) + return; + m_apple_objc_up->FindByName( + class_name.GetStringRef(), + DIERefCallback(callback, class_name.GetStringRef())); } -void AppleDWARFIndex::GetCompleteObjCClass(ConstString class_name, - bool must_be_implementation, - DIEArray &offsets) { - if (m_apple_types_up) { - m_apple_types_up->FindCompleteObjCClassByName( - class_name.GetStringRef(), offsets, must_be_implementation); - } +void AppleDWARFIndex::GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref<bool(DWARFDIE die)> callback) { + if (!m_apple_types_up) + return; + m_apple_types_up->FindCompleteObjCClassByName( + class_name.GetStringRef(), + DIERefCallback(callback, class_name.GetStringRef()), + must_be_implementation); } -void AppleDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) { - if (m_apple_types_up) - m_apple_types_up->FindByName(name.GetStringRef(), offsets); +void AppleDWARFIndex::GetTypes( + ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) { + if (!m_apple_types_up) + return; + m_apple_types_up->FindByName(name.GetStringRef(), + DIERefCallback(callback, name.GetStringRef())); } -void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context, - DIEArray &offsets) { +void AppleDWARFIndex::GetTypes( + const DWARFDeclContext &context, + llvm::function_ref<bool(DWARFDIE die)> callback) { if (!m_apple_types_up) return; @@ -119,7 +135,8 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context, if (log) m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()"); m_apple_types_up->FindByNameAndTagAndQualifiedNameHash( - type_name.GetStringRef(), tag, qualified_name_hash, offsets); + type_name.GetStringRef(), tag, qualified_name_hash, + DIERefCallback(callback, type_name.GetStringRef())); return; } @@ -133,54 +150,52 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context, if (!has_qualified_name_hash && (context.GetSize() > 1) && (context[1].tag == DW_TAG_class_type || context[1].tag == DW_TAG_structure_type)) { - DIEArray class_matches; - m_apple_types_up->FindByName(context[1].name, class_matches); - if (class_matches.empty()) + if (m_apple_types_up->FindByName(context[1].name, + [&](DIERef ref) { return false; })) return; } if (log) m_module.LogMessage(log, "FindByNameAndTag()"); - m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets); + m_apple_types_up->FindByNameAndTag( + type_name.GetStringRef(), tag, + DIERefCallback(callback, type_name.GetStringRef())); return; } - m_apple_types_up->FindByName(type_name.GetStringRef(), offsets); + m_apple_types_up->FindByName( + type_name.GetStringRef(), + DIERefCallback(callback, type_name.GetStringRef())); } -void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) { - if (m_apple_namespaces_up) - m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets); +void AppleDWARFIndex::GetNamespaces( + ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) { + if (!m_apple_namespaces_up) + return; + m_apple_namespaces_up->FindByName( + name.GetStringRef(), DIERefCallback(callback, name.GetStringRef())); } -void AppleDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - std::vector<DWARFDIE> &dies) { - DIEArray offsets; - m_apple_names_up->FindByName(name.GetStringRef(), offsets); - for (const DIERef &die_ref : offsets) { - ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf, parent_decl_ctx, - name_type_mask, dies); - } +void AppleDWARFIndex::GetFunctions( + ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + llvm::function_ref<bool(DWARFDIE die)> callback) { + m_apple_names_up->FindByName(name.GetStringRef(), [&](DIERef die_ref) { + return ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf, + parent_decl_ctx, name_type_mask, callback); + }); } -void AppleDWARFIndex::GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) { +void AppleDWARFIndex::GetFunctions( + const RegularExpression ®ex, + llvm::function_ref<bool(DWARFDIE die)> callback) { if (!m_apple_names_up) return; DWARFMappedHash::DIEInfoArray hash_data; - if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data)) - DWARFMappedHash::ExtractDIEArray(hash_data, offsets); -} - -void AppleDWARFIndex::ReportInvalidDIERef(const DIERef &ref, - llvm::StringRef name) { - m_module.ReportErrorIfModifyDetected( - "the DWARF debug information has been modified (accelerator table had " - "bad die 0x%8.8x for '%s')\n", - ref.die_offset(), name.str().c_str()); + m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data); + DWARFMappedHash::ExtractDIEArray(hash_data, + DIERefCallback(callback, regex.GetText())); } void AppleDWARFIndex::Dump(Stream &s) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h index d15d61e270b3..a7032f50e590 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_APPLEDWARFINDEX_H -#define LLDB_APPLEDWARFINDEX_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_APPLEDWARFINDEX_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_APPLEDWARFINDEX_H #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" #include "Plugins/SymbolFile/DWARF/HashedNameToDIE.h" @@ -32,23 +32,33 @@ public: void Preload() override {} - void GetGlobalVariables(ConstString basename, DIEArray &offsets) override; - void GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) override; - void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override; - void GetObjCMethods(ConstString class_name, DIEArray &offsets) override; - void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, - DIEArray &offsets) override; - void GetTypes(ConstString name, DIEArray &offsets) override; - void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override; - void GetNamespaces(ConstString name, DIEArray &offsets) override; + void + GetGlobalVariables(ConstString basename, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void + GetGlobalVariables(const DWARFUnit &cu, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetObjCMethods(ConstString class_name, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetTypes(ConstString name, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetTypes(const DWARFDeclContext &context, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetNamespaces(ConstString name, + llvm::function_ref<bool(DWARFDIE die)> callback) override; void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - std::vector<DWARFDIE> &dies) override; - void GetFunctions(const RegularExpression ®ex, DIEArray &offsets) override; + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetFunctions(const RegularExpression ®ex, + llvm::function_ref<bool(DWARFDIE die)> callback) override; - void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override; void Dump(Stream &s) override; private: @@ -59,4 +69,4 @@ private: }; } // namespace lldb_private -#endif // LLDB_APPLEDWARFINDEX_H +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_APPLEDWARFINDEX_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp index f7f2a5bf006b..7a8ab9c9bcfd 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp @@ -1,4 +1,4 @@ -//===-- DIERef.cpp ----------------------------------------------*- C++ -*-===// +//===-- DIERef.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h index 5546bb7e8b86..f7e09ee17283 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DIERef_h_ -#define SymbolFileDWARF_DIERef_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H #include "lldb/Core/dwarf.h" #include "llvm/ADT/Optional.h" @@ -44,6 +44,16 @@ public: dw_offset_t die_offset() const { return m_die_offset; } + bool operator<(DIERef other) const { + if (m_dwo_num_valid != other.m_dwo_num_valid) + return m_dwo_num_valid < other.m_dwo_num_valid; + if (m_dwo_num_valid && (m_dwo_num != other.m_dwo_num)) + return m_dwo_num < other.m_dwo_num; + if (m_section != other.m_section) + return m_section < other.m_section; + return m_die_offset < other.m_die_offset; + } + private: uint32_t m_dwo_num : 30; uint32_t m_dwo_num_valid : 1; @@ -60,4 +70,4 @@ template<> struct format_provider<DIERef> { }; } // namespace llvm -#endif // SymbolFileDWARF_DIERef_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h index 7ee4727cde91..2e0a7fd3ecd3 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFASTParser_h_ -#define SymbolFileDWARF_DWARFASTParser_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSER_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSER_H #include "DWARFDefines.h" #include "lldb/Core/PluginInterface.h" @@ -55,4 +55,4 @@ public: const lldb_private::ExecutionContext *exe_ctx = nullptr); }; -#endif // SymbolFileDWARF_DWARFASTParser_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSER_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 232063a6f339..2d1db66e7fd9 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1,4 +1,4 @@ -//===-- DWARFASTParserClang.cpp ---------------------------------*- C++ -*-===// +//===-- DWARFASTParserClang.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,17 +13,17 @@ #include "DWARFDeclContext.h" #include "DWARFDefines.h" #include "SymbolFileDWARF.h" -#include "SymbolFileDWARFDwo.h" #include "SymbolFileDWARFDebugMap.h" +#include "SymbolFileDWARFDwo.h" #include "UniqueDWARFASTType.h" +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" #include "lldb/Core/Module.h" #include "lldb/Core/Value.h" #include "lldb/Host/Host.h" -#include "lldb/Symbol/ClangASTImporter.h" -#include "lldb/Symbol/ClangASTMetadata.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" @@ -35,6 +35,8 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" +#include "llvm/Demangle/Demangle.h" + #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" @@ -55,7 +57,7 @@ using namespace lldb; using namespace lldb_private; -DWARFASTParserClang::DWARFASTParserClang(ClangASTContext &ast) +DWARFASTParserClang::DWARFASTParserClang(TypeSystemClang &ast) : m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {} DWARFASTParserClang::~DWARFASTParserClang() {} @@ -85,39 +87,10 @@ static bool DeclKindIsCXXClass(clang::Decl::Kind decl_kind) { return false; } -struct BitfieldInfo { - uint64_t bit_size; - uint64_t bit_offset; - - BitfieldInfo() - : bit_size(LLDB_INVALID_ADDRESS), bit_offset(LLDB_INVALID_ADDRESS) {} - - void Clear() { - bit_size = LLDB_INVALID_ADDRESS; - bit_offset = LLDB_INVALID_ADDRESS; - } - - bool IsValid() const { - return (bit_size != LLDB_INVALID_ADDRESS) && - (bit_offset != LLDB_INVALID_ADDRESS); - } - - bool NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const { - if (IsValid()) { - // This bitfield info is valid, so any subsequent bitfields must not - // overlap and must be at a higher bit offset than any previous bitfield - // + size. - return (bit_size + bit_offset) <= next_bit_offset; - } else { - // If the this BitfieldInfo is not valid, then any offset isOK - return true; - } - } -}; ClangASTImporter &DWARFASTParserClang::GetClangASTImporter() { if (!m_clang_ast_importer_up) { - m_clang_ast_importer_up.reset(new ClangASTImporter); + m_clang_ast_importer_up = std::make_unique<ClangASTImporter>(); } return *m_clang_ast_importer_up; } @@ -184,7 +157,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, // The type in the Clang module must have the same language as the current CU. LanguageSet languages; - languages.Insert(die.GetCU()->GetLanguageType()); + languages.Insert(SymbolFileDWARF::GetLanguage(*die.GetCU())); llvm::DenseSet<SymbolFile *> searched_symbol_files; clang_module_sp->GetSymbolFile()->FindTypes(decl_context, languages, searched_symbol_files, pcm_types); @@ -239,14 +212,15 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, TypeSP type_sp(new Type( die.GetID(), dwarf, pcm_type_sp->GetName(), pcm_type_sp->GetByteSize(), nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid, - &pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward)); + &pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward, + TypePayloadClang(GetOwningClangModule(die)))); dwarf->GetTypeList().Insert(type_sp); dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type); - if (tag_decl) + clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type); + if (tag_decl) { LinkDeclContextToDIE(tag_decl, die); - else { + } else { clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die); if (defn_decl_ctx) LinkDeclContextToDIE(defn_decl_ctx, die); @@ -255,7 +229,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, return type_sp; } -static void CompleteExternalTagDeclType(ClangASTContext &ast, +static void CompleteExternalTagDeclType(TypeSystemClang &ast, ClangASTImporter &ast_importer, clang::DeclContext *decl_ctx, DWARFDIE die, @@ -277,8 +251,8 @@ static void CompleteExternalTagDeclType(ClangASTContext &ast, type_name_cstr ? type_name_cstr : "", die.GetOffset()); // We need to make the type look complete otherwise, we might crash in // Clang when adding children. - if (ClangASTContext::StartTagDeclarationDefinition(type)) - ClangASTContext::CompleteTagDeclarationDefinition(type); + if (TypeSystemClang::StartTagDeclarationDefinition(type)) + TypeSystemClang::CompleteTagDeclarationDefinition(type); } } @@ -533,7 +507,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc, DWARF_LOG_LOOKUPS)); SymbolFileDWARF *dwarf = die.GetDWARF(); const dw_tag_t tag = die.Tag(); - LanguageType cu_language = die.GetLanguage(); + LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU()); Type::ResolveState resolve_state = Type::ResolveState::Unresolved; Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID; TypeSP type_sp; @@ -735,7 +709,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc, type_sp = std::make_shared<Type>( die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl, - clang_type, resolve_state); + clang_type, resolve_state, TypePayloadClang(GetOwningClangModule(die))); dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); return type_sp; @@ -755,8 +729,7 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc, if (type_sp) return type_sp; - DWARFDeclContext die_decl_ctx; - die.GetDWARFDeclContext(die_decl_ctx); + DWARFDeclContext die_decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); @@ -818,27 +791,28 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc, clang_type = m_ast.CreateEnumerationType( attrs.name.GetCString(), GetClangDeclContextContainingDIE(die, nullptr), - attrs.decl, enumerator_clang_type, attrs.is_scoped_enum); + GetOwningClangModule(die), attrs.decl, enumerator_clang_type, + attrs.is_scoped_enum); } else { - enumerator_clang_type = - m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType()); + enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type); } - LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); + LinkDeclContextToDIE(TypeSystemClang::GetDeclContextForType(clang_type), die); type_sp = std::make_shared<Type>( die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, dwarf->GetUID(attrs.type.Reference()), Type::eEncodingIsUID, &attrs.decl, - clang_type, Type::ResolveState::Forward); + clang_type, Type::ResolveState::Forward, + TypePayloadClang(GetOwningClangModule(die))); - if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) { + if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) { if (die.HasChildren()) { bool is_signed = false; enumerator_clang_type.IsIntegerType(is_signed); ParseChildEnumerators(clang_type, is_signed, type_sp->GetByteSize().getValueOr(0), die); } - ClangASTContext::CompleteTagDeclarationDefinition(clang_type); + TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); } else { dwarf->GetObjectFile()->GetModule()->ReportError( "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its " @@ -948,7 +922,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, if (complete_objc_class_type_sp) { CompilerType type_clang_forward_type = complete_objc_class_type_sp->GetForwardCompilerType(); - if (ClangASTContext::IsObjCObjectOrInterfaceType( + if (TypeSystemClang::IsObjCObjectOrInterfaceType( type_clang_forward_type)) class_opaque_type = type_clang_forward_type; } @@ -1053,7 +1027,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, } else { CompilerType class_opaque_type = class_type->GetForwardCompilerType(); - if (ClangASTContext::IsCXXClassType(class_opaque_type)) { + if (TypeSystemClang::IsCXXClassType(class_opaque_type)) { if (class_opaque_type.IsBeingDefined() || alternate_defn) { if (!is_static && !die.HasChildren()) { // We have a C++ member function with no children (this @@ -1198,27 +1172,38 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, } if (!function_decl) { + const char *name = attrs.name.GetCString(); + + // We currently generate function templates with template parameters in + // their name. In order to get closer to the AST that clang generates + // we want to strip these from the name when creating the AST. + if (attrs.mangled_name) { + llvm::ItaniumPartialDemangler D; + if (!D.partialDemangle(attrs.mangled_name)) + name = D.getFunctionBaseName(nullptr, nullptr); + } + // We just have a function that isn't part of a class function_decl = m_ast.CreateFunctionDeclaration( ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, - attrs.name.GetCString(), clang_type, attrs.storage, + GetOwningClangModule(die), name, clang_type, attrs.storage, attrs.is_inline); if (has_template_params) { - ClangASTContext::TemplateParameterInfos template_param_infos; + TypeSystemClang::TemplateParameterInfos template_param_infos; ParseTemplateParameterInfos(die, template_param_infos); template_function_decl = m_ast.CreateFunctionDeclaration( ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, - attrs.name.GetCString(), clang_type, attrs.storage, - attrs.is_inline); + GetOwningClangModule(die), attrs.name.GetCString(), clang_type, + attrs.storage, attrs.is_inline); clang::FunctionTemplateDecl *func_template_decl = m_ast.CreateFunctionTemplateDecl( - containing_decl_ctx, template_function_decl, - attrs.name.GetCString(), template_param_infos); + containing_decl_ctx, GetOwningClangModule(die), + template_function_decl, name, template_param_infos); m_ast.CreateFunctionTemplateSpecializationInfo( - function_decl, func_template_decl, template_param_infos); + template_function_decl, func_template_decl, template_param_infos); } lldbassert(function_decl); @@ -1278,44 +1263,7 @@ TypeSP DWARFASTParserClang::ParseArrayType(const DWARFDIE &die, if (attrs.byte_stride == 0 && attrs.bit_stride == 0) attrs.byte_stride = element_type->GetByteSize().getValueOr(0); CompilerType array_element_type = element_type->GetForwardCompilerType(); - - if (ClangASTContext::IsCXXClassType(array_element_type) && - !array_element_type.GetCompleteType()) { - ModuleSP module_sp = die.GetModule(); - if (module_sp) { - if (die.GetCU()->GetProducer() == eProducerClang) - module_sp->ReportError( - "DWARF DW_TAG_array_type DIE at 0x%8.8x has a " - "class/union/struct element type DIE 0x%8.8x that is a " - "forward declaration, not a complete definition.\nTry " - "compiling the source file with -fstandalone-debug or " - "disable -gmodules", - die.GetOffset(), type_die.GetOffset()); - else - module_sp->ReportError( - "DWARF DW_TAG_array_type DIE at 0x%8.8x has a " - "class/union/struct element type DIE 0x%8.8x that is a " - "forward declaration, not a complete definition.\nPlease " - "file a bug against the compiler and include the " - "preprocessed output for %s", - die.GetOffset(), type_die.GetOffset(), GetUnitName(die).c_str()); - } - - // We have no choice other than to pretend that the element class - // type is complete. If we don't do this, clang will crash when - // trying to layout the class. Since we provide layout - // assistance, all ivars in this class and other classes will be - // fine, this is the best we can do short of crashing. - if (ClangASTContext::StartTagDeclarationDefinition(array_element_type)) { - ClangASTContext::CompleteTagDeclarationDefinition(array_element_type); - } else { - module_sp->ReportError("DWARF DIE at 0x%8.8x was not able to " - "start its definition.\nPlease file a " - "bug and attach the file at the start " - "of this error message", - type_die.GetOffset()); - } - } + CompleteType(array_element_type); uint64_t array_element_bit_stride = attrs.byte_stride * 8 + attrs.bit_stride; @@ -1357,7 +1305,7 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType( CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType(); CompilerType class_clang_type = class_type->GetLayoutCompilerType(); - CompilerType clang_type = ClangASTContext::CreateMemberPointerType( + CompilerType clang_type = TypeSystemClang::CreateMemberPointerType( class_clang_type, pointee_clang_type); if (llvm::Optional<uint64_t> clang_type_size = @@ -1370,6 +1318,28 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType( return nullptr; } +void DWARFASTParserClang::CompleteType(CompilerType type) { + // Technically, enums can be incomplete too, but we don't handle those as they + // are emitted even under -flimit-debug-info. + if (!TypeSystemClang::IsCXXClassType(type)) + return; + + if (type.GetCompleteType()) + return; + + // No complete definition in this module. Mark the class as complete to + // satisfy local ast invariants, but make a note of the fact that + // it is not _really_ complete so we can later search for a definition in a + // different module. + // Since we provide layout assistance, layouts of types containing this class + // will be correct even if we are not able to find the definition elsewhere. + bool started = TypeSystemClang::StartTagDeclarationDefinition(type); + lldbassert(started && "Unable to start a class type definition."); + TypeSystemClang::CompleteTagDeclarationDefinition(type); + const clang::TagDecl *td = ClangUtil::GetAsTagDecl(type); + m_ast.GetMetadata(td)->SetIsForcefullyCompleted(); +} + TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType( const SymbolContext &sc, const DWARFDIE &die, TypeSP type_sp) { if (!type_sp) @@ -1412,7 +1382,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, CompilerType clang_type; const dw_tag_t tag = die.Tag(); SymbolFileDWARF *dwarf = die.GetDWARF(); - LanguageType cu_language = die.GetLanguage(); + LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU()); Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_TYPE_COMPLETION | DWARF_LOG_LOOKUPS); @@ -1544,8 +1514,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, if (type_sp) return type_sp; - DWARFDeclContext die_decl_ctx; - die.GetDWARFDeclContext(die_decl_ctx); + DWARFDeclContext die_decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, // type_name_const_str); @@ -1611,12 +1580,12 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die)); if (attrs.name.GetStringRef().contains('<')) { - ClangASTContext::TemplateParameterInfos template_param_infos; + TypeSystemClang::TemplateParameterInfos template_param_infos; if (ParseTemplateParameterInfos(die, template_param_infos)) { clang::ClassTemplateDecl *class_template_decl = - m_ast.ParseClassTemplateDecl(decl_ctx, attrs.accessibility, - attrs.name.GetCString(), tag_decl_kind, - template_param_infos); + m_ast.ParseClassTemplateDecl( + decl_ctx, GetOwningClangModule(die), attrs.accessibility, + attrs.name.GetCString(), tag_decl_kind, template_param_infos); if (!class_template_decl) { if (log) { dwarf->GetObjectFile()->GetModule()->LogMessage( @@ -1631,8 +1600,8 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, clang::ClassTemplateSpecializationDecl *class_specialization_decl = m_ast.CreateClassTemplateSpecializationDecl( - decl_ctx, class_template_decl, tag_decl_kind, - template_param_infos); + decl_ctx, GetOwningClangModule(die), class_template_decl, + tag_decl_kind, template_param_infos); clang_type = m_ast.CreateClassTemplateSpecializationType( class_specialization_decl); clang_type_was_created = true; @@ -1645,8 +1614,9 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, if (!clang_type_was_created) { clang_type_was_created = true; clang_type = m_ast.CreateRecordType( - decl_ctx, attrs.accessibility, attrs.name.GetCString(), tag_decl_kind, - attrs.class_language, &metadata, attrs.exports_symbols); + decl_ctx, GetOwningClangModule(die), attrs.accessibility, + attrs.name.GetCString(), tag_decl_kind, attrs.class_language, + &metadata, attrs.exports_symbols); } } @@ -1654,12 +1624,11 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, // parameters in any class methods need it for the clang types for // function prototypes. LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die); - type_sp = std::make_shared<Type>(die.GetID(), dwarf, attrs.name, - attrs.byte_size, nullptr, LLDB_INVALID_UID, - Type::eEncodingIsUID, &attrs.decl, - clang_type, Type::ResolveState::Forward); - - type_sp->SetIsCompleteObjCClass(attrs.is_complete_objc_class); + type_sp = std::make_shared<Type>( + die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, + LLDB_INVALID_UID, Type::eEncodingIsUID, &attrs.decl, clang_type, + Type::ResolveState::Forward, + TypePayloadClang(OptionalClangModuleID(), attrs.is_complete_objc_class)); // 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 @@ -1705,8 +1674,8 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, // these child definitions. if (!die.HasChildren()) { // No children for this struct/union/class, lets finish it - if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) { - ClangASTContext::CompleteTagDeclarationDefinition(clang_type); + if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) { + TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); } else { dwarf->GetObjectFile()->GetModule()->ReportError( "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its " @@ -1718,7 +1687,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, if (tag == DW_TAG_structure_type) // this only applies in C { clang::RecordDecl *record_decl = - ClangASTContext::GetAsRecordDecl(clang_type); + TypeSystemClang::GetAsRecordDecl(clang_type); if (record_decl) { GetClangASTImporter().SetRecordLayout( @@ -1736,7 +1705,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, if (attrs.class_language != eLanguageTypeObjC && attrs.class_language != eLanguageTypeObjC_plus_plus) - ClangASTContext::StartTagDeclarationDefinition(clang_type); + TypeSystemClang::StartTagDeclarationDefinition(clang_type); // Leave this as a forward declaration until we need to know the // details of the type. lldb_private::Type will automatically call @@ -1752,9 +1721,9 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, // binaries. dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = clang_type.GetOpaqueQualType(); - dwarf->GetForwardDeclClangTypeToDie() - [ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] = - die.GetID(); + dwarf->GetForwardDeclClangTypeToDie().try_emplace( + ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType(), + *die.GetDIERef()); m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true); } } @@ -1799,7 +1768,7 @@ public: m_property_getter_name(property_getter_name), m_property_attributes(property_attributes) { if (metadata != nullptr) { - m_metadata_up.reset(new ClangASTMetadata()); + m_metadata_up = std::make_unique<ClangASTMetadata>(); *m_metadata_up = *metadata; } } @@ -1819,14 +1788,14 @@ public: m_property_attributes = rhs.m_property_attributes; if (rhs.m_metadata_up) { - m_metadata_up.reset(new ClangASTMetadata()); + m_metadata_up = std::make_unique<ClangASTMetadata>(); *m_metadata_up = *rhs.m_metadata_up; } return *this; } bool Finalize() { - return ClangASTContext::AddObjCClassProperty( + return TypeSystemClang::AddObjCClassProperty( m_class_opaque_type, m_property_name, m_property_opaque_type, m_ivar_decl, m_property_setter_name, m_property_getter_name, m_property_attributes, m_metadata_up.get()); @@ -1845,14 +1814,14 @@ private: bool DWARFASTParserClang::ParseTemplateDIE( const DWARFDIE &die, - ClangASTContext::TemplateParameterInfos &template_param_infos) { + TypeSystemClang::TemplateParameterInfos &template_param_infos) { const dw_tag_t tag = die.Tag(); bool is_template_template_argument = false; switch (tag) { case DW_TAG_GNU_template_parameter_pack: { - template_param_infos.packed_args.reset( - new ClangASTContext::TemplateParameterInfos); + template_param_infos.packed_args = + std::make_unique<TypeSystemClang::TemplateParameterInfos>(); for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); child_die = child_die.GetSibling()) { if (!ParseTemplateDIE(child_die, *template_param_infos.packed_args)) @@ -1954,7 +1923,7 @@ bool DWARFASTParserClang::ParseTemplateDIE( bool DWARFASTParserClang::ParseTemplateParameterInfos( const DWARFDIE &parent_die, - ClangASTContext::TemplateParameterInfos &template_param_infos) { + TypeSystemClang::TemplateParameterInfos &template_param_infos) { if (!parent_die) return false; @@ -1988,141 +1957,102 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, ClangASTImporter::LayoutInfo layout_info; - { - if (die.HasChildren()) { - LanguageType class_language = eLanguageTypeUnknown; - if (ClangASTContext::IsObjCObjectOrInterfaceType(clang_type)) { - class_language = eLanguageTypeObjC; - // For objective C we don't start the definition when the class is - // created. - ClangASTContext::StartTagDeclarationDefinition(clang_type); - } - - 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; - } - - std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases; - std::vector<int> member_accessibilities; - bool is_a_class = false; - // Parse members and base classes first - std::vector<DWARFDIE> member_function_dies; - - DelayedPropertyList delayed_properties; - ParseChildMembers(die, clang_type, class_language, bases, - member_accessibilities, member_function_dies, - delayed_properties, default_accessibility, is_a_class, - layout_info); - - // Now parse any methods if there were any... - for (const DWARFDIE &die : member_function_dies) - dwarf->ResolveType(die); - - if (class_language == eLanguageTypeObjC) { - ConstString class_name(clang_type.GetTypeName()); - if (class_name) { - DIEArray method_die_offsets; - dwarf->GetObjCMethodDIEOffsets(class_name, method_die_offsets); - - if (!method_die_offsets.empty()) { - DWARFDebugInfo *debug_info = dwarf->DebugInfo(); - - const size_t num_matches = method_die_offsets.size(); - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = method_die_offsets[i]; - DWARFDIE method_die = debug_info->GetDIE(die_ref); - - if (method_die) - method_die.ResolveType(); - } - } - - for (DelayedPropertyList::iterator pi = delayed_properties.begin(), - pe = delayed_properties.end(); - pi != pe; ++pi) - pi->Finalize(); - } - } + if (die.HasChildren()) { + const bool type_is_objc_object_or_interface = + TypeSystemClang::IsObjCObjectOrInterfaceType(clang_type); + if (type_is_objc_object_or_interface) { + // For objective C we don't start the definition when the class is + // created. + TypeSystemClang::StartTagDeclarationDefinition(clang_type); + } + + 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; + } + + std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases; + std::vector<int> member_accessibilities; + bool is_a_class = false; + // Parse members and base classes first + std::vector<DWARFDIE> member_function_dies; + + DelayedPropertyList delayed_properties; + ParseChildMembers(die, clang_type, bases, member_accessibilities, + member_function_dies, delayed_properties, + default_accessibility, is_a_class, layout_info); + + // Now parse any methods if there were any... + for (const DWARFDIE &die : member_function_dies) + dwarf->ResolveType(die); + + if (type_is_objc_object_or_interface) { + ConstString class_name(clang_type.GetTypeName()); + if (class_name) { + dwarf->GetObjCMethods(class_name, [&](DWARFDIE method_die) { + method_die.ResolveType(); + return true; + }); - // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we - // need to tell the clang type it is actually a class. - if (class_language != eLanguageTypeObjC) { - if (is_a_class && tag_decl_kind != clang::TTK_Class) - m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type), - clang::TTK_Class); + for (DelayedPropertyList::iterator pi = delayed_properties.begin(), + pe = delayed_properties.end(); + pi != pe; ++pi) + pi->Finalize(); } + } - // Since DW_TAG_structure_type gets used for both classes and - // structures, we may need to set any DW_TAG_member fields to have a - // "private" access if none was specified. When we parsed the child - // members we tracked that actual accessibility value for each - // DW_TAG_member in the "member_accessibilities" array. If the value - // for the member is zero, then it was set to the - // "default_accessibility" which for structs was "public". Below we - // correct this by setting any fields to "private" that weren't - // correctly set. - if (is_a_class && !member_accessibilities.empty()) { - // This is a class and all members that didn't have their access - // specified are private. - m_ast.SetDefaultAccessForRecordFields( - m_ast.GetAsRecordDecl(clang_type), eAccessPrivate, - &member_accessibilities.front(), member_accessibilities.size()); + // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we + // need to tell the clang type it is actually a class. + if (!type_is_objc_object_or_interface) { + if (is_a_class && tag_decl_kind != clang::TTK_Class) + m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type), + clang::TTK_Class); + } + + // Since DW_TAG_structure_type gets used for both classes and + // structures, we may need to set any DW_TAG_member fields to have a + // "private" access if none was specified. When we parsed the child + // members we tracked that actual accessibility value for each + // DW_TAG_member in the "member_accessibilities" array. If the value + // for the member is zero, then it was set to the + // "default_accessibility" which for structs was "public". Below we + // correct this by setting any fields to "private" that weren't + // correctly set. + if (is_a_class && !member_accessibilities.empty()) { + // This is a class and all members that didn't have their access + // specified are private. + m_ast.SetDefaultAccessForRecordFields( + m_ast.GetAsRecordDecl(clang_type), eAccessPrivate, + &member_accessibilities.front(), member_accessibilities.size()); + } + + if (!bases.empty()) { + // Make sure all base classes refer to complete types and not forward + // declarations. If we don't do this, clang will crash with an + // assertion in the call to clang_type.TransferBaseClasses() + for (const auto &base_class : bases) { + clang::TypeSourceInfo *type_source_info = + base_class->getTypeSourceInfo(); + if (type_source_info) + CompleteType(m_ast.GetType(type_source_info->getType())); } - if (!bases.empty()) { - // Make sure all base classes refer to complete types and not forward - // declarations. If we don't do this, clang will crash with an - // assertion in the call to clang_type.TransferBaseClasses() - for (const auto &base_class : bases) { - clang::TypeSourceInfo *type_source_info = - base_class->getTypeSourceInfo(); - if (type_source_info) { - CompilerType base_class_type = - m_ast.GetType(type_source_info->getType()); - if (!base_class_type.GetCompleteType()) { - auto module = dwarf->GetObjectFile()->GetModule(); - module->ReportError(":: Class '%s' has a base class '%s' which " - "does not have a complete definition.", - die.GetName(), - base_class_type.GetTypeName().GetCString()); - if (die.GetCU()->GetProducer() == eProducerClang) - module->ReportError(":: Try compiling the source file with " - "-fstandalone-debug."); - - // We have no choice other than to pretend that the base class - // is complete. If we don't do this, clang will crash when we - // call setBases() inside of - // "clang_type.TransferBaseClasses()" below. Since we - // provide layout assistance, all ivars in this class and other - // classes will be fine, this is the best we can do short of - // crashing. - if (ClangASTContext::StartTagDeclarationDefinition( - base_class_type)) { - ClangASTContext::CompleteTagDeclarationDefinition( - base_class_type); - } - } - } - } - - m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(), - std::move(bases)); - } + m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(), + std::move(bases)); } } m_ast.AddMethodOverridesForCXXRecordType(clang_type.GetOpaqueQualType()); - ClangASTContext::BuildIndirectFields(clang_type); - ClangASTContext::CompleteTagDeclarationDefinition(clang_type); + TypeSystemClang::BuildIndirectFields(clang_type); + TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); if (!layout_info.field_offsets.empty() || !layout_info.base_offsets.empty() || !layout_info.vbase_offsets.empty()) { @@ -2144,14 +2074,14 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, bool DWARFASTParserClang::CompleteEnumType(const DWARFDIE &die, lldb_private::Type *type, CompilerType &clang_type) { - if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) { + if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) { if (die.HasChildren()) { bool is_signed = false; clang_type.IsIntegerType(is_signed); ParseChildEnumerators(clang_type, is_signed, type->GetByteSize().getValueOr(0), die); } - ClangASTContext::CompleteTagDeclarationDefinition(clang_type); + TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); } return (bool)clang_type; } @@ -2211,7 +2141,7 @@ void DWARFASTParserClang::EnsureAllDIEsInDeclContextHaveBeenParsed( CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) { clang::Decl *clang_decl = GetClangDeclForDIE(die); if (clang_decl != nullptr) - return CompilerDecl(&m_ast, clang_decl); + return m_ast.GetCompilerDecl(clang_decl); return CompilerDecl(); } @@ -2340,9 +2270,11 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, func_name.SetValue(ConstString(mangled), true); else if ((die.GetParent().Tag() == DW_TAG_compile_unit || die.GetParent().Tag() == DW_TAG_partial_unit) && - Language::LanguageIsCPlusPlus(die.GetLanguage()) && - !Language::LanguageIsObjC(die.GetLanguage()) && name && - strcmp(name, "main") != 0) { + Language::LanguageIsCPlusPlus( + SymbolFileDWARF::GetLanguage(*die.GetCU())) && + !Language::LanguageIsObjC( + SymbolFileDWARF::GetLanguage(*die.GetCU())) && + name && strcmp(name, "main") != 0) { // If the mangled name is not present in the DWARF, generate the // demangled name using the decl context. We skip if the function is // "main" as its name is never mangled. @@ -2352,10 +2284,9 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, unsigned type_quals = 0; std::vector<CompilerType> param_types; std::vector<clang::ParmVarDecl *> param_decls; - DWARFDeclContext decl_ctx; StreamString sstr; - die.GetDWARFDeclContext(decl_ctx); + DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); sstr << decl_ctx.GetQualifiedName(); clang::DeclContext *containing_decl_ctx = @@ -2382,8 +2313,8 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, FunctionSP func_sp; std::unique_ptr<Declaration> decl_up; if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_up.reset(new Declaration(die.GetCU()->GetFile(decl_file), - decl_line, decl_column)); + decl_up = std::make_unique<Declaration>(die.GetCU()->GetFile(decl_file), + decl_line, decl_column); SymbolFileDWARF *dwarf = die.GetDWARF(); // Supply the type _only_ if it has already been parsed @@ -2413,13 +2344,12 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, void DWARFASTParserClang::ParseSingleMember( const DWARFDIE &die, const DWARFDIE &parent_die, - lldb_private::CompilerType &class_clang_type, - const lldb::LanguageType class_language, + const lldb_private::CompilerType &class_clang_type, std::vector<int> &member_accessibilities, - lldb::AccessType &default_accessibility, + lldb::AccessType default_accessibility, DelayedPropertyList &delayed_properties, lldb_private::ClangASTImporter::LayoutInfo &layout_info, - BitfieldInfo &last_field_info) { + FieldInfo &last_field_info) { ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule(); const dw_tag_t tag = die.Tag(); // Get the parent byte size so we can verify any members will fit @@ -2430,453 +2360,400 @@ void DWARFASTParserClang::ParseSingleMember( DWARFAttributes attributes; const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes > 0) { - const char *name = nullptr; - const char *prop_name = nullptr; - const char *prop_getter_name = nullptr; - const char *prop_setter_name = nullptr; - uint32_t prop_attributes = 0; - - bool is_artificial = false; - DWARFFormValue encoding_form; - AccessType accessibility = eAccessNone; - uint32_t member_byte_offset = - (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX; - llvm::Optional<uint64_t> byte_size; - int64_t bit_offset = 0; - uint64_t data_bit_offset = UINT64_MAX; - size_t bit_size = 0; - bool is_external = - false; // On DW_TAG_members, this means the member is static - uint32_t i; - for (i = 0; i < num_attributes && !is_artificial; ++i) { - const dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - name = form_value.AsCString(); - break; - case DW_AT_type: - encoding_form = form_value; - break; - case DW_AT_bit_offset: - bit_offset = form_value.Signed(); - break; - case DW_AT_bit_size: - bit_size = form_value.Unsigned(); - break; - case DW_AT_byte_size: - byte_size = form_value.Unsigned(); - break; - case DW_AT_data_bit_offset: - data_bit_offset = form_value.Unsigned(); - break; - case DW_AT_data_member_location: - if (form_value.BlockData()) { - Value initialValue(0); - Value memberOffset(0); - const DWARFDataExtractor &debug_info_data = die.GetData(); - uint32_t block_length = form_value.Unsigned(); - uint32_t block_offset = - form_value.BlockData() - debug_info_data.GetDataStart(); - if (DWARFExpression::Evaluate( - nullptr, // ExecutionContext * - nullptr, // RegisterContext * - module_sp, - DataExtractor(debug_info_data, block_offset, block_length), - die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr, - memberOffset, nullptr)) { - member_byte_offset = memberOffset.ResolveValue(nullptr).UInt(); - } - } else { - // With DWARF 3 and later, if the value is an integer constant, - // this form value is the offset in bytes from the beginning of - // the containing entity. - member_byte_offset = form_value.Unsigned(); + if (num_attributes == 0) + return; + + const char *name = nullptr; + const char *prop_name = nullptr; + const char *prop_getter_name = nullptr; + const char *prop_setter_name = nullptr; + uint32_t prop_attributes = 0; + + bool is_artificial = false; + DWARFFormValue encoding_form; + AccessType accessibility = eAccessNone; + uint32_t member_byte_offset = + (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX; + llvm::Optional<uint64_t> byte_size; + int64_t bit_offset = 0; + uint64_t data_bit_offset = UINT64_MAX; + size_t bit_size = 0; + bool is_external = + false; // On DW_TAG_members, this means the member is static + uint32_t i; + for (i = 0; i < num_attributes && !is_artificial; ++i) { + const dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + // DW_AT_data_member_location indicates the byte offset of the + // word from the base address of the structure. + // + // DW_AT_bit_offset indicates how many bits into the word + // (according to the host endianness) the low-order bit of the + // field starts. AT_bit_offset can be negative. + // + // DW_AT_bit_size indicates the size of the field in bits. + switch (attr) { + case DW_AT_name: + name = form_value.AsCString(); + break; + case DW_AT_type: + encoding_form = form_value; + break; + case DW_AT_bit_offset: + bit_offset = form_value.Signed(); + break; + case DW_AT_bit_size: + bit_size = form_value.Unsigned(); + break; + case DW_AT_byte_size: + byte_size = form_value.Unsigned(); + break; + case DW_AT_data_bit_offset: + data_bit_offset = form_value.Unsigned(); + break; + case DW_AT_data_member_location: + if (form_value.BlockData()) { + Value initialValue(0); + Value memberOffset(0); + const DWARFDataExtractor &debug_info_data = die.GetData(); + uint32_t block_length = form_value.Unsigned(); + uint32_t block_offset = + form_value.BlockData() - debug_info_data.GetDataStart(); + if (DWARFExpression::Evaluate( + nullptr, // ExecutionContext * + nullptr, // RegisterContext * + module_sp, + DataExtractor(debug_info_data, block_offset, block_length), + die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr, + memberOffset, nullptr)) { + member_byte_offset = memberOffset.ResolveValue(nullptr).UInt(); } - break; + } else { + // With DWARF 3 and later, if the value is an integer constant, + // this form value is the offset in bytes from the beginning of + // the containing entity. + member_byte_offset = form_value.Unsigned(); + } + break; - case DW_AT_accessibility: - accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); - break; - case DW_AT_artificial: - is_artificial = form_value.Boolean(); - break; - case DW_AT_APPLE_property_name: - prop_name = form_value.AsCString(); - break; - case DW_AT_APPLE_property_getter: - prop_getter_name = form_value.AsCString(); - break; - case DW_AT_APPLE_property_setter: - prop_setter_name = form_value.AsCString(); - break; - case DW_AT_APPLE_property_attribute: - prop_attributes = form_value.Unsigned(); - break; - case DW_AT_external: - is_external = form_value.Boolean(); - break; + case DW_AT_accessibility: + accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); + break; + case DW_AT_artificial: + is_artificial = form_value.Boolean(); + break; + case DW_AT_APPLE_property_name: + prop_name = form_value.AsCString(); + break; + case DW_AT_APPLE_property_getter: + prop_getter_name = form_value.AsCString(); + break; + case DW_AT_APPLE_property_setter: + prop_setter_name = form_value.AsCString(); + break; + case DW_AT_APPLE_property_attribute: + prop_attributes = form_value.Unsigned(); + break; + case DW_AT_external: + is_external = form_value.Boolean(); + break; - default: - case DW_AT_declaration: - case DW_AT_description: - case DW_AT_mutable: - case DW_AT_visibility: - case DW_AT_sibling: - break; - } + default: + case DW_AT_declaration: + case DW_AT_description: + case DW_AT_mutable: + case DW_AT_visibility: + case DW_AT_sibling: + break; } } + } - if (prop_name) { - ConstString fixed_setter; + if (prop_name) { + ConstString fixed_setter; - // Check if the property getter/setter were provided as full names. - // We want basenames, so we extract them. + // Check if the property getter/setter were provided as full names. + // We want basenames, so we extract them. - if (prop_getter_name && prop_getter_name[0] == '-') { - ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true); - prop_getter_name = prop_getter_method.GetSelector().GetCString(); - } + if (prop_getter_name && prop_getter_name[0] == '-') { + ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true); + prop_getter_name = prop_getter_method.GetSelector().GetCString(); + } - if (prop_setter_name && prop_setter_name[0] == '-') { - ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true); - prop_setter_name = prop_setter_method.GetSelector().GetCString(); - } + if (prop_setter_name && prop_setter_name[0] == '-') { + ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true); + prop_setter_name = prop_setter_method.GetSelector().GetCString(); + } - // If the names haven't been provided, they need to be filled in. + // If the names haven't been provided, they need to be filled in. - if (!prop_getter_name) { - prop_getter_name = prop_name; - } - if (!prop_setter_name && prop_name[0] && - !(prop_attributes & DW_APPLE_PROPERTY_readonly)) { - StreamString ss; + if (!prop_getter_name) { + prop_getter_name = prop_name; + } + if (!prop_setter_name && prop_name[0] && + !(prop_attributes & DW_APPLE_PROPERTY_readonly)) { + StreamString ss; - ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]); + ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]); - fixed_setter.SetString(ss.GetString()); - prop_setter_name = fixed_setter.GetCString(); - } + fixed_setter.SetString(ss.GetString()); + prop_setter_name = fixed_setter.GetCString(); } + } - // Clang has a DWARF generation bug where sometimes it represents - // fields that are references with bad byte size and bit size/offset - // information such as: - // - // DW_AT_byte_size( 0x00 ) - // DW_AT_bit_size( 0x40 ) - // DW_AT_bit_offset( 0xffffffffffffffc0 ) - // - // So check the bit offset to make sure it is sane, and if the values - // are not sane, remove them. If we don't do this then we will end up - // with a crash if we try to use this type in an expression when clang - // becomes unhappy with its recycled debug info. + // Clang has a DWARF generation bug where sometimes it represents + // fields that are references with bad byte size and bit size/offset + // information such as: + // + // DW_AT_byte_size( 0x00 ) + // DW_AT_bit_size( 0x40 ) + // DW_AT_bit_offset( 0xffffffffffffffc0 ) + // + // So check the bit offset to make sure it is sane, and if the values + // are not sane, remove them. If we don't do this then we will end up + // with a crash if we try to use this type in an expression when clang + // becomes unhappy with its recycled debug info. + + if (byte_size.getValueOr(0) == 0 && bit_offset < 0) { + bit_size = 0; + bit_offset = 0; + } + + const bool class_is_objc_object_or_interface = + TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type); + + // FIXME: Make Clang ignore Objective-C accessibility for expressions + if (class_is_objc_object_or_interface) + accessibility = eAccessNone; - if (byte_size.getValueOr(0) == 0 && bit_offset < 0) { - bit_size = 0; - bit_offset = 0; + // Handle static members + if (is_external && member_byte_offset == UINT32_MAX) { + Type *var_type = die.ResolveTypeUID(encoding_form.Reference()); + + if (var_type) { + if (accessibility == eAccessNone) + accessibility = eAccessPublic; + TypeSystemClang::AddVariableToRecordType( + class_clang_type, name, var_type->GetLayoutCompilerType(), + accessibility); } + return; + } - // FIXME: Make Clang ignore Objective-C accessibility for expressions - if (class_language == eLanguageTypeObjC || - class_language == eLanguageTypeObjC_plus_plus) - accessibility = eAccessNone; + if (!is_artificial) { + Type *member_type = die.ResolveTypeUID(encoding_form.Reference()); - // Handle static members - if (is_external && member_byte_offset == UINT32_MAX) { - Type *var_type = die.ResolveTypeUID(encoding_form.Reference()); + clang::FieldDecl *field_decl = nullptr; + const uint64_t character_width = 8; + const uint64_t word_width = 32; + if (tag == DW_TAG_member) { + if (member_type) { + CompilerType member_clang_type = member_type->GetLayoutCompilerType(); - if (var_type) { if (accessibility == eAccessNone) - accessibility = eAccessPublic; - ClangASTContext::AddVariableToRecordType( - class_clang_type, name, var_type->GetLayoutCompilerType(), - accessibility); - } - return; - } - - if (!is_artificial) { - Type *member_type = die.ResolveTypeUID(encoding_form.Reference()); - - clang::FieldDecl *field_decl = nullptr; - if (tag == DW_TAG_member) { - if (member_type) { - if (accessibility == eAccessNone) - accessibility = default_accessibility; - member_accessibilities.push_back(accessibility); - - uint64_t field_bit_offset = - (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8)); - if (bit_size > 0) { - - BitfieldInfo this_field_info; - this_field_info.bit_offset = field_bit_offset; - this_field_info.bit_size = bit_size; - - ///////////////////////////////////////////////////////////// - // How to locate a field given the DWARF debug information - // - // AT_byte_size indicates the size of the word in which the bit - // offset must be interpreted. - // - // AT_data_member_location indicates the byte offset of the - // word from the base address of the structure. - // - // AT_bit_offset indicates how many bits into the word - // (according to the host endianness) the low-order bit of the - // field starts. AT_bit_offset can be negative. - // - // AT_bit_size indicates the size of the field in bits. - ///////////////////////////////////////////////////////////// - - if (data_bit_offset != UINT64_MAX) { - this_field_info.bit_offset = data_bit_offset; - } else { - if (!byte_size) - byte_size = member_type->GetByteSize(); + accessibility = default_accessibility; + member_accessibilities.push_back(accessibility); - ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); - if (objfile->GetByteOrder() == eByteOrderLittle) { - this_field_info.bit_offset += byte_size.getValueOr(0) * 8; - this_field_info.bit_offset -= (bit_offset + bit_size); - } else { - this_field_info.bit_offset += bit_offset; - } + uint64_t field_bit_offset = + (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8)); + + if (bit_size > 0) { + FieldInfo this_field_info; + this_field_info.bit_offset = field_bit_offset; + this_field_info.bit_size = bit_size; + + if (data_bit_offset != UINT64_MAX) { + this_field_info.bit_offset = data_bit_offset; + } else { + if (!byte_size) + byte_size = member_type->GetByteSize(); + + ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); + if (objfile->GetByteOrder() == eByteOrderLittle) { + this_field_info.bit_offset += byte_size.getValueOr(0) * 8; + this_field_info.bit_offset -= (bit_offset + bit_size); + } else { + this_field_info.bit_offset += bit_offset; } + } + + if ((this_field_info.bit_offset >= parent_bit_size) || + (last_field_info.IsBitfield() && + !last_field_info.NextBitfieldOffsetIsValid( + this_field_info.bit_offset))) { + ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); + objfile->GetModule()->ReportWarning( + "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid " + "bit offset (0x%8.8" PRIx64 + ") member will be ignored. Please file a bug against the " + "compiler and include the preprocessed output for %s\n", + die.GetID(), DW_TAG_value_to_name(tag), name, + this_field_info.bit_offset, GetUnitName(parent_die).c_str()); + return; + } + + // Update the field bit offset we will report for layout + field_bit_offset = this_field_info.bit_offset; + + // Objective-C has invalid DW_AT_bit_offset values in older + // versions of clang, so we have to be careful and only insert + // unnamed bitfields if we have a new enough clang. + bool detect_unnamed_bitfields = true; + + if (class_is_objc_object_or_interface) + detect_unnamed_bitfields = + die.GetCU()->Supports_unnamed_objc_bitfields(); - if ((this_field_info.bit_offset >= parent_bit_size) || - !last_field_info.NextBitfieldOffsetIsValid( - this_field_info.bit_offset)) { - ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); - objfile->GetModule()->ReportWarning( - "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid " - "bit offset (0x%8.8" PRIx64 - ") member will be ignored. Please file a bug against the " - "compiler and include the preprocessed output for %s\n", - die.GetID(), DW_TAG_value_to_name(tag), name, - this_field_info.bit_offset, GetUnitName(parent_die).c_str()); - this_field_info.Clear(); - return; + if (detect_unnamed_bitfields) { + clang::Optional<FieldInfo> unnamed_field_info; + uint64_t last_field_end = 0; + + last_field_end = + last_field_info.bit_offset + last_field_info.bit_size; + + if (!last_field_info.IsBitfield()) { + // The last field was not a bit-field... + // but if it did take up the entire word then we need to extend + // last_field_end so the bit-field does not step into the last + // fields padding. + if (last_field_end != 0 && ((last_field_end % word_width) != 0)) + last_field_end += word_width - (last_field_end % word_width); } - // Update the field bit offset we will report for layout - field_bit_offset = this_field_info.bit_offset; - - // If the member to be emitted did not start on a character - // boundary and there is empty space between the last field and - // this one, then we need to emit an anonymous member filling - // up the space up to its start. There are three cases here: - // - // 1 If the previous member ended on a character boundary, then - // we can emit an - // anonymous member starting at the most recent character - // boundary. - // - // 2 If the previous member did not end on a character boundary - // and the distance - // from the end of the previous member to the current member - // is less than a - // word width, then we can emit an anonymous member starting - // right after the - // previous member and right before this member. - // - // 3 If the previous member did not end on a character boundary - // and the distance - // from the end of the previous member to the current member - // is greater than - // or equal a word width, then we act as in Case 1. - - const uint64_t character_width = 8; - const uint64_t word_width = 32; - - // Objective-C has invalid DW_AT_bit_offset values in older - // versions of clang, so we have to be careful and only insert - // unnamed bitfields if we have a new enough clang. - bool detect_unnamed_bitfields = true; - - if (class_language == eLanguageTypeObjC || - class_language == eLanguageTypeObjC_plus_plus) - detect_unnamed_bitfields = - die.GetCU()->Supports_unnamed_objc_bitfields(); - - if (detect_unnamed_bitfields) { - BitfieldInfo anon_field_info; - - if ((this_field_info.bit_offset % character_width) != - 0) // not char aligned - { - uint64_t last_field_end = 0; - - if (last_field_info.IsValid()) - last_field_end = - last_field_info.bit_offset + last_field_info.bit_size; - - if (this_field_info.bit_offset != last_field_end) { - if (((last_field_end % character_width) == 0) || // case 1 - (this_field_info.bit_offset - last_field_end >= - word_width)) // case 3 - { - anon_field_info.bit_size = - this_field_info.bit_offset % character_width; - anon_field_info.bit_offset = - this_field_info.bit_offset - anon_field_info.bit_size; - } else // case 2 - { - anon_field_info.bit_size = - this_field_info.bit_offset - last_field_end; - anon_field_info.bit_offset = last_field_end; - } - } - } + // If we have a gap between the last_field_end and the current + // field we have an unnamed bit-field. + // If we have a base class, we assume there is no unnamed + // bit-field if this is the first field since the gap can be + // attributed to the members from the base class. This assumption + // is not correct if the first field of the derived class is + // indeed an unnamed bit-field. We currently do not have the + // machinary to track the offset of the last field of classes we + // have seen before, so we are not handling this case. + if (this_field_info.bit_offset != last_field_end && + this_field_info.bit_offset > last_field_end && + !(last_field_info.bit_offset == 0 && + last_field_info.bit_size == 0 && + layout_info.base_offsets.size() != 0)) { + unnamed_field_info = FieldInfo{}; + unnamed_field_info->bit_size = + this_field_info.bit_offset - last_field_end; + unnamed_field_info->bit_offset = last_field_end; + } - if (anon_field_info.IsValid()) { - clang::FieldDecl *unnamed_bitfield_decl = - ClangASTContext::AddFieldToRecordType( - class_clang_type, llvm::StringRef(), - m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, - word_width), - accessibility, anon_field_info.bit_size); + if (unnamed_field_info) { + clang::FieldDecl *unnamed_bitfield_decl = + TypeSystemClang::AddFieldToRecordType( + class_clang_type, llvm::StringRef(), + m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, + word_width), + accessibility, unnamed_field_info->bit_size); - layout_info.field_offsets.insert(std::make_pair( - unnamed_bitfield_decl, anon_field_info.bit_offset)); - } + layout_info.field_offsets.insert(std::make_pair( + unnamed_bitfield_decl, unnamed_field_info->bit_offset)); } - last_field_info = this_field_info; - } else { - last_field_info.Clear(); } - CompilerType member_clang_type = member_type->GetLayoutCompilerType(); - if (!member_clang_type.IsCompleteType()) - member_clang_type.GetCompleteType(); - - { - // Older versions of clang emit array[0] and array[1] in the - // same way (<rdar://problem/12566646>). If the current field - // is at the end of the structure, then there is definitely no - // room for extra elements and we override the type to - // array[0]. - - CompilerType member_array_element_type; - uint64_t member_array_size; - bool member_array_is_incomplete; - - if (member_clang_type.IsArrayType(&member_array_element_type, - &member_array_size, - &member_array_is_incomplete) && - !member_array_is_incomplete) { - uint64_t parent_byte_size = - parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, - UINT64_MAX); - - if (member_byte_offset >= parent_byte_size) { - if (member_array_size != 1 && - (member_array_size != 0 || - member_byte_offset > parent_byte_size)) { - module_sp->ReportError( - "0x%8.8" PRIx64 - ": DW_TAG_member '%s' refers to type 0x%8.8x" - " which extends beyond the bounds of 0x%8.8" PRIx64, - die.GetID(), name, encoding_form.Reference().GetOffset(), - parent_die.GetID()); - } + last_field_info = this_field_info; + last_field_info.SetIsBitfield(true); + } else { + last_field_info.bit_offset = field_bit_offset; - member_clang_type = - m_ast.CreateArrayType(member_array_element_type, 0, false); - } - } + if (llvm::Optional<uint64_t> clang_type_size = + member_clang_type.GetByteSize(nullptr)) { + last_field_info.bit_size = *clang_type_size * character_width; } - if (ClangASTContext::IsCXXClassType(member_clang_type) && - !member_clang_type.GetCompleteType()) { - if (die.GetCU()->GetProducer() == eProducerClang) - module_sp->ReportError( - "DWARF DIE at 0x%8.8x (class %s) has a member variable " - "0x%8.8x (%s) whose type is a forward declaration, not a " - "complete definition.\nTry compiling the source file " - "with -fstandalone-debug", - parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(), - name); - else - module_sp->ReportError( - "DWARF DIE at 0x%8.8x (class %s) has a member variable " - "0x%8.8x (%s) whose type is a forward declaration, not a " - "complete definition.\nPlease file a bug against the " - "compiler and include the preprocessed output for %s", - parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(), - name, GetUnitName(parent_die).c_str()); - // We have no choice other than to pretend that the member - // class is complete. If we don't do this, clang will crash - // when trying to layout the class. Since we provide layout - // assistance, all ivars in this class and other classes will - // be fine, this is the best we can do short of crashing. - if (ClangASTContext::StartTagDeclarationDefinition( - member_clang_type)) { - ClangASTContext::CompleteTagDeclarationDefinition( - member_clang_type); - } else { - module_sp->ReportError( - "DWARF DIE at 0x%8.8x (class %s) has a member variable " - "0x%8.8x (%s) whose type claims to be a C++ class but we " - "were not able to start its definition.\nPlease file a " - "bug and attach the file at the start of this error " - "message", - parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(), - name); + last_field_info.SetIsBitfield(false); + } + + if (!member_clang_type.IsCompleteType()) + member_clang_type.GetCompleteType(); + + { + // Older versions of clang emit array[0] and array[1] in the + // same way (<rdar://problem/12566646>). If the current field + // is at the end of the structure, then there is definitely no + // room for extra elements and we override the type to + // array[0]. + + CompilerType member_array_element_type; + uint64_t member_array_size; + bool member_array_is_incomplete; + + if (member_clang_type.IsArrayType(&member_array_element_type, + &member_array_size, + &member_array_is_incomplete) && + !member_array_is_incomplete) { + uint64_t parent_byte_size = + parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, + UINT64_MAX); + + if (member_byte_offset >= parent_byte_size) { + if (member_array_size != 1 && + (member_array_size != 0 || + member_byte_offset > parent_byte_size)) { + module_sp->ReportError( + "0x%8.8" PRIx64 + ": DW_TAG_member '%s' refers to type 0x%8.8x" + " which extends beyond the bounds of 0x%8.8" PRIx64, + die.GetID(), name, encoding_form.Reference().GetOffset(), + parent_die.GetID()); + } + + member_clang_type = + m_ast.CreateArrayType(member_array_element_type, 0, false); } } + } - field_decl = ClangASTContext::AddFieldToRecordType( - class_clang_type, name, member_clang_type, accessibility, - bit_size); + CompleteType(member_clang_type); - m_ast.SetMetadataAsUserID(field_decl, die.GetID()); + field_decl = TypeSystemClang::AddFieldToRecordType( + class_clang_type, name, member_clang_type, accessibility, + bit_size); - layout_info.field_offsets.insert( - std::make_pair(field_decl, field_bit_offset)); - } else { - if (name) - module_sp->ReportError( - "0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8x" - " which was unable to be parsed", - die.GetID(), name, encoding_form.Reference().GetOffset()); - else - module_sp->ReportError( - "0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8x" - " which was unable to be parsed", - die.GetID(), encoding_form.Reference().GetOffset()); - } + m_ast.SetMetadataAsUserID(field_decl, die.GetID()); + + layout_info.field_offsets.insert( + std::make_pair(field_decl, field_bit_offset)); + } else { + if (name) + module_sp->ReportError( + "0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8x" + " which was unable to be parsed", + die.GetID(), name, encoding_form.Reference().GetOffset()); + else + module_sp->ReportError( + "0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8x" + " which was unable to be parsed", + die.GetID(), encoding_form.Reference().GetOffset()); } + } - if (prop_name != nullptr && member_type) { - clang::ObjCIvarDecl *ivar_decl = nullptr; + if (prop_name != nullptr && member_type) { + clang::ObjCIvarDecl *ivar_decl = nullptr; - if (field_decl) { - ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl); - assert(ivar_decl != nullptr); - } + if (field_decl) { + ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl); + assert(ivar_decl != nullptr); + } - ClangASTMetadata metadata; - metadata.SetUserID(die.GetID()); - delayed_properties.push_back(DelayedAddObjCClassProperty( - class_clang_type, prop_name, member_type->GetLayoutCompilerType(), - ivar_decl, prop_setter_name, prop_getter_name, prop_attributes, - &metadata)); + ClangASTMetadata metadata; + metadata.SetUserID(die.GetID()); + delayed_properties.push_back(DelayedAddObjCClassProperty( + class_clang_type, prop_name, member_type->GetLayoutCompilerType(), + ivar_decl, prop_setter_name, prop_getter_name, prop_attributes, + &metadata)); - if (ivar_decl) - m_ast.SetMetadataAsUserID(ivar_decl, die.GetID()); - } + if (ivar_decl) + m_ast.SetMetadataAsUserID(ivar_decl, die.GetID()); } } } bool DWARFASTParserClang::ParseChildMembers( const DWARFDIE &parent_die, CompilerType &class_clang_type, - const LanguageType class_language, std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes, std::vector<int> &member_accessibilities, std::vector<DWARFDIE> &member_function_dies, @@ -2885,11 +2762,11 @@ bool DWARFASTParserClang::ParseChildMembers( if (!parent_die) return false; - BitfieldInfo last_field_info; + FieldInfo last_field_info; ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule(); - ClangASTContext *ast = - llvm::dyn_cast_or_null<ClangASTContext>(class_clang_type.GetTypeSystem()); + TypeSystemClang *ast = + llvm::dyn_cast_or_null<TypeSystemClang>(class_clang_type.GetTypeSystem()); if (ast == nullptr) return false; @@ -2900,7 +2777,7 @@ bool DWARFASTParserClang::ParseChildMembers( switch (tag) { case DW_TAG_member: case DW_TAG_APPLE_property: - ParseSingleMember(die, parent_die, class_clang_type, class_language, + ParseSingleMember(die, parent_die, class_clang_type, member_accessibilities, default_accessibility, delayed_properties, layout_info, last_field_info); break; @@ -2990,7 +2867,7 @@ bool DWARFASTParserClang::ParseChildMembers( CompilerType base_class_clang_type = base_class_type->GetFullCompilerType(); assert(base_class_clang_type); - if (class_language == eLanguageTypeObjC) { + if (TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type)) { ast->SetObjCSuperClass(class_clang_type, base_class_clang_type); } else { std::unique_ptr<clang::CXXBaseSpecifier> result = @@ -3121,9 +2998,9 @@ size_t DWARFASTParserClang::ParseChildParameters( function_param_types.push_back(type->GetForwardCompilerType()); clang::ParmVarDecl *param_var_decl = - m_ast.CreateParameterDeclaration(containing_decl_ctx, name, - type->GetForwardCompilerType(), - storage); + m_ast.CreateParameterDeclaration( + containing_decl_ctx, GetOwningClangModule(die), name, + type->GetForwardCompilerType(), storage); assert(param_var_decl); function_param_decls.push_back(param_var_decl); @@ -3318,10 +3195,10 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) { if (dwarf && type) { const char *name = die.GetName(); clang::DeclContext *decl_context = - ClangASTContext::DeclContextGetAsDeclContext( + TypeSystemClang::DeclContextGetAsDeclContext( dwarf->GetDeclContextContainingUID(die.GetID())); decl = m_ast.CreateVariableDeclaration( - decl_context, name, + decl_context, GetOwningClangModule(die), name, ClangUtil::GetQualType(type->GetForwardCompilerType())); } break; @@ -3330,16 +3207,16 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) { SymbolFileDWARF *dwarf = die.GetDWARF(); DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import); if (imported_uid) { - CompilerDecl imported_decl = imported_uid.GetDecl(); + CompilerDecl imported_decl = SymbolFileDWARF::GetDecl(imported_uid); if (imported_decl) { clang::DeclContext *decl_context = - ClangASTContext::DeclContextGetAsDeclContext( + TypeSystemClang::DeclContextGetAsDeclContext( dwarf->GetDeclContextContainingUID(die.GetID())); if (clang::NamedDecl *clang_imported_decl = llvm::dyn_cast<clang::NamedDecl>( (clang::Decl *)imported_decl.GetOpaqueDecl())) - decl = - m_ast.CreateUsingDeclaration(decl_context, clang_imported_decl); + decl = m_ast.CreateUsingDeclaration( + decl_context, OptionalClangModuleID(), clang_imported_decl); } } break; @@ -3349,15 +3226,17 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) { DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import); if (imported_uid) { - CompilerDeclContext imported_decl_ctx = imported_uid.GetDeclContext(); + CompilerDeclContext imported_decl_ctx = + SymbolFileDWARF::GetDeclContext(imported_uid); if (imported_decl_ctx) { clang::DeclContext *decl_context = - ClangASTContext::DeclContextGetAsDeclContext( + TypeSystemClang::DeclContextGetAsDeclContext( dwarf->GetDeclContextContainingUID(die.GetID())); if (clang::NamespaceDecl *ns_decl = - ClangASTContext::DeclContextGetAsNamespaceDecl( + TypeSystemClang::DeclContextGetAsNamespaceDecl( imported_decl_ctx)) - decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl); + decl = m_ast.CreateUsingDirectiveDeclaration( + decl_context, OptionalClangModuleID(), ns_decl); } } break; @@ -3415,6 +3294,32 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) { return nullptr; } +OptionalClangModuleID +DWARFASTParserClang::GetOwningClangModule(const DWARFDIE &die) { + if (!die.IsValid()) + return {}; + + for (DWARFDIE parent = die.GetParent(); parent.IsValid(); + parent = parent.GetParent()) { + const dw_tag_t tag = parent.Tag(); + if (tag == DW_TAG_module) { + DWARFDIE module_die = parent; + auto it = m_die_to_module.find(module_die.GetDIE()); + if (it != m_die_to_module.end()) + return it->second; + const char *name = module_die.GetAttributeValueAsString(DW_AT_name, 0); + if (!name) + return {}; + + OptionalClangModuleID id = + m_ast.GetOrCreateClangModule(name, GetOwningClangModule(module_die)); + m_die_to_module.insert({module_die.GetDIE(), id}); + return id; + } + } + return {}; +} + static bool IsSubroutine(const DWARFDIE &die) { switch (die.Tag()) { case DW_TAG_subprogram: @@ -3487,7 +3392,8 @@ clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) { DWARFDIE decl_context_die; clang::DeclContext *decl_context = GetClangDeclContextContainingDIE(die, &decl_context_die); - decl = m_ast.CreateBlockDeclaration(decl_context); + decl = + m_ast.CreateBlockDeclaration(decl_context, GetOwningClangModule(die)); if (decl) LinkDeclContextToDIE((clang::DeclContext *)decl, die); @@ -3515,7 +3421,8 @@ DWARFASTParserClang::ResolveNamespaceDIE(const DWARFDIE &die) { die.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0; namespace_decl = m_ast.GetUniqueNamespaceDeclaration( - namespace_name, containing_decl_ctx, is_inline); + namespace_name, containing_decl_ctx, GetOwningClangModule(die), + is_inline); Log *log = nullptr; // (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); if (log) { @@ -3697,9 +3604,11 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( } DWARFASTParserClang *src_dwarf_ast_parser = - (DWARFASTParserClang *)src_die.GetDWARFParser(); + static_cast<DWARFASTParserClang *>( + SymbolFileDWARF::GetDWARFParser(*src_die.GetCU())); DWARFASTParserClang *dst_dwarf_ast_parser = - (DWARFASTParserClang *)dst_die.GetDWARFParser(); + static_cast<DWARFASTParserClang *>( + SymbolFileDWARF::GetDWARFParser(*dst_die.GetCU())); // Now do the work of linking the DeclContexts and Types. if (fast_path) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 4ad757247c3e..2ef49abc1da1 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFASTParserClang_h_ -#define SymbolFileDWARF_DWARFASTParserClang_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H #include "clang/AST/CharUnits.h" #include "llvm/ADT/DenseMap.h" @@ -19,10 +19,10 @@ #include "DWARFDefines.h" #include "DWARFFormValue.h" #include "LogChannelDWARF.h" -#include "lldb/Core/ClangForward.h" #include "lldb/Core/PluginInterface.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangASTImporter.h" + +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include <vector> @@ -36,7 +36,7 @@ struct ParsedDWARFTypeAttributes; class DWARFASTParserClang : public DWARFASTParser { public: - DWARFASTParserClang(lldb_private::ClangASTContext &ast); + DWARFASTParserClang(lldb_private::TypeSystemClang &ast); ~DWARFASTParserClang() override; @@ -78,15 +78,19 @@ protected: DIEToDeclContextMap; typedef std::multimap<const clang::DeclContext *, const DWARFDIE> DeclContextToDIEMap; + typedef llvm::DenseMap<const DWARFDebugInfoEntry *, + lldb_private::OptionalClangModuleID> + DIEToModuleMap; typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *> DIEToDeclMap; typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap; - lldb_private::ClangASTContext &m_ast; + lldb_private::TypeSystemClang &m_ast; DIEToDeclMap m_die_to_decl; DeclToDIEMap m_decl_to_die; DIEToDeclContextMap m_die_to_decl_ctx; DeclContextToDIEMap m_decl_ctx_to_die; + DIEToModuleMap m_die_to_module; std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up; /// @} @@ -97,16 +101,15 @@ protected: clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die); bool ParseTemplateDIE(const DWARFDIE &die, - lldb_private::ClangASTContext::TemplateParameterInfos + lldb_private::TypeSystemClang::TemplateParameterInfos &template_param_infos); bool ParseTemplateParameterInfos( const DWARFDIE &parent_die, - lldb_private::ClangASTContext::TemplateParameterInfos + lldb_private::TypeSystemClang::TemplateParameterInfos &template_param_infos); bool ParseChildMembers( const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type, - const lldb::LanguageType class_language, std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes, std::vector<int> &member_accessibilities, std::vector<DWARFDIE> &member_function_dies, @@ -140,6 +143,7 @@ protected: clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die, DWARFDIE *decl_ctx_die); + lldb_private::OptionalClangModuleID GetOwningClangModule(const DWARFDIE &die); bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die, const DWARFDIE &dst_class_die, @@ -170,45 +174,31 @@ protected: lldb::ModuleSP GetModuleForType(const DWARFDIE &die); private: - struct BitfieldInfo { - uint64_t bit_size; - uint64_t bit_offset; + struct FieldInfo { + uint64_t bit_size = 0; + uint64_t bit_offset = 0; + bool is_bitfield = false; - BitfieldInfo() - : bit_size(LLDB_INVALID_ADDRESS), bit_offset(LLDB_INVALID_ADDRESS) {} + FieldInfo() = default; - void Clear() { - bit_size = LLDB_INVALID_ADDRESS; - bit_offset = LLDB_INVALID_ADDRESS; - } - - bool IsValid() const { - return (bit_size != LLDB_INVALID_ADDRESS) && - (bit_offset != LLDB_INVALID_ADDRESS); - } + void SetIsBitfield(bool flag) { is_bitfield = flag; } + bool IsBitfield() { return is_bitfield; } bool NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const { - if (IsValid()) { - // This bitfield info is valid, so any subsequent bitfields must not - // overlap and must be at a higher bit offset than any previous bitfield - // + size. - return (bit_size + bit_offset) <= next_bit_offset; - } else { - // If the this BitfieldInfo is not valid, then any offset isOK - return true; - } + // Any subsequent bitfields must not overlap and must be at a higher + // bit offset than any previous bitfield + size. + return (bit_size + bit_offset) <= next_bit_offset; } }; void ParseSingleMember(const DWARFDIE &die, const DWARFDIE &parent_die, - lldb_private::CompilerType &class_clang_type, - const lldb::LanguageType class_language, + const lldb_private::CompilerType &class_clang_type, std::vector<int> &member_accessibilities, - lldb::AccessType &default_accessibility, + lldb::AccessType default_accessibility, DelayedPropertyList &delayed_properties, lldb_private::ClangASTImporter::LayoutInfo &layout_info, - BitfieldInfo &last_field_info); + FieldInfo &last_field_info); bool CompleteRecordType(const DWARFDIE &die, lldb_private::Type *type, lldb_private::CompilerType &clang_type); @@ -227,6 +217,12 @@ private: ParsedDWARFTypeAttributes &attrs); lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die, const ParsedDWARFTypeAttributes &attrs); + + /// Complete a type from debug info, or mark it as forcefully completed if + /// there is no of the type in the current Module. Call this function in + /// contexts where the usual C++ rules require a type to be complete (base + /// class, member, etc.). + void CompleteType(lldb_private::CompilerType type); }; /// Parsed form of all attributes that are relevant for type reconstruction. @@ -264,4 +260,4 @@ struct ParsedDWARFTypeAttributes { uint32_t encoding = 0; }; -#endif // SymbolFileDWARF_DWARFASTParserClang_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp index 741669b05754..0e9370be15fb 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp @@ -1,4 +1,4 @@ -//===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===// +//===-- DWARFAbbreviationDeclaration.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h index c0cf8823a368..f70aa71a5958 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFAbbreviationDeclaration_h_ -#define liblldb_DWARFAbbreviationDeclaration_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFABBREVIATIONDECLARATION_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFABBREVIATIONDECLARATION_H #include "DWARFAttribute.h" #include "DWARFDefines.h" @@ -62,4 +62,4 @@ protected: DWARFAttribute::collection m_attributes; }; -#endif // liblldb_DWARFAbbreviationDeclaration_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFABBREVIATIONDECLARATION_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp index b3594a455680..6c72d9e26221 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp @@ -1,4 +1,4 @@ -//===-- DWARFAttribute.cpp --------------------------------------*- C++ -*-===// +//===-- DWARFAttribute.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h index 58427b19100a..9948969f108f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFAttribute_h_ -#define SymbolFileDWARF_DWARFAttribute_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFATTRIBUTE_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFATTRIBUTE_H #include "DWARFDefines.h" #include "DWARFFormValue.h" @@ -82,4 +82,4 @@ protected: collection m_infos; }; -#endif // SymbolFileDWARF_DWARFAttribute_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFATTRIBUTE_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp index 033105efdc53..fcb424029f5a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp @@ -1,4 +1,4 @@ -//===-- DWARFBaseDIE.cpp ---------------------------------------*- C++ -*-===// +//===-- DWARFBaseDIE.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -74,13 +74,6 @@ const char *DWARFBaseDIE::GetName() const { return nullptr; } -lldb::LanguageType DWARFBaseDIE::GetLanguage() const { - if (IsValid()) - return m_cu->GetLanguageType(); - else - return lldb::eLanguageTypeUnknown; -} - lldb::ModuleSP DWARFBaseDIE::GetModule() const { SymbolFileDWARF *dwarf = GetDWARF(); if (dwarf) @@ -103,24 +96,6 @@ SymbolFileDWARF *DWARFBaseDIE::GetDWARF() const { return nullptr; } -llvm::Expected<lldb_private::TypeSystem &> DWARFBaseDIE::GetTypeSystem() const { - if (!m_cu) - return llvm::make_error<llvm::StringError>( - "Unable to get TypeSystem, no compilation unit available", - llvm::inconvertibleErrorCode()); - return m_cu->GetTypeSystem(); -} - -DWARFASTParser *DWARFBaseDIE::GetDWARFParser() const { - auto type_system_or_err = GetTypeSystem(); - if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to get DWARFASTParser"); - return nullptr; - } - return type_system_or_err->GetDWARFParser(); -} - bool DWARFBaseDIE::HasChildren() const { return m_die && m_die->HasChildren(); } @@ -130,11 +105,10 @@ bool DWARFBaseDIE::Supports_DW_AT_APPLE_objc_complete_type() const { } size_t DWARFBaseDIE::GetAttributes(DWARFAttributes &attributes, - uint32_t depth) const { + Recurse recurse) const { if (IsValid()) - return m_die->GetAttributes(m_cu, attributes, depth); - if (depth == 0) - attributes.Clear(); + return m_die->GetAttributes(m_cu, attributes, recurse); + attributes.Clear(); return 0; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h index 9652d7946e87..059b84864be7 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFBaseDIE_h_ -#define SymbolFileDWARF_DWARFBaseDIE_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFBASEDIE_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFBASEDIE_H #include "lldb/Core/dwarf.h" #include "lldb/lldb-types.h" @@ -57,10 +57,6 @@ public: llvm::Optional<DIERef> GetDIERef() const; - llvm::Expected<lldb_private::TypeSystem &> GetTypeSystem() const; - - DWARFASTParser *GetDWARFParser() const; - void Set(DWARFUnit *cu, DWARFDebugInfoEntry *die) { if (cu && die) { m_cu = cu; @@ -98,8 +94,6 @@ public: const char *GetName() const; - lldb::LanguageType GetLanguage() const; - lldb::ModuleSP GetModule() const; // Getting attribute values from the DIE. @@ -116,7 +110,9 @@ public: uint64_t GetAttributeValueAsAddress(const dw_attr_t attr, uint64_t fail_value) const; - size_t GetAttributes(DWARFAttributes &attributes, uint32_t depth = 0) const; + enum class Recurse : bool { no, yes }; + size_t GetAttributes(DWARFAttributes &attributes, + Recurse recurse = Recurse::yes) const; protected: DWARFUnit *m_cu; @@ -126,4 +122,4 @@ protected: bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs); bool operator!=(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs); -#endif // SymbolFileDWARF_DWARFBaseDIE_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFBASEDIE_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index 718f0537d6ed..f54fe0662aa2 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -1,4 +1,4 @@ -//===-- DWARFCompileUnit.cpp ------------------------------------*- C++ -*-===// +//===-- DWARFCompileUnit.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -33,41 +33,27 @@ void DWARFCompileUnit::BuildAddressRangeTable( size_t num_debug_aranges = debug_aranges->GetNumRanges(); - // First get the compile unit DIE only and check if it has a DW_AT_ranges + // First get the compile unit DIE only and check contains ranges information. const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); const dw_offset_t cu_offset = GetOffset(); if (die) { DWARFRangeList ranges; const size_t num_ranges = - die->GetAttributeAddressRanges(this, ranges, false); + die->GetAttributeAddressRanges(this, ranges, /*check_hi_lo_pc=*/true); if (num_ranges > 0) { - // This compile unit has DW_AT_ranges, assume this is correct if it is - // present since clang no longer makes .debug_aranges by default and it - // emits DW_AT_ranges for DW_TAG_compile_units. GCC also does this with - // recent GCC builds. for (size_t i = 0; i < num_ranges; ++i) { const DWARFRangeList::Entry &range = ranges.GetEntryRef(i); debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), range.GetRangeEnd()); } - return; // We got all of our ranges from the DW_AT_ranges attribute + return; } } - // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF - - // If the DIEs weren't parsed, then we don't want all dies for all compile - // units to stay loaded when they weren't needed. So we can end up parsing - // the DWARF and then throwing them all away to keep memory usage down. - ScopedExtractDIEs clear_dies(ExtractDIEsScoped()); - - die = DIEPtr(); - if (die) - die->BuildAddressRangeTable(this, debug_aranges); if (debug_aranges->GetNumRanges() == num_debug_aranges) { - // We got nothing from the functions, maybe we have a line tables only + // We got nothing from the debug info, maybe we have a line tables only // situation. Check the line tables and build the arange table from this. SymbolContext sc; sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h index 454637ef981c..3ec161f7dd51 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFCompileUnit_h_ -#define SymbolFileDWARF_DWARFCompileUnit_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCOMPILEUNIT_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCOMPILEUNIT_H #include "DWARFUnit.h" #include "llvm/Support/Error.h" @@ -27,9 +27,10 @@ private: DIERef::Section section, bool is_dwo) : DWARFUnit(dwarf, uid, header, abbrevs, section, is_dwo) {} - DISALLOW_COPY_AND_ASSIGN(DWARFCompileUnit); + DWARFCompileUnit(const DWARFCompileUnit &) = delete; + const DWARFCompileUnit &operator=(const DWARFCompileUnit &) = delete; friend class DWARFUnit; }; -#endif // SymbolFileDWARF_DWARFCompileUnit_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCOMPILEUNIT_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp index 5052b825fea6..37e28a09f3c4 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp @@ -1,4 +1,4 @@ -//===-- DWARFContext.cpp ----------------------------------------*- C++ -*-===// +//===-- DWARFContext.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -28,18 +28,28 @@ static DWARFDataExtractor LoadSection(SectionList *section_list, } const DWARFDataExtractor & -DWARFContext::LoadOrGetSection(SectionType main_section_type, +DWARFContext::LoadOrGetSection(llvm::Optional<SectionType> main_section_type, llvm::Optional<SectionType> dwo_section_type, SectionData &data) { llvm::call_once(data.flag, [&] { if (dwo_section_type && isDwo()) data.data = LoadSection(m_dwo_section_list, *dwo_section_type); - else - data.data = LoadSection(m_main_section_list, main_section_type); + else if (main_section_type) + data.data = LoadSection(m_main_section_list, *main_section_type); }); return data.data; } +const DWARFDataExtractor &DWARFContext::getOrLoadCuIndexData() { + return LoadOrGetSection(llvm::None, eSectionTypeDWARFDebugCuIndex, + m_data_debug_cu_index); +} + +const DWARFDataExtractor &DWARFContext::getOrLoadTuIndexData() { + return LoadOrGetSection(llvm::None, eSectionTypeDWARFDebugTuIndex, + m_data_debug_tu_index); +} + const DWARFDataExtractor &DWARFContext::getOrLoadAbbrevData() { return LoadOrGetSection(eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAbbrevDwo, m_data_debug_abbrev); @@ -117,32 +127,19 @@ llvm::DWARFContext &DWARFContext::GetAsLLVM() { if (!m_llvm_context) { llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> section_map; uint8_t addr_size = 0; - - auto AddSection = [&](Section §ion) { - DataExtractor section_data; - section.GetSectionData(section_data); - + auto AddSection = [&](llvm::StringRef name, DWARFDataExtractor data) { // Set the address size the first time we see it. if (addr_size == 0) - addr_size = section_data.GetByteSize(); + addr_size = data.GetAddressByteSize(); - llvm::StringRef data = llvm::toStringRef(section_data.GetData()); - llvm::StringRef name = section.GetName().GetStringRef(); - if (name.startswith(".")) - name = name.drop_front(); section_map.try_emplace( - name, llvm::MemoryBuffer::getMemBuffer(data, name, false)); + name, llvm::MemoryBuffer::getMemBuffer(toStringRef(data.GetData()), + name, false)); }; - if (m_main_section_list) { - for (auto §ion : *m_main_section_list) - AddSection(*section); - } - - if (m_dwo_section_list) { - for (auto §ion : *m_dwo_section_list) - AddSection(*section); - } + AddSection("debug_line_str", getOrLoadLineStrData()); + AddSection("debug_cu_index", getOrLoadCuIndexData()); + AddSection("debug_tu_index", getOrLoadTuIndexData()); m_llvm_context = llvm::DWARFContext::create(section_map, addr_size); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h index 8691001b1b76..92161a21d167 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILE_DWARF_DWARFCONTEXT_H -#define LLDB_PLUGINS_SYMBOLFILE_DWARF_DWARFCONTEXT_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCONTEXT_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCONTEXT_H #include "DWARFDataExtractor.h" #include "lldb/Core/Section.h" @@ -31,6 +31,7 @@ private: SectionData m_data_debug_abbrev; SectionData m_data_debug_addr; SectionData m_data_debug_aranges; + SectionData m_data_debug_cu_index; SectionData m_data_debug_info; SectionData m_data_debug_line; SectionData m_data_debug_line_str; @@ -41,13 +42,17 @@ private: SectionData m_data_debug_rnglists; SectionData m_data_debug_str; SectionData m_data_debug_str_offsets; + SectionData m_data_debug_tu_index; SectionData m_data_debug_types; const DWARFDataExtractor & - LoadOrGetSection(lldb::SectionType main_section_type, + LoadOrGetSection(llvm::Optional<lldb::SectionType> main_section_type, llvm::Optional<lldb::SectionType> dwo_section_type, SectionData &data); + const DWARFDataExtractor &getOrLoadCuIndexData(); + const DWARFDataExtractor &getOrLoadTuIndexData(); + public: explicit DWARFContext(SectionList *main_section_list, SectionList *dwo_section_list) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index c5411a17f274..8e995e627978 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDIE.cpp --------------------------------------------*- C++ -*-===// +//===-- DWARFDIE.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -32,7 +32,7 @@ class ElaboratingDIEIterator // Container sizes are optimized for the case of following DW_AT_specification // and DW_AT_abstract_origin just once. llvm::SmallVector<DWARFDIE, 2> m_worklist; - llvm::SmallSet<lldb::user_id_t, 3> m_seen; + llvm::SmallSet<DWARFDebugInfoEntry *, 3> m_seen; void Next() { assert(!m_worklist.empty() && "Incrementing end iterator?"); @@ -44,7 +44,7 @@ class ElaboratingDIEIterator // And add back any items that elaborate it. for (dw_attr_t attr : {DW_AT_specification, DW_AT_abstract_origin}) { if (DWARFDIE d = die.GetReferencedDIE(attr)) - if (m_seen.insert(die.GetID()).second) + if (m_seen.insert(die.GetDIE()).second) m_worklist.push_back(d); } } @@ -140,25 +140,64 @@ DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const { } DWARFDIE -DWARFDIE::LookupDeepestBlock(lldb::addr_t file_addr) const { - if (IsValid()) { - SymbolFileDWARF *dwarf = GetDWARF(); - DWARFUnit *cu = GetCU(); - DWARFDebugInfoEntry *function_die = nullptr; - DWARFDebugInfoEntry *block_die = nullptr; - if (m_die->LookupAddress(file_addr, cu, &function_die, &block_die)) { - if (block_die && block_die != function_die) { - if (cu->ContainsDIEOffset(block_die->GetOffset())) - return DWARFDIE(cu, block_die); - else - return DWARFDIE(dwarf->DebugInfo()->GetUnit(DIERef( - cu->GetSymbolFileDWARF().GetDwoNum(), - cu->GetDebugSection(), block_die->GetOffset())), - block_die); +DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const { + if (!IsValid()) + return DWARFDIE(); + + DWARFDIE result; + bool check_children = false; + bool match_addr_range = false; + switch (Tag()) { + case DW_TAG_class_type: + case DW_TAG_namespace: + case DW_TAG_structure_type: + case DW_TAG_common_block: + check_children = true; + break; + case DW_TAG_compile_unit: + case DW_TAG_module: + case DW_TAG_catch_block: + case DW_TAG_subprogram: + case DW_TAG_try_block: + case DW_TAG_partial_unit: + match_addr_range = true; + break; + case DW_TAG_lexical_block: + case DW_TAG_inlined_subroutine: + check_children = true; + match_addr_range = true; + break; + default: + break; + } + + if (match_addr_range) { + DWARFRangeList ranges; + if (m_die->GetAttributeAddressRanges(m_cu, ranges, + /*check_hi_lo_pc=*/true) && + ranges.FindEntryThatContains(address)) { + check_children = true; + switch (Tag()) { + default: + break; + + case DW_TAG_inlined_subroutine: // Inlined Function + case DW_TAG_lexical_block: // Block { } in code + result = *this; + break; } + } else { + check_children = false; } } - return DWARFDIE(); + + if (check_children) { + for (DWARFDIE child = GetFirstChild(); child; child = child.GetSibling()) { + if (DWARFDIE child_result = child.LookupDeepestBlock(address)) + return child_result; + } + } + return result; } const char *DWARFDIE::GetMangledName() const { @@ -333,15 +372,6 @@ std::vector<DWARFDIE> DWARFDIE::GetDeclContextDIEs() const { return result; } -void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const { - if (IsValid()) { - dwarf_decl_ctx.SetLanguage(GetLanguage()); - m_die->GetDWARFDeclContext(GetCU(), dwarf_decl_ctx); - } else { - dwarf_decl_ctx.Clear(); - } -} - void DWARFDIE::GetDeclContext( llvm::SmallVectorImpl<lldb_private::CompilerContext> &context) const { const dw_tag_t tag = Tag(); @@ -418,27 +448,3 @@ bool DWARFDIE::GetDIENamesAndRanges( } else return false; } - -CompilerDecl DWARFDIE::GetDecl() const { - DWARFASTParser *dwarf_ast = GetDWARFParser(); - if (dwarf_ast) - return dwarf_ast->GetDeclForUIDFromDWARF(*this); - else - return CompilerDecl(); -} - -CompilerDeclContext DWARFDIE::GetDeclContext() const { - DWARFASTParser *dwarf_ast = GetDWARFParser(); - if (dwarf_ast) - return dwarf_ast->GetDeclContextForUIDFromDWARF(*this); - else - return CompilerDeclContext(); -} - -CompilerDeclContext DWARFDIE::GetContainingDeclContext() const { - DWARFASTParser *dwarf_ast = GetDWARFParser(); - if (dwarf_ast) - return dwarf_ast->GetDeclContextContainingUIDFromDWARF(*this); - else - return CompilerDeclContext(); -} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h index 87d52eee9dd9..13737280926c 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDIE_h_ -#define SymbolFileDWARF_DWARFDIE_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H #include "DWARFBaseDIE.h" #include "llvm/ADT/SmallSet.h" @@ -70,8 +70,6 @@ public: // DeclContext related functions std::vector<DWARFDIE> GetDeclContextDIEs() const; - void GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const; - /// Return this DIE's decl context as it is needed to look up types /// in Clang's -gmodules debug info format. void GetDeclContext( @@ -90,14 +88,6 @@ public: int &decl_line, int &decl_column, int &call_file, int &call_line, int &call_column, lldb_private::DWARFExpression *frame_base) const; - - // CompilerDecl related functions - - lldb_private::CompilerDecl GetDecl() const; - - lldb_private::CompilerDeclContext GetDeclContext() const; - - lldb_private::CompilerDeclContext GetContainingDeclContext() const; }; -#endif // SymbolFileDWARF_DWARFDIE_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp index 1678b228137f..cf483286a66d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDataExtractor.cpp ----------------------------------*- C++ -*-===// +//===-- DWARFDataExtractor.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -23,8 +23,7 @@ DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const { llvm::DWARFDataExtractor DWARFDataExtractor::GetAsLLVM() const { return llvm::DWARFDataExtractor( - llvm::StringRef(reinterpret_cast<const char *>(GetDataStart()), - GetByteSize()), + llvm::makeArrayRef(GetDataStart(), GetByteSize()), GetByteOrder() == lldb::eByteOrderLittle, GetAddressByteSize()); } } // namespace lldb_private diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h index 22db5e8c0b79..df92bd45d5cc 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDataExtractor_h_ -#define liblldb_DWARFDataExtractor_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDATAEXTRACTOR_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDATAEXTRACTOR_H #include "lldb/Core/dwarf.h" #include "lldb/Utility/DataExtractor.h" @@ -34,4 +34,4 @@ public: }; } -#endif // liblldb_DWARFDataExtractor_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDATAEXTRACTOR_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp index 26301566a8e1..0f0f50a645db 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugAbbrev.cpp ------------------------------------*- C++ -*-===// +//===-- DWARFDebugAbbrev.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h index 9c4729326081..555864f44967 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDebugAbbrev_h_ -#define SymbolFileDWARF_DWARFDebugAbbrev_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGABBREV_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGABBREV_H #include <list> #include <map> @@ -78,4 +78,4 @@ protected: mutable DWARFAbbreviationDeclarationCollMapConstIter m_prev_abbr_offset_pos; }; -#endif // SymbolFileDWARF_DWARFDebugAbbrev_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGABBREV_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp index 86ce3b329b25..728cefe620a5 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugArangeSet.cpp ---------------------------------*- C++ -*-===// +//===-- DWARFDebugArangeSet.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -63,7 +63,8 @@ llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data, // 1 - the version looks good // 2 - the address byte size looks plausible // 3 - the length seems to make sense - // size looks plausible + // 4 - size looks plausible + // 5 - the arange tuples do not contain a segment field if (m_header.version < 2 || m_header.version > 5) return llvm::make_error<llvm::object::GenericBinaryError>( "Invalid arange header version"); @@ -81,6 +82,10 @@ llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data, return llvm::make_error<llvm::object::GenericBinaryError>( "Invalid arange header length"); + if (m_header.seg_size) + return llvm::make_error<llvm::object::GenericBinaryError>( + "segmented arange entries are not supported"); + // The first tuple following the header in each set begins at an offset // that is a multiple of the size of a single tuple (that is, twice the // size of an address). The header is padded, if necessary, to the diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h index db0cf22a3f45..6b5b69a70a80 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDebugArangeSet_h_ -#define SymbolFileDWARF_DWARFDebugArangeSet_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGESET_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGESET_H #include "lldb/Core/dwarf.h" #include <cstdint> @@ -59,4 +59,4 @@ protected: DescriptorColl m_arange_descriptors; }; -#endif // SymbolFileDWARF_DWARFDebugArangeSet_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGESET_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp index c8da2381353e..7dc52c1e2df0 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugAranges.cpp -----------------------------------*- C++ -*-===// +//===-- DWARFDebugAranges.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h index 74ba011b27af..96e82619f985 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDebugAranges_h_ -#define SymbolFileDWARF_DWARFDebugAranges_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGES_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGES_H #include "lldb/Core/dwarf.h" #include "lldb/Utility/RangeMap.h" @@ -52,4 +52,4 @@ protected: RangeToDIE m_aranges; }; -#endif // SymbolFileDWARF_DWARFDebugAranges_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGES_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index 1e04baca2c58..874978bf1398 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugInfo.cpp --------------------------------------*- C++ -*-===// +//===-- DWARFDebugInfo.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -72,10 +72,16 @@ void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) { DWARFDataExtractor data = section == DIERef::Section::DebugTypes ? m_context.getOrLoadDebugTypesData() : m_context.getOrLoadDebugInfoData(); + const llvm::DWARFUnitIndex *index = nullptr; + if (m_context.isDwo()) + index = &llvm::getDWARFUnitIndex(m_context.GetAsLLVM(), + section == DIERef::Section::DebugTypes + ? llvm::DW_SECT_EXT_TYPES + : llvm::DW_SECT_INFO); lldb::offset_t offset = 0; while (data.ValidOffset(offset)) { - llvm::Expected<DWARFUnitSP> unit_sp = - DWARFUnit::extract(m_dwarf, m_units.size(), data, section, &offset); + llvm::Expected<DWARFUnitSP> unit_sp = DWARFUnit::extract( + m_dwarf, m_units.size(), data, section, &offset, index); if (!unit_sp) { // FIXME: Propagate this error up. @@ -96,12 +102,11 @@ void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) { } void DWARFDebugInfo::ParseUnitHeadersIfNeeded() { - if (!m_units.empty()) - return; - - ParseUnitsFor(DIERef::Section::DebugInfo); - ParseUnitsFor(DIERef::Section::DebugTypes); - llvm::sort(m_type_hash_to_unit_index, llvm::less_first()); + llvm::call_once(m_units_once_flag, [&] { + ParseUnitsFor(DIERef::Section::DebugInfo); + ParseUnitsFor(DIERef::Section::DebugTypes); + llvm::sort(m_type_hash_to_unit_index, llvm::less_first()); + }); } size_t DWARFDebugInfo::GetNumUnits() { @@ -109,7 +114,7 @@ size_t DWARFDebugInfo::GetNumUnits() { return m_units.size(); } -DWARFUnit *DWARFDebugInfo::GetUnitAtIndex(user_id_t idx) { +DWARFUnit *DWARFDebugInfo::GetUnitAtIndex(size_t idx) { DWARFUnit *cu = nullptr; if (idx < GetNumUnits()) cu = m_units[idx].get(); @@ -191,7 +196,7 @@ DWARFDIE DWARFDebugInfo::GetDIE(const DIERef &die_ref) { DWARFUnit *cu = GetUnit(die_ref); if (cu) - return cu->GetDIE(die_ref.die_offset()); + return cu->GetNonSkeletonUnit().GetDIE(die_ref.die_offset()); return DWARFDIE(); // Not found } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h index 056cf33a202f..bdc718a5c2fa 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDebugInfo_h_ -#define SymbolFileDWARF_DWARFDebugInfo_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFO_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFO_H #include <map> #include <vector> @@ -35,7 +35,7 @@ public: lldb_private::DWARFContext &context); size_t GetNumUnits(); - DWARFUnit *GetUnitAtIndex(lldb::user_id_t idx); + DWARFUnit *GetUnitAtIndex(size_t idx); DWARFUnit *GetUnitAtOffset(DIERef::Section section, dw_offset_t cu_offset, uint32_t *idx_ptr = nullptr); DWARFUnit *GetUnitContainingDIEOffset(DIERef::Section section, @@ -61,7 +61,10 @@ protected: SymbolFileDWARF &m_dwarf; lldb_private::DWARFContext &m_context; + + llvm::once_flag m_units_once_flag; UnitColl m_units; + std::unique_ptr<DWARFDebugAranges> m_cu_aranges_up; // A quick address to compile unit table @@ -76,7 +79,8 @@ private: uint32_t FindUnitIndex(DIERef::Section section, dw_offset_t offset); - DISALLOW_COPY_AND_ASSIGN(DWARFDebugInfo); + DWARFDebugInfo(const DWARFDebugInfo &) = delete; + const DWARFDebugInfo &operator=(const DWARFDebugInfo &) = delete; }; -#endif // SymbolFileDWARF_DWARFDebugInfo_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFO_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 320500fe608d..f6425a889da8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===// +//===-- DWARFDebugInfoEntry.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -395,152 +395,14 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( return !ranges.IsEmpty(); } -// Dump -// -// Dumps a debug information entry and all of it's attributes to the specified -// stream. -void DWARFDebugInfoEntry::Dump(const DWARFUnit *cu, Stream &s, - uint32_t recurse_depth) const { - const DWARFDataExtractor &data = cu->GetData(); - lldb::offset_t offset = m_offset; - - if (data.ValidOffset(offset)) { - dw_uleb128_t abbrCode = data.GetULEB128(&offset); - - s.Printf("\n0x%8.8x: ", m_offset); - s.Indent(); - if (abbrCode != m_abbr_idx) { - s.Printf("error: DWARF has been modified\n"); - } else if (abbrCode) { - const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); - if (abbrevDecl) { - s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag())); - s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' '); - - // Dump all data in the .debug_info/.debug_types for the attributes - const uint32_t numAttributes = abbrevDecl->NumAttributes(); - for (uint32_t i = 0; i < numAttributes; ++i) { - DWARFFormValue form_value(cu); - dw_attr_t attr; - abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); - - DumpAttribute(cu, data, &offset, s, attr, form_value); - } - - const DWARFDebugInfoEntry *child = GetFirstChild(); - if (recurse_depth > 0 && child) { - s.IndentMore(); - - while (child) { - child->Dump(cu, s, recurse_depth - 1); - child = child->GetSibling(); - } - s.IndentLess(); - } - } else - s.Printf("Abbreviation code note found in 'debug_abbrev' class for " - "code: %u\n", - abbrCode); - } else { - s.Printf("NULL\n"); - } - } -} - -// DumpAttribute -// -// Dumps a debug information entry attribute along with it's form. Any special -// display of attributes is done (disassemble location lists, show enumeration -// values for attributes, etc). -void DWARFDebugInfoEntry::DumpAttribute( - const DWARFUnit *cu, const DWARFDataExtractor &data, - lldb::offset_t *offset_ptr, Stream &s, dw_attr_t attr, - DWARFFormValue &form_value) { - bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm); - - s.Printf(" "); - s.Indent(DW_AT_value_to_name(attr)); - - if (show_form) { - s.Printf("[%s", DW_FORM_value_to_name(form_value.Form())); - } - - if (!form_value.ExtractValue(data, offset_ptr)) - return; - - if (show_form) { - if (form_value.Form() == DW_FORM_indirect) { - s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form())); - } - - s.PutCString("] "); - } - - s.PutCString("( "); - - // Check to see if we have any special attribute formatters - switch (attr) { - case DW_AT_stmt_list: - s.Printf("0x%8.8" PRIx64, form_value.Unsigned()); - break; - - case DW_AT_language: - s.PutCString(DW_LANG_value_to_name(form_value.Unsigned())); - break; - - case DW_AT_encoding: - s.PutCString(DW_ATE_value_to_name(form_value.Unsigned())); - break; - - case DW_AT_frame_base: - case DW_AT_location: - case DW_AT_data_member_location: { - const uint8_t *blockData = form_value.BlockData(); - if (blockData) { - // Location description is inlined in data in the form value - DWARFDataExtractor locationData(data, - (*offset_ptr) - form_value.Unsigned(), - form_value.Unsigned()); - DWARFExpression::PrintDWARFExpression( - s, locationData, DWARFUnit::GetAddressByteSize(cu), 4, false); - } else { - // We have a location list offset as the value that is the offset into - // the .debug_loc section that describes the value over it's lifetime - uint64_t debug_loc_offset = form_value.Unsigned(); - DWARFExpression::PrintDWARFLocationList(s, cu, cu->GetLocationData(), - debug_loc_offset); - } - } break; - - case DW_AT_abstract_origin: - case DW_AT_specification: { - DWARFDIE abstract_die = form_value.Reference(); - form_value.Dump(s); - // *ostrm_ptr << HEX32 << abstract_die.GetOffset() << " ( "; - abstract_die.GetName(s); - } break; - - case DW_AT_type: { - DWARFDIE type_die = form_value.Reference(); - s.PutCString(" ( "); - type_die.AppendTypeName(s); - s.PutCString(" )"); - } break; - - default: - break; - } - - s.PutCString(" )\n"); -} - // Get all attribute values for a given DIE, including following any // specification or abstract origin attributes and including those in the // results. Any duplicate attributes will have the first instance take // precedence (this can happen for declaration attributes). -size_t DWARFDebugInfoEntry::GetAttributes( - const DWARFUnit *cu, DWARFAttributes &attributes, - uint32_t curr_depth) const { +size_t DWARFDebugInfoEntry::GetAttributes(const DWARFUnit *cu, + DWARFAttributes &attributes, + Recurse recurse, + uint32_t curr_depth) const { const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); if (abbrevDecl) { const DWARFDataExtractor &data = cu->GetData(); @@ -571,11 +433,13 @@ size_t DWARFDebugInfoEntry::GetAttributes( break; } - if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) { + if (recurse == Recurse::yes && + ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))) { if (form_value.ExtractValue(data, &offset)) { DWARFDIE spec_die = form_value.Reference(); if (spec_die) - spec_die.GetAttributes(attributes, curr_depth + 1); + spec_die.GetDIE()->GetAttributes(spec_die.GetCU(), attributes, + recurse, curr_depth + 1); } } else { llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu); @@ -819,34 +683,9 @@ const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const { return name; } -// BuildAddressRangeTable -void DWARFDebugInfoEntry::BuildAddressRangeTable( - const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const { - if (m_tag) { - if (m_tag == DW_TAG_subprogram) { - dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; - dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; - if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) { - /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - - /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc); - debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc); - } - } - - const DWARFDebugInfoEntry *child = GetFirstChild(); - while (child) { - child->BuildAddressRangeTable(cu, debug_aranges); - child = child->GetSibling(); - } - } -} - -// BuildFunctionAddressRangeTable -// -// This function is very similar to the BuildAddressRangeTable function except -// that the actual DIE offset for the function is placed in the table instead -// of the compile unit offset (which is the way the standard .debug_aranges -// section does it). +/// This function is builds a table very similar to the standard .debug_aranges +/// table, except that the actual DIE offset for the function is placed in the +/// table instead of the compile unit offset. void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const { if (m_tag) { @@ -854,8 +693,6 @@ void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) { - // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - - // 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc); } } @@ -868,25 +705,34 @@ void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( } } -void DWARFDebugInfoEntry::GetDWARFDeclContext( - DWARFUnit *cu, DWARFDeclContext &dwarf_decl_ctx) const { - const dw_tag_t tag = Tag(); - if (tag != DW_TAG_compile_unit && tag != DW_TAG_partial_unit) { - dwarf_decl_ctx.AppendDeclContext(tag, GetName(cu)); - DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu); - if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) { - if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit && - parent_decl_ctx_die.Tag() != DW_TAG_partial_unit) - parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext( - parent_decl_ctx_die.GetCU(), dwarf_decl_ctx); - } +DWARFDeclContext +DWARFDebugInfoEntry::GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, + DWARFUnit *cu) { + DWARFDeclContext dwarf_decl_ctx; + for (;;) { + const dw_tag_t tag = die->Tag(); + if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit) + return dwarf_decl_ctx; + dwarf_decl_ctx.AppendDeclContext(tag, die->GetName(cu)); + DWARFDIE parent_decl_ctx_die = die->GetParentDeclContextDIE(cu); + if (!parent_decl_ctx_die || parent_decl_ctx_die.GetDIE() == die) + return dwarf_decl_ctx; + if (parent_decl_ctx_die.Tag() == DW_TAG_compile_unit || + parent_decl_ctx_die.Tag() == DW_TAG_partial_unit) + return dwarf_decl_ctx; + die = parent_decl_ctx_die.GetDIE(); + cu = parent_decl_ctx_die.GetCU(); } } +DWARFDeclContext DWARFDebugInfoEntry::GetDWARFDeclContext(DWARFUnit *cu) const { + return GetDWARFDeclContextStatic(this, cu); +} + DWARFDIE DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const { DWARFAttributes attributes; - GetAttributes(cu, attributes); + GetAttributes(cu, attributes, Recurse::yes); return GetParentDeclContextDIE(cu, attributes); } @@ -936,7 +782,7 @@ DWARFDebugInfoEntry::GetParentDeclContextDIE( const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu, std::string &storage) const { DWARFAttributes attributes; - GetAttributes(cu, attributes); + GetAttributes(cu, attributes, Recurse::yes); return GetQualifiedName(cu, attributes, storage); } @@ -993,209 +839,6 @@ DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu, return storage.c_str(); } -bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, DWARFUnit *cu, - DWARFDebugInfoEntry **function_die, - DWARFDebugInfoEntry **block_die) { - bool found_address = false; - if (m_tag) { - bool check_children = false; - bool match_addr_range = false; - // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, - // DW_TAG_value_to_name(tag), address); - switch (m_tag) { - case DW_TAG_array_type: - break; - case DW_TAG_class_type: - check_children = true; - break; - case DW_TAG_entry_point: - case DW_TAG_enumeration_type: - case DW_TAG_formal_parameter: - case DW_TAG_imported_declaration: - case DW_TAG_label: - break; - case DW_TAG_lexical_block: - check_children = true; - match_addr_range = true; - break; - case DW_TAG_member: - case DW_TAG_pointer_type: - case DW_TAG_reference_type: - break; - case DW_TAG_compile_unit: - match_addr_range = true; - break; - case DW_TAG_string_type: - break; - case DW_TAG_structure_type: - check_children = true; - break; - case DW_TAG_subroutine_type: - case DW_TAG_typedef: - case DW_TAG_union_type: - case DW_TAG_unspecified_parameters: - case DW_TAG_variant: - break; - case DW_TAG_common_block: - check_children = true; - break; - case DW_TAG_common_inclusion: - case DW_TAG_inheritance: - break; - case DW_TAG_inlined_subroutine: - check_children = true; - match_addr_range = true; - break; - case DW_TAG_module: - match_addr_range = true; - break; - case DW_TAG_ptr_to_member_type: - case DW_TAG_set_type: - case DW_TAG_subrange_type: - case DW_TAG_with_stmt: - case DW_TAG_access_declaration: - case DW_TAG_base_type: - break; - case DW_TAG_catch_block: - match_addr_range = true; - break; - case DW_TAG_const_type: - case DW_TAG_constant: - case DW_TAG_enumerator: - case DW_TAG_file_type: - case DW_TAG_friend: - case DW_TAG_namelist: - case DW_TAG_namelist_item: - case DW_TAG_packed_type: - break; - case DW_TAG_subprogram: - match_addr_range = true; - break; - case DW_TAG_template_type_parameter: - case DW_TAG_template_value_parameter: - case DW_TAG_GNU_template_parameter_pack: - case DW_TAG_thrown_type: - break; - case DW_TAG_try_block: - match_addr_range = true; - break; - case DW_TAG_variant_part: - case DW_TAG_variable: - case DW_TAG_volatile_type: - case DW_TAG_dwarf_procedure: - case DW_TAG_restrict_type: - case DW_TAG_interface_type: - break; - case DW_TAG_namespace: - check_children = true; - break; - case DW_TAG_imported_module: - case DW_TAG_unspecified_type: - break; - case DW_TAG_partial_unit: - match_addr_range = true; - break; - case DW_TAG_imported_unit: - case DW_TAG_shared_type: - default: - break; - } - - if (match_addr_range) { - dw_addr_t lo_pc = - GetAttributeValueAsAddress(cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS); - if (lo_pc != LLDB_INVALID_ADDRESS) { - dw_addr_t hi_pc = GetAttributeHighPC(cu, lo_pc, LLDB_INVALID_ADDRESS); - if (hi_pc != LLDB_INVALID_ADDRESS) { - // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ", - // m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc); - if ((lo_pc <= address) && (address < hi_pc)) { - found_address = true; - // puts("***MATCH***"); - switch (m_tag) { - case DW_TAG_compile_unit: // File - case DW_TAG_partial_unit: // File - check_children = - ((function_die != nullptr) || (block_die != nullptr)); - break; - - case DW_TAG_subprogram: // Function - if (function_die) - *function_die = this; - check_children = (block_die != nullptr); - break; - - case DW_TAG_inlined_subroutine: // Inlined Function - case DW_TAG_lexical_block: // Block { } in code - if (block_die) { - *block_die = this; - check_children = true; - } - break; - - default: - check_children = true; - break; - } - } - } else { - // Compile units may not have a valid high/low pc when there - // are address gaps in subroutines so we must always search - // if there is no valid high and low PC. - check_children = - (m_tag == DW_TAG_compile_unit || m_tag == DW_TAG_partial_unit) && - ((function_die != nullptr) || (block_die != nullptr)); - } - } else { - DWARFRangeList ranges; - if (GetAttributeAddressRanges(cu, ranges, /*check_hi_lo_pc*/ false) && - ranges.FindEntryThatContains(address)) { - found_address = true; - // puts("***MATCH***"); - switch (m_tag) { - case DW_TAG_compile_unit: // File - case DW_TAG_partial_unit: // File - check_children = - ((function_die != nullptr) || (block_die != nullptr)); - break; - - case DW_TAG_subprogram: // Function - if (function_die) - *function_die = this; - check_children = (block_die != nullptr); - break; - - case DW_TAG_inlined_subroutine: // Inlined Function - case DW_TAG_lexical_block: // Block { } in code - if (block_die) { - *block_die = this; - check_children = true; - } - break; - - default: - check_children = true; - break; - } - } else { - check_children = false; - } - } - } - - if (check_children) { - // printf("checking children\n"); - DWARFDebugInfoEntry *child = GetFirstChild(); - while (child) { - if (child->LookupAddress(address, cu, function_die, block_die)) - return true; - child = child->GetSibling(); - } - } - } - return found_address; -} - lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const { return GetOffset() + llvm::getULEB128Size(m_abbr_idx); } @@ -1210,6 +853,29 @@ DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const { return nullptr; } +bool DWARFDebugInfoEntry::IsGlobalOrStaticScopeVariable() const { + if (Tag() != DW_TAG_variable) + return false; + const DWARFDebugInfoEntry *parent_die = GetParent(); + while (parent_die != nullptr) { + switch (parent_die->Tag()) { + case DW_TAG_subprogram: + case DW_TAG_lexical_block: + case DW_TAG_inlined_subroutine: + return false; + + case DW_TAG_compile_unit: + case DW_TAG_partial_unit: + return true; + + default: + break; + } + parent_die = parent_die->GetParent(); + } + return false; +} + bool DWARFDebugInfoEntry::operator==(const DWARFDebugInfoEntry &rhs) const { return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx && m_sibling_idx == rhs.m_sibling_idx && diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h index f35af6e7d498..3019e1767f18 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -6,13 +6,14 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDebugInfoEntry_h_ -#define SymbolFileDWARF_DWARFDebugInfoEntry_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H #include "SymbolFileDWARF.h" #include "llvm/ADT/SmallVector.h" #include "DWARFAbbreviationDeclaration.h" +#include "DWARFBaseDIE.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugRanges.h" #include <map> @@ -41,23 +42,17 @@ public: bool operator==(const DWARFDebugInfoEntry &rhs) const; bool operator!=(const DWARFDebugInfoEntry &rhs) const; - void BuildAddressRangeTable(const DWARFUnit *cu, - DWARFDebugAranges *debug_aranges) const; - void BuildFunctionAddressRangeTable(const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const; bool Extract(const lldb_private::DWARFDataExtractor &data, const DWARFUnit *cu, lldb::offset_t *offset_ptr); - bool LookupAddress(const dw_addr_t address, DWARFUnit *cu, - DWARFDebugInfoEntry **function_die, - DWARFDebugInfoEntry **block_die); - - size_t GetAttributes(const DWARFUnit *cu, - DWARFAttributes &attrs, - uint32_t curr_depth = 0) - const; // "curr_depth" for internal use only, don't set this yourself!!! + using Recurse = DWARFBaseDIE::Recurse; + size_t GetAttributes(const DWARFUnit *cu, DWARFAttributes &attrs, + Recurse recurse = Recurse::yes) const { + return GetAttributes(cu, attrs, recurse, 0 /* curr_depth */); + } dw_offset_t GetAttributeValue(const DWARFUnit *cu, const dw_attr_t attr, @@ -106,15 +101,6 @@ public: const char *GetQualifiedName(DWARFUnit *cu, const DWARFAttributes &attributes, std::string &storage) const; - void Dump(const DWARFUnit *cu, lldb_private::Stream &s, - uint32_t recurse_depth) const; - - static void - DumpAttribute(const DWARFUnit *cu, - const lldb_private::DWARFDataExtractor &data, - lldb::offset_t *offset_ptr, lldb_private::Stream &s, - dw_attr_t attr, DWARFFormValue &form_value); - bool GetDIENamesAndRanges( DWARFUnit *cu, const char *&name, const char *&mangled, DWARFRangeList &rangeList, int &decl_file, int &decl_line, @@ -162,8 +148,7 @@ public: return HasChildren() ? this + 1 : nullptr; } - void GetDWARFDeclContext(DWARFUnit *cu, - DWARFDeclContext &dwarf_decl_ctx) const; + DWARFDeclContext GetDWARFDeclContext(DWARFUnit *cu) const; DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu) const; DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu, @@ -172,7 +157,15 @@ public: void SetSiblingIndex(uint32_t idx) { m_sibling_idx = idx; } void SetParentIndex(uint32_t idx) { m_parent_idx = idx; } + // This function returns true if the variable scope is either + // global or (file-static). It will return false for static variables + // that are local to a function, as they have local scope. + bool IsGlobalOrStaticScopeVariable() const; + protected: + static DWARFDeclContext + GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu); + dw_offset_t m_offset; // Offset within the .debug_info/.debug_types uint32_t m_parent_idx; // How many to subtract from "this" to get the parent. // If zero this die has no parent @@ -185,6 +178,10 @@ protected: /// A copy of the DW_TAG value so we don't have to go through the compile /// unit abbrev table dw_tag_t m_tag = llvm::dwarf::DW_TAG_null; + +private: + size_t GetAttributes(const DWARFUnit *cu, DWARFAttributes &attrs, + Recurse recurse, uint32_t curr_depth) const; }; -#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp index 4238be7ec1c3..278950a9f336 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugMacro.cpp -------------------------------------*- C++ -*-===// +//===-- DWARFDebugMacro.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h index c3a93a9f4d14..5c0338e950eb 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDebugMacro_h_ -#define SymbolFileDWARF_DWARFDebugMacro_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGMACRO_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGMACRO_H #include <map> @@ -58,4 +58,4 @@ public: lldb_private::DebugMacrosSP &debug_macros_sp); }; -#endif // SymbolFileDWARF_DWARFDebugMacro_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGMACRO_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp index 6c074002cb20..6a0f11d2a1c4 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugRanges.cpp ------------------------------------*- C++ -*-===// +//===-- DWARFDebugRanges.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h index 1888a7760f27..b587845a67d9 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDebugRanges_h_ -#define SymbolFileDWARF_DWARFDebugRanges_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGRANGES_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGRANGES_H #include "lldb/Core/dwarf.h" #include <map> @@ -39,4 +39,4 @@ protected: range_map m_range_map; }; -#endif // SymbolFileDWARF_DWARFDebugRanges_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGRANGES_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp index a664314035e4..f4c8c14cc8af 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDeclContext.cpp ------------------------------------*- C++ -*-===// +//===-- DWARFDeclContext.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h index 348b33464a54..9072b2dc0115 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDeclContext_h_ -#define SymbolFileDWARF_DWARFDeclContext_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H #include <string> #include <vector> @@ -48,6 +48,7 @@ public: } bool operator==(const DWARFDeclContext &rhs) const; + bool operator!=(const DWARFDeclContext &rhs) const { return !(*this == rhs); } uint32_t GetSize() const { return m_entries.size(); } @@ -85,4 +86,4 @@ protected: lldb::LanguageType m_language; }; -#endif // SymbolFileDWARF_DWARFDeclContext_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp index 2ae1bbc9f507..4e99a295ce50 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDefines.cpp ----------------------------------------*- C++ -*-===// +//===-- DWARFDefines.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -58,321 +58,6 @@ const char *DW_OP_value_to_name(uint32_t val) { return llvmstr.data(); } -DRC_class DW_OP_value_to_class(uint32_t val) { - // FIXME: If we just used llvm's DWARFExpression printer, we could delete - // all this code (and more in lldb's DWARFExpression.cpp). - switch (val) { - case 0x03: - return DRC_ONEOPERAND; - case 0x06: - return DRC_ZEROOPERANDS; - case 0x08: - return DRC_ONEOPERAND; - case 0x09: - return DRC_ONEOPERAND; - case 0x0a: - return DRC_ONEOPERAND; - case 0x0b: - return DRC_ONEOPERAND; - case 0x0c: - return DRC_ONEOPERAND; - case 0x0d: - return DRC_ONEOPERAND; - case 0x0e: - return DRC_ONEOPERAND; - case 0x0f: - return DRC_ONEOPERAND; - case 0x10: - return DRC_ONEOPERAND; - case 0x11: - return DRC_ONEOPERAND; - case 0x12: - return DRC_ZEROOPERANDS; - case 0x13: - return DRC_ZEROOPERANDS; - case 0x14: - return DRC_ZEROOPERANDS; - case 0x15: - return DRC_ONEOPERAND; - case 0x16: - return DRC_ZEROOPERANDS; - case 0x17: - return DRC_ZEROOPERANDS; - case 0x18: - return DRC_ZEROOPERANDS; - case 0x19: - return DRC_ZEROOPERANDS; - case 0x1a: - return DRC_ZEROOPERANDS; - case 0x1b: - return DRC_ZEROOPERANDS; - case 0x1c: - return DRC_ZEROOPERANDS; - case 0x1d: - return DRC_ZEROOPERANDS; - case 0x1e: - return DRC_ZEROOPERANDS; - case 0x1f: - return DRC_ZEROOPERANDS; - case 0x20: - return DRC_ZEROOPERANDS; - case 0x21: - return DRC_ZEROOPERANDS; - case 0x22: - return DRC_ZEROOPERANDS; - case 0x23: - return DRC_ONEOPERAND; - case 0x24: - return DRC_ZEROOPERANDS; - case 0x25: - return DRC_ZEROOPERANDS; - case 0x26: - return DRC_ZEROOPERANDS; - case 0x27: - return DRC_ZEROOPERANDS; - case 0x2f: - return DRC_ONEOPERAND; - case 0x28: - return DRC_ONEOPERAND; - case 0x29: - return DRC_ZEROOPERANDS; - case 0x2a: - return DRC_ZEROOPERANDS; - case 0x2b: - return DRC_ZEROOPERANDS; - case 0x2c: - return DRC_ZEROOPERANDS; - case 0x2d: - return DRC_ZEROOPERANDS; - case 0x2e: - return DRC_ZEROOPERANDS; - case 0x30: - return DRC_ZEROOPERANDS; - case 0x31: - return DRC_ZEROOPERANDS; - case 0x32: - return DRC_ZEROOPERANDS; - case 0x33: - return DRC_ZEROOPERANDS; - case 0x34: - return DRC_ZEROOPERANDS; - case 0x35: - return DRC_ZEROOPERANDS; - case 0x36: - return DRC_ZEROOPERANDS; - case 0x37: - return DRC_ZEROOPERANDS; - case 0x38: - return DRC_ZEROOPERANDS; - case 0x39: - return DRC_ZEROOPERANDS; - case 0x3a: - return DRC_ZEROOPERANDS; - case 0x3b: - return DRC_ZEROOPERANDS; - case 0x3c: - return DRC_ZEROOPERANDS; - case 0x3d: - return DRC_ZEROOPERANDS; - case 0x3e: - return DRC_ZEROOPERANDS; - case 0x3f: - return DRC_ZEROOPERANDS; - case 0x40: - return DRC_ZEROOPERANDS; - case 0x41: - return DRC_ZEROOPERANDS; - case 0x42: - return DRC_ZEROOPERANDS; - case 0x43: - return DRC_ZEROOPERANDS; - case 0x44: - return DRC_ZEROOPERANDS; - case 0x45: - return DRC_ZEROOPERANDS; - case 0x46: - return DRC_ZEROOPERANDS; - case 0x47: - return DRC_ZEROOPERANDS; - case 0x48: - return DRC_ZEROOPERANDS; - case 0x49: - return DRC_ZEROOPERANDS; - case 0x4a: - return DRC_ZEROOPERANDS; - case 0x4b: - return DRC_ZEROOPERANDS; - case 0x4c: - return DRC_ZEROOPERANDS; - case 0x4d: - return DRC_ZEROOPERANDS; - case 0x4e: - return DRC_ZEROOPERANDS; - case 0x4f: - return DRC_ZEROOPERANDS; - case 0x50: - return DRC_ZEROOPERANDS; - case 0x51: - return DRC_ZEROOPERANDS; - case 0x52: - return DRC_ZEROOPERANDS; - case 0x53: - return DRC_ZEROOPERANDS; - case 0x54: - return DRC_ZEROOPERANDS; - case 0x55: - return DRC_ZEROOPERANDS; - case 0x56: - return DRC_ZEROOPERANDS; - case 0x57: - return DRC_ZEROOPERANDS; - case 0x58: - return DRC_ZEROOPERANDS; - case 0x59: - return DRC_ZEROOPERANDS; - case 0x5a: - return DRC_ZEROOPERANDS; - case 0x5b: - return DRC_ZEROOPERANDS; - case 0x5c: - return DRC_ZEROOPERANDS; - case 0x5d: - return DRC_ZEROOPERANDS; - case 0x5e: - return DRC_ZEROOPERANDS; - case 0x5f: - return DRC_ZEROOPERANDS; - case 0x60: - return DRC_ZEROOPERANDS; - case 0x61: - return DRC_ZEROOPERANDS; - case 0x62: - return DRC_ZEROOPERANDS; - case 0x63: - return DRC_ZEROOPERANDS; - case 0x64: - return DRC_ZEROOPERANDS; - case 0x65: - return DRC_ZEROOPERANDS; - case 0x66: - return DRC_ZEROOPERANDS; - case 0x67: - return DRC_ZEROOPERANDS; - case 0x68: - return DRC_ZEROOPERANDS; - case 0x69: - return DRC_ZEROOPERANDS; - case 0x6a: - return DRC_ZEROOPERANDS; - case 0x6b: - return DRC_ZEROOPERANDS; - case 0x6c: - return DRC_ZEROOPERANDS; - case 0x6d: - return DRC_ZEROOPERANDS; - case 0x6e: - return DRC_ZEROOPERANDS; - case 0x6f: - return DRC_ZEROOPERANDS; - case 0x70: - return DRC_ONEOPERAND; - case 0x71: - return DRC_ONEOPERAND; - case 0x72: - return DRC_ONEOPERAND; - case 0x73: - return DRC_ONEOPERAND; - case 0x74: - return DRC_ONEOPERAND; - case 0x75: - return DRC_ONEOPERAND; - case 0x76: - return DRC_ONEOPERAND; - case 0x77: - return DRC_ONEOPERAND; - case 0x78: - return DRC_ONEOPERAND; - case 0x79: - return DRC_ONEOPERAND; - case 0x7a: - return DRC_ONEOPERAND; - case 0x7b: - return DRC_ONEOPERAND; - case 0x7c: - return DRC_ONEOPERAND; - case 0x7d: - return DRC_ONEOPERAND; - case 0x7e: - return DRC_ONEOPERAND; - case 0x7f: - return DRC_ONEOPERAND; - case 0x80: - return DRC_ONEOPERAND; - case 0x81: - return DRC_ONEOPERAND; - case 0x82: - return DRC_ONEOPERAND; - case 0x83: - return DRC_ONEOPERAND; - case 0x84: - return DRC_ONEOPERAND; - case 0x85: - return DRC_ONEOPERAND; - case 0x86: - return DRC_ONEOPERAND; - case 0x87: - return DRC_ONEOPERAND; - case 0x88: - return DRC_ONEOPERAND; - case 0x89: - return DRC_ONEOPERAND; - case 0x8a: - return DRC_ONEOPERAND; - case 0x8b: - return DRC_ONEOPERAND; - case 0x8c: - return DRC_ONEOPERAND; - case 0x8d: - return DRC_ONEOPERAND; - case 0x8e: - return DRC_ONEOPERAND; - case 0x8f: - return DRC_ONEOPERAND; - case 0x90: - return DRC_ONEOPERAND; - case 0x91: - return DRC_ONEOPERAND; - case 0x92: - return DRC_TWOOPERANDS; - case 0x93: - return DRC_ONEOPERAND; - case 0x94: - return DRC_ONEOPERAND; - case 0x95: - return DRC_ONEOPERAND; - case 0x96: - return DRC_ZEROOPERANDS; - case 0x97: - return DRC_DWARFv3 | DRC_ZEROOPERANDS; - case 0x98: - return DRC_DWARFv3 | DRC_ONEOPERAND; - case 0x99: - return DRC_DWARFv3 | DRC_ONEOPERAND; - case 0x9a: - return DRC_DWARFv3 | DRC_ONEOPERAND; - case 0xa3: /* DW_OP_entry_value */ - return DRC_TWOOPERANDS; - case 0xf0: - return DRC_ZEROOPERANDS; /* DW_OP_APPLE_uninit */ - case 0xe0: - return 0; - case 0xff: - return 0; - default: - return 0; - } -} - const char *DW_ATE_value_to_name(uint32_t val) { static char invalid[100]; llvm::StringRef llvmstr = llvm::dwarf::AttributeEncodingString(val); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h index d16cb07baf88..1b7102cd7e31 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDefines_h_ -#define SymbolFileDWARF_DWARFDefines_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEFINES_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEFINES_H #include "lldb/Core/dwarf.h" #include <stdint.h> @@ -26,52 +26,12 @@ const char *DW_FORM_value_to_name(uint32_t val); const char *DW_OP_value_to_name(uint32_t val); -DRC_class DW_OP_value_to_class(uint32_t val); - const char *DW_ATE_value_to_name(uint32_t val); const char *DW_LANG_value_to_name(uint32_t val); const char *DW_LNS_value_to_name(uint32_t val); -/* These DRC are entirely our own construction, - although they are derived from various comments in the DWARF standard. - Most of these are not useful to the parser, but the DW_AT and DW_FORM - classes should prove to be usable in some fashion. */ - -#define DRC_0x65 0x1 -#define DRC_ADDRESS 0x2 -#define DRC_BLOCK 0x4 -#define DRC_CONSTANT 0x8 -#define DRC_DWARFv3 0x10 -#define DRC_FLAG 0x20 -#define DRC_INDIRECT_SPECIAL 0x40 -#define DRC_LINEPTR 0x80 -#define DRC_LOCEXPR 0x100 -#define DRC_LOCLISTPTR 0x200 -#define DRC_MACPTR 0x400 -#define DRC_ONEOPERAND 0x800 -#define DRC_OPERANDONE_1BYTE_DELTA 0x1000 -#define DRC_OPERANDONE_2BYTE_DELTA 0x2000 -#define DRC_OPERANDONE_4BYTE_DELTA 0x4000 -#define DRC_OPERANDONE_ADDRESS 0x8000 -#define DRC_OPERANDONE_BLOCK 0x10000 -#define DRC_OPERANDONE_SLEB128_OFFSET 0x20000 -#define DRC_OPERANDONE_ULEB128_OFFSET 0x40000 -#define DRC_OPERANDONE_ULEB128_REGISTER 0x80000 -#define DRC_OPERANDTWO_BLOCK 0x100000 -#define DRC_OPERANDTWO_SLEB128_OFFSET 0x200000 -#define DRC_OPERANDTWO_ULEB128_OFFSET 0x400000 -#define DRC_OPERANDTWO_ULEB128_REGISTER 0x800000 -#define DRC_OPERNADONE_ULEB128_REGISTER 0x1000000 -#define DRC_RANGELISTPTR 0x2000000 -#define DRC_REFERENCE 0x4000000 -#define DRC_STRING 0x8000000 -#define DRC_TWOOPERANDS 0x10000000 -#define DRC_VENDOR_GNU 0x20000000 -#define DRC_VENDOR_MIPS 0x40000000 -#define DRC_ZEROOPERANDS 0x80000000 - } // namespace lldb_private -#endif // SymbolFileDWARF_DWARFDefines_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEFINES_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index f660cc32b3f8..305f1cbd2826 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -1,4 +1,4 @@ -//===-- DWARFFormValue.cpp --------------------------------------*- C++ -*-===// +//===-- DWARFFormValue.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -454,40 +454,26 @@ void DWARFFormValue::Dump(Stream &s) const { } const char *DWARFFormValue::AsCString() const { - SymbolFileDWARF &symbol_file = m_unit->GetSymbolFileDWARF(); + DWARFContext &context = m_unit->GetSymbolFileDWARF().GetDWARFContext(); - if (m_form == DW_FORM_string) { + if (m_form == DW_FORM_string) return m_value.value.cstr; - } else if (m_form == DW_FORM_strp) { - return symbol_file.GetDWARFContext().getOrLoadStrData().PeekCStr( - m_value.value.uval); - } else if (m_form == DW_FORM_GNU_str_index) { - uint32_t index_size = 4; - lldb::offset_t offset = m_value.value.uval * index_size; - dw_offset_t str_offset = - symbol_file.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64( - &offset, index_size); - return symbol_file.GetDWARFContext().getOrLoadStrData().PeekCStr( - str_offset); - } - - if (m_form == DW_FORM_strx || m_form == DW_FORM_strx1 || - m_form == DW_FORM_strx2 || m_form == DW_FORM_strx3 || - m_form == DW_FORM_strx4) { - - // The same code as above. - uint32_t indexSize = 4; - lldb::offset_t offset = - m_unit->GetStrOffsetsBase() + m_value.value.uval * indexSize; - dw_offset_t strOffset = - symbol_file.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64( - &offset, indexSize); - return symbol_file.GetDWARFContext().getOrLoadStrData().PeekCStr(strOffset); + if (m_form == DW_FORM_strp) + return context.getOrLoadStrData().PeekCStr(m_value.value.uval); + + if (m_form == DW_FORM_GNU_str_index || m_form == DW_FORM_strx || + m_form == DW_FORM_strx1 || m_form == DW_FORM_strx2 || + m_form == DW_FORM_strx3 || m_form == DW_FORM_strx4) { + + llvm::Optional<uint64_t> offset = + m_unit->GetStringOffsetSectionItem(m_value.value.uval); + if (!offset) + return nullptr; + return context.getOrLoadStrData().PeekCStr(*offset); } if (m_form == DW_FORM_line_strp) - return symbol_file.GetDWARFContext().getOrLoadLineStrData().PeekCStr( - m_value.value.uval); + return context.getOrLoadLineStrData().PeekCStr(m_value.value.uval); return nullptr; } @@ -531,7 +517,7 @@ DWARFDIE DWARFFormValue::Reference() const { case DW_FORM_ref_addr: { DWARFUnit *ref_cu = - m_unit->GetSymbolFileDWARF().DebugInfo()->GetUnitContainingDIEOffset( + m_unit->GetSymbolFileDWARF().DebugInfo().GetUnitContainingDIEOffset( DIERef::Section::DebugInfo, value); if (!ref_cu) { m_unit->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( @@ -544,7 +530,7 @@ DWARFDIE DWARFFormValue::Reference() const { case DW_FORM_ref_sig8: { DWARFTypeUnit *tu = - m_unit->GetSymbolFileDWARF().DebugInfo()->GetTypeUnitForHash(value); + m_unit->GetSymbolFileDWARF().DebugInfo().GetTypeUnitForHash(value); if (!tu) return {}; return tu->GetDIE(tu->GetTypeOffset()); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h index 848db2990ded..b401352c693d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFFormValue_h_ -#define SymbolFileDWARF_DWARFFormValue_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFFORMVALUE_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFFORMVALUE_H #include "DWARFDataExtractor.h" #include <stddef.h> @@ -86,4 +86,4 @@ protected: ValueType m_value; // Contains all data for the form }; -#endif // SymbolFileDWARF_DWARFFormValue_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFFORMVALUE_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp index c122f756e81a..683033d0ee4c 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp @@ -1,4 +1,4 @@ -//===-- DWARFIndex.cpp -----------------------------------------*- C++ -*-===// +//===-- DWARFIndex.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,20 +11,21 @@ #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" +#include "lldb/Core/Module.h" + using namespace lldb_private; using namespace lldb; DWARFIndex::~DWARFIndex() = default; -void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref, - SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - std::vector<DWARFDIE> &dies) { +bool DWARFIndex::ProcessFunctionDIE( + llvm::StringRef name, DIERef ref, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + llvm::function_ref<bool(DWARFDIE die)> callback) { DWARFDIE die = dwarf.GetDIE(ref); if (!die) { ReportInvalidDIERef(ref, name); - return; + return true; } // Exit early if we're searching exclusively for methods or selectors and @@ -32,26 +33,22 @@ void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref, uint32_t looking_for_nonmethods = name_type_mask & ~(eFunctionNameTypeMethod | eFunctionNameTypeSelector); if (!looking_for_nonmethods && parent_decl_ctx.IsValid()) - return; + return true; // Otherwise, we need to also check that the context matches. If it does not // match, we do nothing. - if (!SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die)) - return; + if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) + return true; // In case of a full match, we just insert everything we find. - if (name_type_mask & eFunctionNameTypeFull) { - dies.push_back(die); - return; - } + if (name_type_mask & eFunctionNameTypeFull) + return callback(die); // If looking for ObjC selectors, we need to also check if the name is a // possible selector. if (name_type_mask & eFunctionNameTypeSelector && - ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) { - dies.push_back(die); - return; - } + ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) + return callback(die); bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod; bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase; @@ -61,6 +58,29 @@ void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref, // searching for. if ((looking_for_methods && looking_for_functions) || looking_for_methods == die.IsMethod()) - dies.push_back(die); + return callback(die); } + + return true; +} + +DWARFIndex::DIERefCallbackImpl::DIERefCallbackImpl( + const DWARFIndex &index, llvm::function_ref<bool(DWARFDIE die)> callback, + llvm::StringRef name) + : m_index(index), + m_dwarf(*llvm::cast<SymbolFileDWARF>(index.m_module.GetSymbolFile())), + m_callback(callback), m_name(name) {} + +bool DWARFIndex::DIERefCallbackImpl::operator()(DIERef ref) const { + if (DWARFDIE die = m_dwarf.GetDIE(ref)) + return m_callback(die); + m_index.ReportInvalidDIERef(ref, m_name); + return true; +} + +void DWARFIndex::ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const { + m_module.ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (accelerator table had " + "bad die 0x%8.8x for '%s')\n", + ref.die_offset(), name.str().c_str()); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h index e3c7c5e63ac8..ecf82a910b66 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_DWARFINDEX_H -#define LLDB_DWARFINDEX_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFINDEX_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFINDEX_H #include "Plugins/SymbolFile/DWARF/DIERef.h" #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" @@ -27,26 +27,38 @@ public: /// Finds global variables with the given base name. Any additional filtering /// (e.g., to only retrieve variables from a given context) should be done by /// the consumer. - virtual void GetGlobalVariables(ConstString basename, DIEArray &offsets) = 0; + virtual void + GetGlobalVariables(ConstString basename, + llvm::function_ref<bool(DWARFDIE die)> callback) = 0; - virtual void GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) = 0; - virtual void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) = 0; - virtual void GetObjCMethods(ConstString class_name, DIEArray &offsets) = 0; - virtual void GetCompleteObjCClass(ConstString class_name, - bool must_be_implementation, - DIEArray &offsets) = 0; - virtual void GetTypes(ConstString name, DIEArray &offsets) = 0; - virtual void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) = 0; - virtual void GetNamespaces(ConstString name, DIEArray &offsets) = 0; - virtual void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - std::vector<DWARFDIE> &dies) = 0; - virtual void GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) = 0; + virtual void + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref<bool(DWARFDIE die)> callback) = 0; + virtual void + GetGlobalVariables(const DWARFUnit &cu, + llvm::function_ref<bool(DWARFDIE die)> callback) = 0; + virtual void + GetObjCMethods(ConstString class_name, + llvm::function_ref<bool(DWARFDIE die)> callback) = 0; + virtual void + GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, + llvm::function_ref<bool(DWARFDIE die)> callback) = 0; + virtual void GetTypes(ConstString name, + llvm::function_ref<bool(DWARFDIE die)> callback) = 0; + virtual void GetTypes(const DWARFDeclContext &context, + llvm::function_ref<bool(DWARFDIE die)> callback) = 0; + virtual void + GetNamespaces(ConstString name, + llvm::function_ref<bool(DWARFDIE die)> callback) = 0; + virtual void + GetFunctions(ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, + uint32_t name_type_mask, + llvm::function_ref<bool(DWARFDIE die)> callback) = 0; + virtual void + GetFunctions(const RegularExpression ®ex, + llvm::function_ref<bool(DWARFDIE die)> callback) = 0; - virtual void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) = 0; virtual void Dump(Stream &s) = 0; protected: @@ -56,11 +68,33 @@ protected: /// the function given by "ref" matches search criteria given by /// "parent_decl_ctx" and "name_type_mask", it is inserted into the "dies" /// vector. - void ProcessFunctionDIE(llvm::StringRef name, DIERef ref, + bool ProcessFunctionDIE(llvm::StringRef name, DIERef ref, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, std::vector<DWARFDIE> &dies); + uint32_t name_type_mask, + llvm::function_ref<bool(DWARFDIE die)> callback); + + class DIERefCallbackImpl { + public: + DIERefCallbackImpl(const DWARFIndex &index, + llvm::function_ref<bool(DWARFDIE die)> callback, + llvm::StringRef name); + bool operator()(DIERef ref) const; + + private: + const DWARFIndex &m_index; + SymbolFileDWARF &m_dwarf; + const llvm::function_ref<bool(DWARFDIE die)> m_callback; + const llvm::StringRef m_name; + }; + DIERefCallbackImpl + DIERefCallback(llvm::function_ref<bool(DWARFDIE die)> callback, + llvm::StringRef name = {}) const { + return DIERefCallbackImpl(*this, callback, name); + } + + void ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const; }; } // namespace lldb_private -#endif // LLDB_DWARFINDEX_H +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFINDEX_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp index fcc031bf1ea0..48d578977c57 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp @@ -1,4 +1,4 @@ -//===-- DWARFTypeUnit.cpp ---------------------------------------*- C++ -*-===// +//===-- DWARFTypeUnit.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h index 8967509c081a..5e4d48ab285a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFTypeUnit_h_ -#define SymbolFileDWARF_DWARFTypeUnit_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFTYPEUNIT_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFTYPEUNIT_H #include "DWARFUnit.h" #include "llvm/Support/Error.h" @@ -34,4 +34,4 @@ private: friend class DWARFUnit; }; -#endif // SymbolFileDWARF_DWARFTypeUnit_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFTYPEUNIT_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 22e3e40dac93..dfa40759a7ff 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -1,4 +1,4 @@ -//===-- DWARFUnit.cpp -------------------------------------------*- C++ -*-===// +//===-- DWARFUnit.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -188,7 +188,7 @@ void DWARFUnit::ExtractDIEsRWLocked() { // simultaneously. We also don't need to do that as the dwo file will // contain a superset of information. So, we don't even attempt to parse // any remaining DIEs. - if (m_dwo_symbol_file) { + if (m_dwo) { m_die_array.front().SetHasChildren(false); break; } @@ -249,10 +249,8 @@ void DWARFUnit::ExtractDIEsRWLocked() { m_die_array.shrink_to_fit(); - if (m_dwo_symbol_file) { - DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit(); - dwo_cu->ExtractDIEsIfNeeded(); - } + if (m_dwo) + m_dwo->ExtractDIEsIfNeeded(); } // This is used when a split dwarf is enabled. @@ -261,23 +259,33 @@ void DWARFUnit::ExtractDIEsRWLocked() { // .debug_str_offsets. At the same time, the corresponding split debug unit also // may use DW_FORM_strx* forms pointing to its own .debug_str_offsets.dwo and // for that case, we should find the offset (skip the section header). -static void SetDwoStrOffsetsBase(DWARFUnit *dwo_cu) { +void DWARFUnit::SetDwoStrOffsetsBase() { lldb::offset_t baseOffset = 0; - const DWARFDataExtractor &strOffsets = - dwo_cu->GetSymbolFileDWARF().GetDWARFContext().getOrLoadStrOffsetsData(); - uint64_t length = strOffsets.GetU32(&baseOffset); - if (length == 0xffffffff) - length = strOffsets.GetU64(&baseOffset); + if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) { + if (const auto *contribution = + entry->getContribution(llvm::DW_SECT_STR_OFFSETS)) + baseOffset = contribution->Offset; + else + return; + } - // Check version. - if (strOffsets.GetU16(&baseOffset) < 5) - return; + if (GetVersion() >= 5) { + const DWARFDataExtractor &strOffsets = + GetSymbolFileDWARF().GetDWARFContext().getOrLoadStrOffsetsData(); + uint64_t length = strOffsets.GetU32(&baseOffset); + if (length == 0xffffffff) + length = strOffsets.GetU64(&baseOffset); - // Skip padding. - baseOffset += 2; + // Check version. + if (strOffsets.GetU16(&baseOffset) < 5) + return; + + // Skip padding. + baseOffset += 2; + } - dwo_cu->SetStrOffsetsBase(baseOffset); + SetStrOffsetsBase(baseOffset); } // m_die_array_mutex must be already held as read/write. @@ -336,32 +344,27 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { } } - if (m_is_dwo) + if (m_is_dwo) { + SetDwoStrOffsetsBase(); return; + } - std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file = + std::shared_ptr<SymbolFileDWARFDwo> dwo_symbol_file = m_dwarf.GetDwoSymbolFileForCompileUnit(*this, cu_die); if (!dwo_symbol_file) return; - DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit(); + uint64_t main_dwo_id = + cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, 0); + DWARFUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash(main_dwo_id); if (!dwo_cu) return; // Can't fetch the compile unit from the dwo file. + dwo_cu->SetUserData(this); DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly(); if (!dwo_cu_die.IsValid()) return; // Can't fetch the compile unit DIE from the dwo file. - uint64_t main_dwo_id = - cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, 0); - uint64_t sub_dwo_id = - dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0); - if (main_dwo_id != sub_dwo_id) - return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to - // a differectn compilation. - - m_dwo_symbol_file = std::move(dwo_symbol_file); - // Here for DWO CU we want to use the address base set in the skeleton unit // (DW_AT_addr_base) if it is available and use the DW_AT_GNU_addr_base // otherwise. We do that because pre-DWARF v5 could use the DW_AT_GNU_* @@ -375,21 +378,18 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { if (GetVersion() <= 4 && gnu_ranges_base) dwo_cu->SetRangesBase(*gnu_ranges_base); - else if (m_dwo_symbol_file->GetDWARFContext() + else if (dwo_symbol_file->GetDWARFContext() .getOrLoadRngListsData() .GetByteSize() > 0) dwo_cu->SetRangesBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32)); - if (GetVersion() >= 5 && m_dwo_symbol_file->GetDWARFContext() - .getOrLoadLocListsData() - .GetByteSize() > 0) + if (GetVersion() >= 5 && + dwo_symbol_file->GetDWARFContext().getOrLoadLocListsData().GetByteSize() > + 0) dwo_cu->SetLoclistsBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32)); dwo_cu->SetBaseAddress(GetBaseAddress()); - for (size_t i = 0; i < m_dwo_symbol_file->DebugInfo()->GetNumUnits(); ++i) { - DWARFUnit *unit = m_dwo_symbol_file->DebugInfo()->GetUnitAtIndex(i); - SetDwoStrOffsetsBase(unit); - } + m_dwo = std::shared_ptr<DWARFUnit>(std::move(dwo_symbol_file), dwo_cu); } DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) { @@ -467,18 +467,25 @@ void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) { std::unique_ptr<llvm::DWARFLocationTable> DWARFUnit::GetLocationTable(const DataExtractor &data) const { llvm::DWARFDataExtractor llvm_data( - toStringRef(data.GetData()), - data.GetByteOrder() == lldb::eByteOrderLittle, data.GetAddressByteSize()); + data.GetData(), data.GetByteOrder() == lldb::eByteOrderLittle, + data.GetAddressByteSize()); if (m_is_dwo || GetVersion() >= 5) return std::make_unique<llvm::DWARFDebugLoclists>(llvm_data, GetVersion()); return std::make_unique<llvm::DWARFDebugLoc>(llvm_data); } -const DWARFDataExtractor &DWARFUnit::GetLocationData() const { +DWARFDataExtractor DWARFUnit::GetLocationData() const { DWARFContext &Ctx = GetSymbolFileDWARF().GetDWARFContext(); - return GetVersion() >= 5 ? Ctx.getOrLoadLocListsData() - : Ctx.getOrLoadLocData(); + const DWARFDataExtractor &data = + GetVersion() >= 5 ? Ctx.getOrLoadLocListsData() : Ctx.getOrLoadLocData(); + if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) { + if (const auto *contribution = entry->getContribution(llvm::DW_SECT_EXT_LOC)) + return DWARFDataExtractor(data, contribution->Offset, + contribution->Length); + return DWARFDataExtractor(); + } + return data; } void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) { @@ -506,18 +513,14 @@ void DWARFUnit::ClearDIEsRWLocked() { m_die_array.clear(); m_die_array.shrink_to_fit(); - if (m_dwo_symbol_file) - m_dwo_symbol_file->GetCompileUnit()->ClearDIEsRWLocked(); + if (m_dwo) + m_dwo->ClearDIEsRWLocked(); } lldb::ByteOrder DWARFUnit::GetByteOrder() const { return m_dwarf.GetObjectFile()->GetByteOrder(); } -llvm::Expected<TypeSystem &> DWARFUnit::GetTypeSystem() { - return m_dwarf.GetTypeSystemForLanguage(GetLanguageType()); -} - void DWARFUnit::SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; } // Compare function DWARFDebugAranges::Range structures @@ -534,9 +537,6 @@ static bool CompareDIEOffset(const DWARFDebugInfoEntry &die, DWARFDIE DWARFUnit::GetDIE(dw_offset_t die_offset) { if (die_offset != DW_INVALID_OFFSET) { - if (GetDwoSymbolFile()) - return GetDwoSymbolFile()->GetCompileUnit()->GetDIE(die_offset); - if (ContainsDIEOffset(die_offset)) { ExtractDIEsIfNeeded(); DWARFDebugInfoEntry::const_iterator end = m_die_array.cend(); @@ -555,8 +555,9 @@ DWARFUnit::GetDIE(dw_offset_t die_offset) { } DWARFUnit &DWARFUnit::GetNonSkeletonUnit() { - if (SymbolFileDWARFDwo *dwo = GetDwoSymbolFile()) - return *dwo->GetCompileUnit(); + ExtractUnitDIEIfNeeded(); + if (m_dwo) + return *m_dwo; return *this; } @@ -570,11 +571,7 @@ uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; } void *DWARFUnit::GetUserData() const { return m_user_data; } -void DWARFUnit::SetUserData(void *d) { - m_user_data = d; - if (m_dwo_symbol_file) - m_dwo_symbol_file->GetCompileUnit()->SetUserData(d); -} +void DWARFUnit::SetUserData(void *d) { m_user_data = d; } bool DWARFUnit::Supports_DW_AT_APPLE_objc_complete_type() { return GetProducer() != eProducerLLVMGCC; @@ -658,28 +655,17 @@ uint32_t DWARFUnit::GetProducerVersionUpdate() { ParseProducerInfo(); return m_producer_version_update; } -LanguageType DWARFUnit::LanguageTypeFromDWARF(uint64_t val) { - // Note: user languages between lo_user and hi_user must be handled - // explicitly here. - switch (val) { - case DW_LANG_Mips_Assembler: - return eLanguageTypeMipsAssembler; - case DW_LANG_GOOGLE_RenderScript: - return eLanguageTypeExtRenderScript; - default: - return static_cast<LanguageType>(val); - } -} -LanguageType DWARFUnit::GetLanguageType() { - if (m_language_type != eLanguageTypeUnknown) - return m_language_type; +uint64_t DWARFUnit::GetDWARFLanguageType() { + if (m_language_type) + return *m_language_type; const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); - if (die) - m_language_type = LanguageTypeFromDWARF( - die->GetAttributeValueAsUnsigned(this, DW_AT_language, 0)); - return m_language_type; + if (!die) + m_language_type = 0; + else + m_language_type = die->GetAttributeValueAsUnsigned(this, DW_AT_language, 0); + return *m_language_type; } bool DWARFUnit::GetIsOptimized() { @@ -738,25 +724,6 @@ removeHostnameFromPathname(llvm::StringRef path_from_dwarf) { return path; } -static FileSpec resolveCompDir(const FileSpec &path) { - bool is_symlink = SymbolFileDWARF::GetSymlinkPaths().FindFileIndex( - 0, path, /*full*/ true) != UINT32_MAX; - - if (!is_symlink) - return path; - - namespace fs = llvm::sys::fs; - if (fs::get_file_type(path.GetPath(), false) != fs::file_type::symlink_file) - return path; - - FileSpec resolved_symlink; - const auto error = FileSystem::Instance().Readlink(path, resolved_symlink); - if (error.Success()) - return resolved_symlink; - - return path; -} - void DWARFUnit::ComputeCompDirAndGuessPathStyle() { m_comp_dir = FileSpec(); const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); @@ -768,7 +735,7 @@ void DWARFUnit::ComputeCompDirAndGuessPathStyle() { if (!comp_dir.empty()) { FileSpec::Style comp_dir_style = FileSpec::GuessPathStyle(comp_dir).getValueOr(FileSpec::Style::native); - m_comp_dir = resolveCompDir(FileSpec(comp_dir, comp_dir_style)); + m_comp_dir = FileSpec(comp_dir, comp_dir_style); } else { // Try to detect the style based on the DW_AT_name attribute, but just store // the detected style in the m_comp_dir field. @@ -795,21 +762,22 @@ void DWARFUnit::ComputeAbsolutePath() { SymbolFileDWARFDwo *DWARFUnit::GetDwoSymbolFile() { ExtractUnitDIEIfNeeded(); - return m_dwo_symbol_file.get(); + if (m_dwo) + return &llvm::cast<SymbolFileDWARFDwo>(m_dwo->GetSymbolFileDWARF()); + return nullptr; } const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() { if (m_func_aranges_up == nullptr) { - m_func_aranges_up.reset(new DWARFDebugAranges()); + m_func_aranges_up = std::make_unique<DWARFDebugAranges>(); const DWARFDebugInfoEntry *die = DIEPtr(); if (die) die->BuildFunctionAddressRangeTable(this, m_func_aranges_up.get()); - if (m_dwo_symbol_file) { - DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit(); - const DWARFDebugInfoEntry *dwo_die = dwo_cu->DIEPtr(); + if (m_dwo) { + const DWARFDebugInfoEntry *dwo_die = m_dwo->DIEPtr(); if (dwo_die) - dwo_die->BuildFunctionAddressRangeTable(dwo_cu, + dwo_die->BuildFunctionAddressRangeTable(m_dwo.get(), m_func_aranges_up.get()); } @@ -820,10 +788,13 @@ const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() { } llvm::Expected<DWARFUnitHeader> -DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section, - lldb::offset_t *offset_ptr) { +DWARFUnitHeader::extract(const DWARFDataExtractor &data, + DIERef::Section section, lldb::offset_t *offset_ptr, + const llvm::DWARFUnitIndex *index) { DWARFUnitHeader header; header.m_offset = *offset_ptr; + if (index) + header.m_index_entry = index->getFromOffset(*offset_ptr); header.m_length = data.GetDWARFInitialLength(offset_ptr); header.m_version = data.GetU16(offset_ptr); if (header.m_version == 5) { @@ -839,6 +810,26 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile; } + if (header.m_index_entry) { + if (header.m_abbr_offset) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Package unit with a non-zero abbreviation offset"); + } + auto *unit_contrib = header.m_index_entry->getContribution(); + if (!unit_contrib || unit_contrib->Length != header.m_length + 4) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Inconsistent DWARF package unit index"); + } + auto *abbr_entry = + header.m_index_entry->getContribution(llvm::DW_SECT_ABBREV); + if (!abbr_entry) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "DWARF package index missing abbreviation column"); + } + header.m_abbr_offset = abbr_entry->Offset; + } if (header.IsTypeUnit()) { header.m_type_hash = data.GetU64(offset_ptr); header.m_type_offset = data.GetDWARFOffset(offset_ptr); @@ -869,11 +860,12 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section llvm::Expected<DWARFUnitSP> DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid, const DWARFDataExtractor &debug_info, - DIERef::Section section, lldb::offset_t *offset_ptr) { + DIERef::Section section, lldb::offset_t *offset_ptr, + const llvm::DWARFUnitIndex *index) { assert(debug_info.ValidOffset(*offset_ptr)); auto expected_header = - DWARFUnitHeader::extract(debug_info, section, offset_ptr); + DWARFUnitHeader::extract(debug_info, section, offset_ptr, index); if (!expected_header) return expected_header.takeError(); @@ -924,6 +916,12 @@ uint32_t DWARFUnit::GetHeaderByteSize() const { llvm_unreachable("invalid UnitType."); } +llvm::Optional<uint64_t> +DWARFUnit::GetStringOffsetSectionItem(uint32_t index) const { + offset_t offset = GetStrOffsetsBase() + index * 4; + return m_dwarf.GetDWARFContext().getOrLoadStrOffsetsData().GetU32(&offset); +} + llvm::Expected<DWARFRangeList> DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) { if (GetVersion() <= 4) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 217f9bb89ace..affad286a490 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -6,12 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFUnit_h_ -#define SymbolFileDWARF_DWARFUnit_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFUNIT_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFUNIT_H #include "DWARFDIE.h" #include "DWARFDebugInfoEntry.h" #include "lldb/lldb-enumerations.h" +#include "lldb/Utility/XcodeSDK.h" #include "llvm/Support/RWMutex.h" #include <atomic> @@ -39,6 +40,9 @@ class DWARFUnitHeader { dw_offset_t m_length = 0; uint16_t m_version = 0; dw_offset_t m_abbr_offset = 0; + + const llvm::DWARFUnitIndex::Entry *m_index_entry = nullptr; + uint8_t m_unit_type = 0; uint8_t m_addr_size = 0; @@ -56,6 +60,9 @@ public: dw_offset_t GetLength() const { return m_length; } dw_offset_t GetAbbrOffset() const { return m_abbr_offset; } uint8_t GetUnitType() const { return m_unit_type; } + const llvm::DWARFUnitIndex::Entry *GetIndexEntry() const { + return m_index_entry; + } uint64_t GetTypeHash() const { return m_type_hash; } dw_offset_t GetTypeOffset() const { return m_type_offset; } bool IsTypeUnit() const { @@ -65,7 +72,7 @@ public: static llvm::Expected<DWARFUnitHeader> extract(const lldb_private::DWARFDataExtractor &data, DIERef::Section section, - lldb::offset_t *offset_ptr); + lldb::offset_t *offset_ptr, const llvm::DWARFUnitIndex *index); }; class DWARFUnit : public lldb_private::UserID { @@ -76,9 +83,12 @@ public: static llvm::Expected<DWARFUnitSP> extract(SymbolFileDWARF &dwarf2Data, lldb::user_id_t uid, const lldb_private::DWARFDataExtractor &debug_info, - DIERef::Section section, lldb::offset_t *offset_ptr); + DIERef::Section section, lldb::offset_t *offset_ptr, + const llvm::DWARFUnitIndex *index); virtual ~DWARFUnit(); + bool IsDWOUnit() { return m_is_dwo; } + void ExtractUnitDIEIfNeeded(); void ExtractDIEsIfNeeded(); @@ -88,7 +98,8 @@ public: bool m_clear_dies = false; ScopedExtractDIEs(DWARFUnit &cu); ~ScopedExtractDIEs(); - DISALLOW_COPY_AND_ASSIGN(ScopedExtractDIEs); + ScopedExtractDIEs(const ScopedExtractDIEs &) = delete; + const ScopedExtractDIEs &operator=(const ScopedExtractDIEs &) = delete; ScopedExtractDIEs(ScopedExtractDIEs &&rhs); ScopedExtractDIEs &operator=(ScopedExtractDIEs &&rhs); }; @@ -152,8 +163,6 @@ public: lldb::ByteOrder GetByteOrder() const; - llvm::Expected<lldb_private::TypeSystem &> GetTypeSystem(); - const DWARFDebugAranges &GetFunctionAranges(); void SetBaseAddress(dw_addr_t base_addr); @@ -190,9 +199,7 @@ public: uint32_t GetProducerVersionUpdate(); - static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val); - - lldb::LanguageType GetLanguageType(); + uint64_t GetDWARFLanguageType(); bool GetIsOptimized(); @@ -213,6 +220,8 @@ public: uint8_t GetUnitType() const { return m_header.GetUnitType(); } bool IsTypeUnit() const { return m_header.IsTypeUnit(); } + llvm::Optional<uint64_t> GetStringOffsetSectionItem(uint32_t index) const; + /// Return a list of address ranges resulting from a (possibly encoded) /// range list starting at a given offset in the appropriate ranges section. llvm::Expected<DWARFRangeList> FindRnglistFromOffset(dw_offset_t offset); @@ -248,7 +257,7 @@ public: std::unique_ptr<llvm::DWARFLocationTable> GetLocationTable(const lldb_private::DataExtractor &data) const; - const lldb_private::DWARFDataExtractor &GetLocationData() const; + lldb_private::DWARFDataExtractor GetLocationData() const; protected: DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid, @@ -279,7 +288,7 @@ protected: } SymbolFileDWARF &m_dwarf; - std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file; + std::shared_ptr<DWARFUnit> m_dwo; DWARFUnitHeader m_header; const DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr; void *m_user_data = nullptr; @@ -304,7 +313,7 @@ protected: uint32_t m_producer_version_major = 0; uint32_t m_producer_version_minor = 0; uint32_t m_producer_version_update = 0; - lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown; + llvm::Optional<uint64_t> m_language_type; lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate; llvm::Optional<lldb_private::FileSpec> m_comp_dir; llvm::Optional<lldb_private::FileSpec> m_file_spec; @@ -329,11 +338,13 @@ private: void ClearDIEsRWLocked(); void AddUnitDIE(const DWARFDebugInfoEntry &cu_die); + void SetDwoStrOffsetsBase(); void ComputeCompDirAndGuessPathStyle(); void ComputeAbsolutePath(); - DISALLOW_COPY_AND_ASSIGN(DWARFUnit); + DWARFUnit(const DWARFUnit &) = delete; + const DWARFUnit &operator=(const DWARFUnit &) = delete; }; -#endif // SymbolFileDWARF_DWARFUnit_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFUNIT_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index 007ef2e05e59..cb3e662a6cdf 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -1,4 +1,4 @@ -//===-- DebugNamesDWARFIndex.cpp -------------------------------*- C++ -*-===// +//===-- DebugNamesDWARFIndex.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,6 +10,7 @@ #include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h" #include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h" +#include "lldb/Core/Module.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" @@ -19,18 +20,14 @@ using namespace lldb; llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names, DWARFDataExtractor debug_str, - DWARFDebugInfo *debug_info) { - if (!debug_info) { - return llvm::make_error<llvm::StringError>("debug info null", - llvm::inconvertibleErrorCode()); - } + SymbolFileDWARF &dwarf) { auto index_up = std::make_unique<DebugNames>(debug_names.GetAsLLVM(), debug_str.GetAsLLVM()); if (llvm::Error E = index_up->extract()) return std::move(E); return std::unique_ptr<DebugNamesDWARFIndex>(new DebugNamesDWARFIndex( - module, std::move(index_up), debug_names, debug_str, *debug_info)); + module, std::move(index_up), debug_names, debug_str, dwarf)); } llvm::DenseSet<dw_offset_t> @@ -53,12 +50,7 @@ DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) { if (!cu) return llvm::None; - // This initializes the DWO symbol file. It's not possible for - // GetDwoSymbolFile to call this automatically because of mutual recursion - // between this and DWARFDebugInfoEntry::GetAttributeValue. - cu->ExtractUnitDIEIfNeeded(); cu = &cu->GetNonSkeletonUnit(); - if (llvm::Optional<uint64_t> die_offset = entry.getDIEUnitOffset()) return DIERef(cu->GetSymbolFileDWARF().GetDwoNum(), DIERef::Section::DebugInfo, cu->GetOffset() + *die_offset); @@ -66,10 +58,18 @@ DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) { return llvm::None; } -void DebugNamesDWARFIndex::Append(const DebugNames::Entry &entry, - DIEArray &offsets) { - if (llvm::Optional<DIERef> ref = ToDIERef(entry)) - offsets.push_back(*ref); +bool DebugNamesDWARFIndex::ProcessEntry( + const DebugNames::Entry &entry, + llvm::function_ref<bool(DWARFDIE die)> callback, llvm::StringRef name) { + llvm::Optional<DIERef> ref = ToDIERef(entry); + if (!ref) + return true; + SymbolFileDWARF &dwarf = + *llvm::cast<SymbolFileDWARF>(m_module.GetSymbolFile()); + DWARFDIE die = dwarf.GetDIE(*ref); + if (!die) + return true; + return callback(die); } void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error, @@ -83,23 +83,23 @@ void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error, ni.getUnitOffset(), name); } -void DebugNamesDWARFIndex::GetGlobalVariables(ConstString basename, - DIEArray &offsets) { - m_fallback.GetGlobalVariables(basename, offsets); - +void DebugNamesDWARFIndex::GetGlobalVariables( + ConstString basename, llvm::function_ref<bool(DWARFDIE die)> callback) { for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(basename.GetStringRef())) { if (entry.tag() != DW_TAG_variable) continue; - Append(entry, offsets); + if (!ProcessEntry(entry, callback, basename.GetStringRef())) + return; } -} -void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) { - m_fallback.GetGlobalVariables(regex, offsets); + m_fallback.GetGlobalVariables(basename, callback); +} +void DebugNamesDWARFIndex::GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref<bool(DWARFDIE die)> callback) { for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { if (!regex.Execute(nte.getString())) @@ -111,17 +111,19 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, if (entry_or->tag() != DW_TAG_variable) continue; - Append(*entry_or, offsets); + if (!ProcessEntry(*entry_or, callback, + llvm::StringRef(nte.getString()))) + return; } MaybeLogLookupError(entry_or.takeError(), ni, nte.getString()); } } -} -void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu, - DIEArray &offsets) { - m_fallback.GetGlobalVariables(cu, offsets); + m_fallback.GetGlobalVariables(regex, callback); +} +void DebugNamesDWARFIndex::GetGlobalVariables( + const DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) { uint64_t cu_offset = cu.GetOffset(); for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { @@ -133,18 +135,20 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu, if (entry_or->getCUOffset() != cu_offset) continue; - Append(*entry_or, offsets); + if (!ProcessEntry(*entry_or, callback, + llvm::StringRef(nte.getString()))) + return; } MaybeLogLookupError(entry_or.takeError(), ni, nte.getString()); } } -} -void DebugNamesDWARFIndex::GetCompleteObjCClass(ConstString class_name, - bool must_be_implementation, - DIEArray &offsets) { - m_fallback.GetCompleteObjCClass(class_name, must_be_implementation, offsets); + m_fallback.GetGlobalVariables(cu, callback); +} +void DebugNamesDWARFIndex::GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref<bool(DWARFDIE die)> callback) { // Keep a list of incomplete types as fallback for when we don't find the // complete type. DIEArray incomplete_types; @@ -165,84 +169,98 @@ void DebugNamesDWARFIndex::GetCompleteObjCClass(ConstString class_name, continue; } - // FIXME: We should return DWARFDIEs so we don't have to resolve it twice. DWARFDIE die = m_debug_info.GetDIE(*ref); - if (!die) + if (!die) { + ReportInvalidDIERef(*ref, class_name.GetStringRef()); continue; + } if (die.GetAttributeValueAsUnsigned(DW_AT_APPLE_objc_complete_type, 0)) { // If we find the complete version we're done. - offsets.push_back(*ref); + callback(die); return; - } else { - incomplete_types.push_back(*ref); } + incomplete_types.push_back(*ref); } - offsets.insert(offsets.end(), incomplete_types.begin(), - incomplete_types.end()); -} + auto dierefcallback = DIERefCallback(callback, class_name.GetStringRef()); + for (DIERef ref : incomplete_types) + if (!dierefcallback(ref)) + return; -void DebugNamesDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) { - m_fallback.GetTypes(name, offsets); + m_fallback.GetCompleteObjCClass(class_name, must_be_implementation, callback); +} +void DebugNamesDWARFIndex::GetTypes( + ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) { for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { - if (isType(entry.tag())) - Append(entry, offsets); + if (isType(entry.tag())) { + if (!ProcessEntry(entry, callback, name.GetStringRef())) + return; + } } -} -void DebugNamesDWARFIndex::GetTypes(const DWARFDeclContext &context, - DIEArray &offsets) { - m_fallback.GetTypes(context, offsets); + m_fallback.GetTypes(name, callback); +} - for (const DebugNames::Entry &entry : - m_debug_names_up->equal_range(context[0].name)) { - if (entry.tag() == context[0].tag) - Append(entry, offsets); +void DebugNamesDWARFIndex::GetTypes( + const DWARFDeclContext &context, + llvm::function_ref<bool(DWARFDIE die)> callback) { + auto name = context[0].name; + for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name)) { + if (entry.tag() == context[0].tag) { + if (!ProcessEntry(entry, callback, name)) + return; + } } -} -void DebugNamesDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) { - m_fallback.GetNamespaces(name, offsets); + m_fallback.GetTypes(context, callback); +} +void DebugNamesDWARFIndex::GetNamespaces( + ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) { for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { - if (entry.tag() == DW_TAG_namespace) - Append(entry, offsets); + if (entry.tag() == DW_TAG_namespace) { + if (!ProcessEntry(entry, callback, name.GetStringRef())) + return; + } } + + m_fallback.GetNamespaces(name, callback); } void DebugNamesDWARFIndex::GetFunctions( ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - std::vector<DWARFDIE> &dies) { - - std::vector<DWARFDIE> v; - m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask, v); + llvm::function_ref<bool(DWARFDIE die)> callback) { + std::set<DWARFDebugInfoEntry *> seen; for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { Tag tag = entry.tag(); if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine) continue; - if (llvm::Optional<DIERef> ref = ToDIERef(entry)) - ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx, - name_type_mask, v); + if (llvm::Optional<DIERef> ref = ToDIERef(entry)) { + if (!ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx, + name_type_mask, [&](DWARFDIE die) { + if (!seen.insert(die.GetDIE()).second) + return true; + return callback(die); + })) + return; + } } - std::set<DWARFDebugInfoEntry *> seen; - for (DWARFDIE die : v) - if (seen.insert(die.GetDIE()).second) - dies.push_back(die); + m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask, + callback); } -void DebugNamesDWARFIndex::GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) { - m_fallback.GetFunctions(regex, offsets); - +void DebugNamesDWARFIndex::GetFunctions( + const RegularExpression ®ex, + llvm::function_ref<bool(DWARFDIE die)> callback) { for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { if (!regex.Execute(nte.getString())) @@ -255,11 +273,15 @@ void DebugNamesDWARFIndex::GetFunctions(const RegularExpression ®ex, if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine) continue; - Append(*entry_or, offsets); + if (!ProcessEntry(*entry_or, callback, + llvm::StringRef(nte.getString()))) + return; } MaybeLogLookupError(entry_or.takeError(), ni, nte.getString()); } } + + m_fallback.GetFunctions(regex, callback); } void DebugNamesDWARFIndex::Dump(Stream &s) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h index dca25496373f..5d041c36c8f2 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -6,12 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_DEBUGNAMESDWARFINDEX_H -#define LLDB_DEBUGNAMESDWARFINDEX_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DEBUGNAMESDWARFINDEX_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DEBUGNAMESDWARFINDEX_H #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h" #include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h" +#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" #include "lldb/Utility/ConstString.h" #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" @@ -20,28 +21,38 @@ class DebugNamesDWARFIndex : public DWARFIndex { public: static llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> Create(Module &module, DWARFDataExtractor debug_names, - DWARFDataExtractor debug_str, DWARFDebugInfo *debug_info); + DWARFDataExtractor debug_str, SymbolFileDWARF &dwarf); void Preload() override { m_fallback.Preload(); } - void GetGlobalVariables(ConstString basename, DIEArray &offsets) override; - void GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) override; - void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override; - void GetObjCMethods(ConstString class_name, DIEArray &offsets) override {} - void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, - DIEArray &offsets) override; - void GetTypes(ConstString name, DIEArray &offsets) override; - void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override; - void GetNamespaces(ConstString name, DIEArray &offsets) override; + void + GetGlobalVariables(ConstString basename, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void + GetGlobalVariables(const DWARFUnit &cu, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void + GetObjCMethods(ConstString class_name, + llvm::function_ref<bool(DWARFDIE die)> callback) override {} + void GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetTypes(ConstString name, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetTypes(const DWARFDeclContext &context, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetNamespaces(ConstString name, + llvm::function_ref<bool(DWARFDIE die)> callback) override; void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - std::vector<DWARFDIE> &dies) override; + llvm::function_ref<bool(DWARFDIE die)> callback) override; void GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) override; + llvm::function_ref<bool(DWARFDIE die)> callback) override; - void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override {} void Dump(Stream &s) override; private: @@ -49,11 +60,11 @@ private: std::unique_ptr<llvm::DWARFDebugNames> debug_names_up, DWARFDataExtractor debug_names_data, DWARFDataExtractor debug_str_data, - DWARFDebugInfo &debug_info) - : DWARFIndex(module), m_debug_info(debug_info), + SymbolFileDWARF &dwarf) + : DWARFIndex(module), m_debug_info(dwarf.DebugInfo()), m_debug_names_data(debug_names_data), m_debug_str_data(debug_str_data), m_debug_names_up(std::move(debug_names_up)), - m_fallback(module, &debug_info, GetUnits(*m_debug_names_up)) {} + m_fallback(module, dwarf, GetUnits(*m_debug_names_up)) {} DWARFDebugInfo &m_debug_info; @@ -67,7 +78,9 @@ private: ManualDWARFIndex m_fallback; llvm::Optional<DIERef> ToDIERef(const DebugNames::Entry &entry); - void Append(const DebugNames::Entry &entry, DIEArray &offsets); + bool ProcessEntry(const DebugNames::Entry &entry, + llvm::function_ref<bool(DWARFDIE die)> callback, + llvm::StringRef name); static void MaybeLogLookupError(llvm::Error error, const DebugNames::NameIndex &ni, @@ -78,4 +91,4 @@ private: } // namespace lldb_private -#endif // LLDB_DEBUGNAMESDWARFINDEX_H +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DEBUGNAMESDWARFINDEX_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp index 88a29f4a2672..d36f2a8bccf7 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp @@ -1,4 +1,4 @@ -//===-- HashedNameToDIE.cpp -------------------------------------*- C++ -*-===// +//===-- HashedNameToDIE.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,91 +9,99 @@ #include "HashedNameToDIE.h" #include "llvm/ADT/StringRef.h" -void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, - DIEArray &die_offsets) { +bool DWARFMappedHash::ExtractDIEArray( + const DIEInfoArray &die_info_array, + llvm::function_ref<bool(DIERef ref)> callback) { const size_t count = die_info_array.size(); for (size_t i = 0; i < count; ++i) - die_offsets.emplace_back(die_info_array[i]); + if (!callback(DIERef(die_info_array[i]))) + return false; + return true; } -void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, - const dw_tag_t tag, - DIEArray &die_offsets) { +void DWARFMappedHash::ExtractDIEArray( + const DIEInfoArray &die_info_array, const dw_tag_t tag, + llvm::function_ref<bool(DIERef ref)> callback) { 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.emplace_back(die_info_array[i]); + ExtractDIEArray(die_info_array, callback); + return; + } + + 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) { + if (!callback(DIERef(die_info_array[i]))) + return; } } } -void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, - const dw_tag_t tag, - const uint32_t qualified_name_hash, - DIEArray &die_offsets) { +void DWARFMappedHash::ExtractDIEArray( + const DIEInfoArray &die_info_array, const dw_tag_t tag, + const uint32_t qualified_name_hash, + llvm::function_ref<bool(DIERef ref)> callback) { 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.emplace_back(die_info_array[i]); + ExtractDIEArray(die_info_array, callback); + return; + } + + 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) { + if (!callback(DIERef(die_info_array[i]))) + return; } } } void DWARFMappedHash::ExtractClassOrStructDIEArray( const DIEInfoArray &die_info_array, - bool return_implementation_only_if_available, DIEArray &die_offsets) { + bool return_implementation_only_if_available, + llvm::function_ref<bool(DIERef ref)> callback) { 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.emplace_back(die_info_array[i]); - return; - } else { - // Put the one true definition as the first entry so it matches first - die_offsets.emplace(die_offsets.begin(), die_info_array[i]); - } - } else { - die_offsets.emplace_back(die_info_array[i]); - } + if (!(die_tag == 0 || die_tag == DW_TAG_class_type || + die_tag == DW_TAG_structure_type)) + continue; + bool is_implementation = + (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) != 0; + if (is_implementation != return_implementation_only_if_available) + continue; + if (return_implementation_only_if_available) { + // We found the one true definition for this class, so only return + // that + callback(DIERef(die_info_array[i])); + return; } + if (!callback(DIERef(die_info_array[i]))) + return; } } void DWARFMappedHash::ExtractTypesFromDIEArray( const DIEInfoArray &die_info_array, uint32_t type_flag_mask, - uint32_t type_flag_value, DIEArray &die_offsets) { + uint32_t type_flag_value, llvm::function_ref<bool(DIERef ref)> callback) { 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.emplace_back(die_info_array[i]); + if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value) { + if (!callback(DIERef(die_info_array[i]))) + return; + } } } @@ -453,7 +461,7 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression( } } -size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex( +void DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex( const lldb_private::RegularExpression ®ex, DIEInfoArray &die_info_array) const { const uint32_t hash_count = m_header.hashes_count; @@ -482,10 +490,9 @@ size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex( } } die_info_array.swap(pair.value); - return die_info_array.size(); } -size_t DWARFMappedHash::MemoryTable::AppendAllDIEsInRange( +void 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; @@ -512,73 +519,74 @@ size_t DWARFMappedHash::MemoryTable::AppendAllDIEsInRange( } } } - return die_info_array.size(); } -size_t DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name, - DIEArray &die_offsets) { +bool DWARFMappedHash::MemoryTable::FindByName( + llvm::StringRef name, llvm::function_ref<bool(DIERef ref)> callback) { if (name.empty()) - return 0; + return true; DIEInfoArray die_info_array; - if (FindByName(name, die_info_array)) - DWARFMappedHash::ExtractDIEArray(die_info_array, die_offsets); - return die_info_array.size(); + FindByName(name, die_info_array); + return DWARFMappedHash::ExtractDIEArray(die_info_array, callback); } -size_t DWARFMappedHash::MemoryTable::FindByNameAndTag(llvm::StringRef name, - const dw_tag_t tag, - DIEArray &die_offsets) { +void DWARFMappedHash::MemoryTable::FindByNameAndTag( + llvm::StringRef name, const dw_tag_t tag, + llvm::function_ref<bool(DIERef ref)> callback) { DIEInfoArray die_info_array; - if (FindByName(name, die_info_array)) - DWARFMappedHash::ExtractDIEArray(die_info_array, tag, die_offsets); - return die_info_array.size(); + FindByName(name, die_info_array); + DWARFMappedHash::ExtractDIEArray(die_info_array, tag, callback); } -size_t DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash( +void DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash( llvm::StringRef name, const dw_tag_t tag, - const uint32_t qualified_name_hash, DIEArray &die_offsets) { + const uint32_t qualified_name_hash, + llvm::function_ref<bool(DIERef ref)> callback) { 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(); + FindByName(name, die_info_array); + DWARFMappedHash::ExtractDIEArray(die_info_array, tag, qualified_name_hash, + callback); } -size_t DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName( - llvm::StringRef name, DIEArray &die_offsets, bool must_be_implementation) { +void DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName( + llvm::StringRef name, llvm::function_ref<bool(DIERef ref)> callback, + 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); - } + 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, callback); + return; } - return die_offsets.size(); + // 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. + bool found_implementation = false; + DWARFMappedHash::ExtractClassOrStructDIEArray( + die_info_array, true /*return_implementation_only_if_available*/, + [&](DIERef ref) { + found_implementation = true; + // Here the return value does not matter as we are called at most once. + return callback(ref); + }); + if (found_implementation) + return; + DWARFMappedHash::ExtractClassOrStructDIEArray( + die_info_array, false /*return_implementation_only_if_available*/, + callback); } -size_t DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name, - DIEInfoArray &die_info_array) { +void DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name, + DIEInfoArray &die_info_array) { if (name.empty()) - return 0; + return; Pair kv_pair; - size_t old_size = die_info_array.size(); - if (Find(name, kv_pair)) { + if (Find(name, kv_pair)) die_info_array.swap(kv_pair.value); - return die_info_array.size() - old_size; - } - return 0; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h index 56d9bc548877..ad178fc6a987 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_HashedNameToDIE_h_ -#define SymbolFileDWARF_HashedNameToDIE_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H #include <vector> @@ -132,33 +132,36 @@ public: bool ReadHashData(uint32_t hash_data_offset, HashData &hash_data) const override; - size_t + void AppendAllDIEsThatMatchingRegex(const lldb_private::RegularExpression ®ex, 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; + void AppendAllDIEsInRange(const uint32_t die_offset_start, + const uint32_t die_offset_end, + DIEInfoArray &die_info_array) const; - size_t FindByName(llvm::StringRef name, DIEArray &die_offsets); + bool FindByName(llvm::StringRef name, + llvm::function_ref<bool(DIERef ref)> callback); - size_t FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag, - DIEArray &die_offsets); + void FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag, + llvm::function_ref<bool(DIERef ref)> callback); - size_t FindByNameAndTagAndQualifiedNameHash( + void FindByNameAndTagAndQualifiedNameHash( llvm::StringRef name, const dw_tag_t tag, - const uint32_t qualified_name_hash, DIEArray &die_offsets); + const uint32_t qualified_name_hash, + llvm::function_ref<bool(DIERef ref)> callback); - size_t FindCompleteObjCClassByName(llvm::StringRef name, - DIEArray &die_offsets, - bool must_be_implementation); + void + FindCompleteObjCClassByName(llvm::StringRef name, + llvm::function_ref<bool(DIERef ref)> callback, + bool must_be_implementation); protected: Result AppendHashDataForRegularExpression( const lldb_private::RegularExpression ®ex, lldb::offset_t *hash_data_offset_ptr, Pair &pair) const; - size_t FindByName(llvm::StringRef name, DIEInfoArray &die_info_array); + void FindByName(llvm::StringRef name, DIEInfoArray &die_info_array); Result GetHashDataForName(llvm::StringRef name, lldb::offset_t *hash_data_offset_ptr, @@ -169,29 +172,30 @@ public: std::string m_name; }; - static void ExtractDIEArray(const DIEInfoArray &die_info_array, - DIEArray &die_offsets); + static bool ExtractDIEArray(const DIEInfoArray &die_info_array, + llvm::function_ref<bool(DIERef ref)> callback); protected: static void ExtractDIEArray(const DIEInfoArray &die_info_array, - const dw_tag_t tag, DIEArray &die_offsets); + const dw_tag_t tag, + llvm::function_ref<bool(DIERef ref)> callback); static void ExtractDIEArray(const DIEInfoArray &die_info_array, const dw_tag_t tag, const uint32_t qualified_name_hash, - DIEArray &die_offsets); + llvm::function_ref<bool(DIERef ref)> callback); static void ExtractClassOrStructDIEArray(const DIEInfoArray &die_info_array, bool return_implementation_only_if_available, - DIEArray &die_offsets); + llvm::function_ref<bool(DIERef ref)> callback); - static void ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array, - uint32_t type_flag_mask, - uint32_t type_flag_value, - DIEArray &die_offsets); + static void + ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array, + uint32_t type_flag_mask, uint32_t type_flag_value, + llvm::function_ref<bool(DIERef ref)> callback); static const char *GetAtomTypeName(uint16_t atom); }; -#endif // SymbolFileDWARF_HashedNameToDIE_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp index 8495016d4280..3f1d6677bacf 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp @@ -1,4 +1,4 @@ -//===-- LogChannelDWARF.cpp ------------------------------------*- C++ -*-===// +//===-- LogChannelDWARF.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h index a89c686735d2..2fc23563ef93 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_LogChannelDWARF_h_ -#define SymbolFileDWARF_LogChannelDWARF_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_LOGCHANNELDWARF_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_LOGCHANNELDWARF_H #include "lldb/Utility/Log.h" @@ -32,4 +32,4 @@ public: }; } -#endif // SymbolFileDWARF_LogChannelDWARF_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_LOGCHANNELDWARF_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp index 1e5927bd14f0..7bf4b52bc783 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -1,4 +1,4 @@ -//===-- ManualDWARFIndex.cpp -----------------------------------*- C++ -*-===// +//===-- ManualDWARFIndex.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,31 +13,47 @@ #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" #include "lldb/Utility/Stream.h" #include "lldb/Utility/Timer.h" +#include "llvm/Support/ThreadPool.h" using namespace lldb_private; using namespace lldb; void ManualDWARFIndex::Index() { - if (!m_debug_info) + if (!m_dwarf) return; - DWARFDebugInfo &debug_info = *m_debug_info; - m_debug_info = nullptr; + SymbolFileDWARF &main_dwarf = *m_dwarf; + m_dwarf = nullptr; static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); - Timer scoped_timer(func_cat, "%p", static_cast<void *>(&debug_info)); + Timer scoped_timer(func_cat, "%p", static_cast<void *>(&main_dwarf)); + + DWARFDebugInfo &main_info = main_dwarf.DebugInfo(); + SymbolFileDWARFDwo *dwp_dwarf = main_dwarf.GetDwpSymbolFile().get(); + DWARFDebugInfo *dwp_info = dwp_dwarf ? &dwp_dwarf->DebugInfo() : nullptr; std::vector<DWARFUnit *> units_to_index; - units_to_index.reserve(debug_info.GetNumUnits()); - for (size_t U = 0; U < debug_info.GetNumUnits(); ++U) { - DWARFUnit *unit = debug_info.GetUnitAtIndex(U); + units_to_index.reserve(main_info.GetNumUnits() + + (dwp_info ? dwp_info->GetNumUnits() : 0)); + + // Process all units in the main file, as well as any type units in the dwp + // file. Type units in dwo files are handled when we reach the dwo file in + // IndexUnit. + for (size_t U = 0; U < main_info.GetNumUnits(); ++U) { + DWARFUnit *unit = main_info.GetUnitAtIndex(U); if (unit && m_units_to_avoid.count(unit->GetOffset()) == 0) units_to_index.push_back(unit); } + if (dwp_info && dwp_info->ContainsTypeUnits()) { + for (size_t U = 0; U < dwp_info->GetNumUnits(); ++U) { + if (auto *tu = llvm::dyn_cast<DWARFTypeUnit>(dwp_info->GetUnitAtIndex(U))) + units_to_index.push_back(tu); + } + } + if (units_to_index.empty()) return; @@ -48,27 +64,34 @@ void ManualDWARFIndex::Index() { std::vector<llvm::Optional<DWARFUnit::ScopedExtractDIEs>> clear_cu_dies( units_to_index.size()); auto parser_fn = [&](size_t cu_idx) { - IndexUnit(*units_to_index[cu_idx], sets[cu_idx]); + IndexUnit(*units_to_index[cu_idx], dwp_dwarf, sets[cu_idx]); }; auto extract_fn = [&units_to_index, &clear_cu_dies](size_t cu_idx) { clear_cu_dies[cu_idx] = units_to_index[cu_idx]->ExtractDIEsScoped(); }; + // Share one thread pool across operations to avoid the overhead of + // recreating the threads. + llvm::ThreadPool pool; + // Create a task runner that extracts dies for each DWARF unit in a - // separate thread + // separate thread. // First figure out which units didn't have their DIEs already // parsed and remember this. If no DIEs were parsed prior to this index // function call, we are going to want to clear the CU dies after we are // done indexing to make sure we don't pull in all DWARF dies, but we need // to wait until all units have been indexed in case a DIE in one // unit refers to another and the indexes accesses those DIEs. - TaskMapOverInt(0, units_to_index.size(), extract_fn); + for (size_t i = 0; i < units_to_index.size(); ++i) + pool.async(extract_fn, i); + pool.wait(); // Now create a task runner that can index each DWARF unit in a // separate thread so we can index quickly. - - TaskMapOverInt(0, units_to_index.size(), parser_fn); + for (size_t i = 0; i < units_to_index.size(); ++i) + pool.async(parser_fn, i); + pool.wait(); auto finalize_fn = [this, &sets](NameToDIE(IndexSet::*index)) { NameToDIE &result = m_set.*index; @@ -77,21 +100,19 @@ void ManualDWARFIndex::Index() { result.Finalize(); }; - TaskPool::RunTasks([&]() { finalize_fn(&IndexSet::function_basenames); }, - [&]() { finalize_fn(&IndexSet::function_fullnames); }, - [&]() { finalize_fn(&IndexSet::function_methods); }, - [&]() { finalize_fn(&IndexSet::function_selectors); }, - [&]() { finalize_fn(&IndexSet::objc_class_selectors); }, - [&]() { finalize_fn(&IndexSet::globals); }, - [&]() { finalize_fn(&IndexSet::types); }, - [&]() { finalize_fn(&IndexSet::namespaces); }); + pool.async(finalize_fn, &IndexSet::function_basenames); + pool.async(finalize_fn, &IndexSet::function_fullnames); + pool.async(finalize_fn, &IndexSet::function_methods); + pool.async(finalize_fn, &IndexSet::function_selectors); + pool.async(finalize_fn, &IndexSet::objc_class_selectors); + pool.async(finalize_fn, &IndexSet::globals); + pool.async(finalize_fn, &IndexSet::types); + pool.async(finalize_fn, &IndexSet::namespaces); + pool.wait(); } -void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, IndexSet &set) { - assert( - !unit.GetSymbolFileDWARF().GetBaseCompileUnit() && - "DWARFUnit associated with .dwo or .dwp should not be indexed directly"); - +void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, + IndexSet &set) { Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS); if (log) { @@ -100,14 +121,21 @@ void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, IndexSet &set) { unit.GetOffset()); } - const LanguageType cu_language = unit.GetLanguageType(); + const LanguageType cu_language = SymbolFileDWARF::GetLanguage(unit); IndexUnitImpl(unit, cu_language, set); if (SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile()) { - DWARFDebugInfo &dwo_info = *dwo_symbol_file->DebugInfo(); - for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i) - IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set); + // Type units in a dwp file are indexed separately, so we just need to + // process the split unit here. However, if the split unit is in a dwo file, + // then we need to process type units here. + if (dwo_symbol_file == dwp) { + IndexUnitImpl(unit.GetNonSkeletonUnit(), cu_language, set); + } else { + DWARFDebugInfo &dwo_info = dwo_symbol_file->DebugInfo(); + for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i) + IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set); + } } } @@ -165,12 +193,6 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, 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)) @@ -190,49 +212,8 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, 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 != nullptr) { - 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.UnitAtIndex(i)->GetAddressByteSize()) { - // if (block_data[0] == DW_OP_addr) - // add_die = true; - // } - // } - // } - parent_die = nullptr; // Terminate the while loop. - break; - - case DW_TAG_compile_unit: - case DW_TAG_partial_unit: - is_global_or_static_variable = true; - parent_die = nullptr; // Terminate the while loop. - break; - - default: - parent_die = - parent_die->GetParent(); // Keep going in the while loop. - break; - } - } - } + is_global_or_static_variable = die.IsGlobalOrStaticScopeVariable(); + break; case DW_AT_specification: @@ -347,108 +328,118 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, } } -void ManualDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) { +void ManualDWARFIndex::GetGlobalVariables( + ConstString basename, llvm::function_ref<bool(DWARFDIE die)> callback) { Index(); - m_set.globals.Find(basename, offsets); + m_set.globals.Find(basename, + DIERefCallback(callback, basename.GetStringRef())); } -void ManualDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) { +void ManualDWARFIndex::GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref<bool(DWARFDIE die)> callback) { Index(); - m_set.globals.Find(regex, offsets); + m_set.globals.Find(regex, DIERefCallback(callback, regex.GetText())); } -void ManualDWARFIndex::GetGlobalVariables(const DWARFUnit &unit, - DIEArray &offsets) { +void ManualDWARFIndex::GetGlobalVariables( + const DWARFUnit &unit, llvm::function_ref<bool(DWARFDIE die)> callback) { Index(); - m_set.globals.FindAllEntriesForUnit(unit, offsets); + m_set.globals.FindAllEntriesForUnit(unit, DIERefCallback(callback)); } -void ManualDWARFIndex::GetObjCMethods(ConstString class_name, - DIEArray &offsets) { +void ManualDWARFIndex::GetObjCMethods( + ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) { Index(); - m_set.objc_class_selectors.Find(class_name, offsets); + m_set.objc_class_selectors.Find( + class_name, DIERefCallback(callback, class_name.GetStringRef())); } -void ManualDWARFIndex::GetCompleteObjCClass(ConstString class_name, - bool must_be_implementation, - DIEArray &offsets) { +void ManualDWARFIndex::GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref<bool(DWARFDIE die)> callback) { Index(); - m_set.types.Find(class_name, offsets); + m_set.types.Find(class_name, + DIERefCallback(callback, class_name.GetStringRef())); } -void ManualDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) { +void ManualDWARFIndex::GetTypes( + ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) { Index(); - m_set.types.Find(name, offsets); + m_set.types.Find(name, DIERefCallback(callback, name.GetStringRef())); } -void ManualDWARFIndex::GetTypes(const DWARFDeclContext &context, - DIEArray &offsets) { +void ManualDWARFIndex::GetTypes( + const DWARFDeclContext &context, + llvm::function_ref<bool(DWARFDIE die)> callback) { Index(); - m_set.types.Find(ConstString(context[0].name), offsets); + auto name = context[0].name; + m_set.types.Find(ConstString(name), + DIERefCallback(callback, llvm::StringRef(name))); } -void ManualDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) { +void ManualDWARFIndex::GetNamespaces( + ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) { Index(); - m_set.namespaces.Find(name, offsets); + m_set.namespaces.Find(name, DIERefCallback(callback, name.GetStringRef())); } -void ManualDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - std::vector<DWARFDIE> &dies) { +void ManualDWARFIndex::GetFunctions( + ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + llvm::function_ref<bool(DWARFDIE die)> callback) { Index(); if (name_type_mask & eFunctionNameTypeFull) { - DIEArray offsets; - m_set.function_fullnames.Find(name, offsets); - for (const DIERef &die_ref: offsets) { - DWARFDIE die = dwarf.GetDIE(die_ref); - if (!die) - continue; - if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die)) - dies.push_back(die); - } + if (!m_set.function_fullnames.Find( + name, DIERefCallback( + [&](DWARFDIE die) { + if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, + die)) + return true; + return callback(die); + }, + name.GetStringRef()))) + return; } if (name_type_mask & eFunctionNameTypeBase) { - DIEArray offsets; - m_set.function_basenames.Find(name, offsets); - for (const DIERef &die_ref: offsets) { - DWARFDIE die = dwarf.GetDIE(die_ref); - if (!die) - continue; - if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die)) - dies.push_back(die); - } - offsets.clear(); + if (!m_set.function_basenames.Find( + name, DIERefCallback( + [&](DWARFDIE die) { + if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, + die)) + return true; + return callback(die); + }, + name.GetStringRef()))) + return; } if (name_type_mask & eFunctionNameTypeMethod && !parent_decl_ctx.IsValid()) { - DIEArray offsets; - m_set.function_methods.Find(name, offsets); - for (const DIERef &die_ref: offsets) { - if (DWARFDIE die = dwarf.GetDIE(die_ref)) - dies.push_back(die); - } + if (!m_set.function_methods.Find( + name, DIERefCallback(callback, name.GetStringRef()))) + return; } if (name_type_mask & eFunctionNameTypeSelector && !parent_decl_ctx.IsValid()) { - DIEArray offsets; - m_set.function_selectors.Find(name, offsets); - for (const DIERef &die_ref: offsets) { - if (DWARFDIE die = dwarf.GetDIE(die_ref)) - dies.push_back(die); - } + if (!m_set.function_selectors.Find( + name, DIERefCallback(callback, name.GetStringRef()))) + return; } } -void ManualDWARFIndex::GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) { +void ManualDWARFIndex::GetFunctions( + const RegularExpression ®ex, + llvm::function_ref<bool(DWARFDIE die)> callback) { Index(); - m_set.function_basenames.Find(regex, offsets); - m_set.function_fullnames.Find(regex, offsets); + if (!m_set.function_basenames.Find(regex, + DIERefCallback(callback, regex.GetText()))) + return; + if (!m_set.function_fullnames.Find(regex, + DIERefCallback(callback, regex.GetText()))) + return; } void ManualDWARFIndex::Dump(Stream &s) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h index dd03b103c936..baff989eecca 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h @@ -6,42 +6,53 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_MANUALDWARFINDEX_H -#define LLDB_MANUALDWARFINDEX_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" #include "Plugins/SymbolFile/DWARF/NameToDIE.h" #include "llvm/ADT/DenseSet.h" class DWARFDebugInfo; +class SymbolFileDWARFDwo; namespace lldb_private { class ManualDWARFIndex : public DWARFIndex { public: - ManualDWARFIndex(Module &module, DWARFDebugInfo *debug_info, + ManualDWARFIndex(Module &module, SymbolFileDWARF &dwarf, llvm::DenseSet<dw_offset_t> units_to_avoid = {}) - : DWARFIndex(module), m_debug_info(debug_info), + : DWARFIndex(module), m_dwarf(&dwarf), m_units_to_avoid(std::move(units_to_avoid)) {} void Preload() override { Index(); } - void GetGlobalVariables(ConstString basename, DIEArray &offsets) override; - void GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) override; - void GetGlobalVariables(const DWARFUnit &unit, DIEArray &offsets) override; - void GetObjCMethods(ConstString class_name, DIEArray &offsets) override; - void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, - DIEArray &offsets) override; - void GetTypes(ConstString name, DIEArray &offsets) override; - void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override; - void GetNamespaces(ConstString name, DIEArray &offsets) override; + void + GetGlobalVariables(ConstString basename, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void + GetGlobalVariables(const DWARFUnit &unit, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetObjCMethods(ConstString class_name, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetTypes(ConstString name, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetTypes(const DWARFDeclContext &context, + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetNamespaces(ConstString name, + llvm::function_ref<bool(DWARFDIE die)> callback) override; void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - std::vector<DWARFDIE> &dies) override; - void GetFunctions(const RegularExpression ®ex, DIEArray &offsets) override; + llvm::function_ref<bool(DWARFDIE die)> callback) override; + void GetFunctions(const RegularExpression ®ex, + llvm::function_ref<bool(DWARFDIE die)> callback) override; - void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override {} void Dump(Stream &s) override; private: @@ -56,14 +67,15 @@ private: NameToDIE namespaces; }; void Index(); - void IndexUnit(DWARFUnit &unit, IndexSet &set); + void IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, IndexSet &set); static void IndexUnitImpl(DWARFUnit &unit, const lldb::LanguageType cu_language, IndexSet &set); - /// Non-null value means we haven't built the index yet. - DWARFDebugInfo *m_debug_info; + /// The DWARF file which we are indexing. Set to nullptr after the index is + /// built. + SymbolFileDWARF *m_dwarf; /// Which dwarf units should we skip while building the index. llvm::DenseSet<dw_offset_t> m_units_to_avoid; @@ -71,4 +83,4 @@ private: }; } // namespace lldb_private -#endif // LLDB_MANUALDWARFINDEX_H +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp index 7d81afb1b226..42e96af84a96 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -1,4 +1,4 @@ -//===-- NameToDIE.cpp -------------------------------------------*- C++ -*-===// +//===-- NameToDIE.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -26,28 +26,38 @@ void NameToDIE::Insert(ConstString name, const DIERef &die_ref) { m_map.Append(name, die_ref); } -size_t NameToDIE::Find(ConstString name, DIEArray &info_array) const { - return m_map.GetValues(name, info_array); +bool NameToDIE::Find(ConstString name, + llvm::function_ref<bool(DIERef ref)> callback) const { + for (const auto &entry : m_map.equal_range(name)) + if (!callback(entry.value)) + return false; + return true; } -size_t NameToDIE::Find(const RegularExpression ®ex, - DIEArray &info_array) const { - return m_map.GetValues(regex, info_array); +bool NameToDIE::Find(const RegularExpression ®ex, + llvm::function_ref<bool(DIERef ref)> callback) const { + for (const auto &entry : m_map) + if (regex.Execute(entry.cstring.GetCString())) { + if (!callback(entry.value)) + return false; + } + return true; } -size_t NameToDIE::FindAllEntriesForUnit(const DWARFUnit &unit, - DIEArray &info_array) const { - const size_t initial_size = info_array.size(); +void NameToDIE::FindAllEntriesForUnit( + const DWARFUnit &unit, + llvm::function_ref<bool(DIERef ref)> callback) const { const uint32_t size = m_map.GetSize(); for (uint32_t i = 0; i < size; ++i) { const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i); if (unit.GetSymbolFileDWARF().GetDwoNum() == die_ref.dwo_num() && unit.GetDebugSection() == die_ref.section() && unit.GetOffset() <= die_ref.die_offset() && - die_ref.die_offset() < unit.GetNextUnitOffset()) - info_array.push_back(die_ref); + die_ref.die_offset() < unit.GetNextUnitOffset()) { + if (!callback(die_ref)) + return; + } } - return info_array.size() - initial_size; } void NameToDIE::Dump(Stream *s) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h index b504f45e81b5..5aa841cf3d10 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_NameToDIE_h_ -#define SymbolFileDWARF_NameToDIE_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_NAMETODIE_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_NAMETODIE_H #include <functional> @@ -32,14 +32,15 @@ public: void Finalize(); - size_t Find(lldb_private::ConstString name, - DIEArray &info_array) const; + bool Find(lldb_private::ConstString name, + llvm::function_ref<bool(DIERef ref)> callback) const; - size_t Find(const lldb_private::RegularExpression ®ex, - DIEArray &info_array) const; + bool Find(const lldb_private::RegularExpression ®ex, + llvm::function_ref<bool(DIERef ref)> callback) const; - size_t FindAllEntriesForUnit(const DWARFUnit &unit, - DIEArray &info_array) const; + void + FindAllEntriesForUnit(const DWARFUnit &unit, + llvm::function_ref<bool(DIERef ref)> callback) const; void ForEach(std::function<bool(lldb_private::ConstString name, @@ -50,4 +51,4 @@ protected: lldb_private::UniqueCStringMap<DIERef> m_map; }; -#endif // SymbolFileDWARF_NameToDIE_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_NAMETODIE_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index d45a8b56efe4..9f64e5255fd5 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFileDWARF.cpp ------------------------------------*- C++ -*-===// +//===-- SymbolFileDWARF.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -34,9 +34,9 @@ #include "lldb/Interpreter/OptionValueFileSpecList.h" #include "lldb/Interpreter/OptionValueProperties.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Symbol/Block.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" @@ -70,7 +70,6 @@ #include "ManualDWARFIndex.h" #include "SymbolFileDWARFDebugMap.h" #include "SymbolFileDWARFDwo.h" -#include "SymbolFileDWARFDwp.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/Support/FileSystem.h" @@ -94,6 +93,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(SymbolFileDWARF) + char SymbolFileDWARF::ID; // static inline bool @@ -135,14 +136,6 @@ public: m_collection_sp->Initialize(g_symbolfiledwarf_properties); } - FileSpecList GetSymLinkPaths() { - const OptionValueFileSpecList *option_value = - m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList( - nullptr, true, ePropertySymLinkPaths); - assert(option_value); - return option_value->GetCurrentValue(); - } - bool IgnoreFileIndexes() const { return m_collection_sp->GetPropertyAtIndexAsBoolean( nullptr, ePropertyIgnoreIndexes, false); @@ -169,18 +162,46 @@ ParseLLVMLineTable(lldb_private::DWARFContext &context, llvm::Expected<const llvm::DWARFDebugLine::LineTable *> line_table = line.getOrParseLineTable( data, line_offset, ctx, nullptr, [&](llvm::Error e) { - LLDB_LOG_ERROR(log, std::move(e), - "SymbolFileDWARF::ParseLineTable failed to parse"); + LLDB_LOG_ERROR( + log, std::move(e), + "SymbolFileDWARF::ParseLineTable failed to parse: {0}"); }); if (!line_table) { LLDB_LOG_ERROR(log, line_table.takeError(), - "SymbolFileDWARF::ParseLineTable failed to parse"); + "SymbolFileDWARF::ParseLineTable failed to parse: {0}"); return nullptr; } return *line_table; } +static bool ParseLLVMLineTablePrologue(lldb_private::DWARFContext &context, + llvm::DWARFDebugLine::Prologue &prologue, + dw_offset_t line_offset, + dw_offset_t unit_offset) { + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); + bool success = true; + llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVM(); + llvm::DWARFContext &ctx = context.GetAsLLVM(); + uint64_t offset = line_offset; + llvm::Error error = prologue.parse( + data, &offset, + [&](llvm::Error e) { + success = false; + LLDB_LOG_ERROR(log, std::move(e), + "SymbolFileDWARF::ParseSupportFiles failed to parse " + "line table prologue: {0}"); + }, + ctx, nullptr); + if (error) { + LLDB_LOG_ERROR(log, std::move(error), + "SymbolFileDWARF::ParseSupportFiles failed to parse line " + "table prologue: {0}"); + return false; + } + return success; +} + static llvm::Optional<std::string> GetFileByIndex(const llvm::DWARFDebugLine::Prologue &prologue, size_t idx, llvm::StringRef compile_dir, FileSpec::Style style) { @@ -192,7 +213,7 @@ GetFileByIndex(const llvm::DWARFDebugLine::Prologue &prologue, size_t idx, // Otherwise ask for a relative path. std::string rel_path; - auto relative = llvm::DILineInfoSpecifier::FileLineInfoKind::Default; + auto relative = llvm::DILineInfoSpecifier::FileLineInfoKind::RawValue; if (!prologue.getFileNameByIndex(idx, compile_dir, relative, rel_path, style)) return {}; return std::move(rel_path); @@ -227,15 +248,12 @@ ParseSupportFilesFromPrologue(const lldb::ModuleSP &module, return support_files; } -FileSpecList SymbolFileDWARF::GetSymlinkPaths() { - return GetGlobalPluginProperties()->GetSymLinkPaths(); -} - void SymbolFileDWARF::Initialize() { LogChannelDWARF::Initialize(); PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, DebuggerInitialize); + SymbolFileDWARFDebugMap::Initialize(); } void SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) { @@ -250,6 +268,7 @@ void SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) { } void SymbolFileDWARF::Terminate() { + SymbolFileDWARFDebugMap::Terminate(); PluginManager::UnregisterPlugin(CreateInstance); LogChannelDWARF::Terminate(); } @@ -333,10 +352,8 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset, if (add_type) { const bool assert_not_being_parsed = true; Type *type = ResolveTypeUID(die, assert_not_being_parsed); - if (type) { - if (type_set.find(type) == type_set.end()) - type_set.insert(type); - } + if (type) + type_set.insert(type); } } @@ -366,15 +383,12 @@ void SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope, GetTypes(dwarf_cu->DIE(), dwarf_cu->GetOffset(), dwarf_cu->GetNextUnitOffset(), type_mask, type_set); } else { - DWARFDebugInfo *info = DebugInfo(); - if (info) { - const size_t num_cus = info->GetNumUnits(); - for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx) { - dwarf_cu = info->GetUnitAtIndex(cu_idx); - if (dwarf_cu) { - GetTypes(dwarf_cu->DIE(), 0, UINT32_MAX, type_mask, type_set); - } - } + DWARFDebugInfo &info = DebugInfo(); + const size_t num_cus = info.GetNumUnits(); + for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx) { + dwarf_cu = info.GetUnitAtIndex(cu_idx); + if (dwarf_cu) + GetTypes(dwarf_cu->DIE(), 0, UINT32_MAX, type_mask, type_set); } } @@ -418,9 +432,8 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp, // contain the .o file index/ID m_debug_map_module_wp(), m_debug_map_symfile(nullptr), m_context(m_objfile_sp->GetModule()->GetSectionList(), dwo_section_list), - m_data_debug_loc(), m_abbr(), m_info(), m_fetched_external_modules(false), - m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), - m_unique_ast_type_map() {} + m_fetched_external_modules(false), + m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {} SymbolFileDWARF::~SymbolFileDWARF() {} @@ -471,9 +484,9 @@ void SymbolFileDWARF::InitializeObject() { LoadSectionData(eSectionTypeDWARFDebugNames, debug_names); if (debug_names.GetByteSize() > 0) { llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or = - DebugNamesDWARFIndex::Create( - *GetObjectFile()->GetModule(), debug_names, - m_context.getOrLoadStrData(), DebugInfo()); + DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(), + debug_names, + m_context.getOrLoadStrData(), *this); if (index_or) { m_index = std::move(*index_or); return; @@ -483,8 +496,8 @@ void SymbolFileDWARF::InitializeObject() { } } - m_index = std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(), - DebugInfo()); + m_index = + std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(), *this); } bool SymbolFileDWARF::SupportedVersion(uint16_t version) { @@ -573,15 +586,6 @@ uint32_t SymbolFileDWARF::CalculateAbilities() { return abilities; } -const DWARFDataExtractor & -SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type, - DWARFDataSegment &data_segment) { - llvm::call_once(data_segment.m_flag, [this, sect_type, &data_segment] { - this->LoadSectionData(sect_type, std::ref(data_segment.m_data)); - }); - return data_segment.m_data; -} - void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type, DWARFDataExtractor &data) { ModuleSP module_sp(m_objfile_sp->GetModule()); @@ -618,23 +622,14 @@ DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() { return m_abbr.get(); } -const DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() const { - return m_abbr.get(); -} - -DWARFDebugInfo *SymbolFileDWARF::DebugInfo() { - if (m_info == nullptr) { +DWARFDebugInfo &SymbolFileDWARF::DebugInfo() { + llvm::call_once(m_info_once_flag, [&] { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, static_cast<void *>(this)); - if (m_context.getOrLoadDebugInfoData().GetByteSize() > 0) - m_info = std::make_unique<DWARFDebugInfo>(*this, m_context); - } - return m_info.get(); -} - -const DWARFDebugInfo *SymbolFileDWARF::DebugInfo() const { - return m_info.get(); + m_info = std::make_unique<DWARFDebugInfo>(*this, m_context); + }); + return *m_info; } DWARFUnit * @@ -642,15 +637,11 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) { if (!comp_unit) return nullptr; - DWARFDebugInfo *info = DebugInfo(); - if (info) { - // The compile unit ID is the index of the DWARF unit. - DWARFUnit *dwarf_cu = info->GetUnitAtIndex(comp_unit->GetID()); - if (dwarf_cu && dwarf_cu->GetUserData() == nullptr) - dwarf_cu->SetUserData(comp_unit); - return dwarf_cu; - } - return nullptr; + // The compile unit ID is the index of the DWARF unit. + DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(comp_unit->GetID()); + if (dwarf_cu && dwarf_cu->GetUserData() == nullptr) + dwarf_cu->SetUserData(comp_unit); + return dwarf_cu; } DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() { @@ -660,7 +651,7 @@ DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() { static_cast<void *>(this)); if (m_context.getOrLoadRangesData().GetByteSize() > 0) - m_ranges.reset(new DWARFDebugRanges()); + m_ranges = std::make_unique<DWARFDebugRanges>(); if (m_ranges) m_ranges->Extract(m_context); @@ -668,6 +659,22 @@ DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() { return m_ranges.get(); } +/// Make an absolute path out of \p file_spec and remap it using the +/// module's source remapping dictionary. +static void MakeAbsoluteAndRemap(FileSpec &file_spec, DWARFUnit &dwarf_cu, + const ModuleSP &module_sp) { + if (!file_spec) + return; + // If we have a full path to the compile unit, we don't need to + // resolve the file. This can be expensive e.g. when the source + // files are NFS mounted. + file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory()); + + std::string remapped_file; + if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file)) + file_spec.SetFile(remapped_file, FileSpec::Style::native); +} + lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { CompUnitSP cu_sp; CompileUnit *comp_unit = (CompileUnit *)dwarf_cu.GetUserData(); @@ -675,9 +682,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { // We already parsed this compile unit, had out a shared pointer to it cu_sp = comp_unit->shared_from_this(); } else { - if (&dwarf_cu.GetSymbolFileDWARF() != this) { - return dwarf_cu.GetSymbolFileDWARF().ParseCompileUnit(dwarf_cu); - } else if (dwarf_cu.GetOffset() == 0 && GetDebugMapSymfile()) { + if (dwarf_cu.GetOffset() == 0 && GetDebugMapSymfile()) { // Let the debug map create the compile unit cu_sp = m_debug_map_symfile->GetCompileUnit(this); dwarf_cu.SetUserData(cu_sp.get()); @@ -688,19 +693,9 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { dwarf_cu.GetNonSkeletonUnit().GetUnitDIEOnly(); if (cu_die) { FileSpec cu_file_spec(cu_die.GetName(), dwarf_cu.GetPathStyle()); - if (cu_file_spec) { - // If we have a full path to the compile unit, we don't need to - // resolve the file. This can be expensive e.g. when the source - // files are NFS mounted. - cu_file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory()); - - std::string remapped_file; - if (module_sp->RemapSourceFile(cu_file_spec.GetPath(), - remapped_file)) - cu_file_spec.SetFile(remapped_file, FileSpec::Style::native); - } + MakeAbsoluteAndRemap(cu_file_spec, dwarf_cu, module_sp); - LanguageType cu_language = DWARFUnit::LanguageTypeFromDWARF( + LanguageType cu_language = SymbolFileDWARF::LanguageTypeFromDWARF( cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0)); bool is_optimized = dwarf_cu.GetNonSkeletonUnit().GetIsOptimized(); @@ -724,16 +719,13 @@ void SymbolFileDWARF::BuildCuTranslationTable() { if (!m_lldb_cu_to_dwarf_unit.empty()) return; - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return; - - if (!info->ContainsTypeUnits()) { + DWARFDebugInfo &info = DebugInfo(); + if (!info.ContainsTypeUnits()) { // We can use a 1-to-1 mapping. No need to build a translation table. return; } - for (uint32_t i = 0, num = info->GetNumUnits(); i < num; ++i) { - if (auto *cu = llvm::dyn_cast<DWARFCompileUnit>(info->GetUnitAtIndex(i))) { + for (uint32_t i = 0, num = info.GetNumUnits(); i < num; ++i) { + if (auto *cu = llvm::dyn_cast<DWARFCompileUnit>(info.GetUnitAtIndex(i))) { cu->SetID(m_lldb_cu_to_dwarf_unit.size()); m_lldb_cu_to_dwarf_unit.push_back(i); } @@ -750,23 +742,16 @@ llvm::Optional<uint32_t> SymbolFileDWARF::GetDWARFUnitIndex(uint32_t cu_idx) { } uint32_t SymbolFileDWARF::CalculateNumCompileUnits() { - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return 0; BuildCuTranslationTable(); - return m_lldb_cu_to_dwarf_unit.empty() ? info->GetNumUnits() + return m_lldb_cu_to_dwarf_unit.empty() ? DebugInfo().GetNumUnits() : m_lldb_cu_to_dwarf_unit.size(); } CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) { ASSERT_MODULE_LOCK(this); - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return {}; - if (llvm::Optional<uint32_t> dwarf_idx = GetDWARFUnitIndex(cu_idx)) { if (auto *dwarf_cu = llvm::cast_or_null<DWARFCompileUnit>( - info->GetUnitAtIndex(*dwarf_idx))) + DebugInfo().GetUnitAtIndex(*dwarf_idx))) return ParseCompileUnit(*dwarf_cu); } return {}; @@ -778,8 +763,7 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit, if (!die.IsValid()) return nullptr; - auto type_system_or_err = - GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); + auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), std::move(err), "Unable to parse function"); @@ -792,6 +776,13 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit, return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die); } +lldb::addr_t SymbolFileDWARF::FixupAddress(lldb::addr_t file_addr) { + SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); + if (debug_map_symfile) + return debug_map_symfile->LinkOSOFileAddress(this, file_addr); + return file_addr; +} + bool SymbolFileDWARF::FixupAddress(Address &addr) { SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); if (debug_map_symfile) { @@ -804,11 +795,39 @@ lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) - return dwarf_cu->GetLanguageType(); + return GetLanguage(*dwarf_cu); else return eLanguageTypeUnknown; } +XcodeSDK SymbolFileDWARF::ParseXcodeSDK(CompileUnit &comp_unit) { + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); + if (!dwarf_cu) + return {}; + const DWARFBaseDIE cu_die = dwarf_cu->GetNonSkeletonUnit().GetUnitDIEOnly(); + if (!cu_die) + return {}; + const char *sdk = cu_die.GetAttributeValueAsString(DW_AT_APPLE_sdk, nullptr); + if (!sdk) + return {}; + const char *sysroot = + cu_die.GetAttributeValueAsString(DW_AT_LLVM_sysroot, ""); + // Register the sysroot path remapping with the module belonging to + // the CU as well as the one belonging to the symbol file. The two + // would be different if this is an OSO object and module is the + // corresponding debug map, in which case both should be updated. + ModuleSP module_sp = comp_unit.GetModule(); + if (module_sp) + module_sp->RegisterXcodeSDK(sdk, sysroot); + + ModuleSP local_module_sp = m_objfile_sp->GetModule(); + if (local_module_sp && local_module_sp != module_sp) + local_module_sp->RegisterXcodeSDK(sdk, sysroot); + + return {sdk}; +} + size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "SymbolFileDWARF::ParseFunctions"); @@ -863,8 +882,24 @@ bool SymbolFileDWARF::ForEachExternalModule( bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit, FileSpecList &support_files) { - if (!comp_unit.GetLineTable()) - ParseLineTable(comp_unit); + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); + if (!dwarf_cu) + return false; + + dw_offset_t offset = dwarf_cu->GetLineTableOffset(); + if (offset == DW_INVALID_OFFSET) + return false; + + llvm::DWARFDebugLine::Prologue prologue; + if (!ParseLLVMLineTablePrologue(m_context, prologue, offset, + dwarf_cu->GetOffset())) + return false; + + comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue( + comp_unit.GetModule(), prologue, dwarf_cu->GetPathStyle(), + dwarf_cu->GetCompilationDirectory().GetCString())); + return true; } @@ -898,12 +933,15 @@ SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit &tu) { llvm::DWARFDataExtractor data = m_context.getOrLoadLineData().GetAsLLVM(); llvm::DWARFContext &ctx = m_context.GetAsLLVM(); llvm::DWARFDebugLine::Prologue prologue; - llvm::Error error = prologue.parse(data, &line_table_offset, ctx); - if (error) { + auto report = [](llvm::Error error) { Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); LLDB_LOG_ERROR(log, std::move(error), "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse " "the line table prologue"); + }; + llvm::Error error = prologue.parse(data, &line_table_offset, report, ctx); + if (error) { + report(std::move(error)); } else { list = ParseSupportFilesFromPrologue(GetObjectFile()->GetModule(), prologue, tu.GetPathStyle()); @@ -961,9 +999,12 @@ bool SymbolFileDWARF::ParseImportedModules( } std::reverse(module.path.begin(), module.path.end()); if (const char *include_path = module_die.GetAttributeValueAsString( - DW_AT_LLVM_include_path, nullptr)) - module.search_path = ConstString(include_path); - if (const char *sysroot = module_die.GetAttributeValueAsString( + DW_AT_LLVM_include_path, nullptr)) { + FileSpec include_spec(include_path, dwarf_cu->GetPathStyle()); + MakeAbsoluteAndRemap(include_spec, *dwarf_cu, m_objfile_sp->GetModule()); + module.search_path = ConstString(include_spec.GetPath()); + } + if (const char *sysroot = dwarf_cu->DIE().GetAttributeValueAsString( DW_AT_LLVM_sysroot, nullptr)) module.sysroot = ConstString(sysroot); imported_modules.push_back(module); @@ -981,18 +1022,13 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { if (!dwarf_cu) return false; - const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly(); - if (!dwarf_cu_die) - return false; - - const dw_offset_t cu_line_offset = dwarf_cu_die.GetAttributeValueAsUnsigned( - DW_AT_stmt_list, DW_INVALID_OFFSET); - if (cu_line_offset == DW_INVALID_OFFSET) + dw_offset_t offset = dwarf_cu->GetLineTableOffset(); + if (offset == DW_INVALID_OFFSET) return false; llvm::DWARFDebugLine line; - const llvm::DWARFDebugLine::LineTable *line_table = ParseLLVMLineTable( - m_context, line, cu_line_offset, dwarf_cu->GetOffset()); + const llvm::DWARFDebugLine::LineTable *line_table = + ParseLLVMLineTable(m_context, line, offset, dwarf_cu->GetOffset()); if (!line_table) return false; @@ -1000,20 +1036,23 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { // FIXME: Rather than parsing the whole line table and then copying it over // into LLDB, we should explore using a callback to populate the line table // while we parse to reduce memory usage. - std::unique_ptr<LineTable> line_table_up = - std::make_unique<LineTable>(&comp_unit); - LineSequence *sequence = line_table_up->CreateLineSequenceContainer(); + std::unique_ptr<LineSequence> sequence = + LineTable::CreateLineSequenceContainer(); + std::vector<std::unique_ptr<LineSequence>> sequences; for (auto &row : line_table->Rows) { - line_table_up->AppendLineEntryToSequence( - sequence, row.Address.Address, row.Line, row.Column, row.File, + LineTable::AppendLineEntryToSequence( + sequence.get(), row.Address.Address, row.Line, row.Column, row.File, row.IsStmt, row.BasicBlock, row.PrologueEnd, row.EpilogueBegin, row.EndSequence); if (row.EndSequence) { - line_table_up->InsertSequence(sequence); - sequence = line_table_up->CreateLineSequenceContainer(); + sequences.push_back(std::move(sequence)); + sequence = LineTable::CreateLineSequenceContainer(); } } + std::unique_ptr<LineTable> line_table_up = + std::make_unique<LineTable>(&comp_unit, std::move(sequences)); + if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile()) { // We have an object file that has a line table with addresses that are not // linked. We need to link the line table and convert the addresses that @@ -1024,10 +1063,6 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { comp_unit.SetLineTable(line_table_up.release()); } - comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue( - comp_unit.GetModule(), line_table->Prologue, dwarf_cu->GetPathStyle(), - dwarf_cu->GetCompilationDirectory().GetCString())); - return true; } @@ -1157,15 +1192,15 @@ size_t SymbolFileDWARF::ParseBlocksRecursive( (name != nullptr || mangled_name != nullptr)) { std::unique_ptr<Declaration> decl_up; if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_up.reset(new Declaration( + decl_up = std::make_unique<Declaration>( comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file), - decl_line, decl_column)); + decl_line, decl_column); std::unique_ptr<Declaration> call_up; if (call_file != 0 || call_line != 0 || call_column != 0) - call_up.reset(new Declaration( + call_up = std::make_unique<Declaration>( comp_unit.GetSupportFiles().GetFileSpecAtIndex(call_file), - call_line, call_column)); + call_line, call_column); block->SetInlinedFunctionInfo(name, mangled_name, decl_up.get(), call_up.get()); @@ -1289,7 +1324,7 @@ CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) { // SymbolFileDWARF::GetDIE(). See comments inside the // SymbolFileDWARF::GetDIE() for details. if (DWARFDIE die = GetDIE(type_uid)) - return die.GetDecl(); + return GetDecl(die); return CompilerDecl(); } @@ -1302,7 +1337,7 @@ SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) { // SymbolFileDWARF::GetDIE(). See comments inside the // SymbolFileDWARF::GetDIE() for details. if (DWARFDIE die = GetDIE(type_uid)) - return die.GetDeclContext(); + return GetDeclContext(die); return CompilerDeclContext(); } @@ -1313,7 +1348,7 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) { // SymbolFileDWARF::GetDIE(). See comments inside the // SymbolFileDWARF::GetDIE() for details. if (DWARFDIE die = GetDIE(type_uid)) - return die.GetContainingDeclContext(); + return GetContainingDeclContext(die); return CompilerDeclContext(); } @@ -1394,8 +1429,8 @@ bool SymbolFileDWARF::HasForwardDeclForClangType( } TypeSystem *type_system = compiler_type.GetTypeSystem(); - ClangASTContext *clang_type_system = - llvm::dyn_cast_or_null<ClangASTContext>(type_system); + TypeSystemClang *clang_type_system = + llvm::dyn_cast_or_null<TypeSystemClang>(type_system); if (!clang_type_system) return false; DWARFASTParserClang *ast_parser = @@ -1406,8 +1441,8 @@ bool SymbolFileDWARF::HasForwardDeclForClangType( bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); - ClangASTContext *clang_type_system = - llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem()); + TypeSystemClang *clang_type_system = + llvm::dyn_cast_or_null<TypeSystemClang>(compiler_type.GetTypeSystem()); if (clang_type_system) { DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser()); @@ -1444,8 +1479,7 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) { dwarf_die.GetID(), dwarf_die.GetTagAsCString(), type->GetName().AsCString()); assert(compiler_type); - DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser(); - if (dwarf_ast) + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU())) return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type); } return false; @@ -1473,20 +1507,25 @@ Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die, CompileUnit * SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu) { + if (dwarf_cu.IsDWOUnit()) { + DWARFCompileUnit *non_dwo_cu = + static_cast<DWARFCompileUnit *>(dwarf_cu.GetUserData()); + assert(non_dwo_cu); + return non_dwo_cu->GetSymbolFileDWARF().GetCompUnitForDWARFCompUnit( + *non_dwo_cu); + } // Check if the symbol vendor already knows about this compile unit? if (dwarf_cu.GetUserData() == nullptr) { // The symbol vendor doesn't know about this compile unit, we need to parse // and add it to the symbol vendor object. return ParseCompileUnit(dwarf_cu).get(); } - return (CompileUnit *)dwarf_cu.GetUserData(); + return static_cast<CompileUnit *>(dwarf_cu.GetUserData()); } -size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name, - DIEArray &method_die_offsets) { - method_die_offsets.clear(); - m_index->GetObjCMethods(class_name, method_die_offsets); - return method_die_offsets.size(); +void SymbolFileDWARF::GetObjCMethods( + ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) { + m_index->GetObjCMethods(class_name, callback); } bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) { @@ -1522,17 +1561,15 @@ lldb::ModuleSP SymbolFileDWARF::GetExternalModule(ConstString name) { DWARFDIE SymbolFileDWARF::GetDIE(const DIERef &die_ref) { if (die_ref.dwo_num()) { - return DebugInfo() - ->GetUnitAtIndex(*die_ref.dwo_num()) - ->GetDwoSymbolFile() - ->GetDIE(die_ref); + SymbolFileDWARF *dwarf = *die_ref.dwo_num() == 0x3fffffff + ? m_dwp_symfile.get() + : this->DebugInfo() + .GetUnitAtIndex(*die_ref.dwo_num()) + ->GetDwoSymbolFile(); + return dwarf->DebugInfo().GetDIE(die_ref); } - DWARFDebugInfo *debug_info = DebugInfo(); - if (debug_info) - return debug_info->GetDIE(die_ref); - else - return DWARFDIE(); + return DebugInfo().GetDIE(die_ref); } /// Return the DW_AT_(GNU_)dwo_name. @@ -1569,7 +1606,7 @@ llvm::Optional<uint64_t> SymbolFileDWARF::GetDWOId() { return {}; } -std::unique_ptr<SymbolFileDWARFDwo> +std::shared_ptr<SymbolFileDWARFDwo> SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( DWARFUnit &unit, const DWARFDebugInfoEntry &cu_die) { // If this is a Darwin-style debug map (non-.dSYM) symbol file, @@ -1589,14 +1626,8 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( if (!dwo_name) return nullptr; - SymbolFileDWARFDwp *dwp_symfile = GetDwpSymbolFile(); - if (dwp_symfile) { - uint64_t dwo_id = ::GetDWOId(*dwarf_cu, cu_die); - std::unique_ptr<SymbolFileDWARFDwo> dwo_symfile = - dwp_symfile->GetSymbolFileForDwoId(*dwarf_cu, dwo_id); - if (dwo_symfile) - return dwo_symfile; - } + if (std::shared_ptr<SymbolFileDWARFDwo> dwp_sp = GetDwpSymbolFile()) + return dwp_sp; FileSpec dwo_file(dwo_name); FileSystem::Instance().Resolve(dwo_file); @@ -1624,20 +1655,21 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( if (dwo_obj_file == nullptr) return nullptr; - return std::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, *dwarf_cu); + return std::make_shared<SymbolFileDWARFDwo>(*this, dwo_obj_file, + dwarf_cu->GetID()); } void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { if (m_fetched_external_modules) return; m_fetched_external_modules = true; - DWARFDebugInfo *debug_info = DebugInfo(); + DWARFDebugInfo &debug_info = DebugInfo(); // Follow DWO skeleton unit breadcrumbs. const uint32_t num_compile_units = GetNumCompileUnits(); for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { auto *dwarf_cu = - llvm::dyn_cast<DWARFCompileUnit>(debug_info->GetUnitAtIndex(cu_idx)); + llvm::dyn_cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(cu_idx)); if (!dwarf_cu) continue; @@ -1731,7 +1763,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() { if (!m_global_aranges_up) { - m_global_aranges_up.reset(new GlobalVariableMap()); + m_global_aranges_up = std::make_unique<GlobalVariableMap>(); ModuleSP module_sp = GetObjectFile()->GetModule(); if (module_sp) { @@ -1773,6 +1805,32 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() { return *m_global_aranges_up; } +void SymbolFileDWARF::ResolveFunctionAndBlock(lldb::addr_t file_vm_addr, + bool lookup_block, + SymbolContext &sc) { + assert(sc.comp_unit); + DWARFUnit &cu = GetDWARFCompileUnit(sc.comp_unit)->GetNonSkeletonUnit(); + DWARFDIE function_die = cu.LookupAddress(file_vm_addr); + DWARFDIE block_die; + if (function_die) { + sc.function = sc.comp_unit->FindFunctionByUID(function_die.GetID()).get(); + if (sc.function == nullptr) + sc.function = ParseFunction(*sc.comp_unit, function_die); + + if (sc.function && lookup_block) + block_die = function_die.LookupDeepestBlock(file_vm_addr); + } + + if (!sc.function || ! lookup_block) + return; + + Block &block = sc.function->GetBlock(true); + if (block_die) + sc.block = block.FindBlockByID(block_die.GetID()); + else + sc.block = block.FindBlockByID(function_die.GetID()); +} + uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, SymbolContextItem resolve_scope, SymbolContext &sc) { @@ -1791,123 +1849,99 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, eSymbolContextLineEntry | eSymbolContextVariable)) { lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); - DWARFDebugInfo *debug_info = DebugInfo(); - if (debug_info) { - llvm::Expected<DWARFDebugAranges &> aranges = - debug_info->GetCompileUnitAranges(); - if (!aranges) { - Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); - LLDB_LOG_ERROR(log, aranges.takeError(), - "SymbolFileDWARF::ResolveSymbolContext failed to get cu " - "aranges. {0}"); - return 0; - } + DWARFDebugInfo &debug_info = DebugInfo(); + llvm::Expected<DWARFDebugAranges &> aranges = + debug_info.GetCompileUnitAranges(); + if (!aranges) { + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); + LLDB_LOG_ERROR(log, aranges.takeError(), + "SymbolFileDWARF::ResolveSymbolContext failed to get cu " + "aranges. {0}"); + return 0; + } - const dw_offset_t cu_offset = aranges->FindAddress(file_vm_addr); - if (cu_offset == DW_INVALID_OFFSET) { - // Global variables are not in the compile unit address ranges. The - // only way to currently find global variables is to iterate over the - // .debug_pubnames or the __apple_names table and find all items in - // there that point to DW_TAG_variable DIEs and then find the address - // that matches. - if (resolve_scope & eSymbolContextVariable) { - GlobalVariableMap &map = GetGlobalAranges(); - const GlobalVariableMap::Entry *entry = - map.FindEntryThatContains(file_vm_addr); - if (entry && entry->data) { - Variable *variable = entry->data; - SymbolContextScope *scc = variable->GetSymbolContextScope(); - if (scc) { - scc->CalculateSymbolContext(&sc); - sc.variable = variable; - } - return sc.GetResolvedMask(); + const dw_offset_t cu_offset = aranges->FindAddress(file_vm_addr); + if (cu_offset == DW_INVALID_OFFSET) { + // Global variables are not in the compile unit address ranges. The only + // way to currently find global variables is to iterate over the + // .debug_pubnames or the __apple_names table and find all items in there + // that point to DW_TAG_variable DIEs and then find the address that + // matches. + if (resolve_scope & eSymbolContextVariable) { + GlobalVariableMap &map = GetGlobalAranges(); + const GlobalVariableMap::Entry *entry = + map.FindEntryThatContains(file_vm_addr); + if (entry && entry->data) { + Variable *variable = entry->data; + SymbolContextScope *scc = variable->GetSymbolContextScope(); + if (scc) { + scc->CalculateSymbolContext(&sc); + sc.variable = variable; } + return sc.GetResolvedMask(); } - } else { - uint32_t cu_idx = DW_INVALID_INDEX; - if (auto *dwarf_cu = llvm::dyn_cast_or_null<DWARFCompileUnit>( - debug_info->GetUnitAtOffset(DIERef::Section::DebugInfo, - cu_offset, &cu_idx))) { - sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); - if (sc.comp_unit) { - resolved |= eSymbolContextCompUnit; - - bool force_check_line_table = false; - if (resolve_scope & - (eSymbolContextFunction | eSymbolContextBlock)) { - DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr); - DWARFDIE block_die; - if (function_die) { - sc.function = - sc.comp_unit->FindFunctionByUID(function_die.GetID()).get(); - if (sc.function == nullptr) - sc.function = ParseFunction(*sc.comp_unit, function_die); - - if (sc.function && (resolve_scope & eSymbolContextBlock)) - block_die = function_die.LookupDeepestBlock(file_vm_addr); - } else { - // We might have had a compile unit that had discontiguous - // address ranges where the gaps are symbols that don't have - // any debug info. Discontiguous compile unit address ranges - // should only happen when there aren't other functions from - // other compile units in these gaps. This helps keep the size - // of the aranges down. - force_check_line_table = true; - } - - if (sc.function != nullptr) { - resolved |= eSymbolContextFunction; - - if (resolve_scope & eSymbolContextBlock) { - Block &block = sc.function->GetBlock(true); - - if (block_die) - sc.block = block.FindBlockByID(block_die.GetID()); - else - sc.block = block.FindBlockByID(function_die.GetID()); - if (sc.block) - resolved |= eSymbolContextBlock; - } - } + } + } else { + uint32_t cu_idx = DW_INVALID_INDEX; + if (auto *dwarf_cu = llvm::dyn_cast_or_null<DWARFCompileUnit>( + debug_info.GetUnitAtOffset(DIERef::Section::DebugInfo, cu_offset, + &cu_idx))) { + sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); + if (sc.comp_unit) { + resolved |= eSymbolContextCompUnit; + + bool force_check_line_table = false; + if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) { + ResolveFunctionAndBlock(file_vm_addr, + resolve_scope & eSymbolContextBlock, sc); + if (sc.function) + resolved |= eSymbolContextFunction; + else { + // We might have had a compile unit that had discontiguous address + // ranges where the gaps are symbols that don't have any debug + // info. Discontiguous compile unit address ranges should only + // happen when there aren't other functions from other compile + // units in these gaps. This helps keep the size of the aranges + // down. + force_check_line_table = true; } + if (sc.block) + resolved |= eSymbolContextBlock; + } - if ((resolve_scope & eSymbolContextLineEntry) || - force_check_line_table) { - LineTable *line_table = sc.comp_unit->GetLineTable(); - if (line_table != nullptr) { - // And address that makes it into this function should be in - // terms of this debug file if there is no debug map, or it - // will be an address in the .o file which needs to be fixed up - // to be in terms of the debug map executable. Either way, - // calling FixupAddress() will work for us. - Address exe_so_addr(so_addr); - if (FixupAddress(exe_so_addr)) { - if (line_table->FindLineEntryByAddress(exe_so_addr, - sc.line_entry)) { - resolved |= eSymbolContextLineEntry; - } + if ((resolve_scope & eSymbolContextLineEntry) || + force_check_line_table) { + LineTable *line_table = sc.comp_unit->GetLineTable(); + if (line_table != nullptr) { + // And address that makes it into this function should be in terms + // of this debug file if there is no debug map, or it will be an + // address in the .o file which needs to be fixed up to be in + // terms of the debug map executable. Either way, calling + // FixupAddress() will work for us. + Address exe_so_addr(so_addr); + if (FixupAddress(exe_so_addr)) { + if (line_table->FindLineEntryByAddress(exe_so_addr, + sc.line_entry)) { + resolved |= eSymbolContextLineEntry; } } } + } - if (force_check_line_table && - !(resolved & eSymbolContextLineEntry)) { - // We might have had a compile unit that had discontiguous - // address ranges where the gaps are symbols that don't have any - // debug info. Discontiguous compile unit address ranges should - // only happen when there aren't other functions from other - // compile units in these gaps. This helps keep the size of the - // aranges down. - sc.comp_unit = nullptr; - resolved &= ~eSymbolContextCompUnit; - } - } else { - GetObjectFile()->GetModule()->ReportWarning( - "0x%8.8x: compile unit %u failed to create a valid " - "lldb_private::CompileUnit class.", - cu_offset, cu_idx); + if (force_check_line_table && !(resolved & eSymbolContextLineEntry)) { + // We might have had a compile unit that had discontiguous address + // ranges where the gaps are symbols that don't have any debug info. + // Discontiguous compile unit address ranges should only happen when + // there aren't other functions from other compile units in these + // gaps. This helps keep the size of the aranges down. + sc.comp_unit = nullptr; + resolved &= ~eSymbolContextCompUnit; } + } else { + GetObjectFile()->GetModule()->ReportWarning( + "0x%8.8x: compile unit %u failed to create a valid " + "lldb_private::CompileUnit class.", + cu_offset, cu_idx); } } } @@ -1969,30 +2003,8 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec, const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress(); if (file_vm_addr != LLDB_INVALID_ADDRESS) { - DWARFDIE function_die = - GetDWARFCompileUnit(dc_cu)->LookupAddress(file_vm_addr); - DWARFDIE block_die; - if (function_die) { - sc.function = - sc.comp_unit->FindFunctionByUID(function_die.GetID()) - .get(); - if (sc.function == nullptr) - sc.function = - ParseFunction(*sc.comp_unit, function_die); - - if (sc.function && (resolve_scope & eSymbolContextBlock)) - block_die = - function_die.LookupDeepestBlock(file_vm_addr); - } - - if (sc.function != nullptr) { - Block &block = sc.function->GetBlock(true); - - if (block_die) - sc.block = block.FindBlockByID(block_die.GetID()); - else if (function_die) - sc.block = block.FindBlockByID(function_die.GetID()); - } + ResolveFunctionAndBlock( + file_vm_addr, resolve_scope & eSymbolContextBlock, sc); } } @@ -2035,15 +2047,15 @@ std::recursive_mutex &SymbolFileDWARF::GetModuleMutex() const { } bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile( - const lldb_private::CompilerDeclContext *decl_ctx) { - if (decl_ctx == nullptr || !decl_ctx->IsValid()) { + const lldb_private::CompilerDeclContext &decl_ctx) { + if (!decl_ctx.IsValid()) { // Invalid namespace decl which means we aren't matching only things in // this symbol file, so return true to indicate it matches this symbol // file. return true; } - TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem(); + TypeSystem *decl_ctx_type_system = decl_ctx.GetTypeSystem(); auto type_system_or_err = GetTypeSystemForLanguage( decl_ctx_type_system->GetMinimumLanguage(nullptr)); if (auto err = type_system_or_err.takeError()) { @@ -2067,7 +2079,7 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile( } void SymbolFileDWARF::FindGlobalVariables( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); @@ -2077,16 +2089,12 @@ void SymbolFileDWARF::FindGlobalVariables( log, "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", " "parent_decl_ctx=%p, max_matches=%u, variables)", - name.GetCString(), static_cast<const void *>(parent_decl_ctx), + name.GetCString(), static_cast<const void *>(&parent_decl_ctx), max_matches); if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return; - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return; - // Remember how many variables are in the list before we search. const uint32_t original_size = variables.GetSize(); @@ -2098,69 +2106,46 @@ void SymbolFileDWARF::FindGlobalVariables( context, basename)) basename = name.GetStringRef(); - DIEArray die_offsets; - m_index->GetGlobalVariables(ConstString(basename), die_offsets); - const size_t num_die_matches = die_offsets.size(); - if (num_die_matches) { - SymbolContext sc; - sc.module_sp = m_objfile_sp->GetModule(); - assert(sc.module_sp); - - // Loop invariant: Variables up to this index have been checked for context - // matches. - uint32_t pruned_idx = original_size; + // Loop invariant: Variables up to this index have been checked for context + // matches. + uint32_t pruned_idx = original_size; - bool done = false; - for (size_t i = 0; i < num_die_matches && !done; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE die = GetDIE(die_ref); - - if (die) { - switch (die.Tag()) { - default: - case DW_TAG_subprogram: - case DW_TAG_inlined_subroutine: - case DW_TAG_try_block: - case DW_TAG_catch_block: - break; + SymbolContext sc; + m_index->GetGlobalVariables(ConstString(basename), [&](DWARFDIE die) { + if (!sc.module_sp) + sc.module_sp = m_objfile_sp->GetModule(); + assert(sc.module_sp); - case DW_TAG_variable: { - auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU()); - if (!dwarf_cu) - continue; - sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); - - if (parent_decl_ctx) { - DWARFASTParser *dwarf_ast = die.GetDWARFParser(); - if (dwarf_ast) { - CompilerDeclContext actual_parent_decl_ctx = - dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); - if (!actual_parent_decl_ctx || - actual_parent_decl_ctx != *parent_decl_ctx) - continue; - } - } + if (die.Tag() != DW_TAG_variable) + return true; - ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, - &variables); - while (pruned_idx < variables.GetSize()) { - VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx); - if (name_is_mangled || - var_sp->GetName().GetStringRef().contains(name.GetStringRef())) - ++pruned_idx; - else - variables.RemoveVariableAtIndex(pruned_idx); - } + auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU()); + if (!dwarf_cu) + return true; + sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); - if (variables.GetSize() - original_size >= max_matches) - done = true; - } break; - } - } else { - m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); + if (parent_decl_ctx) { + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) { + CompilerDeclContext actual_parent_decl_ctx = + dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); + if (!actual_parent_decl_ctx || + actual_parent_decl_ctx != parent_decl_ctx) + return true; } } - } + + ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); + while (pruned_idx < variables.GetSize()) { + VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx); + if (name_is_mangled || + var_sp->GetName().GetStringRef().contains(name.GetStringRef())) + ++pruned_idx; + else + variables.RemoveVariableAtIndex(pruned_idx); + } + + return variables.GetSize() - original_size < max_matches; + }); // Return the number of variable that were appended to the list const uint32_t num_matches = variables.GetSize() - original_size; @@ -2169,7 +2154,7 @@ void SymbolFileDWARF::FindGlobalVariables( log, "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", " "parent_decl_ctx=%p, max_matches=%u, variables) => %u", - name.GetCString(), static_cast<const void *>(parent_decl_ctx), + name.GetCString(), static_cast<const void *>(&parent_decl_ctx), max_matches, num_matches); } } @@ -2188,41 +2173,24 @@ void SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex, regex.GetText().str().c_str(), max_matches); } - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return; - // Remember how many variables are in the list before we search. const uint32_t original_size = variables.GetSize(); - DIEArray die_offsets; - m_index->GetGlobalVariables(regex, die_offsets); - SymbolContext sc; - sc.module_sp = m_objfile_sp->GetModule(); - assert(sc.module_sp); - - const size_t num_matches = die_offsets.size(); - if (num_matches) { - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE die = GetDIE(die_ref); + m_index->GetGlobalVariables(regex, [&](DWARFDIE die) { + if (!sc.module_sp) + sc.module_sp = m_objfile_sp->GetModule(); + assert(sc.module_sp); - if (die) { - DWARFCompileUnit *dwarf_cu = - llvm::dyn_cast<DWARFCompileUnit>(die.GetCU()); - if (!dwarf_cu) - continue; - sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); + DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU()); + if (!dwarf_cu) + return true; + sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); - ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); + ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); - if (variables.GetSize() - original_size >= max_matches) - break; - } else - m_index->ReportInvalidDIERef(die_ref, regex.GetText()); - } - } + return variables.GetSize() - original_size < max_matches; + }); } bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, @@ -2281,28 +2249,26 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, return false; } -bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx, +bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext &decl_ctx, const DWARFDIE &die) { // If we have no parent decl context to match this DIE matches, and if the // parent decl context isn't valid, we aren't trying to look for any // particular decl context so any die matches. - if (decl_ctx == nullptr || !decl_ctx->IsValid()) + if (!decl_ctx.IsValid()) return true; if (die) { - DWARFASTParser *dwarf_ast = die.GetDWARFParser(); - if (dwarf_ast) { - CompilerDeclContext actual_decl_ctx = - dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); - if (actual_decl_ctx) - return decl_ctx->IsContainedInLookup(actual_decl_ctx); + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) { + if (CompilerDeclContext actual_decl_ctx = + dwarf_ast->GetDeclContextContainingUIDFromDWARF(die)) + return decl_ctx.IsContainedInLookup(actual_decl_ctx); } } return false; } void SymbolFileDWARF::FindFunctions(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) { @@ -2337,17 +2303,13 @@ void SymbolFileDWARF::FindFunctions(ConstString name, const uint32_t original_size = sc_list.GetSize(); llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies; - DIEArray offsets; - CompilerDeclContext empty_decl_ctx; - if (!parent_decl_ctx) - parent_decl_ctx = &empty_decl_ctx; - - std::vector<DWARFDIE> dies; - m_index->GetFunctions(name, *this, *parent_decl_ctx, name_type_mask, dies); - for (const DWARFDIE &die : dies) { - if (resolved_dies.insert(die.GetDIE()).second) - ResolveFunction(die, include_inlines, sc_list); - } + + m_index->GetFunctions(name, *this, parent_decl_ctx, name_type_mask, + [&](DWARFDIE die) { + if (resolved_dies.insert(die.GetDIE()).second) + ResolveFunction(die, include_inlines, sc_list); + return true; + }); // Return the number of variable that were appended to the list const uint32_t num_matches = sc_list.GetSize() - original_size; @@ -2378,35 +2340,21 @@ void SymbolFileDWARF::FindFunctions(const RegularExpression ®ex, regex.GetText().str().c_str()); } - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return; - - DIEArray offsets; - m_index->GetFunctions(regex, offsets); - llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies; - for (DIERef ref : offsets) { - DWARFDIE die = info->GetDIE(ref); - if (!die) { - m_index->ReportInvalidDIERef(ref, regex.GetText()); - continue; - } + m_index->GetFunctions(regex, [&](DWARFDIE die) { if (resolved_dies.insert(die.GetDIE()).second) ResolveFunction(die, include_inlines, sc_list); - } + return true; + }); } void SymbolFileDWARF::GetMangledNamesForFunction( const std::string &scope_qualified_name, std::vector<ConstString> &mangled_names) { - DWARFDebugInfo *info = DebugInfo(); - uint32_t num_comp_units = 0; - if (info) - num_comp_units = info->GetNumUnits(); - + DWARFDebugInfo &info = DebugInfo(); + uint32_t num_comp_units = info.GetNumUnits(); for (uint32_t i = 0; i < num_comp_units; i++) { - DWARFUnit *cu = info->GetUnitAtIndex(i); + DWARFUnit *cu = info.GetUnitAtIndex(i); if (cu == nullptr) continue; @@ -2415,15 +2363,15 @@ void SymbolFileDWARF::GetMangledNamesForFunction( dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names); } - for (lldb::user_id_t uid : + for (DIERef die_ref : m_function_scope_qualified_name_map.lookup(scope_qualified_name)) { - DWARFDIE die = GetDIE(uid); + DWARFDIE die = GetDIE(die_ref); mangled_names.push_back(ConstString(die.GetMangledName())); } } void SymbolFileDWARF::FindTypes( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types) { @@ -2432,10 +2380,6 @@ void SymbolFileDWARF::FindTypes( if (!searched_symbol_files.insert(this).second) return; - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return; - Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); if (log) { @@ -2444,8 +2388,8 @@ void SymbolFileDWARF::FindTypes( log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = " "%p (\"%s\"), max_matches=%u, type_list)", - name.GetCString(), static_cast<const void *>(parent_decl_ctx), - parent_decl_ctx->GetName().AsCString("<NULL>"), max_matches); + name.GetCString(), static_cast<const void *>(&parent_decl_ctx), + parent_decl_ctx.GetName().AsCString("<NULL>"), max_matches); else GetObjectFile()->GetModule()->LogMessage( log, @@ -2457,38 +2401,28 @@ void SymbolFileDWARF::FindTypes( if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return; - DIEArray die_offsets; - m_index->GetTypes(name, die_offsets); - const size_t num_die_matches = die_offsets.size(); + m_index->GetTypes(name, [&](DWARFDIE die) { + if (!DIEInDeclContext(parent_decl_ctx, die)) + return true; // The containing decl contexts don't match - for (size_t i = 0; i < num_die_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE die = GetDIE(die_ref); - if (die) { - if (!DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match - - Type *matching_type = ResolveType(die, true, true); - if (matching_type) { - // We found a type pointer, now find the shared pointer form our type - // list - types.InsertUnique(matching_type->shared_from_this()); - if (types.GetSize() >= max_matches) - break; - } - } else { - m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); - } - } + Type *matching_type = ResolveType(die, true, true); + if (!matching_type) + return true; + + // We found a type pointer, now find the shared pointer form our type + // list + types.InsertUnique(matching_type->shared_from_this()); + return types.GetSize() < max_matches; + }); // Next search through the reachable Clang modules. This only applies for // DWARF objects compiled with -gmodules that haven't been processed by // dsymutil. - if (num_die_matches < max_matches) { + if (types.GetSize() < max_matches) { UpdateExternalModuleListIfNeeded(); for (const auto &pair : m_external_type_modules) - if (ModuleSP external_module_sp = pair.second) + if (ModuleSP external_module_sp = pair.second) if (SymbolFile *sym_file = external_module_sp->GetSymbolFile()) sym_file->FindTypes(name, parent_decl_ctx, max_matches, searched_symbol_files, types); @@ -2500,8 +2434,8 @@ void SymbolFileDWARF::FindTypes( log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx " "= %p (\"%s\"), max_matches=%u, type_list) => %u", - name.GetCString(), static_cast<const void *>(parent_decl_ctx), - parent_decl_ctx->GetName().AsCString("<NULL>"), max_matches, + name.GetCString(), static_cast<const void *>(&parent_decl_ctx), + parent_decl_ctx.GetName().AsCString("<NULL>"), max_matches, types.GetSize()); } else { GetObjectFile()->GetModule()->LogMessage( @@ -2529,32 +2463,22 @@ void SymbolFileDWARF::FindTypes( if (!name) return; - DIEArray die_offsets; - m_index->GetTypes(name, die_offsets); - const size_t num_die_matches = die_offsets.size(); - - for (size_t i = 0; i < num_die_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE die = GetDIE(die_ref); - - if (!die) { - m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); - continue; - } - if (!languages[die.GetCU()->GetLanguageType()]) - continue; + m_index->GetTypes(name, [&](DWARFDIE die) { + if (!languages[GetLanguage(*die.GetCU())]) + return true; llvm::SmallVector<CompilerContext, 4> die_context; die.GetDeclContext(die_context); if (!contextMatches(die_context, pattern)) - continue; + return true; if (Type *matching_type = ResolveType(die, true, true)) { // We found a type pointer, now find the shared pointer form our type // list. types.InsertUnique(matching_type->shared_from_this()); } - } + return true; + }); // Next search through the reachable Clang modules. This only applies for // DWARF objects compiled with -gmodules that haven't been processed by @@ -2569,7 +2493,7 @@ void SymbolFileDWARF::FindTypes( CompilerDeclContext SymbolFileDWARF::FindNamespace(ConstString name, - const CompilerDeclContext *parent_decl_ctx) { + const CompilerDeclContext &parent_decl_ctx) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); @@ -2584,32 +2508,18 @@ SymbolFileDWARF::FindNamespace(ConstString name, if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return namespace_decl_ctx; - DWARFDebugInfo *info = DebugInfo(); - if (info) { - DIEArray die_offsets; - m_index->GetNamespaces(name, die_offsets); - const size_t num_matches = die_offsets.size(); - if (num_matches) { - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE die = GetDIE(die_ref); - - if (die) { - if (!DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match - - DWARFASTParser *dwarf_ast = die.GetDWARFParser(); - if (dwarf_ast) { - namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die); - if (namespace_decl_ctx) - break; - } - } else { - m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); - } - } - } - } + m_index->GetNamespaces(name, [&](DWARFDIE die) { + if (!DIEInDeclContext(parent_decl_ctx, die)) + return true; // The containing decl contexts don't match + + DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()); + if (!dwarf_ast) + return true; + + namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die); + return !namespace_decl_ctx.IsValid(); + }); + if (log && namespace_decl_ctx) { GetObjectFile()->GetModule()->LogMessage( log, @@ -2735,10 +2645,10 @@ bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu) { if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type()) m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; else { - DWARFDebugInfo *debug_info = DebugInfo(); + DWARFDebugInfo &debug_info = DebugInfo(); const uint32_t num_compile_units = GetNumCompileUnits(); for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { - DWARFUnit *dwarf_cu = debug_info->GetUnitAtIndex(cu_idx); + DWARFUnit *dwarf_cu = debug_info.GetUnitAtIndex(cu_idx); if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type()) { m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; @@ -2763,17 +2673,8 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE( if (!type_name || (must_be_implementation && !GetObjCClassSymbol(type_name))) return type_sp; - DIEArray die_offsets; - m_index->GetCompleteObjCClass(type_name, must_be_implementation, die_offsets); - - const size_t num_matches = die_offsets.size(); - - if (num_matches) { - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE type_die = GetDIE(die_ref); - - if (type_die) { + m_index->GetCompleteObjCClass( + type_name, must_be_implementation, [&](DWARFDIE type_die) { bool try_resolving_type = false; // Don't try and resolve the DIE we are looking for with the DIE @@ -2788,35 +2689,32 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE( break; } } + if (!try_resolving_type) + return true; - if (try_resolving_type) { - if (must_be_implementation && - type_die.Supports_DW_AT_APPLE_objc_complete_type()) - try_resolving_type = type_die.GetAttributeValueAsUnsigned( - DW_AT_APPLE_objc_complete_type, 0); - - if (try_resolving_type) { - Type *resolved_type = ResolveType(type_die, false, true); - if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) { - DEBUG_PRINTF("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 - " (cu 0x%8.8" PRIx64 ")\n", - die.GetID(), - m_objfile_sp->GetFileSpec().GetFilename().AsCString( - "<Unknown>"), - type_die.GetID(), type_cu->GetID()); - - if (die) - GetDIEToType()[die.GetDIE()] = resolved_type; - type_sp = resolved_type->shared_from_this(); - break; - } - } - } - } else { - m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef()); - } - } - } + if (must_be_implementation && + type_die.Supports_DW_AT_APPLE_objc_complete_type()) + try_resolving_type = type_die.GetAttributeValueAsUnsigned( + DW_AT_APPLE_objc_complete_type, 0); + if (!try_resolving_type) + return true; + + Type *resolved_type = ResolveType(type_die, false, true); + if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED) + return true; + + DEBUG_PRINTF( + "resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 + " (cu 0x%8.8" PRIx64 ")\n", + die.GetID(), + m_objfile_sp->GetFileSpec().GetFilename().AsCString("<Unknown>"), + type_die.GetID(), type_cu->GetID()); + + if (die) + GetDIEToType()[die.GetDIE()] = resolved_type; + type_sp = resolved_type->shared_from_this(); + return false; + }); return type_sp; } @@ -2930,10 +2828,6 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext( dwarf_decl_ctx.GetQualifiedName()); } - DIEArray die_offsets; - m_index->GetTypes(dwarf_decl_ctx, die_offsets); - const size_t num_matches = die_offsets.size(); - // Get the type system that we are looking to find a type for. We will // use this to ensure any matches we find are in a language that this // type system supports @@ -2950,91 +2844,85 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext( type_system = &type_system_or_err.get(); } } - if (num_matches) { - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE type_die = GetDIE(die_ref); - - if (type_die) { - // Make sure type_die's langauge matches the type system we are - // looking for. We don't want to find a "Foo" type from Java if we - // are looking for a "Foo" type for C, C++, ObjC, or ObjC++. - if (type_system && - !type_system->SupportsLanguage(type_die.GetLanguage())) - continue; - bool try_resolving_type = false; - - // Don't try and resolve the DIE we are looking for with the DIE - // itself! - const dw_tag_t type_tag = type_die.Tag(); - // Make sure the tags match - if (type_tag == tag) { - // The tags match, lets try resolving this type - try_resolving_type = true; - } else { - // The tags don't match, but we need to watch our for a forward - // declaration for a struct and ("struct foo") ends up being a - // class ("class foo { ... };") or vice versa. - switch (type_tag) { - case DW_TAG_class_type: - // We had a "class foo", see if we ended up with a "struct foo - // { ... };" - try_resolving_type = (tag == DW_TAG_structure_type); - break; - case DW_TAG_structure_type: - // We had a "struct foo", see if we ended up with a "class foo - // { ... };" - try_resolving_type = (tag == DW_TAG_class_type); - break; - default: - // Tags don't match, don't event try to resolve using this type - // whose name matches.... - break; - } - } - if (try_resolving_type) { - DWARFDeclContext type_dwarf_decl_ctx; - type_die.GetDWARFDeclContext(type_dwarf_decl_ctx); - - if (log) { - GetObjectFile()->GetModule()->LogMessage( - log, - "SymbolFileDWARF::" - "FindDefinitionTypeForDWARFDeclContext(tag=%s, " - "qualified-name='%s') trying die=0x%8.8x (%s)", - DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), - dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(), - type_dwarf_decl_ctx.GetQualifiedName()); - } + m_index->GetTypes(dwarf_decl_ctx, [&](DWARFDIE type_die) { + // Make sure type_die's langauge matches the type system we are + // looking for. We don't want to find a "Foo" type from Java if we + // are looking for a "Foo" type for C, C++, ObjC, or ObjC++. + if (type_system && + !type_system->SupportsLanguage(GetLanguage(*type_die.GetCU()))) + return true; + bool try_resolving_type = false; - // Make sure the decl contexts match all the way up - if (dwarf_decl_ctx == type_dwarf_decl_ctx) { - Type *resolved_type = ResolveType(type_die, false); - if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) { - type_sp = resolved_type->shared_from_this(); - break; - } - } - } else { - if (log) { - std::string qualified_name; - type_die.GetQualifiedName(qualified_name); - GetObjectFile()->GetModule()->LogMessage( - log, - "SymbolFileDWARF::" - "FindDefinitionTypeForDWARFDeclContext(tag=%s, " - "qualified-name='%s') ignoring die=0x%8.8x (%s)", - DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), - dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(), - qualified_name.c_str()); - } - } - } else { - m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef()); + // Don't try and resolve the DIE we are looking for with the DIE + // itself! + const dw_tag_t type_tag = type_die.Tag(); + // Make sure the tags match + if (type_tag == tag) { + // The tags match, lets try resolving this type + try_resolving_type = true; + } else { + // The tags don't match, but we need to watch our for a forward + // declaration for a struct and ("struct foo") ends up being a + // class ("class foo { ... };") or vice versa. + switch (type_tag) { + case DW_TAG_class_type: + // We had a "class foo", see if we ended up with a "struct foo + // { ... };" + try_resolving_type = (tag == DW_TAG_structure_type); + break; + case DW_TAG_structure_type: + // We had a "struct foo", see if we ended up with a "class foo + // { ... };" + try_resolving_type = (tag == DW_TAG_class_type); + break; + default: + // Tags don't match, don't event try to resolve using this type + // whose name matches.... + break; } } - } + + if (!try_resolving_type) { + if (log) { + std::string qualified_name; + type_die.GetQualifiedName(qualified_name); + GetObjectFile()->GetModule()->LogMessage( + log, + "SymbolFileDWARF::" + "FindDefinitionTypeForDWARFDeclContext(tag=%s, " + "qualified-name='%s') ignoring die=0x%8.8x (%s)", + DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), + dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(), + qualified_name.c_str()); + } + return true; + } + + DWARFDeclContext type_dwarf_decl_ctx = GetDWARFDeclContext(type_die); + + if (log) { + GetObjectFile()->GetModule()->LogMessage( + log, + "SymbolFileDWARF::" + "FindDefinitionTypeForDWARFDeclContext(tag=%s, " + "qualified-name='%s') trying die=0x%8.8x (%s)", + DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), + dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(), + type_dwarf_decl_ctx.GetQualifiedName()); + } + + // Make sure the decl contexts match all the way up + if (dwarf_decl_ctx != type_dwarf_decl_ctx) + return true; + + Type *resolved_type = ResolveType(type_die, false); + if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED) + return true; + + type_sp = resolved_type->shared_from_this(); + return false; + }); } } return type_sp; @@ -3045,8 +2933,7 @@ TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die, if (!die) return {}; - auto type_system_or_err = - GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); + auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), std::move(err), "Unable to parse type"); @@ -3067,7 +2954,7 @@ TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die, .AsCString("")); if (scope_qualified_name.size()) { m_function_scope_qualified_name_map[scope_qualified_name].insert( - die.GetID()); + *die.GetDIERef()); } } } @@ -3124,7 +3011,8 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) { size_t functions_added = 0; const dw_offset_t function_die_offset = func.GetID(); - DWARFDIE function_die = dwarf_cu->GetDIE(function_die_offset); + DWARFDIE function_die = + dwarf_cu->GetNonSkeletonUnit().GetDIE(function_die_offset); if (function_die) { ParseBlocksRecursive(*comp_unit, &func.GetBlock(false), function_die, LLDB_INVALID_ADDRESS, 0); @@ -3152,10 +3040,6 @@ size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) { size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); if (sc.comp_unit != nullptr) { - DWARFDebugInfo *info = DebugInfo(); - if (info == nullptr) - return 0; - if (sc.function) { DWARFDIE function_die = GetDIE(sc.function->GetID()); @@ -3170,7 +3054,7 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { return num_variables; } } else if (sc.comp_unit) { - DWARFUnit *dwarf_cu = info->GetUnitAtIndex(sc.comp_unit->GetID()); + DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(sc.comp_unit->GetID()); if (dwarf_cu == nullptr) return 0; @@ -3182,25 +3066,16 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { variables = std::make_shared<VariableList>(); sc.comp_unit->SetVariableList(variables); - DIEArray die_offsets; - m_index->GetGlobalVariables(dwarf_cu->GetNonSkeletonUnit(), - die_offsets); - const size_t num_matches = die_offsets.size(); - if (num_matches) { - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE die = GetDIE(die_ref); - if (die) { + m_index->GetGlobalVariables( + dwarf_cu->GetNonSkeletonUnit(), [&](DWARFDIE die) { VariableSP var_sp( ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS)); if (var_sp) { variables->AddVariableIfUnique(var_sp); ++vars_added; } - } else - m_index->ReportInvalidDIERef(die_ref, ""); - } - } + return true; + }); } return vars_added; } @@ -3412,12 +3287,10 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, // declaration context. if ((parent_tag == DW_TAG_compile_unit || parent_tag == DW_TAG_partial_unit) && - Language::LanguageIsCPlusPlus(die.GetLanguage())) { - DWARFDeclContext decl_ctx; - - die.GetDWARFDeclContext(decl_ctx); - mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString(); - } + Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU()))) + mangled = GetDWARFDeclContext(die) + .GetQualifiedNameAsConstString() + .GetCString(); } if (tag == DW_TAG_formal_parameter) @@ -3524,7 +3397,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, } } } else { - if (location_is_const_value_data) + if (location_is_const_value_data && + die.GetDIE()->IsGlobalOrStaticScopeVariable()) scope = eValueTypeVariableStatic; else { scope = eValueTypeVariableLocal; @@ -3603,7 +3477,7 @@ SymbolFileDWARF::FindBlockContainingSpecification( // Give the concrete function die specified by "func_die_offset", find the // concrete block whose DW_AT_specification or DW_AT_abstract_origin points // to "spec_block_die_offset" - return FindBlockContainingSpecification(DebugInfo()->GetDIE(func_die_ref), + return FindBlockContainingSpecification(DebugInfo().GetDIE(func_die_ref), spec_block_die_offset); } @@ -3762,7 +3636,8 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) { CallSiteParameterArray parameters; for (DWARFDIE child = call_site_die.GetFirstChild(); child.IsValid(); child = child.GetSibling()) { - if (child.Tag() != DW_TAG_call_site_parameter) + if (child.Tag() != DW_TAG_call_site_parameter && + child.Tag() != DW_TAG_GNU_call_site_parameter) continue; llvm::Optional<DWARFExpression> LocationInCallee; @@ -3792,7 +3667,7 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) { dw_attr_t attr = attributes.AttributeAtIndex(i); if (attr == DW_AT_location) LocationInCallee = parse_simple_location(i); - if (attr == DW_AT_call_value) + if (attr == DW_AT_call_value || attr == DW_AT_GNU_call_site_value) LocationInCaller = parse_simple_location(i); } @@ -3805,12 +3680,13 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) { } /// Collect call graph edges present in a function DIE. -static std::vector<std::unique_ptr<lldb_private::CallEdge>> -CollectCallEdges(ModuleSP module, DWARFDIE function_die) { +std::vector<std::unique_ptr<lldb_private::CallEdge>> +SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) { // Check if the function has a supported call site-related attribute. // TODO: In the future it may be worthwhile to support call_all_source_calls. - uint64_t has_call_edges = - function_die.GetAttributeValueAsUnsigned(DW_AT_call_all_calls, 0); + bool has_call_edges = + function_die.GetAttributeValueAsUnsigned(DW_AT_call_all_calls, 0) || + function_die.GetAttributeValueAsUnsigned(DW_AT_GNU_all_call_sites, 0); if (!has_call_edges) return {}; @@ -3826,15 +3702,22 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) { std::vector<std::unique_ptr<CallEdge>> call_edges; for (DWARFDIE child = function_die.GetFirstChild(); child.IsValid(); child = child.GetSibling()) { - if (child.Tag() != DW_TAG_call_site) + if (child.Tag() != DW_TAG_call_site && child.Tag() != DW_TAG_GNU_call_site) continue; llvm::Optional<DWARFDIE> call_origin; llvm::Optional<DWARFExpression> call_target; addr_t return_pc = LLDB_INVALID_ADDRESS; + addr_t call_inst_pc = LLDB_INVALID_ADDRESS; + addr_t low_pc = LLDB_INVALID_ADDRESS; + bool tail_call = false; + // Second DW_AT_low_pc may come from DW_TAG_subprogram referenced by + // DW_TAG_GNU_call_site's DW_AT_abstract_origin overwriting our 'low_pc'. + // So do not inherit attributes from DW_AT_abstract_origin. DWARFAttributes attributes; - const size_t num_attributes = child.GetAttributes(attributes); + const size_t num_attributes = + child.GetAttributes(attributes, DWARFDIE::Recurse::no); for (size_t i = 0; i < num_attributes; ++i) { DWARFFormValue form_value; if (!attributes.ExtractFormValueAtIndex(i, form_value)) { @@ -3844,8 +3727,11 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) { dw_attr_t attr = attributes.AttributeAtIndex(i); + if (attr == DW_AT_call_tail_call || attr == DW_AT_GNU_tail_call) + tail_call = form_value.Boolean(); + // Extract DW_AT_call_origin (the call target's DIE). - if (attr == DW_AT_call_origin) { + if (attr == DW_AT_call_origin || attr == DW_AT_abstract_origin) { call_origin = form_value.Reference(); if (!call_origin->IsValid()) { LLDB_LOG(log, "CollectCallEdges: Invalid call origin in {0}", @@ -3854,15 +3740,24 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) { } } + if (attr == DW_AT_low_pc) + low_pc = form_value.Address(); + // Extract DW_AT_call_return_pc (the PC the call returns to) if it's // available. It should only ever be unavailable for tail call edges, in // which case use LLDB_INVALID_ADDRESS. if (attr == DW_AT_call_return_pc) return_pc = form_value.Address(); + // Extract DW_AT_call_pc (the PC at the call/branch instruction). It + // should only ever be unavailable for non-tail calls, in which case use + // LLDB_INVALID_ADDRESS. + if (attr == DW_AT_call_pc) + call_inst_pc = form_value.Address(); + // Extract DW_AT_call_target (the location of the address of the indirect // call). - if (attr == DW_AT_call_target) { + if (attr == DW_AT_call_target || attr == DW_AT_GNU_call_site_target) { if (!DWARFFormValue::IsBlockForm(form_value.Form())) { LLDB_LOG(log, "CollectCallEdges: AT_call_target does not have block form"); @@ -3882,16 +3777,39 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) { continue; } + addr_t caller_address; + CallEdge::AddrType caller_address_type; + if (return_pc != LLDB_INVALID_ADDRESS) { + caller_address = return_pc; + caller_address_type = CallEdge::AddrType::AfterCall; + } else if (low_pc != LLDB_INVALID_ADDRESS) { + caller_address = low_pc; + caller_address_type = CallEdge::AddrType::AfterCall; + } else if (call_inst_pc != LLDB_INVALID_ADDRESS) { + caller_address = call_inst_pc; + caller_address_type = CallEdge::AddrType::Call; + } else { + LLDB_LOG(log, "CollectCallEdges: No caller address"); + continue; + } + // Adjust any PC forms. It needs to be fixed up if the main executable + // contains a debug map (i.e. pointers to object files), because we need a + // file address relative to the executable's text section. + caller_address = FixupAddress(caller_address); + // Extract call site parameters. CallSiteParameterArray parameters = CollectCallSiteParameters(module, child); std::unique_ptr<CallEdge> edge; if (call_origin) { - LLDB_LOG(log, "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x})", - call_origin->GetPubname(), return_pc); - edge = std::make_unique<DirectCallEdge>(call_origin->GetMangledName(), - return_pc, std::move(parameters)); + LLDB_LOG(log, + "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x}) " + "(call-PC: {2:x})", + call_origin->GetPubname(), return_pc, call_inst_pc); + edge = std::make_unique<DirectCallEdge>( + call_origin->GetMangledName(), caller_address_type, caller_address, + tail_call, std::move(parameters)); } else { if (log) { StreamString call_target_desc; @@ -3900,8 +3818,9 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) { LLDB_LOG(log, "CollectCallEdges: Found indirect call target: {0}", call_target_desc.GetString()); } - edge = std::make_unique<IndirectCallEdge>(*call_target, return_pc, - std::move(parameters)); + edge = std::make_unique<IndirectCallEdge>( + *call_target, caller_address_type, caller_address, tail_call, + std::move(parameters)); } if (log && parameters.size()) { @@ -3925,6 +3844,11 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) { std::vector<std::unique_ptr<lldb_private::CallEdge>> SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) { + // ParseCallEdgesInFunction must be called at the behest of an exclusively + // locked lldb::Function instance. Storage for parsed call edges is owned by + // the lldb::Function instance: locking at the SymbolFile level would be too + // late, because the act of storing results from ParseCallEdgesInFunction + // would be racy. DWARFDIE func_die = GetDIE(func_id.GetID()); if (func_die.IsValid()) return CollectCallEdges(GetObjectFile()->GetModule(), func_die); @@ -3945,8 +3869,8 @@ void SymbolFileDWARF::DumpClangAST(Stream &s) { auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus); if (!ts_or_err) return; - ClangASTContext *clang = - llvm::dyn_cast_or_null<ClangASTContext>(&ts_or_err.get()); + TypeSystemClang *clang = + llvm::dyn_cast_or_null<TypeSystemClang>(&ts_or_err.get()); if (!clang) return; clang->Dump(s); @@ -3957,26 +3881,93 @@ SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { lldb::ModuleSP module_sp(m_debug_map_module_wp.lock()); if (module_sp) { m_debug_map_symfile = - (SymbolFileDWARFDebugMap *)module_sp->GetSymbolFile(); + static_cast<SymbolFileDWARFDebugMap *>(module_sp->GetSymbolFile()); } } return m_debug_map_symfile; } -SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() { +const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() { llvm::call_once(m_dwp_symfile_once_flag, [this]() { ModuleSpec module_spec; module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec(); module_spec.GetSymbolFileSpec() = - FileSpec(m_objfile_sp->GetFileSpec().GetPath() + ".dwp"); + FileSpec(m_objfile_sp->GetModule()->GetFileSpec().GetPath() + ".dwp"); FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); FileSpec dwp_filespec = Symbols::LocateExecutableSymbolFile(module_spec, search_paths); if (FileSystem::Instance().Exists(dwp_filespec)) { - m_dwp_symfile = SymbolFileDWARFDwp::Create(GetObjectFile()->GetModule(), - dwp_filespec); + DataBufferSP dwp_file_data_sp; + lldb::offset_t dwp_file_data_offset = 0; + ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin( + GetObjectFile()->GetModule(), &dwp_filespec, 0, + FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp, + dwp_file_data_offset); + if (!dwp_obj_file) + return; + m_dwp_symfile = + std::make_shared<SymbolFileDWARFDwo>(*this, dwp_obj_file, 0x3fffffff); } }); - return m_dwp_symfile.get(); + return m_dwp_symfile; +} + +llvm::Expected<TypeSystem &> SymbolFileDWARF::GetTypeSystem(DWARFUnit &unit) { + return unit.GetSymbolFileDWARF().GetTypeSystemForLanguage(GetLanguage(unit)); +} + +DWARFASTParser *SymbolFileDWARF::GetDWARFParser(DWARFUnit &unit) { + auto type_system_or_err = GetTypeSystem(unit); + if (auto err = type_system_or_err.takeError()) { + LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), + std::move(err), "Unable to get DWARFASTParser"); + return nullptr; + } + return type_system_or_err->GetDWARFParser(); +} + +CompilerDecl SymbolFileDWARF::GetDecl(const DWARFDIE &die) { + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) + return dwarf_ast->GetDeclForUIDFromDWARF(die); + return CompilerDecl(); +} + +CompilerDeclContext SymbolFileDWARF::GetDeclContext(const DWARFDIE &die) { + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) + return dwarf_ast->GetDeclContextForUIDFromDWARF(die); + return CompilerDeclContext(); +} + +CompilerDeclContext +SymbolFileDWARF::GetContainingDeclContext(const DWARFDIE &die) { + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) + return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); + return CompilerDeclContext(); +} + +DWARFDeclContext SymbolFileDWARF::GetDWARFDeclContext(const DWARFDIE &die) { + if (!die.IsValid()) + return {}; + DWARFDeclContext dwarf_decl_ctx = + die.GetDIE()->GetDWARFDeclContext(die.GetCU()); + dwarf_decl_ctx.SetLanguage(GetLanguage(*die.GetCU())); + return dwarf_decl_ctx; +} + +LanguageType SymbolFileDWARF::LanguageTypeFromDWARF(uint64_t val) { + // Note: user languages between lo_user and hi_user must be handled + // explicitly here. + switch (val) { + case DW_LANG_Mips_Assembler: + return eLanguageTypeMipsAssembler; + case DW_LANG_GOOGLE_RenderScript: + return eLanguageTypeExtRenderScript; + default: + return static_cast<LanguageType>(val); + } +} + +LanguageType SymbolFileDWARF::GetLanguage(DWARFUnit &unit) { + return LanguageTypeFromDWARF(unit.GetDWARFLanguageType()); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 23e26732453f..76ceb279c718 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -6,17 +6,17 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_SymbolFileDWARF_h_ -#define SymbolFileDWARF_SymbolFileDWARF_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H #include <list> #include <map> #include <mutex> -#include <set> #include <unordered_map> #include <vector> #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SetVector.h" #include "llvm/Support/Threading.h" #include "lldb/Core/UniqueCStringMap.h" @@ -90,8 +90,6 @@ public: static lldb_private::SymbolFile * CreateInstance(lldb::ObjectFileSP objfile_sp); - static lldb_private::FileSpecList GetSymlinkPaths(); - // Constructors and Destructors SymbolFileDWARF(lldb::ObjectFileSP objfile_sp, @@ -108,6 +106,9 @@ public: lldb::LanguageType ParseLanguage(lldb_private::CompileUnit &comp_unit) override; + lldb_private::XcodeSDK + ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override; + size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override; bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override; @@ -168,7 +169,7 @@ public: void FindGlobalVariables(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, lldb_private::VariableList &variables) override; @@ -177,7 +178,7 @@ public: lldb_private::VariableList &variables) override; void FindFunctions(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, lldb_private::SymbolContextList &sc_list) override; @@ -192,7 +193,7 @@ public: void FindTypes(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap &types) override; @@ -211,7 +212,7 @@ public: lldb_private::CompilerDeclContext FindNamespace( lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx) override; + const lldb_private::CompilerDeclContext &parent_decl_ctx) override; void PreloadSymbols() override; @@ -224,11 +225,7 @@ public: DWARFDebugAbbrev *DebugAbbrev(); - const DWARFDebugAbbrev *DebugAbbrev() const; - - DWARFDebugInfo *DebugInfo(); - - const DWARFDebugInfo *DebugInfo() const; + DWARFDebugInfo &DebugInfo(); DWARFDebugRanges *GetDebugRanges(); @@ -243,8 +240,8 @@ public: lldb_private::CompileUnit * GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu); - virtual size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name, - DIEArray &method_die_offsets); + virtual void GetObjCMethods(lldb_private::ConstString class_name, + llvm::function_ref<bool(DWARFDIE die)> callback); bool Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu); @@ -252,8 +249,6 @@ public: static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die); - virtual lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu); - lldb::ModuleSP GetExternalModule(lldb_private::ConstString name); typedef std::map<lldb_private::ConstString, lldb::ModuleSP> @@ -278,22 +273,17 @@ public: lldb::user_id_t GetUID(DIERef ref); - std::unique_ptr<SymbolFileDWARFDwo> + std::shared_ptr<SymbolFileDWARFDwo> GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die); - // For regular SymbolFileDWARF instances the method returns nullptr, - // for the instances of the subclass SymbolFileDWARFDwo - // the method returns a pointer to the base compile unit. - virtual DWARFCompileUnit *GetBaseCompileUnit() { return nullptr; } - virtual llvm::Optional<uint32_t> GetDwoNum() { return llvm::None; } /// If this is a DWARF object with a single CU, return its DW_AT_dwo_id. llvm::Optional<uint64_t> GetDWOId(); static bool - DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx, + DIEInDeclContext(const lldb_private::CompilerDeclContext &parent_decl_ctx, const DWARFDIE &die); std::vector<std::unique_ptr<lldb_private::CallEdge>> @@ -305,8 +295,30 @@ public: lldb_private::DWARFContext &GetDWARFContext() { return m_context; } + const std::shared_ptr<SymbolFileDWARFDwo> &GetDwpSymbolFile(); + lldb_private::FileSpec GetFile(DWARFUnit &unit, size_t file_idx); + static llvm::Expected<lldb_private::TypeSystem &> + GetTypeSystem(DWARFUnit &unit); + + static DWARFASTParser *GetDWARFParser(DWARFUnit &unit); + + // CompilerDecl related functions + + static lldb_private::CompilerDecl GetDecl(const DWARFDIE &die); + + static lldb_private::CompilerDeclContext GetDeclContext(const DWARFDIE &die); + + static lldb_private::CompilerDeclContext + GetContainingDeclContext(const DWARFDIE &die); + + static DWARFDeclContext GetDWARFDeclContext(const DWARFDIE &die); + + static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val); + + static lldb::LanguageType GetLanguage(DWARFUnit &unit); + protected: typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr; @@ -315,25 +327,16 @@ protected: typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::opaque_compiler_type_t> DIEToClangType; - typedef llvm::DenseMap<lldb::opaque_compiler_type_t, lldb::user_id_t> - ClangTypeToDIE; + typedef llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> ClangTypeToDIE; - struct DWARFDataSegment { - llvm::once_flag m_flag; - lldb_private::DWARFDataExtractor m_data; - }; - - DISALLOW_COPY_AND_ASSIGN(SymbolFileDWARF); - - const lldb_private::DWARFDataExtractor & - GetCachedSectionData(lldb::SectionType sect_type, - DWARFDataSegment &data_segment); + SymbolFileDWARF(const SymbolFileDWARF &) = delete; + const SymbolFileDWARF &operator=(const SymbolFileDWARF &) = delete; virtual void LoadSectionData(lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data); bool DeclContextMatchesThisSymbolFile( - const lldb_private::CompilerDeclContext *decl_ctx); + const lldb_private::CompilerDeclContext &decl_ctx); uint32_t CalculateNumCompileUnits() override; @@ -341,6 +344,8 @@ protected: lldb_private::TypeList &GetTypeList() override; + lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu); + virtual DWARFUnit * GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit); @@ -383,6 +388,13 @@ protected: bool ResolveFunction(const DWARFDIE &die, bool include_inlines, lldb_private::SymbolContextList &sc_list); + /// Resolve functions and (possibly) blocks for the given file address and a + /// compile unit. The compile unit comes from the sc argument and it must be + /// set. The results of the lookup (if any) are written back to the symbol + /// context. + void ResolveFunctionAndBlock(lldb::addr_t file_vm_addr, bool lookup_block, + lldb_private::SymbolContext &sc); + virtual lldb::TypeSP FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx); @@ -417,9 +429,21 @@ protected: bool ClassContainsSelector(const DWARFDIE &class_die, lldb_private::ConstString selector); + /// Parse call site entries (DW_TAG_call_site), including any nested call site + /// parameters (DW_TAG_call_site_parameter). + std::vector<std::unique_ptr<lldb_private::CallEdge>> + CollectCallEdges(lldb::ModuleSP module, DWARFDIE function_die); + + /// If this symbol file is linked to by a debug map (see + /// SymbolFileDWARFDebugMap), and \p file_addr is a file address relative to + /// an object file, adjust \p file_addr so that it is relative to the main + /// binary. Returns the adjusted address, or \p file_addr if no adjustment is + /// needed, on success and LLDB_INVALID_ADDRESS otherwise. + lldb::addr_t FixupAddress(lldb::addr_t file_addr); + bool FixupAddress(lldb_private::Address &addr); - typedef std::set<lldb_private::Type *> TypeSet; + typedef llvm::SetVector<lldb_private::Type *> TypeSet; void GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset, dw_offset_t max_die_offset, uint32_t type_mask, @@ -454,7 +478,7 @@ protected: }; llvm::Optional<DecodedUID> DecodeUID(lldb::user_id_t uid); - SymbolFileDWARFDwp *GetDwpSymbolFile(); + void FindDwpSymbolFile(); const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu); @@ -462,17 +486,14 @@ protected: SymbolFileDWARFDebugMap *m_debug_map_symfile; llvm::once_flag m_dwp_symfile_once_flag; - std::unique_ptr<SymbolFileDWARFDwp> m_dwp_symfile; + std::shared_ptr<SymbolFileDWARFDwo> m_dwp_symfile; lldb_private::DWARFContext m_context; - DWARFDataSegment m_data_debug_loc; - DWARFDataSegment m_data_debug_loclists; + llvm::once_flag m_info_once_flag; + std::unique_ptr<DWARFDebugInfo> m_info; - // The unique pointer items below are generated on demand if and when someone - // accesses them through a non const version of this class. std::unique_ptr<DWARFDebugAbbrev> m_abbr; - std::unique_ptr<DWARFDebugInfo> m_info; std::unique_ptr<GlobalVariableMap> m_global_aranges_up; typedef std::unordered_map<lldb::offset_t, lldb_private::DebugMacrosSP> @@ -484,7 +505,7 @@ protected: bool m_fetched_external_modules : 1; lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type; - typedef std::set<lldb::user_id_t> DIERefSet; + typedef std::set<DIERef> DIERefSet; typedef llvm::StringMap<DIERefSet> NameToOffsetMap; NameToOffsetMap m_function_scope_qualified_name_map; std::unique_ptr<DWARFDebugRanges> m_ranges; @@ -498,4 +519,4 @@ protected: std::vector<uint32_t> m_lldb_cu_to_dwarf_unit; }; -#endif // SymbolFileDWARF_SymbolFileDWARF_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index cce666a222d0..6515d78b8f23 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFileDWARFDebugMap.cpp -----------------------------*- C++ -*-===// +//===-- SymbolFileDWARFDebugMap.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -108,8 +108,7 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap( // First we find the original symbol in the .o file's symbol table Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType( - exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, - Mangled::ePreferMangled), + exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny); if (oso_fun_symbol) { // Add the inverse OSO file address to debug map entry mapping @@ -139,8 +138,7 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap( // in the .o file Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType( - exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, - Mangled::ePreferMangled), + exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny); if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && oso_gsym_symbol->ValueIsAddress()) { @@ -416,6 +414,7 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo( FileSpec oso_file(oso_path); ConstString oso_object; if (FileSystem::Instance().Exists(oso_file)) { + FileSystem::Instance().Collect(oso_file); // The modification time returned by the FS can have a higher precision // than the one from the CU. auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>( @@ -531,7 +530,7 @@ SymbolFileDWARF * SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) { if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic()) - return (SymbolFileDWARF *)sym_file; + return static_cast<SymbolFileDWARF *>(sym_file); return nullptr; } @@ -630,6 +629,14 @@ SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) { return eLanguageTypeUnknown; } +XcodeSDK SymbolFileDWARFDebugMap::ParseXcodeSDK(CompileUnit &comp_unit) { + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); + if (oso_dwarf) + return oso_dwarf->ParseXcodeSDK(comp_unit); + return {}; +} + size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); @@ -826,7 +833,7 @@ uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( } void SymbolFileDWARFDebugMap::PrivateFindGlobalVariables( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, const std::vector<uint32_t> &indexes, // Indexes into the symbol table that match "name" uint32_t max_matches, VariableList &variables) { @@ -848,7 +855,7 @@ void SymbolFileDWARFDebugMap::PrivateFindGlobalVariables( } void SymbolFileDWARFDebugMap::FindGlobalVariables( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); uint32_t total_matches = 0; @@ -1002,7 +1009,7 @@ static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp, } void SymbolFileDWARFDebugMap::FindFunctions( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); @@ -1172,7 +1179,7 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE( } void SymbolFileDWARFDebugMap::FindTypes( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types) { @@ -1209,7 +1216,7 @@ void SymbolFileDWARFDebugMap::FindTypes( CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( lldb_private::ConstString name, - const CompilerDeclContext *parent_decl_ctx) { + const CompilerDeclContext &parent_decl_ctx) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); CompilerDeclContext matching_namespace; @@ -1225,6 +1232,9 @@ CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) { ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) -> bool { oso_dwarf->DumpClangAST(s); + // The underlying assumption is that DumpClangAST(...) will obtain the + // AST from the underlying TypeSystem and therefore we only need to do + // this once and can stop after the first iteration hence we return true. return true; }); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index 035a902498be..06f0d48c04ca 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_ -#define SymbolFileDWARF_SymbolFileDWARFDebugMap_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H #include "lldb/Symbol/SymbolFile.h" #include "lldb/Utility/RangeMap.h" @@ -57,11 +57,10 @@ public: // Compile Unit function calls lldb::LanguageType ParseLanguage(lldb_private::CompileUnit &comp_unit) override; - + lldb_private::XcodeSDK + ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override; size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override; - bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override; - bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override; bool ForEachExternalModule( @@ -105,14 +104,14 @@ public: lldb_private::SymbolContextList &sc_list) override; void FindGlobalVariables(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, lldb_private::VariableList &variables) override; void FindGlobalVariables(const lldb_private::RegularExpression ®ex, uint32_t max_matches, lldb_private::VariableList &variables) override; void FindFunctions(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, lldb_private::SymbolContextList &sc_list) override; @@ -121,7 +120,7 @@ public: lldb_private::SymbolContextList &sc_list) override; void FindTypes(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap &types) override; @@ -132,7 +131,7 @@ public: lldb_private::TypeMap &types) override; lldb_private::CompilerDeclContext FindNamespace( lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx) override; + const lldb_private::CompilerDeclContext &parent_decl_ctx) override; void GetTypes(lldb_private::SymbolContextScope *sc_scope, lldb::TypeClass type_mask, lldb_private::TypeList &type_list) override; @@ -254,7 +253,7 @@ protected: void PrivateFindGlobalVariables( lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, const std::vector<uint32_t> &name_symbol_indexes, uint32_t max_matches, lldb_private::VariableList &variables); @@ -379,4 +378,4 @@ protected: DWARFDebugAranges *debug_aranges); }; -#endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp index f75f06f31e2d..3aaa7d330b84 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFileDWARFDwo.cpp ----------------------------------*- C++ -*-===// +//===-- SymbolFileDWARFDwo.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -23,62 +23,52 @@ using namespace lldb_private; char SymbolFileDWARFDwo::ID; -SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile, - DWARFCompileUnit &dwarf_cu) +SymbolFileDWARFDwo::SymbolFileDWARFDwo(SymbolFileDWARF &base_symbol_file, + ObjectFileSP objfile, uint32_t id) : SymbolFileDWARF(objfile, objfile->GetSectionList( /*update_module_section_list*/ false)), - m_base_dwarf_cu(dwarf_cu) { - SetID(((lldb::user_id_t)dwarf_cu.GetID()) << 32); -} - -void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type, - DWARFDataExtractor &data) { - const SectionList *section_list = - m_objfile_sp->GetSectionList(false /* update_module_section_list */); - if (section_list) { - SectionSP section_sp(section_list->FindSectionByType(sect_type, true)); - if (section_sp) { + m_base_symbol_file(base_symbol_file) { + SetID(user_id_t(id) << 32); - if (m_objfile_sp->ReadSectionData(section_sp.get(), data) != 0) - return; + // Parsing of the dwarf unit index is not thread-safe, so we need to prime it + // to enable subsequent concurrent lookups. + m_context.GetAsLLVM().getCUIndex(); +} - data.Clear(); +DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) { + if (const llvm::DWARFUnitIndex &index = m_context.GetAsLLVM().getCUIndex()) { + if (const llvm::DWARFUnitIndex::Entry *entry = index.getFromHash(hash)) { + if (auto *unit_contrib = entry->getContribution()) + return llvm::dyn_cast_or_null<DWARFCompileUnit>( + DebugInfo().GetUnitAtOffset(DIERef::Section::DebugInfo, + unit_contrib->Offset)); } + return nullptr; } - SymbolFileDWARF::LoadSectionData(sect_type, data); -} - -lldb::CompUnitSP -SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { - assert(GetCompileUnit() == &dwarf_cu && - "SymbolFileDWARFDwo::ParseCompileUnit called with incompatible " - "compile unit"); - return GetBaseSymbolFile().ParseCompileUnit(m_base_dwarf_cu); -} - -DWARFCompileUnit *SymbolFileDWARFDwo::GetCompileUnit() { - if (!m_cu) - m_cu = ComputeCompileUnit(); - return m_cu; + DWARFCompileUnit *cu = FindSingleCompileUnit(); + if (!cu) + return nullptr; + if (hash != + cu->GetUnitDIEOnly().GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0)) + return nullptr; + return cu; } -DWARFCompileUnit *SymbolFileDWARFDwo::ComputeCompileUnit() { - DWARFDebugInfo *debug_info = DebugInfo(); - if (!debug_info) - return nullptr; +DWARFCompileUnit *SymbolFileDWARFDwo::FindSingleCompileUnit() { + DWARFDebugInfo &debug_info = DebugInfo(); // Right now we only support dwo files with one compile unit. If we don't have // type units, we can just check for the unit count. - if (!debug_info->ContainsTypeUnits() && debug_info->GetNumUnits() == 1) - return llvm::cast<DWARFCompileUnit>(debug_info->GetUnitAtIndex(0)); + if (!debug_info.ContainsTypeUnits() && debug_info.GetNumUnits() == 1) + return llvm::cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(0)); // Otherwise, we have to run through all units, and find the compile unit that // way. DWARFCompileUnit *cu = nullptr; - for (size_t i = 0; i < debug_info->GetNumUnits(); ++i) { + for (size_t i = 0; i < debug_info.GetNumUnits(); ++i) { if (auto *candidate = - llvm::dyn_cast<DWARFCompileUnit>(debug_info->GetUnitAtIndex(i))) { + llvm::dyn_cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(i))) { if (cu) return nullptr; // More that one CU found. cu = candidate; @@ -87,11 +77,6 @@ DWARFCompileUnit *SymbolFileDWARFDwo::ComputeCompileUnit() { return cu; } -DWARFUnit * -SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) { - return GetCompileUnit(); -} - SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() { return GetBaseSymbolFile().GetDIEToType(); } @@ -110,10 +95,10 @@ SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() { return GetBaseSymbolFile().GetForwardDeclClangTypeToDie(); } -size_t SymbolFileDWARFDwo::GetObjCMethodDIEOffsets( - lldb_private::ConstString class_name, DIEArray &method_die_offsets) { - return GetBaseSymbolFile().GetObjCMethodDIEOffsets(class_name, - method_die_offsets); +void SymbolFileDWARFDwo::GetObjCMethods( + lldb_private::ConstString class_name, + llvm::function_ref<bool(DWARFDIE die)> callback) { + GetBaseSymbolFile().GetObjCMethods(class_name, callback); } UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() { @@ -133,10 +118,6 @@ lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE( die, type_name, must_be_implementation); } -SymbolFileDWARF &SymbolFileDWARFDwo::GetBaseSymbolFile() { - return m_base_dwarf_cu.GetSymbolFileDWARF(); -} - llvm::Expected<TypeSystem &> SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) { return GetBaseSymbolFile().GetTypeSystemForLanguage(language); @@ -144,7 +125,7 @@ SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) { DWARFDIE SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) { - if (*die_ref.dwo_num() == GetDwoNum()) - return DebugInfo()->GetDIE(die_ref); + if (die_ref.dwo_num() == GetDwoNum()) + return DebugInfo().GetDIE(die_ref); return GetBaseSymbolFile().GetDIE(die_ref); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h index 0855dba044e4..93538aac3c54 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ -#define SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDWO_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDWO_H #include "SymbolFileDWARF.h" @@ -24,19 +24,15 @@ public: static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} - SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFCompileUnit &dwarf_cu); + SymbolFileDWARFDwo(SymbolFileDWARF &m_base_symbol_file, + lldb::ObjectFileSP objfile, uint32_t id); ~SymbolFileDWARFDwo() override = default; - lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu) override; + DWARFCompileUnit *GetDWOCompileUnitForHash(uint64_t hash); - DWARFCompileUnit *GetCompileUnit(); - - DWARFUnit * - GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override; - - size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name, - DIEArray &method_die_offsets) override; + void GetObjCMethods(lldb_private::ConstString class_name, + llvm::function_ref<bool(DWARFDIE die)> callback) override; llvm::Expected<lldb_private::TypeSystem &> GetTypeSystemForLanguage(lldb::LanguageType language) override; @@ -44,14 +40,9 @@ public: DWARFDIE GetDIE(const DIERef &die_ref) override; - DWARFCompileUnit *GetBaseCompileUnit() override { return &m_base_dwarf_cu; } - llvm::Optional<uint32_t> GetDwoNum() override { return GetID() >> 32; } protected: - void LoadSectionData(lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data) override; - DIEToTypePtr &GetDIEToType() override; DIEToVariableSP &GetDIEToVariable() override; @@ -69,12 +60,13 @@ protected: const DWARFDIE &die, lldb_private::ConstString type_name, bool must_be_implementation) override; - SymbolFileDWARF &GetBaseSymbolFile(); + SymbolFileDWARF &GetBaseSymbolFile() { return m_base_symbol_file; } - DWARFCompileUnit *ComputeCompileUnit(); + /// If this file contains exactly one compile unit, this function will return + /// it. Otherwise it returns nullptr. + DWARFCompileUnit *FindSingleCompileUnit(); - DWARFCompileUnit &m_base_dwarf_cu; - DWARFCompileUnit *m_cu = nullptr; + SymbolFileDWARF &m_base_symbol_file; }; -#endif // SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDWO_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp deleted file mode 100644 index 4288dcb5c9bd..000000000000 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp +++ /dev/null @@ -1,37 +0,0 @@ -//===-- SymbolFileDWARFDwoDwp.cpp -------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "SymbolFileDWARFDwoDwp.h" - -#include "lldb/Core/Section.h" -#include "lldb/Expression/DWARFExpression.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Utility/LLDBAssert.h" - -#include "DWARFUnit.h" -#include "DWARFDebugInfo.h" - -using namespace lldb; -using namespace lldb_private; - -char SymbolFileDWARFDwoDwp::ID; - -SymbolFileDWARFDwoDwp::SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile, - ObjectFileSP objfile, - DWARFCompileUnit &dwarf_cu, - uint64_t dwo_id) - : SymbolFileDWARFDwo(objfile, dwarf_cu), m_dwp_symfile(dwp_symfile), - m_dwo_id(dwo_id) {} - -void SymbolFileDWARFDwoDwp::LoadSectionData(lldb::SectionType sect_type, - DWARFDataExtractor &data) { - if (m_dwp_symfile->LoadSectionData(m_dwo_id, sect_type, data)) - return; - - SymbolFileDWARF::LoadSectionData(sect_type, data); -} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h deleted file mode 100644 index a55795ba5950..000000000000 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h +++ /dev/null @@ -1,39 +0,0 @@ -//===-- SymbolFileDWARFDwoDwp.h ---------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_ -#define SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_ - -#include "SymbolFileDWARFDwo.h" -#include "SymbolFileDWARFDwp.h" - -class SymbolFileDWARFDwoDwp : public SymbolFileDWARFDwo { - /// LLVM RTTI support. - static char ID; - -public: - /// LLVM RTTI support. - /// \{ - bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFileDWARFDwo::isA(ClassID); - } - static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } - /// \} - SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile, - lldb::ObjectFileSP objfile, DWARFCompileUnit &dwarf_cu, - uint64_t dwo_id); - -protected: - void LoadSectionData(lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data) override; - - SymbolFileDWARFDwp *m_dwp_symfile; - uint64_t m_dwo_id; -}; - -#endif // SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp deleted file mode 100644 index 08e6e1c8c2f3..000000000000 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp +++ /dev/null @@ -1,138 +0,0 @@ -//===-- SymbolFileDWARFDwp.cpp ----------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "SymbolFileDWARFDwp.h" - -#include "lldb/Core/Section.h" -#include "lldb/Symbol/ObjectFile.h" - -#include "SymbolFileDWARFDwoDwp.h" - -static llvm::DWARFSectionKind -lldbSectTypeToLlvmSectionKind(lldb::SectionType type) { - switch (type) { - case lldb::eSectionTypeDWARFDebugInfo: - return llvm::DW_SECT_INFO; - // case lldb::eSectionTypeDWARFDebugTypes: - // return llvm::DW_SECT_TYPES; - case lldb::eSectionTypeDWARFDebugAbbrev: - return llvm::DW_SECT_ABBREV; - case lldb::eSectionTypeDWARFDebugLine: - return llvm::DW_SECT_LINE; - case lldb::eSectionTypeDWARFDebugLoc: - return llvm::DW_SECT_LOC; - case lldb::eSectionTypeDWARFDebugStrOffsets: - return llvm::DW_SECT_STR_OFFSETS; - // case lldb::eSectionTypeDWARFDebugMacinfo: - // return llvm::DW_SECT_MACINFO; - case lldb::eSectionTypeDWARFDebugMacro: - return llvm::DW_SECT_MACRO; - default: - // Note: 0 is an invalid dwarf section kind. - return llvm::DWARFSectionKind(0); - } -} - -std::unique_ptr<SymbolFileDWARFDwp> -SymbolFileDWARFDwp::Create(lldb::ModuleSP module_sp, - const lldb_private::FileSpec &file_spec) { - const lldb::offset_t file_offset = 0; - lldb::DataBufferSP file_data_sp; - lldb::offset_t file_data_offset = 0; - lldb::ObjectFileSP obj_file = lldb_private::ObjectFile::FindPlugin( - module_sp, &file_spec, file_offset, - lldb_private::FileSystem::Instance().GetByteSize(file_spec), file_data_sp, - file_data_offset); - if (obj_file == nullptr) - return nullptr; - - std::unique_ptr<SymbolFileDWARFDwp> dwp_symfile( - new SymbolFileDWARFDwp(module_sp, obj_file)); - - lldb_private::DWARFDataExtractor debug_cu_index; - if (!dwp_symfile->LoadRawSectionData(lldb::eSectionTypeDWARFDebugCuIndex, - debug_cu_index)) - return nullptr; - - llvm::DataExtractor llvm_debug_cu_index( - llvm::StringRef(debug_cu_index.PeekCStr(0), debug_cu_index.GetByteSize()), - debug_cu_index.GetByteOrder() == lldb::eByteOrderLittle, - debug_cu_index.GetAddressByteSize()); - if (!dwp_symfile->m_debug_cu_index.parse(llvm_debug_cu_index)) - return nullptr; - dwp_symfile->InitDebugCUIndexMap(); - return dwp_symfile; -} - -void SymbolFileDWARFDwp::InitDebugCUIndexMap() { - m_debug_cu_index_map.clear(); - for (const auto &entry : m_debug_cu_index.getRows()) - m_debug_cu_index_map.emplace(entry.getSignature(), &entry); -} - -SymbolFileDWARFDwp::SymbolFileDWARFDwp(lldb::ModuleSP module_sp, - lldb::ObjectFileSP obj_file) - : m_obj_file(std::move(obj_file)), m_debug_cu_index(llvm::DW_SECT_INFO) -{} - -std::unique_ptr<SymbolFileDWARFDwo> -SymbolFileDWARFDwp::GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu, - uint64_t dwo_id) { - return std::unique_ptr<SymbolFileDWARFDwo>( - new SymbolFileDWARFDwoDwp(this, m_obj_file, dwarf_cu, dwo_id)); -} - -bool SymbolFileDWARFDwp::LoadSectionData( - uint64_t dwo_id, lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data) { - lldb_private::DWARFDataExtractor section_data; - if (!LoadRawSectionData(sect_type, section_data)) - return false; - - auto it = m_debug_cu_index_map.find(dwo_id); - if (it == m_debug_cu_index_map.end()) - return false; - - auto *offsets = - it->second->getOffset(lldbSectTypeToLlvmSectionKind(sect_type)); - if (offsets) { - data.SetData(section_data, offsets->Offset, offsets->Length); - } else { - data.SetData(section_data, 0, section_data.GetByteSize()); - } - return true; -} - -bool SymbolFileDWARFDwp::LoadRawSectionData( - lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data) { - std::lock_guard<std::mutex> lock(m_sections_mutex); - - auto it = m_sections.find(sect_type); - if (it != m_sections.end()) { - if (it->second.GetByteSize() == 0) - return false; - - data = it->second; - return true; - } - - const lldb_private::SectionList *section_list = - m_obj_file->GetSectionList(false /* update_module_section_list */); - if (section_list) { - lldb::SectionSP section_sp( - section_list->FindSectionByType(sect_type, true)); - if (section_sp) { - if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) { - m_sections[sect_type] = data; - return true; - } - } - } - m_sections[sect_type].Clear(); - return false; -} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h deleted file mode 100644 index ef06b9dca8bb..000000000000 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h +++ /dev/null @@ -1,50 +0,0 @@ -//===-- SymbolFileDWARFDwp.h ------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_ -#define SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_ - -#include <memory> - -#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" - -#include "lldb/Core/Module.h" - -#include "DWARFDataExtractor.h" -#include "SymbolFileDWARFDwo.h" - -class SymbolFileDWARFDwp { -public: - static std::unique_ptr<SymbolFileDWARFDwp> - Create(lldb::ModuleSP module_sp, const lldb_private::FileSpec &file_spec); - - std::unique_ptr<SymbolFileDWARFDwo> - GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu, uint64_t dwo_id); - - bool LoadSectionData(uint64_t dwo_id, lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data); - -private: - explicit SymbolFileDWARFDwp(lldb::ModuleSP module_sp, - lldb::ObjectFileSP obj_file); - - bool LoadRawSectionData(lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data); - - void InitDebugCUIndexMap(); - - lldb::ObjectFileSP m_obj_file; - - std::mutex m_sections_mutex; - std::map<lldb::SectionType, lldb_private::DWARFDataExtractor> m_sections; - - llvm::DWARFUnitIndex m_debug_cu_index; - std::map<uint64_t, const llvm::DWARFUnitIndex::Entry *> m_debug_cu_index_map; -}; - -#endif // SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td index ef6ae3498588..2f1ce88808b7 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td @@ -1,10 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" let Definition = "symbolfiledwarf" in { - def SymLinkPaths: Property<"comp-dir-symlink-paths", "FileSpecList">, - Global, - DefaultStringValue<"">, - Desc<"If the DW_AT_comp_dir matches any of these paths the symbolic links will be resolved at DWARF parse time.">; def IgnoreIndexes: Property<"ignore-file-indexes", "Boolean">, Global, DefaultFalse, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp index 4862fea8d079..2181989cd37a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp @@ -1,4 +1,4 @@ -//===-- UniqueDWARFASTType.cpp ----------------------------------*- C++ -*-===// +//===-- UniqueDWARFASTType.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h index 1269dbac7126..a1b1a3009787 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_UniqueDWARFASTType_h_ -#define lldb_UniqueDWARFASTType_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_UNIQUEDWARFASTTYPE_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_UNIQUEDWARFASTTYPE_H #include <vector> @@ -100,4 +100,4 @@ protected: collection m_collection; }; -#endif // lldb_UniqueDWARFASTType_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_UNIQUEDWARFASTTYPE_H diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp index 3834165c71c0..ca9ddcec287f 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp @@ -1,4 +1,4 @@ -//===-- CodeViewRegisterMapping.cpp -----------------------------*- C++ -*-===// +//===-- CodeViewRegisterMapping.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h b/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h index b1c31e0c1785..02c7495565b8 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Plugins_SymbolFile_PDB_CodeViewRegisterMapping_h_ -#define lldb_Plugins_SymbolFile_PDB_CodeViewRegisterMapping_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_CODEVIEWREGISTERMAPPING_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_CODEVIEWREGISTERMAPPING_H #include "llvm/ADT/Triple.h" #include "llvm/DebugInfo/CodeView/CodeView.h" diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp index 830d78f81679..f25dc84fb342 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp @@ -1,4 +1,4 @@ -//===-- CompileUnitIndex.cpp ------------------------------------*- C++ -*-===// +//===-- CompileUnitIndex.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -154,7 +154,7 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) { // name until we find it, and we can cache that one since the memory is backed // by a contiguous chunk inside the mapped PDB. llvm::SmallString<64> main_file = GetMainSourceFile(*cci); - std::string s = main_file.str(); + std::string s = std::string(main_file.str()); llvm::sys::path::native(main_file); uint32_t file_count = modules.getSourceFileCount(modi); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h index 44a1c8cdd9c2..088de970cbf3 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_COMPILEUNITINDEX_H -#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_COMPILEUNITINDEX_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_COMPILEUNITINDEX_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_COMPILEUNITINDEX_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp index 6aaff06cc134..d0672352a58f 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp @@ -1,4 +1,4 @@ -//===-- DWARFLocationExpression.cpp -----------------------------*- C++ -*-===// +//===-- DWARFLocationExpression.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h index c37d715babdc..99da09b70fe1 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h @@ -6,14 +6,15 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H -#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H #include "lldb/lldb-forward.h" #include "llvm/DebugInfo/CodeView/CodeView.h" namespace llvm { class APSInt; +class StringRef; namespace codeview { class TypeIndex; } diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index 4588c80aa1b1..0acc77d7c67f 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -14,11 +14,11 @@ #include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "llvm/Demangle/MicrosoftDemangle.h" +#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Module.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangASTMetadata.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/LLDBAssert.h" @@ -178,7 +178,7 @@ GetNestedTagDefinition(const NestedTypeRecord &Record, // single component of a mangled name. So we can inject it into the parent's // mangled name to see if it matches. CVTagRecord child = CVTagRecord::create(cvt); - std::string qname = parent.asTag().getUniqueName(); + std::string qname = std::string(parent.asTag().getUniqueName()); if (qname.size() < 4 || child.asTag().getUniqueName().size() < 4) return llvm::None; @@ -202,7 +202,7 @@ static bool IsAnonymousNamespaceName(llvm::StringRef name) { return name == "`anonymous namespace'" || name == "`anonymous-namespace'"; } -PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang) +PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index, TypeSystemClang &clang) : m_index(index), m_clang(clang) { BuildParentMap(); } @@ -221,7 +221,7 @@ PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) { StringView sv(record.UniqueName.begin(), record.UniqueName.size()); llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv); if (demangler.Error) - return {m_clang.GetTranslationUnitDecl(), record.UniqueName}; + return {m_clang.GetTranslationUnitDecl(), std::string(record.UniqueName)}; llvm::ms_demangle::IdentifierNode *idn = ttn->QualifiedName->getUnqualifiedIdentifier(); @@ -248,7 +248,7 @@ PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) { // a NamespaceDecl and a CXXRecordDecl, so instead we create a class at // global scope with the fully qualified name. if (AnyScopesHaveTemplateParams(scopes)) - return {context, record.Name}; + return {context, std::string(record.Name)}; for (llvm::ms_demangle::Node *scope : scopes) { auto *nii = static_cast<llvm::ms_demangle::NamedIdentifierNode *>(scope); @@ -507,7 +507,7 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) { llvm::StringRef uname = specs.back().GetBaseName(); specs = specs.drop_back(); if (specs.empty()) - return {context, name}; + return {context, std::string(name)}; llvm::StringRef scope_name = specs.back().GetFullName(); @@ -517,7 +517,7 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) { clang::QualType qt = GetOrCreateType(types.back()); clang::TagDecl *tag = qt->getAsTagDecl(); if (tag) - return {clang::TagDecl::castToDeclContext(tag), uname}; + return {clang::TagDecl::castToDeclContext(tag), std::string(uname)}; types.pop_back(); } @@ -526,7 +526,7 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) { std::string ns_name = spec.GetBaseName().str(); context = GetOrCreateNamespaceDecl(ns_name.c_str(), *context); } - return {context, uname}; + return {context, std::string(uname)}; } clang::DeclContext * @@ -656,7 +656,7 @@ bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) { lldbassert(IsTagRecord(type_id, m_index.tpi())); clang::QualType tag_qt = m_clang.getASTContext().getTypeDeclType(&tag); - ClangASTContext::SetHasExternalStorage(tag_qt.getAsOpaquePtr(), false); + TypeSystemClang::SetHasExternalStorage(tag_qt.getAsOpaquePtr(), false); TypeIndex tag_ti = type_id.index; CVType cvt = m_index.tpi().getType(tag_ti); @@ -681,7 +681,7 @@ bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) { // Visit all members of this class, then perform any finalization necessary // to complete the class. CompilerType ct = ToCompilerType(tag_qt); - UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index.tpi()); + UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index); auto error = llvm::codeview::visitMemberRecordStream(field_list_cvt.data(), completer); completer.complete(); @@ -776,12 +776,13 @@ clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id, metadata.SetUserID(toOpaqueUid(id)); metadata.SetIsDynamicCXXType(false); - CompilerType ct = m_clang.CreateRecordType( - context, access, uname, ttk, lldb::eLanguageTypeC_plus_plus, &metadata); + CompilerType ct = + m_clang.CreateRecordType(context, OptionalClangModuleID(), access, uname, + ttk, lldb::eLanguageTypeC_plus_plus, &metadata); lldbassert(ct.IsValid()); - ClangASTContext::StartTagDeclarationDefinition(ct); + TypeSystemClang::StartTagDeclarationDefinition(ct); // Even if it's possible, don't complete it at this point. Just mark it // forward resolved, and if/when LLDB needs the full definition, it can @@ -789,7 +790,7 @@ clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id, clang::QualType result = clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType()); - ClangASTContext::SetHasExternalStorage(result.getAsOpaquePtr(), true); + TypeSystemClang::SetHasExternalStorage(result.getAsOpaquePtr(), true); return result; } @@ -804,7 +805,8 @@ clang::NamespaceDecl * PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name, clang::DeclContext &context) { return m_clang.GetUniqueNamespaceDeclaration( - IsAnonymousNamespaceName(name) ? nullptr : name, &context); + IsAnonymousNamespaceName(name) ? nullptr : name, &context, + OptionalClangModuleID()); } clang::BlockDecl * @@ -814,7 +816,8 @@ PdbAstBuilder::GetOrCreateBlockDecl(PdbCompilandSymId block_id) { clang::DeclContext *scope = GetParentDeclContext(block_id); - clang::BlockDecl *block_decl = m_clang.CreateBlockDeclaration(scope); + clang::BlockDecl *block_decl = + m_clang.CreateBlockDeclaration(scope, OptionalClangModuleID()); m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl}); DeclStatus status; @@ -831,7 +834,7 @@ clang::VarDecl *PdbAstBuilder::CreateVariableDecl(PdbSymUid uid, CVSymbol sym, clang::QualType qt = GetOrCreateType(var_info.type); clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration( - &scope, var_info.name.str().c_str(), qt); + &scope, OptionalClangModuleID(), var_info.name.str().c_str(), qt); m_uid_to_decl[toOpaqueUid(uid)] = var_decl; DeclStatus status; @@ -876,10 +879,10 @@ PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) { PdbTypeSymId real_type_id{udt.Type, false}; clang::QualType qt = GetOrCreateType(real_type_id); - std::string uname = DropNameScope(udt.Name); + std::string uname = std::string(DropNameScope(udt.Name)); CompilerType ct = m_clang.CreateTypedefType(ToCompilerType(qt), uname.c_str(), - ToCompilerDeclContext(*scope)); + ToCompilerDeclContext(*scope), 0); clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct); DeclStatus status; status.resolved = true; @@ -1012,7 +1015,8 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { proc_name.consume_front("::"); clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration( - parent, proc_name.str().c_str(), func_ct, storage, false); + parent, OptionalClangModuleID(), proc_name.str().c_str(), func_ct, + storage, false); lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0); m_uid_to_decl[toOpaqueUid(func_id)] = function_decl; @@ -1080,8 +1084,8 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id, CompilerType param_type_ct = m_clang.GetType(qt); clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration( - &function_decl, param_name.str().c_str(), param_type_ct, - clang::SC_None, true); + &function_decl, OptionalClangModuleID(), param_name.str().c_str(), + param_type_ct, clang::SC_None, true); lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0); m_uid_to_decl[toOpaqueUid(param_uid)] = param; @@ -1102,11 +1106,11 @@ clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id, Declaration declaration; CompilerType enum_ct = m_clang.CreateEnumerationType( - uname.c_str(), decl_context, declaration, ToCompilerType(underlying_type), - er.isScoped()); + uname.c_str(), decl_context, OptionalClangModuleID(), declaration, + ToCompilerType(underlying_type), er.isScoped()); - ClangASTContext::StartTagDeclarationDefinition(enum_ct); - ClangASTContext::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true); + TypeSystemClang::StartTagDeclarationDefinition(enum_ct); + TypeSystemClang::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true); return clang::QualType::getFromOpaquePtr(enum_ct.GetOpaqueQualType()); } @@ -1334,7 +1338,7 @@ void PdbAstBuilder::ParseDeclsForContext(clang::DeclContext &context) { } CompilerDecl PdbAstBuilder::ToCompilerDecl(clang::Decl &decl) { - return {&m_clang, &decl}; + return m_clang.GetCompilerDecl(&decl); } CompilerType PdbAstBuilder::ToCompilerType(clang::QualType qt) { @@ -1347,7 +1351,7 @@ PdbAstBuilder::ToCompilerDeclContext(clang::DeclContext &context) { } clang::Decl * PdbAstBuilder::FromCompilerDecl(CompilerDecl decl) { - return static_cast<clang::Decl *>(decl.GetOpaqueDecl()); + return ClangUtil::GetDecl(decl); } clang::DeclContext * diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h index a4242e90810d..7bb2584d19a3 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h @@ -6,13 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H -#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" -#include "lldb/Symbol/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" #include "PdbIndex.h" #include "PdbSymUid.h" @@ -51,7 +51,7 @@ struct DeclStatus { class PdbAstBuilder { public: // Constructors and Destructors - PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang); + PdbAstBuilder(ObjectFile &obj, PdbIndex &index, TypeSystemClang &clang); lldb_private::CompilerDeclContext GetTranslationUnitDecl(); @@ -80,7 +80,7 @@ public: clang::Decl *FromCompilerDecl(CompilerDecl decl); clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context); - ClangASTContext &clang() { return m_clang; } + TypeSystemClang &clang() { return m_clang; } ClangASTImporter &importer() { return m_importer; } void Dump(Stream &stream); @@ -129,7 +129,7 @@ private: clang::QualType CreateSimpleType(TypeIndex ti); PdbIndex &m_index; - ClangASTContext &m_clang; + TypeSystemClang &m_clang; ClangASTImporter m_importer; @@ -142,4 +142,4 @@ private: } // namespace npdb } // namespace lldb_private -#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp index a7bc23519710..ecae767e4469 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp @@ -1,4 +1,4 @@ -//===-- PdbFPOProgramToDWARFExpression.cpp ----------------------*- C++ -*-===// +//===-- PdbFPOProgramToDWARFExpression.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h index 107e26fb04cb..fb979b877143 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Plugins_SymbolFile_PDB_PDBFPOProgramToDWARFExpression_h_ -#define lldb_Plugins_SymbolFile_PDB_PDBFPOProgramToDWARFExpression_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBFPOPROGRAMTODWARFEXPRESSION_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBFPOPROGRAMTODWARFEXPRESSION_H #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp index ba9a95b16e18..6ac6cc2da29b 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp @@ -1,4 +1,4 @@ -//===-- PdbIndex.cpp --------------------------------------------*- C++ -*-===// +//===-- PdbIndex.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h index b30e7870bbdb..ccc3cc2f4538 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H -#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBINDEX_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBINDEX_H #include "lldb/lldb-types.h" #include "llvm/ADT/IntervalMap.h" diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp index e5ad23f813eb..67397d707110 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp @@ -1,4 +1,4 @@ -//===-- PdbSymUid.cpp -------------------------------------------*- C++ -*-===// +//===-- PdbSymUid.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h index 7252d63c1ab4..3accd38d710e 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h @@ -14,8 +14,8 @@ // access to the compile unit's information. //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H -#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBSYMUID_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBSYMUID_H #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp index fc047e25a2f4..b5a16447d9cf 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp @@ -1,4 +1,4 @@ -//===-- PdbUtil.cpp ---------------------------------------------*- C++ -*-===// +//===-- PdbUtil.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h index 6f675b56dca4..c309c5c8ea1c 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H -#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBUTIL_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBUTIL_H #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/Variable.h" diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 370c339fb74b..cce06473d92f 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFileNativePDB.cpp ---------------------------------*- C++ -*-===// +//===-- SymbolFileNativePDB.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,13 +14,13 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/Type.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/StreamBuffer.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/ObjectFile.h" @@ -129,17 +129,18 @@ loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) { // If it doesn't have a debug directory, fail. llvm::StringRef pdb_file; - auto ec = obj->getDebugPDBInfo(pdb_info, pdb_file); - if (ec) + if (llvm::Error e = obj->getDebugPDBInfo(pdb_info, pdb_file)) { + consumeError(std::move(e)); return nullptr; + } // if the file doesn't exist, is not a pdb, or doesn't have a matching guid, // fail. llvm::file_magic magic; - ec = llvm::identify_magic(pdb_file, magic); + auto ec = llvm::identify_magic(pdb_file, magic); if (ec || magic != llvm::file_magic::pdb) return nullptr; - std::unique_ptr<PDBFile> pdb = loadPDBFile(pdb_file, allocator); + std::unique_ptr<PDBFile> pdb = loadPDBFile(std::string(pdb_file), allocator); if (!pdb) return nullptr; @@ -331,7 +332,7 @@ void SymbolFileNativePDB::InitializeObject() { std::move(err), "Failed to initialize"); } else { ts_or_err->SetSymbolFile(this); - auto *clang = llvm::cast_or_null<ClangASTContext>(&ts_or_err.get()); + auto *clang = llvm::cast_or_null<TypeSystemClang>(&ts_or_err.get()); lldbassert(clang); m_ast = std::make_unique<PdbAstBuilder>(*m_objfile_sp, *m_index, *clang); } @@ -452,7 +453,7 @@ lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id, std::string name; if (mr.ModifiedType.isSimple()) - name = GetSimpleTypeName(mr.ModifiedType.getSimpleKind()); + name = std::string(GetSimpleTypeName(mr.ModifiedType.getSimpleKind())); else name = computeTypeName(stream.typeCollection(), mr.ModifiedType); Declaration decl; @@ -532,14 +533,14 @@ static std::string GetUnqualifiedTypeName(const TagRecord &record) { MSVCUndecoratedNameParser parser(record.Name); llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); - return specs.back().GetBaseName(); + return std::string(specs.back().GetBaseName()); } llvm::ms_demangle::Demangler demangler; StringView sv(record.UniqueName.begin(), record.UniqueName.size()); llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv); if (demangler.Error) - return record.Name; + return std::string(record.Name); llvm::ms_demangle::IdentifierNode *idn = ttn->QualifiedName->getUnqualifiedIdentifier(); @@ -1171,7 +1172,7 @@ size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) { void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); } void SymbolFileNativePDB::FindGlobalVariables( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>; @@ -1198,7 +1199,7 @@ void SymbolFileNativePDB::FindGlobalVariables( } void SymbolFileNativePDB::FindFunctions( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); @@ -1236,7 +1237,7 @@ void SymbolFileNativePDB::FindFunctions(const RegularExpression ®ex, SymbolContextList &sc_list) {} void SymbolFileNativePDB::FindTypes( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); @@ -1563,7 +1564,7 @@ void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, CompilerDeclContext SymbolFileNativePDB::FindNamespace(ConstString name, - const CompilerDeclContext *parent_decl_ctx) { + const CompilerDeclContext &parent_decl_ctx) { return {}; } diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index a37de0f58ef3..bf5718e11a19 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H -#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H #include "lldb/Symbol/SymbolFile.h" @@ -100,7 +100,7 @@ public: size_t ParseBlocksRecursive(Function &func) override; void FindGlobalVariables(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) override; @@ -129,14 +129,14 @@ public: TypeList &type_list) override; void FindFunctions(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) override; void FindFunctions(const RegularExpression ®ex, bool include_inlines, SymbolContextList &sc_list) override; - void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx, + void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) override; @@ -150,7 +150,7 @@ public: CompilerDeclContext FindNamespace(ConstString name, - const CompilerDeclContext *parent_decl_ctx) override; + const CompilerDeclContext &parent_decl_ctx) override; ConstString GetPluginName() override; @@ -246,4 +246,4 @@ private: } // namespace npdb } // namespace lldb_private -#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp index 7221144407c1..c8fb46c75034 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp @@ -5,15 +5,18 @@ #include "PdbSymUid.h" #include "PdbUtil.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Symbol/Type.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" +#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" #include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" @@ -29,10 +32,10 @@ UdtRecordCompleter::UdtRecordCompleter(PdbTypeSymId id, CompilerType &derived_ct, clang::TagDecl &tag_decl, PdbAstBuilder &ast_builder, - TpiStream &tpi) + PdbIndex &index) : m_id(id), m_derived_ct(derived_ct), m_tag_decl(tag_decl), - m_ast_builder(ast_builder), m_tpi(tpi) { - CVType cvt = m_tpi.getType(m_id.index); + m_ast_builder(ast_builder), m_index(index) { + CVType cvt = m_index.tpi().getType(m_id.index); switch (cvt.kind()) { case LF_ENUM: llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, m_cvr.er)); @@ -55,7 +58,7 @@ clang::QualType UdtRecordCompleter::AddBaseClassForTypeIndex( PdbTypeSymId type_id(ti); clang::QualType qt = m_ast_builder.GetOrCreateType(type_id); - CVType udt_cvt = m_tpi.getType(ti); + CVType udt_cvt = m_index.tpi().getType(ti); std::unique_ptr<clang::CXXBaseSpecifier> base_spec = m_ast_builder.clang().CreateBaseClassSpecifier( @@ -128,9 +131,70 @@ Error UdtRecordCompleter::visitKnownMember( lldb::AccessType access = TranslateMemberAccess(static_data_member.getAccess()); - ClangASTContext::AddVariableToRecordType( + auto decl = TypeSystemClang::AddVariableToRecordType( m_derived_ct, static_data_member.Name, member_ct, access); + // Static constant members may be a const[expr] declaration. + // Query the symbol's value as the variable initializer if valid. + if (member_ct.IsConst()) { + std::string qual_name = decl->getQualifiedNameAsString(); + + auto results = + m_index.globals().findRecordsByName(qual_name, m_index.symrecords()); + + for (const auto &result : results) { + if (result.second.kind() == SymbolKind::S_CONSTANT) { + ConstantSym constant(SymbolRecordKind::ConstantSym); + cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(result.second, + constant)); + + clang::QualType qual_type = decl->getType(); + unsigned type_width = decl->getASTContext().getIntWidth(qual_type); + unsigned constant_width = constant.Value.getBitWidth(); + + if (qual_type->isIntegralOrEnumerationType()) { + if (type_width >= constant_width) { + TypeSystemClang::SetIntegerInitializerForVariable( + decl, constant.Value.extOrTrunc(type_width)); + } else { + LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " + "which resolves to a wider constant value ({4} bits). " + "Ignoring constant.", + m_derived_ct.GetTypeName(), static_data_member.Name, + member_ct.GetTypeName(), type_width, constant_width); + } + } else { + lldb::BasicType basic_type_enum = member_ct.GetBasicTypeEnumeration(); + switch (basic_type_enum) { + case lldb::eBasicTypeFloat: + case lldb::eBasicTypeDouble: + case lldb::eBasicTypeLongDouble: + if (type_width == constant_width) { + TypeSystemClang::SetFloatingInitializerForVariable( + decl, basic_type_enum == lldb::eBasicTypeFloat + ? llvm::APFloat(constant.Value.bitsToFloat()) + : llvm::APFloat(constant.Value.bitsToDouble())); + decl->setConstexpr(true); + } else { + LLDB_LOG( + GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " + "which resolves to a constant value of mismatched width " + "({4} bits). Ignoring constant.", + m_derived_ct.GetTypeName(), static_data_member.Name, + member_ct.GetTypeName(), type_width, constant_width); + } + break; + default: + break; + } + } + break; + } + } + } + // FIXME: Add a PdbSymUid namespace for field list members and update // the m_uid_to_decl map with this decl. return Error::success(); @@ -149,7 +213,7 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, TypeIndex ti(data_member.Type); if (!ti.isSimple()) { - CVType cvt = m_tpi.getType(ti); + CVType cvt = m_index.tpi().getType(ti); if (cvt.kind() == LF_BITFIELD) { BitFieldRecord bfr; llvm::cantFail(TypeDeserializer::deserializeAs<BitFieldRecord>(cvt, bfr)); @@ -164,7 +228,7 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, lldb::AccessType access = TranslateMemberAccess(data_member.getAccess()); - clang::FieldDecl *decl = ClangASTContext::AddFieldToRecordType( + clang::FieldDecl *decl = TypeSystemClang::AddFieldToRecordType( m_derived_ct, data_member.Name, m_ast_builder.ToCompilerType(member_qt), access, bitfield_width); // FIXME: Add a PdbSymUid namespace for field list members and update @@ -187,7 +251,7 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, OverloadedMethodRecord &overloaded) { TypeIndex method_list_idx = overloaded.MethodList; - CVType method_list_type = m_tpi.getType(method_list_idx); + CVType method_list_type = m_index.tpi().getType(method_list_idx); assert(method_list_type.kind() == LF_METHODLIST); MethodOverloadListRecord method_list; @@ -223,12 +287,12 @@ void UdtRecordCompleter::complete() { for (auto &ib : m_bases) bases.push_back(std::move(ib.second)); - ClangASTContext &clang = m_ast_builder.clang(); + TypeSystemClang &clang = m_ast_builder.clang(); clang.TransferBaseClasses(m_derived_ct.GetOpaqueQualType(), std::move(bases)); clang.AddMethodOverridesForCXXRecordType(m_derived_ct.GetOpaqueQualType()); - ClangASTContext::BuildIndirectFields(m_derived_ct); - ClangASTContext::CompleteTagDeclarationDefinition(m_derived_ct); + TypeSystemClang::BuildIndirectFields(m_derived_ct); + TypeSystemClang::CompleteTagDeclarationDefinition(m_derived_ct); if (auto *record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(&m_tag_decl)) { m_ast_builder.importer().SetRecordLayout(record_decl, m_layout); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h index 55397582209b..ae7e47c82fe5 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h @@ -6,10 +6,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H -#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H -#include "lldb/Symbol/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" @@ -25,6 +25,7 @@ class TagDecl; namespace llvm { namespace pdb { class TpiStream; +class GlobalsStream; } } // namespace llvm @@ -33,6 +34,7 @@ class Type; class CompilerType; namespace npdb { class PdbAstBuilder; +class PdbIndex; class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks { using IndexedBase = @@ -49,14 +51,14 @@ class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks { CompilerType &m_derived_ct; clang::TagDecl &m_tag_decl; PdbAstBuilder &m_ast_builder; - llvm::pdb::TpiStream &m_tpi; + PdbIndex &m_index; std::vector<IndexedBase> m_bases; ClangASTImporter::LayoutInfo m_layout; public: UdtRecordCompleter(PdbTypeSymId id, CompilerType &derived_ct, clang::TagDecl &tag_decl, PdbAstBuilder &ast_builder, - llvm::pdb::TpiStream &tpi); + PdbIndex &index); #define MEMBER_RECORD(EnumName, EnumVal, Name) \ llvm::Error visitKnownMember(llvm::codeview::CVMemberRecord &CVR, \ @@ -79,4 +81,4 @@ private: } // namespace npdb } // namespace lldb_private -#endif // LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp index 6b2dbd9e1e5a..d87926a6588f 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -1,4 +1,4 @@ -//===-- PDBASTParser.cpp ----------------------------------------*- C++ -*-===// +//===-- PDBASTParser.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,10 +14,10 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Module.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangASTMetadata.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/Declaration.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/TypeMap.h" @@ -100,7 +100,7 @@ static lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) { } static CompilerType -GetBuiltinTypeForPDBEncodingAndBitSize(ClangASTContext &clang_ast, +GetBuiltinTypeForPDBEncodingAndBitSize(TypeSystemClang &clang_ast, const PDBSymbolTypeBuiltin &pdb_type, Encoding encoding, uint32_t width) { clang::ASTContext &ast = clang_ast.getASTContext(); @@ -353,7 +353,7 @@ static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) { } } -PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {} +PDBASTParser::PDBASTParser(lldb_private::TypeSystemClang &ast) : m_ast(ast) {} PDBASTParser::~PDBASTParser() {} @@ -386,7 +386,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { return nullptr; // Ignore unnamed-tag UDTs. - std::string name = MSVCUndecoratedNameParser::DropScope(udt->getName()); + std::string name = + std::string(MSVCUndecoratedNameParser::DropScope(udt->getName())); if (name.empty()) return nullptr; @@ -408,9 +409,9 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { metadata.SetUserID(type.getSymIndexId()); metadata.SetIsDynamicCXXType(false); - clang_type = - m_ast.CreateRecordType(decl_context, access, name, tag_type_kind, - lldb::eLanguageTypeC_plus_plus, &metadata); + clang_type = m_ast.CreateRecordType( + decl_context, OptionalClangModuleID(), access, name, tag_type_kind, + lldb::eLanguageTypeC_plus_plus, &metadata); assert(clang_type.IsValid()); auto record_decl = @@ -422,15 +423,15 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { m_ast.getASTContext(), GetMSInheritance(*udt)); record_decl->addAttr(inheritance_attr); - ClangASTContext::StartTagDeclarationDefinition(clang_type); + TypeSystemClang::StartTagDeclarationDefinition(clang_type); auto children = udt->findAllChildren(); if (!children || children->getChildCount() == 0) { // PDB does not have symbol of forwarder. We assume we get an udt w/o // any fields. Just complete it at this point. - ClangASTContext::CompleteTagDeclarationDefinition(clang_type); + TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); - ClangASTContext::SetHasExternalStorage(clang_type.GetOpaqueQualType(), + TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(), false); type_resolve_state = Type::ResolveState::Full; @@ -439,7 +440,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { // an endless recursion in CompleteTypeFromUdt function. m_forward_decl_to_uid[record_decl] = type.getSymIndexId(); - ClangASTContext::SetHasExternalStorage(clang_type.GetOpaqueQualType(), + TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(), true); type_resolve_state = Type::ResolveState::Forward; @@ -465,7 +466,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { assert(enum_type); std::string name = - MSVCUndecoratedNameParser::DropScope(enum_type->getName()); + std::string(MSVCUndecoratedNameParser::DropScope(enum_type->getName())); auto decl_context = GetDeclContextContainingSymbol(type); uint64_t bytes = enum_type->getLength(); @@ -496,10 +497,11 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { // Class). Set it false for now. bool isScoped = false; - ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context, decl, + ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context, + OptionalClangModuleID(), decl, builtin_type, isScoped); - auto enum_decl = ClangASTContext::GetAsEnumDecl(ast_enum); + auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum); assert(enum_decl); m_uid_to_decl[type.getSymIndexId()] = enum_decl; @@ -512,8 +514,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { } } - if (ClangASTContext::StartTagDeclarationDefinition(ast_enum)) - ClangASTContext::CompleteTagDeclarationDefinition(ast_enum); + if (TypeSystemClang::StartTagDeclarationDefinition(ast_enum)) + TypeSystemClang::CompleteTagDeclarationDefinition(ast_enum); } if (enum_type->isConstType()) @@ -538,7 +540,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { return nullptr; std::string name = - MSVCUndecoratedNameParser::DropScope(type_def->getName()); + std::string(MSVCUndecoratedNameParser::DropScope(type_def->getName())); auto decl_ctx = GetDeclContextContainingSymbol(type); // Check if such a typedef already exists in the current context @@ -549,11 +551,11 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { CompilerType target_ast_type = target_type->GetFullCompilerType(); ast_typedef = m_ast.CreateTypedefType( - target_ast_type, name.c_str(), m_ast.CreateDeclContext(decl_ctx)); + target_ast_type, name.c_str(), m_ast.CreateDeclContext(decl_ctx), 0); if (!ast_typedef) return nullptr; - auto typedef_decl = ClangASTContext::GetAsTypedefDecl(ast_typedef); + auto typedef_decl = TypeSystemClang::GetAsTypedefDecl(ast_typedef); assert(typedef_decl); m_uid_to_decl[type.getSymIndexId()] = typedef_decl; } @@ -587,7 +589,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { return nullptr; func_sig = sig.release(); // Function type is named. - name = MSVCUndecoratedNameParser::DropScope(pdb_func->getName()); + name = std::string( + MSVCUndecoratedNameParser::DropScope(pdb_func->getName())); } else if (auto pdb_func_sig = llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) { func_sig = const_cast<PDBSymbolTypeFunctionSig *>(pdb_func_sig); @@ -660,10 +663,10 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { CompilerType element_ast_type = element_type->GetForwardCompilerType(); // If element type is UDT, it needs to be complete. - if (ClangASTContext::IsCXXClassType(element_ast_type) && + if (TypeSystemClang::IsCXXClassType(element_ast_type) && !element_ast_type.GetCompleteType()) { - if (ClangASTContext::StartTagDeclarationDefinition(element_ast_type)) { - ClangASTContext::CompleteTagDeclarationDefinition(element_ast_type); + if (TypeSystemClang::StartTagDeclarationDefinition(element_ast_type)) { + TypeSystemClang::CompleteTagDeclarationDefinition(element_ast_type); } else { // We are not able to start defintion. return nullptr; @@ -721,7 +724,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { assert(class_parent_type); CompilerType pointer_ast_type; - pointer_ast_type = ClangASTContext::CreateMemberPointerType( + pointer_ast_type = TypeSystemClang::CreateMemberPointerType( class_parent_type->GetLayoutCompilerType(), pointee_type->GetForwardCompilerType()); assert(pointer_ast_type); @@ -787,7 +790,7 @@ bool PDBASTParser::CompleteTypeFromPDB( m_forward_decl_to_uid.erase(uid_it); - ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), + TypeSystemClang::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), false); switch (symbol->getSymTag()) { @@ -887,7 +890,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { if (auto parent_decl = llvm::dyn_cast_or_null<clang::TagDecl>(decl_context)) m_ast.GetCompleteDecl(parent_decl); - std::string name = MSVCUndecoratedNameParser::DropScope(data->getName()); + std::string name = + std::string(MSVCUndecoratedNameParser::DropScope(data->getName())); // Check if the current context already contains the symbol with the name. clang::Decl *decl = @@ -898,7 +902,7 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { return nullptr; decl = m_ast.CreateVariableDeclaration( - decl_context, name.c_str(), + decl_context, OptionalClangModuleID(), name.c_str(), ClangUtil::GetQualType(type->GetLayoutCompilerType())); } @@ -913,7 +917,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { auto decl_context = GetDeclContextContainingSymbol(symbol); assert(decl_context); - std::string name = MSVCUndecoratedNameParser::DropScope(func->getName()); + std::string name = + std::string(MSVCUndecoratedNameParser::DropScope(func->getName())); Type *type = symbol_file->ResolveTypeUID(sym_id); if (!type) @@ -923,8 +928,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { : clang::StorageClass::SC_None; auto decl = m_ast.CreateFunctionDeclaration( - decl_context, name.c_str(), type->GetForwardCompilerType(), storage, - func->hasInlineAttribute()); + decl_context, OptionalClangModuleID(), name.c_str(), + type->GetForwardCompilerType(), storage, func->hasInlineAttribute()); std::vector<clang::ParmVarDecl *> params; if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) { @@ -937,8 +942,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { continue; clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration( - decl, nullptr, arg_type->GetForwardCompilerType(), - clang::SC_None, true); + decl, OptionalClangModuleID(), nullptr, + arg_type->GetForwardCompilerType(), clang::SC_None, true); if (param) params.push_back(param); } @@ -1047,13 +1052,13 @@ clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol( // or a type. We check it to avoid fake namespaces such as `__l2': // `N0::N1::CClass::PrivateFunc::__l2::InnerFuncStruct' if (!has_type_or_function_parent) { - std::string namespace_name = specs[i].GetBaseName(); + std::string namespace_name = std::string(specs[i].GetBaseName()); const char *namespace_name_c_str = IsAnonymousNamespaceName(namespace_name) ? nullptr : namespace_name.data(); clang::NamespaceDecl *namespace_decl = - m_ast.GetUniqueNamespaceDeclaration(namespace_name_c_str, - curr_context); + m_ast.GetUniqueNamespaceDeclaration( + namespace_name_c_str, curr_context, OptionalClangModuleID()); m_parent_to_namespaces[curr_context].insert(namespace_decl); m_namespaces.insert(namespace_decl); @@ -1119,7 +1124,8 @@ bool PDBASTParser::AddEnumValue(CompilerType enum_type, const PDBSymbolData &enum_value) { Declaration decl; Variant v = enum_value.getValue(); - std::string name = MSVCUndecoratedNameParser::DropScope(enum_value.getName()); + std::string name = + std::string(MSVCUndecoratedNameParser::DropScope(enum_value.getName())); int64_t raw_value; switch (v.Type) { case PDB_VariantType::Int8: @@ -1149,8 +1155,7 @@ bool PDBASTParser::AddEnumValue(CompilerType enum_type, default: return false; } - CompilerType underlying_type = - m_ast.GetEnumerationIntegerType(enum_type.GetOpaqueQualType()); + CompilerType underlying_type = m_ast.GetEnumerationIntegerType(enum_type); uint32_t byte_size = m_ast.getASTContext().getTypeSize( ClangUtil::GetQualType(underlying_type)); auto enum_constant_decl = m_ast.AddEnumerationValueToEnumerationType( @@ -1190,8 +1195,8 @@ bool PDBASTParser::CompleteTypeFromUDT( AddRecordMethods(symbol_file, compiler_type, *methods_enum); m_ast.AddMethodOverridesForCXXRecordType(compiler_type.GetOpaqueQualType()); - ClangASTContext::BuildIndirectFields(compiler_type); - ClangASTContext::CompleteTagDeclarationDefinition(compiler_type); + TypeSystemClang::BuildIndirectFields(compiler_type); + TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type); clang::CXXRecordDecl *record_decl = m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType()); @@ -1225,8 +1230,8 @@ void PDBASTParser::AddRecordMembers( "which does not have a complete definition.", record_type.GetTypeName().GetCString(), member_name.c_str(), member_comp_type.GetTypeName().GetCString()); - if (ClangASTContext::StartTagDeclarationDefinition(member_comp_type)) - ClangASTContext::CompleteTagDeclarationDefinition(member_comp_type); + if (TypeSystemClang::StartTagDeclarationDefinition(member_comp_type)) + TypeSystemClang::CompleteTagDeclarationDefinition(member_comp_type); } auto access = TranslateMemberAccess(member->getAccess()); @@ -1239,7 +1244,7 @@ void PDBASTParser::AddRecordMembers( if (location_type == PDB_LocType::ThisRel) bit_size *= 8; - auto decl = ClangASTContext::AddFieldToRecordType( + auto decl = TypeSystemClang::AddFieldToRecordType( record_type, member_name.c_str(), member_comp_type, access, bit_size); if (!decl) continue; @@ -1255,11 +1260,57 @@ void PDBASTParser::AddRecordMembers( break; } case PDB_DataKind::StaticMember: { - auto decl = ClangASTContext::AddVariableToRecordType( + auto decl = TypeSystemClang::AddVariableToRecordType( record_type, member_name.c_str(), member_comp_type, access); if (!decl) continue; + // Static constant members may be a const[expr] declaration. + // Query the symbol's value as the variable initializer if valid. + if (member_comp_type.IsConst()) { + auto value = member->getValue(); + clang::QualType qual_type = decl->getType(); + unsigned type_width = m_ast.getASTContext().getIntWidth(qual_type); + unsigned constant_width = value.getBitWidth(); + + if (qual_type->isIntegralOrEnumerationType()) { + if (type_width >= constant_width) { + TypeSystemClang::SetIntegerInitializerForVariable( + decl, value.toAPSInt().extOrTrunc(type_width)); + } else { + LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " + "which resolves to a wider constant value ({4} bits). " + "Ignoring constant.", + record_type.GetTypeName(), member_name, + member_comp_type.GetTypeName(), type_width, + constant_width); + } + } else { + switch (member_comp_type.GetBasicTypeEnumeration()) { + case lldb::eBasicTypeFloat: + case lldb::eBasicTypeDouble: + case lldb::eBasicTypeLongDouble: + if (type_width == constant_width) { + TypeSystemClang::SetFloatingInitializerForVariable( + decl, value.toAPFloat()); + decl->setConstexpr(true); + } else { + LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + "Class '{0}' has a member '{1}' of type '{2}' ({3} " + "bits) which resolves to a constant value of mismatched " + "width ({4} bits). Ignoring constant.", + record_type.GetTypeName(), member_name, + member_comp_type.GetTypeName(), type_width, + constant_width); + } + break; + default: + break; + } + } + } + m_uid_to_decl[member->getSymIndexId()] = decl; break; @@ -1289,8 +1340,8 @@ void PDBASTParser::AddRecordBases( "which does not have a complete definition.", record_type.GetTypeName().GetCString(), base_comp_type.GetTypeName().GetCString()); - if (ClangASTContext::StartTagDeclarationDefinition(base_comp_type)) - ClangASTContext::CompleteTagDeclarationDefinition(base_comp_type); + if (TypeSystemClang::StartTagDeclarationDefinition(base_comp_type)) + TypeSystemClang::CompleteTagDeclarationDefinition(base_comp_type); } auto access = TranslateMemberAccess(base->getAccess()); @@ -1333,7 +1384,8 @@ clang::CXXMethodDecl * PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file, lldb_private::CompilerType &record_type, const llvm::pdb::PDBSymbolFunc &method) const { - std::string name = MSVCUndecoratedNameParser::DropScope(method.getName()); + std::string name = + std::string(MSVCUndecoratedNameParser::DropScope(method.getName())); Type *method_type = symbol_file.ResolveTypeUID(method.getSymIndexId()); // MSVC specific __vecDelDtor. @@ -1346,8 +1398,8 @@ PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file, ":: Class '%s' has a method '%s' whose type cannot be completed.", record_type.GetTypeName().GetCString(), method_comp_type.GetTypeName().GetCString()); - if (ClangASTContext::StartTagDeclarationDefinition(method_comp_type)) - ClangASTContext::CompleteTagDeclarationDefinition(method_comp_type); + if (TypeSystemClang::StartTagDeclarationDefinition(method_comp_type)) + TypeSystemClang::CompleteTagDeclarationDefinition(method_comp_type); } AccessType access = TranslateMemberAccess(method.getAccess()); diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h index 9221d42b2020..06f317f4c4d9 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h +++ b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H -#define LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H #include "lldb/lldb-forward.h" -#include "lldb/Symbol/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" class SymbolFilePDB; @@ -23,7 +23,7 @@ class RecordDecl; } // namespace clang namespace lldb_private { -class ClangASTContext; +class TypeSystemClang; class CompilerType; } // namespace lldb_private @@ -42,7 +42,7 @@ class PDBSymbolTypeUDT; class PDBASTParser { public: - PDBASTParser(lldb_private::ClangASTContext &ast); + PDBASTParser(lldb_private::TypeSystemClang &ast); ~PDBASTParser(); lldb::TypeSP CreateLLDBTypeFromPDBType(const llvm::pdb::PDBSymbol &type); @@ -103,7 +103,7 @@ private: lldb_private::CompilerType &record_type, const llvm::pdb::PDBSymbolFunc &method) const; - lldb_private::ClangASTContext &m_ast; + lldb_private::TypeSystemClang &m_ast; lldb_private::ClangASTImporter m_ast_importer; CXXRecordDeclToUidMap m_forward_decl_to_uid; @@ -113,4 +113,4 @@ private: DeclContextToUidMap m_decl_context_to_uid; }; -#endif // LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp index 42bf1b34c956..330188e29f00 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp @@ -1,4 +1,4 @@ -//===-- PDBLocationToDWARFExpression.cpp ------------------------*- C++ -*-===// +//===-- PDBLocationToDWARFExpression.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h b/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h index 2e9d1386d537..fd0fef03e2c8 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h +++ b/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Plugins_SymbolFile_PDB_PDBLocationToDWARFExpression_h_ -#define lldb_Plugins_SymbolFile_PDB_PDBLocationToDWARFExpression_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBLOCATIONTODWARFEXPRESSION_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBLOCATIONTODWARFEXPRESSION_H #include "lldb/Core/Module.h" #include "lldb/Symbol/Variable.h" diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 917ab68af418..1001514edede 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFilePDB.cpp ---------------------------------------*- C++ -*-===// +//===-- SymbolFilePDB.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,9 +13,9 @@ #include "clang/Lex/Lexer.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/ObjectFile.h" @@ -58,6 +58,8 @@ using namespace lldb; using namespace lldb_private; using namespace llvm::pdb; +LLDB_PLUGIN_DEFINE(SymbolFilePDB) + char SymbolFilePDB::ID; namespace { @@ -310,8 +312,8 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func, return nullptr; } - ClangASTContext *clang_type_system = - llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); + TypeSystemClang *clang_type_system = + llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get()); if (!clang_type_system) return nullptr; clang_type_system->GetPDBParser()->GetDeclForSymbol(pdb_func); @@ -560,8 +562,8 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { return nullptr; } - ClangASTContext *clang_type_system = - llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); + TypeSystemClang *clang_type_system = + llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get()); if (!clang_type_system) return nullptr; PDBASTParser *pdb = clang_type_system->GetPDBParser(); @@ -597,8 +599,8 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) { return false; } - ClangASTContext *clang_ast_ctx = - llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); + TypeSystemClang *clang_ast_ctx = + llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get()); if (!clang_ast_ctx) return false; @@ -619,8 +621,8 @@ lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) { return CompilerDecl(); } - ClangASTContext *clang_ast_ctx = - llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); + TypeSystemClang *clang_ast_ctx = + llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get()); if (!clang_ast_ctx) return CompilerDecl(); @@ -636,7 +638,7 @@ lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) { if (!decl) return CompilerDecl(); - return CompilerDecl(clang_ast_ctx, decl); + return clang_ast_ctx->GetCompilerDecl(decl); } lldb_private::CompilerDeclContext @@ -649,8 +651,8 @@ SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) { return CompilerDeclContext(); } - ClangASTContext *clang_ast_ctx = - llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); + TypeSystemClang *clang_ast_ctx = + llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get()); if (!clang_ast_ctx) return CompilerDeclContext(); @@ -679,8 +681,8 @@ SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { return CompilerDeclContext(); } - ClangASTContext *clang_ast_ctx = - llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); + TypeSystemClang *clang_ast_ctx = + llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get()); if (!clang_ast_ctx) return CompilerDeclContext(); @@ -708,8 +710,8 @@ void SymbolFilePDB::ParseDeclsForContext( return; } - ClangASTContext *clang_ast_ctx = - llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); + TypeSystemClang *clang_ast_ctx = + llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get()); if (!clang_ast_ctx) return; @@ -1096,8 +1098,7 @@ SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc, } void SymbolFilePDB::FindGlobalVariables( - lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, lldb_private::VariableList &variables) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) @@ -1129,8 +1130,8 @@ void SymbolFilePDB::FindGlobalVariables( if (sc.comp_unit == nullptr) continue; - if (parent_decl_ctx && GetDeclContextContainingUID( - result->getSymIndexId()) != *parent_decl_ctx) + if (parent_decl_ctx.IsValid() && + GetDeclContextContainingUID(result->getSymIndexId()) != parent_decl_ctx) continue; ParseVariables(sc, *pdb_data, &variables); @@ -1225,7 +1226,7 @@ void SymbolFilePDB::CacheFunctionNames() { // To search a method name, like NS::Class:MemberFunc, LLDB searches // its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does - // not have inforamtion of this, we extract base names and cache them + // not have information of this, we extract base names and cache them // by our own effort. llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name); if (!basename.empty()) @@ -1294,7 +1295,7 @@ void SymbolFilePDB::CacheFunctionNames() { void SymbolFilePDB::FindFunctions( lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, bool include_inlines, lldb_private::SymbolContextList &sc_list) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); @@ -1323,8 +1324,8 @@ void SymbolFilePDB::FindFunctions( if (resolved_ids.find(id) != resolved_ids.end()) continue; - if (parent_decl_ctx && - GetDeclContextContainingUID(id) != *parent_decl_ctx) + if (parent_decl_ctx.IsValid() && + GetDeclContextContainingUID(id) != parent_decl_ctx) continue; if (ResolveFunction(id, include_inlines, sc_list)) @@ -1422,8 +1423,7 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) { } void SymbolFilePDB::FindTypes( - lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap &types) { @@ -1450,7 +1450,7 @@ void SymbolFilePDB::DumpClangAST(Stream &s) { } auto *clang_type_system = - llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); + llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get()); if (!clang_type_system) return; clang_type_system->Dump(s); @@ -1513,7 +1513,7 @@ void SymbolFilePDB::FindTypesByRegex( void SymbolFilePDB::FindTypesByName( llvm::StringRef name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, lldb_private::TypeMap &types) { std::unique_ptr<IPDBEnumSymbols> results; if (name.empty()) @@ -1548,8 +1548,8 @@ void SymbolFilePDB::FindTypesByName( if (!ResolveTypeUID(result->getSymIndexId())) continue; - if (parent_decl_ctx && GetDeclContextContainingUID( - result->getSymIndexId()) != *parent_decl_ctx) + if (parent_decl_ctx.IsValid() && + GetDeclContextContainingUID(result->getSymIndexId()) != parent_decl_ctx) continue; auto iter = m_types.find(result->getSymIndexId()); @@ -1663,17 +1663,16 @@ PDBASTParser *SymbolFilePDB::GetPDBAstParser() { } auto *clang_type_system = - llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); + llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get()); if (!clang_type_system) return nullptr; return clang_type_system->GetPDBParser(); } - -lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace( - lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx) { +lldb_private::CompilerDeclContext +SymbolFilePDB::FindNamespace(lldb_private::ConstString name, + const CompilerDeclContext &parent_decl_ctx) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); @@ -1685,7 +1684,7 @@ lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace( } auto *clang_type_system = - llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); + llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get()); if (!clang_type_system) return CompilerDeclContext(); @@ -1696,7 +1695,7 @@ lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace( clang::DeclContext *decl_context = nullptr; if (parent_decl_ctx) decl_context = static_cast<clang::DeclContext *>( - parent_decl_ctx->GetOpaqueDeclContext()); + parent_decl_ctx.GetOpaqueDeclContext()); auto namespace_decl = pdb->FindNamespaceDecl(decl_context, name.GetStringRef()); @@ -1817,7 +1816,7 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit, prev_source_idx, false, false, false, false, true); line_table->InsertSequence(sequence.release()); - sequence.reset(line_table->CreateLineSequenceContainer()); + sequence = line_table->CreateLineSequenceContainer(); } if (ShouldAddLine(match_line, lno, length)) { @@ -1854,7 +1853,7 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit, prev_source_idx, false, false, false, false, true); } - line_table->InsertSequence(sequence.release()); + line_table->InsertSequence(sequence.get()); } if (line_table->GetSize()) { @@ -1940,18 +1939,17 @@ SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) { mangled.SetMangledName(ConstString(func_decorated_name)); // For MSVC, format of C funciton's decorated name depends on calling - // conventon. Unfortunately none of the format is recognized by current + // convention. Unfortunately none of the format is recognized by current // LLDB. For example, `_purecall` is a __cdecl C function. From PDB, // `__purecall` is retrieved as both its decorated and undecorated name // (using PDBSymbolFunc::getUndecoratedName method). However `__purecall` // string is not treated as mangled in LLDB (neither `?` nor `_Z` prefix). // Mangled::GetDemangledName method will fail internally and caches an - // empty string as its undecorated name. So we will face a contradition + // empty string as its undecorated name. So we will face a contradiction // here for the same symbol: // non-empty undecorated name from PDB // empty undecorated name from LLDB - if (!func_undecorated_name.empty() && - mangled.GetDemangledName(mangled.GuessLanguage()).IsEmpty()) + if (!func_undecorated_name.empty() && mangled.GetDemangledName().IsEmpty()) mangled.SetDemangledName(ConstString(func_undecorated_name)); // LLDB uses several flags to control how a C++ decorated name is @@ -1960,8 +1958,7 @@ SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) { // PDB source unless we also apply same flags in getting undecorated // name through PDBSymbolFunc::getUndecoratedNameEx method. if (!func_undecorated_name.empty() && - mangled.GetDemangledName(mangled.GuessLanguage()) != - ConstString(func_undecorated_name)) + mangled.GetDemangledName() != ConstString(func_undecorated_name)) mangled.SetDemangledName(ConstString(func_undecorated_name)); } else if (!func_undecorated_name.empty()) { mangled.SetDemangledName(ConstString(func_undecorated_name)); @@ -1972,11 +1969,11 @@ SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) { } bool SymbolFilePDB::DeclContextMatchesThisSymbolFile( - const lldb_private::CompilerDeclContext *decl_ctx) { - if (decl_ctx == nullptr || !decl_ctx->IsValid()) + const lldb_private::CompilerDeclContext &decl_ctx) { + if (!decl_ctx.IsValid()) return true; - TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem(); + TypeSystem *decl_ctx_type_system = decl_ctx.GetTypeSystem(); if (!decl_ctx_type_system) return false; auto type_system_or_err = GetTypeSystemForLanguage( diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h index 7a4eee48771a..928cbffc5f63 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ -#define lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_SYMBOLFILEPDB_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_SYMBOLFILEPDB_H #include "lldb/Core/UniqueCStringMap.h" #include "lldb/Symbol/SymbolFile.h" @@ -112,7 +112,7 @@ public: void FindGlobalVariables(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, lldb_private::VariableList &variables) override; @@ -121,7 +121,7 @@ public: lldb_private::VariableList &variables) override; void FindFunctions(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, lldb_private::SymbolContextList &sc_list) override; @@ -138,7 +138,7 @@ public: void FindTypes(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap &types) override; @@ -160,7 +160,7 @@ public: lldb_private::CompilerDeclContext FindNamespace( lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx) override; + const lldb_private::CompilerDeclContext &parent_decl_ctx) override; lldb_private::ConstString GetPluginName() override; @@ -195,7 +195,7 @@ private: llvm::DenseMap<uint32_t, uint32_t> &index_map) const; void FindTypesByName(llvm::StringRef name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, lldb_private::TypeMap &types); std::string GetMangledForPDBData(const llvm::pdb::PDBSymbolData &pdb_data); @@ -242,7 +242,7 @@ private: void CacheFunctionNames(); bool DeclContextMatchesThisSymbolFile( - const lldb_private::CompilerDeclContext *decl_ctx); + const lldb_private::CompilerDeclContext &decl_ctx); uint32_t GetCompilandId(const llvm::pdb::PDBSymbolData &data); @@ -262,4 +262,4 @@ private: lldb_private::UniqueCStringMap<uint32_t> m_func_method_names; }; -#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_SYMBOLFILEPDB_H diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp index 305efea1afab..c4a0e609aa22 100644 --- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFileSymtab.cpp ------------------------------------*- C++ -*-===// +//===-- SymbolFileSymtab.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,6 +25,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(SymbolFileSymtab) + char SymbolFileSymtab::ID; void SymbolFileSymtab::Initialize() { diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h index 1fff8188433e..9557ebbcb272 100644 --- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h +++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SymbolFileSymtab_h_ -#define liblldb_SymbolFileSymtab_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_SYMTAB_SYMBOLFILESYMTAB_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_SYMTAB_SYMBOLFILESYMTAB_H #include <map> #include <vector> @@ -106,7 +106,8 @@ protected: TypeMap m_objc_class_types; private: - DISALLOW_COPY_AND_ASSIGN(SymbolFileSymtab); + SymbolFileSymtab(const SymbolFileSymtab &) = delete; + const SymbolFileSymtab &operator=(const SymbolFileSymtab &) = delete; }; -#endif // liblldb_SymbolFileSymtab_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_SYMTAB_SYMBOLFILESYMTAB_H |