xref: /llvm-project/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp (revision 7f845cba2ccc2ab637b8e40fbafb9f83a2d67c70)
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-18, clang-19, clang-20
16 
17 // The Android libc++ tests are run on a non-Android host, connected to an
18 // Android device over adb. gdb needs special support to make this work (e.g.
19 // gdbclient.py, ndk-gdb.py, gdbserver), and the Android organization doesn't
20 // support gdb anymore, favoring lldb instead.
21 // UNSUPPORTED: android
22 
23 // This test doesn't work as such on Windows.
24 // UNSUPPORTED: windows
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;
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>
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 
104 template <typename TypeToPrint> void ComparePrettyPrintToChars(
105     TypeToPrint value,
106     const char *expectation) {
107   MarkAsLive(value);
108   StopForDebugger(&value, &expectation);
109 }
110 
111 template <typename TypeToPrint> void ComparePrettyPrintToRegex(
112     TypeToPrint value,
113     const char *expectation) {
114   MarkAsLive(value);
115   StopForDebugger(&value, &expectation);
116 }
117 
118 void CompareExpressionPrettyPrintToChars(
119     std::string value,
120     const char *expectation) {
121   MarkAsLive(value);
122   StopForDebugger(&value, &expectation);
123 }
124 
125 void CompareExpressionPrettyPrintToRegex(
126     std::string value,
127     const char *expectation) {
128   MarkAsLive(value);
129   StopForDebugger(&value, &expectation);
130 }
131 
132 template <typename TypeToPrint>
133 void CompareListChildrenToChars(TypeToPrint value, const char* expectation) {
134   MarkAsLive(value);
135   StopForDebugger(&value, &expectation);
136 }
137 
138 namespace example {
139   struct example_struct {
140     int a = 0;
141     int arr[1000];
142   };
143 }
144 
145 // If enabled, the self test will "fail"--because we want to be sure it properly
146 // diagnoses tests that *should* fail. Evaluate the output by hand.
147 void framework_self_test() {
148 #ifdef FRAMEWORK_SELF_TEST
149   // Use the most simple data structure we can.
150   const char a = 'a';
151 
152   // Tests that should pass
153   ComparePrettyPrintToChars(a, "97 'a'");
154   ComparePrettyPrintToRegex(a, ".*");
155 
156   // Tests that should fail.
157   ComparePrettyPrintToChars(a, "b");
158   ComparePrettyPrintToRegex(a, "b");
159 #endif
160 }
161 
162 // A simple pass-through allocator to check that we handle CompressedPair
163 // correctly.
164 template <typename T> class UncompressibleAllocator : public std::allocator<T> {
165  public:
166   char X;
167 
168   template <class U>
169   struct rebind {
170     using other = UncompressibleAllocator<U>;
171   };
172 };
173 
174 void string_test() {
175   std::string short_string("kdjflskdjf");
176   // The display_hint "string" adds quotes the printed result.
177   ComparePrettyPrintToChars(short_string, "\"kdjflskdjf\"");
178 
179   std::basic_string<char, std::char_traits<char>, UncompressibleAllocator<char>>
180       long_string("mehmet bizim dostumuz agzi kirik testimiz");
181   ComparePrettyPrintToChars(long_string,
182                             "\"mehmet bizim dostumuz agzi kirik testimiz\"");
183 }
184 
185 namespace a_namespace {
186 // To test name-lookup in the presence of using inside a namespace. Inside this
187 // namespace, unqualified string_view variables will appear in the debug info as
188 // "a_namespace::string_view, rather than "std::string_view".
189 //
190 // There is nothing special here about string_view; it's just the data structure
191 // where lookup with using inside a namespace wasn't always working.
192 
193 using string_view = std::string_view;
194 
195 void string_view_test() {
196   std::string_view i_am_empty;
197   ComparePrettyPrintToChars(i_am_empty, "\"\"");
198 
199   std::string source_string("to be or not to be");
200   std::string_view to_be(source_string);
201   ComparePrettyPrintToChars(to_be, "\"to be or not to be\"");
202 
203   const char char_arr[] = "what a wonderful world";
204   std::string_view wonderful(&char_arr[7], 9);
205   ComparePrettyPrintToChars(wonderful, "\"wonderful\"");
206 
207   const char char_arr1[] = "namespace_stringview";
208   string_view namespace_stringview(&char_arr1[10], 10);
209   ComparePrettyPrintToChars(namespace_stringview, "\"stringview\"");
210 }
211 }
212 
213 void u16string_test() {
214   std::u16string test0 = u"Hello World";
215   ComparePrettyPrintToChars(test0, "u\"Hello World\"");
216   std::u16string test1 = u"\U00010196\u20AC\u00A3\u0024";
217   ComparePrettyPrintToChars(test1, "u\"\U00010196\u20AC\u00A3\u0024\"");
218   std::u16string test2 = u"\u0024\u0025\u0026\u0027";
219   ComparePrettyPrintToChars(test2, "u\"\u0024\u0025\u0026\u0027\"");
220   std::u16string test3 = u"mehmet bizim dostumuz agzi kirik testimiz";
221   ComparePrettyPrintToChars(test3,
222                             ("u\"mehmet bizim dostumuz agzi kirik testimiz\""));
223 }
224 
225 void u32string_test() {
226   std::u32string test0 = U"Hello World";
227   ComparePrettyPrintToChars(test0, "U\"Hello World\"");
228   std::u32string test1 =
229       U"\U0001d552\U0001d553\U0001d554\U0001d555\U0001d556\U0001d557";
230   ComparePrettyPrintToChars(
231       test1,
232       ("U\"\U0001d552\U0001d553\U0001d554\U0001d555\U0001d556\U0001d557\""));
233   std::u32string test2 = U"\U00004f60\U0000597d";
234   ComparePrettyPrintToChars(test2, ("U\"\U00004f60\U0000597d\""));
235   std::u32string test3 = U"mehmet bizim dostumuz agzi kirik testimiz";
236   ComparePrettyPrintToChars(test3, ("U\"mehmet bizim dostumuz agzi kirik testimiz\""));
237 }
238 
239 void tuple_test() {
240   std::tuple<int, int, int> test0(2, 3, 4);
241   ComparePrettyPrintToChars(test0, "std::tuple containing = {[0] = 2, [1] = 3, [2] = 4}");
242 
243   std::tuple<> test1;
244   ComparePrettyPrintToChars(
245       test1,
246       "empty std::tuple");
247 }
248 
249 void unique_ptr_test() {
250   std::unique_ptr<std::string> matilda(new std::string("Matilda"));
251   ComparePrettyPrintToRegex(
252       std::move(matilda),
253       R"(std::unique_ptr<std::string> containing = {__ptr_ = 0x[a-f0-9]+})");
254   std::unique_ptr<int> forty_two(new int(42));
255   ComparePrettyPrintToRegex(std::move(forty_two),
256       R"(std::unique_ptr<int> containing = {__ptr_ = 0x[a-f0-9]+})");
257 
258   std::unique_ptr<int> this_is_null;
259   ComparePrettyPrintToChars(std::move(this_is_null),
260       R"(std::unique_ptr is nullptr)");
261 }
262 
263 void bitset_test() {
264   std::bitset<258> i_am_empty(0);
265   ComparePrettyPrintToRegex(i_am_empty, "std::bitset<258(u|ul)?>");
266 
267   std::bitset<0> very_empty;
268   ComparePrettyPrintToRegex(very_empty, "std::bitset<0(u|ul)?>");
269 
270   std::bitset<15> b_000001111111100(1020);
271   ComparePrettyPrintToRegex(b_000001111111100,
272       R"(std::bitset<15(u|ul)?> = {\[2\] = 1, \[3\] = 1, \[4\] = 1, \[5\] = 1, \[6\] = 1, )"
273       R"(\[7\] = 1, \[8\] = 1, \[9\] = 1})");
274 
275   std::bitset<258> b_0_129_132(0);
276   b_0_129_132[0] = true;
277   b_0_129_132[129] = true;
278   b_0_129_132[132] = true;
279   ComparePrettyPrintToRegex(b_0_129_132,
280       R"(std::bitset<258(u|ul)?> = {\[0\] = 1, \[129\] = 1, \[132\] = 1})");
281 }
282 
283 void list_test() {
284   std::list<int> i_am_empty{};
285   ComparePrettyPrintToChars(i_am_empty, "std::list is empty");
286 
287   std::list<int> one_two_three {1, 2, 3};
288   ComparePrettyPrintToChars(one_two_three,
289       "std::list with 3 elements = {1, 2, 3}");
290 
291   std::list<std::string> colors {"red", "blue", "green"};
292   ComparePrettyPrintToChars(colors,
293       R"(std::list with 3 elements = {"red", "blue", "green"})");
294 }
295 
296 void deque_test() {
297   std::deque<int> i_am_empty{};
298   ComparePrettyPrintToChars(i_am_empty, "std::deque is empty");
299 
300   std::deque<int> one_two_three {1, 2, 3};
301   ComparePrettyPrintToChars(one_two_three,
302       "std::deque with 3 elements = {1, 2, 3}");
303 
304   std::deque<example::example_struct> bfg;
305   for (int i = 0; i < 10; ++i) {
306     example::example_struct current;
307     current.a = i;
308     bfg.push_back(current);
309   }
310   for (int i = 0; i < 3; ++i) {
311     bfg.pop_front();
312   }
313   for (int i = 0; i < 3; ++i) {
314     bfg.pop_back();
315   }
316   ComparePrettyPrintToRegex(bfg,
317       "std::deque with 4 elements = {"
318       "{a = 3, arr = {[^}]+}}, "
319       "{a = 4, arr = {[^}]+}}, "
320       "{a = 5, arr = {[^}]+}}, "
321       "{a = 6, arr = {[^}]+}}}");
322 }
323 
324 void map_test() {
325   std::map<int, int> i_am_empty{};
326   ComparePrettyPrintToChars(i_am_empty, "std::map is empty");
327 
328   std::map<int, std::string> one_two_three;
329   one_two_three.insert({1, "one"});
330   one_two_three.insert({2, "two"});
331   one_two_three.insert({3, "three"});
332   ComparePrettyPrintToChars(one_two_three,
333       "std::map with 3 elements = "
334       R"({[1] = "one", [2] = "two", [3] = "three"})");
335 
336   std::map<int, example::example_struct> bfg;
337   for (int i = 0; i < 4; ++i) {
338     example::example_struct current;
339     current.a = 17 * i;
340     bfg.insert({i, current});
341   }
342   ComparePrettyPrintToRegex(bfg,
343       R"(std::map with 4 elements = {)"
344       R"(\[0\] = {a = 0, arr = {[^}]+}}, )"
345       R"(\[1\] = {a = 17, arr = {[^}]+}}, )"
346       R"(\[2\] = {a = 34, arr = {[^}]+}}, )"
347       R"(\[3\] = {a = 51, arr = {[^}]+}}})");
348 }
349 
350 void multimap_test() {
351   std::multimap<int, int> i_am_empty{};
352   ComparePrettyPrintToChars(i_am_empty, "std::multimap is empty");
353 
354   std::multimap<int, std::string> one_two_three;
355   one_two_three.insert({1, "one"});
356   one_two_three.insert({3, "three"});
357   one_two_three.insert({1, "ein"});
358   one_two_three.insert({2, "two"});
359   one_two_three.insert({2, "zwei"});
360   one_two_three.insert({1, "bir"});
361 
362   ComparePrettyPrintToChars(one_two_three,
363       "std::multimap with 6 elements = "
364       R"({[1] = "one", [1] = "ein", [1] = "bir", )"
365       R"([2] = "two", [2] = "zwei", [3] = "three"})");
366 }
367 
368 void queue_test() {
369   std::queue<int> i_am_empty;
370   ComparePrettyPrintToChars(i_am_empty, "std::queue wrapping: std::deque is empty");
371 
372   std::queue<int> one_two_three(std::deque<int>{1, 2, 3});
373   ComparePrettyPrintToChars(
374       one_two_three,
375       "std::queue wrapping: "
376       "std::deque with 3 elements = {1, 2, 3}");
377 }
378 
379 void priority_queue_test() {
380   std::priority_queue<int> i_am_empty;
381   ComparePrettyPrintToChars(i_am_empty, "std::priority_queue wrapping: std::vector of length 0, capacity 0");
382 
383   std::priority_queue<int> one_two_three;
384   one_two_three.push(11111);
385   one_two_three.push(22222);
386   one_two_three.push(33333);
387 
388   ComparePrettyPrintToRegex(
389       one_two_three,
390       R"(std::priority_queue wrapping: )"
391       R"(std::vector of length 3, capacity 3 = {33333)");
392 
393   ComparePrettyPrintToRegex(one_two_three, ".*11111.*");
394   ComparePrettyPrintToRegex(one_two_three, ".*22222.*");
395 }
396 
397 void set_test() {
398   std::set<int> i_am_empty;
399   ComparePrettyPrintToChars(i_am_empty, "std::set is empty");
400 
401   std::set<int> one_two_three {3, 1, 2};
402   ComparePrettyPrintToChars(one_two_three,
403       "std::set with 3 elements = {1, 2, 3}");
404 
405   std::set<std::pair<int, int>> prime_pairs {
406       std::make_pair(3, 5), std::make_pair(5, 7), std::make_pair(3, 5)};
407 
408   ComparePrettyPrintToChars(prime_pairs,
409       "std::set with 2 elements = {"
410       "{first = 3, second = 5}, {first = 5, second = 7}}");
411 
412   using using_set = std::set<int>;
413   using_set other{1, 2, 3};
414   ComparePrettyPrintToChars(other, "std::set with 3 elements = {1, 2, 3}");
415 }
416 
417 void stack_test() {
418   std::stack<int> test0;
419   ComparePrettyPrintToChars(test0, "std::stack wrapping: std::deque is empty");
420   test0.push(5);
421   test0.push(6);
422   ComparePrettyPrintToChars(test0, "std::stack wrapping: std::deque with 2 elements = {5, 6}");
423   std::stack<bool> test1;
424   test1.push(true);
425   test1.push(false);
426   ComparePrettyPrintToChars(test1, "std::stack wrapping: std::deque with 2 elements = {true, false}");
427 
428   std::stack<std::string> test2;
429   test2.push("Hello");
430   test2.push("World");
431   ComparePrettyPrintToChars(
432       test2,
433       "std::stack wrapping: std::deque with 2 elements "
434       "= {\"Hello\", \"World\"}");
435 }
436 
437 void multiset_test() {
438   std::multiset<int> i_am_empty;
439   ComparePrettyPrintToChars(i_am_empty, "std::multiset is empty");
440 
441   std::multiset<std::string> one_two_three {"1:one", "2:two", "3:three", "1:one"};
442   ComparePrettyPrintToChars(one_two_three,
443       "std::multiset with 4 elements = {"
444       R"("1:one", "1:one", "2:two", "3:three"})");
445 }
446 
447 void vector_test() {
448   std::vector<bool> test0 = {true, false};
449   ComparePrettyPrintToRegex(test0,
450                             "std::vector<bool> of "
451                             "length 2, capacity (32|64) = {1, 0}");
452   for (int i = 0; i < 31; ++i) {
453     test0.push_back(true);
454     test0.push_back(false);
455   }
456   ComparePrettyPrintToRegex(
457       test0,
458       "std::vector<bool> of length 64, "
459       "capacity 64 = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, "
460       "0, 1, 0, 1, 0, 1, 0, 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}");
462   test0.push_back(true);
463   ComparePrettyPrintToRegex(
464       test0,
465       "std::vector<bool> of length 65, "
466       "capacity (96|128) = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, "
467       "0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, "
468       "0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}");
469 
470   std::vector<int> test1;
471   ComparePrettyPrintToChars(test1, "std::vector of length 0, capacity 0");
472 
473   std::vector<int> test2 = {5, 6, 7};
474   ComparePrettyPrintToChars(test2,
475                             "std::vector of length "
476                             "3, capacity 3 = {5, 6, 7}");
477 
478   std::vector<int, UncompressibleAllocator<int>> test3({7, 8});
479   ComparePrettyPrintToChars(std::move(test3),
480                             "std::vector of length "
481                             "2, capacity 2 = {7, 8}");
482 }
483 
484 void set_iterator_test() {
485   std::set<int> one_two_three {1111, 2222, 3333};
486   auto it = one_two_three.find(2222);
487   MarkAsLive(it);
488   CompareExpressionPrettyPrintToRegex("it",
489       R"(std::__tree_const_iterator  = {\[0x[a-f0-9]+\] = 2222})");
490 
491   auto not_found = one_two_three.find(1234);
492   MarkAsLive(not_found);
493   // Because the end_node is not easily detected, just be sure it doesn't crash.
494   CompareExpressionPrettyPrintToRegex("not_found",
495       R"(std::__tree_const_iterator ( = {\[0x[a-f0-9]+\] = .*}|<error reading variable:.*>))");
496 }
497 
498 void map_iterator_test() {
499   std::map<int, std::string> one_two_three;
500   one_two_three.insert({1, "one"});
501   one_two_three.insert({2, "two"});
502   one_two_three.insert({3, "three"});
503   auto it = one_two_three.begin();
504   MarkAsLive(it);
505   CompareExpressionPrettyPrintToRegex("it",
506       R"(std::__map_iterator  = )"
507       R"({\[0x[a-f0-9]+\] = {first = 1, second = "one"}})");
508 
509   auto not_found = one_two_three.find(7);
510   MarkAsLive(not_found);
511   // Because the end_node is not easily detected, just be sure it doesn't crash.
512   CompareExpressionPrettyPrintToRegex(
513       "not_found", R"(std::__map_iterator ( = {\[0x[a-f0-9]+\] = .*}|<error reading variable:.*>))");
514 }
515 
516 void unordered_set_test() {
517   std::unordered_set<int> i_am_empty;
518   ComparePrettyPrintToChars(i_am_empty, "std::unordered_set is empty");
519 
520   std::unordered_set<int> numbers {12345, 67890, 222333, 12345};
521   numbers.erase(numbers.find(222333));
522   ComparePrettyPrintToRegex(numbers, "std::unordered_set with 2 elements = ");
523   ComparePrettyPrintToRegex(numbers, ".*12345.*");
524   ComparePrettyPrintToRegex(numbers, ".*67890.*");
525 
526   std::unordered_set<std::string> colors {"red", "blue", "green"};
527   ComparePrettyPrintToRegex(colors, "std::unordered_set with 3 elements = ");
528   ComparePrettyPrintToRegex(colors, R"(.*"red".*)");
529   ComparePrettyPrintToRegex(colors, R"(.*"blue".*)");
530   ComparePrettyPrintToRegex(colors, R"(.*"green".*)");
531 }
532 
533 void unordered_multiset_test() {
534   std::unordered_multiset<int> i_am_empty;
535   ComparePrettyPrintToChars(i_am_empty, "std::unordered_multiset is empty");
536 
537   std::unordered_multiset<int> numbers {12345, 67890, 222333, 12345};
538   ComparePrettyPrintToRegex(numbers,
539                             "std::unordered_multiset with 4 elements = ");
540   ComparePrettyPrintToRegex(numbers, ".*12345.*12345.*");
541   ComparePrettyPrintToRegex(numbers, ".*67890.*");
542   ComparePrettyPrintToRegex(numbers, ".*222333.*");
543 
544   std::unordered_multiset<std::string> colors {"red", "blue", "green", "red"};
545   ComparePrettyPrintToRegex(colors,
546                             "std::unordered_multiset with 4 elements = ");
547   ComparePrettyPrintToRegex(colors, R"(.*"red".*"red".*)");
548   ComparePrettyPrintToRegex(colors, R"(.*"blue".*)");
549   ComparePrettyPrintToRegex(colors, R"(.*"green".*)");
550 }
551 
552 void unordered_map_test() {
553   std::unordered_map<int, int> i_am_empty;
554   ComparePrettyPrintToChars(i_am_empty, "std::unordered_map is empty");
555 
556   std::unordered_map<int, std::string> one_two_three;
557   one_two_three.insert({1, "one"});
558   one_two_three.insert({2, "two"});
559   one_two_three.insert({3, "three"});
560   ComparePrettyPrintToRegex(one_two_three,
561                             "std::unordered_map with 3 elements = ");
562   ComparePrettyPrintToRegex(one_two_three, R"(.*\[1\] = "one".*)");
563   ComparePrettyPrintToRegex(one_two_three, R"(.*\[2\] = "two".*)");
564   ComparePrettyPrintToRegex(one_two_three, R"(.*\[3\] = "three".*)");
565 }
566 
567 void unordered_multimap_test() {
568   std::unordered_multimap<int, int> i_am_empty;
569   ComparePrettyPrintToChars(i_am_empty, "std::unordered_multimap is empty");
570 
571   std::unordered_multimap<int, std::string> one_two_three;
572   one_two_three.insert({1, "one"});
573   one_two_three.insert({2, "two"});
574   one_two_three.insert({3, "three"});
575   one_two_three.insert({2, "two"});
576   ComparePrettyPrintToRegex(one_two_three,
577                             "std::unordered_multimap with 4 elements = ");
578   ComparePrettyPrintToRegex(one_two_three, R"(.*\[1\] = "one".*)");
579   ComparePrettyPrintToRegex(one_two_three, R"(.*\[2\] = "two".*\[2\] = "two")");
580   ComparePrettyPrintToRegex(one_two_three, R"(.*\[3\] = "three".*)");
581 }
582 
583 void unordered_map_iterator_test() {
584   std::unordered_map<int, int> ones_to_eights;
585   ones_to_eights.insert({1, 8});
586   ones_to_eights.insert({11, 88});
587   ones_to_eights.insert({111, 888});
588 
589   auto ones_to_eights_begin = ones_to_eights.begin();
590   MarkAsLive(ones_to_eights_begin);
591   CompareExpressionPrettyPrintToRegex("ones_to_eights_begin",
592       R"(std::__hash_map_iterator  = {\[1+\] = 8+})");
593 
594   auto not_found = ones_to_eights.find(5);
595   MarkAsLive(not_found);
596   CompareExpressionPrettyPrintToRegex("not_found",
597       R"(std::__hash_map_iterator = end\(\))");
598 }
599 
600 void unordered_set_iterator_test() {
601   std::unordered_set<int> ones;
602   ones.insert(111);
603   ones.insert(1111);
604   ones.insert(11111);
605 
606   auto ones_begin = ones.begin();
607   MarkAsLive(ones_begin);
608   CompareExpressionPrettyPrintToRegex("ones_begin",
609       R"(std::__hash_const_iterator  = {1+})");
610 
611   auto not_found = ones.find(5);
612   MarkAsLive(not_found);
613   CompareExpressionPrettyPrintToRegex("not_found",
614       R"(std::__hash_const_iterator = end\(\))");
615 }
616 
617 // Check that libc++ pretty printers do not handle pointers.
618 void pointer_negative_test() {
619   int abc = 123;
620   int *int_ptr = &abc;
621   // Check that the result is equivalent to "p/r int_ptr" command.
622   ComparePrettyPrintToRegex(int_ptr, R"(\(int \*\) 0x[a-f0-9]+)");
623 }
624 
625 void shared_ptr_test() {
626   // Shared ptr tests while using test framework call another function
627   // due to which there is one more count for the pointer. Hence, all the
628   // following tests are testing with expected count plus 1.
629   std::shared_ptr<const int> test0 = std::make_shared<const int>(5);
630   // The python regular expression matcher treats newlines as significant, so
631   // these regular expressions should be on one line.
632   ComparePrettyPrintToRegex(
633       test0,
634       R"(std::shared_ptr<int> count [2\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
635 
636   std::shared_ptr<const int> test1(test0);
637   ComparePrettyPrintToRegex(
638       test1,
639       R"(std::shared_ptr<int> count [3\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
640 
641   {
642     std::weak_ptr<const int> test2 = test1;
643     ComparePrettyPrintToRegex(
644         test0,
645         R"(std::shared_ptr<int> count [3\?], weak [1\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
646   }
647 
648   ComparePrettyPrintToRegex(
649       test0,
650       R"(std::shared_ptr<int> count [3\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
651 
652   std::shared_ptr<const int> test3;
653   ComparePrettyPrintToChars(test3, "std::shared_ptr is nullptr");
654 }
655 
656 void streampos_test() {
657   std::streampos test0 = 67;
658   ComparePrettyPrintToRegex(test0, "^std::fpos with stream offset:67( with state: {count:0 value:0})?$");
659   std::istringstream input("testing the input stream here");
660   std::streampos test1 = input.tellg();
661   ComparePrettyPrintToRegex(test1, "^std::fpos with stream offset:0( with state: {count:0 value:0})?$");
662   std::unique_ptr<char[]> buffer(new char[5]);
663   input.read(buffer.get(), 5);
664   test1 = input.tellg();
665   ComparePrettyPrintToRegex(test1, "^std::fpos with stream offset:5( with state: {count:0 value:0})?$");
666 }
667 
668 void mi_mode_test() {
669   std::map<int, std::string> one_two_three_map;
670   one_two_three_map.insert({1, "one"});
671   one_two_three_map.insert({2, "two"});
672   one_two_three_map.insert({3, "three"});
673   CompareListChildrenToChars(
674       one_two_three_map, R"([{"key": 1, "value": "one"}, {"key": 2, "value": "two"}, {"key": 3, "value": "three"}])");
675 
676   std::unordered_map<int, std::string> one_two_three_umap;
677   one_two_three_umap.insert({3, "three"});
678   one_two_three_umap.insert({2, "two"});
679   one_two_three_umap.insert({1, "one"});
680   CompareListChildrenToChars(
681       one_two_three_umap, R"([{"key": 3, "value": "three"}, {"key": 2, "value": "two"}, {"key": 1, "value": "one"}])");
682 
683   std::deque<int> one_two_three_deque{1, 2, 3};
684   CompareListChildrenToChars(one_two_three_deque, "[1, 2, 3]");
685 }
686 
687 int main(int, char**) {
688   framework_self_test();
689 
690   string_test();
691   a_namespace::string_view_test();
692 
693   //u16string_test();
694   u32string_test();
695   tuple_test();
696   unique_ptr_test();
697   shared_ptr_test();
698   bitset_test();
699   list_test();
700   deque_test();
701   map_test();
702   multimap_test();
703   queue_test();
704   priority_queue_test();
705   stack_test();
706   set_test();
707   multiset_test();
708   vector_test();
709   set_iterator_test();
710   map_iterator_test();
711   unordered_set_test();
712   unordered_multiset_test();
713   unordered_map_test();
714   unordered_multimap_test();
715   unordered_map_iterator_test();
716   unordered_set_iterator_test();
717   pointer_negative_test();
718   streampos_test();
719   mi_mode_test();
720   return 0;
721 }
722