https://github.com/kastiglione updated https://github.com/llvm/llvm-project/pull/205931
>From 6edc6a9fb8b7e79586eed84da9c70f268b452c62 Mon Sep 17 00:00:00 2001 From: Dave Lee <[email protected]> Date: Tue, 23 Jun 2026 15:47:44 -0700 Subject: [PATCH 1/6] [lldb] Condense formatter output for null smart pointers Elide the "pointer" child of smart pointers when the value is null. This avoids redudant output, which can add up when printing large data types with many smart pointers. Prior to this change, a nullptr value would be printed like so: ``` (lldb) p name (std::shared_ptr<std::string>) nullptr { pointer = nullptr } ``` With this change, the braced output is eliminated, leaving: ``` (lldb) p name (std::shared_ptr<std::string>) nullptr ``` --- .../Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp | 11 ++++++++--- lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp | 8 ++++++-- lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp | 4 +++- .../Language/CPlusPlus/LibStdcppUniquePointer.cpp | 6 +++--- .../Language/CPlusPlus/MsvcStlSmartPointer.cpp | 6 ++++-- .../shared_ptr/TestDataFormatterStdSharedPtr.py | 7 ++++++- .../unique_ptr/TestDataFormatterStdUniquePtr.py | 5 ++++- 7 files changed, 34 insertions(+), 13 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 74a5a414de67b..3da00528fa54b 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -1056,6 +1056,7 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "^std::__[[:alnum:]]+::span<.+>$", stl_summary_flags, true); stl_summary_flags.SetSkipPointers(true); + stl_summary_flags.SetHideEmptyAggregates(true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxSmartPointerSummaryProvider, @@ -1877,15 +1878,19 @@ static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider, "std::initializer_list summary provider", "^std::initializer_list<.+>$", stl_summary_flags, true); + + TypeSummaryImpl::Flags stl_smart_pointer_flags = stl_summary_flags; + stl_smart_pointer_flags.SetHideEmptyAggregates(true); AddCXXSummary(cpp_category_sp, GenericSmartPointerSummaryProvider, "MSVC STL/libstdc++ std::shared_ptr summary provider", - "^std::shared_ptr<.+>(( )?&)?$", stl_summary_flags, true); + "^std::shared_ptr<.+>(( )?&)?$", stl_smart_pointer_flags, true); AddCXXSummary(cpp_category_sp, GenericSmartPointerSummaryProvider, "MSVC STL/libstdc++ std::weak_ptr summary provider", - "^std::weak_ptr<.+>(( )?&)?$", stl_summary_flags, true); + "^std::weak_ptr<.+>(( )?&)?$", stl_smart_pointer_flags, true); AddCXXSummary(cpp_category_sp, GenericUniquePtrSummaryProvider, "MSVC STL/libstdc++ std::unique_ptr summary provider", - "^std::unique_ptr<.+>(( )?&)?$", stl_summary_flags, true); + "^std::unique_ptr<.+>(( )?&)?$", stl_smart_pointer_flags, true); + AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider, "MSVC STL/libstdc++ std::tuple summary provider", "^std::tuple<.*>(( )?&)?$", stl_summary_flags, true); diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index d70769f3a0e3e..8e83719649f5e 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -350,7 +350,11 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd:: llvm::Expected<uint32_t> lldb_private::formatters:: LibcxxSharedPtrSyntheticFrontEnd::CalculateNumChildren() { - return (m_cntrl ? 1 : 0); + if (m_cntrl) { + if (m_ptr_obj && m_ptr_obj->GetValueAsUnsigned(0) != 0) + return 1; + } + return 0; } lldb::ValueObjectSP @@ -447,7 +451,7 @@ lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator( llvm::Expected<uint32_t> lldb_private::formatters:: LibcxxUniquePtrSyntheticFrontEnd::CalculateNumChildren() { - if (m_value_ptr_sp) + if (m_value_ptr_sp && m_value_ptr_sp->GetValueAsUnsigned(0) != 0) return m_deleter_sp ? 2 : 1; return 0; } diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index 83bea8bb533b6..3e2d4cd88c987 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -339,7 +339,9 @@ LibStdcppSharedPtrSyntheticFrontEnd::LibStdcppSharedPtrSyntheticFrontEnd( llvm::Expected<uint32_t> LibStdcppSharedPtrSyntheticFrontEnd::CalculateNumChildren() { - return 1; + if (m_ptr_obj && m_ptr_obj->GetValueAsUnsigned(0) != 0) + return 1; + return 0; } lldb::ValueObjectSP diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp index d5d8ebc457684..45dc1960d2482 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp @@ -133,9 +133,9 @@ LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(uint32_t idx) { llvm::Expected<uint32_t> LibStdcppUniquePtrSyntheticFrontEnd::CalculateNumChildren() { - if (m_del_obj) - return 2; - return 1; + if (m_ptr_obj && m_ptr_obj->GetValueAsUnsigned(0) != 0) + return m_del_obj ? 2 : 1; + return 0; } llvm::Expected<size_t> diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlSmartPointer.cpp b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlSmartPointer.cpp index d6a2c28ba7a7e..6faba15c39b13 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlSmartPointer.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlSmartPointer.cpp @@ -114,7 +114,9 @@ lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd:: llvm::Expected<uint32_t> lldb_private::formatters:: MsvcStlSmartPointerSyntheticFrontEnd::CalculateNumChildren() { - return (m_ptr_obj ? 1 : 0); + if (m_ptr_obj && m_ptr_obj->GetValueAsUnsigned(0) != 0) + return 1; + return 0; } lldb::ValueObjectSP @@ -213,7 +215,7 @@ lldb_private::formatters::MsvcStlUniquePtrSyntheticFrontEnd:: llvm::Expected<uint32_t> lldb_private::formatters:: MsvcStlUniquePtrSyntheticFrontEnd::CalculateNumChildren() { - if (m_value_ptr_sp) + if (m_value_ptr_sp && m_value_ptr_sp->GetValueAsUnsigned(0) != 0) return m_deleter_sp ? 2 : 1; return 0; } diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py index cc0798f262f8d..ee1773a6496fd 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py @@ -22,12 +22,15 @@ def do_test(self): "sp_empty", type="std::shared_ptr<int>", summary="nullptr", - children=[ValueCheck(name="pointer")], ) + self.assertEqual(valobj.GetNumChildren(), 0) self.assertEqual( valobj.child[0].GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0 ) + # Null shared_ptr should not output braces. + self.expect("frame variable sp_empty", patterns=[" = nullptr$"]) + self.expect( "frame variable *sp_empty", substrs=["(int) *sp_empty = <parent is NULL>"] ) @@ -106,9 +109,11 @@ def do_test(self): valobj = self.expect_var_path( "sie", type="std::shared_ptr<int>", summary="nullptr strong=2 weak=2" ) + self.assertEqual(valobj.GetNumChildren(), 0) valobj = self.expect_var_path( "wie", type="std::weak_ptr<int>", summary="nullptr strong=2 weak=2" ) + self.assertEqual(valobj.GetNumChildren(), 0) self.expect_var_path("si.pointer", type="int *") self.expect_var_path("*si.pointer", type="int", value="47") diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py index c0e579aa80587..1687c3c4c62a6 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py @@ -22,12 +22,15 @@ def do_test(self): valobj = self.expect_var_path( "up_empty", summary="nullptr", - children=[ValueCheck(name="pointer")], ) + self.assertEqual(valobj.GetNumChildren(), 0) self.assertEqual( valobj.child[0].GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0 ) + # Null unique_ptr should not output braces. + self.expect("frame variable up_empty", patterns=[" = nullptr$"]) + self.expect( "frame variable *up_empty", substrs=["(int) *up_empty = <parent is NULL>"] ) >From 0ea96a557f7df25abb3722b6c5b19f77945bdf14 Mon Sep 17 00:00:00 2001 From: Dave Lee <[email protected]> Date: Thu, 25 Jun 2026 15:10:43 -0700 Subject: [PATCH 2/6] Validate "pointer" child --- .../generic/shared_ptr/TestDataFormatterStdSharedPtr.py | 1 + .../generic/unique_ptr/TestDataFormatterStdUniquePtr.py | 1 + 2 files changed, 2 insertions(+) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py index ee1773a6496fd..0fd242a6a70d5 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py @@ -27,6 +27,7 @@ def do_test(self): self.assertEqual( valobj.child[0].GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0 ) + self.assertEqual(valobj.child[0].GetID(), valobj.member["pointer"].GetID()) # Null shared_ptr should not output braces. self.expect("frame variable sp_empty", patterns=[" = nullptr$"]) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py index 1687c3c4c62a6..35aa6901a347c 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py @@ -27,6 +27,7 @@ def do_test(self): self.assertEqual( valobj.child[0].GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0 ) + self.assertEqual(valobj.child[0].GetID(), valobj.member["pointer"].GetID()) # Null unique_ptr should not output braces. self.expect("frame variable up_empty", patterns=[" = nullptr$"]) >From fd0ab10dabbebd129711a0fd5260589cf5e9c8f9 Mon Sep 17 00:00:00 2001 From: Dave Lee <[email protected]> Date: Thu, 25 Jun 2026 19:16:13 -0700 Subject: [PATCH 3/6] Use GetChildAtIndex in tests --- .../generic/shared_ptr/TestDataFormatterStdSharedPtr.py | 6 ++++-- .../generic/unique_ptr/TestDataFormatterStdUniquePtr.py | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py index 0fd242a6a70d5..32749af3ead99 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py @@ -25,9 +25,11 @@ def do_test(self): ) self.assertEqual(valobj.GetNumChildren(), 0) self.assertEqual( - valobj.child[0].GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0 + valobj.GetChildAtIndex(0).GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0 + ) + self.assertEqual( + valobj.GetChildAtIndex(0).GetID(), valobj.member["pointer"].GetID() ) - self.assertEqual(valobj.child[0].GetID(), valobj.member["pointer"].GetID()) # Null shared_ptr should not output braces. self.expect("frame variable sp_empty", patterns=[" = nullptr$"]) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py index 35aa6901a347c..0b751a738d95b 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py @@ -25,9 +25,11 @@ def do_test(self): ) self.assertEqual(valobj.GetNumChildren(), 0) self.assertEqual( - valobj.child[0].GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0 + valobj.GetChildAtIndex(0).GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0 + ) + self.assertEqual( + valobj.GetChildAtIndex(0).GetID(), valobj.member["pointer"].GetID() ) - self.assertEqual(valobj.child[0].GetID(), valobj.member["pointer"].GetID()) # Null unique_ptr should not output braces. self.expect("frame variable up_empty", patterns=[" = nullptr$"]) >From 104179f2abaa9f57589f42c72ae1d35cea03e20c Mon Sep 17 00:00:00 2001 From: Dave Lee <[email protected]> Date: Tue, 30 Jun 2026 10:41:31 -0700 Subject: [PATCH 4/6] Access pointer child in tests by name not index --- .../generic/shared_ptr/TestDataFormatterStdSharedPtr.py | 2 +- .../generic/unique_ptr/TestDataFormatterStdUniquePtr.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py index 32749af3ead99..3960b92b53fe5 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py @@ -25,7 +25,7 @@ def do_test(self): ) self.assertEqual(valobj.GetNumChildren(), 0) self.assertEqual( - valobj.GetChildAtIndex(0).GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0 + valobj.member["pointer"].GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0 ) self.assertEqual( valobj.GetChildAtIndex(0).GetID(), valobj.member["pointer"].GetID() diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py index 0b751a738d95b..84912a95d79c3 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py @@ -25,7 +25,7 @@ def do_test(self): ) self.assertEqual(valobj.GetNumChildren(), 0) self.assertEqual( - valobj.GetChildAtIndex(0).GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0 + valobj.member["pointer"].GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0 ) self.assertEqual( valobj.GetChildAtIndex(0).GetID(), valobj.member["pointer"].GetID() >From 306e9f989fe95dacfe4cbf70a353b3b741525005 Mon Sep 17 00:00:00 2001 From: Dave Lee <[email protected]> Date: Tue, 30 Jun 2026 11:30:53 -0700 Subject: [PATCH 5/6] Flatten nested if --- lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 8e83719649f5e..ab21ef90749fd 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -350,10 +350,8 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd:: llvm::Expected<uint32_t> lldb_private::formatters:: LibcxxSharedPtrSyntheticFrontEnd::CalculateNumChildren() { - if (m_cntrl) { - if (m_ptr_obj && m_ptr_obj->GetValueAsUnsigned(0) != 0) - return 1; - } + if (m_cntrl && m_ptr_obj && m_ptr_obj->GetValueAsUnsigned(0) != 0) + return 1; return 0; } >From 1080134c2ff8bed26e48d590d288c55393853cd0 Mon Sep 17 00:00:00 2001 From: Dave Lee <[email protected]> Date: Thu, 2 Jul 2026 10:28:18 -0700 Subject: [PATCH 6/6] Check GetIndexOfChildWithName in tests --- .../generic/shared_ptr/TestDataFormatterStdSharedPtr.py | 4 +--- .../generic/unique_ptr/TestDataFormatterStdUniquePtr.py | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py index 3960b92b53fe5..4d249d1e39d8e 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py @@ -24,12 +24,10 @@ def do_test(self): summary="nullptr", ) self.assertEqual(valobj.GetNumChildren(), 0) + self.assertEqual(valobj.GetIndexOfChildWithName("pointer"), 0) self.assertEqual( valobj.member["pointer"].GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0 ) - self.assertEqual( - valobj.GetChildAtIndex(0).GetID(), valobj.member["pointer"].GetID() - ) # Null shared_ptr should not output braces. self.expect("frame variable sp_empty", patterns=[" = nullptr$"]) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py index 84912a95d79c3..4cd3bc271dc99 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unique_ptr/TestDataFormatterStdUniquePtr.py @@ -24,12 +24,10 @@ def do_test(self): summary="nullptr", ) self.assertEqual(valobj.GetNumChildren(), 0) + self.assertEqual(valobj.GetIndexOfChildWithName("pointer"), 0) self.assertEqual( valobj.member["pointer"].GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0 ) - self.assertEqual( - valobj.GetChildAtIndex(0).GetID(), valobj.member["pointer"].GetID() - ) # Null unique_ptr should not output braces. self.expect("frame variable up_empty", patterns=[" = nullptr$"]) _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
