1
1
"""
2
- Test lldb data formatter for libc++ std::unique_ptr.
2
+ Test lldb data formatter for std::unique_ptr.
3
3
"""
4
4
5
-
6
5
import lldb
7
6
from lldbsuite .test .decorators import *
8
7
from lldbsuite .test .lldbtest import *
9
8
from lldbsuite .test import lldbutil
10
9
11
10
12
11
class 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 ):
37
13
"""Test `frame variable` output for `std::unique_ptr` types."""
38
- self .build ()
39
14
40
15
lldbutil .run_to_source_breakpoint (
41
16
self , "// break here" , lldb .SBFileSpec ("main.cpp" )
42
17
)
43
18
44
19
valobj = self .expect_var_path (
45
20
"up_empty" ,
46
- type = self .make_expected_type ("int" ),
47
21
summary = "nullptr" ,
48
22
children = [ValueCheck (name = "pointer" )],
49
23
)
@@ -57,36 +31,32 @@ def test_unique_ptr_variables(self):
57
31
58
32
valobj = self .expect_var_path (
59
33
"up_int" ,
60
- type = self .make_expected_type ("int" ),
61
34
summary = "10" ,
62
35
children = [ValueCheck (name = "pointer" )],
63
36
)
64
37
self .assertNotEqual (valobj .child [0 ].unsigned , 0 )
65
38
66
39
valobj = self .expect_var_path (
67
40
"up_int_ref" ,
68
- type = self .make_expected_type ("int" , qualifiers = "&" ),
69
41
summary = "10" ,
70
42
children = [ValueCheck (name = "pointer" )],
71
43
)
72
44
self .assertNotEqual (valobj .child [0 ].unsigned , 0 )
73
45
74
46
valobj = self .expect_var_path (
75
47
"up_int_ref_ref" ,
76
- type = self .make_expected_type ("int" , qualifiers = "&&" ),
77
48
summary = "10" ,
78
49
children = [ValueCheck (name = "pointer" )],
79
50
)
80
51
self .assertNotEqual (valobj .child [0 ].unsigned , 0 )
81
52
82
53
valobj = self .expect_var_path (
83
54
"up_str" ,
84
- type = self .make_expected_basic_string_ptr (),
85
55
summary = '"hello"' ,
86
56
children = [ValueCheck (name = "pointer" , summary = '"hello"' )],
87
57
)
88
58
89
- valobj = self .expect_var_path ("up_user" , type = self . make_expected_type ( "User" ) )
59
+ valobj = self .expect_var_path ("up_user" )
90
60
self .assertRegex (valobj .summary , "^User @ 0x0*[1-9a-f][0-9a-f]+$" )
91
61
self .assertNotEqual (valobj .child [0 ].unsigned , 0 )
92
62
@@ -121,3 +91,67 @@ def test_unique_ptr_variables(self):
121
91
self .expect_var_path ("ptr_node->next->value" , value = "2" )
122
92
self .expect_var_path ("(*ptr_node).value" , value = "1" )
123
93
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