xref: /llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (revision 57b48987f6c21e369e7bb1626dc79ca74aa34fdb)
1 //===-- SymbolFileDWARF.cpp -----------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "SymbolFileDWARF.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
12 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
13 #include "llvm/Support/Casting.h"
14 #include "llvm/Support/FileUtilities.h"
15 #include "llvm/Support/FormatAdapters.h"
16 #include "llvm/Support/Threading.h"
17 
18 #include "lldb/Core/Module.h"
19 #include "lldb/Core/ModuleList.h"
20 #include "lldb/Core/ModuleSpec.h"
21 #include "lldb/Core/PluginManager.h"
22 #include "lldb/Core/Progress.h"
23 #include "lldb/Core/Section.h"
24 #include "lldb/Core/Value.h"
25 #include "lldb/Utility/ArchSpec.h"
26 #include "lldb/Utility/LLDBLog.h"
27 #include "lldb/Utility/RegularExpression.h"
28 #include "lldb/Utility/Scalar.h"
29 #include "lldb/Utility/StreamString.h"
30 #include "lldb/Utility/StructuredData.h"
31 #include "lldb/Utility/Timer.h"
32 
33 #include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
34 #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
35 
36 #include "lldb/Host/FileSystem.h"
37 #include "lldb/Host/Host.h"
38 
39 #include "lldb/Interpreter/OptionValueFileSpecList.h"
40 #include "lldb/Interpreter/OptionValueProperties.h"
41 
42 #include "Plugins/ExpressionParser/Clang/ClangUtil.h"
43 #include "Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h"
44 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
45 #include "lldb/Symbol/Block.h"
46 #include "lldb/Symbol/CompileUnit.h"
47 #include "lldb/Symbol/CompilerDecl.h"
48 #include "lldb/Symbol/CompilerDeclContext.h"
49 #include "lldb/Symbol/DebugMacros.h"
50 #include "lldb/Symbol/LineTable.h"
51 #include "lldb/Symbol/ObjectFile.h"
52 #include "lldb/Symbol/SymbolFile.h"
53 #include "lldb/Symbol/TypeMap.h"
54 #include "lldb/Symbol/TypeSystem.h"
55 #include "lldb/Symbol/VariableList.h"
56 
57 #include "lldb/Target/Language.h"
58 #include "lldb/Target/Target.h"
59 
60 #include "AppleDWARFIndex.h"
61 #include "DWARFASTParser.h"
62 #include "DWARFASTParserClang.h"
63 #include "DWARFCompileUnit.h"
64 #include "DWARFDebugAranges.h"
65 #include "DWARFDebugInfo.h"
66 #include "DWARFDebugMacro.h"
67 #include "DWARFDeclContext.h"
68 #include "DWARFFormValue.h"
69 #include "DWARFTypeUnit.h"
70 #include "DWARFUnit.h"
71 #include "DebugNamesDWARFIndex.h"
72 #include "LogChannelDWARF.h"
73 #include "ManualDWARFIndex.h"
74 #include "SymbolFileDWARFDebugMap.h"
75 #include "SymbolFileDWARFDwo.h"
76 
77 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
78 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
79 #include "llvm/Support/FileSystem.h"
80 #include "llvm/Support/FormatVariadic.h"
81 
82 #include <algorithm>
83 #include <map>
84 #include <memory>
85 #include <optional>
86 
87 #include <cctype>
88 #include <cstring>
89 
90 //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
91 
92 #ifdef ENABLE_DEBUG_PRINTF
93 #include <cstdio>
94 #define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
95 #else
96 #define DEBUG_PRINTF(fmt, ...)
97 #endif
98 
99 using namespace lldb;
100 using namespace lldb_private;
101 using namespace lldb_private::dwarf;
102 using namespace lldb_private::plugin::dwarf;
103 
104 LLDB_PLUGIN_DEFINE(SymbolFileDWARF)
105 
106 char SymbolFileDWARF::ID;
107 
108 namespace {
109 
110 #define LLDB_PROPERTIES_symbolfiledwarf
111 #include "SymbolFileDWARFProperties.inc"
112 
113 enum {
114 #define LLDB_PROPERTIES_symbolfiledwarf
115 #include "SymbolFileDWARFPropertiesEnum.inc"
116 };
117 
118 class PluginProperties : public Properties {
119 public:
120   static llvm::StringRef GetSettingName() {
121     return SymbolFileDWARF::GetPluginNameStatic();
122   }
123 
124   PluginProperties() {
125     m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
126     m_collection_sp->Initialize(g_symbolfiledwarf_properties);
127   }
128 
129   bool IgnoreFileIndexes() const {
130     return GetPropertyAtIndexAs<bool>(ePropertyIgnoreIndexes, false);
131   }
132 };
133 
134 } // namespace
135 
136 bool IsStructOrClassTag(llvm::dwarf::Tag Tag) {
137   return Tag == llvm::dwarf::Tag::DW_TAG_class_type ||
138          Tag == llvm::dwarf::Tag::DW_TAG_structure_type;
139 }
140 
141 static PluginProperties &GetGlobalPluginProperties() {
142   static PluginProperties g_settings;
143   return g_settings;
144 }
145 
146 static const llvm::DWARFDebugLine::LineTable *
147 ParseLLVMLineTable(DWARFContext &context, llvm::DWARFDebugLine &line,
148                    dw_offset_t line_offset, dw_offset_t unit_offset) {
149   Log *log = GetLog(DWARFLog::DebugInfo);
150 
151   llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVMDWARF();
152   llvm::DWARFContext &ctx = context.GetAsLLVM();
153   llvm::Expected<const llvm::DWARFDebugLine::LineTable *> line_table =
154       line.getOrParseLineTable(
155           data, line_offset, ctx, nullptr, [&](llvm::Error e) {
156             LLDB_LOG_ERROR(
157                 log, std::move(e),
158                 "SymbolFileDWARF::ParseLineTable failed to parse: {0}");
159           });
160 
161   if (!line_table) {
162     LLDB_LOG_ERROR(log, line_table.takeError(),
163                    "SymbolFileDWARF::ParseLineTable failed to parse: {0}");
164     return nullptr;
165   }
166   return *line_table;
167 }
168 
169 static bool ParseLLVMLineTablePrologue(DWARFContext &context,
170                                        llvm::DWARFDebugLine::Prologue &prologue,
171                                        dw_offset_t line_offset,
172                                        dw_offset_t unit_offset) {
173   Log *log = GetLog(DWARFLog::DebugInfo);
174   bool success = true;
175   llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVMDWARF();
176   llvm::DWARFContext &ctx = context.GetAsLLVM();
177   uint64_t offset = line_offset;
178   llvm::Error error = prologue.parse(
179       data, &offset,
180       [&](llvm::Error e) {
181         success = false;
182         LLDB_LOG_ERROR(log, std::move(e),
183                        "SymbolFileDWARF::ParseSupportFiles failed to parse "
184                        "line table prologue: {0}");
185       },
186       ctx, nullptr);
187   if (error) {
188     LLDB_LOG_ERROR(log, std::move(error),
189                    "SymbolFileDWARF::ParseSupportFiles failed to parse line "
190                    "table prologue: {0}");
191     return false;
192   }
193   return success;
194 }
195 
196 static std::optional<std::string>
197 GetFileByIndex(const llvm::DWARFDebugLine::Prologue &prologue, size_t idx,
198                llvm::StringRef compile_dir, FileSpec::Style style) {
199   // Try to get an absolute path first.
200   std::string abs_path;
201   auto absolute = llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath;
202   if (prologue.getFileNameByIndex(idx, compile_dir, absolute, abs_path, style))
203     return std::move(abs_path);
204 
205   // Otherwise ask for a relative path.
206   std::string rel_path;
207   auto relative = llvm::DILineInfoSpecifier::FileLineInfoKind::RawValue;
208   if (!prologue.getFileNameByIndex(idx, compile_dir, relative, rel_path, style))
209     return {};
210   return std::move(rel_path);
211 }
212 
213 static void ParseSupportFilesFromPrologue(
214     SupportFileList &support_files, const lldb::ModuleSP &module,
215     const llvm::DWARFDebugLine::Prologue &prologue, FileSpec::Style style,
216     llvm::StringRef compile_dir = {}) {
217   // Handle the case where there are no files first to avoid having to special
218   // case this later.
219   if (prologue.FileNames.empty())
220     return;
221 
222   // Before DWARF v5, the line table indexes were one based.
223   const bool is_one_based = prologue.getVersion() < 5;
224   const size_t file_names = prologue.FileNames.size();
225   const size_t first_file_idx = is_one_based ? 1 : 0;
226   const size_t last_file_idx = is_one_based ? file_names : file_names - 1;
227 
228   // Add a dummy entry to ensure the support file list indices match those we
229   // get from the debug info and line tables.
230   if (is_one_based)
231     support_files.Append(FileSpec());
232 
233   for (size_t idx = first_file_idx; idx <= last_file_idx; ++idx) {
234     std::string remapped_file;
235     if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style)) {
236       auto entry = prologue.getFileNameEntry(idx);
237       auto source = entry.Source.getAsCString();
238       if (!source)
239         consumeError(source.takeError());
240       else {
241         llvm::StringRef source_ref(*source);
242         if (!source_ref.empty()) {
243           /// Wrap a path for an in-DWARF source file. Lazily write it
244           /// to disk when Materialize() is called.
245           struct LazyDWARFSourceFile : public SupportFile {
246             LazyDWARFSourceFile(const FileSpec &fs, llvm::StringRef source,
247                                 FileSpec::Style style)
248                 : SupportFile(fs), source(source), style(style) {}
249             FileSpec tmp_file;
250             /// The file contents buffer.
251             llvm::StringRef source;
252             /// Deletes the temporary file at the end.
253             std::unique_ptr<llvm::FileRemover> remover;
254             FileSpec::Style style;
255 
256             /// Write the file contents to a temporary file.
257             const FileSpec &Materialize() override {
258               if (tmp_file)
259                 return tmp_file;
260               llvm::SmallString<0> name;
261               int fd;
262               auto orig_name = m_file_spec.GetFilename().GetStringRef();
263               auto ec = llvm::sys::fs::createTemporaryFile(
264                   "", llvm::sys::path::filename(orig_name, style), fd, name);
265               if (ec || fd <= 0) {
266                 LLDB_LOG(GetLog(DWARFLog::DebugInfo),
267                          "Could not create temporary file");
268                 return tmp_file;
269               }
270               remover = std::make_unique<llvm::FileRemover>(name);
271               NativeFile file(fd, File::eOpenOptionWriteOnly, true);
272               size_t num_bytes = source.size();
273               file.Write(source.data(), num_bytes);
274               tmp_file.SetPath(name);
275               return tmp_file;
276             }
277           };
278           support_files.Append(std::make_unique<LazyDWARFSourceFile>(
279               FileSpec(*file_path), *source, style));
280           continue;
281         }
282       }
283       if (auto remapped = module->RemapSourceFile(llvm::StringRef(*file_path)))
284         remapped_file = *remapped;
285       else
286         remapped_file = std::move(*file_path);
287     }
288 
289     Checksum checksum;
290     if (prologue.ContentTypes.HasMD5) {
291       const llvm::DWARFDebugLine::FileNameEntry &file_name_entry =
292           prologue.getFileNameEntry(idx);
293       checksum = file_name_entry.Checksum;
294     }
295 
296     // Unconditionally add an entry, so the indices match up.
297     support_files.EmplaceBack(FileSpec(remapped_file, style), checksum);
298   }
299 }
300 
301 void SymbolFileDWARF::Initialize() {
302   LogChannelDWARF::Initialize();
303   PluginManager::RegisterPlugin(GetPluginNameStatic(),
304                                 GetPluginDescriptionStatic(), CreateInstance,
305                                 DebuggerInitialize);
306   SymbolFileDWARFDebugMap::Initialize();
307 }
308 
309 void SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) {
310   if (!PluginManager::GetSettingForSymbolFilePlugin(
311           debugger, PluginProperties::GetSettingName())) {
312     const bool is_global_setting = true;
313     PluginManager::CreateSettingForSymbolFilePlugin(
314         debugger, GetGlobalPluginProperties().GetValueProperties(),
315         "Properties for the dwarf symbol-file plug-in.", is_global_setting);
316   }
317 }
318 
319 void SymbolFileDWARF::Terminate() {
320   SymbolFileDWARFDebugMap::Terminate();
321   PluginManager::UnregisterPlugin(CreateInstance);
322   LogChannelDWARF::Terminate();
323 }
324 
325 llvm::StringRef SymbolFileDWARF::GetPluginDescriptionStatic() {
326   return "DWARF and DWARF3 debug symbol file reader.";
327 }
328 
329 SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFileSP objfile_sp) {
330   return new SymbolFileDWARF(std::move(objfile_sp),
331                              /*dwo_section_list*/ nullptr);
332 }
333 
334 TypeList &SymbolFileDWARF::GetTypeList() {
335   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
336   if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
337     return debug_map_symfile->GetTypeList();
338   return SymbolFileCommon::GetTypeList();
339 }
340 void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
341                                dw_offset_t max_die_offset, uint32_t type_mask,
342                                TypeSet &type_set) {
343   if (die) {
344     const dw_offset_t die_offset = die.GetOffset();
345 
346     if (die_offset >= max_die_offset)
347       return;
348 
349     if (die_offset >= min_die_offset) {
350       const dw_tag_t tag = die.Tag();
351 
352       bool add_type = false;
353 
354       switch (tag) {
355       case DW_TAG_array_type:
356         add_type = (type_mask & eTypeClassArray) != 0;
357         break;
358       case DW_TAG_unspecified_type:
359       case DW_TAG_base_type:
360         add_type = (type_mask & eTypeClassBuiltin) != 0;
361         break;
362       case DW_TAG_class_type:
363         add_type = (type_mask & eTypeClassClass) != 0;
364         break;
365       case DW_TAG_structure_type:
366         add_type = (type_mask & eTypeClassStruct) != 0;
367         break;
368       case DW_TAG_union_type:
369         add_type = (type_mask & eTypeClassUnion) != 0;
370         break;
371       case DW_TAG_enumeration_type:
372         add_type = (type_mask & eTypeClassEnumeration) != 0;
373         break;
374       case DW_TAG_subroutine_type:
375       case DW_TAG_subprogram:
376       case DW_TAG_inlined_subroutine:
377         add_type = (type_mask & eTypeClassFunction) != 0;
378         break;
379       case DW_TAG_pointer_type:
380         add_type = (type_mask & eTypeClassPointer) != 0;
381         break;
382       case DW_TAG_rvalue_reference_type:
383       case DW_TAG_reference_type:
384         add_type = (type_mask & eTypeClassReference) != 0;
385         break;
386       case DW_TAG_typedef:
387         add_type = (type_mask & eTypeClassTypedef) != 0;
388         break;
389       case DW_TAG_ptr_to_member_type:
390         add_type = (type_mask & eTypeClassMemberPointer) != 0;
391         break;
392       default:
393         break;
394       }
395 
396       if (add_type) {
397         const bool assert_not_being_parsed = true;
398         Type *type = ResolveTypeUID(die, assert_not_being_parsed);
399         if (type)
400           type_set.insert(type);
401       }
402     }
403 
404     for (DWARFDIE child_die : die.children()) {
405       GetTypes(child_die, min_die_offset, max_die_offset, type_mask, type_set);
406     }
407   }
408 }
409 
410 void SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
411                                TypeClass type_mask, TypeList &type_list)
412 
413 {
414   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
415   TypeSet type_set;
416 
417   CompileUnit *comp_unit = nullptr;
418   if (sc_scope)
419     comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
420 
421   const auto &get = [&](DWARFUnit *unit) {
422     if (!unit)
423       return;
424     unit = &unit->GetNonSkeletonUnit();
425     GetTypes(unit->DIE(), unit->GetOffset(), unit->GetNextUnitOffset(),
426              type_mask, type_set);
427   };
428   if (comp_unit) {
429     get(GetDWARFCompileUnit(comp_unit));
430   } else {
431     DWARFDebugInfo &info = DebugInfo();
432     const size_t num_cus = info.GetNumUnits();
433     for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx)
434       get(info.GetUnitAtIndex(cu_idx));
435   }
436 
437   std::set<CompilerType> compiler_type_set;
438   for (Type *type : type_set) {
439     CompilerType compiler_type = type->GetForwardCompilerType();
440     if (compiler_type_set.find(compiler_type) == compiler_type_set.end()) {
441       compiler_type_set.insert(compiler_type);
442       type_list.Insert(type->shared_from_this());
443     }
444   }
445 }
446 
447 // Gets the first parent that is a lexical block, function or inlined
448 // subroutine, or compile unit.
449 DWARFDIE
450 SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) {
451   DWARFDIE die;
452   for (die = child_die.GetParent(); die; die = die.GetParent()) {
453     dw_tag_t tag = die.Tag();
454 
455     switch (tag) {
456     case DW_TAG_compile_unit:
457     case DW_TAG_partial_unit:
458     case DW_TAG_subprogram:
459     case DW_TAG_inlined_subroutine:
460     case DW_TAG_lexical_block:
461       return die;
462     default:
463       break;
464     }
465   }
466   return DWARFDIE();
467 }
468 
469 SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp,
470                                  SectionList *dwo_section_list)
471     : SymbolFileCommon(std::move(objfile_sp)), m_debug_map_module_wp(),
472       m_debug_map_symfile(nullptr),
473       m_context(m_objfile_sp->GetModule()->GetSectionList(), dwo_section_list),
474       m_fetched_external_modules(false) {}
475 
476 SymbolFileDWARF::~SymbolFileDWARF() = default;
477 
478 static ConstString GetDWARFMachOSegmentName() {
479   static ConstString g_dwarf_section_name("__DWARF");
480   return g_dwarf_section_name;
481 }
482 
483 llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> &
484 SymbolFileDWARF::GetDIEToType() {
485   if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
486     return debug_map_symfile->GetDIEToType();
487   return m_die_to_type;
488 }
489 
490 llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> &
491 SymbolFileDWARF::GetForwardDeclCompilerTypeToDIE() {
492   if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
493     return debug_map_symfile->GetForwardDeclCompilerTypeToDIE();
494   return m_forward_decl_compiler_type_to_die;
495 }
496 
497 UniqueDWARFASTTypeMap &SymbolFileDWARF::GetUniqueDWARFASTTypeMap() {
498   SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
499   if (debug_map_symfile)
500     return debug_map_symfile->GetUniqueDWARFASTTypeMap();
501   else
502     return m_unique_ast_type_map;
503 }
504 
505 llvm::Expected<lldb::TypeSystemSP>
506 SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {
507   if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
508     return debug_map_symfile->GetTypeSystemForLanguage(language);
509 
510   auto type_system_or_err =
511       m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
512   if (type_system_or_err)
513     if (auto ts = *type_system_or_err)
514       ts->SetSymbolFile(this);
515   return type_system_or_err;
516 }
517 
518 void SymbolFileDWARF::InitializeObject() {
519   Log *log = GetLog(DWARFLog::DebugInfo);
520 
521   InitializeFirstCodeAddress();
522 
523   if (!GetGlobalPluginProperties().IgnoreFileIndexes()) {
524     StreamString module_desc;
525     GetObjectFile()->GetModule()->GetDescription(module_desc.AsRawOstream(),
526                                                  lldb::eDescriptionLevelBrief);
527     DWARFDataExtractor apple_names, apple_namespaces, apple_types, apple_objc;
528     LoadSectionData(eSectionTypeDWARFAppleNames, apple_names);
529     LoadSectionData(eSectionTypeDWARFAppleNamespaces, apple_namespaces);
530     LoadSectionData(eSectionTypeDWARFAppleTypes, apple_types);
531     LoadSectionData(eSectionTypeDWARFAppleObjC, apple_objc);
532 
533     if (apple_names.GetByteSize() > 0 || apple_namespaces.GetByteSize() > 0 ||
534         apple_types.GetByteSize() > 0 || apple_objc.GetByteSize() > 0) {
535       m_index = AppleDWARFIndex::Create(
536           *GetObjectFile()->GetModule(), apple_names, apple_namespaces,
537           apple_types, apple_objc, m_context.getOrLoadStrData());
538 
539       if (m_index)
540         return;
541     }
542 
543     DWARFDataExtractor debug_names;
544     LoadSectionData(eSectionTypeDWARFDebugNames, debug_names);
545     if (debug_names.GetByteSize() > 0) {
546       Progress progress("Loading DWARF5 index", module_desc.GetData());
547       llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or =
548           DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(),
549                                        debug_names,
550                                        m_context.getOrLoadStrData(), *this);
551       if (index_or) {
552         m_index = std::move(*index_or);
553         return;
554       }
555       LLDB_LOG_ERROR(log, index_or.takeError(),
556                      "Unable to read .debug_names data: {0}");
557     }
558   }
559 
560   m_index =
561       std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(), *this);
562 }
563 
564 void SymbolFileDWARF::InitializeFirstCodeAddress() {
565   InitializeFirstCodeAddressRecursive(
566       *m_objfile_sp->GetModule()->GetSectionList());
567   if (m_first_code_address == LLDB_INVALID_ADDRESS)
568     m_first_code_address = 0;
569 }
570 
571 void SymbolFileDWARF::InitializeFirstCodeAddressRecursive(
572     const lldb_private::SectionList &section_list) {
573   for (SectionSP section_sp : section_list) {
574     if (section_sp->GetChildren().GetSize() > 0) {
575       InitializeFirstCodeAddressRecursive(section_sp->GetChildren());
576     } else if (section_sp->GetType() == eSectionTypeCode) {
577       m_first_code_address =
578           std::min(m_first_code_address, section_sp->GetFileAddress());
579     }
580   }
581 }
582 
583 bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
584   return version >= 2 && version <= 5;
585 }
586 
587 static std::set<dw_form_t>
588 GetUnsupportedForms(llvm::DWARFDebugAbbrev *debug_abbrev) {
589   if (!debug_abbrev)
590     return {};
591 
592   std::set<dw_form_t> unsupported_forms;
593   for (const auto &[_, decl_set] : *debug_abbrev)
594     for (const auto &decl : decl_set)
595       for (const auto &attr : decl.attributes())
596         if (!DWARFFormValue::FormIsSupported(attr.Form))
597           unsupported_forms.insert(attr.Form);
598 
599   return unsupported_forms;
600 }
601 
602 uint32_t SymbolFileDWARF::CalculateAbilities() {
603   uint32_t abilities = 0;
604   if (m_objfile_sp != nullptr) {
605     const Section *section = nullptr;
606     const SectionList *section_list = m_objfile_sp->GetSectionList();
607     if (section_list == nullptr)
608       return 0;
609 
610     uint64_t debug_abbrev_file_size = 0;
611     uint64_t debug_info_file_size = 0;
612     uint64_t debug_line_file_size = 0;
613 
614     section = section_list->FindSectionByName(GetDWARFMachOSegmentName()).get();
615 
616     if (section)
617       section_list = &section->GetChildren();
618 
619     section =
620         section_list->FindSectionByType(eSectionTypeDWARFDebugInfo, true).get();
621     if (section != nullptr) {
622       debug_info_file_size = section->GetFileSize();
623 
624       section =
625           section_list->FindSectionByType(eSectionTypeDWARFDebugAbbrev, true)
626               .get();
627       if (section)
628         debug_abbrev_file_size = section->GetFileSize();
629 
630       llvm::DWARFDebugAbbrev *abbrev = DebugAbbrev();
631       std::set<dw_form_t> unsupported_forms = GetUnsupportedForms(abbrev);
632       if (!unsupported_forms.empty()) {
633         StreamString error;
634         error.Printf("unsupported DW_FORM value%s:",
635                      unsupported_forms.size() > 1 ? "s" : "");
636         for (auto form : unsupported_forms)
637           error.Printf(" %#x", form);
638         m_objfile_sp->GetModule()->ReportWarning("{0}", error.GetString());
639         return 0;
640       }
641 
642       section =
643           section_list->FindSectionByType(eSectionTypeDWARFDebugLine, true)
644               .get();
645       if (section)
646         debug_line_file_size = section->GetFileSize();
647     } else {
648       llvm::StringRef symfile_dir =
649           m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef();
650       if (symfile_dir.contains_insensitive(".dsym")) {
651         if (m_objfile_sp->GetType() == ObjectFile::eTypeDebugInfo) {
652           // We have a dSYM file that didn't have a any debug info. If the
653           // string table has a size of 1, then it was made from an
654           // executable with no debug info, or from an executable that was
655           // stripped.
656           section =
657               section_list->FindSectionByType(eSectionTypeDWARFDebugStr, true)
658                   .get();
659           if (section && section->GetFileSize() == 1) {
660             m_objfile_sp->GetModule()->ReportWarning(
661                 "empty dSYM file detected, dSYM was created with an "
662                 "executable with no debug info.");
663           }
664         }
665       }
666     }
667 
668     constexpr uint64_t MaxDebugInfoSize = (1ull) << DW_DIE_OFFSET_MAX_BITSIZE;
669     if (debug_info_file_size >= MaxDebugInfoSize) {
670       m_objfile_sp->GetModule()->ReportWarning(
671           "SymbolFileDWARF can't load this DWARF. It's larger then {0:x+16}",
672           MaxDebugInfoSize);
673       return 0;
674     }
675 
676     if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
677       abilities |= CompileUnits | Functions | Blocks | GlobalVariables |
678                    LocalVariables | VariableTypes;
679 
680     if (debug_line_file_size > 0)
681       abilities |= LineTables;
682   }
683   return abilities;
684 }
685 
686 void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,
687                                       DWARFDataExtractor &data) {
688   ModuleSP module_sp(m_objfile_sp->GetModule());
689   const SectionList *section_list = module_sp->GetSectionList();
690   if (!section_list)
691     return;
692 
693   SectionSP section_sp(section_list->FindSectionByType(sect_type, true));
694   if (!section_sp)
695     return;
696 
697   data.Clear();
698   m_objfile_sp->ReadSectionData(section_sp.get(), data);
699 }
700 
701 llvm::DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
702   if (m_abbr)
703     return m_abbr.get();
704 
705   const DWARFDataExtractor &debug_abbrev_data = m_context.getOrLoadAbbrevData();
706   if (debug_abbrev_data.GetByteSize() == 0)
707     return nullptr;
708 
709   ElapsedTime elapsed(m_parse_time);
710   auto abbr =
711       std::make_unique<llvm::DWARFDebugAbbrev>(debug_abbrev_data.GetAsLLVM());
712   llvm::Error error = abbr->parse();
713   if (error) {
714     Log *log = GetLog(DWARFLog::DebugInfo);
715     LLDB_LOG_ERROR(log, std::move(error),
716                    "Unable to read .debug_abbrev section: {0}");
717     return nullptr;
718   }
719 
720   m_abbr = std::move(abbr);
721   return m_abbr.get();
722 }
723 
724 DWARFDebugInfo &SymbolFileDWARF::DebugInfo() {
725   llvm::call_once(m_info_once_flag, [&] {
726     LLDB_SCOPED_TIMER();
727 
728     m_info = std::make_unique<DWARFDebugInfo>(*this, m_context);
729   });
730   return *m_info;
731 }
732 
733 DWARFCompileUnit *SymbolFileDWARF::GetDWARFCompileUnit(CompileUnit *comp_unit) {
734   if (!comp_unit)
735     return nullptr;
736 
737   // The compile unit ID is the index of the DWARF unit.
738   DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(comp_unit->GetID());
739   if (dwarf_cu && dwarf_cu->GetLLDBCompUnit() == nullptr)
740     dwarf_cu->SetLLDBCompUnit(comp_unit);
741 
742   // It must be DWARFCompileUnit when it created a CompileUnit.
743   return llvm::cast_or_null<DWARFCompileUnit>(dwarf_cu);
744 }
745 
746 /// Make an absolute path out of \p file_spec and remap it using the
747 /// module's source remapping dictionary.
748 static void MakeAbsoluteAndRemap(FileSpec &file_spec, DWARFUnit &dwarf_cu,
749                                  const ModuleSP &module_sp) {
750   if (!file_spec)
751     return;
752   // If we have a full path to the compile unit, we don't need to
753   // resolve the file.  This can be expensive e.g. when the source
754   // files are NFS mounted.
755   file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory());
756 
757   if (auto remapped_file = module_sp->RemapSourceFile(file_spec.GetPath()))
758     file_spec.SetFile(*remapped_file, FileSpec::Style::native);
759 }
760 
761 /// Return the DW_AT_(GNU_)dwo_name.
762 static const char *GetDWOName(DWARFCompileUnit &dwarf_cu,
763                               const DWARFDebugInfoEntry &cu_die) {
764   const char *dwo_name =
765       cu_die.GetAttributeValueAsString(&dwarf_cu, DW_AT_GNU_dwo_name, nullptr);
766   if (!dwo_name)
767     dwo_name =
768         cu_die.GetAttributeValueAsString(&dwarf_cu, DW_AT_dwo_name, nullptr);
769   return dwo_name;
770 }
771 
772 lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
773   CompUnitSP cu_sp;
774   CompileUnit *comp_unit = dwarf_cu.GetLLDBCompUnit();
775   if (comp_unit) {
776     // We already parsed this compile unit, had out a shared pointer to it
777     cu_sp = comp_unit->shared_from_this();
778   } else {
779     if (GetDebugMapSymfile()) {
780       // Let the debug map create the compile unit
781       cu_sp = m_debug_map_symfile->GetCompileUnit(this, dwarf_cu);
782       dwarf_cu.SetLLDBCompUnit(cu_sp.get());
783     } else {
784       ModuleSP module_sp(m_objfile_sp->GetModule());
785       if (module_sp) {
786         auto initialize_cu = [&](lldb::SupportFileSP support_file_sp,
787                                  LanguageType cu_language,
788                                  SupportFileList &&support_files = {}) {
789           BuildCuTranslationTable();
790           cu_sp = std::make_shared<CompileUnit>(
791               module_sp, &dwarf_cu, support_file_sp,
792               *GetDWARFUnitIndex(dwarf_cu.GetID()), cu_language,
793               eLazyBoolCalculate, std::move(support_files));
794 
795           dwarf_cu.SetLLDBCompUnit(cu_sp.get());
796 
797           SetCompileUnitAtIndex(dwarf_cu.GetID(), cu_sp);
798         };
799 
800         auto lazy_initialize_cu = [&]() {
801           // If the version is < 5, we can't do lazy initialization.
802           if (dwarf_cu.GetVersion() < 5)
803             return false;
804 
805           // If there is no DWO, there is no reason to initialize
806           // lazily; we will do eager initialization in that case.
807           if (GetDebugMapSymfile())
808             return false;
809           const DWARFBaseDIE cu_die = dwarf_cu.GetUnitDIEOnly();
810           if (!cu_die)
811             return false;
812           if (!GetDWOName(dwarf_cu, *cu_die.GetDIE()))
813             return false;
814 
815           // With DWARFv5 we can assume that the first support
816           // file is also the name of the compile unit. This
817           // allows us to avoid loading the non-skeleton unit,
818           // which may be in a separate DWO file.
819           SupportFileList support_files;
820           if (!ParseSupportFiles(dwarf_cu, module_sp, support_files))
821             return false;
822           if (support_files.GetSize() == 0)
823             return false;
824           initialize_cu(support_files.GetSupportFileAtIndex(0),
825                         eLanguageTypeUnknown, std::move(support_files));
826           return true;
827         };
828 
829         if (!lazy_initialize_cu()) {
830           // Eagerly initialize compile unit
831           const DWARFBaseDIE cu_die =
832               dwarf_cu.GetNonSkeletonUnit().GetUnitDIEOnly();
833           if (cu_die) {
834             LanguageType cu_language = SymbolFileDWARF::LanguageTypeFromDWARF(
835                 dwarf_cu.GetDWARFLanguageType());
836 
837             FileSpec cu_file_spec(cu_die.GetName(), dwarf_cu.GetPathStyle());
838 
839             // Path needs to be remapped in this case. In the support files
840             // case ParseSupportFiles takes care of the remapping.
841             MakeAbsoluteAndRemap(cu_file_spec, dwarf_cu, module_sp);
842 
843             initialize_cu(std::make_shared<SupportFile>(cu_file_spec),
844                           cu_language);
845           }
846         }
847       }
848     }
849   }
850   return cu_sp;
851 }
852 
853 void SymbolFileDWARF::BuildCuTranslationTable() {
854   if (!m_lldb_cu_to_dwarf_unit.empty())
855     return;
856 
857   DWARFDebugInfo &info = DebugInfo();
858   if (!info.ContainsTypeUnits()) {
859     // We can use a 1-to-1 mapping. No need to build a translation table.
860     return;
861   }
862   for (uint32_t i = 0, num = info.GetNumUnits(); i < num; ++i) {
863     if (auto *cu = llvm::dyn_cast<DWARFCompileUnit>(info.GetUnitAtIndex(i))) {
864       cu->SetID(m_lldb_cu_to_dwarf_unit.size());
865       m_lldb_cu_to_dwarf_unit.push_back(i);
866     }
867   }
868 }
869 
870 std::optional<uint32_t> SymbolFileDWARF::GetDWARFUnitIndex(uint32_t cu_idx) {
871   BuildCuTranslationTable();
872   if (m_lldb_cu_to_dwarf_unit.empty())
873     return cu_idx;
874   if (cu_idx >= m_lldb_cu_to_dwarf_unit.size())
875     return std::nullopt;
876   return m_lldb_cu_to_dwarf_unit[cu_idx];
877 }
878 
879 uint32_t SymbolFileDWARF::CalculateNumCompileUnits() {
880   BuildCuTranslationTable();
881   return m_lldb_cu_to_dwarf_unit.empty() ? DebugInfo().GetNumUnits()
882                                          : m_lldb_cu_to_dwarf_unit.size();
883 }
884 
885 CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
886   ASSERT_MODULE_LOCK(this);
887   if (std::optional<uint32_t> dwarf_idx = GetDWARFUnitIndex(cu_idx)) {
888     if (auto *dwarf_cu = llvm::cast_or_null<DWARFCompileUnit>(
889             DebugInfo().GetUnitAtIndex(*dwarf_idx)))
890       return ParseCompileUnit(*dwarf_cu);
891   }
892   return {};
893 }
894 
895 Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
896                                          const DWARFDIE &die) {
897   ASSERT_MODULE_LOCK(this);
898   Log *log = GetLog(LLDBLog::Symbols);
899   if (!die.IsValid())
900     return nullptr;
901 
902   auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));
903   if (auto err = type_system_or_err.takeError()) {
904     LLDB_LOG_ERROR(log, std::move(err), "Unable to parse function: {0}");
905     return nullptr;
906   }
907   auto ts = *type_system_or_err;
908   if (!ts)
909     return nullptr;
910   DWARFASTParser *dwarf_ast = ts->GetDWARFParser();
911   if (!dwarf_ast)
912     return nullptr;
913 
914   AddressRanges ranges;
915   ModuleSP module_sp(die.GetModule());
916   if (llvm::Expected<llvm::DWARFAddressRangesVector> die_ranges =
917           die.GetDIE()->GetAttributeAddressRanges(die.GetCU(),
918                                                   /*check_hi_lo_pc=*/true)) {
919     for (const auto &range : *die_ranges) {
920       if (range.valid() && range.LowPC < m_first_code_address)
921         continue;
922       if (Address base_addr(range.LowPC, module_sp->GetSectionList());
923           base_addr.IsValid() && FixupAddress(base_addr))
924         ranges.emplace_back(std::move(base_addr), range.HighPC - range.LowPC);
925     }
926   } else {
927     LLDB_LOG_ERROR(log, die_ranges.takeError(), "DIE({1:x}): {0}", die.GetID());
928   }
929   if (ranges.empty())
930     return nullptr;
931 
932   return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die, std::move(ranges));
933 }
934 
935 ConstString
936 SymbolFileDWARF::ConstructFunctionDemangledName(const DWARFDIE &die) {
937   ASSERT_MODULE_LOCK(this);
938   if (!die.IsValid()) {
939     return ConstString();
940   }
941 
942   auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));
943   if (auto err = type_system_or_err.takeError()) {
944     LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
945                    "Unable to construct demangled name for function: {0}");
946     return ConstString();
947   }
948 
949   auto ts = *type_system_or_err;
950   if (!ts) {
951     LLDB_LOG(GetLog(LLDBLog::Symbols), "Type system no longer live");
952     return ConstString();
953   }
954   DWARFASTParser *dwarf_ast = ts->GetDWARFParser();
955   if (!dwarf_ast)
956     return ConstString();
957 
958   return dwarf_ast->ConstructDemangledNameFromDWARF(die);
959 }
960 
961 lldb::addr_t SymbolFileDWARF::FixupAddress(lldb::addr_t file_addr) {
962   SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
963   if (debug_map_symfile)
964     return debug_map_symfile->LinkOSOFileAddress(this, file_addr);
965   return file_addr;
966 }
967 
968 bool SymbolFileDWARF::FixupAddress(Address &addr) {
969   SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
970   if (debug_map_symfile) {
971     return debug_map_symfile->LinkOSOAddress(addr);
972   }
973   // This is a normal DWARF file, no address fixups need to happen
974   return true;
975 }
976 lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) {
977   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
978   DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
979   if (dwarf_cu)
980     return GetLanguage(dwarf_cu->GetNonSkeletonUnit());
981   else
982     return eLanguageTypeUnknown;
983 }
984 
985 XcodeSDK SymbolFileDWARF::ParseXcodeSDK(CompileUnit &comp_unit) {
986   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
987   DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
988   if (!dwarf_cu)
989     return {};
990   const DWARFBaseDIE cu_die = dwarf_cu->GetNonSkeletonUnit().GetUnitDIEOnly();
991   if (!cu_die)
992     return {};
993   const char *sdk = cu_die.GetAttributeValueAsString(DW_AT_APPLE_sdk, nullptr);
994   if (!sdk)
995     return {};
996   const char *sysroot =
997       cu_die.GetAttributeValueAsString(DW_AT_LLVM_sysroot, "");
998   // Register the sysroot path remapping with the module belonging to
999   // the CU as well as the one belonging to the symbol file. The two
1000   // would be different if this is an OSO object and module is the
1001   // corresponding debug map, in which case both should be updated.
1002   ModuleSP module_sp = comp_unit.GetModule();
1003   if (module_sp)
1004     module_sp->RegisterXcodeSDK(sdk, sysroot);
1005 
1006   ModuleSP local_module_sp = m_objfile_sp->GetModule();
1007   if (local_module_sp && local_module_sp != module_sp)
1008     local_module_sp->RegisterXcodeSDK(sdk, sysroot);
1009 
1010   return {sdk};
1011 }
1012 
1013 size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {
1014   LLDB_SCOPED_TIMER();
1015   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1016   DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
1017   if (!dwarf_cu)
1018     return 0;
1019 
1020   size_t functions_added = 0;
1021   dwarf_cu = &dwarf_cu->GetNonSkeletonUnit();
1022   for (DWARFDebugInfoEntry &entry : dwarf_cu->dies()) {
1023     if (entry.Tag() != DW_TAG_subprogram)
1024       continue;
1025 
1026     DWARFDIE die(dwarf_cu, &entry);
1027     if (comp_unit.FindFunctionByUID(die.GetID()))
1028       continue;
1029     if (ParseFunction(comp_unit, die))
1030       ++functions_added;
1031   }
1032   // FixupTypes();
1033   return functions_added;
1034 }
1035 
1036 bool SymbolFileDWARF::ForEachExternalModule(
1037     CompileUnit &comp_unit,
1038     llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,
1039     llvm::function_ref<bool(Module &)> lambda) {
1040   // Only visit each symbol file once.
1041   if (!visited_symbol_files.insert(this).second)
1042     return false;
1043 
1044   UpdateExternalModuleListIfNeeded();
1045   for (auto &p : m_external_type_modules) {
1046     ModuleSP module = p.second;
1047     if (!module)
1048       continue;
1049 
1050     // Invoke the action and potentially early-exit.
1051     if (lambda(*module))
1052       return true;
1053 
1054     for (std::size_t i = 0; i < module->GetNumCompileUnits(); ++i) {
1055       auto cu = module->GetCompileUnitAtIndex(i);
1056       bool early_exit = cu->ForEachExternalModule(visited_symbol_files, lambda);
1057       if (early_exit)
1058         return true;
1059     }
1060   }
1061   return false;
1062 }
1063 
1064 bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit,
1065                                         SupportFileList &support_files) {
1066   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1067   DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
1068   if (!dwarf_cu)
1069     return false;
1070 
1071   if (!ParseSupportFiles(*dwarf_cu, comp_unit.GetModule(), support_files))
1072     return false;
1073 
1074   return true;
1075 }
1076 
1077 bool SymbolFileDWARF::ParseSupportFiles(DWARFUnit &dwarf_cu,
1078                                         const ModuleSP &module,
1079                                         SupportFileList &support_files) {
1080 
1081   dw_offset_t offset = dwarf_cu.GetLineTableOffset();
1082   if (offset == DW_INVALID_OFFSET)
1083     return false;
1084 
1085   ElapsedTime elapsed(m_parse_time);
1086   llvm::DWARFDebugLine::Prologue prologue;
1087   if (!ParseLLVMLineTablePrologue(m_context, prologue, offset,
1088                                   dwarf_cu.GetOffset()))
1089     return false;
1090 
1091   std::string comp_dir = dwarf_cu.GetCompilationDirectory().GetPath();
1092   ParseSupportFilesFromPrologue(support_files, module, prologue,
1093                                 dwarf_cu.GetPathStyle(), comp_dir);
1094   return true;
1095 }
1096 
1097 FileSpec SymbolFileDWARF::GetFile(DWARFUnit &unit, size_t file_idx) {
1098   if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(&unit)) {
1099     if (CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(*dwarf_cu))
1100       return lldb_cu->GetSupportFiles().GetFileSpecAtIndex(file_idx);
1101     return FileSpec();
1102   }
1103 
1104   auto &tu = llvm::cast<DWARFTypeUnit>(unit);
1105   if (const SupportFileList *support_files = GetTypeUnitSupportFiles(tu))
1106     return support_files->GetFileSpecAtIndex(file_idx);
1107   return {};
1108 }
1109 
1110 const SupportFileList *
1111 SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit &tu) {
1112   static SupportFileList empty_list;
1113 
1114   dw_offset_t offset = tu.GetLineTableOffset();
1115   if (offset == DW_INVALID_OFFSET ||
1116       offset == llvm::DenseMapInfo<dw_offset_t>::getEmptyKey() ||
1117       offset == llvm::DenseMapInfo<dw_offset_t>::getTombstoneKey())
1118     return nullptr;
1119 
1120   // Many type units can share a line table, so parse the support file list
1121   // once, and cache it based on the offset field.
1122   auto iter_bool = m_type_unit_support_files.try_emplace(offset);
1123   std::unique_ptr<SupportFileList> &list = iter_bool.first->second;
1124   if (iter_bool.second) {
1125     list = std::make_unique<SupportFileList>();
1126     uint64_t line_table_offset = offset;
1127     llvm::DWARFDataExtractor data =
1128         m_context.getOrLoadLineData().GetAsLLVMDWARF();
1129     llvm::DWARFContext &ctx = m_context.GetAsLLVM();
1130     llvm::DWARFDebugLine::Prologue prologue;
1131     auto report = [](llvm::Error error) {
1132       Log *log = GetLog(DWARFLog::DebugInfo);
1133       LLDB_LOG_ERROR(log, std::move(error),
1134                      "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse "
1135                      "the line table prologue: {0}");
1136     };
1137     ElapsedTime elapsed(m_parse_time);
1138     llvm::Error error = prologue.parse(data, &line_table_offset, report, ctx);
1139     if (error)
1140       report(std::move(error));
1141     else
1142       ParseSupportFilesFromPrologue(*list, GetObjectFile()->GetModule(),
1143                                     prologue, tu.GetPathStyle());
1144   }
1145   return list.get();
1146 }
1147 
1148 bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) {
1149   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1150   DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
1151   if (dwarf_cu)
1152     return dwarf_cu->GetNonSkeletonUnit().GetIsOptimized();
1153   return false;
1154 }
1155 
1156 bool SymbolFileDWARF::ParseImportedModules(
1157     const lldb_private::SymbolContext &sc,
1158     std::vector<SourceModule> &imported_modules) {
1159   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1160   assert(sc.comp_unit);
1161   DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1162   if (!dwarf_cu)
1163     return false;
1164   if (!ClangModulesDeclVendor::LanguageSupportsClangModules(
1165           sc.comp_unit->GetLanguage()))
1166     return false;
1167   UpdateExternalModuleListIfNeeded();
1168 
1169   const DWARFDIE die = dwarf_cu->DIE();
1170   if (!die)
1171     return false;
1172 
1173   for (DWARFDIE child_die : die.children()) {
1174     if (child_die.Tag() != DW_TAG_imported_declaration)
1175       continue;
1176 
1177     DWARFDIE module_die = child_die.GetReferencedDIE(DW_AT_import);
1178     if (module_die.Tag() != DW_TAG_module)
1179       continue;
1180 
1181     if (const char *name =
1182             module_die.GetAttributeValueAsString(DW_AT_name, nullptr)) {
1183       SourceModule module;
1184       module.path.push_back(ConstString(name));
1185 
1186       DWARFDIE parent_die = module_die;
1187       while ((parent_die = parent_die.GetParent())) {
1188         if (parent_die.Tag() != DW_TAG_module)
1189           break;
1190         if (const char *name =
1191                 parent_die.GetAttributeValueAsString(DW_AT_name, nullptr))
1192           module.path.push_back(ConstString(name));
1193       }
1194       std::reverse(module.path.begin(), module.path.end());
1195       if (const char *include_path = module_die.GetAttributeValueAsString(
1196               DW_AT_LLVM_include_path, nullptr)) {
1197         FileSpec include_spec(include_path, dwarf_cu->GetPathStyle());
1198         MakeAbsoluteAndRemap(include_spec, *dwarf_cu,
1199                              m_objfile_sp->GetModule());
1200         module.search_path = ConstString(include_spec.GetPath());
1201       }
1202       if (const char *sysroot = dwarf_cu->DIE().GetAttributeValueAsString(
1203               DW_AT_LLVM_sysroot, nullptr))
1204         module.sysroot = ConstString(sysroot);
1205       imported_modules.push_back(module);
1206     }
1207   }
1208   return true;
1209 }
1210 
1211 bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
1212   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1213   if (comp_unit.GetLineTable() != nullptr)
1214     return true;
1215 
1216   DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
1217   if (!dwarf_cu)
1218     return false;
1219 
1220   dw_offset_t offset = dwarf_cu->GetLineTableOffset();
1221   if (offset == DW_INVALID_OFFSET)
1222     return false;
1223 
1224   ElapsedTime elapsed(m_parse_time);
1225   llvm::DWARFDebugLine line;
1226   const llvm::DWARFDebugLine::LineTable *line_table =
1227       ParseLLVMLineTable(m_context, line, offset, dwarf_cu->GetOffset());
1228 
1229   if (!line_table)
1230     return false;
1231 
1232   // FIXME: Rather than parsing the whole line table and then copying it over
1233   // into LLDB, we should explore using a callback to populate the line table
1234   // while we parse to reduce memory usage.
1235   std::vector<std::unique_ptr<LineSequence>> sequences;
1236   // The Sequences view contains only valid line sequences. Don't iterate over
1237   // the Rows directly.
1238   for (const llvm::DWARFDebugLine::Sequence &seq : line_table->Sequences) {
1239     // Ignore line sequences that do not start after the first code address.
1240     // All addresses generated in a sequence are incremental so we only need
1241     // to check the first one of the sequence. Check the comment at the
1242     // m_first_code_address declaration for more details on this.
1243     if (seq.LowPC < m_first_code_address)
1244       continue;
1245     std::unique_ptr<LineSequence> sequence =
1246         LineTable::CreateLineSequenceContainer();
1247     for (unsigned idx = seq.FirstRowIndex; idx < seq.LastRowIndex; ++idx) {
1248       const llvm::DWARFDebugLine::Row &row = line_table->Rows[idx];
1249       LineTable::AppendLineEntryToSequence(
1250           sequence.get(), row.Address.Address, row.Line, row.Column, row.File,
1251           row.IsStmt, row.BasicBlock, row.PrologueEnd, row.EpilogueBegin,
1252           row.EndSequence);
1253     }
1254     sequences.push_back(std::move(sequence));
1255   }
1256 
1257   std::unique_ptr<LineTable> line_table_up =
1258       std::make_unique<LineTable>(&comp_unit, std::move(sequences));
1259 
1260   if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile()) {
1261     // We have an object file that has a line table with addresses that are not
1262     // linked. We need to link the line table and convert the addresses that
1263     // are relative to the .o file into addresses for the main executable.
1264     comp_unit.SetLineTable(
1265         debug_map_symfile->LinkOSOLineTable(this, line_table_up.get()));
1266   } else {
1267     comp_unit.SetLineTable(line_table_up.release());
1268   }
1269 
1270   return true;
1271 }
1272 
1273 lldb_private::DebugMacrosSP
1274 SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) {
1275   auto iter = m_debug_macros_map.find(*offset);
1276   if (iter != m_debug_macros_map.end())
1277     return iter->second;
1278 
1279   ElapsedTime elapsed(m_parse_time);
1280   const DWARFDataExtractor &debug_macro_data = m_context.getOrLoadMacroData();
1281   if (debug_macro_data.GetByteSize() == 0)
1282     return DebugMacrosSP();
1283 
1284   lldb_private::DebugMacrosSP debug_macros_sp(new lldb_private::DebugMacros());
1285   m_debug_macros_map[*offset] = debug_macros_sp;
1286 
1287   const DWARFDebugMacroHeader &header =
1288       DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset);
1289   DWARFDebugMacroEntry::ReadMacroEntries(
1290       debug_macro_data, m_context.getOrLoadStrData(), header.OffsetIs64Bit(),
1291       offset, this, debug_macros_sp);
1292 
1293   return debug_macros_sp;
1294 }
1295 
1296 bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) {
1297   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1298 
1299   DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
1300   if (dwarf_cu == nullptr)
1301     return false;
1302 
1303   const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly();
1304   if (!dwarf_cu_die)
1305     return false;
1306 
1307   lldb::offset_t sect_offset =
1308       dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_macros, DW_INVALID_OFFSET);
1309   if (sect_offset == DW_INVALID_OFFSET)
1310     sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_macros,
1311                                                            DW_INVALID_OFFSET);
1312   if (sect_offset == DW_INVALID_OFFSET)
1313     return false;
1314 
1315   comp_unit.SetDebugMacros(ParseDebugMacros(&sect_offset));
1316 
1317   return true;
1318 }
1319 
1320 size_t SymbolFileDWARF::ParseBlocksRecursive(CompileUnit &comp_unit,
1321                                              Block *parent_block, DWARFDIE die,
1322                                              addr_t subprogram_low_pc) {
1323   size_t blocks_added = 0;
1324   for (; die; die = die.GetSibling()) {
1325     dw_tag_t tag = die.Tag();
1326 
1327     if (tag != DW_TAG_inlined_subroutine && tag != DW_TAG_lexical_block)
1328       continue;
1329 
1330     Block *block = parent_block->CreateChild(die.GetID()).get();
1331     llvm::DWARFAddressRangesVector ranges;
1332     const char *name = nullptr;
1333     const char *mangled_name = nullptr;
1334 
1335     std::optional<int> decl_file;
1336     std::optional<int> decl_line;
1337     std::optional<int> decl_column;
1338     std::optional<int> call_file;
1339     std::optional<int> call_line;
1340     std::optional<int> call_column;
1341     if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file,
1342                                  decl_line, decl_column, call_file, call_line,
1343                                  call_column, nullptr)) {
1344       for (const llvm::DWARFAddressRange &range : ranges) {
1345         if (!range.valid())
1346           continue;
1347         if (range.LowPC >= subprogram_low_pc)
1348           block->AddRange(Block::Range(range.LowPC - subprogram_low_pc,
1349                                        range.HighPC - range.LowPC));
1350         else {
1351           GetObjectFile()->GetModule()->ReportError(
1352               "{0:x8}: adding range [{1:x16}-{2:x16}) which has a base "
1353               "that is less than the function's low PC {3:x16}. Please file "
1354               "a bug and attach the file at the "
1355               "start of this error message",
1356               block->GetID(), range.LowPC, range.HighPC, subprogram_low_pc);
1357         }
1358       }
1359       block->FinalizeRanges();
1360 
1361       if (tag != DW_TAG_subprogram &&
1362           (name != nullptr || mangled_name != nullptr)) {
1363         std::unique_ptr<Declaration> decl_up;
1364         if (decl_file || decl_line || decl_column)
1365           decl_up = std::make_unique<Declaration>(
1366               comp_unit.GetSupportFiles().GetFileSpecAtIndex(
1367                   decl_file ? *decl_file : 0),
1368               decl_line ? *decl_line : 0, decl_column ? *decl_column : 0);
1369 
1370         std::unique_ptr<Declaration> call_up;
1371         if (call_file || call_line || call_column)
1372           call_up = std::make_unique<Declaration>(
1373               comp_unit.GetSupportFiles().GetFileSpecAtIndex(
1374                   call_file ? *call_file : 0),
1375               call_line ? *call_line : 0, call_column ? *call_column : 0);
1376 
1377         block->SetInlinedFunctionInfo(name, mangled_name, decl_up.get(),
1378                                       call_up.get());
1379       }
1380 
1381       ++blocks_added;
1382 
1383       if (die.HasChildren()) {
1384         blocks_added += ParseBlocksRecursive(
1385             comp_unit, block, die.GetFirstChild(), subprogram_low_pc);
1386       }
1387     }
1388   }
1389   return blocks_added;
1390 }
1391 
1392 bool SymbolFileDWARF::ClassOrStructIsVirtual(const DWARFDIE &parent_die) {
1393   if (parent_die) {
1394     for (DWARFDIE die : parent_die.children()) {
1395       dw_tag_t tag = die.Tag();
1396       bool check_virtuality = false;
1397       switch (tag) {
1398       case DW_TAG_inheritance:
1399       case DW_TAG_subprogram:
1400         check_virtuality = true;
1401         break;
1402       default:
1403         break;
1404       }
1405       if (check_virtuality) {
1406         if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)
1407           return true;
1408       }
1409     }
1410   }
1411   return false;
1412 }
1413 
1414 void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) {
1415   auto *type_system = decl_ctx.GetTypeSystem();
1416   if (type_system != nullptr)
1417     type_system->GetDWARFParser()->EnsureAllDIEsInDeclContextHaveBeenParsed(
1418         decl_ctx);
1419 }
1420 
1421 DWARFDIE
1422 SymbolFileDWARF::GetDIE(lldb::user_id_t uid) { return GetDIE(DIERef(uid)); }
1423 
1424 CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) {
1425   // This method can be called without going through the symbol vendor so we
1426   // need to lock the module.
1427   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1428   // Anytime we have a lldb::user_id_t, we must get the DIE by calling
1429   // SymbolFileDWARF::GetDIE(). See comments inside the
1430   // SymbolFileDWARF::GetDIE() for details.
1431   if (DWARFDIE die = GetDIE(type_uid))
1432     return GetDecl(die);
1433   return CompilerDecl();
1434 }
1435 
1436 CompilerDeclContext
1437 SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {
1438   // This method can be called without going through the symbol vendor so we
1439   // need to lock the module.
1440   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1441   // Anytime we have a lldb::user_id_t, we must get the DIE by calling
1442   // SymbolFileDWARF::GetDIE(). See comments inside the
1443   // SymbolFileDWARF::GetDIE() for details.
1444   if (DWARFDIE die = GetDIE(type_uid))
1445     return GetDeclContext(die);
1446   return CompilerDeclContext();
1447 }
1448 
1449 CompilerDeclContext
1450 SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
1451   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1452   // Anytime we have a lldb::user_id_t, we must get the DIE by calling
1453   // SymbolFileDWARF::GetDIE(). See comments inside the
1454   // SymbolFileDWARF::GetDIE() for details.
1455   if (DWARFDIE die = GetDIE(type_uid))
1456     return GetContainingDeclContext(die);
1457   return CompilerDeclContext();
1458 }
1459 
1460 std::vector<CompilerContext>
1461 SymbolFileDWARF::GetCompilerContextForUID(lldb::user_id_t type_uid) {
1462   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1463   // Anytime we have a lldb::user_id_t, we must get the DIE by calling
1464   // SymbolFileDWARF::GetDIE(). See comments inside the
1465   // SymbolFileDWARF::GetDIE() for details.
1466   if (DWARFDIE die = GetDIE(type_uid))
1467     return die.GetDeclContext();
1468   return {};
1469 }
1470 
1471 Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) {
1472   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1473   // Anytime we have a lldb::user_id_t, we must get the DIE by calling
1474   // SymbolFileDWARF::GetDIE(). See comments inside the
1475   // SymbolFileDWARF::GetDIE() for details.
1476   if (DWARFDIE type_die = GetDIE(type_uid))
1477     return type_die.ResolveType();
1478   else
1479     return nullptr;
1480 }
1481 
1482 std::optional<SymbolFile::ArrayInfo> SymbolFileDWARF::GetDynamicArrayInfoForUID(
1483     lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
1484   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1485   if (DWARFDIE type_die = GetDIE(type_uid))
1486     return DWARFASTParser::ParseChildArrayInfo(type_die, exe_ctx);
1487   else
1488     return std::nullopt;
1489 }
1490 
1491 Type *SymbolFileDWARF::ResolveTypeUID(const DIERef &die_ref) {
1492   return ResolveType(GetDIE(die_ref), true);
1493 }
1494 
1495 Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die,
1496                                       bool assert_not_being_parsed) {
1497   if (die) {
1498     Log *log = GetLog(DWARFLog::DebugInfo);
1499     if (log)
1500       GetObjectFile()->GetModule()->LogMessage(
1501           log,
1502           "SymbolFileDWARF::ResolveTypeUID (die = {0:x16}) {1} ({2}) '{3}'",
1503           die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.Tag(),
1504           die.GetName());
1505 
1506     // We might be coming in in the middle of a type tree (a class within a
1507     // class, an enum within a class), so parse any needed parent DIEs before
1508     // we get to this one...
1509     DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(die);
1510     if (decl_ctx_die) {
1511       if (log) {
1512         switch (decl_ctx_die.Tag()) {
1513         case DW_TAG_structure_type:
1514         case DW_TAG_union_type:
1515         case DW_TAG_class_type: {
1516           // Get the type, which could be a forward declaration
1517           if (log)
1518             GetObjectFile()->GetModule()->LogMessage(
1519                 log,
1520                 "SymbolFileDWARF::ResolveTypeUID (die = {0:x16}) {1} ({2}) "
1521                 "'{3}' resolve parent forward type for {4:x16})",
1522                 die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.Tag(),
1523                 die.GetName(), decl_ctx_die.GetOffset());
1524         } break;
1525 
1526         default:
1527           break;
1528         }
1529       }
1530     }
1531     return ResolveType(die);
1532   }
1533   return nullptr;
1534 }
1535 
1536 // This function is used when SymbolFileDWARFDebugMap owns a bunch of
1537 // SymbolFileDWARF objects to detect if this DWARF file is the one that can
1538 // resolve a compiler_type.
1539 bool SymbolFileDWARF::HasForwardDeclForCompilerType(
1540     const CompilerType &compiler_type) {
1541   CompilerType compiler_type_no_qualifiers =
1542       ClangUtil::RemoveFastQualifiers(compiler_type);
1543   if (GetForwardDeclCompilerTypeToDIE().count(
1544           compiler_type_no_qualifiers.GetOpaqueQualType())) {
1545     return true;
1546   }
1547   auto type_system = compiler_type.GetTypeSystem();
1548   auto clang_type_system = type_system.dyn_cast_or_null<TypeSystemClang>();
1549   if (!clang_type_system)
1550     return false;
1551   DWARFASTParserClang *ast_parser =
1552       static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
1553   return ast_parser->GetClangASTImporter().CanImport(compiler_type);
1554 }
1555 
1556 bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
1557   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1558   auto clang_type_system =
1559       compiler_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
1560   if (clang_type_system) {
1561     DWARFASTParserClang *ast_parser =
1562         static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
1563     if (ast_parser &&
1564         ast_parser->GetClangASTImporter().CanImport(compiler_type))
1565       return ast_parser->GetClangASTImporter().CompleteType(compiler_type);
1566   }
1567 
1568   // We have a struct/union/class/enum that needs to be fully resolved.
1569   CompilerType compiler_type_no_qualifiers =
1570       ClangUtil::RemoveFastQualifiers(compiler_type);
1571   auto die_it = GetForwardDeclCompilerTypeToDIE().find(
1572       compiler_type_no_qualifiers.GetOpaqueQualType());
1573   if (die_it == GetForwardDeclCompilerTypeToDIE().end()) {
1574     // We have already resolved this type...
1575     return true;
1576   }
1577 
1578   DWARFDIE decl_die = GetDIE(die_it->getSecond());
1579   // Once we start resolving this type, remove it from the forward
1580   // declaration map in case anyone's child members or other types require this
1581   // type to get resolved.
1582   GetForwardDeclCompilerTypeToDIE().erase(die_it);
1583   DWARFDIE def_die = FindDefinitionDIE(decl_die);
1584   if (!def_die) {
1585     SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
1586     if (debug_map_symfile) {
1587       // We weren't able to find a full declaration in this DWARF, see
1588       // if we have a declaration anywhere else...
1589       def_die = debug_map_symfile->FindDefinitionDIE(decl_die);
1590     }
1591   }
1592   if (!def_die) {
1593     // If we don't have definition DIE, CompleteTypeFromDWARF will forcefully
1594     // complete this type.
1595     def_die = decl_die;
1596   }
1597 
1598   DWARFASTParser *dwarf_ast = GetDWARFParser(*def_die.GetCU());
1599   if (!dwarf_ast)
1600     return false;
1601   Type *type = GetDIEToType().lookup(decl_die.GetDIE());
1602   assert(type);
1603 
1604   if (decl_die != def_die) {
1605     GetDIEToType()[def_die.GetDIE()] = type;
1606     DWARFASTParserClang *ast_parser =
1607         static_cast<DWARFASTParserClang *>(dwarf_ast);
1608     ast_parser->MapDeclDIEToDefDIE(decl_die, def_die);
1609   }
1610 
1611   Log *log = GetLog(DWARFLog::DebugInfo | DWARFLog::TypeCompletion);
1612   if (log)
1613     GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
1614         log, "{0:x8}: {1} ({2}) '{3}' resolving forward declaration...",
1615         def_die.GetID(), DW_TAG_value_to_name(def_die.Tag()), def_die.Tag(),
1616         type->GetName().AsCString());
1617   assert(compiler_type);
1618   return dwarf_ast->CompleteTypeFromDWARF(def_die, type, compiler_type);
1619 }
1620 
1621 Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die,
1622                                    bool assert_not_being_parsed,
1623                                    bool resolve_function_context) {
1624   if (die) {
1625     Type *type = GetTypeForDIE(die, resolve_function_context).get();
1626 
1627     if (assert_not_being_parsed) {
1628       if (type != DIE_IS_BEING_PARSED)
1629         return type;
1630 
1631       GetObjectFile()->GetModule()->ReportError(
1632           "Parsing a die that is being parsed die: {0:x16}: {1} ({2}) {3}",
1633           die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.Tag(),
1634           die.GetName());
1635 
1636     } else
1637       return type;
1638   }
1639   return nullptr;
1640 }
1641 
1642 CompileUnit *
1643 SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu) {
1644 
1645   if (dwarf_cu.IsDWOUnit()) {
1646     DWARFCompileUnit *non_dwo_cu = dwarf_cu.GetSkeletonUnit();
1647     assert(non_dwo_cu);
1648     return non_dwo_cu->GetSymbolFileDWARF().GetCompUnitForDWARFCompUnit(
1649         *non_dwo_cu);
1650   }
1651   // Check if the symbol vendor already knows about this compile unit?
1652   CompileUnit *lldb_cu = dwarf_cu.GetLLDBCompUnit();
1653   if (lldb_cu)
1654     return lldb_cu;
1655   // The symbol vendor doesn't know about this compile unit, we need to parse
1656   // and add it to the symbol vendor object.
1657   return ParseCompileUnit(dwarf_cu).get();
1658 }
1659 
1660 void SymbolFileDWARF::GetObjCMethods(
1661     ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) {
1662   m_index->GetObjCMethods(class_name, callback);
1663 }
1664 
1665 bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) {
1666   sc.Clear(false);
1667 
1668   if (die && llvm::isa<DWARFCompileUnit>(die.GetCU())) {
1669     // Check if the symbol vendor already knows about this compile unit?
1670     sc.comp_unit =
1671         GetCompUnitForDWARFCompUnit(llvm::cast<DWARFCompileUnit>(*die.GetCU()));
1672 
1673     sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
1674     if (sc.function == nullptr)
1675       sc.function = ParseFunction(*sc.comp_unit, die);
1676 
1677     if (sc.function) {
1678       sc.module_sp = sc.function->CalculateSymbolContextModule();
1679       return true;
1680     }
1681   }
1682 
1683   return false;
1684 }
1685 
1686 lldb::ModuleSP SymbolFileDWARF::GetExternalModule(ConstString name) {
1687   UpdateExternalModuleListIfNeeded();
1688   const auto &pos = m_external_type_modules.find(name);
1689   if (pos == m_external_type_modules.end())
1690     return lldb::ModuleSP();
1691   return pos->second;
1692 }
1693 
1694 SymbolFileDWARF *SymbolFileDWARF::GetDIERefSymbolFile(const DIERef &die_ref) {
1695   // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we
1696   // must make sure we use the correct DWARF file when resolving things. On
1697   // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
1698   // SymbolFileDWARF classes, one for each .o file. We can often end up with
1699   // references to other DWARF objects and we must be ready to receive a
1700   // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
1701   // instance.
1702 
1703   std::optional<uint32_t> file_index = die_ref.file_index();
1704 
1705   // If the file index matches, then we have the right SymbolFileDWARF already.
1706   // This will work for both .dwo file and DWARF in .o files for mac. Also if
1707   // both the file indexes are invalid, then we have a match.
1708   if (GetFileIndex() == file_index)
1709     return this;
1710 
1711   if (file_index) {
1712       // We have a SymbolFileDWARFDebugMap, so let it find the right file
1713     if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile())
1714       return debug_map->GetSymbolFileByOSOIndex(*file_index);
1715 
1716     // Handle the .dwp file case correctly
1717     if (*file_index == DIERef::k_file_index_mask)
1718       return GetDwpSymbolFile().get(); // DWP case
1719 
1720     // Handle the .dwo file case correctly
1721     return DebugInfo().GetUnitAtIndex(*die_ref.file_index())
1722         ->GetDwoSymbolFile(); // DWO case
1723   }
1724   return this;
1725 }
1726 
1727 DWARFDIE
1728 SymbolFileDWARF::GetDIE(const DIERef &die_ref) {
1729   if (die_ref.die_offset() == DW_INVALID_OFFSET)
1730     return DWARFDIE();
1731 
1732   // This method can be called without going through the symbol vendor so we
1733   // need to lock the module.
1734   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1735   SymbolFileDWARF *symbol_file = GetDIERefSymbolFile(die_ref);
1736   if (symbol_file)
1737     return symbol_file->DebugInfo().GetDIE(die_ref.section(),
1738                                            die_ref.die_offset());
1739   return DWARFDIE();
1740 }
1741 
1742 /// Return the DW_AT_(GNU_)dwo_id.
1743 static std::optional<uint64_t> GetDWOId(DWARFCompileUnit &dwarf_cu,
1744                                         const DWARFDebugInfoEntry &cu_die) {
1745   std::optional<uint64_t> dwo_id =
1746       cu_die.GetAttributeValueAsOptionalUnsigned(&dwarf_cu, DW_AT_GNU_dwo_id);
1747   if (dwo_id)
1748     return dwo_id;
1749   return cu_die.GetAttributeValueAsOptionalUnsigned(&dwarf_cu, DW_AT_dwo_id);
1750 }
1751 
1752 std::optional<uint64_t> SymbolFileDWARF::GetDWOId() {
1753   if (GetNumCompileUnits() == 1) {
1754     if (auto comp_unit = GetCompileUnitAtIndex(0))
1755       if (DWARFCompileUnit *cu = GetDWARFCompileUnit(comp_unit.get()))
1756         if (DWARFDebugInfoEntry *cu_die = cu->DIE().GetDIE())
1757           return ::GetDWOId(*cu, *cu_die);
1758   }
1759   return {};
1760 }
1761 
1762 DWARFUnit *SymbolFileDWARF::GetSkeletonUnit(DWARFUnit *dwo_unit) {
1763   return DebugInfo().GetSkeletonUnit(dwo_unit);
1764 }
1765 
1766 std::shared_ptr<SymbolFileDWARFDwo>
1767 SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
1768     DWARFUnit &unit, const DWARFDebugInfoEntry &cu_die) {
1769   // If this is a Darwin-style debug map (non-.dSYM) symbol file,
1770   // never attempt to load ELF-style DWO files since the -gmodules
1771   // support uses the same DWO mechanism to specify full debug info
1772   // files for modules. This is handled in
1773   // UpdateExternalModuleListIfNeeded().
1774   if (GetDebugMapSymfile())
1775     return nullptr;
1776 
1777   DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(&unit);
1778   // Only compile units can be split into two parts and we should only
1779   // look for a DWO file if there is a valid DWO ID.
1780   if (!dwarf_cu || !dwarf_cu->GetDWOId().has_value())
1781     return nullptr;
1782 
1783   const char *dwo_name = GetDWOName(*dwarf_cu, cu_die);
1784   if (!dwo_name) {
1785     unit.SetDwoError(Status::FromErrorStringWithFormatv(
1786         "missing DWO name in skeleton DIE {0:x16}", cu_die.GetOffset()));
1787     return nullptr;
1788   }
1789 
1790   if (std::shared_ptr<SymbolFileDWARFDwo> dwp_sp = GetDwpSymbolFile())
1791     return dwp_sp;
1792 
1793   FileSpec dwo_file(dwo_name);
1794   FileSystem::Instance().Resolve(dwo_file);
1795   bool found = false;
1796 
1797   const FileSpecList &debug_file_search_paths =
1798       Target::GetDefaultDebugFileSearchPaths();
1799   size_t num_search_paths = debug_file_search_paths.GetSize();
1800 
1801   // It's relative, e.g. "foo.dwo", but we just to happen to be right next to
1802   // it. Or it's absolute.
1803   found = FileSystem::Instance().Exists(dwo_file);
1804 
1805   const char *comp_dir =
1806       cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_comp_dir, nullptr);
1807   if (!found) {
1808     // It could be a relative path that also uses DW_AT_COMP_DIR.
1809     if (comp_dir) {
1810       dwo_file.SetFile(comp_dir, FileSpec::Style::native);
1811       if (!dwo_file.IsRelative()) {
1812         FileSystem::Instance().Resolve(dwo_file);
1813         dwo_file.AppendPathComponent(dwo_name);
1814         found = FileSystem::Instance().Exists(dwo_file);
1815       } else {
1816         FileSpecList dwo_paths;
1817 
1818         // if DW_AT_comp_dir is relative, it should be relative to the location
1819         // of the executable, not to the location from which the debugger was
1820         // launched.
1821         FileSpec relative_to_binary = dwo_file;
1822         relative_to_binary.PrependPathComponent(
1823             m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());
1824         FileSystem::Instance().Resolve(relative_to_binary);
1825         relative_to_binary.AppendPathComponent(dwo_name);
1826         dwo_paths.Append(relative_to_binary);
1827 
1828         // Or it's relative to one of the user specified debug directories.
1829         for (size_t idx = 0; idx < num_search_paths; ++idx) {
1830           FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
1831           dirspec.AppendPathComponent(comp_dir);
1832           FileSystem::Instance().Resolve(dirspec);
1833           if (!FileSystem::Instance().IsDirectory(dirspec))
1834             continue;
1835 
1836           dirspec.AppendPathComponent(dwo_name);
1837           dwo_paths.Append(dirspec);
1838         }
1839 
1840         size_t num_possible = dwo_paths.GetSize();
1841         for (size_t idx = 0; idx < num_possible && !found; ++idx) {
1842           FileSpec dwo_spec = dwo_paths.GetFileSpecAtIndex(idx);
1843           if (FileSystem::Instance().Exists(dwo_spec)) {
1844             dwo_file = dwo_spec;
1845             found = true;
1846           }
1847         }
1848       }
1849     } else {
1850       Log *log = GetLog(LLDBLog::Symbols);
1851       LLDB_LOGF(log,
1852                 "unable to locate relative .dwo debug file \"%s\" for "
1853                 "skeleton DIE 0x%016" PRIx64 " without valid DW_AT_comp_dir "
1854                 "attribute",
1855                 dwo_name, cu_die.GetOffset());
1856     }
1857   }
1858 
1859   if (!found) {
1860     // Try adding the DW_AT_dwo_name ( e.g. "c/d/main-main.dwo"), and just the
1861     // filename ("main-main.dwo") to binary dir and search paths.
1862     FileSpecList dwo_paths;
1863     FileSpec dwo_name_spec(dwo_name);
1864     llvm::StringRef filename_only = dwo_name_spec.GetFilename();
1865 
1866     FileSpec binary_directory(
1867         m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());
1868     FileSystem::Instance().Resolve(binary_directory);
1869 
1870     if (dwo_name_spec.IsRelative()) {
1871       FileSpec dwo_name_binary_directory(binary_directory);
1872       dwo_name_binary_directory.AppendPathComponent(dwo_name);
1873       dwo_paths.Append(dwo_name_binary_directory);
1874     }
1875 
1876     FileSpec filename_binary_directory(binary_directory);
1877     filename_binary_directory.AppendPathComponent(filename_only);
1878     dwo_paths.Append(filename_binary_directory);
1879 
1880     for (size_t idx = 0; idx < num_search_paths; ++idx) {
1881       FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
1882       FileSystem::Instance().Resolve(dirspec);
1883       if (!FileSystem::Instance().IsDirectory(dirspec))
1884         continue;
1885 
1886       FileSpec dwo_name_dirspec(dirspec);
1887       dwo_name_dirspec.AppendPathComponent(dwo_name);
1888       dwo_paths.Append(dwo_name_dirspec);
1889 
1890       FileSpec filename_dirspec(dirspec);
1891       filename_dirspec.AppendPathComponent(filename_only);
1892       dwo_paths.Append(filename_dirspec);
1893     }
1894 
1895     size_t num_possible = dwo_paths.GetSize();
1896     for (size_t idx = 0; idx < num_possible && !found; ++idx) {
1897       FileSpec dwo_spec = dwo_paths.GetFileSpecAtIndex(idx);
1898       if (FileSystem::Instance().Exists(dwo_spec)) {
1899         dwo_file = dwo_spec;
1900         found = true;
1901       }
1902     }
1903   }
1904 
1905   if (!found) {
1906     FileSpec error_dwo_path(dwo_name);
1907     FileSystem::Instance().Resolve(error_dwo_path);
1908     if (error_dwo_path.IsRelative() && comp_dir != nullptr) {
1909       error_dwo_path.PrependPathComponent(comp_dir);
1910       FileSystem::Instance().Resolve(error_dwo_path);
1911     }
1912     unit.SetDwoError(Status::FromErrorStringWithFormatv(
1913         "unable to locate .dwo debug file \"{0}\" for skeleton DIE "
1914         "{1:x16}",
1915         error_dwo_path.GetPath().c_str(), cu_die.GetOffset()));
1916 
1917     if (m_dwo_warning_issued.test_and_set(std::memory_order_relaxed) == false) {
1918       GetObjectFile()->GetModule()->ReportWarning(
1919           "unable to locate separate debug file (dwo, dwp). Debugging will be "
1920           "degraded.");
1921     }
1922     return nullptr;
1923   }
1924 
1925   const lldb::offset_t file_offset = 0;
1926   DataBufferSP dwo_file_data_sp;
1927   lldb::offset_t dwo_file_data_offset = 0;
1928   ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(
1929       GetObjectFile()->GetModule(), &dwo_file, file_offset,
1930       FileSystem::Instance().GetByteSize(dwo_file), dwo_file_data_sp,
1931       dwo_file_data_offset);
1932   if (dwo_obj_file == nullptr) {
1933     unit.SetDwoError(Status::FromErrorStringWithFormatv(
1934         "unable to load object file for .dwo debug file \"{0}\" for "
1935         "unit DIE {1:x16}",
1936         dwo_name, cu_die.GetOffset()));
1937     return nullptr;
1938   }
1939 
1940   return std::make_shared<SymbolFileDWARFDwo>(*this, dwo_obj_file,
1941                                               dwarf_cu->GetID());
1942 }
1943 
1944 void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
1945   if (m_fetched_external_modules)
1946     return;
1947   m_fetched_external_modules = true;
1948   DWARFDebugInfo &debug_info = DebugInfo();
1949 
1950   // Follow DWO skeleton unit breadcrumbs.
1951   const uint32_t num_compile_units = GetNumCompileUnits();
1952   for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
1953     auto *dwarf_cu =
1954         llvm::dyn_cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(cu_idx));
1955     if (!dwarf_cu)
1956       continue;
1957 
1958     const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly();
1959     if (!die || die.HasChildren() || !die.GetDIE())
1960       continue;
1961 
1962     const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr);
1963     if (!name)
1964       continue;
1965 
1966     ConstString const_name(name);
1967     ModuleSP &module_sp = m_external_type_modules[const_name];
1968     if (module_sp)
1969       continue;
1970 
1971     const char *dwo_path = GetDWOName(*dwarf_cu, *die.GetDIE());
1972     if (!dwo_path)
1973       continue;
1974 
1975     ModuleSpec dwo_module_spec;
1976     dwo_module_spec.GetFileSpec().SetFile(dwo_path, FileSpec::Style::native);
1977     if (dwo_module_spec.GetFileSpec().IsRelative()) {
1978       const char *comp_dir =
1979           die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr);
1980       if (comp_dir) {
1981         dwo_module_spec.GetFileSpec().SetFile(comp_dir,
1982                                               FileSpec::Style::native);
1983         FileSystem::Instance().Resolve(dwo_module_spec.GetFileSpec());
1984         dwo_module_spec.GetFileSpec().AppendPathComponent(dwo_path);
1985       }
1986     }
1987     dwo_module_spec.GetArchitecture() =
1988         m_objfile_sp->GetModule()->GetArchitecture();
1989 
1990     // When LLDB loads "external" modules it looks at the presence of
1991     // DW_AT_dwo_name. However, when the already created module
1992     // (corresponding to .dwo itself) is being processed, it will see
1993     // the presence of DW_AT_dwo_name (which contains the name of dwo
1994     // file) and will try to call ModuleList::GetSharedModule
1995     // again. In some cases (i.e., for empty files) Clang 4.0
1996     // generates a *.dwo file which has DW_AT_dwo_name, but no
1997     // DW_AT_comp_dir. In this case the method
1998     // ModuleList::GetSharedModule will fail and the warning will be
1999     // printed. However, as one can notice in this case we don't
2000     // actually need to try to load the already loaded module
2001     // (corresponding to .dwo) so we simply skip it.
2002     if (m_objfile_sp->GetFileSpec().GetFileNameExtension() == ".dwo" &&
2003         llvm::StringRef(m_objfile_sp->GetFileSpec().GetPath())
2004             .ends_with(dwo_module_spec.GetFileSpec().GetPath())) {
2005       continue;
2006     }
2007 
2008     Status error = ModuleList::GetSharedModule(dwo_module_spec, module_sp,
2009                                                nullptr, nullptr, nullptr);
2010     if (!module_sp) {
2011       // ReportWarning also rate-limits based on the warning string,
2012       // but in a -gmodules build, each object file has a similar DAG
2013       // of module dependencies that would all be listed here.
2014       GetObjectFile()->GetModule()->ReportWarning(
2015           "{0}", error.AsCString("unknown error"));
2016       GetObjectFile()->GetModule()->ReportWarning(
2017           "Unable to locate module needed for external types.\n"
2018           "Debugging will be degraded due to missing types. Rebuilding the "
2019           "project will regenerate the needed module files.");
2020       continue;
2021     }
2022 
2023     // Verify the DWO hash.
2024     // FIXME: Technically "0" is a valid hash.
2025     std::optional<uint64_t> dwo_id = ::GetDWOId(*dwarf_cu, *die.GetDIE());
2026     if (!dwo_id)
2027       continue;
2028 
2029     auto *dwo_symfile =
2030         llvm::dyn_cast_or_null<SymbolFileDWARF>(module_sp->GetSymbolFile());
2031     if (!dwo_symfile)
2032       continue;
2033     std::optional<uint64_t> dwo_dwo_id = dwo_symfile->GetDWOId();
2034     if (!dwo_dwo_id)
2035       continue;
2036 
2037     if (dwo_id != dwo_dwo_id) {
2038       GetObjectFile()->GetModule()->ReportWarning(
2039           "Module {0} is out-of-date (hash mismatch).\n"
2040           "Type information from this module may be incomplete or inconsistent "
2041           "with the rest of the program. Rebuilding the project will "
2042           "regenerate the needed module files.",
2043           dwo_module_spec.GetFileSpec().GetPath());
2044     }
2045   }
2046 }
2047 
2048 SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
2049   if (!m_global_aranges_up) {
2050     m_global_aranges_up = std::make_unique<GlobalVariableMap>();
2051 
2052     ModuleSP module_sp = GetObjectFile()->GetModule();
2053     if (module_sp) {
2054       const size_t num_cus = module_sp->GetNumCompileUnits();
2055       for (size_t i = 0; i < num_cus; ++i) {
2056         CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
2057         if (cu_sp) {
2058           VariableListSP globals_sp = cu_sp->GetVariableList(true);
2059           if (globals_sp) {
2060             const size_t num_globals = globals_sp->GetSize();
2061             for (size_t g = 0; g < num_globals; ++g) {
2062               VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
2063               if (var_sp && !var_sp->GetLocationIsConstantValueData()) {
2064                 const DWARFExpressionList &location =
2065                     var_sp->LocationExpressionList();
2066                 ExecutionContext exe_ctx;
2067                 llvm::Expected<Value> location_result = location.Evaluate(
2068                     &exe_ctx, nullptr, LLDB_INVALID_ADDRESS, nullptr, nullptr);
2069                 if (location_result) {
2070                   if (location_result->GetValueType() ==
2071                       Value::ValueType::FileAddress) {
2072                     lldb::addr_t file_addr =
2073                         location_result->GetScalar().ULongLong();
2074                     lldb::addr_t byte_size = 1;
2075                     if (var_sp->GetType())
2076                       byte_size =
2077                           var_sp->GetType()->GetByteSize(nullptr).value_or(0);
2078                     m_global_aranges_up->Append(GlobalVariableMap::Entry(
2079                         file_addr, byte_size, var_sp.get()));
2080                   }
2081                 } else {
2082                   LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols),
2083                                  location_result.takeError(),
2084                                  "location expression failed to execute: {0}");
2085                 }
2086               }
2087             }
2088           }
2089         }
2090       }
2091     }
2092     m_global_aranges_up->Sort();
2093   }
2094   return *m_global_aranges_up;
2095 }
2096 
2097 void SymbolFileDWARF::ResolveFunctionAndBlock(lldb::addr_t file_vm_addr,
2098                                               bool lookup_block,
2099                                               SymbolContext &sc) {
2100   assert(sc.comp_unit);
2101   DWARFCompileUnit &cu =
2102       GetDWARFCompileUnit(sc.comp_unit)->GetNonSkeletonUnit();
2103   DWARFDIE function_die = cu.LookupAddress(file_vm_addr);
2104   DWARFDIE block_die;
2105   if (function_die) {
2106     sc.function = sc.comp_unit->FindFunctionByUID(function_die.GetID()).get();
2107     if (sc.function == nullptr)
2108       sc.function = ParseFunction(*sc.comp_unit, function_die);
2109 
2110     if (sc.function && lookup_block)
2111       block_die = function_die.LookupDeepestBlock(file_vm_addr);
2112   }
2113 
2114   if (!sc.function || !lookup_block)
2115     return;
2116 
2117   Block &block = sc.function->GetBlock(true);
2118   if (block_die)
2119     sc.block = block.FindBlockByID(block_die.GetID());
2120   else
2121     sc.block = block.FindBlockByID(function_die.GetID());
2122 }
2123 
2124 uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
2125                                                SymbolContextItem resolve_scope,
2126                                                SymbolContext &sc) {
2127   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2128   LLDB_SCOPED_TIMERF("SymbolFileDWARF::"
2129                      "ResolveSymbolContext (so_addr = { "
2130                      "section = %p, offset = 0x%" PRIx64
2131                      " }, resolve_scope = 0x%8.8x)",
2132                      static_cast<void *>(so_addr.GetSection().get()),
2133                      so_addr.GetOffset(), resolve_scope);
2134   uint32_t resolved = 0;
2135   if (resolve_scope &
2136       (eSymbolContextCompUnit | eSymbolContextFunction | eSymbolContextBlock |
2137        eSymbolContextLineEntry | eSymbolContextVariable)) {
2138     lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
2139 
2140     DWARFDebugInfo &debug_info = DebugInfo();
2141     const DWARFDebugAranges &aranges = debug_info.GetCompileUnitAranges();
2142     const dw_offset_t cu_offset = aranges.FindAddress(file_vm_addr);
2143     if (cu_offset == DW_INVALID_OFFSET) {
2144       // Global variables are not in the compile unit address ranges. The only
2145       // way to currently find global variables is to iterate over the
2146       // .debug_pubnames or the __apple_names table and find all items in there
2147       // that point to DW_TAG_variable DIEs and then find the address that
2148       // matches.
2149       if (resolve_scope & eSymbolContextVariable) {
2150         GlobalVariableMap &map = GetGlobalAranges();
2151         const GlobalVariableMap::Entry *entry =
2152             map.FindEntryThatContains(file_vm_addr);
2153         if (entry && entry->data) {
2154           Variable *variable = entry->data;
2155           SymbolContextScope *scc = variable->GetSymbolContextScope();
2156           if (scc) {
2157             scc->CalculateSymbolContext(&sc);
2158             sc.variable = variable;
2159           }
2160           return sc.GetResolvedMask();
2161         }
2162       }
2163     } else {
2164       uint32_t cu_idx = DW_INVALID_INDEX;
2165       if (auto *dwarf_cu = llvm::dyn_cast_or_null<DWARFCompileUnit>(
2166               debug_info.GetUnitAtOffset(DIERef::Section::DebugInfo, cu_offset,
2167                                          &cu_idx))) {
2168         sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
2169         if (sc.comp_unit) {
2170           resolved |= eSymbolContextCompUnit;
2171 
2172           bool force_check_line_table = false;
2173           if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) {
2174             ResolveFunctionAndBlock(file_vm_addr,
2175                                     resolve_scope & eSymbolContextBlock, sc);
2176             if (sc.function)
2177               resolved |= eSymbolContextFunction;
2178             else {
2179               // We might have had a compile unit that had discontiguous address
2180               // ranges where the gaps are symbols that don't have any debug
2181               // info. Discontiguous compile unit address ranges should only
2182               // happen when there aren't other functions from other compile
2183               // units in these gaps. This helps keep the size of the aranges
2184               // down.
2185               force_check_line_table = true;
2186             }
2187             if (sc.block)
2188               resolved |= eSymbolContextBlock;
2189           }
2190 
2191           if ((resolve_scope & eSymbolContextLineEntry) ||
2192               force_check_line_table) {
2193             LineTable *line_table = sc.comp_unit->GetLineTable();
2194             if (line_table != nullptr) {
2195               // And address that makes it into this function should be in terms
2196               // of this debug file if there is no debug map, or it will be an
2197               // address in the .o file which needs to be fixed up to be in
2198               // terms of the debug map executable. Either way, calling
2199               // FixupAddress() will work for us.
2200               Address exe_so_addr(so_addr);
2201               if (FixupAddress(exe_so_addr)) {
2202                 if (line_table->FindLineEntryByAddress(exe_so_addr,
2203                                                        sc.line_entry)) {
2204                   resolved |= eSymbolContextLineEntry;
2205                 }
2206               }
2207             }
2208           }
2209 
2210           if (force_check_line_table && !(resolved & eSymbolContextLineEntry)) {
2211             // We might have had a compile unit that had discontiguous address
2212             // ranges where the gaps are symbols that don't have any debug info.
2213             // Discontiguous compile unit address ranges should only happen when
2214             // there aren't other functions from other compile units in these
2215             // gaps. This helps keep the size of the aranges down.
2216             sc.comp_unit = nullptr;
2217             resolved &= ~eSymbolContextCompUnit;
2218           }
2219         } else {
2220           GetObjectFile()->GetModule()->ReportWarning(
2221               "{0:x16}: compile unit {1} failed to create a valid "
2222               "lldb_private::CompileUnit class.",
2223               cu_offset, cu_idx);
2224         }
2225       }
2226     }
2227   }
2228   return resolved;
2229 }
2230 
2231 uint32_t SymbolFileDWARF::ResolveSymbolContext(
2232     const SourceLocationSpec &src_location_spec,
2233     SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
2234   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2235   const bool check_inlines = src_location_spec.GetCheckInlines();
2236   const uint32_t prev_size = sc_list.GetSize();
2237   if (resolve_scope & eSymbolContextCompUnit) {
2238     for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;
2239          ++cu_idx) {
2240       CompileUnit *dc_cu = ParseCompileUnitAtIndex(cu_idx).get();
2241       if (!dc_cu)
2242         continue;
2243 
2244       bool file_spec_matches_cu_file_spec = FileSpec::Match(
2245           src_location_spec.GetFileSpec(), dc_cu->GetPrimaryFile());
2246       if (check_inlines || file_spec_matches_cu_file_spec) {
2247         dc_cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list);
2248         if (!check_inlines)
2249           break;
2250       }
2251     }
2252   }
2253   return sc_list.GetSize() - prev_size;
2254 }
2255 
2256 void SymbolFileDWARF::PreloadSymbols() {
2257   // Get the symbol table for the symbol file prior to taking the module lock
2258   // so that it is available without needing to take the module lock. The DWARF
2259   // indexing might end up needing to relocate items when DWARF sections are
2260   // loaded as they might end up getting the section contents which can call
2261   // ObjectFileELF::RelocateSection() which in turn will ask for the symbol
2262   // table and can cause deadlocks.
2263   GetSymtab();
2264   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2265   m_index->Preload();
2266 }
2267 
2268 std::recursive_mutex &SymbolFileDWARF::GetModuleMutex() const {
2269   lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
2270   if (module_sp)
2271     return module_sp->GetMutex();
2272   return GetObjectFile()->GetModule()->GetMutex();
2273 }
2274 
2275 bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
2276     const lldb_private::CompilerDeclContext &decl_ctx) {
2277   if (!decl_ctx.IsValid()) {
2278     // Invalid namespace decl which means we aren't matching only things in
2279     // this symbol file, so return true to indicate it matches this symbol
2280     // file.
2281     return true;
2282   }
2283 
2284   TypeSystem *decl_ctx_type_system = decl_ctx.GetTypeSystem();
2285   auto type_system_or_err = GetTypeSystemForLanguage(
2286       decl_ctx_type_system->GetMinimumLanguage(nullptr));
2287   if (auto err = type_system_or_err.takeError()) {
2288     LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
2289                    "Unable to match namespace decl using TypeSystem: {0}");
2290     return false;
2291   }
2292 
2293   if (decl_ctx_type_system == type_system_or_err->get())
2294     return true; // The type systems match, return true
2295 
2296   // The namespace AST was valid, and it does not match...
2297   Log *log = GetLog(DWARFLog::Lookups);
2298 
2299   if (log)
2300     GetObjectFile()->GetModule()->LogMessage(
2301         log, "Valid namespace does not match symbol file");
2302 
2303   return false;
2304 }
2305 
2306 void SymbolFileDWARF::FindGlobalVariables(
2307     ConstString name, const CompilerDeclContext &parent_decl_ctx,
2308     uint32_t max_matches, VariableList &variables) {
2309   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2310   Log *log = GetLog(DWARFLog::Lookups);
2311 
2312   if (log)
2313     GetObjectFile()->GetModule()->LogMessage(
2314         log,
2315         "SymbolFileDWARF::FindGlobalVariables (name=\"{0}\", "
2316         "parent_decl_ctx={1:p}, max_matches={2}, variables)",
2317         name.GetCString(), static_cast<const void *>(&parent_decl_ctx),
2318         max_matches);
2319 
2320   if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2321     return;
2322 
2323   // Remember how many variables are in the list before we search.
2324   const uint32_t original_size = variables.GetSize();
2325 
2326   llvm::StringRef basename;
2327   llvm::StringRef context;
2328   bool name_is_mangled = Mangled::GetManglingScheme(name.GetStringRef()) !=
2329                          Mangled::eManglingSchemeNone;
2330 
2331   if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name.GetCString(),
2332                                                       context, basename))
2333     basename = name.GetStringRef();
2334 
2335   // Loop invariant: Variables up to this index have been checked for context
2336   // matches.
2337   uint32_t pruned_idx = original_size;
2338 
2339   SymbolContext sc;
2340   m_index->GetGlobalVariables(ConstString(basename), [&](DWARFDIE die) {
2341     if (!sc.module_sp)
2342       sc.module_sp = m_objfile_sp->GetModule();
2343     assert(sc.module_sp);
2344 
2345     if (die.Tag() != DW_TAG_variable && die.Tag() != DW_TAG_member)
2346       return true;
2347 
2348     auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
2349     if (!dwarf_cu)
2350       return true;
2351     sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
2352 
2353     if (parent_decl_ctx) {
2354       if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) {
2355         CompilerDeclContext actual_parent_decl_ctx =
2356             dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
2357 
2358         /// If the actual namespace is inline (i.e., had a DW_AT_export_symbols)
2359         /// and a child (possibly through other layers of inline namespaces)
2360         /// of the namespace referred to by 'basename', allow the lookup to
2361         /// succeed.
2362         if (!actual_parent_decl_ctx ||
2363             (actual_parent_decl_ctx != parent_decl_ctx &&
2364              !parent_decl_ctx.IsContainedInLookup(actual_parent_decl_ctx)))
2365           return true;
2366       }
2367     }
2368 
2369     ParseAndAppendGlobalVariable(sc, die, variables);
2370     while (pruned_idx < variables.GetSize()) {
2371       VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx);
2372       if (name_is_mangled ||
2373           var_sp->GetName().GetStringRef().contains(name.GetStringRef()))
2374         ++pruned_idx;
2375       else
2376         variables.RemoveVariableAtIndex(pruned_idx);
2377     }
2378 
2379     return variables.GetSize() - original_size < max_matches;
2380   });
2381 
2382   // Return the number of variable that were appended to the list
2383   const uint32_t num_matches = variables.GetSize() - original_size;
2384   if (log && num_matches > 0) {
2385     GetObjectFile()->GetModule()->LogMessage(
2386         log,
2387         "SymbolFileDWARF::FindGlobalVariables (name=\"{0}\", "
2388         "parent_decl_ctx={1:p}, max_matches={2}, variables) => {3}",
2389         name.GetCString(), static_cast<const void *>(&parent_decl_ctx),
2390         max_matches, num_matches);
2391   }
2392 }
2393 
2394 void SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
2395                                           uint32_t max_matches,
2396                                           VariableList &variables) {
2397   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2398   Log *log = GetLog(DWARFLog::Lookups);
2399 
2400   if (log) {
2401     GetObjectFile()->GetModule()->LogMessage(
2402         log,
2403         "SymbolFileDWARF::FindGlobalVariables (regex=\"{0}\", "
2404         "max_matches={1}, variables)",
2405         regex.GetText().str().c_str(), max_matches);
2406   }
2407 
2408   // Remember how many variables are in the list before we search.
2409   const uint32_t original_size = variables.GetSize();
2410 
2411   SymbolContext sc;
2412   m_index->GetGlobalVariables(regex, [&](DWARFDIE die) {
2413     if (!sc.module_sp)
2414       sc.module_sp = m_objfile_sp->GetModule();
2415     assert(sc.module_sp);
2416 
2417     DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
2418     if (!dwarf_cu)
2419       return true;
2420     sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
2421 
2422     ParseAndAppendGlobalVariable(sc, die, variables);
2423 
2424     return variables.GetSize() - original_size < max_matches;
2425   });
2426 }
2427 
2428 bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
2429                                       bool include_inlines,
2430                                       SymbolContextList &sc_list) {
2431   SymbolContext sc;
2432 
2433   if (!orig_die)
2434     return false;
2435 
2436   // If we were passed a die that is not a function, just return false...
2437   if (!(orig_die.Tag() == DW_TAG_subprogram ||
2438         (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine)))
2439     return false;
2440 
2441   DWARFDIE die = orig_die;
2442   DWARFDIE inlined_die;
2443   if (die.Tag() == DW_TAG_inlined_subroutine) {
2444     inlined_die = die;
2445 
2446     while (true) {
2447       die = die.GetParent();
2448 
2449       if (die) {
2450         if (die.Tag() == DW_TAG_subprogram)
2451           break;
2452       } else
2453         break;
2454     }
2455   }
2456   assert(die && die.Tag() == DW_TAG_subprogram);
2457   if (GetFunction(die, sc)) {
2458     Address addr;
2459     // Parse all blocks if needed
2460     if (inlined_die) {
2461       Block &function_block = sc.function->GetBlock(true);
2462       sc.block = function_block.FindBlockByID(inlined_die.GetID());
2463       if (sc.block == nullptr)
2464         sc.block = function_block.FindBlockByID(inlined_die.GetOffset());
2465       if (sc.block == nullptr || !sc.block->GetStartAddress(addr))
2466         addr.Clear();
2467     } else {
2468       sc.block = nullptr;
2469       addr = sc.function->GetAddressRange().GetBaseAddress();
2470     }
2471 
2472     sc_list.Append(sc);
2473     return true;
2474   }
2475 
2476   return false;
2477 }
2478 
2479 bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext &decl_ctx,
2480                                        const DWARFDIE &die,
2481                                        bool only_root_namespaces) {
2482   // If we have no parent decl context to match this DIE matches, and if the
2483   // parent decl context isn't valid, we aren't trying to look for any
2484   // particular decl context so any die matches.
2485   if (!decl_ctx.IsValid()) {
2486     // ...But if we are only checking root decl contexts, confirm that the
2487     // 'die' is a top-level context.
2488     if (only_root_namespaces)
2489       return die.GetParent().Tag() == llvm::dwarf::DW_TAG_compile_unit;
2490 
2491     return true;
2492   }
2493 
2494   if (die) {
2495     if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) {
2496       if (CompilerDeclContext actual_decl_ctx =
2497               dwarf_ast->GetDeclContextContainingUIDFromDWARF(die))
2498         return decl_ctx.IsContainedInLookup(actual_decl_ctx);
2499     }
2500   }
2501   return false;
2502 }
2503 
2504 void SymbolFileDWARF::FindFunctions(const Module::LookupInfo &lookup_info,
2505                                     const CompilerDeclContext &parent_decl_ctx,
2506                                     bool include_inlines,
2507                                     SymbolContextList &sc_list) {
2508   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2509   ConstString name = lookup_info.GetLookupName();
2510   FunctionNameType name_type_mask = lookup_info.GetNameTypeMask();
2511 
2512   // eFunctionNameTypeAuto should be pre-resolved by a call to
2513   // Module::LookupInfo::LookupInfo()
2514   assert((name_type_mask & eFunctionNameTypeAuto) == 0);
2515 
2516   Log *log = GetLog(DWARFLog::Lookups);
2517 
2518   if (log) {
2519     GetObjectFile()->GetModule()->LogMessage(
2520         log,
2521         "SymbolFileDWARF::FindFunctions (name=\"{0}\", name_type_mask={1:x}, "
2522         "sc_list)",
2523         name.GetCString(), name_type_mask);
2524   }
2525 
2526   if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2527     return;
2528 
2529   // If name is empty then we won't find anything.
2530   if (name.IsEmpty())
2531     return;
2532 
2533   // Remember how many sc_list are in the list before we search in case we are
2534   // appending the results to a variable list.
2535 
2536   const uint32_t original_size = sc_list.GetSize();
2537 
2538   llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
2539 
2540   m_index->GetFunctions(lookup_info, *this, parent_decl_ctx, [&](DWARFDIE die) {
2541     if (resolved_dies.insert(die.GetDIE()).second)
2542       ResolveFunction(die, include_inlines, sc_list);
2543     return true;
2544   });
2545   // With -gsimple-template-names, a templated type's DW_AT_name will not
2546   // contain the template parameters. Try again stripping '<' and anything
2547   // after, filtering out entries with template parameters that don't match.
2548   {
2549     const llvm::StringRef name_ref = name.GetStringRef();
2550     auto it = name_ref.find('<');
2551     if (it != llvm::StringRef::npos) {
2552       const llvm::StringRef name_no_template_params = name_ref.slice(0, it);
2553 
2554       Module::LookupInfo no_tp_lookup_info(lookup_info);
2555       no_tp_lookup_info.SetLookupName(ConstString(name_no_template_params));
2556       m_index->GetFunctions(no_tp_lookup_info, *this, parent_decl_ctx,
2557                             [&](DWARFDIE die) {
2558                               if (resolved_dies.insert(die.GetDIE()).second)
2559                                 ResolveFunction(die, include_inlines, sc_list);
2560                               return true;
2561                             });
2562     }
2563   }
2564 
2565   // Return the number of variable that were appended to the list
2566   const uint32_t num_matches = sc_list.GetSize() - original_size;
2567 
2568   if (log && num_matches > 0) {
2569     GetObjectFile()->GetModule()->LogMessage(
2570         log,
2571         "SymbolFileDWARF::FindFunctions (name=\"{0}\", "
2572         "name_type_mask={1:x}, include_inlines={2:d}, sc_list) => {3}",
2573         name.GetCString(), name_type_mask, include_inlines, num_matches);
2574   }
2575 }
2576 
2577 void SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
2578                                     bool include_inlines,
2579                                     SymbolContextList &sc_list) {
2580   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2581   LLDB_SCOPED_TIMERF("SymbolFileDWARF::FindFunctions (regex = '%s')",
2582                      regex.GetText().str().c_str());
2583 
2584   Log *log = GetLog(DWARFLog::Lookups);
2585 
2586   if (log) {
2587     GetObjectFile()->GetModule()->LogMessage(
2588         log, "SymbolFileDWARF::FindFunctions (regex=\"{0}\", sc_list)",
2589         regex.GetText().str().c_str());
2590   }
2591 
2592   llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
2593   m_index->GetFunctions(regex, [&](DWARFDIE die) {
2594     if (resolved_dies.insert(die.GetDIE()).second)
2595       ResolveFunction(die, include_inlines, sc_list);
2596     return true;
2597   });
2598 }
2599 
2600 void SymbolFileDWARF::GetMangledNamesForFunction(
2601     const std::string &scope_qualified_name,
2602     std::vector<ConstString> &mangled_names) {
2603   DWARFDebugInfo &info = DebugInfo();
2604   uint32_t num_comp_units = info.GetNumUnits();
2605   for (uint32_t i = 0; i < num_comp_units; i++) {
2606     DWARFUnit *cu = info.GetUnitAtIndex(i);
2607     if (cu == nullptr)
2608       continue;
2609 
2610     SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile();
2611     if (dwo)
2612       dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names);
2613   }
2614 
2615   for (DIERef die_ref :
2616        m_function_scope_qualified_name_map.lookup(scope_qualified_name)) {
2617     DWARFDIE die = GetDIE(die_ref);
2618     mangled_names.push_back(ConstString(die.GetMangledName()));
2619   }
2620 }
2621 
2622 /// Split a name up into a basename and template parameters.
2623 static bool SplitTemplateParams(llvm::StringRef fullname,
2624                                 llvm::StringRef &basename,
2625                                 llvm::StringRef &template_params) {
2626   auto it = fullname.find('<');
2627   if (it == llvm::StringRef::npos) {
2628     basename = fullname;
2629     template_params = llvm::StringRef();
2630     return false;
2631   }
2632   basename = fullname.slice(0, it);
2633   template_params = fullname.slice(it, fullname.size());
2634   return true;
2635 }
2636 
2637 static bool UpdateCompilerContextForSimpleTemplateNames(TypeQuery &match) {
2638   // We need to find any names in the context that have template parameters
2639   // and strip them so the context can be matched when -gsimple-template-names
2640   // is being used. Returns true if any of the context items were updated.
2641   bool any_context_updated = false;
2642   for (auto &context : match.GetContextRef()) {
2643     llvm::StringRef basename, params;
2644     if (SplitTemplateParams(context.name.GetStringRef(), basename, params)) {
2645       context.name = ConstString(basename);
2646       any_context_updated = true;
2647     }
2648   }
2649   return any_context_updated;
2650 }
2651 
2652 uint64_t SymbolFileDWARF::GetDebugInfoSize(bool load_all_debug_info) {
2653   DWARFDebugInfo &info = DebugInfo();
2654   uint32_t num_comp_units = info.GetNumUnits();
2655 
2656   uint64_t debug_info_size = SymbolFileCommon::GetDebugInfoSize();
2657   // In dwp scenario, debug info == skeleton debug info + dwp debug info.
2658   if (std::shared_ptr<SymbolFileDWARFDwo> dwp_sp = GetDwpSymbolFile())
2659     return debug_info_size + dwp_sp->GetDebugInfoSize();
2660 
2661   // In dwo scenario, debug info == skeleton debug info + all dwo debug info.
2662   for (uint32_t i = 0; i < num_comp_units; i++) {
2663     DWARFUnit *cu = info.GetUnitAtIndex(i);
2664     if (cu == nullptr)
2665       continue;
2666 
2667     SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile(load_all_debug_info);
2668     if (dwo)
2669       debug_info_size += dwo->GetDebugInfoSize();
2670   }
2671   return debug_info_size;
2672 }
2673 
2674 void SymbolFileDWARF::FindTypes(const TypeQuery &query, TypeResults &results) {
2675 
2676   // Make sure we haven't already searched this SymbolFile before.
2677   if (results.AlreadySearched(this))
2678     return;
2679 
2680   auto type_basename = query.GetTypeBasename();
2681 
2682   Log *log = GetLog(DWARFLog::Lookups);
2683   if (log) {
2684     GetObjectFile()->GetModule()->LogMessage(
2685         log, "SymbolFileDWARF::FindTypes(type_basename=\"{0}\")",
2686         type_basename);
2687   }
2688 
2689   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2690 
2691   TypeQuery query_full(query);
2692   bool have_index_match = false;
2693   m_index->GetTypesWithQuery(query_full, [&](DWARFDIE die) {
2694     if (Type *matching_type = ResolveType(die, true, true)) {
2695       if (!query.GetSearchByMangledName() && matching_type->IsTemplateType()) {
2696         // We have to watch out for case where we lookup a type by basename and
2697         // it matches a template with simple template names. Like looking up
2698         // "Foo" and if we have simple template names then we will match
2699         // "Foo<int>" and "Foo<double>" because all the DWARF has is "Foo" in
2700         // the accelerator tables. The main case we see this in is when the
2701         // expression parser is trying to parse "Foo<int>" and it will first do
2702         // a lookup on just "Foo". We verify the type basename matches before
2703         // inserting the type in the results.
2704         auto CompilerTypeBasename =
2705             matching_type->GetForwardCompilerType().GetTypeName(true);
2706         if (CompilerTypeBasename != query.GetTypeBasename())
2707           return true; // Keep iterating over index types, basename mismatch.
2708       }
2709       have_index_match = true;
2710       results.InsertUnique(matching_type->shared_from_this());
2711     }
2712     return !results.Done(query); // Keep iterating if we aren't done.
2713   });
2714 
2715   if (results.Done(query)) {
2716     if (log) {
2717       GetObjectFile()->GetModule()->LogMessage(
2718           log, "SymbolFileDWARF::FindTypes(type_basename=\"{0}\") => {1}",
2719           type_basename, results.GetTypeMap().GetSize());
2720     }
2721     return;
2722   }
2723 
2724   // With -gsimple-template-names, a templated type's DW_AT_name will not
2725   // contain the template parameters. Try again stripping '<' and anything
2726   // after, filtering out entries with template parameters that don't match.
2727   if (!have_index_match && !query.GetSearchByMangledName()) {
2728     // Create a type matcher with a compiler context that is tuned for
2729     // -gsimple-template-names. We will use this for the index lookup and the
2730     // context matching, but will use the original "match" to insert matches
2731     // into if things match. The "match_simple" has a compiler context with
2732     // all template parameters removed to allow the names and context to match.
2733     // The UpdateCompilerContextForSimpleTemplateNames(...) will return true if
2734     // it trims any context items down by removing template parameter names.
2735     TypeQuery query_simple(query);
2736     if (UpdateCompilerContextForSimpleTemplateNames(query_simple)) {
2737       auto type_basename_simple = query_simple.GetTypeBasename();
2738       // Copy our match's context and update the basename we are looking for
2739       // so we can use this only to compare the context correctly.
2740       m_index->GetTypesWithQuery(query_simple, [&](DWARFDIE die) {
2741         std::vector<CompilerContext> qualified_context =
2742             query.GetModuleSearch()
2743                 ? die.GetDeclContext(/*derive_template_names=*/true)
2744                 : die.GetTypeLookupContext(/*derive_template_names=*/true);
2745         if (query.ContextMatches(qualified_context))
2746           if (Type *matching_type = ResolveType(die, true, true))
2747             results.InsertUnique(matching_type->shared_from_this());
2748         return !results.Done(query); // Keep iterating if we aren't done.
2749       });
2750       if (results.Done(query)) {
2751         if (log) {
2752           GetObjectFile()->GetModule()->LogMessage(
2753               log,
2754               "SymbolFileDWARF::FindTypes(type_basename=\"{0}\") => {1} "
2755               "(simplified as \"{2}\")",
2756               type_basename, results.GetTypeMap().GetSize(),
2757               type_basename_simple);
2758         }
2759         return;
2760       }
2761     }
2762   }
2763 
2764   // Next search through the reachable Clang modules. This only applies for
2765   // DWARF objects compiled with -gmodules that haven't been processed by
2766   // dsymutil.
2767   UpdateExternalModuleListIfNeeded();
2768 
2769   for (const auto &pair : m_external_type_modules) {
2770     if (ModuleSP external_module_sp = pair.second) {
2771       external_module_sp->FindTypes(query, results);
2772       if (results.Done(query)) {
2773         // We don't log the results here as they are already logged in the
2774         // nested FindTypes call
2775         return;
2776       }
2777     }
2778   }
2779 }
2780 
2781 CompilerDeclContext
2782 SymbolFileDWARF::FindNamespace(ConstString name,
2783                                const CompilerDeclContext &parent_decl_ctx,
2784                                bool only_root_namespaces) {
2785   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2786   Log *log = GetLog(DWARFLog::Lookups);
2787 
2788   if (log) {
2789     GetObjectFile()->GetModule()->LogMessage(
2790         log, "SymbolFileDWARF::FindNamespace (sc, name=\"{0}\")",
2791         name.GetCString());
2792   }
2793 
2794   CompilerDeclContext namespace_decl_ctx;
2795 
2796   if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
2797     return namespace_decl_ctx;
2798 
2799   m_index->GetNamespacesWithParents(name, parent_decl_ctx, [&](DWARFDIE die) {
2800     if (!DIEInDeclContext(parent_decl_ctx, die, only_root_namespaces))
2801       return true; // The containing decl contexts don't match
2802 
2803     DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU());
2804     if (!dwarf_ast)
2805       return true;
2806 
2807     namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die);
2808     return !namespace_decl_ctx.IsValid();
2809   });
2810 
2811   if (log && namespace_decl_ctx) {
2812     GetObjectFile()->GetModule()->LogMessage(
2813         log,
2814         "SymbolFileDWARF::FindNamespace (sc, name=\"{0}\") => "
2815         "CompilerDeclContext({1:p}/{2:p}) \"{3}\"",
2816         name.GetCString(),
2817         static_cast<const void *>(namespace_decl_ctx.GetTypeSystem()),
2818         static_cast<const void *>(namespace_decl_ctx.GetOpaqueDeclContext()),
2819         namespace_decl_ctx.GetName().AsCString("<NULL>"));
2820   }
2821 
2822   return namespace_decl_ctx;
2823 }
2824 
2825 TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die,
2826                                       bool resolve_function_context) {
2827   TypeSP type_sp;
2828   if (die) {
2829     Type *type_ptr = GetDIEToType().lookup(die.GetDIE());
2830     if (type_ptr == nullptr) {
2831       SymbolContextScope *scope;
2832       if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU()))
2833         scope = GetCompUnitForDWARFCompUnit(*dwarf_cu);
2834       else
2835         scope = GetObjectFile()->GetModule().get();
2836       assert(scope);
2837       SymbolContext sc(scope);
2838       const DWARFDebugInfoEntry *parent_die = die.GetParent().GetDIE();
2839       while (parent_die != nullptr) {
2840         if (parent_die->Tag() == DW_TAG_subprogram)
2841           break;
2842         parent_die = parent_die->GetParent();
2843       }
2844       SymbolContext sc_backup = sc;
2845       if (resolve_function_context && parent_die != nullptr &&
2846           !GetFunction(DWARFDIE(die.GetCU(), parent_die), sc))
2847         sc = sc_backup;
2848 
2849       type_sp = ParseType(sc, die, nullptr);
2850     } else if (type_ptr != DIE_IS_BEING_PARSED) {
2851       // Get the original shared pointer for this type
2852       type_sp = type_ptr->shared_from_this();
2853     }
2854   }
2855   return type_sp;
2856 }
2857 
2858 DWARFDIE
2859 SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) {
2860   if (orig_die) {
2861     DWARFDIE die = orig_die;
2862 
2863     while (die) {
2864       // If this is the original DIE that we are searching for a declaration
2865       // for, then don't look in the cache as we don't want our own decl
2866       // context to be our decl context...
2867       if (orig_die != die) {
2868         switch (die.Tag()) {
2869         case DW_TAG_compile_unit:
2870         case DW_TAG_partial_unit:
2871         case DW_TAG_namespace:
2872         case DW_TAG_structure_type:
2873         case DW_TAG_union_type:
2874         case DW_TAG_class_type:
2875         case DW_TAG_lexical_block:
2876         case DW_TAG_subprogram:
2877           return die;
2878         case DW_TAG_inlined_subroutine: {
2879           DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
2880           if (abs_die) {
2881             return abs_die;
2882           }
2883           break;
2884         }
2885         default:
2886           break;
2887         }
2888       }
2889 
2890       DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification);
2891       if (spec_die) {
2892         DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die);
2893         if (decl_ctx_die)
2894           return decl_ctx_die;
2895       }
2896 
2897       DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
2898       if (abs_die) {
2899         DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die);
2900         if (decl_ctx_die)
2901           return decl_ctx_die;
2902       }
2903 
2904       die = die.GetParent();
2905     }
2906   }
2907   return DWARFDIE();
2908 }
2909 
2910 Symbol *SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {
2911   Symbol *objc_class_symbol = nullptr;
2912   if (m_objfile_sp) {
2913     Symtab *symtab = m_objfile_sp->GetSymtab();
2914     if (symtab) {
2915       objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(
2916           objc_class_name, eSymbolTypeObjCClass, Symtab::eDebugNo,
2917           Symtab::eVisibilityAny);
2918     }
2919   }
2920   return objc_class_symbol;
2921 }
2922 
2923 // This function can be used when a DIE is found that is a forward declaration
2924 // DIE and we want to try and find a type that has the complete definition.
2925 TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
2926     const DWARFDIE &die, ConstString type_name, bool must_be_implementation) {
2927 
2928   TypeSP type_sp;
2929 
2930   if (!type_name || (must_be_implementation && !GetObjCClassSymbol(type_name)))
2931     return type_sp;
2932 
2933   m_index->GetCompleteObjCClass(
2934       type_name, must_be_implementation, [&](DWARFDIE type_die) {
2935         // Don't try and resolve the DIE we are looking for with the DIE
2936         // itself!
2937         if (type_die == die || !IsStructOrClassTag(type_die.Tag()))
2938           return true;
2939 
2940         if (must_be_implementation) {
2941           const bool try_resolving_type = type_die.GetAttributeValueAsUnsigned(
2942               DW_AT_APPLE_objc_complete_type, 0);
2943           if (!try_resolving_type)
2944             return true;
2945         }
2946 
2947         Type *resolved_type = ResolveType(type_die, false, true);
2948         if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED)
2949           return true;
2950 
2951         DEBUG_PRINTF(
2952             "resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64
2953             " (cu 0x%8.8" PRIx64 ")\n",
2954             die.GetID(),
2955             m_objfile_sp->GetFileSpec().GetFilename().AsCString("<Unknown>"),
2956             type_die.GetID(), type_cu->GetID());
2957 
2958         if (die)
2959           GetDIEToType()[die.GetDIE()] = resolved_type;
2960         type_sp = resolved_type->shared_from_this();
2961         return false;
2962       });
2963   return type_sp;
2964 }
2965 
2966 DWARFDIE
2967 SymbolFileDWARF::FindDefinitionDIE(const DWARFDIE &die) {
2968   const char *name = die.GetName();
2969   if (!name)
2970     return {};
2971   if (!die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0))
2972     return die;
2973 
2974   Progress progress(llvm::formatv(
2975       "Searching definition DIE in {0}: '{1}'",
2976       GetObjectFile()->GetFileSpec().GetFilename().GetString(), name));
2977 
2978   const dw_tag_t tag = die.Tag();
2979 
2980   Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
2981   if (log) {
2982     GetObjectFile()->GetModule()->LogMessage(
2983         log,
2984         "SymbolFileDWARF::FindDefinitionDIE(tag={0} "
2985         "({1}), name='{2}')",
2986         DW_TAG_value_to_name(tag), tag, name);
2987   }
2988 
2989   // Get the type system that we are looking to find a type for. We will
2990   // use this to ensure any matches we find are in a language that this
2991   // type system supports
2992   const LanguageType language = GetLanguage(*die.GetCU());
2993   TypeSystemSP type_system = nullptr;
2994   if (language != eLanguageTypeUnknown) {
2995     auto type_system_or_err = GetTypeSystemForLanguage(language);
2996     if (auto err = type_system_or_err.takeError()) {
2997       LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
2998                      "Cannot get TypeSystem for language {1}: {0}",
2999                      Language::GetNameForLanguageType(language));
3000     } else {
3001       type_system = *type_system_or_err;
3002     }
3003   }
3004 
3005   // See comments below about -gsimple-template-names for why we attempt to
3006   // compute missing template parameter names.
3007   std::vector<std::string> template_params;
3008   DWARFDeclContext die_dwarf_decl_ctx;
3009   DWARFASTParser *dwarf_ast =
3010       type_system ? type_system->GetDWARFParser() : nullptr;
3011   for (DWARFDIE ctx_die = die; ctx_die && !isUnitType(ctx_die.Tag());
3012        ctx_die = ctx_die.GetParentDeclContextDIE()) {
3013     die_dwarf_decl_ctx.AppendDeclContext(ctx_die.Tag(), ctx_die.GetName());
3014     template_params.push_back(
3015         (ctx_die.IsStructUnionOrClass() && dwarf_ast)
3016             ? dwarf_ast->GetDIEClassTemplateParams(ctx_die)
3017             : "");
3018   }
3019   const bool any_template_params = llvm::any_of(
3020       template_params, [](llvm::StringRef p) { return !p.empty(); });
3021 
3022   auto die_matches = [&](DWARFDIE type_die) {
3023     // Resolve the type if both have the same tag or {class, struct} tags.
3024     const bool tag_matches =
3025         type_die.Tag() == tag ||
3026         (IsStructOrClassTag(type_die.Tag()) && IsStructOrClassTag(tag));
3027     if (!tag_matches)
3028       return false;
3029     if (any_template_params) {
3030       size_t pos = 0;
3031       for (DWARFDIE ctx_die = type_die; ctx_die && !isUnitType(ctx_die.Tag()) &&
3032                                         pos < template_params.size();
3033            ctx_die = ctx_die.GetParentDeclContextDIE(), ++pos) {
3034         if (template_params[pos].empty())
3035           continue;
3036         if (template_params[pos] !=
3037             dwarf_ast->GetDIEClassTemplateParams(ctx_die))
3038           return false;
3039       }
3040       if (pos != template_params.size())
3041         return false;
3042     }
3043     return true;
3044   };
3045   DWARFDIE result;
3046   m_index->GetFullyQualifiedType(die_dwarf_decl_ctx, [&](DWARFDIE type_die) {
3047     // Make sure type_die's language matches the type system we are
3048     // looking for. We don't want to find a "Foo" type from Java if we
3049     // are looking for a "Foo" type for C, C++, ObjC, or ObjC++.
3050     if (type_system &&
3051         !type_system->SupportsLanguage(GetLanguage(*type_die.GetCU())))
3052       return true;
3053 
3054     if (!die_matches(type_die)) {
3055       if (log) {
3056         GetObjectFile()->GetModule()->LogMessage(
3057             log,
3058             "SymbolFileDWARF::FindDefinitionDIE(tag={0} ({1}), "
3059             "name='{2}') ignoring die={3:x16} ({4})",
3060             DW_TAG_value_to_name(tag), tag, name, type_die.GetOffset(),
3061             type_die.GetName());
3062       }
3063       return true;
3064     }
3065 
3066     if (log) {
3067       DWARFDeclContext type_dwarf_decl_ctx = type_die.GetDWARFDeclContext();
3068       GetObjectFile()->GetModule()->LogMessage(
3069           log,
3070           "SymbolFileDWARF::FindDefinitionTypeDIE(tag={0} ({1}), name='{2}') "
3071           "trying die={3:x16} ({4})",
3072           DW_TAG_value_to_name(tag), tag, name, type_die.GetOffset(),
3073           type_dwarf_decl_ctx.GetQualifiedName());
3074     }
3075 
3076     result = type_die;
3077     return false;
3078   });
3079   return result;
3080 }
3081 
3082 TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,
3083                                   bool *type_is_new_ptr) {
3084   if (!die)
3085     return {};
3086 
3087   auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));
3088   if (auto err = type_system_or_err.takeError()) {
3089     LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
3090                    "Unable to parse type: {0}");
3091     return {};
3092   }
3093   auto ts = *type_system_or_err;
3094   if (!ts)
3095     return {};
3096 
3097   DWARFASTParser *dwarf_ast = ts->GetDWARFParser();
3098   if (!dwarf_ast)
3099     return {};
3100 
3101   TypeSP type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, type_is_new_ptr);
3102   if (type_sp) {
3103     if (die.Tag() == DW_TAG_subprogram) {
3104       std::string scope_qualified_name(GetDeclContextForUID(die.GetID())
3105                                            .GetScopeQualifiedName()
3106                                            .AsCString(""));
3107       if (scope_qualified_name.size()) {
3108         m_function_scope_qualified_name_map[scope_qualified_name].insert(
3109             *die.GetDIERef());
3110       }
3111     }
3112   }
3113 
3114   return type_sp;
3115 }
3116 
3117 size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,
3118                                    const DWARFDIE &orig_die,
3119                                    bool parse_siblings, bool parse_children) {
3120   size_t types_added = 0;
3121   DWARFDIE die = orig_die;
3122 
3123   while (die) {
3124     const dw_tag_t tag = die.Tag();
3125     bool type_is_new = false;
3126 
3127     Tag dwarf_tag = static_cast<Tag>(tag);
3128 
3129     // TODO: Currently ParseTypeFromDWARF(...) which is called by ParseType(...)
3130     // does not handle DW_TAG_subrange_type. It is not clear if this is a bug or
3131     // not.
3132     if (isType(dwarf_tag) && tag != DW_TAG_subrange_type)
3133       ParseType(sc, die, &type_is_new);
3134 
3135     if (type_is_new)
3136       ++types_added;
3137 
3138     if (parse_children && die.HasChildren()) {
3139       if (die.Tag() == DW_TAG_subprogram) {
3140         SymbolContext child_sc(sc);
3141         child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
3142         types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true);
3143       } else
3144         types_added += ParseTypes(sc, die.GetFirstChild(), true, true);
3145     }
3146 
3147     if (parse_siblings)
3148       die = die.GetSibling();
3149     else
3150       die.Clear();
3151   }
3152   return types_added;
3153 }
3154 
3155 size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
3156   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
3157   CompileUnit *comp_unit = func.GetCompileUnit();
3158   lldbassert(comp_unit);
3159 
3160   DWARFUnit *dwarf_cu = GetDWARFCompileUnit(comp_unit);
3161   if (!dwarf_cu)
3162     return 0;
3163 
3164   size_t functions_added = 0;
3165   const dw_offset_t function_die_offset = DIERef(func.GetID()).die_offset();
3166   DWARFDIE function_die =
3167       dwarf_cu->GetNonSkeletonUnit().GetDIE(function_die_offset);
3168   if (function_die) {
3169     // We can't use the file address from the Function object as (in the OSO
3170     // case) it will already be remapped to the main module.
3171     if (llvm::Expected<llvm::DWARFAddressRangesVector> ranges =
3172             function_die.GetDIE()->GetAttributeAddressRanges(
3173                 function_die.GetCU(),
3174                 /*check_hi_lo_pc=*/true)) {
3175       if (ranges->empty())
3176         return 0;
3177       dw_addr_t function_file_addr = ranges->begin()->LowPC;
3178       if (function_file_addr != LLDB_INVALID_ADDRESS)
3179         ParseBlocksRecursive(*comp_unit, &func.GetBlock(false),
3180                              function_die.GetFirstChild(), function_file_addr);
3181     } else {
3182       LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), ranges.takeError(),
3183                      "{1:x}: {0}", dwarf_cu->GetOffset());
3184     }
3185   }
3186 
3187   return functions_added;
3188 }
3189 
3190 size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) {
3191   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
3192   size_t types_added = 0;
3193   DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
3194   if (dwarf_cu) {
3195     DWARFDIE dwarf_cu_die = dwarf_cu->DIE();
3196     if (dwarf_cu_die && dwarf_cu_die.HasChildren()) {
3197       SymbolContext sc;
3198       sc.comp_unit = &comp_unit;
3199       types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true);
3200     }
3201   }
3202 
3203   return types_added;
3204 }
3205 
3206 size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
3207   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
3208   if (sc.comp_unit != nullptr) {
3209     if (sc.function) {
3210       DWARFDIE function_die = GetDIE(sc.function->GetID());
3211 
3212       dw_addr_t func_lo_pc = LLDB_INVALID_ADDRESS;
3213       if (llvm::Expected<llvm::DWARFAddressRangesVector> ranges =
3214               function_die.GetDIE()->GetAttributeAddressRanges(
3215                   function_die.GetCU(), /*check_hi_lo_pc=*/true)) {
3216         if (!ranges->empty())
3217           func_lo_pc = ranges->begin()->LowPC;
3218       } else {
3219         LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), ranges.takeError(),
3220                        "DIE({1:x}): {0}", function_die.GetID());
3221       }
3222       if (func_lo_pc != LLDB_INVALID_ADDRESS) {
3223         const size_t num_variables =
3224             ParseVariablesInFunctionContext(sc, function_die, func_lo_pc);
3225 
3226         // Let all blocks know they have parse all their variables
3227         sc.function->GetBlock(false).SetDidParseVariables(true, true);
3228         return num_variables;
3229       }
3230     } else if (sc.comp_unit) {
3231       DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(sc.comp_unit->GetID());
3232 
3233       if (dwarf_cu == nullptr)
3234         return 0;
3235 
3236       uint32_t vars_added = 0;
3237       VariableListSP variables(sc.comp_unit->GetVariableList(false));
3238 
3239       if (variables.get() == nullptr) {
3240         variables = std::make_shared<VariableList>();
3241         sc.comp_unit->SetVariableList(variables);
3242 
3243         m_index->GetGlobalVariables(*dwarf_cu, [&](DWARFDIE die) {
3244           VariableSP var_sp(ParseVariableDIECached(sc, die));
3245           if (var_sp) {
3246             variables->AddVariableIfUnique(var_sp);
3247             ++vars_added;
3248           }
3249           return true;
3250         });
3251       }
3252       return vars_added;
3253     }
3254   }
3255   return 0;
3256 }
3257 
3258 VariableSP SymbolFileDWARF::ParseVariableDIECached(const SymbolContext &sc,
3259                                                    const DWARFDIE &die) {
3260   if (!die)
3261     return nullptr;
3262 
3263   DIEToVariableSP &die_to_variable = die.GetDWARF()->GetDIEToVariable();
3264 
3265   VariableSP var_sp = die_to_variable[die.GetDIE()];
3266   if (var_sp)
3267     return var_sp;
3268 
3269   var_sp = ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS);
3270   if (var_sp) {
3271     die_to_variable[die.GetDIE()] = var_sp;
3272     if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification))
3273       die_to_variable[spec_die.GetDIE()] = var_sp;
3274   }
3275   return var_sp;
3276 }
3277 
3278 /// Creates a DWARFExpressionList from an DW_AT_location form_value.
3279 static DWARFExpressionList GetExprListFromAtLocation(DWARFFormValue form_value,
3280                                                      ModuleSP module,
3281                                                      const DWARFDIE &die,
3282                                                      const addr_t func_low_pc) {
3283   if (DWARFFormValue::IsBlockForm(form_value.Form())) {
3284     const DWARFDataExtractor &data = die.GetData();
3285 
3286     uint64_t block_offset = form_value.BlockData() - data.GetDataStart();
3287     uint64_t block_length = form_value.Unsigned();
3288     return DWARFExpressionList(
3289         module, DataExtractor(data, block_offset, block_length), die.GetCU());
3290   }
3291 
3292   DWARFExpressionList location_list(module, DWARFExpression(), die.GetCU());
3293   DataExtractor data = die.GetCU()->GetLocationData();
3294   dw_offset_t offset = form_value.Unsigned();
3295   if (form_value.Form() == DW_FORM_loclistx)
3296     offset = die.GetCU()->GetLoclistOffset(offset).value_or(-1);
3297   if (data.ValidOffset(offset)) {
3298     data = DataExtractor(data, offset, data.GetByteSize() - offset);
3299     const DWARFUnit *dwarf_cu = form_value.GetUnit();
3300     if (DWARFExpression::ParseDWARFLocationList(dwarf_cu, data, &location_list))
3301       location_list.SetFuncFileAddress(func_low_pc);
3302   }
3303 
3304   return location_list;
3305 }
3306 
3307 /// Creates a DWARFExpressionList from an DW_AT_const_value. This is either a
3308 /// block form, or a string, or a data form. For data forms, this returns an
3309 /// empty list, as we cannot initialize it properly without a SymbolFileType.
3310 static DWARFExpressionList
3311 GetExprListFromAtConstValue(DWARFFormValue form_value, ModuleSP module,
3312                             const DWARFDIE &die) {
3313   const DWARFDataExtractor &debug_info_data = die.GetData();
3314   if (DWARFFormValue::IsBlockForm(form_value.Form())) {
3315     // Retrieve the value as a block expression.
3316     uint64_t block_offset =
3317         form_value.BlockData() - debug_info_data.GetDataStart();
3318     uint64_t block_length = form_value.Unsigned();
3319     return DWARFExpressionList(
3320         module, DataExtractor(debug_info_data, block_offset, block_length),
3321         die.GetCU());
3322   }
3323   if (const char *str = form_value.AsCString())
3324     return DWARFExpressionList(module,
3325                                DataExtractor(str, strlen(str) + 1,
3326                                              die.GetCU()->GetByteOrder(),
3327                                              die.GetCU()->GetAddressByteSize()),
3328                                die.GetCU());
3329   return DWARFExpressionList(module, DWARFExpression(), die.GetCU());
3330 }
3331 
3332 /// Global variables that are not initialized may have their address set to
3333 /// zero. Since multiple variables may have this address, we cannot apply the
3334 /// OSO relink address approach we normally use.
3335 /// However, the executable will have a matching symbol with a good address;
3336 /// this function attempts to find the correct address by looking into the
3337 /// executable's symbol table. If it succeeds, the expr_list is updated with
3338 /// the new address and the executable's symbol is returned.
3339 static Symbol *fixupExternalAddrZeroVariable(
3340     SymbolFileDWARFDebugMap &debug_map_symfile, llvm::StringRef name,
3341     DWARFExpressionList &expr_list, const DWARFDIE &die) {
3342   ObjectFile *debug_map_objfile = debug_map_symfile.GetObjectFile();
3343   if (!debug_map_objfile)
3344     return nullptr;
3345 
3346   Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
3347   if (!debug_map_symtab)
3348     return nullptr;
3349   Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType(
3350       ConstString(name), eSymbolTypeData, Symtab::eDebugYes,
3351       Symtab::eVisibilityExtern);
3352   if (!exe_symbol || !exe_symbol->ValueIsAddress())
3353     return nullptr;
3354   const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress();
3355   if (exe_file_addr == LLDB_INVALID_ADDRESS)
3356     return nullptr;
3357 
3358   DWARFExpression *location = expr_list.GetMutableExpressionAtAddress();
3359   if (location->Update_DW_OP_addr(die.GetCU(), exe_file_addr))
3360     return exe_symbol;
3361   return nullptr;
3362 }
3363 
3364 VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
3365                                              const DWARFDIE &die,
3366                                              const lldb::addr_t func_low_pc) {
3367   if (die.GetDWARF() != this)
3368     return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);
3369 
3370   if (!die)
3371     return nullptr;
3372 
3373   const dw_tag_t tag = die.Tag();
3374   ModuleSP module = GetObjectFile()->GetModule();
3375 
3376   if (tag != DW_TAG_variable && tag != DW_TAG_constant &&
3377       tag != DW_TAG_member && (tag != DW_TAG_formal_parameter || !sc.function))
3378     return nullptr;
3379 
3380   DWARFAttributes attributes = die.GetAttributes();
3381   const char *name = nullptr;
3382   const char *mangled = nullptr;
3383   Declaration decl;
3384   DWARFFormValue type_die_form;
3385   bool is_external = false;
3386   bool is_artificial = false;
3387   DWARFFormValue const_value_form, location_form;
3388   Variable::RangeList scope_ranges;
3389 
3390   for (size_t i = 0; i < attributes.Size(); ++i) {
3391     dw_attr_t attr = attributes.AttributeAtIndex(i);
3392     DWARFFormValue form_value;
3393 
3394     if (!attributes.ExtractFormValueAtIndex(i, form_value))
3395       continue;
3396     switch (attr) {
3397     case DW_AT_decl_file:
3398       decl.SetFile(
3399           attributes.CompileUnitAtIndex(i)->GetFile(form_value.Unsigned()));
3400       break;
3401     case DW_AT_decl_line:
3402       decl.SetLine(form_value.Unsigned());
3403       break;
3404     case DW_AT_decl_column:
3405       decl.SetColumn(form_value.Unsigned());
3406       break;
3407     case DW_AT_name:
3408       name = form_value.AsCString();
3409       break;
3410     case DW_AT_linkage_name:
3411     case DW_AT_MIPS_linkage_name:
3412       mangled = form_value.AsCString();
3413       break;
3414     case DW_AT_type:
3415       // DW_AT_type on declaration may be less accurate than
3416       // that of definition, so don't overwrite it.
3417       if (!type_die_form.IsValid())
3418         type_die_form = form_value;
3419       break;
3420     case DW_AT_external:
3421       is_external = form_value.Boolean();
3422       break;
3423     case DW_AT_const_value:
3424       const_value_form = form_value;
3425       break;
3426     case DW_AT_location:
3427       location_form = form_value;
3428       break;
3429     case DW_AT_start_scope:
3430       // TODO: Implement this.
3431       break;
3432     case DW_AT_artificial:
3433       is_artificial = form_value.Boolean();
3434       break;
3435     case DW_AT_declaration:
3436     case DW_AT_description:
3437     case DW_AT_endianity:
3438     case DW_AT_segment:
3439     case DW_AT_specification:
3440     case DW_AT_visibility:
3441     default:
3442     case DW_AT_abstract_origin:
3443     case DW_AT_sibling:
3444       break;
3445     }
3446   }
3447 
3448   // Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g.
3449   // for static constexpr member variables -- DW_AT_const_value and
3450   // DW_AT_location will both be present in the DIE defining the member.
3451   bool location_is_const_value_data =
3452       const_value_form.IsValid() && !location_form.IsValid();
3453 
3454   DWARFExpressionList location_list = [&] {
3455     if (location_form.IsValid())
3456       return GetExprListFromAtLocation(location_form, module, die, func_low_pc);
3457     if (const_value_form.IsValid())
3458       return GetExprListFromAtConstValue(const_value_form, module, die);
3459     return DWARFExpressionList(module, DWARFExpression(), die.GetCU());
3460   }();
3461 
3462   const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
3463   const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
3464   const dw_tag_t parent_tag = sc_parent_die.Tag();
3465   bool is_static_member = (parent_tag == DW_TAG_compile_unit ||
3466                            parent_tag == DW_TAG_partial_unit) &&
3467                           (parent_context_die.Tag() == DW_TAG_class_type ||
3468                            parent_context_die.Tag() == DW_TAG_structure_type);
3469 
3470   ValueType scope = eValueTypeInvalid;
3471   SymbolContextScope *symbol_context_scope = nullptr;
3472 
3473   bool has_explicit_mangled = mangled != nullptr;
3474   if (!mangled) {
3475     // LLDB relies on the mangled name (DW_TAG_linkage_name or
3476     // DW_AT_MIPS_linkage_name) to generate fully qualified names
3477     // of global variables with commands like "frame var j". For
3478     // example, if j were an int variable holding a value 4 and
3479     // declared in a namespace B which in turn is contained in a
3480     // namespace A, the command "frame var j" returns
3481     //   "(int) A::B::j = 4".
3482     // If the compiler does not emit a linkage name, we should be
3483     // able to generate a fully qualified name from the
3484     // declaration context.
3485     if ((parent_tag == DW_TAG_compile_unit ||
3486          parent_tag == DW_TAG_partial_unit) &&
3487         Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU())))
3488       mangled = die.GetDWARFDeclContext()
3489                     .GetQualifiedNameAsConstString()
3490                     .GetCString();
3491   }
3492 
3493   if (tag == DW_TAG_formal_parameter)
3494     scope = eValueTypeVariableArgument;
3495   else {
3496     // DWARF doesn't specify if a DW_TAG_variable is a local, global
3497     // or static variable, so we have to do a little digging:
3498     // 1) DW_AT_linkage_name implies static lifetime (but may be missing)
3499     // 2) An empty DW_AT_location is an (optimized-out) static lifetime var.
3500     // 3) DW_AT_location containing a DW_OP_addr implies static lifetime.
3501     // Clang likes to combine small global variables into the same symbol
3502     // with locations like: DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
3503     // so we need to look through the whole expression.
3504     bool has_explicit_location = location_form.IsValid();
3505     bool is_static_lifetime =
3506         has_explicit_mangled ||
3507         (has_explicit_location && !location_list.IsValid());
3508     // Check if the location has a DW_OP_addr with any address value...
3509     lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
3510     if (!location_is_const_value_data) {
3511       if (const DWARFExpression *location =
3512               location_list.GetAlwaysValidExpr()) {
3513         if (auto maybe_location_DW_OP_addr =
3514                 location->GetLocation_DW_OP_addr(location_form.GetUnit())) {
3515           location_DW_OP_addr = *maybe_location_DW_OP_addr;
3516         } else {
3517           StreamString strm;
3518           location->DumpLocation(&strm, eDescriptionLevelFull, nullptr);
3519           GetObjectFile()->GetModule()->ReportError(
3520               "{0:x16}: {1} ({2}) has an invalid location: {3}: {4}",
3521               die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.Tag(),
3522               llvm::fmt_consume(maybe_location_DW_OP_addr.takeError()),
3523               strm.GetData());
3524         }
3525       }
3526       if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
3527         is_static_lifetime = true;
3528     }
3529     SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
3530     if (debug_map_symfile)
3531       // Set the module of the expression to the linked module
3532       // instead of the object file so the relocated address can be
3533       // found there.
3534       location_list.SetModule(debug_map_symfile->GetObjectFile()->GetModule());
3535 
3536     if (is_static_lifetime) {
3537       if (is_external)
3538         scope = eValueTypeVariableGlobal;
3539       else
3540         scope = eValueTypeVariableStatic;
3541 
3542       if (debug_map_symfile) {
3543         bool linked_oso_file_addr = false;
3544 
3545         if (is_external && location_DW_OP_addr == 0) {
3546           if (Symbol *exe_symbol = fixupExternalAddrZeroVariable(
3547                   *debug_map_symfile, mangled ? mangled : name, location_list,
3548                   die)) {
3549             linked_oso_file_addr = true;
3550             symbol_context_scope = exe_symbol;
3551           }
3552         }
3553 
3554         if (!linked_oso_file_addr) {
3555           // The DW_OP_addr is not zero, but it contains a .o file address
3556           // which needs to be linked up correctly.
3557           const lldb::addr_t exe_file_addr =
3558               debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
3559           if (exe_file_addr != LLDB_INVALID_ADDRESS) {
3560             // Update the file address for this variable
3561             DWARFExpression *location =
3562                 location_list.GetMutableExpressionAtAddress();
3563             location->Update_DW_OP_addr(die.GetCU(), exe_file_addr);
3564           } else {
3565             // Variable didn't make it into the final executable
3566             return nullptr;
3567           }
3568         }
3569       }
3570     } else {
3571       if (location_is_const_value_data &&
3572           die.GetDIE()->IsGlobalOrStaticScopeVariable())
3573         scope = eValueTypeVariableStatic;
3574       else {
3575         scope = eValueTypeVariableLocal;
3576         if (debug_map_symfile) {
3577           // We need to check for TLS addresses that we need to fixup
3578           if (location_list.ContainsThreadLocalStorage()) {
3579             location_list.LinkThreadLocalStorage(
3580                 debug_map_symfile->GetObjectFile()->GetModule(),
3581                 [this, debug_map_symfile](
3582                     lldb::addr_t unlinked_file_addr) -> lldb::addr_t {
3583                   return debug_map_symfile->LinkOSOFileAddress(
3584                       this, unlinked_file_addr);
3585                 });
3586             scope = eValueTypeVariableThreadLocal;
3587           }
3588         }
3589       }
3590     }
3591   }
3592 
3593   if (symbol_context_scope == nullptr) {
3594     switch (parent_tag) {
3595     case DW_TAG_subprogram:
3596     case DW_TAG_inlined_subroutine:
3597     case DW_TAG_lexical_block:
3598       if (sc.function) {
3599         symbol_context_scope =
3600             sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
3601         if (symbol_context_scope == nullptr)
3602           symbol_context_scope = sc.function;
3603       }
3604       break;
3605 
3606     default:
3607       symbol_context_scope = sc.comp_unit;
3608       break;
3609     }
3610   }
3611 
3612   if (!symbol_context_scope) {
3613     // Not ready to parse this variable yet. It might be a global or static
3614     // variable that is in a function scope and the function in the symbol
3615     // context wasn't filled in yet
3616     return nullptr;
3617   }
3618 
3619   auto type_sp = std::make_shared<SymbolFileType>(
3620       *this, type_die_form.Reference().GetID());
3621 
3622   bool use_type_size_for_value =
3623       location_is_const_value_data &&
3624       DWARFFormValue::IsDataForm(const_value_form.Form());
3625   if (use_type_size_for_value && type_sp->GetType()) {
3626     DWARFExpression *location = location_list.GetMutableExpressionAtAddress();
3627     location->UpdateValue(const_value_form.Unsigned(),
3628                           type_sp->GetType()->GetByteSize(nullptr).value_or(0),
3629                           die.GetCU()->GetAddressByteSize());
3630   }
3631 
3632   return std::make_shared<Variable>(
3633       die.GetID(), name, mangled, type_sp, scope, symbol_context_scope,
3634       scope_ranges, &decl, location_list, is_external, is_artificial,
3635       location_is_const_value_data, is_static_member);
3636 }
3637 
3638 DWARFDIE
3639 SymbolFileDWARF::FindBlockContainingSpecification(
3640     const DIERef &func_die_ref, dw_offset_t spec_block_die_offset) {
3641   // Give the concrete function die specified by "func_die_offset", find the
3642   // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
3643   // to "spec_block_die_offset"
3644   return FindBlockContainingSpecification(GetDIE(func_die_ref),
3645                                           spec_block_die_offset);
3646 }
3647 
3648 DWARFDIE
3649 SymbolFileDWARF::FindBlockContainingSpecification(
3650     const DWARFDIE &die, dw_offset_t spec_block_die_offset) {
3651   if (die) {
3652     switch (die.Tag()) {
3653     case DW_TAG_subprogram:
3654     case DW_TAG_inlined_subroutine:
3655     case DW_TAG_lexical_block: {
3656       if (die.GetReferencedDIE(DW_AT_specification).GetOffset() ==
3657           spec_block_die_offset)
3658         return die;
3659 
3660       if (die.GetReferencedDIE(DW_AT_abstract_origin).GetOffset() ==
3661           spec_block_die_offset)
3662         return die;
3663     } break;
3664     default:
3665       break;
3666     }
3667 
3668     // Give the concrete function die specified by "func_die_offset", find the
3669     // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
3670     // to "spec_block_die_offset"
3671     for (DWARFDIE child_die : die.children()) {
3672       DWARFDIE result_die =
3673           FindBlockContainingSpecification(child_die, spec_block_die_offset);
3674       if (result_die)
3675         return result_die;
3676     }
3677   }
3678 
3679   return DWARFDIE();
3680 }
3681 
3682 void SymbolFileDWARF::ParseAndAppendGlobalVariable(
3683     const SymbolContext &sc, const DWARFDIE &die,
3684     VariableList &cc_variable_list) {
3685   if (!die)
3686     return;
3687 
3688   dw_tag_t tag = die.Tag();
3689   if (tag != DW_TAG_variable && tag != DW_TAG_constant && tag != DW_TAG_member)
3690     return;
3691 
3692   // Check to see if we have already parsed this variable or constant?
3693   VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
3694   if (var_sp) {
3695     cc_variable_list.AddVariableIfUnique(var_sp);
3696     return;
3697   }
3698 
3699   // We haven't parsed the variable yet, lets do that now. Also, let us include
3700   // the variable in the relevant compilation unit's variable list, if it
3701   // exists.
3702   VariableListSP variable_list_sp;
3703   DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
3704   dw_tag_t parent_tag = sc_parent_die.Tag();
3705   switch (parent_tag) {
3706   case DW_TAG_compile_unit:
3707   case DW_TAG_partial_unit:
3708     if (sc.comp_unit != nullptr) {
3709       variable_list_sp = sc.comp_unit->GetVariableList(false);
3710     } else {
3711       GetObjectFile()->GetModule()->ReportError(
3712           "parent {0:x8} {1} ({2}) with no valid compile unit in "
3713           "symbol context for {3:x8} {4} ({5}).\n",
3714           sc_parent_die.GetID(), DW_TAG_value_to_name(sc_parent_die.Tag()),
3715           sc_parent_die.Tag(), die.GetID(), DW_TAG_value_to_name(die.Tag()),
3716           die.Tag());
3717       return;
3718     }
3719     break;
3720 
3721   default:
3722     LLDB_LOG(GetLog(DWARFLog::Lookups),
3723              "{0} '{1}' ({2:x8}) is not a global variable - ignoring", tag,
3724              die.GetName(), die.GetID());
3725     return;
3726   }
3727 
3728   var_sp = ParseVariableDIECached(sc, die);
3729   if (!var_sp)
3730     return;
3731 
3732   cc_variable_list.AddVariableIfUnique(var_sp);
3733   if (variable_list_sp)
3734     variable_list_sp->AddVariableIfUnique(var_sp);
3735 }
3736 
3737 DIEArray
3738 SymbolFileDWARF::MergeBlockAbstractParameters(const DWARFDIE &block_die,
3739                                               DIEArray &&variable_dies) {
3740   // DW_TAG_inline_subroutine objects may omit DW_TAG_formal_parameter in
3741   // instances of the function when they are unused (i.e., the parameter's
3742   // location list would be empty). The current DW_TAG_inline_subroutine may
3743   // refer to another DW_TAG_subprogram that might actually have the definitions
3744   // of the parameters and we need to include these so they show up in the
3745   // variables for this function (for example, in a stack trace). Let us try to
3746   // find the abstract subprogram that might contain the parameter definitions
3747   // and merge with the concrete parameters.
3748 
3749   // Nothing to merge if the block is not an inlined function.
3750   if (block_die.Tag() != DW_TAG_inlined_subroutine) {
3751     return std::move(variable_dies);
3752   }
3753 
3754   // Nothing to merge if the block does not have abstract parameters.
3755   DWARFDIE abs_die = block_die.GetReferencedDIE(DW_AT_abstract_origin);
3756   if (!abs_die || abs_die.Tag() != DW_TAG_subprogram ||
3757       !abs_die.HasChildren()) {
3758     return std::move(variable_dies);
3759   }
3760 
3761   // For each abstract parameter, if we have its concrete counterpart, insert
3762   // it. Otherwise, insert the abstract parameter.
3763   DIEArray::iterator concrete_it = variable_dies.begin();
3764   DWARFDIE abstract_child = abs_die.GetFirstChild();
3765   DIEArray merged;
3766   bool did_merge_abstract = false;
3767   for (; abstract_child; abstract_child = abstract_child.GetSibling()) {
3768     if (abstract_child.Tag() == DW_TAG_formal_parameter) {
3769       if (concrete_it == variable_dies.end() ||
3770           GetDIE(*concrete_it).Tag() != DW_TAG_formal_parameter) {
3771         // We arrived at the end of the concrete parameter list, so all
3772         // the remaining abstract parameters must have been omitted.
3773         // Let us insert them to the merged list here.
3774         merged.push_back(*abstract_child.GetDIERef());
3775         did_merge_abstract = true;
3776         continue;
3777       }
3778 
3779       DWARFDIE origin_of_concrete =
3780           GetDIE(*concrete_it).GetReferencedDIE(DW_AT_abstract_origin);
3781       if (origin_of_concrete == abstract_child) {
3782         // The current abstract parameter is the origin of the current
3783         // concrete parameter, just push the concrete parameter.
3784         merged.push_back(*concrete_it);
3785         ++concrete_it;
3786       } else {
3787         // Otherwise, the parameter must have been omitted from the concrete
3788         // function, so insert the abstract one.
3789         merged.push_back(*abstract_child.GetDIERef());
3790         did_merge_abstract = true;
3791       }
3792     }
3793   }
3794 
3795   // Shortcut if no merging happened.
3796   if (!did_merge_abstract)
3797     return std::move(variable_dies);
3798 
3799   // We inserted all the abstract parameters (or their concrete counterparts).
3800   // Let us insert all the remaining concrete variables to the merged list.
3801   // During the insertion, let us check there are no remaining concrete
3802   // formal parameters. If that's the case, then just bailout from the merge -
3803   // the variable list is malformed.
3804   for (; concrete_it != variable_dies.end(); ++concrete_it) {
3805     if (GetDIE(*concrete_it).Tag() == DW_TAG_formal_parameter) {
3806       return std::move(variable_dies);
3807     }
3808     merged.push_back(*concrete_it);
3809   }
3810   return merged;
3811 }
3812 
3813 size_t SymbolFileDWARF::ParseVariablesInFunctionContext(
3814     const SymbolContext &sc, const DWARFDIE &die,
3815     const lldb::addr_t func_low_pc) {
3816   if (!die || !sc.function)
3817     return 0;
3818 
3819   DIEArray dummy_block_variables; // The recursive call should not add anything
3820                                   // to this vector because |die| should be a
3821                                   // subprogram, so all variables will be added
3822                                   // to the subprogram's list.
3823   return ParseVariablesInFunctionContextRecursive(sc, die, func_low_pc,
3824                                                   dummy_block_variables);
3825 }
3826 
3827 // This method parses all the variables in the blocks in the subtree of |die|,
3828 // and inserts them to the variable list for all the nested blocks.
3829 // The uninserted variables for the current block are accumulated in
3830 // |accumulator|.
3831 size_t SymbolFileDWARF::ParseVariablesInFunctionContextRecursive(
3832     const lldb_private::SymbolContext &sc, const DWARFDIE &die,
3833     lldb::addr_t func_low_pc, DIEArray &accumulator) {
3834   size_t vars_added = 0;
3835   dw_tag_t tag = die.Tag();
3836 
3837   if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
3838       (tag == DW_TAG_formal_parameter)) {
3839     accumulator.push_back(*die.GetDIERef());
3840   }
3841 
3842   switch (tag) {
3843   case DW_TAG_subprogram:
3844   case DW_TAG_inlined_subroutine:
3845   case DW_TAG_lexical_block: {
3846     // If we start a new block, compute a new block variable list and recurse.
3847     Block *block =
3848         sc.function->GetBlock(/*can_create=*/true).FindBlockByID(die.GetID());
3849     if (block == nullptr) {
3850       // This must be a specification or abstract origin with a
3851       // concrete block counterpart in the current function. We need
3852       // to find the concrete block so we can correctly add the
3853       // variable to it.
3854       const DWARFDIE concrete_block_die = FindBlockContainingSpecification(
3855           GetDIE(sc.function->GetID()), die.GetOffset());
3856       if (concrete_block_die)
3857         block = sc.function->GetBlock(/*can_create=*/true)
3858                     .FindBlockByID(concrete_block_die.GetID());
3859     }
3860 
3861     if (block == nullptr)
3862       return 0;
3863 
3864     const bool can_create = false;
3865     VariableListSP block_variable_list_sp =
3866         block->GetBlockVariableList(can_create);
3867     if (block_variable_list_sp.get() == nullptr) {
3868       block_variable_list_sp = std::make_shared<VariableList>();
3869       block->SetVariableList(block_variable_list_sp);
3870     }
3871 
3872     DIEArray block_variables;
3873     for (DWARFDIE child = die.GetFirstChild(); child;
3874          child = child.GetSibling()) {
3875       vars_added += ParseVariablesInFunctionContextRecursive(
3876           sc, child, func_low_pc, block_variables);
3877     }
3878     block_variables =
3879         MergeBlockAbstractParameters(die, std::move(block_variables));
3880     vars_added += PopulateBlockVariableList(*block_variable_list_sp, sc,
3881                                             block_variables, func_low_pc);
3882     break;
3883   }
3884 
3885   default:
3886     // Recurse to children with the same variable accumulator.
3887     for (DWARFDIE child = die.GetFirstChild(); child;
3888          child = child.GetSibling()) {
3889       vars_added += ParseVariablesInFunctionContextRecursive(
3890           sc, child, func_low_pc, accumulator);
3891     }
3892     break;
3893   }
3894 
3895   return vars_added;
3896 }
3897 
3898 size_t SymbolFileDWARF::PopulateBlockVariableList(
3899     VariableList &variable_list, const lldb_private::SymbolContext &sc,
3900     llvm::ArrayRef<DIERef> variable_dies, lldb::addr_t func_low_pc) {
3901   // Parse the variable DIEs and insert them to the list.
3902   for (auto &die : variable_dies) {
3903     if (VariableSP var_sp = ParseVariableDIE(sc, GetDIE(die), func_low_pc)) {
3904       variable_list.AddVariableIfUnique(var_sp);
3905     }
3906   }
3907   return variable_dies.size();
3908 }
3909 
3910 /// Collect call site parameters in a DW_TAG_call_site DIE.
3911 static CallSiteParameterArray
3912 CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
3913   CallSiteParameterArray parameters;
3914   for (DWARFDIE child : call_site_die.children()) {
3915     if (child.Tag() != DW_TAG_call_site_parameter &&
3916         child.Tag() != DW_TAG_GNU_call_site_parameter)
3917       continue;
3918 
3919     std::optional<DWARFExpressionList> LocationInCallee;
3920     std::optional<DWARFExpressionList> LocationInCaller;
3921 
3922     DWARFAttributes attributes = child.GetAttributes();
3923 
3924     // Parse the location at index \p attr_index within this call site parameter
3925     // DIE, or return std::nullopt on failure.
3926     auto parse_simple_location =
3927         [&](int attr_index) -> std::optional<DWARFExpressionList> {
3928       DWARFFormValue form_value;
3929       if (!attributes.ExtractFormValueAtIndex(attr_index, form_value))
3930         return {};
3931       if (!DWARFFormValue::IsBlockForm(form_value.Form()))
3932         return {};
3933       auto data = child.GetData();
3934       uint64_t block_offset = form_value.BlockData() - data.GetDataStart();
3935       uint64_t block_length = form_value.Unsigned();
3936       return DWARFExpressionList(
3937           module, DataExtractor(data, block_offset, block_length),
3938           child.GetCU());
3939     };
3940 
3941     for (size_t i = 0; i < attributes.Size(); ++i) {
3942       dw_attr_t attr = attributes.AttributeAtIndex(i);
3943       if (attr == DW_AT_location)
3944         LocationInCallee = parse_simple_location(i);
3945       if (attr == DW_AT_call_value || attr == DW_AT_GNU_call_site_value)
3946         LocationInCaller = parse_simple_location(i);
3947     }
3948 
3949     if (LocationInCallee && LocationInCaller) {
3950       CallSiteParameter param = {*LocationInCallee, *LocationInCaller};
3951       parameters.push_back(param);
3952     }
3953   }
3954   return parameters;
3955 }
3956 
3957 /// Collect call graph edges present in a function DIE.
3958 std::vector<std::unique_ptr<lldb_private::CallEdge>>
3959 SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
3960   // Check if the function has a supported call site-related attribute.
3961   // TODO: In the future it may be worthwhile to support call_all_source_calls.
3962   bool has_call_edges =
3963       function_die.GetAttributeValueAsUnsigned(DW_AT_call_all_calls, 0) ||
3964       function_die.GetAttributeValueAsUnsigned(DW_AT_GNU_all_call_sites, 0);
3965   if (!has_call_edges)
3966     return {};
3967 
3968   Log *log = GetLog(LLDBLog::Step);
3969   LLDB_LOG(log, "CollectCallEdges: Found call site info in {0}",
3970            function_die.GetPubname());
3971 
3972   // Scan the DIE for TAG_call_site entries.
3973   // TODO: A recursive scan of all blocks in the subprogram is needed in order
3974   // to be DWARF5-compliant. This may need to be done lazily to be performant.
3975   // For now, assume that all entries are nested directly under the subprogram
3976   // (this is the kind of DWARF LLVM produces) and parse them eagerly.
3977   std::vector<std::unique_ptr<CallEdge>> call_edges;
3978   for (DWARFDIE child : function_die.children()) {
3979     if (child.Tag() != DW_TAG_call_site && child.Tag() != DW_TAG_GNU_call_site)
3980       continue;
3981 
3982     std::optional<DWARFDIE> call_origin;
3983     std::optional<DWARFExpressionList> call_target;
3984     addr_t return_pc = LLDB_INVALID_ADDRESS;
3985     addr_t call_inst_pc = LLDB_INVALID_ADDRESS;
3986     addr_t low_pc = LLDB_INVALID_ADDRESS;
3987     bool tail_call = false;
3988 
3989     // Second DW_AT_low_pc may come from DW_TAG_subprogram referenced by
3990     // DW_TAG_GNU_call_site's DW_AT_abstract_origin overwriting our 'low_pc'.
3991     // So do not inherit attributes from DW_AT_abstract_origin.
3992     DWARFAttributes attributes = child.GetAttributes(DWARFDIE::Recurse::no);
3993     for (size_t i = 0; i < attributes.Size(); ++i) {
3994       DWARFFormValue form_value;
3995       if (!attributes.ExtractFormValueAtIndex(i, form_value)) {
3996         LLDB_LOG(log, "CollectCallEdges: Could not extract TAG_call_site form");
3997         break;
3998       }
3999 
4000       dw_attr_t attr = attributes.AttributeAtIndex(i);
4001 
4002       if (attr == DW_AT_call_tail_call || attr == DW_AT_GNU_tail_call)
4003         tail_call = form_value.Boolean();
4004 
4005       // Extract DW_AT_call_origin (the call target's DIE).
4006       if (attr == DW_AT_call_origin || attr == DW_AT_abstract_origin) {
4007         call_origin = form_value.Reference();
4008         if (!call_origin->IsValid()) {
4009           LLDB_LOG(log, "CollectCallEdges: Invalid call origin in {0}",
4010                    function_die.GetPubname());
4011           break;
4012         }
4013       }
4014 
4015       if (attr == DW_AT_low_pc)
4016         low_pc = form_value.Address();
4017 
4018       // Extract DW_AT_call_return_pc (the PC the call returns to) if it's
4019       // available. It should only ever be unavailable for tail call edges, in
4020       // which case use LLDB_INVALID_ADDRESS.
4021       if (attr == DW_AT_call_return_pc)
4022         return_pc = form_value.Address();
4023 
4024       // Extract DW_AT_call_pc (the PC at the call/branch instruction). It
4025       // should only ever be unavailable for non-tail calls, in which case use
4026       // LLDB_INVALID_ADDRESS.
4027       if (attr == DW_AT_call_pc)
4028         call_inst_pc = form_value.Address();
4029 
4030       // Extract DW_AT_call_target (the location of the address of the indirect
4031       // call).
4032       if (attr == DW_AT_call_target || attr == DW_AT_GNU_call_site_target) {
4033         if (!DWARFFormValue::IsBlockForm(form_value.Form())) {
4034           LLDB_LOG(log,
4035                    "CollectCallEdges: AT_call_target does not have block form");
4036           break;
4037         }
4038 
4039         auto data = child.GetData();
4040         uint64_t block_offset = form_value.BlockData() - data.GetDataStart();
4041         uint64_t block_length = form_value.Unsigned();
4042         call_target = DWARFExpressionList(
4043             module, DataExtractor(data, block_offset, block_length),
4044             child.GetCU());
4045       }
4046     }
4047     if (!call_origin && !call_target) {
4048       LLDB_LOG(log, "CollectCallEdges: call site without any call target");
4049       continue;
4050     }
4051 
4052     addr_t caller_address;
4053     CallEdge::AddrType caller_address_type;
4054     if (return_pc != LLDB_INVALID_ADDRESS) {
4055       caller_address = return_pc;
4056       caller_address_type = CallEdge::AddrType::AfterCall;
4057     } else if (low_pc != LLDB_INVALID_ADDRESS) {
4058       caller_address = low_pc;
4059       caller_address_type = CallEdge::AddrType::AfterCall;
4060     } else if (call_inst_pc != LLDB_INVALID_ADDRESS) {
4061       caller_address = call_inst_pc;
4062       caller_address_type = CallEdge::AddrType::Call;
4063     } else {
4064       LLDB_LOG(log, "CollectCallEdges: No caller address");
4065       continue;
4066     }
4067     // Adjust any PC forms. It needs to be fixed up if the main executable
4068     // contains a debug map (i.e. pointers to object files), because we need a
4069     // file address relative to the executable's text section.
4070     caller_address = FixupAddress(caller_address);
4071 
4072     // Extract call site parameters.
4073     CallSiteParameterArray parameters =
4074         CollectCallSiteParameters(module, child);
4075 
4076     std::unique_ptr<CallEdge> edge;
4077     if (call_origin) {
4078       LLDB_LOG(log,
4079                "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x}) "
4080                "(call-PC: {2:x})",
4081                call_origin->GetPubname(), return_pc, call_inst_pc);
4082       edge = std::make_unique<DirectCallEdge>(
4083           call_origin->GetMangledName(), caller_address_type, caller_address,
4084           tail_call, std::move(parameters));
4085     } else {
4086       if (log) {
4087         StreamString call_target_desc;
4088         call_target->GetDescription(&call_target_desc, eDescriptionLevelBrief,
4089                                     nullptr);
4090         LLDB_LOG(log, "CollectCallEdges: Found indirect call target: {0}",
4091                  call_target_desc.GetString());
4092       }
4093       edge = std::make_unique<IndirectCallEdge>(
4094           *call_target, caller_address_type, caller_address, tail_call,
4095           std::move(parameters));
4096     }
4097 
4098     if (log && parameters.size()) {
4099       for (const CallSiteParameter &param : parameters) {
4100         StreamString callee_loc_desc, caller_loc_desc;
4101         param.LocationInCallee.GetDescription(&callee_loc_desc,
4102                                               eDescriptionLevelBrief, nullptr);
4103         param.LocationInCaller.GetDescription(&caller_loc_desc,
4104                                               eDescriptionLevelBrief, nullptr);
4105         LLDB_LOG(log, "CollectCallEdges: \tparam: {0} => {1}",
4106                  callee_loc_desc.GetString(), caller_loc_desc.GetString());
4107       }
4108     }
4109 
4110     call_edges.push_back(std::move(edge));
4111   }
4112   return call_edges;
4113 }
4114 
4115 std::vector<std::unique_ptr<lldb_private::CallEdge>>
4116 SymbolFileDWARF::ParseCallEdgesInFunction(lldb_private::UserID func_id) {
4117   // ParseCallEdgesInFunction must be called at the behest of an exclusively
4118   // locked lldb::Function instance. Storage for parsed call edges is owned by
4119   // the lldb::Function instance: locking at the SymbolFile level would be too
4120   // late, because the act of storing results from ParseCallEdgesInFunction
4121   // would be racy.
4122   DWARFDIE func_die = GetDIE(func_id.GetID());
4123   if (func_die.IsValid())
4124     return CollectCallEdges(GetObjectFile()->GetModule(), func_die);
4125   return {};
4126 }
4127 
4128 void SymbolFileDWARF::Dump(lldb_private::Stream &s) {
4129   SymbolFileCommon::Dump(s);
4130   m_index->Dump(s);
4131 }
4132 
4133 void SymbolFileDWARF::DumpClangAST(Stream &s) {
4134   auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
4135   if (!ts_or_err)
4136     return;
4137   auto ts = *ts_or_err;
4138   TypeSystemClang *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
4139   if (!clang)
4140     return;
4141   clang->Dump(s.AsRawOstream());
4142 }
4143 
4144 bool SymbolFileDWARF::GetSeparateDebugInfo(StructuredData::Dictionary &d,
4145                                            bool errors_only) {
4146   StructuredData::Array separate_debug_info_files;
4147   DWARFDebugInfo &info = DebugInfo();
4148   const size_t num_cus = info.GetNumUnits();
4149   for (size_t cu_idx = 0; cu_idx < num_cus; cu_idx++) {
4150     DWARFUnit *unit = info.GetUnitAtIndex(cu_idx);
4151     DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(unit);
4152     if (dwarf_cu == nullptr)
4153       continue;
4154 
4155     // Check if this is a DWO unit by checking if it has a DWO ID.
4156     // NOTE: it seems that `DWARFUnit::IsDWOUnit` is always false?
4157     if (!dwarf_cu->GetDWOId().has_value())
4158       continue;
4159 
4160     StructuredData::DictionarySP dwo_data =
4161         std::make_shared<StructuredData::Dictionary>();
4162     const uint64_t dwo_id = dwarf_cu->GetDWOId().value();
4163     dwo_data->AddIntegerItem("dwo_id", dwo_id);
4164 
4165     if (const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly()) {
4166       const char *dwo_name = GetDWOName(*dwarf_cu, *die.GetDIE());
4167       if (dwo_name) {
4168         dwo_data->AddStringItem("dwo_name", dwo_name);
4169       } else {
4170         dwo_data->AddStringItem("error", "missing dwo name");
4171       }
4172 
4173       const char *comp_dir = die.GetDIE()->GetAttributeValueAsString(
4174           dwarf_cu, DW_AT_comp_dir, nullptr);
4175       if (comp_dir) {
4176         dwo_data->AddStringItem("comp_dir", comp_dir);
4177       }
4178     } else {
4179       dwo_data->AddStringItem(
4180           "error",
4181           llvm::formatv("unable to get unit DIE for DWARFUnit at {0:x}",
4182                         dwarf_cu->GetOffset())
4183               .str());
4184     }
4185 
4186     // If we have a DWO symbol file, that means we were able to successfully
4187     // load it.
4188     SymbolFile *dwo_symfile = dwarf_cu->GetDwoSymbolFile();
4189     if (dwo_symfile) {
4190       dwo_data->AddStringItem(
4191           "resolved_dwo_path",
4192           dwo_symfile->GetObjectFile()->GetFileSpec().GetPath());
4193     } else {
4194       dwo_data->AddStringItem("error",
4195                               dwarf_cu->GetDwoError().AsCString("unknown"));
4196     }
4197     dwo_data->AddBooleanItem("loaded", dwo_symfile != nullptr);
4198     if (!errors_only || dwo_data->HasKey("error"))
4199       separate_debug_info_files.AddItem(dwo_data);
4200   }
4201 
4202   d.AddStringItem("type", "dwo");
4203   d.AddStringItem("symfile", GetMainObjectFile()->GetFileSpec().GetPath());
4204   d.AddItem("separate-debug-info-files",
4205             std::make_shared<StructuredData::Array>(
4206                 std::move(separate_debug_info_files)));
4207   return true;
4208 }
4209 
4210 SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
4211   if (m_debug_map_symfile == nullptr) {
4212     lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
4213     if (module_sp) {
4214       m_debug_map_symfile = llvm::cast<SymbolFileDWARFDebugMap>(
4215           module_sp->GetSymbolFile()->GetBackingSymbolFile());
4216     }
4217   }
4218   return m_debug_map_symfile;
4219 }
4220 
4221 const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
4222   llvm::call_once(m_dwp_symfile_once_flag, [this]() {
4223     // Create a list of files to try and append .dwp to.
4224     FileSpecList symfiles;
4225     // Append the module's object file path.
4226     const FileSpec module_fspec = m_objfile_sp->GetModule()->GetFileSpec();
4227     symfiles.Append(module_fspec);
4228     // Append the object file for this SymbolFile only if it is different from
4229     // the module's file path. Our main module could be "a.out", our symbol file
4230     // could be "a.debug" and our ".dwp" file might be "a.debug.dwp" instead of
4231     // "a.out.dwp".
4232     const FileSpec symfile_fspec(m_objfile_sp->GetFileSpec());
4233     if (symfile_fspec != module_fspec) {
4234       symfiles.Append(symfile_fspec);
4235     } else {
4236       // If we don't have a separate debug info file, then try stripping the
4237       // extension. The main module could be "a.debug" and the .dwp file could
4238       // be "a.dwp" instead of "a.debug.dwp".
4239       ConstString filename_no_ext =
4240           module_fspec.GetFileNameStrippingExtension();
4241       if (filename_no_ext != module_fspec.GetFilename()) {
4242         FileSpec module_spec_no_ext(module_fspec);
4243         module_spec_no_ext.SetFilename(filename_no_ext);
4244         symfiles.Append(module_spec_no_ext);
4245       }
4246     }
4247     Log *log = GetLog(DWARFLog::SplitDwarf);
4248     FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
4249     ModuleSpec module_spec;
4250     module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();
4251     FileSpec dwp_filespec;
4252     for (const auto &symfile : symfiles.files()) {
4253       module_spec.GetSymbolFileSpec() =
4254           FileSpec(symfile.GetPath() + ".dwp", symfile.GetPathStyle());
4255       LLDB_LOG(log, "Searching for DWP using: \"{0}\"",
4256                module_spec.GetSymbolFileSpec());
4257       dwp_filespec =
4258           PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
4259       if (FileSystem::Instance().Exists(dwp_filespec)) {
4260         break;
4261       }
4262     }
4263     if (!FileSystem::Instance().Exists(dwp_filespec)) {
4264       LLDB_LOG(log, "No DWP file found locally");
4265       // Fill in the UUID for the module we're trying to match for, so we can
4266       // find the correct DWP file, as the Debuginfod plugin uses *only* this
4267       // data to correctly match the DWP file with the binary.
4268       module_spec.GetUUID() = m_objfile_sp->GetUUID();
4269       dwp_filespec =
4270           PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
4271     }
4272     if (FileSystem::Instance().Exists(dwp_filespec)) {
4273       LLDB_LOG(log, "Found DWP file: \"{0}\"", dwp_filespec);
4274       DataBufferSP dwp_file_data_sp;
4275       lldb::offset_t dwp_file_data_offset = 0;
4276       ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(
4277           GetObjectFile()->GetModule(), &dwp_filespec, 0,
4278           FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp,
4279           dwp_file_data_offset);
4280       if (dwp_obj_file) {
4281         m_dwp_symfile = std::make_shared<SymbolFileDWARFDwo>(
4282             *this, dwp_obj_file, DIERef::k_file_index_mask);
4283       }
4284     }
4285     if (!m_dwp_symfile) {
4286       LLDB_LOG(log, "Unable to locate for DWP file for: \"{0}\"",
4287                m_objfile_sp->GetModule()->GetFileSpec());
4288     }
4289   });
4290   return m_dwp_symfile;
4291 }
4292 
4293 llvm::Expected<lldb::TypeSystemSP>
4294 SymbolFileDWARF::GetTypeSystem(DWARFUnit &unit) {
4295   return unit.GetSymbolFileDWARF().GetTypeSystemForLanguage(GetLanguage(unit));
4296 }
4297 
4298 DWARFASTParser *SymbolFileDWARF::GetDWARFParser(DWARFUnit &unit) {
4299   auto type_system_or_err = GetTypeSystem(unit);
4300   if (auto err = type_system_or_err.takeError()) {
4301     LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
4302                    "Unable to get DWARFASTParser: {0}");
4303     return nullptr;
4304   }
4305   if (auto ts = *type_system_or_err)
4306     return ts->GetDWARFParser();
4307   return nullptr;
4308 }
4309 
4310 CompilerDecl SymbolFileDWARF::GetDecl(const DWARFDIE &die) {
4311   if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))
4312     return dwarf_ast->GetDeclForUIDFromDWARF(die);
4313   return CompilerDecl();
4314 }
4315 
4316 CompilerDeclContext SymbolFileDWARF::GetDeclContext(const DWARFDIE &die) {
4317   if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))
4318     return dwarf_ast->GetDeclContextForUIDFromDWARF(die);
4319   return CompilerDeclContext();
4320 }
4321 
4322 CompilerDeclContext
4323 SymbolFileDWARF::GetContainingDeclContext(const DWARFDIE &die) {
4324   if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))
4325     return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
4326   return CompilerDeclContext();
4327 }
4328 
4329 LanguageType SymbolFileDWARF::LanguageTypeFromDWARF(uint64_t val) {
4330   // Note: user languages between lo_user and hi_user must be handled
4331   // explicitly here.
4332   switch (val) {
4333   case DW_LANG_Mips_Assembler:
4334     return eLanguageTypeMipsAssembler;
4335   default:
4336     return static_cast<LanguageType>(val);
4337   }
4338 }
4339 
4340 LanguageType SymbolFileDWARF::GetLanguage(DWARFUnit &unit) {
4341   return LanguageTypeFromDWARF(unit.GetDWARFLanguageType());
4342 }
4343 
4344 LanguageType SymbolFileDWARF::GetLanguageFamily(DWARFUnit &unit) {
4345   auto lang = (llvm::dwarf::SourceLanguage)unit.GetDWARFLanguageType();
4346   if (llvm::dwarf::isCPlusPlus(lang))
4347     lang = DW_LANG_C_plus_plus;
4348   return LanguageTypeFromDWARF(lang);
4349 }
4350 
4351 StatsDuration::Duration SymbolFileDWARF::GetDebugInfoIndexTime() {
4352   if (m_index)
4353     return m_index->GetIndexTime();
4354   return {};
4355 }
4356 
4357 void SymbolFileDWARF::ResetStatistics() {
4358   m_parse_time.reset();
4359   if (m_index)
4360     return m_index->ResetStatistics();
4361 }
4362 
4363 Status SymbolFileDWARF::CalculateFrameVariableError(StackFrame &frame) {
4364   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
4365   CompileUnit *cu = frame.GetSymbolContext(eSymbolContextCompUnit).comp_unit;
4366   if (!cu)
4367     return Status();
4368 
4369   DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(cu);
4370   if (!dwarf_cu)
4371     return Status();
4372 
4373   // Check if we have a skeleton compile unit that had issues trying to load
4374   // its .dwo/.dwp file. First pares the Unit DIE to make sure we see any .dwo
4375   // related errors.
4376   dwarf_cu->ExtractUnitDIEIfNeeded();
4377   const Status &dwo_error = dwarf_cu->GetDwoError();
4378   if (dwo_error.Fail())
4379     return dwo_error.Clone();
4380 
4381   // Don't return an error for assembly files as they typically don't have
4382   // varaible information.
4383   if (dwarf_cu->GetDWARFLanguageType() == DW_LANG_Mips_Assembler)
4384     return Status();
4385 
4386   // Check if this compile unit has any variable DIEs. If it doesn't then there
4387   // is not variable information for the entire compile unit.
4388   if (dwarf_cu->HasAny({DW_TAG_variable, DW_TAG_formal_parameter}))
4389     return Status();
4390 
4391   return Status::FromErrorString(
4392       "no variable information is available in debug info for this "
4393       "compile unit");
4394 }
4395 
4396 void SymbolFileDWARF::GetCompileOptions(
4397     std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) {
4398 
4399   const uint32_t num_compile_units = GetNumCompileUnits();
4400 
4401   for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
4402     lldb::CompUnitSP comp_unit = GetCompileUnitAtIndex(cu_idx);
4403     if (!comp_unit)
4404       continue;
4405 
4406     DWARFUnit *dwarf_cu = GetDWARFCompileUnit(comp_unit.get());
4407     if (!dwarf_cu)
4408       continue;
4409 
4410     const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly();
4411     if (!die)
4412       continue;
4413 
4414     const char *flags = die.GetAttributeValueAsString(DW_AT_APPLE_flags, NULL);
4415 
4416     if (!flags)
4417       continue;
4418     args.insert({comp_unit, Args(flags)});
4419   }
4420 }
4421