[Lldb-commits] [lldb] [lldb] Add std::source_location summary provider (PR #203185)
Sergei Druzhkov via lldb-commits
lldb-commits at lists.llvm.org
Wed Jun 10 23:48:16 PDT 2026
https://github.com/DrSergei created https://github.com/llvm/llvm-project/pull/203185
Added simple summary provider for `std::source_location` from C++20.
>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] [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
+}
More information about the lldb-commits
mailing list