[Lldb-commits] [lldb] [lldb] Add std::source_location summary provider (PR #203185)

Sergei Druzhkov via lldb-commits lldb-commits at lists.llvm.org
Fri Jun 12 02:44:28 PDT 2026


https://github.com/DrSergei updated https://github.com/llvm/llvm-project/pull/203185

>From b36616c7c2c54803f08aa403b3c2e72aa94acd7d Mon Sep 17 00:00:00 2001
From: Sergei Druzhkov <serzhdruzhok at gmail.com>
Date: Thu, 11 Jun 2026 09:25:33 +0300
Subject: [PATCH 1/4] [lldb] Add std::source_location summary provider

---
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 12 +++++
 .../Plugins/Language/CPlusPlus/LibCxx.cpp     | 35 ++++++++++++
 .../Plugins/Language/CPlusPlus/LibCxx.h       |  4 ++
 .../Plugins/Language/CPlusPlus/LibStdcpp.cpp  | 35 ++++++++++++
 .../Plugins/Language/CPlusPlus/LibStdcpp.h    |  4 ++
 .../generic/source_location/Makefile          |  4 ++
 .../TestDataFormatterStdSourceLocation.py     | 53 +++++++++++++++++++
 .../generic/source_location/main.cpp          | 10 ++++
 8 files changed, 157 insertions(+)
 create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/Makefile
 create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/TestDataFormatterStdSourceLocation.py
 create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/main.cpp

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 74a5a414de67b..1cff63847388b 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1302,6 +1302,12 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
                 "libc++ std::strong_ordering summary provider",
                 "^std::__[[:alnum:]]+::strong_ordering$",
                 eTypeOptionHideChildren | eTypeOptionHideValue, true);
+
+  AddCXXSummary(cpp_category_sp,
+                lldb_private::formatters::LibcxxSourceLocationSummaryProvider,
+                "libc++ std::source_location summary provider",
+                "^std::__[[:alnum:]]+::source_location$", stl_summary_flags,
+                true);
 }
 
 static void RegisterStdStringSummaryProvider(
@@ -1522,6 +1528,12 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
                 lldb_private::formatters::StdlibCoroutineHandleSummaryProvider,
                 "libstdc++ std::coroutine_handle summary provider",
                 libstdcpp_std_coroutine_handle_regex, stl_summary_flags, true);
+
+  AddCXXSummary(
+      cpp_category_sp,
+      lldb_private::formatters::LibStdcppSourceLocationSummaryProvider,
+      "libstdc++ std::source_location summary provider",
+      "^std::source_location$", stl_summary_flags, true);
 }
 
 static lldb_private::SyntheticChildrenFrontEnd *
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 189fee5b8bd22..ca6ba18879aad 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -983,3 +983,38 @@ bool lldb_private::formatters::LibcxxChronoYearMonthDaySummaryProvider(
 
   return true;
 }
+
+bool lldb_private::formatters::LibcxxSourceLocationSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ValueObjectSP ptr_sp = valobj.GetChildMemberWithName("__ptr_");
+  if (!ptr_sp)
+    return false;
+
+  ValueObjectSP file_sp = ptr_sp->GetChildMemberWithName("_M_file_name");
+  ValueObjectSP function_sp =
+      ptr_sp->GetChildMemberWithName("_M_function_name");
+  ValueObjectSP line_sp = ptr_sp->GetChildMemberWithName("_M_line");
+  ValueObjectSP column_sp = ptr_sp->GetChildMemberWithName("_M_column");
+
+  if (!file_sp || !function_sp || !line_sp || !column_sp)
+    return false;
+
+  bool success = false;
+  uint64_t line = line_sp->GetValueAsUnsigned(0, &success);
+  if (!success)
+    return false;
+
+  uint64_t column = column_sp->GetValueAsUnsigned(0, &success);
+  if (!success)
+    return false;
+
+  if (const char *file = file_sp->GetSummaryAsCString())
+    stream.Printf("%s:%lu:%lu", file, line, column);
+  else
+    stream.Printf("Location Unavailable");
+
+  if (const char *function = function_sp->GetSummaryAsCString())
+    stream.Printf(" (%s)", function);
+
+  return true;
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index d9b3f3a694afc..b2cbff8890861 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -103,6 +103,10 @@ bool LibcxxStrongOrderingSummaryProvider(
     ValueObject &valobj, Stream &stream,
     const TypeSummaryOptions &options); // libc++ std::strong_ordering
 
+bool LibcxxSourceLocationSummaryProvider(
+    ValueObject &valobj, Stream &stream,
+    const TypeSummaryOptions &options); // libc++ std::source_location
+
 SyntheticChildrenFrontEnd *
 LibcxxVectorBoolSyntheticFrontEndCreator(CXXSyntheticChildren *,
                                          lldb::ValueObjectSP);
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
index eb7e4300f9214..c933d21be4dc0 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
@@ -577,3 +577,38 @@ bool lldb_private::formatters::LibStdcppStrongOrderingSummaryProvider(
   }
   return true;
 }
+
+bool lldb_private::formatters::LibStdcppSourceLocationSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ValueObjectSP impl_sp = valobj.GetChildMemberWithName("_M_impl");
+  if (!impl_sp)
+    return false;
+
+  ValueObjectSP file_sp = impl_sp->GetChildMemberWithName("_M_file_name");
+  ValueObjectSP function_sp =
+      impl_sp->GetChildMemberWithName("_M_function_name");
+  ValueObjectSP line_sp = impl_sp->GetChildMemberWithName("_M_line");
+  ValueObjectSP column_sp = impl_sp->GetChildMemberWithName("_M_column");
+
+  if (!file_sp || !function_sp || !line_sp || !column_sp)
+    return false;
+
+  bool success = false;
+  uint64_t line = line_sp->GetValueAsUnsigned(0, &success);
+  if (!success)
+    return false;
+
+  uint64_t column = column_sp->GetValueAsUnsigned(0, &success);
+  if (!success)
+    return false;
+
+  if (const char *file = file_sp->GetSummaryAsCString())
+    stream.Printf("%s:%lu:%lu", file, line, column);
+  else
+    stream.Printf("Location Unavailable");
+
+  if (const char *function = function_sp->GetSummaryAsCString())
+    stream.Printf(" (%s)", function);
+
+  return true;
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
index bc67885787bc2..7da72177e0bc7 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
@@ -56,6 +56,10 @@ bool LibStdcppStrongOrderingSummaryProvider(
     ValueObject &valobj, Stream &stream,
     const TypeSummaryOptions &options); // libstdc++ std::strong_ordering
 
+bool LibStdcppSourceLocationSummaryProvider(
+    ValueObject &valobj, Stream &stream,
+    const TypeSummaryOptions &options); // libstdc++ std::source_location
+
 SyntheticChildrenFrontEnd *
 LibstdcppMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *,
                                              lldb::ValueObjectSP);
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/Makefile
new file mode 100644
index 0000000000000..4f79c0a900c3a
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/Makefile
@@ -0,0 +1,4 @@
+CXX_SOURCES := main.cpp
+CXXFLAGS_EXTRAS := -std=c++20
+
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/TestDataFormatterStdSourceLocation.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/TestDataFormatterStdSourceLocation.py
new file mode 100644
index 0000000000000..74a28317b6593
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/TestDataFormatterStdSourceLocation.py
@@ -0,0 +1,53 @@
+"""
+Test std::source_location summary.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class StdSourceLocationTestCase(TestBase):
+    SHARED_BUILD_TESTCASE = False
+    TEST_WITH_PDB_DEBUG_INFO = True
+
+    def do_test(self):
+        lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.cpp")
+        )
+
+        frame = self.frame()
+
+        loc_main = frame.FindVariable("loc_main")
+        self.assertTrue(loc_main.GetError().Success())
+        self.assertRegex(loc_main.summary, r"main\.cpp\":\d+:\d+ \(\"int main\(\)\"\)")
+
+        loc_foo = frame.FindVariable("loc_foo")
+        self.assertTrue(loc_foo.GetError().Success())
+        self.assertRegex(
+            loc_foo.summary, r"main\.cpp\":\d+:\d+ \(\"std::source_location foo\(\)\"\)"
+        )
+
+        loc_empty = frame.FindVariable("loc_empty")
+        self.assertTrue(loc_empty.GetError().Success())
+        self.assertIsNone(loc_empty.summary)
+
+        self.expect(
+            "frame variable",
+            substrs=[
+                f"loc_main = {loc_main.summary}",
+                f"loc_foo = {loc_foo.summary}",
+                "loc_empty = ",
+            ],
+        )
+
+    @add_test_categories(["libc++"])
+    def test_libcxx(self):
+        self.build(dictionary={"USE_LIBCPP": 1})
+        self.do_test()
+
+    @add_test_categories(["libstdcxx"])
+    def test_libstdcxx(self):
+        self.build(dictionary={"USE_LIBSTDCPP": 1})
+        self.do_test()
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/main.cpp
new file mode 100644
index 0000000000000..2927d9cbe2c77
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/main.cpp
@@ -0,0 +1,10 @@
+#include <source_location>
+
+std::source_location foo() { return std::source_location::current(); }
+
+int main() {
+  auto loc_main = std::source_location::current();
+  auto loc_foo = foo();
+  auto loc_empty = std::source_location{};
+  return 0; // break here
+}

>From d0b2e95d4cb80bfe7a61ac82f89344f8b122b8b3 Mon Sep 17 00:00:00 2001
From: Sergei Druzhkov <serzhdruzhok at gmail.com>
Date: Thu, 11 Jun 2026 21:31:33 +0300
Subject: [PATCH 2/4] Fix review comments

---
 .../source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp | 2 +-
 lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp           | 6 ++----
 lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp        | 6 ++----
 3 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 1cff63847388b..b2e4529be2f96 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1533,7 +1533,7 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
       cpp_category_sp,
       lldb_private::formatters::LibStdcppSourceLocationSummaryProvider,
       "libstdc++ std::source_location summary provider",
-      "^std::source_location$", stl_summary_flags, true);
+      "std::source_location", stl_summary_flags);
 }
 
 static lldb_private::SyntheticChildrenFrontEnd *
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index ca6ba18879aad..9ca57093359c3 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -1008,10 +1008,8 @@ bool lldb_private::formatters::LibcxxSourceLocationSummaryProvider(
   if (!success)
     return false;
 
-  if (const char *file = file_sp->GetSummaryAsCString())
-    stream.Printf("%s:%lu:%lu", file, line, column);
-  else
-    stream.Printf("Location Unavailable");
+  const char *file = file_sp->GetSummaryAsCString();
+  stream.Printf("%s:%lu:%lu", file ? file : "<unknown>", line, column);
 
   if (const char *function = function_sp->GetSummaryAsCString())
     stream.Printf(" (%s)", function);
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
index c933d21be4dc0..d994ff95151e1 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
@@ -602,10 +602,8 @@ bool lldb_private::formatters::LibStdcppSourceLocationSummaryProvider(
   if (!success)
     return false;
 
-  if (const char *file = file_sp->GetSummaryAsCString())
-    stream.Printf("%s:%lu:%lu", file, line, column);
-  else
-    stream.Printf("Location Unavailable");
+  const char *file = file_sp->GetSummaryAsCString();
+  stream.Printf("%s:%lu:%lu", file ? file : "<unknown>", line, column);
 
   if (const char *function = function_sp->GetSummaryAsCString())
     stream.Printf(" (%s)", function);

>From b606ce91c32cbc00668587ea30a02d3a54c9474b Mon Sep 17 00:00:00 2001
From: Sergei Druzhkov <serzhdruzhok at gmail.com>
Date: Thu, 11 Jun 2026 21:36:35 +0300
Subject: [PATCH 3/4] Fix format

---
 lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index b2e4529be2f96..8225c2141a84a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1532,8 +1532,8 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
   AddCXXSummary(
       cpp_category_sp,
       lldb_private::formatters::LibStdcppSourceLocationSummaryProvider,
-      "libstdc++ std::source_location summary provider",
-      "std::source_location", stl_summary_flags);
+      "libstdc++ std::source_location summary provider", "std::source_location",
+      stl_summary_flags);
 }
 
 static lldb_private::SyntheticChildrenFrontEnd *

>From 3d390d8f7f8662d6b76d9bbdc1d35da2e8d9b981 Mon Sep 17 00:00:00 2001
From: Sergei Druzhkov <serzhdruzhok at gmail.com>
Date: Fri, 12 Jun 2026 12:43:56 +0300
Subject: [PATCH 4/4] Use fixed line numbers

---
 .../source_location/TestDataFormatterStdSourceLocation.py     | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/TestDataFormatterStdSourceLocation.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/TestDataFormatterStdSourceLocation.py
index 74a28317b6593..4dd28c816a10c 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/TestDataFormatterStdSourceLocation.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/source_location/TestDataFormatterStdSourceLocation.py
@@ -21,12 +21,12 @@ def do_test(self):
 
         loc_main = frame.FindVariable("loc_main")
         self.assertTrue(loc_main.GetError().Success())
-        self.assertRegex(loc_main.summary, r"main\.cpp\":\d+:\d+ \(\"int main\(\)\"\)")
+        self.assertRegex(loc_main.summary, r"main\.cpp\":6:\d+ \(\"int main\(\)\"\)")
 
         loc_foo = frame.FindVariable("loc_foo")
         self.assertTrue(loc_foo.GetError().Success())
         self.assertRegex(
-            loc_foo.summary, r"main\.cpp\":\d+:\d+ \(\"std::source_location foo\(\)\"\)"
+            loc_foo.summary, r"main\.cpp\":3:\d+ \(\"std::source_location foo\(\)\"\)"
         )
 
         loc_empty = frame.FindVariable("loc_empty")



More information about the lldb-commits mailing list