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