xref: /aosp_15_r20/external/cronet/third_party/libc++/src/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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