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