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