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, 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(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 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(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(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 ®ex, 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, eSymbolTypeData, Symtab::eDebugAny, 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 ®ex, 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, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny, 371 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_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(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 "GetTypeSystemForLanguage is skipped by SymbolFileOnDemand", 462 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