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