yinghuitan updated this revision to Diff 415252.
yinghuitan added a comment.

Remove duplicate file and fix wrapping.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D121631/new/

https://reviews.llvm.org/D121631

Files:
  lldb/include/lldb/Core/ModuleList.h
  lldb/include/lldb/Symbol/SymbolFile.h
  lldb/include/lldb/Symbol/SymbolFileOnDemand.h
  lldb/include/lldb/Target/Statistics.h
  lldb/include/lldb/Utility/LLDBLog.h
  lldb/packages/Python/lldbsuite/test/builders/builder.py
  lldb/packages/Python/lldbsuite/test/lldbtest.py
  lldb/packages/Python/lldbsuite/test/test_categories.py
  lldb/source/Core/CoreProperties.td
  lldb/source/Core/Module.cpp
  lldb/source/Core/ModuleList.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
  lldb/source/Symbol/CMakeLists.txt
  lldb/source/Symbol/CompileUnit.cpp
  lldb/source/Symbol/SymbolFile.cpp
  lldb/source/Symbol/SymbolFileOnDemand.cpp
  lldb/source/Target/Statistics.cpp
  lldb/source/Utility/LLDBLog.cpp
  lldb/test/API/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py
  lldb/test/API/functionalities/find-line-entry/TestFindLineEntry.py
  lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py
  lldb/test/API/functionalities/show_location/TestShowLocationDwarf5.py
  lldb/test/API/functionalities/type_get_module/TestTypeGetModule.py
  lldb/test/API/lang/c/enum_types/TestEnumTypes.py
  lldb/test/API/lang/c/global_variables/TestGlobalVariables.py
  lldb/test/API/lang/c/shared_lib/TestSharedLib.py
  
lldb/test/API/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py
  lldb/test/API/lang/c/sizeof/TestCSizeof.py
  lldb/test/API/lang/c/unicode/TestUnicodeSymbols.py
  lldb/test/API/lang/cpp/breakpoint-commands/TestCPPBreakpointCommands.py
  lldb/test/API/lang/cpp/enum_types/TestCPP11EnumTypes.py
  lldb/test/API/lang/cpp/namespace_definitions/TestNamespaceDefinitions.py
  lldb/test/API/lang/cpp/sizeof/TestCPPSizeof.py
  lldb/test/API/lang/cpp/template-function/TestTemplateFunctions.py
  lldb/test/Shell/SymbolFile/OnDemand/Inputs/basic.cpp
  lldb/test/Shell/SymbolFile/OnDemand/Inputs/lib.cpp
  lldb/test/Shell/SymbolFile/OnDemand/Inputs/lib.h
  lldb/test/Shell/SymbolFile/OnDemand/Inputs/shared.cpp
  lldb/test/Shell/SymbolFile/OnDemand/shared-lib-globals.test
  lldb/test/Shell/SymbolFile/OnDemand/shared-lib.test
  lldb/test/Shell/SymbolFile/OnDemand/source-breakpoint.test
  lldb/test/Shell/SymbolFile/OnDemand/symbolic-breakpoint.test

Index: lldb/test/Shell/SymbolFile/OnDemand/symbolic-breakpoint.test
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/OnDemand/symbolic-breakpoint.test
@@ -0,0 +1,24 @@
+
+# Test shows that symbolic function breakpoint works with LLDB on demand symbol loading.
+
+# RUN: mkdir -p %t
+# RUN: cd %t
+# RUN: %build %p/Inputs/basic.cpp -o basic.out
+# RUN: %lldb -b -O "settings set symbols.load-on-demand true" -s %s basic.out | FileCheck %s
+
+breakpoint list
+# CHECK: No breakpoints currently set
+
+b bar
+# CHECK: where = {{.*}}`bar(int, int) + {{.*}} at basic.cpp:1
+
+breakpoint list
+# CHECK: where = {{.*}}`bar(int, int) + {{.*}} at basic.cpp:1
+
+run
+# CHECK: stop reason = breakpoint
+
+bt
+# CHECK: {{.*}}`bar(x=33, y=78) at basic.cpp:1
+# CHECK: {{.*}}`foo(x=33, y=78) at basic.cpp:3
+# CHECK: {{.*}}`main(argc=1, argv={{.*}}) at basic.cpp:5
Index: lldb/test/Shell/SymbolFile/OnDemand/source-breakpoint.test
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/OnDemand/source-breakpoint.test
@@ -0,0 +1,23 @@
+# Test shows that source line breakpoint works with LLDB on demand symbol loading.
+
+# RUN: mkdir -p %t
+# RUN: cd %t
+# RUN: %build %p/Inputs/basic.cpp -o basic.out
+# RUN: %lldb -b -O "settings set symbols.load-on-demand true" -s %s basic.out | FileCheck %s
+
+breakpoint list
+# CHECK: No breakpoints currently set
+
+breakpoint set -f basic.cpp -l 1
+# CHECK: where = {{.*}}`bar(int, int) + {{.*}} at basic.cpp:1
+
+breakpoint list
+# CHECK: file = 'basic.cpp'
+
+run
+# CHECK: stop reason = breakpoint
+
+bt
+# CHECK: {{.*}}`bar(x=33, y=78) at basic.cpp:1
+# CHECK: {{.*}}`foo(x=33, y=78) at basic.cpp:3
+# CHECK: {{.*}}`main(argc=1, argv={{.*}}) at basic.cpp:5
Index: lldb/test/Shell/SymbolFile/OnDemand/shared-lib.test
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/OnDemand/shared-lib.test
@@ -0,0 +1,37 @@
+# Test shows that source line breakpoint works in multiple shared libraries with LLDB on demand symbol loading.
+
+# REQUIRES: system-linux
+
+# RUN: mkdir -p %t
+# RUN: cd %t
+# RUN: %clang_host -shared -g -fpic %p/Inputs/lib.cpp -o libFoo.so
+# RUN: %clang_host -L%t -g -o shared.out %p/Inputs/shared.cpp -lFoo -Wl,-rpath=%t
+# RUN: %lldb -b -O "settings set symbols.load-on-demand true" -s %s shared.out | FileCheck %s
+
+breakpoint list
+# CHECK: No breakpoints currently set
+
+breakpoint set -f lib.cpp -l 4
+# CHECK: where = {{.*}}`foo() + {{.*}} at lib.cpp:4
+
+breakpoint list
+# CHECK: file = 'lib.cpp', line = 4
+
+run
+# CHECK: stop reason = breakpoint
+# CHECK: foo() at lib.cpp:4
+
+bt
+# CHECK: {{.*}}`foo() at lib.cpp:4
+# CHECK: at shared.cpp:7
+
+breakpoint set -f shared.cpp -l 8
+# CHECK: at shared.cpp:8
+
+breakpoint list
+# CHECK: file = 'lib.cpp', line = 4
+# CHECK: file = 'shared.cpp', line = 8
+
+continue
+# CHECK: stop reason = breakpoint
+# CHECK: at shared.cpp:8
Index: lldb/test/Shell/SymbolFile/OnDemand/shared-lib-globals.test
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/OnDemand/shared-lib-globals.test
@@ -0,0 +1,29 @@
+# Test shows that global variables works as expected in multiple shared libraries with LLDB on demand symbol loading.
+# The global varialbes in non-hydrated shared library libFoo.so can't be found.
+
+# REQUIRES: system-linux
+
+# RUN: mkdir -p %t
+# RUN: cd %t
+# RUN: %clang_host -shared -g -fpic %p/Inputs/lib.cpp -o libFoo.so
+# RUN: %clang_host -L%t -g -o shared.out %p/Inputs/shared.cpp -lFoo -Wl,-rpath=%t
+# RUN: %lldb -b -O "settings set symbols.load-on-demand true" -s %s shared.out | FileCheck %s
+
+breakpoint list
+# CHECK: No breakpoints currently set
+
+breakpoint set -f shared.cpp -l 8
+# CHECK: at shared.cpp:8
+
+breakpoint list
+# CHECK: file = 'shared.cpp', line = 8
+
+run
+# CHECK: stop reason = breakpoint
+# CHECK: at shared.cpp:8
+
+target variable --shlib shared.out
+# CHECK: (int) ::global_shared = 897
+
+target variable --shlib libFoo.so
+# CHECK-NOT: global_foo
Index: lldb/test/Shell/SymbolFile/OnDemand/Inputs/shared.cpp
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/OnDemand/Inputs/shared.cpp
@@ -0,0 +1,9 @@
+#include "lib.h"
+#include <stdio.h>
+
+int global_shared = 897;
+int main(void) {
+  puts("This is a shared library test...");
+  foo();
+  return 0;
+}
Index: lldb/test/Shell/SymbolFile/OnDemand/Inputs/lib.h
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/OnDemand/Inputs/lib.h
@@ -0,0 +1,6 @@
+#ifndef foo_h__
+#define foo_h__
+
+extern void foo(void);
+
+#endif // foo_h__
Index: lldb/test/Shell/SymbolFile/OnDemand/Inputs/lib.cpp
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/OnDemand/Inputs/lib.cpp
@@ -0,0 +1,4 @@
+#include <stdio.h>
+
+int global_foo = 321;
+void foo(void) { puts("Hello, I am a shared library"); }
Index: lldb/test/Shell/SymbolFile/OnDemand/Inputs/basic.cpp
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/OnDemand/Inputs/basic.cpp
@@ -0,0 +1,5 @@
+int bar(int x, int y) { return x + y + 5; }
+
+int foo(int x, int y) { return bar(x, y) + 12; }
+
+int main(int argc, char **argv) { return foo(33, 78); }
Index: lldb/test/API/lang/cpp/template-function/TestTemplateFunctions.py
===================================================================
--- lldb/test/API/lang/cpp/template-function/TestTemplateFunctions.py
+++ lldb/test/API/lang/cpp/template-function/TestTemplateFunctions.py
@@ -53,6 +53,6 @@
         self.do_test_template_function(True)
 
     @skipIfWindows
-    @expectedFailureAll(debug_info=["dwarf", "gmodules", "dwo"])
+    @expectedFailureAll(debug_info=["dwarf", "gmodules", "dwo", "ondemand"])
     def test_template_function_without_cast(self):
         self.do_test_template_function(False)
Index: lldb/test/API/lang/cpp/sizeof/TestCPPSizeof.py
===================================================================
--- lldb/test/API/lang/cpp/sizeof/TestCPPSizeof.py
+++ lldb/test/API/lang/cpp/sizeof/TestCPPSizeof.py
@@ -7,6 +7,10 @@
 
     mydir = TestBase.compute_mydir(__file__)
 
+    @skipIf(
+        debug_info="ondemand",
+        bugnumber="Type is not parsed in on-demand mode",
+    )
     def test(self):
         self.build()
         self.createTestTarget()
Index: lldb/test/API/lang/cpp/namespace_definitions/TestNamespaceDefinitions.py
===================================================================
--- lldb/test/API/lang/cpp/namespace_definitions/TestNamespaceDefinitions.py
+++ lldb/test/API/lang/cpp/namespace_definitions/TestNamespaceDefinitions.py
@@ -13,6 +13,10 @@
 
     mydir = TestBase.compute_mydir(__file__)
 
+    @skipIf(
+        debug_info="ondemand",
+        bugnumber="Type in shared library is not parsed in on-demand mode",
+    )
     # See also llvm.org/pr28948
     @expectedFailureAll(
         bugnumber="llvm.org/pr50814",
Index: lldb/test/API/lang/cpp/enum_types/TestCPP11EnumTypes.py
===================================================================
--- lldb/test/API/lang/cpp/enum_types/TestCPP11EnumTypes.py
+++ lldb/test/API/lang/cpp/enum_types/TestCPP11EnumTypes.py
@@ -37,6 +37,10 @@
             self.expect_expr("var_below_" + suffix, result_type=enum_name, result_value="-3")
             self.expect_expr("var_above_" + suffix, result_type=enum_name, result_value="1")
 
+    @skipIf(
+        debug_info="ondemand",
+        bugnumber="Type lookup is expected to fail in on-demand mode",
+    )
     @skipIf(dwarf_version=['<', '4'])
     def test(self):
         self.build()
Index: lldb/test/API/lang/cpp/breakpoint-commands/TestCPPBreakpointCommands.py
===================================================================
--- lldb/test/API/lang/cpp/breakpoint-commands/TestCPPBreakpointCommands.py
+++ lldb/test/API/lang/cpp/breakpoint-commands/TestCPPBreakpointCommands.py
@@ -28,6 +28,13 @@
              num_locations))
         return bkpt
 
+    @skipIf(
+        debug_info="ondemand",
+        bugnumber="""
+            Function name breakpoint filter by compile unit would disable
+            searching in symbol table.
+            """,
+    )
     def test_cpp_breakpoint_cmds(self):
         """Test a sequence of breakpoint command add, list, and delete."""
         self.build()
Index: lldb/test/API/lang/c/unicode/TestUnicodeSymbols.py
===================================================================
--- lldb/test/API/lang/c/unicode/TestUnicodeSymbols.py
+++ lldb/test/API/lang/c/unicode/TestUnicodeSymbols.py
@@ -9,6 +9,8 @@
 
     mydir = TestBase.compute_mydir(__file__)
 
+    @skipIf(debug_info="ondemand",
+            bugnumber="type info is not loaded by default in on-demand mode")
     @skipIf(compiler="clang", compiler_version=['<', '7.0'])
     def test_union_members(self):
         self.build()
Index: lldb/test/API/lang/c/sizeof/TestCSizeof.py
===================================================================
--- lldb/test/API/lang/c/sizeof/TestCSizeof.py
+++ lldb/test/API/lang/c/sizeof/TestCSizeof.py
@@ -7,6 +7,8 @@
 
     mydir = TestBase.compute_mydir(__file__)
 
+    @skipIf(debug_info="ondemand",
+            bugnumber="type info is not loaded by default in on-demand mode")
     def test(self):
         self.build()
         self.createTestTarget()
Index: lldb/test/API/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py
===================================================================
--- lldb/test/API/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py
+++ lldb/test/API/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py
@@ -13,6 +13,8 @@
 
     mydir = TestBase.compute_mydir(__file__)
 
+    @skipIf(debug_info="ondemand",
+            bugnumber="debug info is expected to not load for shared library")
     @expectedFailureAll(oslist=["windows"])
     def test_expr(self):
         """Test that types work when defined in a shared library and forwa/d-declared in the main executable"""
@@ -32,6 +34,8 @@
                 "(sub_foo)",
                 "other_element = 3"])
 
+    @skipIf(debug_info="ondemand",
+            bugnumber="debug info is expected to not load for shared library")
     @expectedFailureAll(oslist=["windows"])
     @expectedFailure("llvm.org/PR36712")
     def test_frame_variable(self):
Index: lldb/test/API/lang/c/shared_lib/TestSharedLib.py
===================================================================
--- lldb/test/API/lang/c/shared_lib/TestSharedLib.py
+++ lldb/test/API/lang/c/shared_lib/TestSharedLib.py
@@ -34,14 +34,20 @@
             "expression GetMeASubFoo(my_foo_ptr)",
             startstr="(sub_foo *) $")
 
+    @skipIf(debug_info="ondemand",
+            bugnumber="debug info is expected to not load for shared library")
     def test_expr(self):
         """Test that types work when defined in a shared library and forward-declared in the main executable"""
         self.common_test_expr(True)
 
+    @skipIf(debug_info="ondemand",
+            bugnumber="debug info is expected to not load for shared library")
     def test_expr_no_preload(self):
         """Test that types work when defined in a shared library and forward-declared in the main executable, but with preloading disabled"""
         self.common_test_expr(False)
 
+    @skipIf(debug_info="ondemand",
+            bugnumber="debug info is expected to not load for shared library")
     @expectedFailure("llvm.org/PR36712")
     def test_frame_variable(self):
         """Test that types work when defined in a shared library and forward-declared in the main executable"""
Index: lldb/test/API/lang/c/global_variables/TestGlobalVariables.py
===================================================================
--- lldb/test/API/lang/c/global_variables/TestGlobalVariables.py
+++ lldb/test/API/lang/c/global_variables/TestGlobalVariables.py
@@ -117,4 +117,3 @@
             VARIABLES_DISPLAYED_CORRECTLY,
             matching=False,
             substrs=["can't be resolved"])
-
Index: lldb/test/API/lang/c/enum_types/TestEnumTypes.py
===================================================================
--- lldb/test/API/lang/c/enum_types/TestEnumTypes.py
+++ lldb/test/API/lang/c/enum_types/TestEnumTypes.py
@@ -125,7 +125,7 @@
     def check_enum_members(self, members):
         name_matches = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "kNumDays"]
         value_matches = [-3, -2, -1, 0, 1, 2, 3, 4]
-        
+
         # First test that the list of members from the type works
         num_matches = len(name_matches)
         self.assertEqual(len(members), num_matches, "enum_members returns the right number of elements")
@@ -134,7 +134,9 @@
             self.assertTrue(member.IsValid(), "Got a valid member for idx: %d"%(idx))
             self.assertEqual(member.name, name_matches[idx], "Name matches for %d"%(idx))
             self.assertEqual(member.signed, value_matches[idx], "Value matches for %d"%(idx))
-        
+
+    @skipIf(debug_info="ondemand",
+            bugnumber="Can't find type in on-demand mode")
     def test_api(self):
         """Test that the SBTypeEnumMember API's work correctly for enum_test_days"""
         self.build()
@@ -158,4 +160,3 @@
             self.assertTrue(check_member.IsValid(), "Got a valid member for %s."%(name))
             self.assertEqual(name, check_member.name, "Got back the right name")
             self.assertEqual(member.unsigned, check_member.unsigned)
-
Index: lldb/test/API/functionalities/type_get_module/TestTypeGetModule.py
===================================================================
--- lldb/test/API/functionalities/type_get_module/TestTypeGetModule.py
+++ lldb/test/API/functionalities/type_get_module/TestTypeGetModule.py
@@ -61,6 +61,8 @@
         self.assertTrue(result.IsValid())
         return result
 
+    @skipIf(debug_info="ondemand",
+            bugnumber="Can't find type in on-demand mode")
     def test(self):
         self.build()
         target  = lldbutil.run_to_breakpoint_make_target(self)
@@ -72,7 +74,7 @@
         comp_unit = self.find_comp_unit(exe_module, 'compile_unit1.c')
         cu_type = self.find_type(comp_unit.GetTypes(), 'compile_unit1_type')
         self.assertEqual(exe_module, cu_type.GetModule())
-        
+
         comp_unit = self.find_comp_unit(exe_module, 'compile_unit2.c')
         cu_type = self.find_type(comp_unit.GetTypes(), 'compile_unit2_type')
         self.assertEqual(exe_module, cu_type.GetModule())
Index: lldb/test/API/functionalities/show_location/TestShowLocationDwarf5.py
===================================================================
--- lldb/test/API/functionalities/show_location/TestShowLocationDwarf5.py
+++ lldb/test/API/functionalities/show_location/TestShowLocationDwarf5.py
@@ -11,6 +11,8 @@
 
     @skipIf(archs="aarch64", oslist="linux",
             bugnumber="https://bugs.llvm.org/show_bug.cgi?id=44180";)
+    @skipIf(debug_info="ondemand",
+            bugnumber="yaml generated binary does not have symbol table")
     def test_source_map(self):
         # Set the target soure map to map "./" to the current test directory.
         yaml_path = os.path.join(self.getSourceDir(), "a.yaml")
Index: lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py
===================================================================
--- lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py
+++ lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py
@@ -31,6 +31,7 @@
         self._check_type(target, "InheritsFromTwo")
 
     @skipIf(bugnumber="pr46284", debug_info="gmodules")
+    @skipIf(bugnumber="FindFirstType() won't work in on-demand", debug_info="ondemand")
     @skipIfWindows # Clang emits type info even with -flimit-debug-info
     # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call
     # by-value functions.
@@ -70,6 +71,7 @@
         self.expect_expr("shadowed_one.one", result_value="142")
 
     @skipIf(bugnumber="pr46284", debug_info="gmodules")
+    @skipIf(bugnumber="FindFirstType() won't work in on-demand", debug_info="ondemand")
     @skipIfWindows # Clang emits type info even with -flimit-debug-info
     # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call
     # by-value functions.
@@ -113,6 +115,7 @@
         self.expect_expr("get_two().member", result_value="224")
 
     @skipIf(bugnumber="pr46284", debug_info="gmodules")
+    @skipIf(bugnumber="FindFirstType() won't work in on-demand", debug_info="ondemand")
     @skipIfWindows # Clang emits type info even with -flimit-debug-info
     # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call
     # by-value functions.
Index: lldb/test/API/functionalities/find-line-entry/TestFindLineEntry.py
===================================================================
--- lldb/test/API/functionalities/find-line-entry/TestFindLineEntry.py
+++ lldb/test/API/functionalities/find-line-entry/TestFindLineEntry.py
@@ -3,6 +3,7 @@
 """
 
 import lldb
+from lldbsuite.test.decorators import *
 import lldbsuite.test.lldbutil as lldbutil
 from lldbsuite.test.lldbtest import *
 
@@ -10,6 +11,10 @@
 
     mydir = TestBase.compute_mydir(__file__)
 
+    @skipIf(
+        debug_info="ondemand",
+        bugnumber="Line table parsing is disabled in on-demand mode",
+    )
     def test_compile_unit_find_line_entry_index(self):
         """ Test the CompileUnit LineEntryIndex lookup API """
         self.build()
Index: lldb/test/API/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py
===================================================================
--- lldb/test/API/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py
+++ lldb/test/API/functionalities/breakpoint/breakpoint_ids/TestBreakpointIDs.py
@@ -5,6 +5,7 @@
 
 
 import lldb
+from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
 import lldbsuite.test.lldbutil as lldbutil
 
@@ -13,6 +14,10 @@
 
     mydir = TestBase.compute_mydir(__file__)
 
+    @skipIf(
+        debug_info="ondemand",
+        bugnumber="symbolic function for inline function won't work in on-demand mode",
+    )
     def test(self):
         self.build()
 
Index: lldb/source/Utility/LLDBLog.cpp
===================================================================
--- lldb/source/Utility/LLDBLog.cpp
+++ lldb/source/Utility/LLDBLog.cpp
@@ -60,6 +60,9 @@
     {{"types"}, {"log type system related activities"}, LLDBLog::Types},
     {{"unwind"}, {"log stack unwind activities"}, LLDBLog::Unwind},
     {{"watch"}, {"log watchpoint related activities"}, LLDBLog::Watchpoints},
+    {{"on-demand"},
+     {"log symbol on-demand related activities"},
+     LLDBLog::OnDemand},
 };
 
 static Log::Channel g_log_channel(g_categories,
Index: lldb/source/Target/Statistics.cpp
===================================================================
--- lldb/source/Target/Statistics.cpp
+++ lldb/source/Target/Statistics.cpp
@@ -62,6 +62,8 @@
                      debug_info_index_loaded_from_cache);
   module.try_emplace("debugInfoIndexSavedToCache",
                      debug_info_index_saved_to_cache);
+  module.try_emplace("debugInfoEnabled", debug_info_enabled);
+  module.try_emplace("symtab_stripped", symtab_stripped);
   if (!symfile_path.empty())
     module.try_emplace("symbolFilePath", symfile_path);
 
@@ -183,7 +185,9 @@
   std::vector<ModuleStats> modules;
   std::lock_guard<std::recursive_mutex> guard(
       Module::GetAllocationModuleCollectionMutex());
-  const size_t num_modules = Module::GetNumberAllocatedModules();
+  const uint64_t num_modules = Module::GetNumberAllocatedModules();
+  uint32_t num_debug_info_enabled_modules = 0;
+  uint32_t num_stripped_modules = 0;
   for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
     Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
     ModuleStats module_stat;
@@ -227,6 +231,15 @@
       ModuleList symbol_modules = sym_file->GetDebugInfoModules();
       for (const auto &symbol_module: symbol_modules.Modules())
         module_stat.symfile_modules.push_back((intptr_t)symbol_module.get());
+      module_stat.symtab_stripped = module->GetObjectFile()->IsStripped();
+      if (module_stat.symtab_stripped) {
+        ++num_stripped_modules;
+      }
+      module_stat.debug_info_enabled = sym_file->GetLoadDebugInfoEnabled() &&
+                                       module_stat.debug_info_size > 0;
+      if (module_stat.debug_info_enabled) {
+        ++num_debug_info_enabled_modules;
+      }
     }
     symtab_parse_time += module_stat.symtab_parse_time;
     symtab_index_time += module_stat.symtab_index_time;
@@ -254,6 +267,9 @@
       {"totalDebugInfoIndexLoadedFromCache", debug_index_loaded},
       {"totalDebugInfoIndexSavedToCache", debug_index_saved},
       {"totalDebugInfoByteSize", debug_info_size},
+      {"totalModuleCount", num_modules},
+      {"totalDebugInfoEnabledModules", num_debug_info_enabled_modules},
+      {"totalSymbolTableStrippedModules", num_stripped_modules},
   };
   return std::move(global_stats);
 }
Index: lldb/source/Symbol/SymbolFileOnDemand.cpp
===================================================================
--- /dev/null
+++ lldb/source/Symbol/SymbolFileOnDemand.cpp
@@ -0,0 +1,611 @@
+//===-- SymbolFileDWARFDebugMap.cpp ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Symbol/SymbolFileOnDemand.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Symbol/SymbolFile.h"
+
+#include <memory>
+
+using namespace lldb;
+using namespace lldb_private;
+
+char SymbolFileOnDemand::ID;
+
+SymbolFileOnDemand::SymbolFileOnDemand(
+    lldb::ObjectFileSP objfile_sp, std::unique_ptr<SymbolFile> &&symbol_file)
+    : SymbolFile(std::move(objfile_sp)),
+      m_sym_file_impl(std::move(symbol_file)) {}
+
+SymbolFileOnDemand::~SymbolFileOnDemand() {}
+
+uint32_t SymbolFileOnDemand::CalculateAbilities() {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
+    if (log) {
+      uint32_t abilities = m_sym_file_impl->CalculateAbilities();
+      if (abilities != 0) {
+        LLDB_LOG(log, "{0} abilities would return if hydrated.", abilities);
+      }
+    }
+    return 0;
+  }
+  return m_sym_file_impl->CalculateAbilities();
+}
+
+std::recursive_mutex &SymbolFileOnDemand::GetModuleMutex() const {
+  return m_sym_file_impl->GetModuleMutex();
+}
+
+void SymbolFileOnDemand::InitializeObject() {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return;
+  }
+  return m_sym_file_impl->InitializeObject();
+}
+
+lldb::LanguageType SymbolFileOnDemand::ParseLanguage(CompileUnit &comp_unit) {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
+    if (log) {
+      lldb::LanguageType langType = m_sym_file_impl->ParseLanguage(comp_unit);
+      if (langType != eLanguageTypeUnknown) {
+        LLDB_LOG(log, "Language {0} would return if hydrated.",
+                 eLanguageTypeUnknown);
+      }
+    }
+    return eLanguageTypeUnknown;
+  }
+  return m_sym_file_impl->ParseLanguage(comp_unit);
+}
+
+XcodeSDK SymbolFileOnDemand::ParseXcodeSDK(CompileUnit &comp_unit) {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
+    XcodeSDK defaultValue{};
+    if (log) {
+      XcodeSDK sdk = m_sym_file_impl->ParseXcodeSDK(comp_unit);
+      if (!(sdk == defaultValue)) {
+        LLDB_LOG(log, "SDK {0} would return if hydrated.", sdk.GetString());
+      }
+    }
+    return defaultValue;
+  }
+  return m_sym_file_impl->ParseXcodeSDK(comp_unit);
+}
+
+size_t SymbolFileOnDemand::ParseFunctions(CompileUnit &comp_unit) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return 0;
+  }
+  return m_sym_file_impl->ParseFunctions(comp_unit);
+}
+
+bool SymbolFileOnDemand::ParseLineTable(CompileUnit &comp_unit) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return false;
+  }
+  return m_sym_file_impl->ParseLineTable(comp_unit);
+}
+
+bool SymbolFileOnDemand::ParseDebugMacros(CompileUnit &comp_unit) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return false;
+  }
+  return m_sym_file_impl->ParseDebugMacros(comp_unit);
+}
+
+bool SymbolFileOnDemand::ForEachExternalModule(
+    CompileUnit &comp_unit,
+    llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,
+    llvm::function_ref<bool(Module &)> lambda) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    // Not early exit.
+    return false;
+  }
+  return m_sym_file_impl->ForEachExternalModule(comp_unit, visited_symbol_files,
+                                                lambda);
+}
+
+bool SymbolFileOnDemand::ParseSupportFiles(CompileUnit &comp_unit,
+                                           FileSpecList &support_files) {
+  LLDB_LOG(GetLog(),
+           "[{0}] {1} is not skipped: explicitly allowed to support breakpoint",
+           GetSymbolFileName(), __FUNCTION__);
+  // Explicitly allow this API through to support source line breakpoint.
+  return m_sym_file_impl->ParseSupportFiles(comp_unit, support_files);
+}
+
+bool SymbolFileOnDemand::ParseIsOptimized(CompileUnit &comp_unit) {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
+    if (log) {
+      bool optimized = m_sym_file_impl->ParseIsOptimized(comp_unit);
+      if (optimized) {
+        LLDB_LOG(log, "Optimized would return if hydrated.");
+      }
+    }
+    return false;
+  }
+  return m_sym_file_impl->ParseIsOptimized(comp_unit);
+}
+
+size_t SymbolFileOnDemand::ParseTypes(CompileUnit &comp_unit) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return 0;
+  }
+  return m_sym_file_impl->ParseTypes(comp_unit);
+}
+
+bool SymbolFileOnDemand::ParseImportedModules(
+    const lldb_private::SymbolContext &sc,
+    std::vector<SourceModule> &imported_modules) {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
+    if (log) {
+      std::vector<SourceModule> tmp_imported_modules;
+      bool succeed =
+          m_sym_file_impl->ParseImportedModules(sc, tmp_imported_modules);
+      if (succeed) {
+        LLDB_LOG(log, "{0} imported modules would be parsed if hydrated.",
+                 tmp_imported_modules.size());
+      }
+    }
+    return false;
+  }
+  return m_sym_file_impl->ParseImportedModules(sc, imported_modules);
+}
+
+size_t SymbolFileOnDemand::ParseBlocksRecursive(Function &func) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return 0;
+  }
+  return m_sym_file_impl->ParseBlocksRecursive(func);
+}
+
+size_t SymbolFileOnDemand::ParseVariablesForContext(const SymbolContext &sc) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return 0;
+  }
+  return m_sym_file_impl->ParseVariablesForContext(sc);
+}
+
+Type *SymbolFileOnDemand::ResolveTypeUID(lldb::user_id_t type_uid) {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
+    if (log) {
+      Type *resolved_type = m_sym_file_impl->ResolveTypeUID(type_uid);
+      if (resolved_type) {
+        LLDB_LOG(log, "Type would be parsed for {0} if hydrated.", type_uid);
+      }
+    }
+    return nullptr;
+  }
+  return m_sym_file_impl->ResolveTypeUID(type_uid);
+}
+
+llvm::Optional<SymbolFile::ArrayInfo>
+SymbolFileOnDemand::GetDynamicArrayInfoForUID(
+    lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return llvm::None;
+  }
+  return m_sym_file_impl->GetDynamicArrayInfoForUID(type_uid, exe_ctx);
+}
+
+bool SymbolFileOnDemand::CompleteType(CompilerType &compiler_type) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return false;
+  }
+  return m_sym_file_impl->CompleteType(compiler_type);
+}
+
+CompilerDecl SymbolFileOnDemand::GetDeclForUID(lldb::user_id_t type_uid) {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
+    if (log) {
+      CompilerDecl parsed_decl = m_sym_file_impl->GetDeclForUID(type_uid);
+      if (parsed_decl != CompilerDecl()) {
+        LLDB_LOG(log, "CompilerDecl {0} would be parsed for {1} if hydrated.",
+                 parsed_decl.GetName(), type_uid);
+      }
+    }
+    return CompilerDecl();
+  }
+  return m_sym_file_impl->GetDeclForUID(type_uid);
+}
+
+CompilerDeclContext
+SymbolFileOnDemand::GetDeclContextForUID(lldb::user_id_t type_uid) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return CompilerDeclContext();
+  }
+  return m_sym_file_impl->GetDeclContextForUID(type_uid);
+}
+
+CompilerDeclContext
+SymbolFileOnDemand::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return CompilerDeclContext();
+  }
+  return m_sym_file_impl->GetDeclContextContainingUID(type_uid);
+}
+
+void SymbolFileOnDemand::ParseDeclsForContext(CompilerDeclContext decl_ctx) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return;
+  }
+  return m_sym_file_impl->ParseDeclsForContext(decl_ctx);
+}
+
+uint32_t
+SymbolFileOnDemand::ResolveSymbolContext(const Address &so_addr,
+                                         SymbolContextItem resolve_scope,
+                                         SymbolContext &sc) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return 0;
+  }
+  return m_sym_file_impl->ResolveSymbolContext(so_addr, resolve_scope, sc);
+}
+
+uint32_t SymbolFileOnDemand::ResolveSymbolContext(
+    const SourceLocationSpec &src_location_spec,
+    SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return 0;
+  }
+  return m_sym_file_impl->ResolveSymbolContext(src_location_spec, resolve_scope,
+                                               sc_list);
+}
+
+void SymbolFileOnDemand::Dump(lldb_private::Stream &s) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return;
+  }
+  return m_sym_file_impl->Dump(s);
+}
+
+void SymbolFileOnDemand::DumpClangAST(lldb_private::Stream &s) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return;
+  }
+  return m_sym_file_impl->DumpClangAST(s);
+}
+
+void SymbolFileOnDemand::FindGlobalVariables(const RegularExpression &regex,
+                                             uint32_t max_matches,
+                                             VariableList &variables) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return;
+  }
+  return m_sym_file_impl->FindGlobalVariables(regex, max_matches, variables);
+}
+
+void SymbolFileOnDemand::FindGlobalVariables(
+    ConstString name, const CompilerDeclContext &parent_decl_ctx,
+    uint32_t max_matches, VariableList &variables) {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+    Symtab *symtab = GetSymtab();
+    if (!symtab) {
+      LLDB_LOG(log, "[{0}] {1} is skipped - fail to get symtab",
+               GetSymbolFileName(), __FUNCTION__);
+      return;
+    }
+    Symbol *sym = symtab->FindFirstSymbolWithNameAndType(
+        name, eSymbolTypeData, Symtab::eDebugAny, Symtab::eVisibilityAny);
+    if (!sym) {
+      LLDB_LOG(log, "[{0}] {1} is skipped - fail to find match in symtab",
+               GetSymbolFileName(), __FUNCTION__);
+      return;
+    }
+    LLDB_LOG(log, "[{0}] {1} is NOT skipped - found match in symtab",
+             GetSymbolFileName(), __FUNCTION__);
+
+    // Found match in symbol table hydrate debug info and
+    // allow the FindGlobalVariables to go through.
+    SetLoadDebugInfoEnabled();
+  }
+  return m_sym_file_impl->FindGlobalVariables(name, parent_decl_ctx,
+                                              max_matches, variables);
+}
+
+void SymbolFileOnDemand::FindFunctions(const RegularExpression &regex,
+                                       bool include_inlines,
+                                       SymbolContextList &sc_list) {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+    Symtab *symtab = GetSymtab();
+    if (!symtab) {
+      LLDB_LOG(log, "[{0}] {1} is skipped - fail to get symtab",
+               GetSymbolFileName(), __FUNCTION__);
+      return;
+    }
+    std::vector<uint32_t> symbol_indexes;
+    symtab->AppendSymbolIndexesMatchingRegExAndType(
+        regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny,
+        symbol_indexes);
+    if (symbol_indexes.empty()) {
+      LLDB_LOG(log, "[{0}] {1} is skipped - fail to find match in symtab",
+               GetSymbolFileName(), __FUNCTION__);
+      return;
+    }
+    LLDB_LOG(log, "[{0}] {1} is NOT skipped - found match in symtab",
+             GetSymbolFileName(), __FUNCTION__);
+
+    // Found match in symbol table hydrate debug info and
+    // allow the FindFucntions to go through.
+    SetLoadDebugInfoEnabled();
+  }
+  return m_sym_file_impl->FindFunctions(regex, include_inlines, sc_list);
+}
+
+void SymbolFileOnDemand::FindFunctions(
+    ConstString name, const CompilerDeclContext &parent_decl_ctx,
+    FunctionNameType name_type_mask, bool include_inlines,
+    SymbolContextList &sc_list) {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+
+    Symtab *symtab = GetSymtab();
+    if (!symtab) {
+      LLDB_LOG(log, "[{0}] {1}({2}) is skipped  - fail to get symtab",
+               GetSymbolFileName(), __FUNCTION__, name);
+      return;
+    }
+
+    SymbolContextList sc_list_helper;
+    symtab->FindFunctionSymbols(name, name_type_mask, sc_list_helper);
+    if (sc_list_helper.GetSize() == 0) {
+      LLDB_LOG(log, "[{0}] {1}({2}) is skipped - fail to find match in symtab",
+               GetSymbolFileName(), __FUNCTION__, name);
+      return;
+    }
+    LLDB_LOG(log, "[{0}] {1}({2}) is NOT skipped - found match in symtab",
+             GetSymbolFileName(), __FUNCTION__, name);
+
+    // Found match in symbol table hydrate debug info and
+    // allow the FindFucntions to go through.
+    SetLoadDebugInfoEnabled();
+  }
+  return m_sym_file_impl->FindFunctions(name, parent_decl_ctx, name_type_mask,
+                                        include_inlines, sc_list);
+}
+
+void SymbolFileOnDemand::GetMangledNamesForFunction(
+    const std::string &scope_qualified_name,
+    std::vector<ConstString> &mangled_names) {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+    LLDB_LOG(log, "[{0}] {1}({2}) is skipped", GetSymbolFileName(),
+             __FUNCTION__, scope_qualified_name);
+    return;
+  }
+  return m_sym_file_impl->GetMangledNamesForFunction(scope_qualified_name,
+                                                     mangled_names);
+}
+
+void SymbolFileOnDemand::FindTypes(
+    ConstString name, const CompilerDeclContext &parent_decl_ctx,
+    uint32_t max_matches,
+    llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
+    TypeMap &types) {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+    LLDB_LOG(log, "[{0}] {1}({2}) is skipped", GetSymbolFileName(),
+             __FUNCTION__, name);
+    return;
+  }
+  return m_sym_file_impl->FindTypes(name, parent_decl_ctx, max_matches,
+                                    searched_symbol_files, types);
+}
+
+void SymbolFileOnDemand::FindTypes(
+    llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
+    llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return;
+  }
+  return m_sym_file_impl->FindTypes(pattern, languages, searched_symbol_files,
+                                    types);
+}
+
+void SymbolFileOnDemand::GetTypes(SymbolContextScope *sc_scope,
+                                  TypeClass type_mask, TypeList &type_list) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return;
+  }
+  return m_sym_file_impl->GetTypes(sc_scope, type_mask, type_list);
+}
+
+llvm::Expected<TypeSystem &>
+SymbolFileOnDemand::GetTypeSystemForLanguage(LanguageType language) {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+    LLDB_LOG(log, "[{0}] {1} is skipped for language type {2}",
+             GetSymbolFileName(), __FUNCTION__, language);
+    return SymbolFile::GetTypeSystemForLanguage(language);
+  }
+  return m_sym_file_impl->GetTypeSystemForLanguage(language);
+}
+
+CompilerDeclContext
+SymbolFileOnDemand::FindNamespace(ConstString name,
+                                  const CompilerDeclContext &parent_decl_ctx) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1}({2}) is skipped", GetSymbolFileName(),
+             __FUNCTION__, name);
+    return SymbolFile::FindNamespace(name, parent_decl_ctx);
+  }
+  return m_sym_file_impl->FindNamespace(name, parent_decl_ctx);
+}
+
+std::vector<std::unique_ptr<lldb_private::CallEdge>>
+SymbolFileOnDemand::ParseCallEdgesInFunction(UserID func_id) {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
+    if (log) {
+      std::vector<std::unique_ptr<lldb_private::CallEdge>> call_edges =
+          m_sym_file_impl->ParseCallEdgesInFunction(func_id);
+      if (call_edges.size() > 0) {
+        LLDB_LOG(log, "{0} call edges would be parsed for {1} if hydrated.",
+                 call_edges.size(), func_id.GetID());
+      }
+    }
+    return {};
+  }
+  return m_sym_file_impl->ParseCallEdgesInFunction(func_id);
+}
+
+lldb::UnwindPlanSP
+SymbolFileOnDemand::GetUnwindPlan(const Address &address,
+                                  const RegisterInfoResolver &resolver) {
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return nullptr;
+  }
+  return m_sym_file_impl->GetUnwindPlan(address, resolver);
+}
+
+llvm::Expected<lldb::addr_t>
+SymbolFileOnDemand::GetParameterStackSize(Symbol &symbol) {
+  if (!this->m_debug_info_enabled) {
+    Log *log = GetLog();
+    LLDB_LOG(log, "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__);
+    if (log) {
+      llvm::Expected<lldb::addr_t> stack_size =
+          m_sym_file_impl->GetParameterStackSize(symbol);
+      if (stack_size) {
+        LLDB_LOG(log, "{0} stack size would return for symbol {1} if hydrated.",
+                 *stack_size, symbol.GetName());
+      }
+    }
+    return SymbolFile::GetParameterStackSize(symbol);
+  }
+  return m_sym_file_impl->GetParameterStackSize(symbol);
+}
+
+void SymbolFileOnDemand::PreloadSymbols() {
+  m_preload_symbols = true;
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return;
+  }
+  return m_sym_file_impl->PreloadSymbols();
+}
+
+uint64_t SymbolFileOnDemand::GetDebugInfoSize() {
+  // Always return the real debug info size.
+  LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
+           __FUNCTION__);
+  return m_sym_file_impl->GetDebugInfoSize();
+}
+
+StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoParseTime() {
+  // Always return the real parse time.
+  LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
+           __FUNCTION__);
+  return m_sym_file_impl->GetDebugInfoParseTime();
+}
+
+StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoIndexTime() {
+  // Always return the real index time.
+  LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
+           __FUNCTION__);
+  return m_sym_file_impl->GetDebugInfoIndexTime();
+}
+
+uint32_t SymbolFileOnDemand::CalculateNumCompileUnits() {
+  Log *log = GetLog();
+  LLDB_LOG(log, "[{0}] {1} is not skipped to support breakpoint hydration",
+           GetSymbolFileName(), __FUNCTION__);
+  // Explicitly allow this API through.
+  return m_sym_file_impl->CalculateNumCompileUnits();
+}
+
+CompUnitSP SymbolFileOnDemand::ParseCompileUnitAtIndex(uint32_t cu_idx) {
+  LLDB_LOG(
+      GetLog(),
+      "[{0}] {1} for cu_idx {2} is not skipped to support breakpoint hydration",
+      GetSymbolFileName(), __FUNCTION__, cu_idx);
+  // Explicitly allow this API through to support source line breakpoint.
+  return m_sym_file_impl->ParseCompileUnitAtIndex(cu_idx);
+}
+
+TypeList &SymbolFileOnDemand::GetTypeList() {
+  // assert(false && "Should never be called");
+  if (!this->m_debug_info_enabled) {
+    LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
+             __FUNCTION__);
+    return SymbolFile::GetTypeList();
+  }
+  return m_sym_file_impl->GetTypeList();
+}
+
+void SymbolFileOnDemand::SetLoadDebugInfoEnabled() {
+  if (m_debug_info_enabled) {
+    return;
+  }
+  LLDB_LOG(GetLog(), "[{0}] Hydrate debug info", GetSymbolFileName());
+  m_debug_info_enabled = true;
+  InitializeObject();
+  if (m_preload_symbols) {
+    PreloadSymbols();
+  }
+}
Index: lldb/source/Symbol/SymbolFile.cpp
===================================================================
--- lldb/source/Symbol/SymbolFile.cpp
+++ lldb/source/Symbol/SymbolFile.cpp
@@ -12,6 +12,7 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolFileOnDemand.h"
 #include "lldb/Symbol/TypeMap.h"
 #include "lldb/Symbol/TypeSystem.h"
 #include "lldb/Symbol/VariableList.h"
@@ -79,6 +80,15 @@
       }
     }
     if (best_symfile_up) {
+      ObjectFile::Type obj_file_type = objfile_sp->CalculateType();
+      if (ModuleList::GetGlobalModuleListProperties().GetLoadSymbolOnDemand() &&
+          best_symfile_up->GetDebugInfoSize() > 0 &&
+          (obj_file_type == ObjectFile::eTypeExecutable ||
+           obj_file_type == ObjectFile::eTypeSharedLibrary ||
+           obj_file_type == ObjectFile::eTypeDebugInfo)) {
+        best_symfile_up = std::make_unique<SymbolFileOnDemand>(
+            objfile_sp, std::move(best_symfile_up));
+      }
       // Let the winning symbol file parser initialize itself more completely
       // now that it has been chosen
       best_symfile_up->InitializeObject();
Index: lldb/source/Symbol/CompileUnit.cpp
===================================================================
--- lldb/source/Symbol/CompileUnit.cpp
+++ lldb/source/Symbol/CompileUnit.cpp
@@ -287,6 +287,9 @@
   if (num_file_indexes == 0)
     return;
 
+  // Found a matching source file in this compile unit load its debug info.
+  GetModule()->GetSymbolFile()->SetLoadDebugInfoEnabled();
+
   LineTable *line_table = sc.comp_unit->GetLineTable();
 
   if (line_table == nullptr) {
@@ -312,7 +315,7 @@
     line_idx = line_table->FindLineEntryIndexByFileIndex(
         0, file_indexes, src_location_spec, &line_entry);
   }
-  
+
   // If "exact == true", then "found_line" will be the same as "line". If
   // "exact == false", the "found_line" will be the closest line entry
   // with a line number greater than "line" and we will use this for our
Index: lldb/source/Symbol/CMakeLists.txt
===================================================================
--- lldb/source/Symbol/CMakeLists.txt
+++ lldb/source/Symbol/CMakeLists.txt
@@ -27,6 +27,7 @@
   Symbol.cpp
   SymbolContext.cpp
   SymbolFile.cpp
+  SymbolFileOnDemand.cpp
   SymbolVendor.cpp
   Symtab.cpp
   Type.cpp
Index: lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -65,8 +65,8 @@
   llvm::Optional<DIERef> ref = ToDIERef(entry);
   if (!ref)
     return true;
-  SymbolFileDWARF &dwarf =
-      *llvm::cast<SymbolFileDWARF>(m_module.GetSymbolFile());
+  SymbolFileDWARF &dwarf = *llvm::cast<SymbolFileDWARF>(
+      m_module.GetSymbolFile()->GetBackingSymbolFile());
   DWARFDIE die = dwarf.GetDIE(*ref);
   if (!die)
     return true;
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
@@ -68,7 +68,8 @@
     const DWARFIndex &index, llvm::function_ref<bool(DWARFDIE die)> callback,
     llvm::StringRef name)
     : m_index(index),
-      m_dwarf(*llvm::cast<SymbolFileDWARF>(index.m_module.GetSymbolFile())),
+      m_dwarf(*llvm::cast<SymbolFileDWARF>(
+          index.m_module.GetSymbolFile()->GetBackingSymbolFile())),
       m_callback(callback), m_name(name) {}
 
 bool DWARFIndex::DIERefCallbackImpl::operator()(DIERef ref) const {
Index: lldb/source/Core/ModuleList.cpp
===================================================================
--- lldb/source/Core/ModuleList.cpp
+++ lldb/source/Core/ModuleList.cpp
@@ -180,6 +180,12 @@
   return m_symlink_paths;
 }
 
+bool ModuleListProperties::GetLoadSymbolOnDemand() {
+  const uint32_t idx = ePropertyLoadSymbolOnDemand;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0);
+}
+
 ModuleList::ModuleList() : m_modules(), m_modules_mutex() {}
 
 ModuleList::ModuleList(const ModuleList &rhs)
Index: lldb/source/Core/Module.cpp
===================================================================
--- lldb/source/Core/Module.cpp
+++ lldb/source/Core/Module.cpp
@@ -469,6 +469,8 @@
     if (!symfile)
       return resolved_flags;
 
+    symfile->SetLoadDebugInfoEnabled();
+
     // Resolve the compile unit, function, block, line table or line entry if
     // requested.
     if (resolve_scope & eSymbolContextCompUnit ||
Index: lldb/source/Core/CoreProperties.td
===================================================================
--- lldb/source/Core/CoreProperties.td
+++ lldb/source/Core/CoreProperties.td
@@ -33,6 +33,10 @@
     Global,
     DefaultUnsignedValue<7>,
     Desc<"The expiration time in days for a file. When a file hasn't been accessed for the specified amount of days, it is removed from the cache. A value of 0 disables the expiration-based pruning.">;
+  def LoadSymbolOnDemand: Property<"load-on-demand", "Boolean">,
+    Global,
+    DefaultFalse,
+    Desc<"Enable on demand symbol loading in LLDB. LLDB will load debug info on demand for each module based on breakpoint to improve performance.">;
 }
 
 let Definition = "debugger" in {
Index: lldb/packages/Python/lldbsuite/test/test_categories.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/test_categories.py
+++ lldb/packages/Python/lldbsuite/test/test_categories.py
@@ -15,7 +15,7 @@
 
 
 debug_info_categories = [
-    'dwarf', 'dwo', 'dsym', 'gmodules'
+    'dwarf', 'dwo', 'dsym', 'gmodules', 'ondemand'
 ]
 
 all_categories = {
@@ -42,6 +42,7 @@
     'std-module': 'Tests related to importing the std module',
     'stresstest': 'Tests related to stressing lldb limits',
     'watchpoint': 'Watchpoint-related tests',
+    'ondemand': 'Tests that can be run with symbol on-demand loading',
 }
 
 
Index: lldb/packages/Python/lldbsuite/test/lldbtest.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -710,6 +710,11 @@
         """Return absolute path to a file in the test's source directory."""
         return os.path.join(self.getSourceDir(), name)
 
+    def getTestCategories(self):
+        test_method = getattr(self, self._testMethodName)
+        if test_method is not None and hasattr(test_method, "categories"):
+            return test_method.categories
+
     @classmethod
     def setUpCommands(cls):
         commands = [
@@ -1796,6 +1801,10 @@
         for s in self.setUpCommands():
             self.runCmd(s)
 
+        test_categories = self.getTestCategories()
+        if test_categories is not None and 'ondemand' in test_categories:
+            self.runCmd("settings set symbols.load-on-demand true")
+
         if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
             self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
 
Index: lldb/packages/Python/lldbsuite/test/builders/builder.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/builders/builder.py
+++ lldb/packages/Python/lldbsuite/test/builders/builder.py
@@ -129,6 +129,8 @@
             return ["MAKE_DSYM=NO", "MAKE_DWO=YES"]
         if debug_info == "gmodules":
             return ["MAKE_DSYM=NO", "MAKE_GMODULES=YES"]
+        if debug_info == "ondemand":
+            return ["MAKE_DSYM=NO"]
         return None
 
     def getBuildCommand(self, debug_info, architecture=None, compiler=None,
Index: lldb/include/lldb/Utility/LLDBLog.h
===================================================================
--- lldb/include/lldb/Utility/LLDBLog.h
+++ lldb/include/lldb/Utility/LLDBLog.h
@@ -47,6 +47,7 @@
   Types = Log::ChannelFlag<28>,
   Unwind = Log::ChannelFlag<29>,
   Watchpoints = Log::ChannelFlag<30>,
+  OnDemand = Log::ChannelFlag<31>,
   LLVM_MARK_AS_BITMASK_ENUM(Watchpoints),
 };
 
Index: lldb/include/lldb/Target/Statistics.h
===================================================================
--- lldb/include/lldb/Target/Statistics.h
+++ lldb/include/lldb/Target/Statistics.h
@@ -116,6 +116,8 @@
   bool symtab_saved_to_cache = false;
   bool debug_info_index_loaded_from_cache = false;
   bool debug_info_index_saved_to_cache = false;
+  bool debug_info_enabled = true;
+  bool symtab_stripped = false;
 };
 
 struct ConstStringStats {
Index: lldb/include/lldb/Symbol/SymbolFileOnDemand.h
===================================================================
--- /dev/null
+++ lldb/include/lldb/Symbol/SymbolFileOnDemand.h
@@ -0,0 +1,208 @@
+//===-- SymbolFileOnDemand.h ------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SYMBOL_SYMBOLFILEONDEMAND_H
+#define LLDB_SYMBOL_SYMBOLFILEONDEMAND_H
+
+#include <mutex>
+#include <vector>
+
+#include "lldb/Core/UniqueCStringMap.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Target/Statistics.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Flags.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+/// SymbolFileOnDemand wraps a real SymbolFile by providing
+/// on demand symbol parsing/indexing to improve performance.
+/// By default SymbolFileOnDemand will skip load the underlying
+/// symbols. Any client can on demand hydrate the underlying
+/// SymbolFile via SetForceLoad() API.
+class SymbolFileOnDemand : public lldb_private::SymbolFile {
+  /// LLVM RTTI support.
+  static char ID;
+
+public:
+  /// LLVM RTTI support.
+  /// \{
+  bool isA(const void *ClassID) const override {
+    return ClassID == &ID || SymbolFile::isA(ClassID);
+  }
+  static bool classof(const SymbolFile *obj) { return obj->isA(&ID); }
+  /// \}
+
+  SymbolFileOnDemand(lldb::ObjectFileSP objfile_sp,
+                     std::unique_ptr<SymbolFile> &&symbol_file);
+  virtual ~SymbolFileOnDemand() override;
+
+  // PluginInterface protocol
+  llvm::StringRef GetPluginName() override { return "ondemand"; }
+
+  bool GetLoadDebugInfoEnabled() override { return m_debug_info_enabled; }
+
+  void SetLoadDebugInfoEnabled() override;
+
+  SymbolFile *GetBackingSymbolFile() override { return m_sym_file_impl.get(); }
+
+  uint32_t CalculateAbilities() override;
+
+  std::recursive_mutex &GetModuleMutex() const override;
+
+  lldb::LanguageType
+  ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
+
+  lldb_private::XcodeSDK
+  ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override;
+
+  void InitializeObject() override;
+
+  size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
+
+  bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
+
+  bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
+
+  bool ForEachExternalModule(
+      lldb_private::CompileUnit &, llvm::DenseSet<lldb_private::SymbolFile *> &,
+      llvm::function_ref<bool(lldb_private::Module &)>) override;
+
+  bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
+                         lldb_private::FileSpecList &support_files) override;
+
+  bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override;
+
+  size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override;
+
+  bool ParseImportedModules(
+      const lldb_private::SymbolContext &sc,
+      std::vector<lldb_private::SourceModule> &imported_modules) override;
+
+  size_t ParseBlocksRecursive(lldb_private::Function &func) override;
+
+  size_t
+  ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
+
+  lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
+  llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID(
+      lldb::user_id_t type_uid,
+      const lldb_private::ExecutionContext *exe_ctx) override;
+
+  bool CompleteType(lldb_private::CompilerType &compiler_type) override;
+
+  lldb_private::CompilerDecl GetDeclForUID(lldb::user_id_t uid) override;
+
+  lldb_private::CompilerDeclContext
+  GetDeclContextForUID(lldb::user_id_t uid) override;
+
+  lldb_private::CompilerDeclContext
+  GetDeclContextContainingUID(lldb::user_id_t uid) override;
+
+  void
+  ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
+
+  uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
+                                lldb::SymbolContextItem resolve_scope,
+                                lldb_private::SymbolContext &sc) override;
+
+  uint32_t ResolveSymbolContext(
+      const lldb_private::SourceLocationSpec &src_location_spec,
+      lldb::SymbolContextItem resolve_scope,
+      lldb_private::SymbolContextList &sc_list) override;
+
+  void Dump(lldb_private::Stream &s) override;
+  void DumpClangAST(lldb_private::Stream &s) override;
+
+  void
+  FindGlobalVariables(lldb_private::ConstString name,
+                      const lldb_private::CompilerDeclContext &parent_decl_ctx,
+                      uint32_t max_matches,
+                      lldb_private::VariableList &variables) override;
+
+  void FindGlobalVariables(const lldb_private::RegularExpression &regex,
+                           uint32_t max_matches,
+                           lldb_private::VariableList &variables) override;
+
+  void FindFunctions(lldb_private::ConstString name,
+                     const lldb_private::CompilerDeclContext &parent_decl_ctx,
+                     lldb::FunctionNameType name_type_mask,
+                     bool include_inlines,
+                     lldb_private::SymbolContextList &sc_list) override;
+
+  void FindFunctions(const lldb_private::RegularExpression &regex,
+                     bool include_inlines,
+                     lldb_private::SymbolContextList &sc_list) override;
+
+  void GetMangledNamesForFunction(
+      const std::string &scope_qualified_name,
+      std::vector<lldb_private::ConstString> &mangled_names) override;
+
+  void
+  FindTypes(lldb_private::ConstString name,
+            const lldb_private::CompilerDeclContext &parent_decl_ctx,
+            uint32_t max_matches,
+            llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
+            lldb_private::TypeMap &types) override;
+
+  void FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern,
+                 lldb_private::LanguageSet languages,
+                 llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+                 lldb_private::TypeMap &types) override;
+
+  void GetTypes(lldb_private::SymbolContextScope *sc_scope,
+                lldb::TypeClass type_mask,
+                lldb_private::TypeList &type_list) override;
+
+  llvm::Expected<lldb_private::TypeSystem &>
+  GetTypeSystemForLanguage(lldb::LanguageType language) override;
+
+  lldb_private::CompilerDeclContext FindNamespace(
+      lldb_private::ConstString name,
+      const lldb_private::CompilerDeclContext &parent_decl_ctx) override;
+
+  std::vector<std::unique_ptr<lldb_private::CallEdge>>
+  ParseCallEdgesInFunction(UserID func_id) override;
+
+  lldb::UnwindPlanSP
+  GetUnwindPlan(const Address &address,
+                const RegisterInfoResolver &resolver) override;
+
+  llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) override;
+
+  void PreloadSymbols() override;
+
+  uint64_t GetDebugInfoSize() override;
+  lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override;
+  lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override;
+
+private:
+  Log *GetLog() const { return ::lldb_private::GetLog(LLDBLog::OnDemand); }
+
+  ConstString GetSymbolFileName() {
+    return GetObjectFile()->GetFileSpec().GetFilename();
+  }
+
+protected:
+  uint32_t CalculateNumCompileUnits() override;
+  lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+  lldb_private::TypeList &GetTypeList() override;
+
+private:
+  bool m_debug_info_enabled{false};
+  bool m_preload_symbols{false};
+  std::unique_ptr<SymbolFile> m_sym_file_impl;
+};
+} // namespace lldb_private
+
+#endif // LLDB_SYMBOL_SYMBOLFILEONDEMAND_H
Index: lldb/include/lldb/Symbol/SymbolFile.h
===================================================================
--- lldb/include/lldb/Symbol/SymbolFile.h
+++ lldb/include/lldb/Symbol/SymbolFile.h
@@ -40,6 +40,11 @@
   /// LLVM RTTI support.
   static char ID;
 
+public:
+  /// Required to call protected member functions from
+  /// SymbolFileOnDemand via forwarding.
+  friend class SymbolFileOnDemand;
+
 public:
   /// LLVM RTTI support.
   /// \{
@@ -72,6 +77,10 @@
 
   ~SymbolFile() override = default;
 
+  /// SymbolFileOnDemand class overrides this to return the underlying
+  /// backing SymbolFile implementation that loads on-demand.
+  virtual SymbolFile *GetBackingSymbolFile() { return this; }
+
   /// Get a mask of what this symbol file supports for the object file
   /// that it was constructed with.
   ///
@@ -123,6 +132,16 @@
   /// prior to any other functions in the SymbolFile protocol.
   virtual void InitializeObject() {}
 
+  /// Whether debug info will be loaded or not.
+  ///
+  /// It will be true for most implementations except SymbolFileOnDemand.
+  virtual bool GetLoadDebugInfoEnabled() { return true; }
+
+  /// Specify debug info should be loaded.
+  ///
+  /// It will be no-op for most implementations except SymbolFileOnDemand.
+  virtual void SetLoadDebugInfoEnabled() { return; }
+
   // Compile Unit function calls
   // Approach 1 - iterator
   uint32_t GetNumCompileUnits();
@@ -353,9 +372,7 @@
   bool GetDebugInfoIndexWasSavedToCache() const {
     return m_index_was_saved_to_cache;
   }
-  void SetDebugInfoIndexWasSavedToCache() {
-    m_index_was_saved_to_cache = true;
-  }
+  void SetDebugInfoIndexWasSavedToCache() { m_index_was_saved_to_cache = true; }
   /// \}
 
 protected:
Index: lldb/include/lldb/Core/ModuleList.h
===================================================================
--- lldb/include/lldb/Core/ModuleList.h
+++ lldb/include/lldb/Core/ModuleList.h
@@ -68,6 +68,8 @@
   FileSpec GetLLDBIndexCachePath() const;
   bool SetLLDBIndexCachePath(const FileSpec &path);
 
+  bool GetLoadSymbolOnDemand();
+
   PathMappingList GetSymlinkMappings() const;
 };
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to