11"""
2- Test lldb data formatter for libc++ std::unique_ptr.
2+ Test lldb data formatter for std::unique_ptr.
33"""
44
5-
65import lldb
76from lldbsuite .test .decorators import *
87from lldbsuite .test .lldbtest import *
98from lldbsuite .test import lldbutil
109
1110
1211class TestCase (TestBase ):
13- def make_expected_type (self , pointee_type : str , qualifiers : str = "" ) -> str :
14- if qualifiers :
15- qualifiers = " " + qualifiers
16-
17- if self .expectedCompiler (["clang" ]) and self .expectedCompilerVersion (
18- [">" , "16.0" ]
19- ):
20- return f"std::unique_ptr<{ pointee_type } >{ qualifiers } "
21- else :
22- return f"std::unique_ptr<{ pointee_type } , std::default_delete<{ pointee_type } > >{ qualifiers } "
23-
24- def make_expected_basic_string_ptr (self ) -> str :
25- if self .expectedCompiler (["clang" ]) and self .expectedCompilerVersion (
26- [">" , "16.0" ]
27- ):
28- return f"std::unique_ptr<std::string>"
29- else :
30- return (
31- "std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, "
32- "std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >"
33- )
34-
35- @add_test_categories (["libc++" ])
36- def test_unique_ptr_variables (self ):
12+ def do_test (self ):
3713 """Test `frame variable` output for `std::unique_ptr` types."""
38- self .build ()
3914
4015 lldbutil .run_to_source_breakpoint (
4116 self , "// break here" , lldb .SBFileSpec ("main.cpp" )
4217 )
4318
4419 valobj = self .expect_var_path (
4520 "up_empty" ,
46- type = self .make_expected_type ("int" ),
4721 summary = "nullptr" ,
4822 children = [ValueCheck (name = "pointer" )],
4923 )
@@ -57,36 +31,32 @@ def test_unique_ptr_variables(self):
5731
5832 valobj = self .expect_var_path (
5933 "up_int" ,
60- type = self .make_expected_type ("int" ),
6134 summary = "10" ,
6235 children = [ValueCheck (name = "pointer" )],
6336 )
6437 self .assertNotEqual (valobj .child [0 ].unsigned , 0 )
6538
6639 valobj = self .expect_var_path (
6740 "up_int_ref" ,
68- type = self .make_expected_type ("int" , qualifiers = "&" ),
6941 summary = "10" ,
7042 children = [ValueCheck (name = "pointer" )],
7143 )
7244 self .assertNotEqual (valobj .child [0 ].unsigned , 0 )
7345
7446 valobj = self .expect_var_path (
7547 "up_int_ref_ref" ,
76- type = self .make_expected_type ("int" , qualifiers = "&&" ),
7748 summary = "10" ,
7849 children = [ValueCheck (name = "pointer" )],
7950 )
8051 self .assertNotEqual (valobj .child [0 ].unsigned , 0 )
8152
8253 valobj = self .expect_var_path (
8354 "up_str" ,
84- type = self .make_expected_basic_string_ptr (),
8555 summary = '"hello"' ,
8656 children = [ValueCheck (name = "pointer" , summary = '"hello"' )],
8757 )
8858
89- valobj = self .expect_var_path ("up_user" , type = self . make_expected_type ( "User" ) )
59+ valobj = self .expect_var_path ("up_user" )
9060 self .assertRegex (valobj .summary , "^User @ 0x0*[1-9a-f][0-9a-f]+$" )
9161 self .assertNotEqual (valobj .child [0 ].unsigned , 0 )
9262
@@ -121,3 +91,67 @@ def test_unique_ptr_variables(self):
12191 self .expect_var_path ("ptr_node->next->value" , value = "2" )
12292 self .expect_var_path ("(*ptr_node).value" , value = "1" )
12393 self .expect_var_path ("(*(*ptr_node).next).value" , value = "2" )
94+
95+ @add_test_categories (["libstdcxx" ])
96+ def test_libstdcxx (self ):
97+ self .build (dictionary = {"USE_LIBSTDCPP" : 1 })
98+ self .do_test ()
99+
100+ @add_test_categories (["libc++" ])
101+ def test_libcxx (self ):
102+ self .build (dictionary = {"USE_LIBCPP" : 1 })
103+ self .do_test ()
104+
105+ def do_test_recursive_unique_ptr (self ):
106+ # Tests that LLDB can handle when we have a loop in the unique_ptr
107+ # reference chain and that it correctly handles the different options
108+ # for the frame variable command in this case.
109+ self .runCmd ("file " + self .getBuildArtifact ("a.out" ), CURRENT_EXECUTABLE_SET )
110+
111+ lldbutil .run_break_set_by_source_regexp (self , "Set break point at this line." )
112+ self .runCmd ("run" , RUN_SUCCEEDED )
113+ self .expect (
114+ "thread list" ,
115+ STOPPED_DUE_TO_BREAKPOINT ,
116+ substrs = ["stopped" , "stop reason = breakpoint" ],
117+ )
118+
119+ self .expect ("frame variable f1->next" , substrs = ["next = NodeU @" ])
120+ self .expect (
121+ "frame variable --ptr-depth=1 f1->next" ,
122+ substrs = ["next = NodeU @" , "value = 2" ],
123+ )
124+ self .expect (
125+ "frame variable --ptr-depth=2 f1->next" ,
126+ substrs = ["next = NodeU @" , "value = 1" , "value = 2" ],
127+ )
128+
129+ frame = self .frame ()
130+ self .assertTrue (frame .IsValid ())
131+ self .assertEqual (
132+ 2 ,
133+ frame .GetValueForVariablePath ("f1->next.object.value" ).GetValueAsUnsigned (),
134+ )
135+ self .assertEqual (
136+ 2 , frame .GetValueForVariablePath ("f1->next->value" ).GetValueAsUnsigned ()
137+ )
138+ self .assertEqual (
139+ 1 ,
140+ frame .GetValueForVariablePath (
141+ "f1->next.object.next.obj.value"
142+ ).GetValueAsUnsigned (),
143+ )
144+ self .assertEqual (
145+ 1 ,
146+ frame .GetValueForVariablePath ("f1->next->next->value" ).GetValueAsUnsigned (),
147+ )
148+
149+ @add_test_categories (["libstdcxx" ])
150+ def test_recursive_unique_ptr_libstdcxx (self ):
151+ self .build (dictionary = {"USE_LIBSTDCPP" : 1 })
152+ self .do_test_recursive_unique_ptr ()
153+
154+ @add_test_categories (["libc++" ])
155+ def test_recursive_unique_ptr_libcxx (self ):
156+ self .build (dictionary = {"USE_LIBCPP" : 1 })
157+ self .do_test_recursive_unique_ptr ()
0 commit comments