Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 23 additions & 16 deletions lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator(

lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
LibcxxSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
: SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr) {
: SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr),
m_ptr_obj(nullptr) {
if (valobj_sp)
Update();
}
Expand All @@ -251,28 +252,25 @@ llvm::Expected<uint32_t> lldb_private::formatters::
lldb::ValueObjectSP
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex(
uint32_t idx) {
if (!m_cntrl)
if (!m_cntrl || !m_ptr_obj)
return lldb::ValueObjectSP();

ValueObjectSP valobj_sp = m_backend.GetSP();
if (!valobj_sp)
return lldb::ValueObjectSP();

if (idx == 0)
return valobj_sp->GetChildMemberWithName("__ptr_");
return m_ptr_obj->GetSP();

if (idx == 1) {
if (auto ptr_sp = valobj_sp->GetChildMemberWithName("__ptr_")) {
Status status;
auto value_type_sp =
valobj_sp->GetCompilerType()
.GetTypeTemplateArgument(0).GetPointerType();
ValueObjectSP cast_ptr_sp = ptr_sp->Cast(value_type_sp);
ValueObjectSP value_sp = cast_ptr_sp->Dereference(status);
if (status.Success()) {
return value_sp;
}
}
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);
if (status.Success())
return value_sp;
}

return lldb::ValueObjectSP();
Expand All @@ -281,6 +279,7 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex(
lldb::ChildCacheState
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() {
m_cntrl = nullptr;
m_ptr_obj = nullptr;

ValueObjectSP valobj_sp = m_backend.GetSP();
if (!valobj_sp)
Expand All @@ -290,6 +289,12 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() {
if (!target_sp)
return lldb::ChildCacheState::eRefetch;

auto ptr_obj_sp = valobj_sp->GetChildMemberWithName("__ptr_");
if (!ptr_obj_sp)
return lldb::ChildCacheState::eRefetch;

m_ptr_obj = ptr_obj_sp->Clone(ConstString("pointer")).get();

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

m_cntrl = cntrl_sp.get(); // need to store the raw pointer to avoid a circular
Expand All @@ -300,10 +305,12 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() {
llvm::Expected<size_t>
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
GetIndexOfChildWithName(ConstString name) {
if (name == "__ptr_")
if (name == "__ptr_" || name == "pointer")
return 0;
if (name == "$$dereference$$")

if (name == "object" || name == "$$dereference$$")
return 1;

return llvm::createStringError("Type has no child named '%s'",
name.AsCString());
}
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class LibcxxSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {

private:
ValueObject *m_cntrl;
ValueObject *m_ptr_obj;
};

class LibcxxUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
Expand Down
27 changes: 16 additions & 11 deletions lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ class LibStdcppSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
// objects are only destroyed when every shared pointer to any of them
// is destroyed, so we must not store a shared pointer to any ValueObject
// derived from our backend ValueObject (since we're in the same cluster).
ValueObject* m_ptr_obj = nullptr; // Underlying pointer (held, not owned)
ValueObject* m_obj_obj = nullptr; // Underlying object (held, not owned)
ValueObject *m_ptr_obj = nullptr; // Underlying pointer (held, not owned)
};

} // end of anonymous namespace
Expand Down Expand Up @@ -266,15 +265,20 @@ LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(uint32_t idx) {

if (idx == 0)
return m_ptr_obj->GetSP();

if (idx == 1) {
if (m_ptr_obj && !m_obj_obj) {
Status error;
ValueObjectSP obj_obj = m_ptr_obj->Dereference(error);
if (error.Success())
m_obj_obj = obj_obj->Clone(ConstString("object")).get();
}
if (m_obj_obj)
return m_obj_obj->GetSP();
ValueObjectSP valobj_sp = m_backend.GetSP();
if (!valobj_sp)
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);
if (status.Success())
return value_sp;
}
return lldb::ValueObjectSP();
}
Expand All @@ -293,7 +297,6 @@ lldb::ChildCacheState LibStdcppSharedPtrSyntheticFrontEnd::Update() {
return lldb::ChildCacheState::eRefetch;

m_ptr_obj = ptr_obj_sp->Clone(ConstString("pointer")).get();
m_obj_obj = nullptr;

return lldb::ChildCacheState::eRefetch;
}
Expand All @@ -302,8 +305,10 @@ llvm::Expected<size_t>
LibStdcppSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName(ConstString name) {
if (name == "pointer")
return 0;

if (name == "object" || name == "$$dereference$$")
return 1;

return llvm::createStringError("Type has no child named '%s'",
name.AsCString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def test_shared_ptr_variables(self):
"sp_empty",
type="std::shared_ptr<int>",
summary="nullptr",
children=[ValueCheck(name="__ptr_")],
children=[ValueCheck(name="pointer")],
)
self.assertEqual(
valobj.child[0].GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0
Expand All @@ -35,23 +35,23 @@ def test_shared_ptr_variables(self):
valobj = self.expect_var_path(
"sp_int",
type="std::shared_ptr<int>",
children=[ValueCheck(name="__ptr_")],
children=[ValueCheck(name="pointer")],
)
self.assertRegex(valobj.summary, r"^10( strong=1)? weak=0$")
self.assertNotEqual(valobj.child[0].unsigned, 0)

valobj = self.expect_var_path(
"sp_int_ref",
type="std::shared_ptr<int> &",
children=[ValueCheck(name="__ptr_")],
children=[ValueCheck(name="pointer")],
)
self.assertRegex(valobj.summary, r"^10( strong=1)? weak=0$")
self.assertNotEqual(valobj.child[0].unsigned, 0)

valobj = self.expect_var_path(
"sp_int_ref_ref",
type="std::shared_ptr<int> &&",
children=[ValueCheck(name="__ptr_")],
children=[ValueCheck(name="pointer")],
)
self.assertRegex(valobj.summary, r"^10( strong=1)? weak=0$")
self.assertNotEqual(valobj.child[0].unsigned, 0)
Expand All @@ -66,7 +66,7 @@ def test_shared_ptr_variables(self):
valobj = self.expect_var_path(
"sp_str",
type="std::shared_ptr<" + string_type + ">",
children=[ValueCheck(name="__ptr_", summary='"hello"')],
children=[ValueCheck(name="pointer", summary='"hello"')],
)
self.assertRegex(valobj.summary, r'^"hello"( strong=1)? weak=0$')

Expand All @@ -85,7 +85,7 @@ def test_shared_ptr_variables(self):
ValueCheck(name="name", summary='"steph"'),
],
)
self.assertEqual(str(valobj), '(User) *__ptr_ = (id = 30, name = "steph")')
self.assertEqual(str(valobj), '(User) *pointer = (id = 30, name = "steph")')

self.expect_var_path("sp_user->id", type="int", value="30")
self.expect_var_path("sp_user->name", type="std::string", summary='"steph"')
Expand Down
Loading