kastiglione created this revision. kastiglione added reviewers: jingham, JDevlieghere, teemperor. kastiglione requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
Add `frame variable` dereference suppport to libc++ `std::shared_ptr`. This change allows for commands like `v *thing_sp` and `v thing_sp->m_id`. These commands now work the same way they do with raw pointers. This is done by adding an unaccounted for child member named `$$dereference$$`. Also, add API tests for `std::shared_ptr`, previously there were none. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D97165 Files: lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp lldb/source/Plugins/Language/CPlusPlus/LibCxx.h lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/Makefile lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/main.cpp
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/main.cpp =================================================================== --- /dev/null +++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/main.cpp @@ -0,0 +1,19 @@ +#include <cstdio> +#include <memory> +#include <string> + +struct User { + int id = 30; + std::string name = "steph"; +}; + +int main() { + std::shared_ptr<int> sp_empty; + std::shared_ptr<int> sp_int = std::make_shared<int>(10); + std::shared_ptr<std::string> sp_str = std::make_shared<std::string>("hello"); + std::shared_ptr<int> &sp_int_ref = sp_int; + std::shared_ptr<int> &&sp_int_ref_ref = std::make_shared<int>(10); + std::shared_ptr<User> sp_user = std::make_shared<User>(); + + return 0; // break here +} Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py =================================================================== --- /dev/null +++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py @@ -0,0 +1,63 @@ +""" +Test lldb data formatter for libc++ std::shared_ptr. +""" + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class LibcxSharedPtrDataFormatterTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @add_test_categories(["libc++"]) + def test_with_run_command(self): + """Test that that file and class static variables display correctly.""" + self.build() + + (self.target, self.process, _, bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here', + lldb.SBFileSpec("main.cpp", False)) + + self.expect("frame variable sp_empty", + substrs=['(std::shared_ptr<int>) sp_empty = nullptr {', + '__ptr_ = 0x0', + '}']) + + self.expect("frame variable *sp_empty", + substrs=['(int) *sp_empty = <parent is NULL>']) + + self.expect("frame variable sp_int", + substrs=['(std::shared_ptr<int>) sp_int = 10 ', + '__ptr_ = 0x', + '}']) + + self.expect("frame variable sp_int_ref", + substrs=['(std::shared_ptr<int> &) sp_int_ref = 10 ', + '__ptr_ = 0x', + '}']) + + self.expect("frame variable sp_int_ref_ref", + substrs=['(std::shared_ptr<int> &&) sp_int_ref_ref = 10 ', + '__ptr_ = ', + '}']) + + self.expect("frame variable sp_str", + substrs=['(std::shared_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >) sp_str = "hello"', + '__ptr_ = "hello"', + '}']) + + self.expect("frame variable sp_user", + substrs=['::shared_ptr<User>) sp_user = std::__1::shared_ptr<User>::element_type @ 0x', + '__ptr_ = 0x', + '}']) + + self.expect("frame variable *sp_user", + substrs=['(User) *sp_user = (id = 30, name = "steph")']) + + self.expect("frame variable sp_user->id", + substrs=['(int) sp_user->id = 30']) + + self.expect("frame variable sp_user->name", + substrs=['(std::string) sp_user->name = "steph"']) Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/Makefile =================================================================== --- /dev/null +++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/Makefile @@ -0,0 +1,6 @@ +CXX_SOURCES := main.cpp + +USE_LIBCPP := 1 + +CXXFLAGS_EXTRAS := -std=c++14 +include Makefile.rules Index: lldb/source/Plugins/Language/CPlusPlus/LibCxx.h =================================================================== --- lldb/source/Plugins/Language/CPlusPlus/LibCxx.h +++ lldb/source/Plugins/Language/CPlusPlus/LibCxx.h @@ -105,10 +105,6 @@ private: ValueObject *m_cntrl; - lldb::ValueObjectSP m_count_sp; - lldb::ValueObjectSP m_weak_count_sp; - uint8_t m_ptr_size; - lldb::ByteOrder m_byte_order; }; class LibcxxUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd { Index: lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp =================================================================== --- lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -379,8 +379,7 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd:: LibcxxSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr), m_count_sp(), - m_weak_count_sp(), m_ptr_size(0), m_byte_order(lldb::eByteOrderInvalid) { + : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr) { if (valobj_sp) Update(); } @@ -403,42 +402,22 @@ if (idx == 0) return valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true); - if (idx > 2) - return lldb::ValueObjectSP(); - if (idx == 1) { - if (!m_count_sp) { - ValueObjectSP shared_owners_sp(m_cntrl->GetChildMemberWithName( - ConstString("__shared_owners_"), true)); - if (!shared_owners_sp) - return lldb::ValueObjectSP(); - uint64_t count = 1 + shared_owners_sp->GetValueAsUnsigned(0); - DataExtractor data(&count, 8, m_byte_order, m_ptr_size); - m_count_sp = CreateValueObjectFromData( - "count", data, valobj_sp->GetExecutionContextRef(), - shared_owners_sp->GetCompilerType()); + auto ptr_sp = + valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true); + Status status; + auto value_sp = ptr_sp->Dereference(status); + if (status.Success()) { + auto value_type_sp = + valobj_sp->GetCompilerType().GetTypeTemplateArgument(0); + return value_sp->Cast(value_type_sp); } - return m_count_sp; - } else /* if (idx == 2) */ - { - if (!m_weak_count_sp) { - ValueObjectSP shared_weak_owners_sp(m_cntrl->GetChildMemberWithName( - ConstString("__shared_weak_owners_"), true)); - if (!shared_weak_owners_sp) - return lldb::ValueObjectSP(); - uint64_t count = 1 + shared_weak_owners_sp->GetValueAsUnsigned(0); - DataExtractor data(&count, 8, m_byte_order, m_ptr_size); - m_weak_count_sp = CreateValueObjectFromData( - "count", data, valobj_sp->GetExecutionContextRef(), - shared_weak_owners_sp->GetCompilerType()); - } - return m_weak_count_sp; } + + return lldb::ValueObjectSP(); } bool lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() { - m_count_sp.reset(); - m_weak_count_sp.reset(); m_cntrl = nullptr; ValueObjectSP valobj_sp = m_backend.GetSP(); @@ -449,9 +428,6 @@ if (!target_sp) return false; - m_byte_order = target_sp->GetArchitecture().GetByteOrder(); - m_ptr_size = target_sp->GetArchitecture().GetAddressByteSize(); - lldb::ValueObjectSP cntrl_sp( valobj_sp->GetChildMemberWithName(ConstString("__cntrl_"), true)); @@ -469,10 +445,8 @@ GetIndexOfChildWithName(ConstString name) { if (name == "__ptr_") return 0; - if (name == "count") + if (name == "$$dereference$$") return 1; - if (name == "weak_count") - return 2; return UINT32_MAX; }
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits