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-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
78void StopForDebugger(void *, void *) OPT_NONE;
79void StopForDebugger(void *, void *) {}
80
81
82// Prevents the compiler optimizing away the parameter in the caller function.
83template <typename Type>
84void MarkAsLive(Type &&) OPT_NONE;
85template <typename Type>
86void 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
104template <typename TypeToPrint> void ComparePrettyPrintToChars(
105 TypeToPrint value,
106 const char *expectation) {
107 MarkAsLive(value);
108 StopForDebugger(&value, &expectation);
109}
110
111template <typename TypeToPrint> void ComparePrettyPrintToRegex(
112 TypeToPrint value,
113 const char *expectation) {
114 MarkAsLive(value);
115 StopForDebugger(&value, &expectation);
116}
117
118void CompareExpressionPrettyPrintToChars(
119 std::string value,
120 const char *expectation) {
121 MarkAsLive(value);
122 StopForDebugger(&value, &expectation);
123}
124
125void CompareExpressionPrettyPrintToRegex(
126 std::string value,
127 const char *expectation) {
128 MarkAsLive(value);
129 StopForDebugger(&value, &expectation);
130}
131
132namespace 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.
141void 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.
158template <typename T> class UncompressibleAllocator : public std::allocator<T> {
159 public:
160 char X;
161};
162
163void string_test() {
164 std::string short_string("kdjflskdjf");
165 // The display_hint "string" adds quotes the printed result.
166 ComparePrettyPrintToChars(value: short_string, expectation: "\"kdjflskdjf\"");
167
168 std::basic_string<char, std::char_traits<char>, UncompressibleAllocator<char>>
169 long_string("mehmet bizim dostumuz agzi kirik testimiz");
170 ComparePrettyPrintToChars(value: long_string,
171 expectation: "\"mehmet bizim dostumuz agzi kirik testimiz\"");
172}
173
174namespace 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
182using string_view = std::string_view;
183
184void string_view_test() {
185 std::string_view i_am_empty;
186 ComparePrettyPrintToChars(value: i_am_empty, expectation: "\"\"");
187
188 std::string source_string("to be or not to be");
189 std::string_view to_be(source_string);
190 ComparePrettyPrintToChars(value: to_be, expectation: "\"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(value: wonderful, expectation: "\"wonderful\"");
195
196 const char char_arr1[] = "namespace_stringview";
197 string_view namespace_stringview(&char_arr1[10], 10);
198 ComparePrettyPrintToChars(value: namespace_stringview, expectation: "\"stringview\"");
199}
200}
201
202void u16string_test() {
203 std::u16string test0 = u"Hello World";
204 ComparePrettyPrintToChars(value: test0, expectation: "u\"Hello World\"");
205 std::u16string test1 = u"\U00010196\u20AC\u00A3\u0024";
206 ComparePrettyPrintToChars(value: test1, expectation: "u\"\U00010196\u20AC\u00A3\u0024\"");
207 std::u16string test2 = u"\u0024\u0025\u0026\u0027";
208 ComparePrettyPrintToChars(value: test2, expectation: "u\"\u0024\u0025\u0026\u0027\"");
209 std::u16string test3 = u"mehmet bizim dostumuz agzi kirik testimiz";
210 ComparePrettyPrintToChars(value: test3,
211 expectation: ("u\"mehmet bizim dostumuz agzi kirik testimiz\""));
212}
213
214void u32string_test() {
215 std::u32string test0 = U"Hello World";
216 ComparePrettyPrintToChars(value: test0, expectation: "U\"Hello World\"");
217 std::u32string test1 =
218 U"\U0001d552\U0001d553\U0001d554\U0001d555\U0001d556\U0001d557";
219 ComparePrettyPrintToChars(
220 value: test1,
221 expectation: ("U\"\U0001d552\U0001d553\U0001d554\U0001d555\U0001d556\U0001d557\""));
222 std::u32string test2 = U"\U00004f60\U0000597d";
223 ComparePrettyPrintToChars(value: test2, expectation: ("U\"\U00004f60\U0000597d\""));
224 std::u32string test3 = U"mehmet bizim dostumuz agzi kirik testimiz";
225 ComparePrettyPrintToChars(value: test3, expectation: ("U\"mehmet bizim dostumuz agzi kirik testimiz\""));
226}
227
228void tuple_test() {
229 std::tuple<int, int, int> test0(2, 3, 4);
230 ComparePrettyPrintToChars(
231 value: test0,
232 expectation: "std::tuple containing = {[1] = 2, [2] = 3, [3] = 4}");
233
234 std::tuple<> test1;
235 ComparePrettyPrintToChars(
236 value: test1,
237 expectation: "empty std::tuple");
238}
239
240void unique_ptr_test() {
241 std::unique_ptr<std::string> matilda(new std::string("Matilda"));
242 ComparePrettyPrintToRegex(
243 value: std::move(matilda),
244 expectation: R"(std::unique_ptr<std::string> containing = {__ptr_ = 0x[a-f0-9]+})");
245 std::unique_ptr<int> forty_two(new int(42));
246 ComparePrettyPrintToRegex(value: std::move(forty_two),
247 expectation: R"(std::unique_ptr<int> containing = {__ptr_ = 0x[a-f0-9]+})");
248
249 std::unique_ptr<int> this_is_null;
250 ComparePrettyPrintToChars(value: std::move(this_is_null),
251 expectation: R"(std::unique_ptr is nullptr)");
252}
253
254void bitset_test() {
255 std::bitset<258> i_am_empty(0);
256 ComparePrettyPrintToRegex(value: i_am_empty, expectation: "std::bitset<258(u|ul)?>");
257
258 std::bitset<0> very_empty;
259 ComparePrettyPrintToRegex(value: very_empty, expectation: "std::bitset<0(u|ul)?>");
260
261 std::bitset<15> b_000001111111100(1020);
262 ComparePrettyPrintToRegex(value: b_000001111111100,
263 expectation: 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(value: b_0_129_132,
271 expectation: R"(std::bitset<258(u|ul)?> = {\[0\] = 1, \[129\] = 1, \[132\] = 1})");
272}
273
274void list_test() {
275 std::list<int> i_am_empty{};
276 ComparePrettyPrintToChars(value: i_am_empty, expectation: "std::list is empty");
277
278 std::list<int> one_two_three {1, 2, 3};
279 ComparePrettyPrintToChars(value: one_two_three,
280 expectation: "std::list with 3 elements = {1, 2, 3}");
281
282 std::list<std::string> colors {"red", "blue", "green"};
283 ComparePrettyPrintToChars(value: colors,
284 expectation: R"(std::list with 3 elements = {"red", "blue", "green"})");
285}
286
287void deque_test() {
288 std::deque<int> i_am_empty{};
289 ComparePrettyPrintToChars(value: i_am_empty, expectation: "std::deque is empty");
290
291 std::deque<int> one_two_three {1, 2, 3};
292 ComparePrettyPrintToChars(value: one_two_three,
293 expectation: "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(x: 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(value: bfg,
308 expectation: "std::deque with 4 elements = {"
309 "{a = 3, arr = {[^}]+}}, "
310 "{a = 4, arr = {[^}]+}}, "
311 "{a = 5, arr = {[^}]+}}, "
312 "{a = 6, arr = {[^}]+}}}");
313}
314
315void map_test() {
316 std::map<int, int> i_am_empty{};
317 ComparePrettyPrintToChars(value: i_am_empty, expectation: "std::map is empty");
318
319 std::map<int, std::string> one_two_three;
320 one_two_three.insert(x: {1, "one"});
321 one_two_three.insert(x: {2, "two"});
322 one_two_three.insert(x: {3, "three"});
323 ComparePrettyPrintToChars(value: one_two_three,
324 expectation: "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(x: {i, current});
332 }
333 ComparePrettyPrintToRegex(value: bfg,
334 expectation: 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
341void multimap_test() {
342 std::multimap<int, int> i_am_empty{};
343 ComparePrettyPrintToChars(value: i_am_empty, expectation: "std::multimap is empty");
344
345 std::multimap<int, std::string> one_two_three;
346 one_two_three.insert(x: {1, "one"});
347 one_two_three.insert(x: {3, "three"});
348 one_two_three.insert(x: {1, "ein"});
349 one_two_three.insert(x: {2, "two"});
350 one_two_three.insert(x: {2, "zwei"});
351 one_two_three.insert(x: {1, "bir"});
352
353 ComparePrettyPrintToChars(value: one_two_three,
354 expectation: "std::multimap with 6 elements = "
355 R"({[1] = "one", [1] = "ein", [1] = "bir", )"
356 R"([2] = "two", [2] = "zwei", [3] = "three"})");
357}
358
359void queue_test() {
360 std::queue<int> i_am_empty;
361 ComparePrettyPrintToChars(value: i_am_empty,
362 expectation: "std::queue wrapping = {std::deque is empty}");
363
364 std::queue<int> one_two_three(std::deque<int>{1, 2, 3});
365 ComparePrettyPrintToChars(value: one_two_three,
366 expectation: "std::queue wrapping = {"
367 "std::deque with 3 elements = {1, 2, 3}}");
368}
369
370void priority_queue_test() {
371 std::priority_queue<int> i_am_empty;
372 ComparePrettyPrintToChars(value: i_am_empty,
373 expectation: "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(x: 11111);
377 one_two_three.push(x: 22222);
378 one_two_three.push(x: 33333);
379
380 ComparePrettyPrintToRegex(value: one_two_three,
381 expectation: R"(std::priority_queue wrapping = )"
382 R"({std::vector of length 3, capacity 3 = {33333)");
383
384 ComparePrettyPrintToRegex(value: one_two_three, expectation: ".*11111.*");
385 ComparePrettyPrintToRegex(value: one_two_three, expectation: ".*22222.*");
386}
387
388void set_test() {
389 std::set<int> i_am_empty;
390 ComparePrettyPrintToChars(value: i_am_empty, expectation: "std::set is empty");
391
392 std::set<int> one_two_three {3, 1, 2};
393 ComparePrettyPrintToChars(value: one_two_three,
394 expectation: "std::set with 3 elements = {1, 2, 3}");
395
396 std::set<std::pair<int, int>> prime_pairs {
397 std::make_pair(x: 3, y: 5), std::make_pair(x: 5, y: 7), std::make_pair(x: 3, y: 5)};
398
399 ComparePrettyPrintToChars(value: prime_pairs,
400 expectation: "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(value: other, expectation: "std::set with 3 elements = {1, 2, 3}");
406}
407
408void stack_test() {
409 std::stack<int> test0;
410 ComparePrettyPrintToChars(value: test0,
411 expectation: "std::stack wrapping = {std::deque is empty}");
412 test0.push(x: 5);
413 test0.push(x: 6);
414 ComparePrettyPrintToChars(
415 value: test0, expectation: "std::stack wrapping = {std::deque with 2 elements = {5, 6}}");
416 std::stack<bool> test1;
417 test1.push(x: true);
418 test1.push(x: false);
419 ComparePrettyPrintToChars(
420 value: test1,
421 expectation: "std::stack wrapping = {std::deque with 2 elements = {true, false}}");
422
423 std::stack<std::string> test2;
424 test2.push(x: "Hello");
425 test2.push(x: "World");
426 ComparePrettyPrintToChars(value: test2,
427 expectation: "std::stack wrapping = {std::deque with 2 elements "
428 "= {\"Hello\", \"World\"}}");
429}
430
431void multiset_test() {
432 std::multiset<int> i_am_empty;
433 ComparePrettyPrintToChars(value: i_am_empty, expectation: "std::multiset is empty");
434
435 std::multiset<std::string> one_two_three {"1:one", "2:two", "3:three", "1:one"};
436 ComparePrettyPrintToChars(value: one_two_three,
437 expectation: "std::multiset with 4 elements = {"
438 R"("1:one", "1:one", "2:two", "3:three"})");
439}
440
441void vector_test() {
442 std::vector<bool> test0 = {true, false};
443 ComparePrettyPrintToRegex(value: test0,
444 expectation: "std::vector<bool> of "
445 "length 2, capacity (32|64) = {1, 0}");
446 for (int i = 0; i < 31; ++i) {
447 test0.push_back(x: true);
448 test0.push_back(x: false);
449 }
450 ComparePrettyPrintToRegex(
451 value: test0,
452 expectation: "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(x: true);
457 ComparePrettyPrintToRegex(
458 value: test0,
459 expectation: "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(value: test1, expectation: "std::vector of length 0, capacity 0");
466
467 std::vector<int> test2 = {5, 6, 7};
468 ComparePrettyPrintToChars(value: test2,
469 expectation: "std::vector of length "
470 "3, capacity 3 = {5, 6, 7}");
471
472 std::vector<int, UncompressibleAllocator<int>> test3({7, 8});
473 ComparePrettyPrintToChars(value: std::move(test3),
474 expectation: "std::vector of length "
475 "2, capacity 2 = {7, 8}");
476}
477
478void set_iterator_test() {
479 std::set<int> one_two_three {1111, 2222, 3333};
480 auto it = one_two_three.find(x: 2222);
481 MarkAsLive(it);
482 CompareExpressionPrettyPrintToRegex(value: "it",
483 expectation: R"(std::__tree_const_iterator = {\[0x[a-f0-9]+\] = 2222})");
484
485 auto not_found = one_two_three.find(x: 1234);
486 MarkAsLive(not_found);
487 // Because the end_node is not easily detected, just be sure it doesn't crash.
488 CompareExpressionPrettyPrintToRegex(value: "not_found",
489 expectation: R"(std::__tree_const_iterator ( = {\[0x[a-f0-9]+\] = .*}|<error reading variable:.*>))");
490}
491
492void map_iterator_test() {
493 std::map<int, std::string> one_two_three;
494 one_two_three.insert(x: {1, "one"});
495 one_two_three.insert(x: {2, "two"});
496 one_two_three.insert(x: {3, "three"});
497 auto it = one_two_three.begin();
498 MarkAsLive(it);
499 CompareExpressionPrettyPrintToRegex(value: "it",
500 expectation: R"(std::__map_iterator = )"
501 R"({\[0x[a-f0-9]+\] = {first = 1, second = "one"}})");
502
503 auto not_found = one_two_three.find(x: 7);
504 MarkAsLive(not_found);
505 // Because the end_node is not easily detected, just be sure it doesn't crash.
506 CompareExpressionPrettyPrintToRegex(
507 value: "not_found", expectation: R"(std::__map_iterator ( = {\[0x[a-f0-9]+\] = .*}|<error reading variable:.*>))");
508}
509
510void unordered_set_test() {
511 std::unordered_set<int> i_am_empty;
512 ComparePrettyPrintToChars(value: i_am_empty, expectation: "std::unordered_set is empty");
513
514 std::unordered_set<int> numbers {12345, 67890, 222333, 12345};
515 numbers.erase(position: numbers.find(x: 222333));
516 ComparePrettyPrintToRegex(value: numbers, expectation: "std::unordered_set with 2 elements = ");
517 ComparePrettyPrintToRegex(value: numbers, expectation: ".*12345.*");
518 ComparePrettyPrintToRegex(value: numbers, expectation: ".*67890.*");
519
520 std::unordered_set<std::string> colors {"red", "blue", "green"};
521 ComparePrettyPrintToRegex(value: colors, expectation: "std::unordered_set with 3 elements = ");
522 ComparePrettyPrintToRegex(value: colors, expectation: R"(.*"red".*)");
523 ComparePrettyPrintToRegex(value: colors, expectation: R"(.*"blue".*)");
524 ComparePrettyPrintToRegex(value: colors, expectation: R"(.*"green".*)");
525}
526
527void unordered_multiset_test() {
528 std::unordered_multiset<int> i_am_empty;
529 ComparePrettyPrintToChars(value: i_am_empty, expectation: "std::unordered_multiset is empty");
530
531 std::unordered_multiset<int> numbers {12345, 67890, 222333, 12345};
532 ComparePrettyPrintToRegex(value: numbers,
533 expectation: "std::unordered_multiset with 4 elements = ");
534 ComparePrettyPrintToRegex(value: numbers, expectation: ".*12345.*12345.*");
535 ComparePrettyPrintToRegex(value: numbers, expectation: ".*67890.*");
536 ComparePrettyPrintToRegex(value: numbers, expectation: ".*222333.*");
537
538 std::unordered_multiset<std::string> colors {"red", "blue", "green", "red"};
539 ComparePrettyPrintToRegex(value: colors,
540 expectation: "std::unordered_multiset with 4 elements = ");
541 ComparePrettyPrintToRegex(value: colors, expectation: R"(.*"red".*"red".*)");
542 ComparePrettyPrintToRegex(value: colors, expectation: R"(.*"blue".*)");
543 ComparePrettyPrintToRegex(value: colors, expectation: R"(.*"green".*)");
544}
545
546void unordered_map_test() {
547 std::unordered_map<int, int> i_am_empty;
548 ComparePrettyPrintToChars(value: i_am_empty, expectation: "std::unordered_map is empty");
549
550 std::unordered_map<int, std::string> one_two_three;
551 one_two_three.insert(x: {1, "one"});
552 one_two_three.insert(x: {2, "two"});
553 one_two_three.insert(x: {3, "three"});
554 ComparePrettyPrintToRegex(value: one_two_three,
555 expectation: "std::unordered_map with 3 elements = ");
556 ComparePrettyPrintToRegex(value: one_two_three, expectation: R"(.*\[1\] = "one".*)");
557 ComparePrettyPrintToRegex(value: one_two_three, expectation: R"(.*\[2\] = "two".*)");
558 ComparePrettyPrintToRegex(value: one_two_three, expectation: R"(.*\[3\] = "three".*)");
559}
560
561void unordered_multimap_test() {
562 std::unordered_multimap<int, int> i_am_empty;
563 ComparePrettyPrintToChars(value: i_am_empty, expectation: "std::unordered_multimap is empty");
564
565 std::unordered_multimap<int, std::string> one_two_three;
566 one_two_three.insert(x: {1, "one"});
567 one_two_three.insert(x: {2, "two"});
568 one_two_three.insert(x: {3, "three"});
569 one_two_three.insert(x: {2, "two"});
570 ComparePrettyPrintToRegex(value: one_two_three,
571 expectation: "std::unordered_multimap with 4 elements = ");
572 ComparePrettyPrintToRegex(value: one_two_three, expectation: R"(.*\[1\] = "one".*)");
573 ComparePrettyPrintToRegex(value: one_two_three, expectation: R"(.*\[2\] = "two".*\[2\] = "two")");
574 ComparePrettyPrintToRegex(value: one_two_three, expectation: R"(.*\[3\] = "three".*)");
575}
576
577void unordered_map_iterator_test() {
578 std::unordered_map<int, int> ones_to_eights;
579 ones_to_eights.insert(x: {1, 8});
580 ones_to_eights.insert(x: {11, 88});
581 ones_to_eights.insert(x: {111, 888});
582
583 auto ones_to_eights_begin = ones_to_eights.begin();
584 MarkAsLive(ones_to_eights_begin);
585 CompareExpressionPrettyPrintToRegex(value: "ones_to_eights_begin",
586 expectation: R"(std::__hash_map_iterator = {\[1+\] = 8+})");
587
588 auto not_found = ones_to_eights.find(x: 5);
589 MarkAsLive(not_found);
590 CompareExpressionPrettyPrintToRegex(value: "not_found",
591 expectation: R"(std::__hash_map_iterator = end\(\))");
592}
593
594void unordered_set_iterator_test() {
595 std::unordered_set<int> ones;
596 ones.insert(x: 111);
597 ones.insert(x: 1111);
598 ones.insert(x: 11111);
599
600 auto ones_begin = ones.begin();
601 MarkAsLive(ones_begin);
602 CompareExpressionPrettyPrintToRegex(value: "ones_begin",
603 expectation: R"(std::__hash_const_iterator = {1+})");
604
605 auto not_found = ones.find(x: 5);
606 MarkAsLive(not_found);
607 CompareExpressionPrettyPrintToRegex(value: "not_found",
608 expectation: R"(std::__hash_const_iterator = end\(\))");
609}
610
611// Check that libc++ pretty printers do not handle pointers.
612void 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(value: int_ptr, expectation: R"(\(int \*\) 0x[a-f0-9]+)");
617}
618
619void 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>(args: 5);
624 // The python regular expression matcher treats newlines as significant, so
625 // these regular expressions should be on one line.
626 ComparePrettyPrintToRegex(
627 value: test0,
628 expectation: 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 value: test1,
633 expectation: 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 value: test0,
639 expectation: R"(std::shared_ptr<int> count [3\?], weak [1\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
640 }
641
642 ComparePrettyPrintToRegex(
643 value: test0,
644 expectation: 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(value: test3, expectation: "std::shared_ptr is nullptr");
648}
649
650void streampos_test() {
651 std::streampos test0 = 67;
652 ComparePrettyPrintToRegex(value: test0, expectation: "^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(value: test1, expectation: "^std::fpos with stream offset:0( with state: {count:0 value:0})?$");
656 std::unique_ptr<char[]> buffer(new char[5]);
657 input.read(s: buffer.get(), n: 5);
658 test1 = input.tellg();
659 ComparePrettyPrintToRegex(value: test1, expectation: "^std::fpos with stream offset:5( with state: {count:0 value:0})?$");
660}
661
662int 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

source code of libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp