1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // REQUIRES: host-has-gdb-with-python
10 // REQUIRES: locale.en_US.UTF-8
11 // UNSUPPORTED: no-localization
12 // UNSUPPORTED: c++03
13
14 // TODO: Investigate these failures which break the CI.
15 // UNSUPPORTED: clang-16, clang-17, clang-18, clang-19
16
17 // TODO: Investigate this failure on GCC 13 (in Ubuntu Jammy)
18 // UNSUPPORTED: gcc-13
19
20 // The Android libc++ tests are run on a non-Android host, connected to an
21 // Android device over adb. gdb needs special support to make this work (e.g.
22 // gdbclient.py, ndk-gdb.py, gdbserver), and the Android organization doesn't
23 // support gdb anymore, favoring lldb instead.
24 // UNSUPPORTED: android
25
26 // RUN: %{cxx} %{flags} %s -o %t.exe %{compile_flags} -g %{link_flags}
27 // Ensure locale-independence for unicode tests.
28 // RUN: env LANG=en_US.UTF-8 %{gdb} -nx -batch -iex "set autoload off" -ex "source %S/../../../utils/gdb/libcxx/printers.py" -ex "python register_libcxx_printer_loader()" -ex "source %S/gdb_pretty_printer_test.py" %t.exe
29
30 #include <bitset>
31 #include <deque>
32 #include <list>
33 #include <map>
34 #include <memory>
35 #include <queue>
36 #include <set>
37 #include <sstream>
38 #include <stack>
39 #include <string>
40 #include <tuple>
41 #include <unordered_map>
42 #include <unordered_set>
43
44 #include "test_macros.h"
45
46 // To write a pretty-printer test:
47 //
48 // 1. Declare a variable of the type you want to test
49 //
50 // 2. Set its value to something which will test the pretty printer in an
51 // interesting way.
52 //
53 // 3. Call ComparePrettyPrintToChars with that variable, and a "const char*"
54 // value to compare to the printer's output.
55 //
56 // Or
57 //
58 // Call ComparePrettyPrintToRegex with that variable, and a "const char*"
59 // *python* regular expression to match against the printer's output.
60 // The set of special characters in a Python regular expression overlaps
61 // with a lot of things the pretty printers print--brackets, for
62 // example--so take care to escape appropriately.
63 //
64 // Alternatively, construct a string that gdb can parse as an expression,
65 // so that printing the value of the expression will test the pretty printer
66 // in an interesting way. Then, call CompareExpressionPrettyPrintToChars or
67 // CompareExpressionPrettyPrintToRegex to compare the printer's output.
68
69 // Avoids setting a breakpoint in every-single instantiation of
70 // ComparePrettyPrintTo*. Also, make sure neither it, nor the
71 // variables we need present in the Compare functions are optimized
72 // away.
73 #ifdef TEST_COMPILER_GCC
74 #define OPT_NONE __attribute__((noinline))
75 #else
76 #define OPT_NONE __attribute__((optnone))
77 #endif
78 void StopForDebugger(void *, void *) OPT_NONE;
StopForDebugger(void *,void *)79 void StopForDebugger(void *, void *) {}
80
81
82 // Prevents the compiler optimizing away the parameter in the caller function.
83 template <typename Type>
84 void MarkAsLive(Type &&) OPT_NONE;
85 template <typename Type>
MarkAsLive(Type &&)86 void MarkAsLive(Type &&) {}
87
88 // In all of the Compare(Expression)PrettyPrintTo(Regex/Chars) functions below,
89 // the python script sets a breakpoint just before the call to StopForDebugger,
90 // compares the result to the expectation.
91 //
92 // The expectation is a literal string to be matched exactly in
93 // *PrettyPrintToChars functions, and is a python regular expression in
94 // *PrettyPrintToRegex functions.
95 //
96 // In ComparePrettyPrint* functions, the value is a variable of any type. In
97 // CompareExpressionPrettyPrint functions, the value is a string expression that
98 // gdb will parse and print the result.
99 //
100 // The python script will print either "PASS", or a detailed failure explanation
101 // along with the line that has invoke the function. The testing will continue
102 // in either case.
103
ComparePrettyPrintToChars(TypeToPrint value,const char * expectation)104 template <typename TypeToPrint> void ComparePrettyPrintToChars(
105 TypeToPrint value,
106 const char *expectation) {
107 MarkAsLive(value);
108 StopForDebugger(&value, &expectation);
109 }
110
ComparePrettyPrintToRegex(TypeToPrint value,const char * expectation)111 template <typename TypeToPrint> void ComparePrettyPrintToRegex(
112 TypeToPrint value,
113 const char *expectation) {
114 MarkAsLive(value);
115 StopForDebugger(&value, &expectation);
116 }
117
CompareExpressionPrettyPrintToChars(std::string value,const char * expectation)118 void CompareExpressionPrettyPrintToChars(
119 std::string value,
120 const char *expectation) {
121 MarkAsLive(value);
122 StopForDebugger(&value, &expectation);
123 }
124
CompareExpressionPrettyPrintToRegex(std::string value,const char * expectation)125 void CompareExpressionPrettyPrintToRegex(
126 std::string value,
127 const char *expectation) {
128 MarkAsLive(value);
129 StopForDebugger(&value, &expectation);
130 }
131
132 namespace example {
133 struct example_struct {
134 int a = 0;
135 int arr[1000];
136 };
137 }
138
139 // If enabled, the self test will "fail"--because we want to be sure it properly
140 // diagnoses tests that *should* fail. Evaluate the output by hand.
framework_self_test()141 void framework_self_test() {
142 #ifdef FRAMEWORK_SELF_TEST
143 // Use the most simple data structure we can.
144 const char a = 'a';
145
146 // Tests that should pass
147 ComparePrettyPrintToChars(a, "97 'a'");
148 ComparePrettyPrintToRegex(a, ".*");
149
150 // Tests that should fail.
151 ComparePrettyPrintToChars(a, "b");
152 ComparePrettyPrintToRegex(a, "b");
153 #endif
154 }
155
156 // A simple pass-through allocator to check that we handle CompressedPair
157 // correctly.
158 template <typename T> class UncompressibleAllocator : public std::allocator<T> {
159 public:
160 char X;
161 };
162
string_test()163 void string_test() {
164 std::string short_string("kdjflskdjf");
165 // The display_hint "string" adds quotes the printed result.
166 ComparePrettyPrintToChars(short_string, "\"kdjflskdjf\"");
167
168 std::basic_string<char, std::char_traits<char>, UncompressibleAllocator<char>>
169 long_string("mehmet bizim dostumuz agzi kirik testimiz");
170 ComparePrettyPrintToChars(long_string,
171 "\"mehmet bizim dostumuz agzi kirik testimiz\"");
172 }
173
174 namespace a_namespace {
175 // To test name-lookup in the presence of using inside a namespace. Inside this
176 // namespace, unqualified string_view variables will appear in the debug info as
177 // "a_namespace::string_view, rather than "std::string_view".
178 //
179 // There is nothing special here about string_view; it's just the data structure
180 // where lookup with using inside a namespace wasn't always working.
181
182 using string_view = std::string_view;
183
string_view_test()184 void string_view_test() {
185 std::string_view i_am_empty;
186 ComparePrettyPrintToChars(i_am_empty, "\"\"");
187
188 std::string source_string("to be or not to be");
189 std::string_view to_be(source_string);
190 ComparePrettyPrintToChars(to_be, "\"to be or not to be\"");
191
192 const char char_arr[] = "what a wonderful world";
193 std::string_view wonderful(&char_arr[7], 9);
194 ComparePrettyPrintToChars(wonderful, "\"wonderful\"");
195
196 const char char_arr1[] = "namespace_stringview";
197 string_view namespace_stringview(&char_arr1[10], 10);
198 ComparePrettyPrintToChars(namespace_stringview, "\"stringview\"");
199 }
200 }
201
u16string_test()202 void u16string_test() {
203 std::u16string test0 = u"Hello World";
204 ComparePrettyPrintToChars(test0, "u\"Hello World\"");
205 std::u16string test1 = u"\U00010196\u20AC\u00A3\u0024";
206 ComparePrettyPrintToChars(test1, "u\"\U00010196\u20AC\u00A3\u0024\"");
207 std::u16string test2 = u"\u0024\u0025\u0026\u0027";
208 ComparePrettyPrintToChars(test2, "u\"\u0024\u0025\u0026\u0027\"");
209 std::u16string test3 = u"mehmet bizim dostumuz agzi kirik testimiz";
210 ComparePrettyPrintToChars(test3,
211 ("u\"mehmet bizim dostumuz agzi kirik testimiz\""));
212 }
213
u32string_test()214 void u32string_test() {
215 std::u32string test0 = U"Hello World";
216 ComparePrettyPrintToChars(test0, "U\"Hello World\"");
217 std::u32string test1 =
218 U"\U0001d552\U0001d553\U0001d554\U0001d555\U0001d556\U0001d557";
219 ComparePrettyPrintToChars(
220 test1,
221 ("U\"\U0001d552\U0001d553\U0001d554\U0001d555\U0001d556\U0001d557\""));
222 std::u32string test2 = U"\U00004f60\U0000597d";
223 ComparePrettyPrintToChars(test2, ("U\"\U00004f60\U0000597d\""));
224 std::u32string test3 = U"mehmet bizim dostumuz agzi kirik testimiz";
225 ComparePrettyPrintToChars(test3, ("U\"mehmet bizim dostumuz agzi kirik testimiz\""));
226 }
227
tuple_test()228 void tuple_test() {
229 std::tuple<int, int, int> test0(2, 3, 4);
230 ComparePrettyPrintToChars(
231 test0,
232 "std::tuple containing = {[1] = 2, [2] = 3, [3] = 4}");
233
234 std::tuple<> test1;
235 ComparePrettyPrintToChars(
236 test1,
237 "empty std::tuple");
238 }
239
unique_ptr_test()240 void unique_ptr_test() {
241 std::unique_ptr<std::string> matilda(new std::string("Matilda"));
242 ComparePrettyPrintToRegex(
243 std::move(matilda),
244 R"(std::unique_ptr<std::string> containing = {__ptr_ = 0x[a-f0-9]+})");
245 std::unique_ptr<int> forty_two(new int(42));
246 ComparePrettyPrintToRegex(std::move(forty_two),
247 R"(std::unique_ptr<int> containing = {__ptr_ = 0x[a-f0-9]+})");
248
249 std::unique_ptr<int> this_is_null;
250 ComparePrettyPrintToChars(std::move(this_is_null),
251 R"(std::unique_ptr is nullptr)");
252 }
253
bitset_test()254 void bitset_test() {
255 std::bitset<258> i_am_empty(0);
256 ComparePrettyPrintToRegex(i_am_empty, "std::bitset<258(u|ul)?>");
257
258 std::bitset<0> very_empty;
259 ComparePrettyPrintToRegex(very_empty, "std::bitset<0(u|ul)?>");
260
261 std::bitset<15> b_000001111111100(1020);
262 ComparePrettyPrintToRegex(b_000001111111100,
263 R"(std::bitset<15(u|ul)?> = {\[2\] = 1, \[3\] = 1, \[4\] = 1, \[5\] = 1, \[6\] = 1, )"
264 R"(\[7\] = 1, \[8\] = 1, \[9\] = 1})");
265
266 std::bitset<258> b_0_129_132(0);
267 b_0_129_132[0] = true;
268 b_0_129_132[129] = true;
269 b_0_129_132[132] = true;
270 ComparePrettyPrintToRegex(b_0_129_132,
271 R"(std::bitset<258(u|ul)?> = {\[0\] = 1, \[129\] = 1, \[132\] = 1})");
272 }
273
list_test()274 void list_test() {
275 std::list<int> i_am_empty{};
276 ComparePrettyPrintToChars(i_am_empty, "std::list is empty");
277
278 std::list<int> one_two_three {1, 2, 3};
279 ComparePrettyPrintToChars(one_two_three,
280 "std::list with 3 elements = {1, 2, 3}");
281
282 std::list<std::string> colors {"red", "blue", "green"};
283 ComparePrettyPrintToChars(colors,
284 R"(std::list with 3 elements = {"red", "blue", "green"})");
285 }
286
deque_test()287 void deque_test() {
288 std::deque<int> i_am_empty{};
289 ComparePrettyPrintToChars(i_am_empty, "std::deque is empty");
290
291 std::deque<int> one_two_three {1, 2, 3};
292 ComparePrettyPrintToChars(one_two_three,
293 "std::deque with 3 elements = {1, 2, 3}");
294
295 std::deque<example::example_struct> bfg;
296 for (int i = 0; i < 10; ++i) {
297 example::example_struct current;
298 current.a = i;
299 bfg.push_back(current);
300 }
301 for (int i = 0; i < 3; ++i) {
302 bfg.pop_front();
303 }
304 for (int i = 0; i < 3; ++i) {
305 bfg.pop_back();
306 }
307 ComparePrettyPrintToRegex(bfg,
308 "std::deque with 4 elements = {"
309 "{a = 3, arr = {[^}]+}}, "
310 "{a = 4, arr = {[^}]+}}, "
311 "{a = 5, arr = {[^}]+}}, "
312 "{a = 6, arr = {[^}]+}}}");
313 }
314
map_test()315 void map_test() {
316 std::map<int, int> i_am_empty{};
317 ComparePrettyPrintToChars(i_am_empty, "std::map is empty");
318
319 std::map<int, std::string> one_two_three;
320 one_two_three.insert({1, "one"});
321 one_two_three.insert({2, "two"});
322 one_two_three.insert({3, "three"});
323 ComparePrettyPrintToChars(one_two_three,
324 "std::map with 3 elements = "
325 R"({[1] = "one", [2] = "two", [3] = "three"})");
326
327 std::map<int, example::example_struct> bfg;
328 for (int i = 0; i < 4; ++i) {
329 example::example_struct current;
330 current.a = 17 * i;
331 bfg.insert({i, current});
332 }
333 ComparePrettyPrintToRegex(bfg,
334 R"(std::map with 4 elements = {)"
335 R"(\[0\] = {a = 0, arr = {[^}]+}}, )"
336 R"(\[1\] = {a = 17, arr = {[^}]+}}, )"
337 R"(\[2\] = {a = 34, arr = {[^}]+}}, )"
338 R"(\[3\] = {a = 51, arr = {[^}]+}}})");
339 }
340
multimap_test()341 void multimap_test() {
342 std::multimap<int, int> i_am_empty{};
343 ComparePrettyPrintToChars(i_am_empty, "std::multimap is empty");
344
345 std::multimap<int, std::string> one_two_three;
346 one_two_three.insert({1, "one"});
347 one_two_three.insert({3, "three"});
348 one_two_three.insert({1, "ein"});
349 one_two_three.insert({2, "two"});
350 one_two_three.insert({2, "zwei"});
351 one_two_three.insert({1, "bir"});
352
353 ComparePrettyPrintToChars(one_two_three,
354 "std::multimap with 6 elements = "
355 R"({[1] = "one", [1] = "ein", [1] = "bir", )"
356 R"([2] = "two", [2] = "zwei", [3] = "three"})");
357 }
358
queue_test()359 void queue_test() {
360 std::queue<int> i_am_empty;
361 ComparePrettyPrintToChars(i_am_empty,
362 "std::queue wrapping = {std::deque is empty}");
363
364 std::queue<int> one_two_three(std::deque<int>{1, 2, 3});
365 ComparePrettyPrintToChars(one_two_three,
366 "std::queue wrapping = {"
367 "std::deque with 3 elements = {1, 2, 3}}");
368 }
369
priority_queue_test()370 void priority_queue_test() {
371 std::priority_queue<int> i_am_empty;
372 ComparePrettyPrintToChars(i_am_empty,
373 "std::priority_queue wrapping = {std::vector of length 0, capacity 0}");
374
375 std::priority_queue<int> one_two_three;
376 one_two_three.push(11111);
377 one_two_three.push(22222);
378 one_two_three.push(33333);
379
380 ComparePrettyPrintToRegex(one_two_three,
381 R"(std::priority_queue wrapping = )"
382 R"({std::vector of length 3, capacity 3 = {33333)");
383
384 ComparePrettyPrintToRegex(one_two_three, ".*11111.*");
385 ComparePrettyPrintToRegex(one_two_three, ".*22222.*");
386 }
387
set_test()388 void set_test() {
389 std::set<int> i_am_empty;
390 ComparePrettyPrintToChars(i_am_empty, "std::set is empty");
391
392 std::set<int> one_two_three {3, 1, 2};
393 ComparePrettyPrintToChars(one_two_three,
394 "std::set with 3 elements = {1, 2, 3}");
395
396 std::set<std::pair<int, int>> prime_pairs {
397 std::make_pair(3, 5), std::make_pair(5, 7), std::make_pair(3, 5)};
398
399 ComparePrettyPrintToChars(prime_pairs,
400 "std::set with 2 elements = {"
401 "{first = 3, second = 5}, {first = 5, second = 7}}");
402
403 using using_set = std::set<int>;
404 using_set other{1, 2, 3};
405 ComparePrettyPrintToChars(other, "std::set with 3 elements = {1, 2, 3}");
406 }
407
stack_test()408 void stack_test() {
409 std::stack<int> test0;
410 ComparePrettyPrintToChars(test0,
411 "std::stack wrapping = {std::deque is empty}");
412 test0.push(5);
413 test0.push(6);
414 ComparePrettyPrintToChars(
415 test0, "std::stack wrapping = {std::deque with 2 elements = {5, 6}}");
416 std::stack<bool> test1;
417 test1.push(true);
418 test1.push(false);
419 ComparePrettyPrintToChars(
420 test1,
421 "std::stack wrapping = {std::deque with 2 elements = {true, false}}");
422
423 std::stack<std::string> test2;
424 test2.push("Hello");
425 test2.push("World");
426 ComparePrettyPrintToChars(test2,
427 "std::stack wrapping = {std::deque with 2 elements "
428 "= {\"Hello\", \"World\"}}");
429 }
430
multiset_test()431 void multiset_test() {
432 std::multiset<int> i_am_empty;
433 ComparePrettyPrintToChars(i_am_empty, "std::multiset is empty");
434
435 std::multiset<std::string> one_two_three {"1:one", "2:two", "3:three", "1:one"};
436 ComparePrettyPrintToChars(one_two_three,
437 "std::multiset with 4 elements = {"
438 R"("1:one", "1:one", "2:two", "3:three"})");
439 }
440
vector_test()441 void vector_test() {
442 std::vector<bool> test0 = {true, false};
443 ComparePrettyPrintToRegex(test0,
444 "std::vector<bool> of "
445 "length 2, capacity (32|64) = {1, 0}");
446 for (int i = 0; i < 31; ++i) {
447 test0.push_back(true);
448 test0.push_back(false);
449 }
450 ComparePrettyPrintToRegex(
451 test0,
452 "std::vector<bool> of length 64, "
453 "capacity 64 = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, "
454 "0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, "
455 "0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}");
456 test0.push_back(true);
457 ComparePrettyPrintToRegex(
458 test0,
459 "std::vector<bool> of length 65, "
460 "capacity (96|128) = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, "
461 "0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, "
462 "0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}");
463
464 std::vector<int> test1;
465 ComparePrettyPrintToChars(test1, "std::vector of length 0, capacity 0");
466
467 std::vector<int> test2 = {5, 6, 7};
468 ComparePrettyPrintToChars(test2,
469 "std::vector of length "
470 "3, capacity 3 = {5, 6, 7}");
471
472 std::vector<int, UncompressibleAllocator<int>> test3({7, 8});
473 ComparePrettyPrintToChars(std::move(test3),
474 "std::vector of length "
475 "2, capacity 2 = {7, 8}");
476 }
477
set_iterator_test()478 void set_iterator_test() {
479 std::set<int> one_two_three {1111, 2222, 3333};
480 auto it = one_two_three.find(2222);
481 MarkAsLive(it);
482 CompareExpressionPrettyPrintToRegex("it",
483 R"(std::__tree_const_iterator = {\[0x[a-f0-9]+\] = 2222})");
484
485 auto not_found = one_two_three.find(1234);
486 MarkAsLive(not_found);
487 // Because the end_node is not easily detected, just be sure it doesn't crash.
488 CompareExpressionPrettyPrintToRegex("not_found",
489 R"(std::__tree_const_iterator ( = {\[0x[a-f0-9]+\] = .*}|<error reading variable:.*>))");
490 }
491
map_iterator_test()492 void map_iterator_test() {
493 std::map<int, std::string> one_two_three;
494 one_two_three.insert({1, "one"});
495 one_two_three.insert({2, "two"});
496 one_two_three.insert({3, "three"});
497 auto it = one_two_three.begin();
498 MarkAsLive(it);
499 CompareExpressionPrettyPrintToRegex("it",
500 R"(std::__map_iterator = )"
501 R"({\[0x[a-f0-9]+\] = {first = 1, second = "one"}})");
502
503 auto not_found = one_two_three.find(7);
504 MarkAsLive(not_found);
505 // Because the end_node is not easily detected, just be sure it doesn't crash.
506 CompareExpressionPrettyPrintToRegex(
507 "not_found", R"(std::__map_iterator ( = {\[0x[a-f0-9]+\] = .*}|<error reading variable:.*>))");
508 }
509
unordered_set_test()510 void unordered_set_test() {
511 std::unordered_set<int> i_am_empty;
512 ComparePrettyPrintToChars(i_am_empty, "std::unordered_set is empty");
513
514 std::unordered_set<int> numbers {12345, 67890, 222333, 12345};
515 numbers.erase(numbers.find(222333));
516 ComparePrettyPrintToRegex(numbers, "std::unordered_set with 2 elements = ");
517 ComparePrettyPrintToRegex(numbers, ".*12345.*");
518 ComparePrettyPrintToRegex(numbers, ".*67890.*");
519
520 std::unordered_set<std::string> colors {"red", "blue", "green"};
521 ComparePrettyPrintToRegex(colors, "std::unordered_set with 3 elements = ");
522 ComparePrettyPrintToRegex(colors, R"(.*"red".*)");
523 ComparePrettyPrintToRegex(colors, R"(.*"blue".*)");
524 ComparePrettyPrintToRegex(colors, R"(.*"green".*)");
525 }
526
unordered_multiset_test()527 void unordered_multiset_test() {
528 std::unordered_multiset<int> i_am_empty;
529 ComparePrettyPrintToChars(i_am_empty, "std::unordered_multiset is empty");
530
531 std::unordered_multiset<int> numbers {12345, 67890, 222333, 12345};
532 ComparePrettyPrintToRegex(numbers,
533 "std::unordered_multiset with 4 elements = ");
534 ComparePrettyPrintToRegex(numbers, ".*12345.*12345.*");
535 ComparePrettyPrintToRegex(numbers, ".*67890.*");
536 ComparePrettyPrintToRegex(numbers, ".*222333.*");
537
538 std::unordered_multiset<std::string> colors {"red", "blue", "green", "red"};
539 ComparePrettyPrintToRegex(colors,
540 "std::unordered_multiset with 4 elements = ");
541 ComparePrettyPrintToRegex(colors, R"(.*"red".*"red".*)");
542 ComparePrettyPrintToRegex(colors, R"(.*"blue".*)");
543 ComparePrettyPrintToRegex(colors, R"(.*"green".*)");
544 }
545
unordered_map_test()546 void unordered_map_test() {
547 std::unordered_map<int, int> i_am_empty;
548 ComparePrettyPrintToChars(i_am_empty, "std::unordered_map is empty");
549
550 std::unordered_map<int, std::string> one_two_three;
551 one_two_three.insert({1, "one"});
552 one_two_three.insert({2, "two"});
553 one_two_three.insert({3, "three"});
554 ComparePrettyPrintToRegex(one_two_three,
555 "std::unordered_map with 3 elements = ");
556 ComparePrettyPrintToRegex(one_two_three, R"(.*\[1\] = "one".*)");
557 ComparePrettyPrintToRegex(one_two_three, R"(.*\[2\] = "two".*)");
558 ComparePrettyPrintToRegex(one_two_three, R"(.*\[3\] = "three".*)");
559 }
560
unordered_multimap_test()561 void unordered_multimap_test() {
562 std::unordered_multimap<int, int> i_am_empty;
563 ComparePrettyPrintToChars(i_am_empty, "std::unordered_multimap is empty");
564
565 std::unordered_multimap<int, std::string> one_two_three;
566 one_two_three.insert({1, "one"});
567 one_two_three.insert({2, "two"});
568 one_two_three.insert({3, "three"});
569 one_two_three.insert({2, "two"});
570 ComparePrettyPrintToRegex(one_two_three,
571 "std::unordered_multimap with 4 elements = ");
572 ComparePrettyPrintToRegex(one_two_three, R"(.*\[1\] = "one".*)");
573 ComparePrettyPrintToRegex(one_two_three, R"(.*\[2\] = "two".*\[2\] = "two")");
574 ComparePrettyPrintToRegex(one_two_three, R"(.*\[3\] = "three".*)");
575 }
576
unordered_map_iterator_test()577 void unordered_map_iterator_test() {
578 std::unordered_map<int, int> ones_to_eights;
579 ones_to_eights.insert({1, 8});
580 ones_to_eights.insert({11, 88});
581 ones_to_eights.insert({111, 888});
582
583 auto ones_to_eights_begin = ones_to_eights.begin();
584 MarkAsLive(ones_to_eights_begin);
585 CompareExpressionPrettyPrintToRegex("ones_to_eights_begin",
586 R"(std::__hash_map_iterator = {\[1+\] = 8+})");
587
588 auto not_found = ones_to_eights.find(5);
589 MarkAsLive(not_found);
590 CompareExpressionPrettyPrintToRegex("not_found",
591 R"(std::__hash_map_iterator = end\(\))");
592 }
593
unordered_set_iterator_test()594 void unordered_set_iterator_test() {
595 std::unordered_set<int> ones;
596 ones.insert(111);
597 ones.insert(1111);
598 ones.insert(11111);
599
600 auto ones_begin = ones.begin();
601 MarkAsLive(ones_begin);
602 CompareExpressionPrettyPrintToRegex("ones_begin",
603 R"(std::__hash_const_iterator = {1+})");
604
605 auto not_found = ones.find(5);
606 MarkAsLive(not_found);
607 CompareExpressionPrettyPrintToRegex("not_found",
608 R"(std::__hash_const_iterator = end\(\))");
609 }
610
611 // Check that libc++ pretty printers do not handle pointers.
pointer_negative_test()612 void pointer_negative_test() {
613 int abc = 123;
614 int *int_ptr = &abc;
615 // Check that the result is equivalent to "p/r int_ptr" command.
616 ComparePrettyPrintToRegex(int_ptr, R"(\(int \*\) 0x[a-f0-9]+)");
617 }
618
shared_ptr_test()619 void shared_ptr_test() {
620 // Shared ptr tests while using test framework call another function
621 // due to which there is one more count for the pointer. Hence, all the
622 // following tests are testing with expected count plus 1.
623 std::shared_ptr<const int> test0 = std::make_shared<const int>(5);
624 // The python regular expression matcher treats newlines as significant, so
625 // these regular expressions should be on one line.
626 ComparePrettyPrintToRegex(
627 test0,
628 R"(std::shared_ptr<int> count [2\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
629
630 std::shared_ptr<const int> test1(test0);
631 ComparePrettyPrintToRegex(
632 test1,
633 R"(std::shared_ptr<int> count [3\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
634
635 {
636 std::weak_ptr<const int> test2 = test1;
637 ComparePrettyPrintToRegex(
638 test0,
639 R"(std::shared_ptr<int> count [3\?], weak [1\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
640 }
641
642 ComparePrettyPrintToRegex(
643 test0,
644 R"(std::shared_ptr<int> count [3\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
645
646 std::shared_ptr<const int> test3;
647 ComparePrettyPrintToChars(test3, "std::shared_ptr is nullptr");
648 }
649
streampos_test()650 void streampos_test() {
651 std::streampos test0 = 67;
652 ComparePrettyPrintToRegex(test0, "^std::fpos with stream offset:67( with state: {count:0 value:0})?$");
653 std::istringstream input("testing the input stream here");
654 std::streampos test1 = input.tellg();
655 ComparePrettyPrintToRegex(test1, "^std::fpos with stream offset:0( with state: {count:0 value:0})?$");
656 std::unique_ptr<char[]> buffer(new char[5]);
657 input.read(buffer.get(), 5);
658 test1 = input.tellg();
659 ComparePrettyPrintToRegex(test1, "^std::fpos with stream offset:5( with state: {count:0 value:0})?$");
660 }
661
main(int,char **)662 int main(int, char**) {
663 framework_self_test();
664
665 string_test();
666 a_namespace::string_view_test();
667
668 //u16string_test();
669 u32string_test();
670 tuple_test();
671 unique_ptr_test();
672 shared_ptr_test();
673 bitset_test();
674 list_test();
675 deque_test();
676 map_test();
677 multimap_test();
678 queue_test();
679 priority_queue_test();
680 stack_test();
681 set_test();
682 multiset_test();
683 vector_test();
684 set_iterator_test();
685 map_iterator_test();
686 unordered_set_test();
687 unordered_multiset_test();
688 unordered_map_test();
689 unordered_multimap_test();
690 unordered_map_iterator_test();
691 unordered_set_iterator_test();
692 pointer_negative_test();
693 streampos_test();
694 return 0;
695 }
696