Skip to content

Commit 1f28da6

Browse files
authored
[lldb][test] Combine libstdc++ and libc++ std::string tests into generic test (llvm#147355)
This combines the libc++ and libstdc++ test cases. The main difference was that the libstdcpp tests had additional tests for references/pointers to std::string. I moved those over. The libstdc++ formatters don't support `std::u16string`/`std::u32string` yet, so I extracted those into XFAILed test cases. There were also two test assertions that failed for libstdc++: 1. libstdc++ doesn't obey the capped/uncapped summary options 2. When a summary isn't available for a std::string, libc++ would print "Summary Unavailable", whereas libstdc++ just prints "((null))". This may be better suited for the STL-specific subdirectories, but left it here for now. I put those in separate XFAILed test-cases. Split out from llvm#146740
1 parent d9b208b commit 1f28da6

File tree

7 files changed

+232
-201
lines changed

7 files changed

+232
-201
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
11
CXX_SOURCES := main.cpp
22

3-
CFLAGS_EXTRAS := -O0
4-
USE_LIBSTDCPP := 1
5-
63
include Makefile.rules
Lines changed: 128 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,16 @@
1010
from lldbsuite.test import lldbutil
1111

1212

13-
class LibcxxStringDataFormatterTestCase(TestBase):
13+
class StdStringDataFormatterTestCase(TestBase):
1414
def setUp(self):
1515
# Call super's setUp().
1616
TestBase.setUp(self)
1717
# Find the line number to break at.
1818
self.main_spec = lldb.SBFileSpec("main.cpp")
1919
self.namespace = "std"
2020

21-
@add_test_categories(["libc++"])
22-
@expectedFailureAll(
23-
bugnumber="llvm.org/pr36109", debug_info="gmodules", triple=".*-android"
24-
)
25-
# Inline namespace is randomly ignored as Clang due to broken lookup inside
26-
# the std namespace.
27-
@expectedFailureAll(debug_info="gmodules")
28-
def test_with_run_command(self):
21+
def do_test(self):
2922
"""Test that that file and class static variables display correctly."""
30-
self.build()
31-
3223
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
3324
self, "Set break point at this line.", self.main_spec
3425
)
@@ -47,42 +38,13 @@ def cleanup():
4738

4839
ns = self.namespace
4940

50-
self.expect(
51-
"frame variable",
52-
substrs=[
53-
'(%s::wstring) wempty = L""' % ns,
54-
'(%s::wstring) s = L"hello world! מזל טוב!"' % ns,
55-
'(%s::wstring) S = L"!!!!"' % ns,
56-
"(const wchar_t *) mazeltov = 0x",
57-
'L"מזל טוב"',
58-
'(%s::string) empty = ""' % ns,
59-
'(%s::string) q = "hello world"' % ns,
60-
'(%s::string) Q = "quite a long std::strin with lots of info inside it"'
61-
% ns,
62-
'(%s::string) IHaveEmbeddedZeros = "a\\0b\\0c\\0d"' % ns,
63-
'(%s::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"'
64-
% ns,
65-
'(%s::u16string) u16_string = u"ß水氶"' % ns,
66-
'(%s::u16string) u16_empty = u""' % ns,
67-
'(%s::u32string) u32_string = U"🍄🍅🍆🍌"' % ns,
68-
'(%s::u32string) u32_empty = U""' % ns,
69-
"(%s::string *) null_str = nullptr" % ns,
70-
],
71-
)
41+
# Check 'S' pre-assignment.
42+
self.expect("frame variable S", substrs=['(%s::wstring) S = L"!!!!"' % ns])
7243

7344
thread.StepOver()
7445

7546
TheVeryLongOne = frame.FindVariable("TheVeryLongOne")
7647
summaryOptions = lldb.SBTypeSummaryOptions()
77-
summaryOptions.SetCapping(lldb.eTypeSummaryUncapped)
78-
uncappedSummaryStream = lldb.SBStream()
79-
TheVeryLongOne.GetSummary(uncappedSummaryStream, summaryOptions)
80-
uncappedSummary = uncappedSummaryStream.GetData()
81-
self.assertGreater(
82-
uncappedSummary.find("someText"),
83-
0,
84-
"uncappedSummary does not include the full string",
85-
)
8648
summaryOptions.SetCapping(lldb.eTypeSummaryCapped)
8749
cappedSummaryStream = lldb.SBStream()
8850
TheVeryLongOne.GetSummary(cappedSummaryStream, summaryOptions)
@@ -108,31 +70,145 @@ def cleanup():
10870
self.expect(
10971
"frame variable",
11072
substrs=[
73+
'(%s::wstring) wempty = L""' % ns,
74+
'(%s::wstring) s = L"hello world! מזל טוב!"' % ns,
11175
'(%s::wstring) S = L"!!!!!"' % ns,
11276
"(const wchar_t *) mazeltov = 0x",
11377
'L"מזל טוב"',
78+
'(%s::string) empty = ""' % ns,
11479
'(%s::string) q = "hello world"' % ns,
11580
'(%s::string) Q = "quite a long std::strin with lots of info inside it"'
11681
% ns,
82+
"(%s::string *) null_str = nullptr" % ns,
83+
],
84+
)
85+
86+
# Test references and pointers to std::string.
87+
var_rq = frame.FindVariable("rq")
88+
var_rQ = frame.FindVariable("rQ")
89+
var_pq = frame.FindVariable("pq")
90+
var_pQ = frame.FindVariable("pQ")
91+
92+
self.assertEqual(var_rq.GetSummary(), '"hello world"', "rq summary wrong")
93+
self.assertEqual(
94+
var_rQ.GetSummary(),
95+
'"quite a long std::strin with lots of info inside it"',
96+
"rQ summary wrong",
97+
)
98+
self.assertEqual(var_pq.GetSummary(), '"hello world"', "pq summary wrong")
99+
self.assertEqual(
100+
var_pQ.GetSummary(),
101+
'"quite a long std::strin with lots of info inside it"',
102+
"pQ summary wrong",
103+
)
104+
105+
@expectedFailureAll(
106+
bugnumber="llvm.org/pr36109", debug_info="gmodules", triple=".*-android"
107+
)
108+
# Inline namespace is randomly ignored as Clang due to broken lookup inside
109+
# the std namespace.
110+
@expectedFailureAll(debug_info="gmodules")
111+
@add_test_categories(["libc++"])
112+
def test_libcxx(self):
113+
self.build(dictionary={"USE_LIBCPP": 1})
114+
self.do_test()
115+
116+
@expectedFailureAll(
117+
bugnumber="llvm.org/pr36109", debug_info="gmodules", triple=".*-android"
118+
)
119+
# Inline namespace is randomly ignored as Clang due to broken lookup inside
120+
# the std namespace.
121+
@expectedFailureAll(debug_info="gmodules")
122+
@add_test_categories(["libstdcxx"])
123+
def test_libstdcxx(self):
124+
self.build(dictionary={"USE_LIBSTDCPP": 1})
125+
self.do_test()
126+
127+
def do_test_multibyte(self):
128+
lldbutil.run_to_source_breakpoint(
129+
self, "Set break point at this line.", self.main_spec
130+
)
131+
132+
ns = self.namespace
133+
134+
self.expect(
135+
"frame variable",
136+
substrs=[
117137
'(%s::string) IHaveEmbeddedZeros = "a\\0b\\0c\\0d"' % ns,
118138
'(%s::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"'
119139
% ns,
120140
'(%s::u16string) u16_string = u"ß水氶"' % ns,
141+
'(%s::u16string) u16_empty = u""' % ns,
121142
'(%s::u32string) u32_string = U"🍄🍅🍆🍌"' % ns,
122143
'(%s::u32string) u32_empty = U""' % ns,
123-
"(%s::string *) null_str = nullptr" % ns,
124144
],
125145
)
126146

127-
# Finally, make sure that if the string is not readable, we give an error:
128-
bkpt_2 = target.BreakpointCreateBySourceRegex(
129-
"Break here to look at bad string", self.main_spec
147+
@add_test_categories(["libc++"])
148+
def test_multibyte_libcxx(self):
149+
self.build(dictionary={"USE_LIBCPP": 1})
150+
self.do_test_multibyte()
151+
152+
@expectedFailureAll(
153+
bugnumber="libstdc++ formatters don't support UTF-16/UTF-32 strings yet."
154+
)
155+
@add_test_categories(["libstdcxx"])
156+
def test_multibyte_libstdcxx(self):
157+
self.build(dictionary={"USE_LIBSTDCPP": 1})
158+
self.do_test_multibyte()
159+
160+
def do_test_uncapped_summary(self):
161+
(_, _, thread, _) = lldbutil.run_to_source_breakpoint(
162+
self, "Set break point at this line.", self.main_spec
163+
)
164+
165+
TheVeryLongOne = thread.frames[0].FindVariable("TheVeryLongOne")
166+
summaryOptions = lldb.SBTypeSummaryOptions()
167+
summaryOptions.SetCapping(lldb.eTypeSummaryUncapped)
168+
uncappedSummaryStream = lldb.SBStream()
169+
TheVeryLongOne.GetSummary(uncappedSummaryStream, summaryOptions)
170+
uncappedSummary = uncappedSummaryStream.GetData()
171+
self.assertGreater(
172+
uncappedSummary.find("someText"),
173+
0,
174+
"uncappedSummary does not include the full string",
130175
)
131-
self.assertEqual(bkpt_2.GetNumLocations(), 1, "Got one location")
132-
threads = lldbutil.continue_to_breakpoint(process, bkpt_2)
133-
self.assertEqual(len(threads), 1, "Stopped at second breakpoint")
134-
frame = threads[0].frames[0]
135-
var = frame.FindVariable("in_str")
136-
self.assertTrue(var.GetError().Success(), "Made variable")
176+
177+
@add_test_categories(["libc++"])
178+
def test_uncapped_libcxx(self):
179+
self.build(dictionary={"USE_LIBCPP": 1})
180+
self.do_test_uncapped_summary()
181+
182+
@expectedFailureAll(
183+
bugnumber="libstdc++ std::string summary provider doesn't obey summary options."
184+
)
185+
@add_test_categories(["libstdcxx"])
186+
def test_uncapped_libstdcxx(self):
187+
self.build(dictionary={"USE_LIBSTDCPP": 1})
188+
self.do_test_uncapped_summary()
189+
190+
def do_test_summary_unavailable(self):
191+
"""
192+
Make sure that if the string is not readable, we give an error.
193+
"""
194+
(_, _, thread, _) = lldbutil.run_to_source_breakpoint(
195+
self, "Break here to look at bad string", self.main_spec
196+
)
197+
198+
var = thread.frames[0].FindVariable("in_str")
199+
self.assertTrue(var.GetError().Success(), "Found variable")
137200
summary = var.GetSummary()
138201
self.assertEqual(summary, "Summary Unavailable", "No summary for bad value")
202+
203+
@add_test_categories(["libc++"])
204+
def test_unavailable_summary_libcxx(self):
205+
self.build(dictionary={"USE_LIBCPP": 1})
206+
self.do_test_summary_unavailable()
207+
208+
@expectedFailureAll(
209+
bugnumber="libstdc++ std::string summary provider doesn't output a user-friendly message for invalid strings."
210+
)
211+
@add_test_categories(["libstdcxx"])
212+
def test_unavailable_summary_libstdcxx(self):
213+
self.build(dictionary={"USE_LIBSTDCPP": 1})
214+
self.do_test_summary_unavailable()
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#include <stdint.h>
2+
#include <string>
3+
4+
size_t touch_string(std::string &in_str) {
5+
return in_str.size(); // Break here to look at bad string
6+
}
7+
8+
int main() {
9+
std::wstring wempty(L"");
10+
std::wstring s(L"hello world! מזל טוב!");
11+
std::wstring S(L"!!!!");
12+
const wchar_t *mazeltov = L"מזל טוב";
13+
std::string empty("");
14+
std::string q("hello world");
15+
std::string Q("quite a long std::strin with lots of info inside it");
16+
std::string TheVeryLongOne(
17+
"123456789012345678901234567890123456789012345678901234567890123456789012"
18+
"345678901234567890123456789012345678901234567890123456789012345678901234"
19+
"567890123456789012345678901234567890123456789012345678901234567890123456"
20+
"789012345678901234567890123456789012345678901234567890123456789012345678"
21+
"901234567890123456789012345678901234567890123456789012345678901234567890"
22+
"123456789012345678901234567890123456789012345678901234567890123456789012"
23+
"345678901234567890123456789012345678901234567890123456789012345678901234"
24+
"567890123456789012345678901234567890123456789012345678901234567890123456"
25+
"789012345678901234567890123456789012345678901234567890123456789012345678"
26+
"901234567890123456789012345678901234567890123456789012345678901234567890"
27+
"123456789012345678901234567890123456789012345678901234567890123456789012"
28+
"345678901234567890123456789012345678901234567890123456789012345678901234"
29+
"567890123456789012345678901234567890123456789012345678901234567890123456"
30+
"789012345678901234567890123456789012345678901234567890123456789012345678"
31+
"901234567890123456789012345678901234567890123456789012345678901234567890"
32+
"123456789012345678901234567890123456789012345678901234567890123456789012"
33+
"345678901234567890123456789012345678901234567890123456789012345678901234"
34+
"567890123456789012345678901234567890123456789012345678901234567890123456"
35+
"789012345678901234567890123456789012345678901234567890123456789012345678"
36+
"901234567890123456789012345678901234567890123456789012345678901234567890"
37+
"123456789012345678901234567890123456789012345678901234567890123456789012"
38+
"345678901234567890123456789012345678901234567890123456789012345678901234"
39+
"567890123456789012345678901234567890123456789012345678901234567890123456"
40+
"789012345678901234567890123456789012345678901234567890123456789012345678"
41+
"901234567890123456789012345678901234567890123456789012345678901234567890"
42+
"123456789012345678901234567890123456789012345678901234567890123456789012"
43+
"345678901234567890123456789012345678901234567890123456789012345678901234"
44+
"567890123456789012345678901234567890123456789012345678901234567890123456"
45+
"789012345678901234567890123456789012345678901234567890123456789012345678"
46+
"901234567890123456789012345678901234567890123456789012345678901234567890"
47+
"123456789012345678901234567890123456789012345678901234567890123456789012"
48+
"345678901234567890123456789012345678901234567890123456789012345678901234"
49+
"567890123456789012345678901234567890123456789012345678901234567890123456"
50+
"789012345678901234567890123456789012345678901234567890123456789012345678"
51+
"9012345678901234567890123456789012345678901234567890someText123456789012"
52+
"345678901234567890123456789012345678901234567890123456789012345678901234"
53+
"567890123456789012345678901234567890123456789012345678901234567890123456"
54+
"789012345678901234567890123456789012345678901234567890123456789012345678"
55+
"901234567890123456789012345678901234567890123456789012345678901234567890"
56+
"123456789012345678901234567890123456789012345678901234567890123456789012"
57+
"345678901234567890123456789012345678901234567890123456789012345678901234"
58+
"567890123456789012345678901234567890123456789012345678901234567890123456"
59+
"789012345678901234567890123456789012345678901234567890123456789012345678"
60+
"901234567890123456789012345678901234567890123456789012345678901234567890"
61+
"123456789012345678901234567890123456789012345678901234567890123456789012"
62+
"345678901234567890123456789012345678901234567890123456789012345678901234"
63+
"567890123456789012345678901234567890123456789012345678901234567890123456"
64+
"789012345678901234567890123456789012345678901234567890123456789012345678"
65+
"901234567890123456789012345678901234567890123456789012345678901234567890"
66+
"123456789012345678901234567890123456789012345678901234567890123456789012"
67+
"345678901234567890123456789012345678901234567890123456789012345678901234"
68+
"567890123456789012345678901234567890123456789012345678901234567890123456"
69+
"789012345678901234567890123456789012345678901234567890123456789012345678"
70+
"901234567890123456789012345678901234567890123456789012345678901234567890"
71+
"123456789012345678901234567890123456789012345678901234567890123456789012"
72+
"345678901234567890123456789012345678901234567890123456789012345678901234"
73+
"567890123456789012345678901234567890123456789012345678901234567890123456"
74+
"789012345678901234567890123456789012345678901234567890123456789012345678"
75+
"901234567890123456789012345678901234567890123456789012345678901234567890"
76+
"123456789012345678901234567890123456789012345678901234567890123456789012"
77+
"345678901234567890123456789012345678901234567890123456789012345678901234"
78+
"567890123456789012345678901234567890123456789012345678901234567890123456"
79+
"789012345678901234567890123456789012345678901234567890123456789012345678"
80+
"901234567890123456789012345678901234567890123456789012345678901234567890"
81+
"123456789012345678901234567890123456789012345678901234567890123456789012"
82+
"345678901234567890123456789012345678901234567890123456789012345678901234"
83+
"567890123456789012345678901234567890123456789012345678901234567890123456"
84+
"789012345678901234567890123456789012345678901234567890123456789012345678"
85+
"901234567890123456789012345678901234567890123456789012345678901234567890"
86+
"1234567890123456789012345678901234567890");
87+
std::string IHaveEmbeddedZeros("a\0b\0c\0d", 7);
88+
std::wstring IHaveEmbeddedZerosToo(
89+
L"hello world!\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監", 38);
90+
std::u16string u16_string(u"ß水氶");
91+
std::u16string u16_empty(u"");
92+
std::u32string u32_string(U"🍄🍅🍆🍌");
93+
std::u32string u32_empty(U"");
94+
std::string *null_str = nullptr;
95+
auto &rq = q;
96+
auto &rQ = Q;
97+
std::string *pq = &q;
98+
std::string *pQ = &Q;
99+
100+
S.assign(L"!!!!!"); // Set break point at this line.
101+
std::string *not_a_string = (std::string *)0x0;
102+
touch_string(*not_a_string);
103+
return 0;
104+
}

lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)