[Lldb-commits] [lldb] f999918 - [lldb][Formatters] Consistently unwrap pointer element_type in std::shared_ptr formatters (#147340)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Jul 8 06:45:19 PDT 2025
Author: Michael Buch
Date: 2025-07-08T14:45:15+01:00
New Revision: f9999184ddde1bc5de1bba0e25780cb25f435909
URL: https://github.com/llvm/llvm-project/commit/f9999184ddde1bc5de1bba0e25780cb25f435909
DIFF: https://github.com/llvm/llvm-project/commit/f9999184ddde1bc5de1bba0e25780cb25f435909.diff
LOG: [lldb][Formatters] Consistently unwrap pointer element_type in std::shared_ptr formatters (#147340)
Follow-up to
https://github.com/llvm/llvm-project/pull/147165#pullrequestreview-2992585513
Currently when we explicitly dereference a std::shared_ptr, both the
libstdc++ and libc++ formatters will cast the type of the synthetic
pointer child to whatever the `std::shared_ptr::element_type` is aliased
to. E.g.,
```
(lldb) v p
(std::shared_ptr<int>) p = 10 strong=1 weak=0 {
pointer = 0x000000010016c6a0
}
(lldb) v *p
(int) *p = 10
```
However, when we print (or dereference) `p.pointer`, the type devolves
to something less user-friendly:
```
(lldb) v p.pointer
(std::shared_ptr<int>::element_type *) p.pointer = 0x000000010016c6a0
(lldb) v *p.pointer
(std::shared_ptr<int>::element_type) *p.pointer = 10
```
This patch changes both formatters to store the casted type. Then
`GetChildAtIndex` will consistently use the unwrapped type.
Added:
lldb/source/Plugins/Language/CPlusPlus/Generic.cpp
Modified:
lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
lldb/source/Plugins/Language/CPlusPlus/Generic.h
lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index bbfc31a722f27..3ec3cad4b8178 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -12,6 +12,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
CPlusPlusLanguage.cpp
CPlusPlusNameParser.cpp
CxxStringTypes.cpp
+ Generic.cpp
GenericBitset.cpp
GenericOptional.cpp
LibCxx.cpp
diff --git a/lldb/source/Plugins/Language/CPlusPlus/Generic.cpp b/lldb/source/Plugins/Language/CPlusPlus/Generic.cpp
new file mode 100644
index 0000000000000..b237a8a27090c
--- /dev/null
+++ b/lldb/source/Plugins/Language/CPlusPlus/Generic.cpp
@@ -0,0 +1,22 @@
+//===-- Generic.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 "Generic.h"
+
+lldb::ValueObjectSP lldb_private::formatters::GetDesugaredSmartPointerValue(
+ ValueObject &ptr, ValueObject &container) {
+ auto container_type = container.GetCompilerType().GetNonReferenceType();
+ if (!container_type)
+ return nullptr;
+
+ auto arg = container_type.GetTypeTemplateArgument(0);
+ if (!arg)
+ return nullptr;
+
+ return ptr.Cast(arg.GetPointerType());
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/Generic.h b/lldb/source/Plugins/Language/CPlusPlus/Generic.h
index 34efef9e82e5c..f3946225ed48d 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Generic.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/Generic.h
@@ -19,6 +19,11 @@ namespace formatters {
bool GenericOptionalSummaryProvider(ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options);
+/// Return the ValueObjectSP of the underlying pointer member whose type
+/// is a desugared 'std::shared_ptr::element_type *'.
+lldb::ValueObjectSP GetDesugaredSmartPointerValue(ValueObject &ptr,
+ ValueObject &container);
+
} // namespace formatters
} // namespace lldb_private
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 3079de4936a85..a7874047942c4 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -25,6 +25,7 @@
#include "lldb/ValueObject/ValueObjectConstResult.h"
#include "Plugins/Language/CPlusPlus/CxxStringTypes.h"
+#include "Plugins/Language/CPlusPlus/Generic.h"
#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/lldb-enumerations.h"
@@ -264,11 +265,7 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex(
if (idx == 1) {
Status status;
- auto value_type_sp = valobj_sp->GetCompilerType()
- .GetTypeTemplateArgument(0)
- .GetPointerType();
- ValueObjectSP cast_ptr_sp = m_ptr_obj->Cast(value_type_sp);
- ValueObjectSP value_sp = cast_ptr_sp->Dereference(status);
+ ValueObjectSP value_sp = m_ptr_obj->Dereference(status);
if (status.Success())
return value_sp;
}
@@ -293,7 +290,11 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() {
if (!ptr_obj_sp)
return lldb::ChildCacheState::eRefetch;
- m_ptr_obj = ptr_obj_sp->Clone(ConstString("pointer")).get();
+ auto cast_ptr_sp = GetDesugaredSmartPointerValue(*ptr_obj_sp, *valobj_sp);
+ if (!cast_ptr_sp)
+ return lldb::ChildCacheState::eRefetch;
+
+ m_ptr_obj = cast_ptr_sp->Clone(ConstString("pointer")).get();
lldb::ValueObjectSP cntrl_sp(valobj_sp->GetChildMemberWithName("__cntrl_"));
@@ -305,7 +306,7 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() {
llvm::Expected<size_t>
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
GetIndexOfChildWithName(ConstString name) {
- if (name == "__ptr_" || name == "pointer")
+ if (name == "pointer")
return 0;
if (name == "object" || name == "$$dereference$$")
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
index 84442273aebd4..c80a52d0f9ed6 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
@@ -9,6 +9,7 @@
#include "LibStdcpp.h"
#include "LibCxx.h"
+#include "Plugins/Language/CPlusPlus/Generic.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/StringPrinter.h"
@@ -273,11 +274,7 @@ LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(uint32_t idx) {
return nullptr;
Status status;
- auto value_type_sp = valobj_sp->GetCompilerType()
- .GetTypeTemplateArgument(0)
- .GetPointerType();
- ValueObjectSP cast_ptr_sp = m_ptr_obj->Cast(value_type_sp);
- ValueObjectSP value_sp = cast_ptr_sp->Dereference(status);
+ ValueObjectSP value_sp = m_ptr_obj->Dereference(status);
if (status.Success())
return value_sp;
}
@@ -297,7 +294,11 @@ lldb::ChildCacheState LibStdcppSharedPtrSyntheticFrontEnd::Update() {
if (!ptr_obj_sp)
return lldb::ChildCacheState::eRefetch;
- m_ptr_obj = ptr_obj_sp->Clone(ConstString("pointer")).get();
+ auto cast_ptr_sp = GetDesugaredSmartPointerValue(*ptr_obj_sp, *valobj_sp);
+ if (!cast_ptr_sp)
+ return lldb::ChildCacheState::eRefetch;
+
+ m_ptr_obj = cast_ptr_sp->Clone(ConstString("pointer")).get();
return lldb::ChildCacheState::eRefetch;
}
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 8b641c9643958..3d8569da0332e 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
@@ -99,6 +99,10 @@ def do_test(self):
"wie", type="std::weak_ptr<int>", summary="nullptr strong=2 weak=2"
)
+ self.expect_var_path("si.pointer", type="int *")
+ self.expect_var_path("*si.pointer", type="int", value="47")
+ self.expect_var_path("si.object", type="int", value="47")
+
self.runCmd("settings set target.experimental.use-DIL true")
self.expect_var_path("ptr_node->value", value="1")
self.expect_var_path("ptr_node->next->value", value="2")
More information about the lldb-commits
mailing list