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
17using namespace lldb;
18using namespace lldb_private;
19
20char SymbolFileOnDemand::ID;
21
22SymbolFileOnDemand::SymbolFileOnDemand(
23 std::unique_ptr<SymbolFile> &&symbol_file)
24 : m_sym_file_impl(std::move(symbol_file)) {}
25
26SymbolFileOnDemand::~SymbolFileOnDemand() = default;
27
28uint32_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
34std::recursive_mutex &SymbolFileOnDemand::GetModuleMutex() const {
35 return m_sym_file_impl->GetModuleMutex();
36}
37
38void 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
47lldb::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
61XcodeSDK 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
76size_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
85bool 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
94bool 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
103bool 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
117bool 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
126bool 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
141size_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
150bool 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, imported_modules&: 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
169size_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
178size_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
187Type *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
201std::optional<SymbolFile::ArrayInfo>
202SymbolFileOnDemand::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
212bool 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
221CompilerDecl 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(uid: 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(uid: type_uid);
235}
236
237CompilerDeclContext
238SymbolFileOnDemand::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(uid: type_uid);
245}
246
247CompilerDeclContext
248SymbolFileOnDemand::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(uid: type_uid);
255}
256
257void 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
266uint32_t
267SymbolFileOnDemand::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
278Status 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
287uint32_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
299void 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
308void SymbolFileOnDemand::DumpClangAST(lldb_private::Stream &s) {
309 if (!m_debug_info_enabled) {
310 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
311 __FUNCTION__);
312 return;
313 }
314 return m_sym_file_impl->DumpClangAST(s);
315}
316
317void SymbolFileOnDemand::FindGlobalVariables(const RegularExpression &regex,
318 uint32_t max_matches,
319 VariableList &variables) {
320 if (!m_debug_info_enabled) {
321 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
322 __FUNCTION__);
323 return;
324 }
325 return m_sym_file_impl->FindGlobalVariables(regex, max_matches, variables);
326}
327
328void SymbolFileOnDemand::FindGlobalVariables(
329 ConstString name, const CompilerDeclContext &parent_decl_ctx,
330 uint32_t max_matches, VariableList &variables) {
331 if (!m_debug_info_enabled) {
332 Log *log = GetLog();
333 Symtab *symtab = GetSymtab();
334 if (!symtab) {
335 LLDB_LOG(log, "[{0}] {1} is skipped - fail to get symtab",
336 GetSymbolFileName(), __FUNCTION__);
337 return;
338 }
339 Symbol *sym = symtab->FindFirstSymbolWithNameAndType(
340 name, symbol_type: eSymbolTypeData, symbol_debug_type: Symtab::eDebugAny, symbol_visibility: Symtab::eVisibilityAny);
341 if (!sym) {
342 LLDB_LOG(log, "[{0}] {1} is skipped - fail to find match in symtab",
343 GetSymbolFileName(), __FUNCTION__);
344 return;
345 }
346 LLDB_LOG(log, "[{0}] {1} is NOT skipped - found match in symtab",
347 GetSymbolFileName(), __FUNCTION__);
348
349 // Found match in symbol table hydrate debug info and
350 // allow the FindGlobalVariables to go through.
351 SetLoadDebugInfoEnabled();
352 }
353 return m_sym_file_impl->FindGlobalVariables(name, parent_decl_ctx,
354 max_matches, variables);
355}
356
357void SymbolFileOnDemand::FindFunctions(const RegularExpression &regex,
358 bool include_inlines,
359 SymbolContextList &sc_list) {
360 if (!m_debug_info_enabled) {
361 Log *log = GetLog();
362 Symtab *symtab = GetSymtab();
363 if (!symtab) {
364 LLDB_LOG(log, "[{0}] {1} is skipped - fail to get symtab",
365 GetSymbolFileName(), __FUNCTION__);
366 return;
367 }
368 std::vector<uint32_t> symbol_indexes;
369 symtab->AppendSymbolIndexesMatchingRegExAndType(
370 regex, symbol_type: eSymbolTypeAny, symbol_debug_type: Symtab::eDebugAny, symbol_visibility: Symtab::eVisibilityAny,
371 indexes&: symbol_indexes);
372 if (symbol_indexes.empty()) {
373 LLDB_LOG(log, "[{0}] {1} is skipped - fail to find match in symtab",
374 GetSymbolFileName(), __FUNCTION__);
375 return;
376 }
377 LLDB_LOG(log, "[{0}] {1} is NOT skipped - found match in symtab",
378 GetSymbolFileName(), __FUNCTION__);
379
380 // Found match in symbol table hydrate debug info and
381 // allow the FindFucntions to go through.
382 SetLoadDebugInfoEnabled();
383 }
384 return m_sym_file_impl->FindFunctions(regex, include_inlines, sc_list);
385}
386
387void SymbolFileOnDemand::FindFunctions(
388 const Module::LookupInfo &lookup_info,
389 const CompilerDeclContext &parent_decl_ctx, bool include_inlines,
390 SymbolContextList &sc_list) {
391 ConstString name = lookup_info.GetLookupName();
392 FunctionNameType name_type_mask = lookup_info.GetNameTypeMask();
393 if (!m_debug_info_enabled) {
394 Log *log = GetLog();
395
396 Symtab *symtab = GetSymtab();
397 if (!symtab) {
398 LLDB_LOG(log, "[{0}] {1}({2}) is skipped - fail to get symtab",
399 GetSymbolFileName(), __FUNCTION__, name);
400 return;
401 }
402
403 SymbolContextList sc_list_helper;
404 symtab->FindFunctionSymbols(name, name_type_mask, sc_list&: sc_list_helper);
405 if (sc_list_helper.GetSize() == 0) {
406 LLDB_LOG(log, "[{0}] {1}({2}) is skipped - fail to find match in symtab",
407 GetSymbolFileName(), __FUNCTION__, name);
408 return;
409 }
410 LLDB_LOG(log, "[{0}] {1}({2}) is NOT skipped - found match in symtab",
411 GetSymbolFileName(), __FUNCTION__, name);
412
413 // Found match in symbol table hydrate debug info and
414 // allow the FindFucntions to go through.
415 SetLoadDebugInfoEnabled();
416 }
417 return m_sym_file_impl->FindFunctions(lookup_info, parent_decl_ctx,
418 include_inlines, sc_list);
419}
420
421void SymbolFileOnDemand::GetMangledNamesForFunction(
422 const std::string &scope_qualified_name,
423 std::vector<ConstString> &mangled_names) {
424 if (!m_debug_info_enabled) {
425 Log *log = GetLog();
426 LLDB_LOG(log, "[{0}] {1}({2}) is skipped", GetSymbolFileName(),
427 __FUNCTION__, scope_qualified_name);
428 return;
429 }
430 return m_sym_file_impl->GetMangledNamesForFunction(scope_qualified_name,
431 mangled_names);
432}
433
434void SymbolFileOnDemand::FindTypes(const TypeQuery &match,
435 TypeResults &results) {
436 if (!m_debug_info_enabled) {
437 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
438 __FUNCTION__);
439 return;
440 }
441 return m_sym_file_impl->FindTypes(query: match, results);
442}
443
444void SymbolFileOnDemand::GetTypes(SymbolContextScope *sc_scope,
445 TypeClass type_mask, TypeList &type_list) {
446 if (!m_debug_info_enabled) {
447 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
448 __FUNCTION__);
449 return;
450 }
451 return m_sym_file_impl->GetTypes(sc_scope, type_mask, type_list);
452}
453
454llvm::Expected<lldb::TypeSystemSP>
455SymbolFileOnDemand::GetTypeSystemForLanguage(LanguageType language) {
456 if (!m_debug_info_enabled) {
457 Log *log = GetLog();
458 LLDB_LOG(log, "[{0}] {1} is skipped for language type {2}",
459 GetSymbolFileName(), __FUNCTION__, language);
460 return llvm::make_error<llvm::StringError>(
461 Args: "GetTypeSystemForLanguage is skipped by SymbolFileOnDemand",
462 Args: llvm::inconvertibleErrorCode());
463 }
464 return m_sym_file_impl->GetTypeSystemForLanguage(language);
465}
466
467CompilerDeclContext
468SymbolFileOnDemand::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
481std::vector<std::unique_ptr<lldb_private::CallEdge>>
482SymbolFileOnDemand::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
499lldb::UnwindPlanSP
500SymbolFileOnDemand::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
510llvm::Expected<lldb::addr_t>
511SymbolFileOnDemand::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
528void 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
538uint64_t SymbolFileOnDemand::GetDebugInfoSize() {
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();
543}
544
545StatsDuration::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
552StatsDuration::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
559void SymbolFileOnDemand::SetLoadDebugInfoEnabled() {
560 if (m_debug_info_enabled)
561 return;
562 LLDB_LOG(GetLog(), "[{0}] Hydrate debug info", GetSymbolFileName());
563 m_debug_info_enabled = true;
564 InitializeObject();
565 if (m_preload_symbols)
566 PreloadSymbols();
567}
568
569uint32_t SymbolFileOnDemand::GetNumCompileUnits() {
570 LLDB_LOG(GetLog(), "[{0}] {1} is not skipped to support breakpoint hydration",
571 GetSymbolFileName(), __FUNCTION__);
572 return m_sym_file_impl->GetNumCompileUnits();
573}
574
575CompUnitSP SymbolFileOnDemand::GetCompileUnitAtIndex(uint32_t idx) {
576 LLDB_LOG(GetLog(), "[{0}] {1} is not skipped to support breakpoint hydration",
577 GetSymbolFileName(), __FUNCTION__);
578 return m_sym_file_impl->GetCompileUnitAtIndex(idx);
579}
580
581uint32_t SymbolFileOnDemand::GetAbilities() {
582 if (!m_debug_info_enabled) {
583 LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
584 __FUNCTION__);
585 return 0;
586 }
587 return m_sym_file_impl->GetAbilities();
588}
589

source code of lldb/source/Symbol/SymbolFileOnDemand.cpp