diff options
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp')
| -rw-r--r-- | source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 959 | 
1 files changed, 526 insertions, 433 deletions
| diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index e2ddcfc5d64b..c982d59c2830 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -8,6 +8,7 @@  #include "SymbolFileDWARF.h" +#include "llvm/ADT/Optional.h"  #include "llvm/Support/Casting.h"  #include "llvm/Support/Threading.h" @@ -43,7 +44,7 @@  #include "lldb/Symbol/LineTable.h"  #include "lldb/Symbol/LocateSymbolFile.h"  #include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Symbol/SymbolFile.h"  #include "lldb/Symbol/TypeMap.h"  #include "lldb/Symbol/TypeSystem.h"  #include "lldb/Symbol/VariableList.h" @@ -58,7 +59,6 @@  #include "DWARFDebugAbbrev.h"  #include "DWARFDebugAranges.h"  #include "DWARFDebugInfo.h" -#include "DWARFDebugLine.h"  #include "DWARFDebugMacro.h"  #include "DWARFDebugRanges.h"  #include "DWARFDeclContext.h" @@ -72,6 +72,7 @@  #include "SymbolFileDWARFDwo.h"  #include "SymbolFileDWARFDwp.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h"  #include "llvm/Support/FileSystem.h"  #include <algorithm> @@ -113,18 +114,12 @@ using namespace lldb_private;  namespace { -static constexpr PropertyDefinition g_properties[] = { -    {"comp-dir-symlink-paths", OptionValue::eTypeFileSpecList, true, 0, nullptr, -     {}, -     "If the DW_AT_comp_dir matches any of these paths the symbolic " -     "links will be resolved at DWARF parse time."}, -    {"ignore-file-indexes", OptionValue::eTypeBoolean, true, 0, nullptr, {}, -     "Ignore indexes present in the object files and always index DWARF " -     "manually."}}; +#define LLDB_PROPERTIES_symbolfiledwarf +#include "SymbolFileDWARFProperties.inc"  enum { -  ePropertySymLinkPaths, -  ePropertyIgnoreIndexes, +#define LLDB_PROPERTIES_symbolfiledwarf +#include "SymbolFileDWARFPropertiesEnum.inc"  };  class PluginProperties : public Properties { @@ -135,7 +130,7 @@ public:    PluginProperties() {      m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName()); -    m_collection_sp->Initialize(g_properties); +    m_collection_sp->Initialize(g_symbolfiledwarf_properties);    }    FileSpecList GetSymLinkPaths() { @@ -159,7 +154,66 @@ static const SymbolFileDWARFPropertiesSP &GetGlobalPluginProperties() {    return g_settings_sp;  } -} // anonymous namespace end +} // namespace + +static const llvm::DWARFDebugLine::LineTable * +ParseLLVMLineTable(lldb_private::DWARFContext &context, +                   llvm::DWARFDebugLine &line, dw_offset_t line_offset, +                   dw_offset_t unit_offset) { +  Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); + +  llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVM(); +  llvm::DWARFContext &ctx = context.GetAsLLVM(); +  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"); +          }); + +  if (!line_table) { +    LLDB_LOG_ERROR(log, line_table.takeError(), +                   "SymbolFileDWARF::ParseLineTable failed to parse"); +    return nullptr; +  } +  return *line_table; +} + +static FileSpecList ParseSupportFilesFromPrologue( +    const lldb::ModuleSP &module, +    const llvm::DWARFDebugLine::Prologue &prologue, FileSpec::Style style, +    llvm::StringRef compile_dir = {}, FileSpec first_file = {}) { +  FileSpecList support_files; +  support_files.Append(first_file); + +  const size_t number_of_files = prologue.FileNames.size(); +  for (size_t idx = 1; idx <= number_of_files; ++idx) { +    std::string original_file; +    if (!prologue.getFileNameByIndex( +            idx, compile_dir, +            llvm::DILineInfoSpecifier::FileLineInfoKind::Default, original_file, +            style)) { +      // Always add an entry so the indexes remain correct. +      support_files.EmplaceBack(); +      continue; +    } + +    std::string remapped_file; +    if (!prologue.getFileNameByIndex( +            idx, compile_dir, +            llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, +            remapped_file, style)) { +      // Always add an entry so the indexes remain correct. +      support_files.EmplaceBack(original_file, style); +      continue; +    } + +    module->RemapSourceFile(llvm::StringRef(original_file), remapped_file); +    support_files.EmplaceBack(remapped_file, style); +  } + +  return support_files; +}  FileSpecList SymbolFileDWARF::GetSymlinkPaths() {    return GetGlobalPluginProperties()->GetSymLinkPaths(); @@ -197,20 +251,16 @@ const char *SymbolFileDWARF::GetPluginDescriptionStatic() {    return "DWARF and DWARF3 debug symbol file reader.";  } -SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFile *obj_file) { -  return new SymbolFileDWARF(obj_file, +SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFileSP objfile_sp) { +  return new SymbolFileDWARF(std::move(objfile_sp),                               /*dwo_section_list*/ nullptr);  } -TypeList *SymbolFileDWARF::GetTypeList() { -  // This method can be called without going through the symbol vendor so we -  // need to lock the module. +TypeList &SymbolFileDWARF::GetTypeList() {    std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); -  SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); -  if (debug_map_symfile) +  if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())      return debug_map_symfile->GetTypeList(); -  else -    return m_obj_file->GetModule()->GetTypeList(); +  return SymbolFile::GetTypeList();  }  void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,                                 dw_offset_t max_die_offset, uint32_t type_mask, @@ -264,6 +314,8 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,        case DW_TAG_ptr_to_member_type:          add_type = (type_mask & eTypeClassMemberPointer) != 0;          break; +      default: +        break;        }        if (add_type) { @@ -283,11 +335,11 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,    }  } -size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope, -                                 TypeClass type_mask, TypeList &type_list) +void SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope, +                               TypeClass type_mask, TypeList &type_list)  { -  ASSERT_MODULE_LOCK(this); +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    TypeSet type_set;    CompileUnit *comp_unit = nullptr; @@ -297,8 +349,8 @@ size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,    if (comp_unit) {      dwarf_cu = GetDWARFCompileUnit(comp_unit); -    if (dwarf_cu == nullptr) -      return 0; +    if (!dwarf_cu) +      return;      GetTypes(dwarf_cu->DIE(), dwarf_cu->GetOffset(),               dwarf_cu->GetNextUnitOffset(), type_mask, type_set);    } else { @@ -315,16 +367,13 @@ size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,    }    std::set<CompilerType> compiler_type_set; -  size_t num_types_added = 0;    for (Type *type : type_set) {      CompilerType compiler_type = type->GetForwardCompilerType();      if (compiler_type_set.find(compiler_type) == compiler_type_set.end()) {        compiler_type_set.insert(compiler_type);        type_list.Insert(type->shared_from_this()); -      ++num_types_added;      }    } -  return num_types_added;  }  // Gets the first parent that is a lexical block, function or inlined @@ -342,19 +391,21 @@ SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) {      case DW_TAG_inlined_subroutine:      case DW_TAG_lexical_block:        return die; +    default: +      break;      }    }    return DWARFDIE();  } -SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile, +SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp,                                   SectionList *dwo_section_list) -    : SymbolFile(objfile), +    : SymbolFile(std::move(objfile_sp)),        UserID(0x7fffffff00000000), // Used by SymbolFileDWARFDebugMap to                                    // when this class parses .o files to                                    // contain the .o file index/ID        m_debug_map_module_wp(), m_debug_map_symfile(nullptr), -      m_context(objfile->GetModule()->GetSectionList(), dwo_section_list), +      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() {} @@ -374,17 +425,17 @@ UniqueDWARFASTTypeMap &SymbolFileDWARF::GetUniqueDWARFASTTypeMap() {      return m_unique_ast_type_map;  } -TypeSystem *SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) { -  SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); -  TypeSystem *type_system; -  if (debug_map_symfile) { -    type_system = debug_map_symfile->GetTypeSystemForLanguage(language); -  } else { -    type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language); -    if (type_system) -      type_system->SetSymbolFile(this); +llvm::Expected<TypeSystem &> +SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) { +  if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile()) +    return debug_map_symfile->GetTypeSystemForLanguage(language); + +  auto type_system_or_err = +      m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language); +  if (type_system_or_err) { +    type_system_or_err->SetSymbolFile(this);    } -  return type_system; +  return type_system_or_err;  }  void SymbolFileDWARF::InitializeObject() { @@ -420,7 +471,7 @@ void SymbolFileDWARF::InitializeObject() {      }    } -  m_index = llvm::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(), +  m_index = std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(),                                                  DebugInfo());  } @@ -430,9 +481,9 @@ bool SymbolFileDWARF::SupportedVersion(uint16_t version) {  uint32_t SymbolFileDWARF::CalculateAbilities() {    uint32_t abilities = 0; -  if (m_obj_file != nullptr) { +  if (m_objfile_sp != nullptr) {      const Section *section = nullptr; -    const SectionList *section_list = m_obj_file->GetSectionList(); +    const SectionList *section_list = m_objfile_sp->GetSectionList();      if (section_list == nullptr)        return 0; @@ -462,10 +513,12 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {          abbrev->GetUnsupportedForms(invalid_forms);          if (!invalid_forms.empty()) {            StreamString error; -          error.Printf("unsupported DW_FORM value%s:", invalid_forms.size() > 1 ? "s" : ""); +          error.Printf("unsupported DW_FORM value%s:", +                       invalid_forms.size() > 1 ? "s" : "");            for (auto form : invalid_forms)              error.Printf(" %#x", form); -          m_obj_file->GetModule()->ReportWarning("%s", error.GetString().str().c_str()); +          m_objfile_sp->GetModule()->ReportWarning( +              "%s", error.GetString().str().c_str());            return 0;          }        } @@ -477,10 +530,10 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {          debug_line_file_size = section->GetFileSize();      } else {        const char *symfile_dir_cstr = -          m_obj_file->GetFileSpec().GetDirectory().GetCString(); +          m_objfile_sp->GetFileSpec().GetDirectory().GetCString();        if (symfile_dir_cstr) {          if (strcasestr(symfile_dir_cstr, ".dsym")) { -          if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo) { +          if (m_objfile_sp->GetType() == ObjectFile::eTypeDebugInfo) {              // We have a dSYM file that didn't have a any debug info. If the              // string table has a size of 1, then it was made from an              // executable with no debug info, or from an executable that was @@ -489,7 +542,7 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {                  section_list->FindSectionByType(eSectionTypeDWARFDebugStr, true)                      .get();              if (section && section->GetFileSize() == 1) { -              m_obj_file->GetModule()->ReportWarning( +              m_objfile_sp->GetModule()->ReportWarning(                    "empty dSYM file detected, dSYM was created with an "                    "executable with no debug info.");              } @@ -519,7 +572,7 @@ SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type,  void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,                                        DWARFDataExtractor &data) { -  ModuleSP module_sp(m_obj_file->GetModule()); +  ModuleSP module_sp(m_objfile_sp->GetModule());    const SectionList *section_list = module_sp->GetSectionList();    if (!section_list)      return; @@ -529,7 +582,7 @@ void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,      return;    data.Clear(); -  m_obj_file->ReadSectionData(section_sp.get(), data); +  m_objfile_sp->ReadSectionData(section_sp.get(), data);  }  const DWARFDataExtractor &SymbolFileDWARF::DebugLocData() { @@ -556,7 +609,7 @@ DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {    if (debug_abbrev_data.GetByteSize() == 0)      return nullptr; -  auto abbr = llvm::make_unique<DWARFDebugAbbrev>(); +  auto abbr = std::make_unique<DWARFDebugAbbrev>();    llvm::Error error = abbr->parse(debug_abbrev_data);    if (error) {      Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); @@ -579,7 +632,7 @@ DWARFDebugInfo *SymbolFileDWARF::DebugInfo() {      Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,                         static_cast<void *>(this));      if (m_context.getOrLoadDebugInfoData().GetByteSize() > 0) -      m_info = llvm::make_unique<DWARFDebugInfo>(*this, m_context); +      m_info = std::make_unique<DWARFDebugInfo>(*this, m_context);    }    return m_info.get();  } @@ -604,7 +657,7 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {    return nullptr;  } -DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRanges() { +DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() {    if (!m_ranges) {      static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);      Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, @@ -619,7 +672,7 @@ DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRanges() {    return m_ranges.get();  } -DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRngLists() { +DWARFDebugRngLists *SymbolFileDWARF::GetDebugRngLists() {    if (!m_rnglists) {      static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);      Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, @@ -648,7 +701,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {        cu_sp = m_debug_map_symfile->GetCompileUnit(this);        dwarf_cu.SetUserData(cu_sp.get());      } else { -      ModuleSP module_sp(m_obj_file->GetModule()); +      ModuleSP module_sp(m_objfile_sp->GetModule());        if (module_sp) {          const DWARFDIE cu_die = dwarf_cu.DIE();          if (cu_die) { @@ -677,8 +730,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {            dwarf_cu.SetUserData(cu_sp.get()); -          m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( -              dwarf_cu.GetID(), cu_sp); +          SetCompileUnitAtIndex(dwarf_cu.GetID(), cu_sp);          }        }      } @@ -715,7 +767,7 @@ llvm::Optional<uint32_t> SymbolFileDWARF::GetDWARFUnitIndex(uint32_t cu_idx) {    return m_lldb_cu_to_dwarf_unit[cu_idx];  } -uint32_t SymbolFileDWARF::GetNumCompileUnits() { +uint32_t SymbolFileDWARF::CalculateNumCompileUnits() {    DWARFDebugInfo *info = DebugInfo();    if (!info)      return 0; @@ -741,17 +793,21 @@ CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {  Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,                                           const DWARFDIE &die) {    ASSERT_MODULE_LOCK(this); -  if (die.IsValid()) { -    TypeSystem *type_system = -        GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); - -    if (type_system) { -      DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); -      if (dwarf_ast) -        return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die); -    } +  if (!die.IsValid()) +    return nullptr; + +  auto type_system_or_err = +      GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); +  if (auto err = type_system_or_err.takeError()) { +    LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), +                   std::move(err), "Unable to parse function"); +    return nullptr;    } -  return nullptr; +  DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser(); +  if (!dwarf_ast) +    return nullptr; + +  return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die);  }  bool SymbolFileDWARF::FixupAddress(Address &addr) { @@ -763,7 +819,7 @@ bool SymbolFileDWARF::FixupAddress(Address &addr) {    return true;  }  lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) { -  ASSERT_MODULE_LOCK(this); +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);    if (dwarf_cu)      return dwarf_cu->GetLanguageType(); @@ -772,7 +828,7 @@ lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) {  }  size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) { -  ASSERT_MODULE_LOCK(this); +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);    if (!dwarf_cu)      return 0; @@ -790,21 +846,23 @@ size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {    return functions_added;  } +void SymbolFileDWARF::ForEachExternalModule( +    CompileUnit &comp_unit, llvm::function_ref<void(ModuleSP)> f) { +  UpdateExternalModuleListIfNeeded(); + +  for (auto &p : m_external_type_modules) { +    ModuleSP module = p.second; +    f(module); +    for (std::size_t i = 0; i < module->GetNumCompileUnits(); ++i) +      module->GetCompileUnitAtIndex(i)->ForEachExternalModule(f); +  } +} +  bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit,                                          FileSpecList &support_files) { -  ASSERT_MODULE_LOCK(this); -  if (DWARFUnit *unit = GetDWARFCompileUnit(&comp_unit)) { -    const dw_offset_t stmt_list = unit->GetLineTableOffset(); -    if (stmt_list != DW_INVALID_OFFSET) { -      // All file indexes in DWARF are one based and a file of index zero is -      // supposed to be the compile unit itself. -      support_files.Append(comp_unit); -      return DWARFDebugLine::ParseSupportFiles(comp_unit.GetModule(), -                                               m_context.getOrLoadLineData(), -                                               stmt_list, support_files, unit); -    } -  } -  return false; +  if (!comp_unit.GetLineTable()) +    ParseLineTable(comp_unit); +  return true;  }  FileSpec SymbolFileDWARF::GetFile(DWARFUnit &unit, size_t file_idx) { @@ -833,16 +891,26 @@ SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit &tu) {    auto iter_bool = m_type_unit_support_files.try_emplace(offset);    FileSpecList &list = iter_bool.first->second;    if (iter_bool.second) { -    list.Append(FileSpec()); -    DWARFDebugLine::ParseSupportFiles(GetObjectFile()->GetModule(), -                                      m_context.getOrLoadLineData(), offset, -                                      list, &tu); +    uint64_t line_table_offset = offset; +    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) { +      Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); +      LLDB_LOG_ERROR(log, std::move(error), +                     "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse " +                     "the line table prologue"); +    } else { +      list = ParseSupportFilesFromPrologue(GetObjectFile()->GetModule(), +                                           prologue, tu.GetPathStyle()); +    }    }    return list;  }  bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) { -  ASSERT_MODULE_LOCK(this); +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);    if (dwarf_cu)      return dwarf_cu->GetIsOptimized(); @@ -852,7 +920,7 @@ bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) {  bool SymbolFileDWARF::ParseImportedModules(      const lldb_private::SymbolContext &sc,      std::vector<SourceModule> &imported_modules) { -  ASSERT_MODULE_LOCK(this); +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    assert(sc.comp_unit);    DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);    if (!dwarf_cu) @@ -901,102 +969,63 @@ bool SymbolFileDWARF::ParseImportedModules(    return true;  } -struct ParseDWARFLineTableCallbackInfo { -  LineTable *line_table; -  std::unique_ptr<LineSequence> sequence_up; -  lldb::addr_t addr_mask; -}; - -// ParseStatementTableCallback -static void ParseDWARFLineTableCallback(dw_offset_t offset, -                                        const DWARFDebugLine::State &state, -                                        void *userData) { -  if (state.row == DWARFDebugLine::State::StartParsingLineTable) { -    // Just started parsing the line table -  } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) { -    // Done parsing line table, nothing to do for the cleanup -  } else { -    ParseDWARFLineTableCallbackInfo *info = -        (ParseDWARFLineTableCallbackInfo *)userData; -    LineTable *line_table = info->line_table; - -    // If this is our first time here, we need to create a sequence container. -    if (!info->sequence_up) { -      info->sequence_up.reset(line_table->CreateLineSequenceContainer()); -      assert(info->sequence_up.get()); -    } -    line_table->AppendLineEntryToSequence( -        info->sequence_up.get(), state.address & info->addr_mask, state.line, -        state.column, state.file, state.is_stmt, state.basic_block, -        state.prologue_end, state.epilogue_begin, state.end_sequence); -    if (state.end_sequence) { -      // First, put the current sequence into the line table. -      line_table->InsertSequence(info->sequence_up.get()); -      // Then, empty it to prepare for the next sequence. -      info->sequence_up->Clear(); -    } -  } -} -  bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { -  ASSERT_MODULE_LOCK(this); +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    if (comp_unit.GetLineTable() != nullptr)      return true;    DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); -  if (dwarf_cu) { -    const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly(); -    if (dwarf_cu_die) { -      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) { -        std::unique_ptr<LineTable> line_table_up(new LineTable(&comp_unit)); -        if (line_table_up) { -          ParseDWARFLineTableCallbackInfo info; -          info.line_table = line_table_up.get(); - -          /* -           * MIPS: -           * The SymbolContext may not have a valid target, thus we may not be -           * able -           * to call Address::GetOpcodeLoadAddress() which would clear the bit -           * #0 -           * for MIPS. Use ArchSpec to clear the bit #0. -          */ -          switch (GetObjectFile()->GetArchitecture().GetMachine()) { -          case llvm::Triple::mips: -          case llvm::Triple::mipsel: -          case llvm::Triple::mips64: -          case llvm::Triple::mips64el: -            info.addr_mask = ~((lldb::addr_t)1); -            break; -          default: -            info.addr_mask = ~((lldb::addr_t)0); -            break; -          } +  if (!dwarf_cu) +    return false; -          lldb::offset_t offset = cu_line_offset; -          DWARFDebugLine::ParseStatementTable( -              m_context.getOrLoadLineData(), &offset, -              ParseDWARFLineTableCallback, &info, dwarf_cu); -          SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); -          if (debug_map_symfile) { -            // 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 are relative to the .o file into addresses for -            // the main executable. -            comp_unit.SetLineTable( -                debug_map_symfile->LinkOSOLineTable(this, line_table_up.get())); -          } else { -            comp_unit.SetLineTable(line_table_up.release()); -            return true; -          } -        } -      } +  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) +    return false; + +  llvm::DWARFDebugLine line; +  const llvm::DWARFDebugLine::LineTable *line_table = ParseLLVMLineTable( +      m_context, line, cu_line_offset, dwarf_cu->GetOffset()); + +  if (!line_table) +    return false; + +  // 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(); +  for (auto &row : line_table->Rows) { +    line_table_up->AppendLineEntryToSequence( +        sequence, 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();      }    } -  return false; + +  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 +    // are relative to the .o file into addresses for the main executable. +    comp_unit.SetLineTable( +        debug_map_symfile->LinkOSOLineTable(this, line_table_up.get())); +  } else { +    comp_unit.SetLineTable(line_table_up.release()); +  } + +  comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue( +      comp_unit.GetModule(), line_table->Prologue, dwarf_cu->GetPathStyle(), +      dwarf_cu->GetCompilationDirectory().GetCString(), FileSpec(comp_unit))); + +  return true;  }  lldb_private::DebugMacrosSP @@ -1022,7 +1051,7 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) {  }  bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) { -  ASSERT_MODULE_LOCK(this); +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);    if (dwarf_cu == nullptr) @@ -1114,7 +1143,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(                  "0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64                  ") which has a base that is less than the function's low PC "                  "0x%" PRIx64 ". Please file a bug and attach the file at the " -                             "start of this error message", +                "start of this error message",                  block->GetID(), range_base, range.GetRangeEnd(),                  subprogram_low_pc);            } @@ -1188,15 +1217,10 @@ bool SymbolFileDWARF::ClassOrStructIsVirtual(const DWARFDIE &parent_die) {  }  void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) { -  TypeSystem *type_system = decl_ctx.GetTypeSystem(); -  DWARFASTParser *ast_parser = type_system->GetDWARFParser(); -  std::vector<DWARFDIE> decl_ctx_die_list = -      ast_parser->GetDIEForDeclContext(decl_ctx); - -  for (DWARFDIE decl_ctx_die : decl_ctx_die_list) -    for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl; -         decl = decl.GetSibling()) -      ast_parser->GetDeclForUIDFromDWARF(decl); +  auto *type_system = decl_ctx.GetTypeSystem(); +  if (type_system != nullptr) +    type_system->GetDWARFParser()->EnsureAllDIEsInDeclContextHaveBeenParsed( +        decl_ctx);  }  user_id_t SymbolFileDWARF::GetUID(DIERef ref) { @@ -1281,8 +1305,6 @@ SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {  CompilerDeclContext  SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) { -  // This method can be called without going through the symbol vendor so we -  // need to lock the module.    std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    // Anytime we have a lldb::user_id_t, we must get the DIE by calling    // SymbolFileDWARF::GetDIE(). See comments inside the @@ -1293,8 +1315,6 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {  }  Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) { -  // This method can be called without going through the symbol vendor so we -  // need to lock the module.    std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    // Anytime we have a lldb::user_id_t, we must get the DIE by calling    // SymbolFileDWARF::GetDIE(). See comments inside the @@ -1341,8 +1361,9 @@ Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die,            // Get the type, which could be a forward declaration            if (log)              GetObjectFile()->GetModule()->LogMessage( -                log, "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' " -                     "resolve parent forward type for 0x%8.8x", +                log, +                "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' " +                "resolve parent forward type for 0x%8.8x",                  die.GetOffset(), die.GetTagAsCString(), die.GetName(),                  decl_ctx_die.GetOffset());          } break; @@ -1504,7 +1525,6 @@ SymbolFileDWARF::GetDIE(const DIERef &die_ref) {          ->GetDIE(die_ref);    } -    DWARFDebugInfo *debug_info = DebugInfo();    if (debug_info)      return debug_info->GetDIE(die_ref); @@ -1567,7 +1587,7 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(    if (dwo_obj_file == nullptr)      return nullptr; -  return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, *dwarf_cu); +  return std::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, *dwarf_cu);  }  void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { @@ -1607,7 +1627,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {                }              }              dwo_module_spec.GetArchitecture() = -                m_obj_file->GetModule()->GetArchitecture(); +                m_objfile_sp->GetModule()->GetArchitecture();              // When LLDB loads "external" modules it looks at the presence of              // DW_AT_GNU_dwo_name. However, when the already created module @@ -1621,8 +1641,8 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {              // printed. However, as one can notice in this case we don't              // actually need to try to load the already loaded module              // (corresponding to .dwo) so we simply skip it. -            if (m_obj_file->GetFileSpec().GetFileNameExtension() == ".dwo" && -                llvm::StringRef(m_obj_file->GetFileSpec().GetPath()) +            if (m_objfile_sp->GetFileSpec().GetFileNameExtension() == ".dwo" && +                llvm::StringRef(m_objfile_sp->GetFileSpec().GetPath())                      .endswith(dwo_module_spec.GetFileSpec().GetPath())) {                continue;              } @@ -1694,6 +1714,7 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {  uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,                                                 SymbolContextItem resolve_scope,                                                 SymbolContext &sc) { +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);    Timer scoped_timer(func_cat,                       "SymbolFileDWARF::" @@ -1837,6 +1858,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,                                                 bool check_inlines,                                                 SymbolContextItem resolve_scope,                                                 SymbolContextList &sc_list) { +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    const uint32_t prev_size = sc_list.GetSize();    if (resolve_scope & eSymbolContextCompUnit) {      for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus; @@ -1849,7 +1871,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,        bool file_spec_matches_cu_file_spec =            FileSpec::Equal(file_spec, *dc_cu, full_match);        if (check_inlines || file_spec_matches_cu_file_spec) { -        SymbolContext sc(m_obj_file->GetModule()); +        SymbolContext sc(m_objfile_sp->GetModule());          sc.comp_unit = dc_cu;          uint32_t file_idx = UINT32_MAX; @@ -1961,9 +1983,16 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(    }    TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem(); -  TypeSystem *type_system = GetTypeSystemForLanguage( +  auto type_system_or_err = GetTypeSystemForLanguage(        decl_ctx_type_system->GetMinimumLanguage(nullptr)); -  if (decl_ctx_type_system == type_system) +  if (auto err = type_system_or_err.takeError()) { +    LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), +                   std::move(err), +                   "Unable to match namespace decl using TypeSystem"); +    return false; +  } + +  if (decl_ctx_type_system == &type_system_or_err.get())      return true; // The type systems match, return true    // The namespace AST was valid, and it does not match... @@ -1976,9 +2005,10 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(    return false;  } -uint32_t SymbolFileDWARF::FindGlobalVariables( +void SymbolFileDWARF::FindGlobalVariables(      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));    if (log) @@ -1990,11 +2020,11 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(          max_matches);    if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) -    return 0; +    return;    DWARFDebugInfo *info = DebugInfo(); -  if (info == nullptr) -    return 0; +  if (!info) +    return;    // Remember how many variables are in the list before we search.    const uint32_t original_size = variables.GetSize(); @@ -2012,7 +2042,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(    const size_t num_die_matches = die_offsets.size();    if (num_die_matches) {      SymbolContext sc; -    sc.module_sp = m_obj_file->GetModule(); +    sc.module_sp = m_objfile_sp->GetModule();      assert(sc.module_sp);      // Loop invariant: Variables up to this index have been checked for context @@ -2081,12 +2111,12 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(          name.GetCString(), static_cast<const void *>(parent_decl_ctx),          max_matches, num_matches);    } -  return num_matches;  } -uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex, -                                              uint32_t max_matches, -                                              VariableList &variables) { +void SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex, +                                          uint32_t max_matches, +                                          VariableList &variables) { +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));    if (log) { @@ -2098,8 +2128,8 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex,    }    DWARFDebugInfo *info = DebugInfo(); -  if (info == nullptr) -    return 0; +  if (!info) +    return;    // Remember how many variables are in the list before we search.    const uint32_t original_size = variables.GetSize(); @@ -2108,7 +2138,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex,    m_index->GetGlobalVariables(regex, die_offsets);    SymbolContext sc; -  sc.module_sp = m_obj_file->GetModule(); +  sc.module_sp = m_objfile_sp->GetModule();    assert(sc.module_sp);    const size_t num_matches = die_offsets.size(); @@ -2132,9 +2162,6 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex,          m_index->ReportInvalidDIERef(die_ref, regex.GetText());      }    } - -  // Return the number of variable that were appended to the list -  return variables.GetSize() - original_size;  }  bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, @@ -2210,10 +2237,12 @@ bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx,    return false;  } -uint32_t SymbolFileDWARF::FindFunctions( -    ConstString name, const CompilerDeclContext *parent_decl_ctx, -    FunctionNameType name_type_mask, bool include_inlines, bool append, -    SymbolContextList &sc_list) { +void SymbolFileDWARF::FindFunctions(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());    static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);    Timer scoped_timer(func_cat, "SymbolFileDWARF::FindFunctions (name = '%s')",                       name.AsCString()); @@ -2226,21 +2255,17 @@ uint32_t SymbolFileDWARF::FindFunctions(    if (log) {      GetObjectFile()->GetModule()->LogMessage( -        log, "SymbolFileDWARF::FindFunctions (name=\"%s\", " -             "name_type_mask=0x%x, append=%u, sc_list)", -        name.GetCString(), name_type_mask, append); +        log, +        "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, sc_list)", +        name.GetCString(), name_type_mask);    } -  // If we aren't appending the results to this list, then clear the list -  if (!append) -    sc_list.Clear(); -    if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) -    return 0; +    return;    // If name is empty then we won't find anything.    if (name.IsEmpty()) -    return 0; +    return;    // Remember how many sc_list are in the list before we search in case we are    // appending the results to a variable list. @@ -2255,7 +2280,7 @@ uint32_t SymbolFileDWARF::FindFunctions(    std::vector<DWARFDIE> dies;    m_index->GetFunctions(name, *this, *parent_decl_ctx, name_type_mask, dies); -  for (const DWARFDIE &die: dies) { +  for (const DWARFDIE &die : dies) {      if (resolved_dies.insert(die.GetDIE()).second)        ResolveFunction(die, include_inlines, sc_list);    } @@ -2265,18 +2290,18 @@ uint32_t SymbolFileDWARF::FindFunctions(    if (log && num_matches > 0) {      GetObjectFile()->GetModule()->LogMessage( -        log, "SymbolFileDWARF::FindFunctions (name=\"%s\", " -             "name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => " -             "%u", -        name.GetCString(), name_type_mask, include_inlines, append, +        log, +        "SymbolFileDWARF::FindFunctions (name=\"%s\", " +        "name_type_mask=0x%x, include_inlines=%d, sc_list) => %u", +        name.GetCString(), name_type_mask, include_inlines,          num_matches);    } -  return num_matches;  } -uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression ®ex, -                                        bool include_inlines, bool append, -                                        SymbolContextList &sc_list) { +void SymbolFileDWARF::FindFunctions(const RegularExpression ®ex, +                                    bool include_inlines, +                                    SymbolContextList &sc_list) { +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);    Timer scoped_timer(func_cat, "SymbolFileDWARF::FindFunctions (regex = '%s')",                       regex.GetText().str().c_str()); @@ -2285,22 +2310,13 @@ uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression ®ex,    if (log) {      GetObjectFile()->GetModule()->LogMessage( -        log, -        "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)", -        regex.GetText().str().c_str(), append); +        log, "SymbolFileDWARF::FindFunctions (regex=\"%s\", sc_list)", +        regex.GetText().str().c_str());    } -  // If we aren't appending the results to this list, then clear the list -  if (!append) -    sc_list.Clear(); -    DWARFDebugInfo *info = DebugInfo();    if (!info) -    return 0; - -  // Remember how many sc_list are in the list before we search in case we are -  // appending the results to a variable list. -  uint32_t original_size = sc_list.GetSize(); +    return;    DIEArray offsets;    m_index->GetFunctions(regex, offsets); @@ -2315,9 +2331,6 @@ uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression ®ex,      if (resolved_dies.insert(die.GetDIE()).second)        ResolveFunction(die, include_inlines, sc_list);    } - -  // Return the number of variable that were appended to the list -  return sc_list.GetSize() - original_size;  }  void SymbolFileDWARF::GetMangledNamesForFunction( @@ -2345,156 +2358,141 @@ void SymbolFileDWARF::GetMangledNamesForFunction(    }  } -uint32_t SymbolFileDWARF::FindTypes( +void SymbolFileDWARF::FindTypes(      ConstString name, const CompilerDeclContext *parent_decl_ctx, -    bool append, uint32_t max_matches, +    uint32_t max_matches,      llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,      TypeMap &types) { -  // If we aren't appending the results to this list, then clear the list -  if (!append) -    types.Clear(); - +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    // Make sure we haven't already searched this SymbolFile before...    if (searched_symbol_files.count(this)) -    return 0; -  else -    searched_symbol_files.insert(this); +    return; + +  searched_symbol_files.insert(this);    DWARFDebugInfo *info = DebugInfo(); -  if (info == nullptr) -    return 0; +  if (!info) +    return;    Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));    if (log) {      if (parent_decl_ctx)        GetObjectFile()->GetModule()->LogMessage( -          log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = " -               "%p (\"%s\"), append=%u, max_matches=%u, type_list)", +          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>"), append, max_matches); +          parent_decl_ctx->GetName().AsCString("<NULL>"), max_matches);      else        GetObjectFile()->GetModule()->LogMessage( -          log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = " -               "NULL, append=%u, max_matches=%u, type_list)", -          name.GetCString(), append, max_matches); +          log, +          "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = " +          "NULL, max_matches=%u, type_list)", +          name.GetCString(), max_matches);    }    if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) -    return 0; +    return;    DIEArray die_offsets;    m_index->GetTypes(name, die_offsets);    const size_t num_die_matches = die_offsets.size(); -  if (num_die_matches) { -    const uint32_t initial_types_size = types.GetSize(); -    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()); -      } -    } -    const uint32_t num_matches = types.GetSize() - initial_types_size; -    if (log && num_matches) { -      if (parent_decl_ctx) { -        GetObjectFile()->GetModule()->LogMessage( -            log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx " -                 "= %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u", -            name.GetCString(), static_cast<const void *>(parent_decl_ctx), -            parent_decl_ctx->GetName().AsCString("<NULL>"), append, max_matches, -            num_matches); -      } else { -        GetObjectFile()->GetModule()->LogMessage( -            log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx " -                 "= NULL, append=%u, max_matches=%u, type_list) => %u", -            name.GetCString(), append, max_matches, num_matches); +  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());      } -    return num_matches; -  } else { +  } + +  // 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) {      UpdateExternalModuleListIfNeeded(); -    for (const auto &pair : m_external_type_modules) { -      ModuleSP external_module_sp = pair.second; -      if (external_module_sp) { -        SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor(); -        if (sym_vendor) { -          const uint32_t num_external_matches = -              sym_vendor->FindTypes(name, parent_decl_ctx, append, max_matches, -                                    searched_symbol_files, types); -          if (num_external_matches) -            return num_external_matches; -        } -      } -    } +    for (const auto &pair : m_external_type_modules) +      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);    } -  return 0; +  if (log && types.GetSize()) { +    if (parent_decl_ctx) { +      GetObjectFile()->GetModule()->LogMessage( +          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, +          types.GetSize()); +    } else { +      GetObjectFile()->GetModule()->LogMessage( +          log, +          "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx " +          "= NULL, max_matches=%u, type_list) => %u", +          name.GetCString(), max_matches, types.GetSize()); +    } +  }  } -size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context, -                                  bool append, TypeMap &types) { -  if (!append) -    types.Clear(); - -  if (context.empty()) -    return 0; +void SymbolFileDWARF::FindTypes(llvm::ArrayRef<CompilerContext> pattern, +                                  LanguageSet languages, TypeMap &types) { +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); +  if (pattern.empty()) +    return; -  ConstString name = context.back().name; +  ConstString name = pattern.back().name;    if (!name) -    return 0; +    return;    DIEArray die_offsets;    m_index->GetTypes(name, die_offsets);    const size_t num_die_matches = die_offsets.size(); -  if (num_die_matches) { -    size_t num_matches = 0; -    for (size_t i = 0; i < num_die_matches; ++i) { -      const DIERef &die_ref = die_offsets[i]; -      DWARFDIE die = GetDIE(die_ref); +  for (size_t i = 0; i < num_die_matches; ++i) { +    const DIERef &die_ref = die_offsets[i]; +    DWARFDIE die = GetDIE(die_ref); -      if (die) { -        std::vector<CompilerContext> die_context; -        die.GetDeclContext(die_context); -        if (die_context != context) -          continue; - -        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()); -          ++num_matches; -        } -      } else { -        m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); -      } +    if (!die) { +      m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); +      continue;      } -    return num_matches; +    if (!languages[die.GetCU()->GetLanguageType()]) +      continue; + +    llvm::SmallVector<CompilerContext, 4> die_context; +    die.GetDeclContext(die_context); +    if (!contextMatches(die_context, pattern)) +      continue; + +    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 0;  }  CompilerDeclContext  SymbolFileDWARF::FindNamespace(ConstString name,                                 const CompilerDeclContext *parent_decl_ctx) { +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));    if (log) { @@ -2536,8 +2534,9 @@ SymbolFileDWARF::FindNamespace(ConstString name,    }    if (log && namespace_decl_ctx) {      GetObjectFile()->GetModule()->LogMessage( -        log, "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => " -             "CompilerDeclContext(%p/%p) \"%s\"", +        log, +        "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => " +        "CompilerDeclContext(%p/%p) \"%s\"",          name.GetCString(),          static_cast<const void *>(namespace_decl_ctx.GetTypeSystem()),          static_cast<const void *>(namespace_decl_ctx.GetOpaqueDeclContext()), @@ -2632,11 +2631,10 @@ SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) {    return DWARFDIE();  } -Symbol * -SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) { +Symbol *SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {    Symbol *objc_class_symbol = nullptr; -  if (m_obj_file) { -    Symtab *symtab = m_obj_file->GetSymtab(); +  if (m_objfile_sp) { +    Symtab *symtab = m_objfile_sp->GetSymtab();      if (symtab) {        objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(            objc_class_name, eSymbolTypeObjCClass, Symtab::eDebugNo, @@ -2653,8 +2651,7 @@ SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {  // worry about the debug map  // DWARF file  // if we are doing darwin DWARF in .o file debugging. -bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type( -    DWARFUnit *cu) { +bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu) {    if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {      m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;      if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type()) @@ -2681,8 +2678,7 @@ bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(  // This function can be used when a DIE is found that is a forward declaration  // DIE and we want to try and find a type that has the complete definition.  TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE( -    const DWARFDIE &die, ConstString type_name, -    bool must_be_implementation) { +    const DWARFDIE &die, ConstString type_name, bool must_be_implementation) {    TypeSP type_sp; @@ -2727,7 +2723,7 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(                DEBUG_PRINTF("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64                             " (cu 0x%8.8" PRIx64 ")\n",                             die.GetID(), -                           m_obj_file->GetFileSpec().GetFilename().AsCString( +                           m_objfile_sp->GetFileSpec().GetFilename().AsCString(                                 "<Unknown>"),                             type_die.GetID(), type_cu->GetID()); @@ -2849,8 +2845,9 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(                                              DWARF_LOG_LOOKUPS));        if (log) {          GetObjectFile()->GetModule()->LogMessage( -            log, "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%" -                 "s, qualified-name='%s')", +            log, +            "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%" +            "s, qualified-name='%s')",              DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),              dwarf_decl_ctx.GetQualifiedName());        } @@ -2863,10 +2860,18 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(        // use this to ensure any matches we find are in a language that this        // type system supports        const LanguageType language = dwarf_decl_ctx.GetLanguage(); -      TypeSystem *type_system = (language == eLanguageTypeUnknown) -                                    ? nullptr -                                    : GetTypeSystemForLanguage(language); - +      TypeSystem *type_system = nullptr; +      if (language != eLanguageTypeUnknown) { +        auto type_system_or_err = GetTypeSystemForLanguage(language); +        if (auto err = type_system_or_err.takeError()) { +          LLDB_LOG_ERROR( +              lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), +              std::move(err), "Cannot get TypeSystem for language {}", +              Language::GetNameForLanguageType(language)); +        } else { +          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]; @@ -2916,9 +2921,10 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(                if (log) {                  GetObjectFile()->GetModule()->LogMessage( -                    log, "SymbolFileDWARF::" -                         "FindDefinitionTypeForDWARFDeclContext(tag=%s, " -                         "qualified-name='%s') trying die=0x%8.8x (%s)", +                    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()); @@ -2937,9 +2943,10 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(                  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)", +                    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()); @@ -2960,21 +2967,21 @@ TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,    if (!die)      return {}; -  TypeSystem *type_system = +  auto type_system_or_err =        GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); -  if (!type_system) +  if (auto err = type_system_or_err.takeError()) { +    LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), +                   std::move(err), "Unable to parse type");      return {}; +  } -  DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); +  DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser();    if (!dwarf_ast)      return {}; -  Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); -  TypeSP type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr); +  TypeSP type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, type_is_new_ptr);    if (type_sp) { -    TypeList *type_list = GetTypeList(); -    if (type_list) -      type_list->Insert(type_sp); +    GetTypeList().Insert(type_sp);      if (die.Tag() == DW_TAG_subprogram) {        std::string scope_qualified_name(GetDeclContextForUID(die.GetID()) @@ -2995,12 +3002,21 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,                                     bool parse_siblings, bool parse_children) {    size_t types_added = 0;    DWARFDIE die = orig_die; +    while (die) { +    const dw_tag_t tag = die.Tag();      bool type_is_new = false; -    if (ParseType(sc, die, &type_is_new).get()) { -      if (type_is_new) -        ++types_added; -    } + +    Tag dwarf_tag = static_cast<Tag>(tag); + +    // TODO: Currently ParseTypeFromDWARF(...) which is called by ParseType(...) +    // does not handle DW_TAG_subrange_type. It is not clear if this is a bug or +    // not. +    if (isType(dwarf_tag) && tag != DW_TAG_subrange_type) +      ParseType(sc, die, &type_is_new); + +    if (type_is_new) +      ++types_added;      if (parse_children && die.HasChildren()) {        if (die.Tag() == DW_TAG_subprogram) { @@ -3020,7 +3036,7 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,  }  size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) { -  ASSERT_MODULE_LOCK(this); +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    CompileUnit *comp_unit = func.GetCompileUnit();    lldbassert(comp_unit); @@ -3040,7 +3056,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {  }  size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) { -  ASSERT_MODULE_LOCK(this); +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    size_t types_added = 0;    DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);    if (dwarf_cu) { @@ -3056,7 +3072,7 @@ size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) {  }  size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { -  ASSERT_MODULE_LOCK(this); +  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());    if (sc.comp_unit != nullptr) {      DWARFDebugInfo *info = DebugInfo();      if (info == nullptr) @@ -3193,15 +3209,18 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,                  uint32_t block_offset =                      form_value.BlockData() - debug_info_data.GetDataStart();                  uint32_t block_length = form_value.Unsigned(); -                location = DWARFExpression(module, debug_info_data, die.GetCU(), -                                           block_offset, block_length); +                location = DWARFExpression( +                    module, +                    DataExtractor(debug_info_data, block_offset, block_length), +                    die.GetCU());                } else if (DWARFFormValue::IsDataForm(form_value.Form())) {                  // Retrieve the value as a data expression.                  uint32_t data_offset = attributes.DIEOffsetAtIndex(i);                  if (auto data_length = form_value.GetFixedSize()) -                  location = -                      DWARFExpression(module, debug_info_data, die.GetCU(), -                                      data_offset, *data_length); +                  location = DWARFExpression( +                      module, +                      DataExtractor(debug_info_data, data_offset, *data_length), +                      die.GetCU());                  else {                    const uint8_t *data_pointer = form_value.BlockData();                    if (data_pointer) { @@ -3217,17 +3236,21 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,                  if (form_value.Form() == DW_FORM_strp) {                    uint32_t data_offset = attributes.DIEOffsetAtIndex(i);                    if (auto data_length = form_value.GetFixedSize()) -                    location = -                        DWARFExpression(module, debug_info_data, die.GetCU(), -                                        data_offset, *data_length); +                    location = DWARFExpression(module, +                                               DataExtractor(debug_info_data, +                                                             data_offset, +                                                             *data_length), +                                               die.GetCU());                  } else {                    const char *str = form_value.AsCString();                    uint32_t string_offset =                        str - (const char *)debug_info_data.GetDataStart();                    uint32_t string_length = strlen(str) + 1; -                  location = -                      DWARFExpression(module, debug_info_data, die.GetCU(), -                                      string_offset, string_length); +                  location = DWARFExpression(module, +                                             DataExtractor(debug_info_data, +                                                           string_offset, +                                                           string_length), +                                             die.GetCU());                  }                }              } @@ -3241,17 +3264,15 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,                uint32_t block_offset =                    form_value.BlockData() - data.GetDataStart();                uint32_t block_length = form_value.Unsigned(); -              location = DWARFExpression(module, data, die.GetCU(), -                                         block_offset, block_length); +              location = DWARFExpression( +                  module, DataExtractor(data, block_offset, block_length), +                  die.GetCU());              } else { -              const DWARFDataExtractor &debug_loc_data = DebugLocData(); -              const dw_offset_t debug_loc_offset = form_value.Unsigned(); - -              size_t loc_list_length = DWARFExpression::LocationListSize( -                  die.GetCU(), debug_loc_data, debug_loc_offset); -              if (loc_list_length > 0) { -                location = DWARFExpression(module, debug_loc_data, die.GetCU(), -                                           debug_loc_offset, loc_list_length); +              DataExtractor data = DebugLocData(); +              const dw_offset_t offset = form_value.Unsigned(); +              if (data.ValidOffset(offset)) { +                data = DataExtractor(data, offset, data.GetByteSize() - offset); +                location = DWARFExpression(module, data, die.GetCU());                  assert(func_low_pc != LLDB_INVALID_ADDRESS);                  location.SetLocationListSlide(                      func_low_pc - @@ -3522,6 +3543,8 @@ SymbolFileDWARF::FindBlockContainingSpecification(            spec_block_die_offset)          return die;      } break; +    default: +      break;      }      // Give the concrete function die specified by "func_die_offset", find the @@ -3577,8 +3600,7 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,              } else {                GetObjectFile()->GetModule()->ReportError(                    "parent 0x%8.8" PRIx64 " %s with no valid compile unit in " -                                         "symbol context for 0x%8.8" PRIx64 -                  " %s.\n", +                  "symbol context for 0x%8.8" PRIx64 " %s.\n",                    sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(),                    orig_die.GetID(), orig_die.GetTagAsCString());              } @@ -3654,9 +3676,57 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,    return vars_added;  } +/// Collect call site parameters in a DW_TAG_call_site DIE. +static CallSiteParameterArray +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) +      continue; + +    llvm::Optional<DWARFExpression> LocationInCallee = {}; +    llvm::Optional<DWARFExpression> LocationInCaller = {}; + +    DWARFAttributes attributes; +    const size_t num_attributes = child.GetAttributes(attributes); + +    // Parse the location at index \p attr_index within this call site parameter +    // DIE, or return None on failure. +    auto parse_simple_location = +        [&](int attr_index) -> llvm::Optional<DWARFExpression> { +      DWARFFormValue form_value; +      if (!attributes.ExtractFormValueAtIndex(attr_index, form_value)) +        return {}; +      if (!DWARFFormValue::IsBlockForm(form_value.Form())) +        return {}; +      auto data = child.GetData(); +      uint32_t block_offset = form_value.BlockData() - data.GetDataStart(); +      uint32_t block_length = form_value.Unsigned(); +      return DWARFExpression(module, +                             DataExtractor(data, block_offset, block_length), +                             child.GetCU()); +    }; + +    for (size_t i = 0; i < num_attributes; ++i) { +      dw_attr_t attr = attributes.AttributeAtIndex(i); +      if (attr == DW_AT_location) +        LocationInCallee = parse_simple_location(i); +      if (attr == DW_AT_call_value) +        LocationInCaller = parse_simple_location(i); +    } + +    if (LocationInCallee && LocationInCaller) { +      CallSiteParameter param = {*LocationInCallee, *LocationInCaller}; +      parameters.push_back(param); +    } +  } +  return parameters; +} +  /// Collect call graph edges present in a function DIE.  static std::vector<lldb_private::CallEdge> -CollectCallEdges(DWARFDIE function_die) { +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 = @@ -3693,9 +3763,28 @@ CollectCallEdges(DWARFDIE function_die) {      addr_t return_pc = child.GetAttributeValueAsAddress(DW_AT_call_return_pc,                                                          LLDB_INVALID_ADDRESS); +    // Extract call site parameters. +    CallSiteParameterArray parameters = +        CollectCallSiteParameters(module, child); +      LLDB_LOG(log, "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x})",               call_origin.GetPubname(), return_pc); -    call_edges.emplace_back(call_origin.GetMangledName(), return_pc); +    if (log && parameters.size()) { +      for (const CallSiteParameter ¶m : parameters) { +        StreamString callee_loc_desc, caller_loc_desc; +        param.LocationInCallee.GetDescription(&callee_loc_desc, +                                              eDescriptionLevelBrief, +                                              LLDB_INVALID_ADDRESS, nullptr); +        param.LocationInCaller.GetDescription(&caller_loc_desc, +                                              eDescriptionLevelBrief, +                                              LLDB_INVALID_ADDRESS, nullptr); +        LLDB_LOG(log, "CollectCallEdges: \tparam: {0} => {1}", +                 callee_loc_desc.GetString(), caller_loc_desc.GetString()); +      } +    } + +    call_edges.emplace_back(call_origin.GetMangledName(), return_pc, +                            std::move(parameters));    }    return call_edges;  } @@ -3704,7 +3793,7 @@ std::vector<lldb_private::CallEdge>  SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) {    DWARFDIE func_die = GetDIE(func_id.GetID());    if (func_die.IsValid()) -    return CollectCallEdges(func_die); +    return CollectCallEdges(GetObjectFile()->GetModule(), func_die);    return {};  } @@ -3713,11 +3802,17 @@ ConstString SymbolFileDWARF::GetPluginName() { return GetPluginNameStatic(); }  uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; } -void SymbolFileDWARF::Dump(lldb_private::Stream &s) { m_index->Dump(s); } +void SymbolFileDWARF::Dump(lldb_private::Stream &s) { +  SymbolFile::Dump(s); +  m_index->Dump(s); +}  void SymbolFileDWARF::DumpClangAST(Stream &s) { -  TypeSystem *ts = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus); -  ClangASTContext *clang = llvm::dyn_cast_or_null<ClangASTContext>(ts); +  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());    if (!clang)      return;    clang->Dump(s); @@ -3727,10 +3822,8 @@ SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {    if (m_debug_map_symfile == nullptr && !m_debug_map_module_wp.expired()) {      lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());      if (module_sp) { -      SymbolVendor *sym_vendor = module_sp->GetSymbolVendor(); -      if (sym_vendor) -        m_debug_map_symfile = -            (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile(); +      m_debug_map_symfile = +          (SymbolFileDWARFDebugMap *)module_sp->GetSymbolFile();      }    }    return m_debug_map_symfile; @@ -3746,9 +3839,9 @@ SymbolFileDWARF::GetLocationListFormat() const {  SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() {    llvm::call_once(m_dwp_symfile_once_flag, [this]() {      ModuleSpec module_spec; -    module_spec.GetFileSpec() = m_obj_file->GetFileSpec(); +    module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();      module_spec.GetSymbolFileSpec() = -        FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp"); +        FileSpec(m_objfile_sp->GetFileSpec().GetPath() + ".dwp");      FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();      FileSpec dwp_filespec = | 
