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