lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
- : SyntheticChildrenFrontEnd(*valobj_sp), m_compressed_pair_sp() {
+ : SyntheticChildrenFrontEnd(*valobj_sp) {
if (valobj_sp)
Update();
}
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() {
if (!ptr_sp)
return false;
- m_compressed_pair_sp = GetValueOfLibCXXCompressedPair(*ptr_sp);
+ m_value_ptr_sp = GetValueOfLibCXXCompressedPair(*ptr_sp);
return false;
}
GetIndexOfChildWithName(ConstString name) {
if (name == "__value_")
return 0;
+ if (name == "$$dereference$$")
+ return 1;
return UINT32_MAX;
}
"""
-
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"')