Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
return 0;
if (name == "deleter")
return 1;
if (name == "$$dereference$$")
if (name == "obj" || name == "object" || name == "$$dereference$$")
return 2;
return llvm::createStringError("Type has no child named '%s'",
name.AsCString());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
CXX_SOURCES := main.cpp

USE_LIBCPP := 1

# We need debug info tuning for lldb in order to emit the preferred name for
# std::string. See https://reviews.llvm.org/D145803.
CXXFLAGS_EXTRAS := -std=c++14 -glldb
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably drop these too now since we don't check the typenames.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"""
Test lldb data formatter for libc++ std::unique_ptr.
Test lldb data formatter for std::unique_ptr.
"""


import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
Expand Down Expand Up @@ -32,10 +31,8 @@ def make_expected_basic_string_ptr(self) -> str:
"std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >"
)

@add_test_categories(["libc++"])
def test_unique_ptr_variables(self):
def do_test(self):
"""Test `frame variable` output for `std::unique_ptr` types."""
self.build()

lldbutil.run_to_source_breakpoint(
self, "// break here", lldb.SBFileSpec("main.cpp")
Expand Down Expand Up @@ -121,3 +118,67 @@ def test_unique_ptr_variables(self):
self.expect_var_path("ptr_node->next->value", value="2")
self.expect_var_path("(*ptr_node).value", value="1")
self.expect_var_path("(*(*ptr_node).next).value", value="2")

@add_test_categories(["libstdcxx"])
def test_libstdcxx(self):
self.build(dictionary={"USE_LIBSTDCPP": 1})
self.do_test()

@add_test_categories(["libc++"])
def test_libcxx(self):
self.build(dictionary={"USE_LIBCPP": 1})
self.do_test()

def do_test_recursive_unique_ptr(self):
# Tests that LLDB can handle when we have a loop in the unique_ptr
# reference chain and that it correctly handles the different options
# for the frame variable command in this case.
self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)

lldbutil.run_break_set_by_source_regexp(self, "Set break point at this line.")
self.runCmd("run", RUN_SUCCEEDED)
self.expect(
"thread list",
STOPPED_DUE_TO_BREAKPOINT,
substrs=["stopped", "stop reason = breakpoint"],
)

self.expect("frame variable f1->next", substrs=["next = NodeU @"])
self.expect(
"frame variable --ptr-depth=1 f1->next",
substrs=["next = NodeU @", "value = 2"],
)
self.expect(
"frame variable --ptr-depth=2 f1->next",
substrs=["next = NodeU @", "value = 1", "value = 2"],
)

frame = self.frame()
self.assertTrue(frame.IsValid())
self.assertEqual(
2,
frame.GetValueForVariablePath("f1->next.object.value").GetValueAsUnsigned(),
)
self.assertEqual(
2, frame.GetValueForVariablePath("f1->next->value").GetValueAsUnsigned()
)
self.assertEqual(
1,
frame.GetValueForVariablePath(
"f1->next.object.next.obj.value"
).GetValueAsUnsigned(),
)
self.assertEqual(
1,
frame.GetValueForVariablePath("f1->next->next->value").GetValueAsUnsigned(),
)

@add_test_categories(["libstdcxx"])
def test_recursive_unique_ptr_libstdcxx(self):
self.build(dictionary={"USE_LIBSTDCPP": 1})
self.do_test_recursive_unique_ptr()

@add_test_categories(["libc++"])
def test_recursive_unique_ptr_libcxx(self):
self.build(dictionary={"USE_LIBCPP": 1})
self.do_test_recursive_unique_ptr()
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,20 @@ struct NodeU {
// representation when the type of the second element is an empty class. So
// we need a deleter class with a dummy data member to trigger the other path.
struct NonEmptyIntDeleter {
void operator()(int* ptr) { delete ptr; }
void operator()(int *ptr) { delete ptr; }

int dummy_ = 9999;
};

static void recursive() {
// Set up a structure where we have a loop in the unique_ptr chain.
NodeU *f1 = new NodeU{nullptr, 1};
NodeU *f2 = new NodeU{nullptr, 2};
f1->next.reset(f2);
f2->next.reset(f1);
std::puts("Set break point at this line.");
}

int main() {
std::unique_ptr<int> up_empty;
std::unique_ptr<int> up_int = std::make_unique<int>(10);
Expand All @@ -33,5 +42,9 @@ int main() {
std::unique_ptr<NodeU>(new NodeU{nullptr, 2});
ptr_node = std::unique_ptr<NodeU>(new NodeU{std::move(ptr_node), 1});

return 0; // break here
std::puts("// break here");

recursive();

return 0;
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading