[Lldb-commits] [lldb] 3a677b2 - [lldb] Add deref support to libc++ unique_ptr synthetic
Dave Lee via lldb-commits
lldb-commits at lists.llvm.org
Fri Feb 26 07:39:08 PST 2021
Author: Dave Lee
Date: 2021-02-26T07:39:01-08:00
New Revision: 3a677b29a3b3f6a2539843db4d56ba59689fc0a0
URL: https://github.com/llvm/llvm-project/commit/3a677b29a3b3f6a2539843db4d56ba59689fc0a0
DIFF: https://github.com/llvm/llvm-project/commit/3a677b29a3b3f6a2539843db4d56ba59689fc0a0.diff
LOG: [lldb] Add deref support to libc++ unique_ptr synthetic
Add frame variable dereference suppport to libc++ `std::unique_ptr`.
This change allows for commands like `v *thing_up` and `v thing_up->m_id`. These commands now work the same way they would with raw pointers, and as they would with expression. This is done by adding an unaccounted for child member named `$$dereference$$`.
Without this change, the command would have to be written as `v *thing_up.__value_` or v thing_up.__value_->m_id` which exposes internal structure and is more clumsy to type.
Additionally, the existing tests were updated. See also https://reviews.llvm.org/D97165 which added deref support for `std::shared_ptr`.
Differential Revision: https://reviews.llvm.org/D97524
Added:
Modified:
lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/main.cpp
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 925076f10d72..8eda422f3145 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -463,7 +463,7 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator(
lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
- : SyntheticChildrenFrontEnd(*valobj_sp), m_compressed_pair_sp() {
+ : SyntheticChildrenFrontEnd(*valobj_sp) {
if (valobj_sp)
Update();
}
@@ -480,19 +480,27 @@ lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator(
size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
CalculateNumChildren() {
- return (m_compressed_pair_sp ? 1 : 0);
+ return (m_value_ptr_sp ? 1 : 0);
}
lldb::ValueObjectSP
lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::GetChildAtIndex(
size_t idx) {
- if (!m_compressed_pair_sp)
+ if (!m_value_ptr_sp)
return lldb::ValueObjectSP();
- if (idx != 0)
- return lldb::ValueObjectSP();
+ if (idx == 0)
+ return m_value_ptr_sp;
- return m_compressed_pair_sp;
+ if (idx == 1) {
+ Status status;
+ auto value_sp = m_value_ptr_sp->Dereference(status);
+ if (status.Success()) {
+ return value_sp;
+ }
+ }
+
+ return lldb::ValueObjectSP();
}
bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() {
@@ -505,7 +513,7 @@ bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() {
if (!ptr_sp)
return false;
- m_compressed_pair_sp = GetValueOfLibCXXCompressedPair(*ptr_sp);
+ m_value_ptr_sp = GetValueOfLibCXXCompressedPair(*ptr_sp);
return false;
}
@@ -519,6 +527,8 @@ size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
GetIndexOfChildWithName(ConstString name) {
if (name == "__value_")
return 0;
+ if (name == "$$dereference$$")
+ return 1;
return UINT32_MAX;
}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index 907025fe8ac8..99e206543197 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -124,7 +124,7 @@ class LibcxxUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
~LibcxxUniquePtrSyntheticFrontEnd() override;
private:
- lldb::ValueObjectSP m_compressed_pair_sp;
+ lldb::ValueObjectSP m_value_ptr_sp;
};
SyntheticChildrenFrontEnd *
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py
index b91e494258bf..825513a0b49b 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py
@@ -3,45 +3,85 @@
"""
-
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
-class LibcxUniquePtrDataFormatterTestCase(TestBase):
+
+class TestCase(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."""
+ def test_unique_ptr_variables(self):
+ """Test `frame variable` output for `std::unique_ptr` types."""
self.build()
- (self.target, self.process, _, bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here',
- lldb.SBFileSpec("main.cpp", False))
-
- self.expect("frame variable up_empty",
- substrs=['(std::unique_ptr<int, std::default_delete<int> >) up_empty = nullptr {',
- '__value_ = ',
- '}'])
-
- self.expect("frame variable up_int",
- substrs=['(std::unique_ptr<int, std::default_delete<int> >) up_int = 10 {',
- '__value_ = ',
- '}'])
-
- self.expect("frame variable up_int_ref",
- substrs=['(std::unique_ptr<int, std::default_delete<int> > &) up_int_ref = 10: {',
- '__value_ = ',
- '}'])
-
- self.expect("frame variable up_int_ref_ref",
- substrs=['(std::unique_ptr<int, std::default_delete<int> > &&) up_int_ref_ref = 10: {',
- '__value_ = ',
- '}'])
-
- self.expect("frame variable up_str",
- substrs=['up_str = "hello" {',
- '__value_ = ',
- '}'])
+ lldbutil.run_to_source_breakpoint(
+ self, "// break here", lldb.SBFileSpec("main.cpp")
+ )
+
+ valobj = self.expect_var_path(
+ "up_empty",
+ type="std::unique_ptr<int, std::default_delete<int> >",
+ summary="nullptr",
+ children=[ValueCheck(name="__value_")],
+ )
+ self.assertEqual(
+ valobj.child[0].GetValueAsUnsigned(lldb.LLDB_INVALID_ADDRESS), 0
+ )
+
+ self.expect(
+ "frame variable *up_empty", substrs=["(int) *up_empty = <parent is NULL>"]
+ )
+
+ valobj = self.expect_var_path(
+ "up_int",
+ type="std::unique_ptr<int, std::default_delete<int> >",
+ summary="10",
+ children=[ValueCheck(name="__value_")],
+ )
+ self.assertNotEqual(valobj.child[0].unsigned, 0)
+
+ valobj = self.expect_var_path(
+ "up_int_ref",
+ type="std::unique_ptr<int, std::default_delete<int> > &",
+ summary="10",
+ children=[ValueCheck(name="__value_")],
+ )
+ self.assertNotEqual(valobj.child[0].unsigned, 0)
+
+ valobj = self.expect_var_path(
+ "up_int_ref_ref",
+ type="std::unique_ptr<int, std::default_delete<int> > &&",
+ summary="10",
+ children=[ValueCheck(name="__value_")],
+ )
+ self.assertNotEqual(valobj.child[0].unsigned, 0)
+
+ valobj = self.expect_var_path(
+ "up_str",
+ type="std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >",
+ summary='"hello"',
+ children=[ValueCheck(name="__value_", summary='"hello"')],
+ )
+
+ valobj = self.expect_var_path(
+ "up_user", type="std::unique_ptr<User, std::default_delete<User> >"
+ )
+ self.assertRegex(valobj.summary, "^User @ 0x0*[1-9a-f][0-9a-f]+$")
+ self.assertNotEqual(valobj.child[0].unsigned, 0)
+
+ valobj = self.expect_var_path(
+ "*up_user",
+ type="User",
+ children=[
+ ValueCheck(name="id", value="30"),
+ ValueCheck(name="name", summary='"steph"'),
+ ],
+ )
+ self.assertEqual(str(valobj), '(User) *__value_ = (id = 30, name = "steph")')
+
+ self.expect_var_path("up_user->id", type="int", value="30")
+ self.expect_var_path("up_user->name", type="std::string", summary='"steph"')
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/main.cpp
index 4ccffe2a006d..5201b2a6e9cb 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/main.cpp
@@ -1,13 +1,18 @@
-#include <cstdio>
#include <memory>
#include <string>
+struct User {
+ int id = 30;
+ std::string name = "steph";
+};
+
int main() {
std::unique_ptr<int> up_empty;
std::unique_ptr<int> up_int = std::make_unique<int>(10);
std::unique_ptr<std::string> up_str = std::make_unique<std::string>("hello");
std::unique_ptr<int> &up_int_ref = up_int;
std::unique_ptr<int> &&up_int_ref_ref = std::make_unique<int>(10);
+ std::unique_ptr<User> up_user = std::make_unique<User>();
return 0; // break here
}
More information about the lldb-commits
mailing list