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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits