[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