xref: /freebsd/contrib/llvm-project/lldb/source/Symbol/SymbolFileOnDemand.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- SymbolFileOnDemand.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 "lldb/Symbol/SymbolFileOnDemand.h"
10 
11 #include "lldb/Core/Module.h"
12 #include "lldb/Symbol/SymbolFile.h"
13 
14 #include <memory>
15 #include <optional>
16 
17 using namespace lldb;
18 using namespace lldb_private;
19 
20 char SymbolFileOnDemand::ID;
21 
SymbolFileOnDemand(std::unique_ptr<SymbolFile> && symbol_file)22 SymbolFileOnDemand::SymbolFileOnDemand(
23     std::unique_ptr<SymbolFile> &&symbol_file)
24     : m_sym_file_impl(std::move(symbol_file)) {}
25 
26 SymbolFileOnDemand::~SymbolFileOnDemand() = default;
27 
CalculateAbilities()28 uint32_t SymbolFileOnDemand::CalculateAbilities() {
29   // Explicitly allow ability checking to pass though.
30   // This should be a cheap operation.
31   return m_sym_file_impl->CalculateAbilities();
32 }
33 
GetModuleMutex() const34 std::recursive_mutex &SymbolFileOnDemand::GetModuleMutex() const {
35   return m_sym_file_impl->GetModuleMutex();
36 }
37 
InitializeObject()38 void SymbolFileOnDemand::InitializeObject() {
39   if (!m_debug_info_enabled) {
40     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
41              __FUNCTION__);
42     return;
43   }
44   return m_sym_file_impl->InitializeObject();
45 }
46 
ParseLanguage(CompileUnit & comp_unit)47 lldb::LanguageType SymbolFileOnDemand::ParseLanguage(CompileUnit &comp_unit) {
48   if (!m_debug_info_enabled) {
49     Log *log = GetLog();
50     LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
51     if (log) {
52       lldb::LanguageType langType = m_sym_file_impl->ParseLanguage(comp_unit);
53       if (langType != eLanguageTypeUnknown)
54         LLDB_LOG(log, "Language {0} would return if hydrated.", langType);
55     }
56     return eLanguageTypeUnknown;
57   }
58   return m_sym_file_impl->ParseLanguage(comp_unit);
59 }
60 
ParseXcodeSDK(CompileUnit & comp_unit)61 XcodeSDK SymbolFileOnDemand::ParseXcodeSDK(CompileUnit &comp_unit) {
62   if (!m_debug_info_enabled) {
63     Log *log = GetLog();
64     LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
65     XcodeSDK defaultValue{};
66     if (log) {
67       XcodeSDK sdk = m_sym_file_impl->ParseXcodeSDK(comp_unit);
68       if (!(sdk == defaultValue))
69         LLDB_LOG(log, "SDK {0} would return if hydrated.", sdk.GetString());
70     }
71     return defaultValue;
72   }
73   return m_sym_file_impl->ParseXcodeSDK(comp_unit);
74 }
75 
ParseFunctions(CompileUnit & comp_unit)76 size_t SymbolFileOnDemand::ParseFunctions(CompileUnit &comp_unit) {
77   if (!m_debug_info_enabled) {
78     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
79              __FUNCTION__);
80     return 0;
81   }
82   return m_sym_file_impl->ParseFunctions(comp_unit);
83 }
84 
ParseLineTable(CompileUnit & comp_unit)85 bool SymbolFileOnDemand::ParseLineTable(CompileUnit &comp_unit) {
86   if (!m_debug_info_enabled) {
87     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
88              __FUNCTION__);
89     return false;
90   }
91   return m_sym_file_impl->ParseLineTable(comp_unit);
92 }
93 
ParseDebugMacros(CompileUnit & comp_unit)94 bool SymbolFileOnDemand::ParseDebugMacros(CompileUnit &comp_unit) {
95   if (!m_debug_info_enabled) {
96     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
97              __FUNCTION__);
98     return false;
99   }
100   return m_sym_file_impl->ParseDebugMacros(comp_unit);
101 }
102 
ForEachExternalModule(CompileUnit & comp_unit,llvm::DenseSet<lldb_private::SymbolFile * > & visited_symbol_files,llvm::function_ref<bool (Module &)> lambda)103 bool SymbolFileOnDemand::ForEachExternalModule(
104     CompileUnit &comp_unit,
105     llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,
106     llvm::function_ref<bool(Module &)> lambda) {
107   if (!m_debug_info_enabled) {
108     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
109              __FUNCTION__);
110     // Return false to not early exit.
111     return false;
112   }
113   return m_sym_file_impl->ForEachExternalModule(comp_unit, visited_symbol_files,
114                                                 lambda);
115 }
116 
ParseSupportFiles(CompileUnit & comp_unit,SupportFileList & support_files)117 bool SymbolFileOnDemand::ParseSupportFiles(CompileUnit &comp_unit,
118                                            SupportFileList &support_files) {
119   LLDB_LOG(GetLog(),
120            "[{0}] {1} is not skipped: explicitly allowed to support breakpoint",
121            GetSymbolFileName(), __FUNCTION__);
122   // Explicitly allow this API through to support source line breakpoint.
123   return m_sym_file_impl->ParseSupportFiles(comp_unit, support_files);
124 }
125 
ParseIsOptimized(CompileUnit & comp_unit)126 bool SymbolFileOnDemand::ParseIsOptimized(CompileUnit &comp_unit) {
127   if (!m_debug_info_enabled) {
128     Log *log = GetLog();
129     LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
130     if (log) {
131       bool optimized = m_sym_file_impl->ParseIsOptimized(comp_unit);
132       if (optimized) {
133         LLDB_LOG(log, "Would return optimized if hydrated.");
134       }
135     }
136     return false;
137   }
138   return m_sym_file_impl->ParseIsOptimized(comp_unit);
139 }
140 
ParseTypes(CompileUnit & comp_unit)141 size_t SymbolFileOnDemand::ParseTypes(CompileUnit &comp_unit) {
142   if (!m_debug_info_enabled) {
143     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
144              __FUNCTION__);
145     return 0;
146   }
147   return m_sym_file_impl->ParseTypes(comp_unit);
148 }
149 
ParseImportedModules(const lldb_private::SymbolContext & sc,std::vector<SourceModule> & imported_modules)150 bool SymbolFileOnDemand::ParseImportedModules(
151     const lldb_private::SymbolContext &sc,
152     std::vector<SourceModule> &imported_modules) {
153   if (!m_debug_info_enabled) {
154     Log *log = GetLog();
155     LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
156     if (log) {
157       std::vector<SourceModule> tmp_imported_modules;
158       bool succeed =
159           m_sym_file_impl->ParseImportedModules(sc, tmp_imported_modules);
160       if (succeed)
161         LLDB_LOG(log, "{0} imported modules would be parsed if hydrated.",
162                  tmp_imported_modules.size());
163     }
164     return false;
165   }
166   return m_sym_file_impl->ParseImportedModules(sc, imported_modules);
167 }
168 
ParseBlocksRecursive(Function & func)169 size_t SymbolFileOnDemand::ParseBlocksRecursive(Function &func) {
170   if (!m_debug_info_enabled) {
171     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
172              __FUNCTION__);
173     return 0;
174   }
175   return m_sym_file_impl->ParseBlocksRecursive(func);
176 }
177 
ParseVariablesForContext(const SymbolContext & sc)178 size_t SymbolFileOnDemand::ParseVariablesForContext(const SymbolContext &sc) {
179   if (!m_debug_info_enabled) {
180     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
181              __FUNCTION__);
182     return 0;
183   }
184   return m_sym_file_impl->ParseVariablesForContext(sc);
185 }
186 
ResolveTypeUID(lldb::user_id_t type_uid)187 Type *SymbolFileOnDemand::ResolveTypeUID(lldb::user_id_t type_uid) {
188   if (!m_debug_info_enabled) {
189     Log *log = GetLog();
190     LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
191     if (log) {
192       Type *resolved_type = m_sym_file_impl->ResolveTypeUID(type_uid);
193       if (resolved_type)
194         LLDB_LOG(log, "Type would be parsed for {0} if hydrated.", type_uid);
195     }
196     return nullptr;
197   }
198   return m_sym_file_impl->ResolveTypeUID(type_uid);
199 }
200 
201 std::optional<SymbolFile::ArrayInfo>
GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,const lldb_private::ExecutionContext * exe_ctx)202 SymbolFileOnDemand::GetDynamicArrayInfoForUID(
203     lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
204   if (!m_debug_info_enabled) {
205     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
206              __FUNCTION__);
207     return std::nullopt;
208   }
209   return m_sym_file_impl->GetDynamicArrayInfoForUID(type_uid, exe_ctx);
210 }
211 
CompleteType(CompilerType & compiler_type)212 bool SymbolFileOnDemand::CompleteType(CompilerType &compiler_type) {
213   if (!m_debug_info_enabled) {
214     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
215              __FUNCTION__);
216     return false;
217   }
218   return m_sym_file_impl->CompleteType(compiler_type);
219 }
220 
GetDeclForUID(lldb::user_id_t type_uid)221 CompilerDecl SymbolFileOnDemand::GetDeclForUID(lldb::user_id_t type_uid) {
222   if (!m_debug_info_enabled) {
223     Log *log = GetLog();
224     LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
225     if (log) {
226       CompilerDecl parsed_decl = m_sym_file_impl->GetDeclForUID(type_uid);
227       if (parsed_decl != CompilerDecl()) {
228         LLDB_LOG(log, "CompilerDecl {0} would be parsed for {1} if hydrated.",
229                  parsed_decl.GetName(), type_uid);
230       }
231     }
232     return CompilerDecl();
233   }
234   return m_sym_file_impl->GetDeclForUID(type_uid);
235 }
236 
237 CompilerDeclContext
GetDeclContextForUID(lldb::user_id_t type_uid)238 SymbolFileOnDemand::GetDeclContextForUID(lldb::user_id_t type_uid) {
239   if (!m_debug_info_enabled) {
240     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
241              __FUNCTION__);
242     return CompilerDeclContext();
243   }
244   return m_sym_file_impl->GetDeclContextForUID(type_uid);
245 }
246 
247 CompilerDeclContext
GetDeclContextContainingUID(lldb::user_id_t type_uid)248 SymbolFileOnDemand::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
249   if (!m_debug_info_enabled) {
250     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
251              __FUNCTION__);
252     return CompilerDeclContext();
253   }
254   return m_sym_file_impl->GetDeclContextContainingUID(type_uid);
255 }
256 
ParseDeclsForContext(CompilerDeclContext decl_ctx)257 void SymbolFileOnDemand::ParseDeclsForContext(CompilerDeclContext decl_ctx) {
258   if (!m_debug_info_enabled) {
259     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
260              __FUNCTION__);
261     return;
262   }
263   return m_sym_file_impl->ParseDeclsForContext(decl_ctx);
264 }
265 
266 uint32_t
ResolveSymbolContext(const Address & so_addr,SymbolContextItem resolve_scope,SymbolContext & sc)267 SymbolFileOnDemand::ResolveSymbolContext(const Address &so_addr,
268                                          SymbolContextItem resolve_scope,
269                                          SymbolContext &sc) {
270   if (!m_debug_info_enabled) {
271     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
272              __FUNCTION__);
273     return 0;
274   }
275   return m_sym_file_impl->ResolveSymbolContext(so_addr, resolve_scope, sc);
276 }
277 
CalculateFrameVariableError(StackFrame & frame)278 Status SymbolFileOnDemand::CalculateFrameVariableError(StackFrame &frame) {
279   if (!m_debug_info_enabled) {
280     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
281              __FUNCTION__);
282     return Status();
283   }
284   return m_sym_file_impl->CalculateFrameVariableError(frame);
285 }
286 
ResolveSymbolContext(const SourceLocationSpec & src_location_spec,SymbolContextItem resolve_scope,SymbolContextList & sc_list)287 uint32_t SymbolFileOnDemand::ResolveSymbolContext(
288     const SourceLocationSpec &src_location_spec,
289     SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
290   if (!m_debug_info_enabled) {
291     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
292              __FUNCTION__);
293     return 0;
294   }
295   return m_sym_file_impl->ResolveSymbolContext(src_location_spec, resolve_scope,
296                                                sc_list);
297 }
298 
Dump(lldb_private::Stream & s)299 void SymbolFileOnDemand::Dump(lldb_private::Stream &s) {
300   if (!m_debug_info_enabled) {
301     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
302              __FUNCTION__);
303     return;
304   }
305   return m_sym_file_impl->Dump(s);
306 }
307 
DumpClangAST(lldb_private::Stream & s,llvm::StringRef filter)308 void SymbolFileOnDemand::DumpClangAST(lldb_private::Stream &s,
309                                       llvm::StringRef filter) {
310   if (!m_debug_info_enabled) {
311     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
312              __FUNCTION__);
313     return;
314   }
315   return m_sym_file_impl->DumpClangAST(s, filter);
316 }
317 
FindGlobalVariables(const RegularExpression & regex,uint32_t max_matches,VariableList & variables)318 void SymbolFileOnDemand::FindGlobalVariables(const RegularExpression &regex,
319                                              uint32_t max_matches,
320                                              VariableList &variables) {
321   if (!m_debug_info_enabled) {
322     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
323              __FUNCTION__);
324     return;
325   }
326   return m_sym_file_impl->FindGlobalVariables(regex, max_matches, variables);
327 }
328 
FindGlobalVariables(ConstString name,const CompilerDeclContext & parent_decl_ctx,uint32_t max_matches,VariableList & variables)329 void SymbolFileOnDemand::FindGlobalVariables(
330     ConstString name, const CompilerDeclContext &parent_decl_ctx,
331     uint32_t max_matches, VariableList &variables) {
332   if (!m_debug_info_enabled) {
333     Log *log = GetLog();
334     Symtab *symtab = GetSymtab();
335     if (!symtab) {
336       LLDB_LOG(log, "[{0}] {1} is skipped - fail to get symtab",
337                GetSymbolFileName(), __FUNCTION__);
338       return;
339     }
340     Symbol *sym = symtab->FindFirstSymbolWithNameAndType(
341         name, eSymbolTypeData, Symtab::eDebugAny, Symtab::eVisibilityAny);
342     if (!sym) {
343       LLDB_LOG(log, "[{0}] {1} is skipped - fail to find match in symtab",
344                GetSymbolFileName(), __FUNCTION__);
345       return;
346     }
347     LLDB_LOG(log, "[{0}] {1} is NOT skipped - found match in symtab",
348              GetSymbolFileName(), __FUNCTION__);
349 
350     // Found match in symbol table hydrate debug info and
351     // allow the FindGlobalVariables to go through.
352     SetLoadDebugInfoEnabled();
353   }
354   return m_sym_file_impl->FindGlobalVariables(name, parent_decl_ctx,
355                                               max_matches, variables);
356 }
357 
FindFunctions(const RegularExpression & regex,bool include_inlines,SymbolContextList & sc_list)358 void SymbolFileOnDemand::FindFunctions(const RegularExpression &regex,
359                                        bool include_inlines,
360                                        SymbolContextList &sc_list) {
361   if (!m_debug_info_enabled) {
362     Log *log = GetLog();
363     Symtab *symtab = GetSymtab();
364     if (!symtab) {
365       LLDB_LOG(log, "[{0}] {1} is skipped - fail to get symtab",
366                GetSymbolFileName(), __FUNCTION__);
367       return;
368     }
369     std::vector<uint32_t> symbol_indexes;
370     symtab->AppendSymbolIndexesMatchingRegExAndType(
371         regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny,
372         symbol_indexes);
373     if (symbol_indexes.empty()) {
374       LLDB_LOG(log, "[{0}] {1} is skipped - fail to find match in symtab",
375                GetSymbolFileName(), __FUNCTION__);
376       return;
377     }
378     LLDB_LOG(log, "[{0}] {1} is NOT skipped - found match in symtab",
379              GetSymbolFileName(), __FUNCTION__);
380 
381     // Found match in symbol table hydrate debug info and
382     // allow the FindFucntions to go through.
383     SetLoadDebugInfoEnabled();
384   }
385   return m_sym_file_impl->FindFunctions(regex, include_inlines, sc_list);
386 }
387 
FindFunctions(const Module::LookupInfo & lookup_info,const CompilerDeclContext & parent_decl_ctx,bool include_inlines,SymbolContextList & sc_list)388 void SymbolFileOnDemand::FindFunctions(
389     const Module::LookupInfo &lookup_info,
390     const CompilerDeclContext &parent_decl_ctx, bool include_inlines,
391     SymbolContextList &sc_list) {
392   ConstString name = lookup_info.GetLookupName();
393   FunctionNameType name_type_mask = lookup_info.GetNameTypeMask();
394   if (!m_debug_info_enabled) {
395     Log *log = GetLog();
396 
397     Symtab *symtab = GetSymtab();
398     if (!symtab) {
399       LLDB_LOG(log, "[{0}] {1}({2}) is skipped  - fail to get symtab",
400                GetSymbolFileName(), __FUNCTION__, name);
401       return;
402     }
403 
404     SymbolContextList sc_list_helper;
405     symtab->FindFunctionSymbols(name, name_type_mask, sc_list_helper);
406     if (sc_list_helper.GetSize() == 0) {
407       LLDB_LOG(log, "[{0}] {1}({2}) is skipped - fail to find match in symtab",
408                GetSymbolFileName(), __FUNCTION__, name);
409       return;
410     }
411     LLDB_LOG(log, "[{0}] {1}({2}) is NOT skipped - found match in symtab",
412              GetSymbolFileName(), __FUNCTION__, name);
413 
414     // Found match in symbol table hydrate debug info and
415     // allow the FindFucntions to go through.
416     SetLoadDebugInfoEnabled();
417   }
418   return m_sym_file_impl->FindFunctions(lookup_info, parent_decl_ctx,
419                                         include_inlines, sc_list);
420 }
421 
GetMangledNamesForFunction(const std::string & scope_qualified_name,std::vector<ConstString> & mangled_names)422 void SymbolFileOnDemand::GetMangledNamesForFunction(
423     const std::string &scope_qualified_name,
424     std::vector<ConstString> &mangled_names) {
425   if (!m_debug_info_enabled) {
426     Log *log = GetLog();
427     LLDB_LOG(log, "[{0}] {1}({2}) is skipped", GetSymbolFileName(),
428              __FUNCTION__, scope_qualified_name);
429     return;
430   }
431   return m_sym_file_impl->GetMangledNamesForFunction(scope_qualified_name,
432                                                      mangled_names);
433 }
434 
FindTypes(const TypeQuery & match,TypeResults & results)435 void SymbolFileOnDemand::FindTypes(const TypeQuery &match,
436                                    TypeResults &results) {
437   if (!m_debug_info_enabled) {
438     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
439              __FUNCTION__);
440     return;
441   }
442   return m_sym_file_impl->FindTypes(match, results);
443 }
444 
GetTypes(SymbolContextScope * sc_scope,TypeClass type_mask,TypeList & type_list)445 void SymbolFileOnDemand::GetTypes(SymbolContextScope *sc_scope,
446                                   TypeClass type_mask, TypeList &type_list) {
447   if (!m_debug_info_enabled) {
448     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
449              __FUNCTION__);
450     return;
451   }
452   return m_sym_file_impl->GetTypes(sc_scope, type_mask, type_list);
453 }
454 
455 llvm::Expected<lldb::TypeSystemSP>
GetTypeSystemForLanguage(LanguageType language)456 SymbolFileOnDemand::GetTypeSystemForLanguage(LanguageType language) {
457   if (!m_debug_info_enabled) {
458     Log *log = GetLog();
459     LLDB_LOG(log, "[{0}] {1} is skipped for language type {2}",
460              GetSymbolFileName(), __FUNCTION__, language);
461     return llvm::createStringError(
462         "GetTypeSystemForLanguage is skipped by SymbolFileOnDemand");
463   }
464   return m_sym_file_impl->GetTypeSystemForLanguage(language);
465 }
466 
467 CompilerDeclContext
FindNamespace(ConstString name,const CompilerDeclContext & parent_decl_ctx,bool only_root_namespaces)468 SymbolFileOnDemand::FindNamespace(ConstString name,
469                                   const CompilerDeclContext &parent_decl_ctx,
470                                   bool only_root_namespaces) {
471   if (!m_debug_info_enabled) {
472     LLDB_LOG(GetLog(), "[{0}] {1}({2}) is skipped", GetSymbolFileName(),
473              __FUNCTION__, name);
474     return SymbolFile::FindNamespace(name, parent_decl_ctx,
475                                      only_root_namespaces);
476   }
477   return m_sym_file_impl->FindNamespace(name, parent_decl_ctx,
478                                         only_root_namespaces);
479 }
480 
481 std::vector<std::unique_ptr<lldb_private::CallEdge>>
ParseCallEdgesInFunction(UserID func_id)482 SymbolFileOnDemand::ParseCallEdgesInFunction(UserID func_id) {
483   if (!m_debug_info_enabled) {
484     Log *log = GetLog();
485     LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
486     if (log) {
487       std::vector<std::unique_ptr<lldb_private::CallEdge>> call_edges =
488           m_sym_file_impl->ParseCallEdgesInFunction(func_id);
489       if (call_edges.size() > 0) {
490         LLDB_LOG(log, "{0} call edges would be parsed for {1} if hydrated.",
491                  call_edges.size(), func_id.GetID());
492       }
493     }
494     return {};
495   }
496   return m_sym_file_impl->ParseCallEdgesInFunction(func_id);
497 }
498 
499 lldb::UnwindPlanSP
GetUnwindPlan(const Address & address,const RegisterInfoResolver & resolver)500 SymbolFileOnDemand::GetUnwindPlan(const Address &address,
501                                   const RegisterInfoResolver &resolver) {
502   if (!m_debug_info_enabled) {
503     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
504              __FUNCTION__);
505     return nullptr;
506   }
507   return m_sym_file_impl->GetUnwindPlan(address, resolver);
508 }
509 
510 llvm::Expected<lldb::addr_t>
GetParameterStackSize(Symbol & symbol)511 SymbolFileOnDemand::GetParameterStackSize(Symbol &symbol) {
512   if (!m_debug_info_enabled) {
513     Log *log = GetLog();
514     LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
515     if (log) {
516       llvm::Expected<lldb::addr_t> stack_size =
517           m_sym_file_impl->GetParameterStackSize(symbol);
518       if (stack_size) {
519         LLDB_LOG(log, "{0} stack size would return for symbol {1} if hydrated.",
520                  *stack_size, symbol.GetName());
521       }
522     }
523     return SymbolFile::GetParameterStackSize(symbol);
524   }
525   return m_sym_file_impl->GetParameterStackSize(symbol);
526 }
527 
PreloadSymbols()528 void SymbolFileOnDemand::PreloadSymbols() {
529   m_preload_symbols = true;
530   if (!m_debug_info_enabled) {
531     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
532              __FUNCTION__);
533     return;
534   }
535   return m_sym_file_impl->PreloadSymbols();
536 }
537 
GetDebugInfoSize(bool load_all_debug_info)538 uint64_t SymbolFileOnDemand::GetDebugInfoSize(bool load_all_debug_info) {
539   // Always return the real debug info size.
540   LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
541            __FUNCTION__);
542   return m_sym_file_impl->GetDebugInfoSize(load_all_debug_info);
543 }
544 
GetDebugInfoParseTime()545 StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoParseTime() {
546   // Always return the real parse time.
547   LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
548            __FUNCTION__);
549   return m_sym_file_impl->GetDebugInfoParseTime();
550 }
551 
GetDebugInfoIndexTime()552 StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoIndexTime() {
553   // Always return the real index time.
554   LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
555            __FUNCTION__);
556   return m_sym_file_impl->GetDebugInfoIndexTime();
557 }
558 
ResetStatistics()559 void SymbolFileOnDemand::ResetStatistics() {
560   LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
561            __FUNCTION__);
562   return m_sym_file_impl->ResetStatistics();
563 }
564 
SetLoadDebugInfoEnabled()565 void SymbolFileOnDemand::SetLoadDebugInfoEnabled() {
566   if (m_debug_info_enabled)
567     return;
568   LLDB_LOG(GetLog(), "[{0}] Hydrate debug info", GetSymbolFileName());
569   m_debug_info_enabled = true;
570   InitializeObject();
571   if (m_preload_symbols)
572     PreloadSymbols();
573 }
574 
GetNumCompileUnits()575 uint32_t SymbolFileOnDemand::GetNumCompileUnits() {
576   LLDB_LOG(GetLog(), "[{0}] {1} is not skipped to support breakpoint hydration",
577            GetSymbolFileName(), __FUNCTION__);
578   return m_sym_file_impl->GetNumCompileUnits();
579 }
580 
GetCompileUnitAtIndex(uint32_t idx)581 CompUnitSP SymbolFileOnDemand::GetCompileUnitAtIndex(uint32_t idx) {
582   LLDB_LOG(GetLog(), "[{0}] {1} is not skipped to support breakpoint hydration",
583            GetSymbolFileName(), __FUNCTION__);
584   return m_sym_file_impl->GetCompileUnitAtIndex(idx);
585 }
586 
GetAbilities()587 uint32_t SymbolFileOnDemand::GetAbilities() {
588   if (!m_debug_info_enabled) {
589     LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
590              __FUNCTION__);
591     return 0;
592   }
593   return m_sym_file_impl->GetAbilities();
594 }
595