Skip to content

Commit 311d115

Browse files
authored
[LLDB] Run MSVC STL string(-view) tests with PDB (#166833)
PDB doesn't include the typedefs for types, so all types use their full name. For `std::string` and friends, this means they show up as `std::basic_string<char, std::char_traits<char>, std::allocator<char>>`. This PR updates the `std::{,w,u8,u16,u32}string(_view)` tests to account for this and runs them with PDB.
1 parent 7ac6a95 commit 311d115

File tree

4 files changed

+122
-69
lines changed

4 files changed

+122
-69
lines changed

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,26 @@
1111

1212

1313
class StdStringDataFormatterTestCase(TestBase):
14+
TEST_WITH_PDB_DEBUG_INFO = True
15+
1416
def setUp(self):
1517
# Call super's setUp().
1618
TestBase.setUp(self)
1719
# Find the line number to break at.
1820
self.main_spec = lldb.SBFileSpec("main.cpp")
1921
self.namespace = "std"
2022

23+
def _makeStringName(self, typedef: str, char_type: str, allocator=None):
24+
if allocator is None:
25+
allocator = self.namespace + "::allocator"
26+
27+
if self.getDebugInfo() == "pdb":
28+
return f"{self.namespace}::basic_string<{char_type}, std::char_traits<{char_type}>, {allocator}<{char_type}>>"
29+
30+
if typedef.startswith("::"):
31+
return self.namespace + typedef
32+
return typedef
33+
2134
def do_test(self):
2235
"""Test that that file and class static variables display correctly."""
2336
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
@@ -36,10 +49,17 @@ def cleanup():
3649
# Execute the cleanup function during test case tear down.
3750
self.addTearDownHook(cleanup)
3851

39-
ns = self.namespace
52+
string_name = self._makeStringName("::string", "char")
53+
wstring_name = self._makeStringName("::wstring", "wchar_t")
54+
custom_string_name = self._makeStringName(
55+
"CustomString", "char", allocator="CustomAlloc"
56+
)
57+
custom_wstring_name = self._makeStringName(
58+
"CustomWString", "wchar_t", allocator="CustomAlloc"
59+
)
4060

4161
# Check 'S' pre-assignment.
42-
self.expect("frame variable S", substrs=['(%s::wstring) S = L"!!!!"' % ns])
62+
self.expect("frame variable S", substrs=[f'({wstring_name}) S = L"!!!!"'])
4363

4464
thread.StepOver()
4565

@@ -54,34 +74,31 @@ def cleanup():
5474
)
5575

5676
self.expect_expr(
57-
"s", result_type=ns + "::wstring", result_summary='L"hello world! מזל טוב!"'
77+
"s", result_type=wstring_name, result_summary='L"hello world! מזל טוב!"'
5878
)
5979

60-
self.expect_expr(
61-
"q", result_type=ns + "::string", result_summary='"hello world"'
62-
)
80+
self.expect_expr("q", result_type=string_name, result_summary='"hello world"')
6381

6482
self.expect_expr(
6583
"Q",
66-
result_type=ns + "::string",
84+
result_type=string_name,
6785
result_summary='"quite a long std::strin with lots of info inside it"',
6886
)
6987

7088
self.expect(
7189
"frame variable",
7290
substrs=[
73-
'(%s::wstring) wempty = L""' % ns,
74-
'(%s::wstring) s = L"hello world! מזל טוב!"' % ns,
75-
'(%s::wstring) S = L"!!!!!"' % ns,
91+
f'({wstring_name}) wempty = L""',
92+
f'({wstring_name}) s = L"hello world! מזל טוב!"',
93+
f'({wstring_name}) S = L"!!!!!"',
7694
"(const wchar_t *) mazeltov = 0x",
7795
'L"מזל טוב"',
78-
'(%s::string) empty = ""' % ns,
79-
'(%s::string) q = "hello world"' % ns,
80-
'(%s::string) Q = "quite a long std::strin with lots of info inside it"'
81-
% ns,
82-
"(%s::string *) null_str = nullptr" % ns,
83-
'(CustomString) custom_str = "hello!"',
84-
'(CustomWString) custom_wstr = L"hello!"',
96+
f'({string_name}) empty = ""',
97+
f'({string_name}) q = "hello world"',
98+
f'({string_name}) Q = "quite a long std::strin with lots of info inside it"',
99+
f"({string_name} *) null_str = nullptr",
100+
f'({custom_string_name}) custom_str = "hello!"',
101+
f'({custom_wstring_name}) custom_wstr = L"hello!"',
85102
],
86103
)
87104

@@ -136,19 +153,26 @@ def do_test_multibyte(self):
136153
self, "Set break point at this line.", self.main_spec
137154
)
138155

139-
ns = self.namespace
156+
u16string_name = self._makeStringName("::u16string", "char16_t")
157+
u32string_name = self._makeStringName("::u32string", "char32_t")
158+
custom_u16string_name = self._makeStringName(
159+
"CustomStringU16", "char16_t", allocator="CustomAlloc"
160+
)
161+
custom_u32string_name = self._makeStringName(
162+
"CustomStringU32", "char32_t", allocator="CustomAlloc"
163+
)
140164

141165
self.expect(
142166
"frame variable",
143167
substrs=[
144-
'(%s::u16string) u16_string = u"ß水氶"' % ns,
145-
'(%s::u16string) u16_empty = u""' % ns,
146-
'(%s::u32string) u32_string = U"🍄🍅🍆🍌"' % ns,
147-
'(%s::u32string) u32_empty = U""' % ns,
148-
'(CustomStringU16) custom_u16 = u"ß水氶"',
149-
'(CustomStringU16) custom_u16_empty = u""',
150-
'(CustomStringU32) custom_u32 = U"🍄🍅🍆🍌"',
151-
'(CustomStringU32) custom_u32_empty = U""',
168+
f'({u16string_name}) u16_string = u"ß水氶"',
169+
f'({u16string_name}) u16_empty = u""',
170+
f'({u32string_name}) u32_string = U"🍄🍅🍆🍌"',
171+
f'({u32string_name}) u32_empty = U""',
172+
f'({custom_u16string_name}) custom_u16 = u"ß水氶"',
173+
f'({custom_u16string_name}) custom_u16_empty = u""',
174+
f'({custom_u32string_name}) custom_u32 = U"🍄🍅🍆🍌"',
175+
f'({custom_u32string_name}) custom_u32_empty = U""',
152176
],
153177
)
154178

@@ -271,9 +295,8 @@ def do_test_embedded_null(self):
271295
self.expect(
272296
"frame variable",
273297
substrs=[
274-
'(%s::string) IHaveEmbeddedZeros = "a\\0b\\0c\\0d"' % ns,
275-
'(%s::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"'
276-
% ns,
298+
f'({self._makeStringName("::string", "char")}) IHaveEmbeddedZeros = "a\\0b\\0c\\0d"',
299+
f'({self._makeStringName("::wstring", "wchar_t")}) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"',
277300
],
278301
)
279302

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/TestDataFormatterStdStringView.py

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212

1313
class StdStringViewDataFormatterTestCase(TestBase):
14+
TEST_WITH_PDB_DEBUG_INFO = True
15+
1416
def setUp(self):
1517
# Call super's setUp().
1618
TestBase.setUp(self)
@@ -20,6 +22,12 @@ def setUp(self):
2022
"main.cpp", "// Break here to look at bad string view."
2123
)
2224

25+
def _makeStringName(self, typedef: str, char_type: str):
26+
if self.getDebugInfo() == "pdb":
27+
return f"std::basic_string_view<{char_type}, std::char_traits<{char_type}>>"
28+
29+
return typedef
30+
2331
def do_test(self):
2432
"""Test that that file and class static variables display correctly."""
2533
self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
@@ -51,39 +59,47 @@ def cleanup():
5159
# Execute the cleanup function during test case tear down.
5260
self.addTearDownHook(cleanup)
5361

54-
self.expect_var_path("wempty", type="std::wstring_view", summary='L""')
62+
string_view_name = self._makeStringName("std::string_view", "char")
63+
wstring_view_name = self._makeStringName("std::wstring_view", "wchar_t")
64+
u16string_view_name = self._makeStringName("std::u16string_view", "char16_t")
65+
u32string_view_name = self._makeStringName("std::u32string_view", "char32_t")
66+
string_name = (
67+
"std::basic_string<char, std::char_traits<char>, std::allocator<char>>"
68+
if self.getDebugInfo() == "pdb"
69+
else "std::string"
70+
)
71+
72+
self.expect_var_path("wempty", type=wstring_view_name, summary='L""')
5573
self.expect_var_path(
56-
"s", type="std::wstring_view", summary='L"hello world! מזל טוב!"'
74+
"s", type=wstring_view_name, summary='L"hello world! מזל טוב!"'
5775
)
58-
self.expect_var_path("S", type="std::wstring_view", summary='L"!!!!"')
59-
self.expect_var_path("empty", type="std::string_view", summary='""')
60-
self.expect_var_path("q_source", type="std::string", summary='"hello world"')
61-
self.expect_var_path("q", type="std::string_view", summary='"hello world"')
76+
self.expect_var_path("S", type=wstring_view_name, summary='L"!!!!"')
77+
self.expect_var_path("empty", type=string_view_name, summary='""')
78+
self.expect_var_path("q_source", type=string_name, summary='"hello world"')
79+
self.expect_var_path("q", type=string_view_name, summary='"hello world"')
6280
self.expect_var_path(
6381
"Q",
64-
type="std::string_view",
82+
type=string_view_name,
6583
summary='"quite a long std::strin with lots of info inside it"',
6684
)
6785
self.expect_var_path(
68-
"IHaveEmbeddedZeros", type="std::string_view", summary='"a\\0b\\0c\\0d"'
86+
"IHaveEmbeddedZeros", type=string_view_name, summary='"a\\0b\\0c\\0d"'
6987
)
7088
self.expect_var_path(
7189
"IHaveEmbeddedZerosToo",
72-
type="std::wstring_view",
90+
type=wstring_view_name,
7391
summary='L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"',
7492
)
75-
self.expect_var_path("u16_string", type="std::u16string_view", summary='u"ß水氶"')
76-
self.expect_var_path("u16_empty", type="std::u16string_view", summary='u""')
77-
self.expect_var_path(
78-
"u32_string", type="std::u32string_view", summary='U"🍄🍅🍆🍌"'
79-
)
80-
self.expect_var_path("u32_empty", type="std::u32string_view", summary='U""')
93+
self.expect_var_path("u16_string", type=u16string_view_name, summary='u"ß水氶"')
94+
self.expect_var_path("u16_empty", type=u16string_view_name, summary='u""')
95+
self.expect_var_path("u32_string", type=u32string_view_name, summary='U"🍄🍅🍆🍌"')
96+
self.expect_var_path("u32_empty", type=u32string_view_name, summary='U""')
8197

8298
# GetSummary returns None so can't be checked by expect_var_path, so we
8399
# use the str representation instead
84100
null_obj = self.frame().GetValueForVariablePath("null_str")
85101
self.assertEqual(null_obj.GetSummary(), "Summary Unavailable")
86-
self.assertEqual(str(null_obj), "(std::string_view *) null_str = nullptr")
102+
self.assertEqual(str(null_obj), f"({string_view_name} *) null_str = nullptr")
87103

88104
self.runCmd("n")
89105

@@ -108,37 +124,35 @@ def cleanup():
108124

109125
self.expect_expr(
110126
"s",
111-
result_type="std::wstring_view",
127+
result_type=wstring_view_name,
112128
result_summary='L"hello world! מזל טוב!"',
113129
)
114130

115-
self.expect_var_path("wempty", type="std::wstring_view", summary='L""')
131+
self.expect_var_path("wempty", type=wstring_view_name, summary='L""')
116132
self.expect_var_path(
117-
"s", type="std::wstring_view", summary='L"hello world! מזל טוב!"'
133+
"s", type=wstring_view_name, summary='L"hello world! מזל טוב!"'
118134
)
119-
self.expect_var_path("S", type="std::wstring_view", summary='L"!!!!"')
120-
self.expect_var_path("empty", type="std::string_view", summary='""')
121-
self.expect_var_path("q_source", type="std::string", summary='"Hello world"')
122-
self.expect_var_path("q", type="std::string_view", summary='"Hello world"')
135+
self.expect_var_path("S", type=wstring_view_name, summary='L"!!!!"')
136+
self.expect_var_path("empty", type=string_view_name, summary='""')
137+
self.expect_var_path("q_source", type=string_name, summary='"Hello world"')
138+
self.expect_var_path("q", type=string_view_name, summary='"Hello world"')
123139
self.expect_var_path(
124140
"Q",
125-
type="std::string_view",
141+
type=string_view_name,
126142
summary='"quite a long std::strin with lots of info inside it"',
127143
)
128144
self.expect_var_path(
129-
"IHaveEmbeddedZeros", type="std::string_view", summary='"a\\0b\\0c\\0d"'
145+
"IHaveEmbeddedZeros", type=string_view_name, summary='"a\\0b\\0c\\0d"'
130146
)
131147
self.expect_var_path(
132148
"IHaveEmbeddedZerosToo",
133-
type="std::wstring_view",
149+
type=wstring_view_name,
134150
summary='L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"',
135151
)
136-
self.expect_var_path("u16_string", type="std::u16string_view", summary='u"ß水氶"')
137-
self.expect_var_path("u16_empty", type="std::u16string_view", summary='u""')
138-
self.expect_var_path(
139-
"u32_string", type="std::u32string_view", summary='U"🍄🍅🍆🍌"'
140-
)
141-
self.expect_var_path("u32_empty", type="std::u32string_view", summary='U""')
152+
self.expect_var_path("u16_string", type=u16string_view_name, summary='u"ß水氶"')
153+
self.expect_var_path("u16_empty", type=u16string_view_name, summary='u""')
154+
self.expect_var_path("u32_string", type=u32string_view_name, summary='U"🍄🍅🍆🍌"')
155+
self.expect_var_path("u32_empty", type=u32string_view_name, summary='U""')
142156

143157
self.runCmd("cont")
144158
self.expect(

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string/TestDataFormatterStdU8String.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,26 @@
1111

1212

1313
class StdU8StringDataFormatterTestCase(TestBase):
14+
TEST_WITH_PDB_DEBUG_INFO = True
15+
1416
def do_test(self):
1517
lldbutil.run_to_source_breakpoint(
1618
self, "Set break point at this line.", lldb.SBFileSpec("main.cpp")
1719
)
1820

21+
string_name = (
22+
"std::basic_string<char8_t, std::char_traits<char8_t>, std::allocator<char8_t>>"
23+
if self.getDebugInfo() == "pdb"
24+
else "std::u8string"
25+
)
26+
1927
self.expect(
2028
"frame variable",
2129
substrs=[
22-
'(std::u8string) u8_string_small = u8"🍄"',
23-
'(std::u8string) u8_string = u8"❤️👍📄📁😃🧑‍🌾"',
24-
'(std::u8string) u8_empty = u8""',
25-
'(std::u8string) u8_text = u8"ABCd"',
30+
f'({string_name}) u8_string_small = u8"🍄"',
31+
f'({string_name}) u8_string = u8"❤️👍📄📁😃🧑‍🌾"',
32+
f'({string_name}) u8_empty = u8""',
33+
f'({string_name}) u8_text = u8"ABCd"',
2634
],
2735
)
2836

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/TestDataFormatterStdU8StringView.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,26 @@
1111

1212

1313
class StdU8StringViewDataFormatterTestCase(TestBase):
14+
TEST_WITH_PDB_DEBUG_INFO = True
15+
1416
def do_test(self):
1517
lldbutil.run_to_source_breakpoint(
1618
self, "Set break point at this line.", lldb.SBFileSpec("main.cpp")
1719
)
1820

21+
string_view_name = (
22+
"std::basic_string_view<char8_t, std::char_traits<char8_t>>"
23+
if self.getDebugInfo() == "pdb"
24+
else "std::u8string_view"
25+
)
26+
1927
self.expect(
2028
"frame variable",
2129
substrs=[
22-
'(std::u8string_view) u8_string_small = u8"🍄"',
23-
'(std::u8string_view) u8_string = u8"❤️👍📄📁😃🧑‍🌾"',
24-
'(std::u8string_view) u8_empty = u8""',
25-
'(std::u8string_view) u8_text = u8"ABCd"',
30+
f'({string_view_name}) u8_string_small = u8"🍄"',
31+
f'({string_view_name}) u8_string = u8"❤️👍📄📁😃🧑‍🌾"',
32+
f'({string_view_name}) u8_empty = u8""',
33+
f'({string_view_name}) u8_text = u8"ABCd"',
2634
],
2735
)
2836

0 commit comments

Comments
 (0)