Skip to content

Commit f999918

Browse files
authored
[lldb][Formatters] Consistently unwrap pointer element_type in std::shared_ptr formatters (#147340)
Follow-up to #147165 (review) 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.
1 parent 1693ac3 commit f999918

File tree

6 files changed

+47
-13
lines changed

6 files changed

+47
-13
lines changed

lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
1212
CPlusPlusLanguage.cpp
1313
CPlusPlusNameParser.cpp
1414
CxxStringTypes.cpp
15+
Generic.cpp
1516
GenericBitset.cpp
1617
GenericOptional.cpp
1718
LibCxx.cpp
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===-- Generic.cpp ------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===---------------------------------------------------------------------===//
8+
9+
#include "Generic.h"
10+
11+
lldb::ValueObjectSP lldb_private::formatters::GetDesugaredSmartPointerValue(
12+
ValueObject &ptr, ValueObject &container) {
13+
auto container_type = container.GetCompilerType().GetNonReferenceType();
14+
if (!container_type)
15+
return nullptr;
16+
17+
auto arg = container_type.GetTypeTemplateArgument(0);
18+
if (!arg)
19+
return nullptr;
20+
21+
return ptr.Cast(arg.GetPointerType());
22+
}

lldb/source/Plugins/Language/CPlusPlus/Generic.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ namespace formatters {
1919
bool GenericOptionalSummaryProvider(ValueObject &valobj, Stream &stream,
2020
const TypeSummaryOptions &options);
2121

22+
/// Return the ValueObjectSP of the underlying pointer member whose type
23+
/// is a desugared 'std::shared_ptr::element_type *'.
24+
lldb::ValueObjectSP GetDesugaredSmartPointerValue(ValueObject &ptr,
25+
ValueObject &container);
26+
2227
} // namespace formatters
2328
} // namespace lldb_private
2429

lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "lldb/ValueObject/ValueObjectConstResult.h"
2626

2727
#include "Plugins/Language/CPlusPlus/CxxStringTypes.h"
28+
#include "Plugins/Language/CPlusPlus/Generic.h"
2829
#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"
2930
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
3031
#include "lldb/lldb-enumerations.h"
@@ -264,11 +265,7 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex(
264265

265266
if (idx == 1) {
266267
Status status;
267-
auto value_type_sp = valobj_sp->GetCompilerType()
268-
.GetTypeTemplateArgument(0)
269-
.GetPointerType();
270-
ValueObjectSP cast_ptr_sp = m_ptr_obj->Cast(value_type_sp);
271-
ValueObjectSP value_sp = cast_ptr_sp->Dereference(status);
268+
ValueObjectSP value_sp = m_ptr_obj->Dereference(status);
272269
if (status.Success())
273270
return value_sp;
274271
}
@@ -293,7 +290,11 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() {
293290
if (!ptr_obj_sp)
294291
return lldb::ChildCacheState::eRefetch;
295292

296-
m_ptr_obj = ptr_obj_sp->Clone(ConstString("pointer")).get();
293+
auto cast_ptr_sp = GetDesugaredSmartPointerValue(*ptr_obj_sp, *valobj_sp);
294+
if (!cast_ptr_sp)
295+
return lldb::ChildCacheState::eRefetch;
296+
297+
m_ptr_obj = cast_ptr_sp->Clone(ConstString("pointer")).get();
297298

298299
lldb::ValueObjectSP cntrl_sp(valobj_sp->GetChildMemberWithName("__cntrl_"));
299300

@@ -305,7 +306,7 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() {
305306
llvm::Expected<size_t>
306307
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
307308
GetIndexOfChildWithName(ConstString name) {
308-
if (name == "__ptr_" || name == "pointer")
309+
if (name == "pointer")
309310
return 0;
310311

311312
if (name == "object" || name == "$$dereference$$")

lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "LibStdcpp.h"
1010
#include "LibCxx.h"
1111

12+
#include "Plugins/Language/CPlusPlus/Generic.h"
1213
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
1314
#include "lldb/DataFormatters/FormattersHelpers.h"
1415
#include "lldb/DataFormatters/StringPrinter.h"
@@ -273,11 +274,7 @@ LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(uint32_t idx) {
273274
return nullptr;
274275

275276
Status status;
276-
auto value_type_sp = valobj_sp->GetCompilerType()
277-
.GetTypeTemplateArgument(0)
278-
.GetPointerType();
279-
ValueObjectSP cast_ptr_sp = m_ptr_obj->Cast(value_type_sp);
280-
ValueObjectSP value_sp = cast_ptr_sp->Dereference(status);
277+
ValueObjectSP value_sp = m_ptr_obj->Dereference(status);
281278
if (status.Success())
282279
return value_sp;
283280
}
@@ -297,7 +294,11 @@ lldb::ChildCacheState LibStdcppSharedPtrSyntheticFrontEnd::Update() {
297294
if (!ptr_obj_sp)
298295
return lldb::ChildCacheState::eRefetch;
299296

300-
m_ptr_obj = ptr_obj_sp->Clone(ConstString("pointer")).get();
297+
auto cast_ptr_sp = GetDesugaredSmartPointerValue(*ptr_obj_sp, *valobj_sp);
298+
if (!cast_ptr_sp)
299+
return lldb::ChildCacheState::eRefetch;
300+
301+
m_ptr_obj = cast_ptr_sp->Clone(ConstString("pointer")).get();
301302

302303
return lldb::ChildCacheState::eRefetch;
303304
}

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/shared_ptr/TestDataFormatterStdSharedPtr.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ def do_test(self):
9999
"wie", type="std::weak_ptr<int>", summary="nullptr strong=2 weak=2"
100100
)
101101

102+
self.expect_var_path("si.pointer", type="int *")
103+
self.expect_var_path("*si.pointer", type="int", value="47")
104+
self.expect_var_path("si.object", type="int", value="47")
105+
102106
self.runCmd("settings set target.experimental.use-DIL true")
103107
self.expect_var_path("ptr_node->value", value="1")
104108
self.expect_var_path("ptr_node->next->value", value="2")

0 commit comments

Comments
 (0)