1 //===- unittests/AST/DeclPrinterTest.cpp --- Declaration printer tests ----===// 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 // This file contains tests for Decl::print() and related methods. 10 // 11 // Search this file for WRONG to see test cases that are producing something 12 // completely wrong, invalid C++ or just misleading. 13 // 14 // These tests have a coding convention: 15 // * declaration to be printed is named 'A' unless it should have some special 16 // name (e.g., 'operator+'); 17 // * additional helper declarations are 'Z', 'Y', 'X' and so on. 18 // 19 //===----------------------------------------------------------------------===// 20 21 #include "ASTPrint.h" 22 #include "clang/AST/ASTContext.h" 23 #include "clang/ASTMatchers/ASTMatchFinder.h" 24 #include "clang/ASTMatchers/ASTMatchers.h" 25 #include "clang/Tooling/Tooling.h" 26 #include "llvm/ADT/SmallString.h" 27 #include "llvm/ADT/StringRef.h" 28 #include "gtest/gtest.h" 29 30 using namespace clang; 31 using namespace ast_matchers; 32 using namespace tooling; 33 34 namespace { 35 36 void PrintDecl(raw_ostream &Out, const ASTContext *Context, const Decl *D, 37 PrintingPolicyAdjuster PolicyModifier) { 38 PrintingPolicy Policy = Context->getPrintingPolicy(); 39 Policy.TerseOutput = true; 40 Policy.Indentation = 0; 41 if (PolicyModifier) 42 PolicyModifier(Policy); 43 D->print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ false); 44 } 45 46 ::testing::AssertionResult 47 PrintedDeclMatches(StringRef Code, const std::vector<std::string> &Args, 48 const DeclarationMatcher &NodeMatch, 49 StringRef ExpectedPrinted, StringRef FileName, 50 PrintingPolicyAdjuster PolicyModifier = nullptr, 51 bool AllowError = false) { 52 return PrintedNodeMatches<Decl>( 53 Code, Args, NodeMatch, ExpectedPrinted, FileName, PrintDecl, 54 PolicyModifier, AllowError, 55 // Filter out implicit decls 56 [](const Decl *D) { return !D->isImplicit(); }); 57 } 58 59 ::testing::AssertionResult 60 PrintedDeclCXX98Matches(StringRef Code, StringRef DeclName, 61 StringRef ExpectedPrinted, 62 PrintingPolicyAdjuster PolicyModifier = nullptr) { 63 std::vector<std::string> Args(1, "-std=c++98"); 64 return PrintedDeclMatches(Code, Args, namedDecl(hasName(DeclName)).bind("id"), 65 ExpectedPrinted, "input.cc", PolicyModifier); 66 } 67 68 ::testing::AssertionResult 69 PrintedDeclCXX98Matches(StringRef Code, const DeclarationMatcher &NodeMatch, 70 StringRef ExpectedPrinted, 71 PrintingPolicyAdjuster PolicyModifier = nullptr) { 72 std::vector<std::string> Args(1, "-std=c++98"); 73 return PrintedDeclMatches(Code, 74 Args, 75 NodeMatch, 76 ExpectedPrinted, 77 "input.cc", 78 PolicyModifier); 79 } 80 81 ::testing::AssertionResult PrintedDeclCXX11Matches(StringRef Code, 82 StringRef DeclName, 83 StringRef ExpectedPrinted) { 84 std::vector<std::string> Args(1, "-std=c++11"); 85 return PrintedDeclMatches(Code, Args, namedDecl(hasName(DeclName)).bind("id"), 86 ExpectedPrinted, "input.cc"); 87 } 88 89 ::testing::AssertionResult PrintedDeclCXX11Matches( 90 StringRef Code, 91 const DeclarationMatcher &NodeMatch, 92 StringRef ExpectedPrinted) { 93 std::vector<std::string> Args(1, "-std=c++11"); 94 return PrintedDeclMatches(Code, 95 Args, 96 NodeMatch, 97 ExpectedPrinted, 98 "input.cc"); 99 } 100 101 ::testing::AssertionResult PrintedDeclCXX11nonMSCMatches( 102 StringRef Code, 103 const DeclarationMatcher &NodeMatch, 104 StringRef ExpectedPrinted) { 105 std::vector<std::string> Args{"-std=c++11", "-fno-delayed-template-parsing"}; 106 return PrintedDeclMatches(Code, 107 Args, 108 NodeMatch, 109 ExpectedPrinted, 110 "input.cc"); 111 } 112 113 ::testing::AssertionResult 114 PrintedDeclCXX17Matches(StringRef Code, const DeclarationMatcher &NodeMatch, 115 StringRef ExpectedPrinted, 116 PrintingPolicyAdjuster PolicyModifier = nullptr) { 117 std::vector<std::string> Args{"-std=c++17", "-fno-delayed-template-parsing"}; 118 return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.cc", 119 PolicyModifier); 120 } 121 122 ::testing::AssertionResult 123 PrintedDeclC11Matches(StringRef Code, const DeclarationMatcher &NodeMatch, 124 StringRef ExpectedPrinted, 125 PrintingPolicyAdjuster PolicyModifier = nullptr) { 126 std::vector<std::string> Args(1, "-std=c11"); 127 return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.c", 128 PolicyModifier); 129 } 130 131 ::testing::AssertionResult 132 PrintedDeclObjCMatches(StringRef Code, const DeclarationMatcher &NodeMatch, 133 StringRef ExpectedPrinted, bool AllowError = false) { 134 std::vector<std::string> Args(1, ""); 135 return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.m", 136 /*PolicyModifier=*/nullptr, AllowError); 137 } 138 139 } // unnamed namespace 140 141 TEST(DeclPrinter, TestTypedef1) { 142 ASSERT_TRUE(PrintedDeclCXX98Matches( 143 "typedef int A;", 144 "A", 145 "typedef int A")); 146 // Should be: with semicolon 147 } 148 149 TEST(DeclPrinter, TestTypedef2) { 150 ASSERT_TRUE(PrintedDeclCXX98Matches( 151 "typedef const char *A;", 152 "A", 153 "typedef const char *A")); 154 // Should be: with semicolon 155 } 156 157 TEST(DeclPrinter, TestTypedef3) { 158 ASSERT_TRUE(PrintedDeclCXX98Matches( 159 "template <typename Y> class X {};" 160 "typedef X<int> A;", 161 "A", 162 "typedef X<int> A")); 163 // Should be: with semicolon 164 } 165 166 TEST(DeclPrinter, TestTypedef4) { 167 ASSERT_TRUE(PrintedDeclCXX98Matches( 168 "namespace X { class Y {}; }" 169 "typedef X::Y A;", 170 "A", 171 "typedef X::Y A")); 172 // Should be: with semicolon 173 } 174 175 TEST(DeclPrinter, TestNamespace1) { 176 ASSERT_TRUE(PrintedDeclCXX98Matches( 177 "namespace A { int B; }", 178 "A", 179 "namespace A {\n}")); 180 // Should be: with { ... } 181 } 182 183 TEST(DeclPrinter, TestNamespace2) { 184 ASSERT_TRUE(PrintedDeclCXX11Matches( 185 "inline namespace A { int B; }", 186 "A", 187 "inline namespace A {\n}")); 188 // Should be: with { ... } 189 } 190 191 TEST(DeclPrinter, TestNamespaceAlias1) { 192 ASSERT_TRUE(PrintedDeclCXX98Matches( 193 "namespace Z { }" 194 "namespace A = Z;", 195 "A", 196 "namespace A = Z")); 197 // Should be: with semicolon 198 } 199 200 TEST(DeclPrinter, TestNamespaceAlias2) { 201 ASSERT_TRUE(PrintedDeclCXX98Matches( 202 "namespace X { namespace Y {} }" 203 "namespace A = X::Y;", 204 "A", 205 "namespace A = X::Y")); 206 // Should be: with semicolon 207 } 208 209 TEST(DeclPrinter, TestNamespaceUnnamed) { 210 ASSERT_TRUE(PrintedDeclCXX17Matches( 211 "namespace { int X; }", 212 namespaceDecl(has(varDecl(hasName("X")))).bind("id"), 213 "namespace {\nint X;\n}", 214 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 215 } 216 217 TEST(DeclPrinter, TestNamespaceUsingDirective) { 218 ASSERT_TRUE(PrintedDeclCXX17Matches( 219 "namespace X { namespace A {} }" 220 "using namespace X::A;", 221 usingDirectiveDecl().bind("id"), "using namespace X::A", 222 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 223 } 224 225 TEST(DeclPrinter, TestEnumDecl1) { 226 ASSERT_TRUE(PrintedDeclCXX17Matches( 227 "enum A { a0, a1, a2 };", enumDecl(hasName("A")).bind("id"), 228 "enum A {\na0,\na1,\na2\n}", 229 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 230 } 231 232 TEST(DeclPrinter, TestEnumDecl2) { 233 ASSERT_TRUE(PrintedDeclCXX17Matches( 234 "enum A { a0 = -1, a1, a2 = 1 };", enumDecl(hasName("A")).bind("id"), 235 "enum A {\na0 = -1,\na1,\na2 = 1\n}", 236 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 237 } 238 239 TEST(DeclPrinter, TestEnumDecl3) { 240 ASSERT_TRUE(PrintedDeclCXX17Matches( 241 "enum { a0, a1, a2 };", 242 enumDecl(has(enumConstantDecl(hasName("a0")))).bind("id"), 243 "enum {\na0,\na1,\na2\n}", 244 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 245 } 246 247 TEST(DeclPrinter, TestEnumDecl4) { 248 ASSERT_TRUE(PrintedDeclCXX17Matches( 249 "enum class A { a0, a1, a2 };", enumDecl(hasName("A")).bind("id"), 250 "enum class A : int {\na0,\na1,\na2\n}", 251 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 252 } 253 254 TEST(DeclPrinter, TestRecordDecl1) { 255 ASSERT_TRUE(PrintedDeclC11Matches( 256 "struct A { int a; };", recordDecl(hasName("A")).bind("id"), 257 "struct A {\nint a;\n}", 258 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 259 } 260 261 TEST(DeclPrinter, TestRecordDecl2) { 262 ASSERT_TRUE(PrintedDeclC11Matches( 263 "struct A { struct { int i; }; };", recordDecl(hasName("A")).bind("id"), 264 "struct A {\nstruct {\nint i;\n};\n}", 265 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 266 } 267 268 TEST(DeclPrinter, TestRecordDecl3) { 269 ASSERT_TRUE(PrintedDeclC11Matches( 270 "union { int A; } u;", 271 recordDecl(has(fieldDecl(hasName("A")))).bind("id"), "union {\nint A;\n}", 272 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 273 } 274 275 TEST(DeclPrinter, TestCXXRecordDecl1) { 276 ASSERT_TRUE(PrintedDeclCXX98Matches( 277 "class A { int a; };", 278 "A", 279 "class A {}")); 280 } 281 282 TEST(DeclPrinter, TestCXXRecordDecl2) { 283 ASSERT_TRUE(PrintedDeclCXX98Matches( 284 "struct A { int a; };", 285 "A", 286 "struct A {}")); 287 } 288 289 TEST(DeclPrinter, TestCXXRecordDecl3) { 290 ASSERT_TRUE(PrintedDeclCXX98Matches( 291 "union A { int a; };", 292 "A", 293 "union A {}")); 294 } 295 296 TEST(DeclPrinter, TestCXXRecordDecl4) { 297 ASSERT_TRUE(PrintedDeclCXX98Matches( 298 "class Z { int a; };" 299 "class A : Z { int b; };", 300 "A", 301 "class A : Z {}")); 302 } 303 304 TEST(DeclPrinter, TestCXXRecordDecl5) { 305 ASSERT_TRUE(PrintedDeclCXX98Matches( 306 "struct Z { int a; };" 307 "struct A : Z { int b; };", 308 "A", 309 "struct A : Z {}")); 310 } 311 312 TEST(DeclPrinter, TestCXXRecordDecl6) { 313 ASSERT_TRUE(PrintedDeclCXX98Matches( 314 "class Z { int a; };" 315 "class A : public Z { int b; };", 316 "A", 317 "class A : public Z {}")); 318 } 319 320 TEST(DeclPrinter, TestCXXRecordDecl7) { 321 ASSERT_TRUE(PrintedDeclCXX98Matches( 322 "class Z { int a; };" 323 "class A : protected Z { int b; };", 324 "A", 325 "class A : protected Z {}")); 326 } 327 328 TEST(DeclPrinter, TestCXXRecordDecl8) { 329 ASSERT_TRUE(PrintedDeclCXX98Matches( 330 "class Z { int a; };" 331 "class A : private Z { int b; };", 332 "A", 333 "class A : private Z {}")); 334 } 335 336 TEST(DeclPrinter, TestCXXRecordDecl9) { 337 ASSERT_TRUE(PrintedDeclCXX98Matches( 338 "class Z { int a; };" 339 "class A : virtual Z { int b; };", 340 "A", 341 "class A : virtual Z {}")); 342 } 343 344 TEST(DeclPrinter, TestCXXRecordDecl10) { 345 ASSERT_TRUE(PrintedDeclCXX98Matches( 346 "class Z { int a; };" 347 "class A : virtual public Z { int b; };", 348 "A", 349 "class A : virtual public Z {}")); 350 } 351 352 TEST(DeclPrinter, TestCXXRecordDecl11) { 353 ASSERT_TRUE(PrintedDeclCXX98Matches( 354 "class Z { int a; };" 355 "class Y : virtual public Z { int b; };" 356 "class A : virtual public Z, private Y { int c; };", 357 "A", 358 "class A : virtual public Z, private Y {}")); 359 } 360 361 TEST(DeclPrinter, TestFunctionDecl1) { 362 ASSERT_TRUE(PrintedDeclCXX98Matches( 363 "void A();", 364 "A", 365 "void A()")); 366 } 367 368 TEST(DeclPrinter, TestFreeFunctionDecl_FullyQualifiedName) { 369 ASSERT_TRUE(PrintedDeclCXX98Matches( 370 "void A();", 371 "A", 372 "void A()", 373 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); 374 } 375 376 TEST(DeclPrinter, TestFreeFunctionDeclInNamespace_FullyQualifiedName) { 377 ASSERT_TRUE(PrintedDeclCXX98Matches( 378 "namespace X { void A(); };", 379 "A", 380 "void X::A()", 381 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); 382 } 383 384 TEST(DeclPrinter, TestMemberFunction_FullyQualifiedName) { 385 ASSERT_TRUE(PrintedDeclCXX98Matches( 386 "struct X { void A(); };", 387 "A", 388 "void X::A()", 389 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); 390 } 391 392 TEST(DeclPrinter, TestMemberFunctionInNamespace_FullyQualifiedName) { 393 ASSERT_TRUE(PrintedDeclCXX98Matches( 394 "namespace Z { struct X { void A(); }; }", 395 "A", 396 "void Z::X::A()", 397 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); 398 } 399 400 TEST(DeclPrinter, TestMemberFunctionOutside_FullyQualifiedName) { 401 ASSERT_TRUE(PrintedDeclCXX98Matches( 402 "struct X { void A(); };" 403 "void X::A() {}", 404 functionDecl(hasName("A"), isDefinition()).bind("id"), 405 "void X::A()", 406 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); 407 } 408 409 TEST(DeclPrinter, TestFunctionDecl2) { 410 ASSERT_TRUE(PrintedDeclCXX98Matches( 411 "void A() {}", 412 "A", 413 "void A()")); 414 } 415 416 TEST(DeclPrinter, TestFunctionDecl3) { 417 ASSERT_TRUE(PrintedDeclCXX98Matches( 418 "void Z();" 419 "void A() { Z(); }", 420 "A", 421 "void A()")); 422 } 423 424 TEST(DeclPrinter, TestFunctionDecl4) { 425 ASSERT_TRUE(PrintedDeclCXX98Matches( 426 "extern void A();", 427 "A", 428 "extern void A()")); 429 } 430 431 TEST(DeclPrinter, TestFunctionDecl5) { 432 ASSERT_TRUE(PrintedDeclCXX98Matches( 433 "static void A();", 434 "A", 435 "static void A()")); 436 } 437 438 TEST(DeclPrinter, TestFunctionDecl6) { 439 ASSERT_TRUE(PrintedDeclCXX98Matches( 440 "inline void A();", 441 "A", 442 "inline void A()")); 443 } 444 445 TEST(DeclPrinter, TestFunctionDecl7) { 446 ASSERT_TRUE(PrintedDeclCXX11Matches( 447 "constexpr int A(int a);", 448 "A", 449 "constexpr int A(int a)")); 450 } 451 452 TEST(DeclPrinter, TestFunctionDecl8) { 453 ASSERT_TRUE(PrintedDeclCXX98Matches( 454 "void A(int a);", 455 "A", 456 "void A(int a)")); 457 } 458 459 TEST(DeclPrinter, TestFunctionDecl9) { 460 ASSERT_TRUE(PrintedDeclCXX98Matches( 461 "void A(...);", 462 "A", 463 "void A(...)")); 464 } 465 466 TEST(DeclPrinter, TestFunctionDecl10) { 467 ASSERT_TRUE(PrintedDeclCXX98Matches( 468 "void A(int a, ...);", 469 "A", 470 "void A(int a, ...)")); 471 } 472 473 TEST(DeclPrinter, TestFunctionDecl11) { 474 ASSERT_TRUE(PrintedDeclCXX98Matches( 475 "typedef long ssize_t;" 476 "typedef int *pInt;" 477 "void A(int a, pInt b, ssize_t c);", 478 "A", 479 "void A(int a, pInt b, ssize_t c)")); 480 } 481 482 TEST(DeclPrinter, TestFunctionDecl12) { 483 ASSERT_TRUE(PrintedDeclCXX98Matches( 484 "void A(int a, int b = 0);", 485 "A", 486 "void A(int a, int b = 0)")); 487 } 488 489 TEST(DeclPrinter, TestFunctionDecl13) { 490 ASSERT_TRUE(PrintedDeclCXX98Matches( 491 "void (*A(int a))(int b);", 492 "A", 493 "void (*A(int a))(int)")); 494 // Should be: with parameter name (?) 495 } 496 497 TEST(DeclPrinter, TestFunctionDecl14) { 498 ASSERT_TRUE(PrintedDeclCXX98Matches( 499 "template<typename T>" 500 "void A(T t) { }" 501 "template<>" 502 "void A(int N) { }", 503 functionDecl(hasName("A"), isExplicitTemplateSpecialization()).bind("id"), 504 "template<> void A<int>(int N)")); 505 } 506 507 508 TEST(DeclPrinter, TestCXXConstructorDecl1) { 509 ASSERT_TRUE(PrintedDeclCXX98Matches( 510 "struct A {" 511 " A();" 512 "};", 513 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 514 "A()")); 515 } 516 517 TEST(DeclPrinter, TestCXXConstructorDecl2) { 518 ASSERT_TRUE(PrintedDeclCXX98Matches( 519 "struct A {" 520 " A(int a);" 521 "};", 522 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 523 "A(int a)")); 524 } 525 526 TEST(DeclPrinter, TestCXXConstructorDecl3) { 527 ASSERT_TRUE(PrintedDeclCXX98Matches( 528 "struct A {" 529 " A(const A &a);" 530 "};", 531 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 532 "A(const A &a)")); 533 } 534 535 TEST(DeclPrinter, TestCXXConstructorDecl4) { 536 ASSERT_TRUE(PrintedDeclCXX98Matches( 537 "struct A {" 538 " A(const A &a, int = 0);" 539 "};", 540 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 541 "A(const A &a, int = 0)")); 542 } 543 544 TEST(DeclPrinter, TestCXXConstructorDeclWithMemberInitializer) { 545 ASSERT_TRUE(PrintedDeclCXX98Matches( 546 "struct A {" 547 " int m;" 548 " A() : m(2) {}" 549 "};", 550 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 551 "A()")); 552 } 553 554 TEST(DeclPrinter, TestCXXConstructorDeclWithMemberInitializer_NoTerseOutput) { 555 ASSERT_TRUE(PrintedDeclCXX98Matches( 556 "struct A {" 557 " int m;" 558 " A() : m(2) {}" 559 "};", 560 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 561 "A() : m(2) {\n}\n", 562 [](PrintingPolicy &Policy){ Policy.TerseOutput = false; })); 563 } 564 565 TEST(DeclPrinter, TestCXXConstructorDecl5) { 566 ASSERT_TRUE(PrintedDeclCXX11Matches( 567 "struct A {" 568 " A(const A &&a);" 569 "};", 570 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 571 "A(const A &&a)")); 572 } 573 574 TEST(DeclPrinter, TestCXXConstructorDecl6) { 575 ASSERT_TRUE(PrintedDeclCXX98Matches( 576 "struct A {" 577 " explicit A(int a);" 578 "};", 579 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 580 "explicit A(int a)")); 581 } 582 583 TEST(DeclPrinter, TestCXXConstructorDecl7) { 584 ASSERT_TRUE(PrintedDeclCXX11Matches( 585 "struct A {" 586 " constexpr A();" 587 "};", 588 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 589 "constexpr A()")); 590 } 591 592 TEST(DeclPrinter, TestCXXConstructorDecl8) { 593 ASSERT_TRUE(PrintedDeclCXX11Matches( 594 "struct A {" 595 " A() = default;" 596 "};", 597 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 598 "A() = default")); 599 } 600 601 TEST(DeclPrinter, TestCXXConstructorDecl9) { 602 ASSERT_TRUE(PrintedDeclCXX11Matches( 603 "struct A {" 604 " A() = delete;" 605 "};", 606 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 607 "A() = delete")); 608 } 609 610 TEST(DeclPrinter, TestCXXConstructorDecl10) { 611 ASSERT_TRUE(PrintedDeclCXX11Matches( 612 "template<typename... T>" 613 "struct A {" 614 " A(const A &a);" 615 "};", 616 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 617 "A<T...>(const A<T...> &a)")); 618 } 619 620 TEST(DeclPrinter, TestCXXConstructorDecl11) { 621 ASSERT_TRUE(PrintedDeclCXX11nonMSCMatches( 622 "template<typename... T>" 623 "struct A : public T... {" 624 " A(T&&... ts) : T(ts)... {}" 625 "};", 626 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 627 "A<T...>(T &&...ts)")); 628 } 629 630 TEST(DeclPrinter, TestCXXDestructorDecl1) { 631 ASSERT_TRUE(PrintedDeclCXX98Matches( 632 "struct A {" 633 " ~A();" 634 "};", 635 cxxDestructorDecl(ofClass(hasName("A"))).bind("id"), 636 "~A()")); 637 } 638 639 TEST(DeclPrinter, TestCXXDestructorDecl2) { 640 ASSERT_TRUE(PrintedDeclCXX98Matches( 641 "struct A {" 642 " virtual ~A();" 643 "};", 644 cxxDestructorDecl(ofClass(hasName("A"))).bind("id"), 645 "virtual ~A()")); 646 } 647 648 TEST(DeclPrinter, TestCXXConversionDecl1) { 649 ASSERT_TRUE(PrintedDeclCXX98Matches( 650 "struct A {" 651 " operator int();" 652 "};", 653 cxxMethodDecl(ofClass(hasName("A"))).bind("id"), 654 "operator int()")); 655 } 656 657 TEST(DeclPrinter, TestCXXConversionDecl2) { 658 ASSERT_TRUE(PrintedDeclCXX98Matches( 659 "struct A {" 660 " operator bool();" 661 "};", 662 cxxMethodDecl(ofClass(hasName("A"))).bind("id"), 663 "operator bool()")); 664 } 665 666 TEST(DeclPrinter, TestCXXConversionDecl3) { 667 ASSERT_TRUE(PrintedDeclCXX98Matches( 668 "struct Z {};" 669 "struct A {" 670 " operator Z();" 671 "};", 672 cxxMethodDecl(ofClass(hasName("A"))).bind("id"), 673 "operator Z()")); 674 } 675 676 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) { 677 ASSERT_TRUE(PrintedDeclCXX11Matches( 678 "namespace std { typedef decltype(sizeof(int)) size_t; }" 679 "struct Z {" 680 " void *operator new(std::size_t);" 681 "};", 682 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 683 "void *operator new(std::size_t)")); 684 } 685 686 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction2) { 687 ASSERT_TRUE(PrintedDeclCXX11Matches( 688 "namespace std { typedef decltype(sizeof(int)) size_t; }" 689 "struct Z {" 690 " void *operator new[](std::size_t);" 691 "};", 692 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 693 "void *operator new[](std::size_t)")); 694 } 695 696 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction3) { 697 ASSERT_TRUE(PrintedDeclCXX11Matches( 698 "struct Z {" 699 " void operator delete(void *);" 700 "};", 701 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 702 "void operator delete(void *) noexcept")); 703 // Should be: without noexcept? 704 } 705 706 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction4) { 707 ASSERT_TRUE(PrintedDeclCXX98Matches( 708 "struct Z {" 709 " void operator delete(void *);" 710 "};", 711 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 712 "void operator delete(void *)")); 713 } 714 715 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction5) { 716 ASSERT_TRUE(PrintedDeclCXX11Matches( 717 "struct Z {" 718 " void operator delete[](void *);" 719 "};", 720 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 721 "void operator delete[](void *) noexcept")); 722 // Should be: without noexcept? 723 } 724 725 TEST(DeclPrinter, TestCXXMethodDecl_Operator1) { 726 const char *OperatorNames[] = { 727 "+", "-", "*", "/", "%", "^", "&", "|", 728 "=", "<", ">", "+=", "-=", "*=", "/=", "%=", 729 "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==", "!=", 730 "<=", ">=", "&&", "||", ",", "->*", 731 "()", "[]" 732 }; 733 734 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) { 735 SmallString<128> Code; 736 Code.append("struct Z { void operator"); 737 Code.append(OperatorNames[i]); 738 Code.append("(Z z); };"); 739 740 SmallString<128> Expected; 741 Expected.append("void operator"); 742 Expected.append(OperatorNames[i]); 743 Expected.append("(Z z)"); 744 745 ASSERT_TRUE(PrintedDeclCXX98Matches( 746 Code, 747 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 748 Expected)); 749 } 750 } 751 752 TEST(DeclPrinter, TestCXXMethodDecl_Operator2) { 753 const char *OperatorNames[] = { 754 "~", "!", "++", "--", "->" 755 }; 756 757 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) { 758 SmallString<128> Code; 759 Code.append("struct Z { void operator"); 760 Code.append(OperatorNames[i]); 761 Code.append("(); };"); 762 763 SmallString<128> Expected; 764 Expected.append("void operator"); 765 Expected.append(OperatorNames[i]); 766 Expected.append("()"); 767 768 ASSERT_TRUE(PrintedDeclCXX98Matches( 769 Code, 770 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 771 Expected)); 772 } 773 } 774 775 TEST(DeclPrinter, TestCXXMethodDecl1) { 776 ASSERT_TRUE(PrintedDeclCXX98Matches( 777 "struct Z {" 778 " void A(int a);" 779 "};", 780 "A", 781 "void A(int a)")); 782 } 783 784 TEST(DeclPrinter, TestCXXMethodDecl2) { 785 ASSERT_TRUE(PrintedDeclCXX98Matches( 786 "struct Z {" 787 " virtual void A(int a);" 788 "};", 789 "A", 790 "virtual void A(int a)")); 791 } 792 793 TEST(DeclPrinter, TestCXXMethodDecl3) { 794 ASSERT_TRUE(PrintedDeclCXX98Matches( 795 "struct Z {" 796 " virtual void A(int a);" 797 "};" 798 "struct ZZ : Z {" 799 " void A(int a);" 800 "};", 801 "ZZ::A", 802 "void A(int a)")); 803 // TODO: should we print "virtual"? 804 } 805 806 TEST(DeclPrinter, TestCXXMethodDecl4) { 807 ASSERT_TRUE(PrintedDeclCXX98Matches( 808 "struct Z {" 809 " inline void A(int a);" 810 "};", 811 "A", 812 "inline void A(int a)")); 813 } 814 815 TEST(DeclPrinter, TestCXXMethodDecl5) { 816 ASSERT_TRUE(PrintedDeclCXX98Matches( 817 "struct Z {" 818 " virtual void A(int a) = 0;" 819 "};", 820 "A", 821 "virtual void A(int a) = 0")); 822 } 823 824 TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier1) { 825 ASSERT_TRUE(PrintedDeclCXX98Matches( 826 "struct Z {" 827 " void A(int a) const;" 828 "};", 829 "A", 830 "void A(int a) const")); 831 } 832 833 TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier2) { 834 ASSERT_TRUE(PrintedDeclCXX98Matches( 835 "struct Z {" 836 " void A(int a) volatile;" 837 "};", 838 "A", 839 "void A(int a) volatile")); 840 } 841 842 TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier3) { 843 ASSERT_TRUE(PrintedDeclCXX98Matches( 844 "struct Z {" 845 " void A(int a) const volatile;" 846 "};", 847 "A", 848 "void A(int a) const volatile")); 849 } 850 851 TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier1) { 852 ASSERT_TRUE(PrintedDeclCXX11Matches( 853 "struct Z {" 854 " void A(int a) &;" 855 "};", 856 "A", 857 "void A(int a) &")); 858 } 859 860 TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) { 861 ASSERT_TRUE(PrintedDeclCXX11Matches( 862 "struct Z {" 863 " void A(int a) &&;" 864 "};", 865 "A", 866 "void A(int a) &&")); 867 } 868 869 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) { 870 ASSERT_TRUE(PrintedDeclCXX98Matches( 871 "struct Z {" 872 " void A(int a) throw();" 873 "};", 874 "A", 875 "void A(int a) throw()")); 876 } 877 878 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification2) { 879 ASSERT_TRUE(PrintedDeclCXX98Matches( 880 "struct Z {" 881 " void A(int a) throw(int);" 882 "};", 883 "A", 884 "void A(int a) throw(int)")); 885 } 886 887 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification3) { 888 ASSERT_TRUE(PrintedDeclCXX98Matches( 889 "class ZZ {};" 890 "struct Z {" 891 " void A(int a) throw(ZZ, int);" 892 "};", 893 "A", 894 "void A(int a) throw(ZZ, int)")); 895 } 896 897 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification4) { 898 ASSERT_TRUE(PrintedDeclCXX11Matches( 899 "struct Z {" 900 " void A(int a) noexcept;" 901 "};", 902 "A", 903 "void A(int a) noexcept")); 904 } 905 906 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification5) { 907 ASSERT_TRUE(PrintedDeclCXX11Matches( 908 "struct Z {" 909 " void A(int a) noexcept(true);" 910 "};", 911 "A", 912 "void A(int a) noexcept(true)")); 913 } 914 915 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification6) { 916 ASSERT_TRUE(PrintedDeclCXX11Matches( 917 "struct Z {" 918 " void A(int a) noexcept(1 < 2);" 919 "};", 920 "A", 921 "void A(int a) noexcept(1 < 2)")); 922 } 923 924 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification7) { 925 ASSERT_TRUE(PrintedDeclCXX11Matches( 926 "template<int N>" 927 "struct Z {" 928 " void A(int a) noexcept(N < 2);" 929 "};", 930 "A", 931 "void A(int a) noexcept(N < 2)")); 932 } 933 934 TEST(DeclPrinter, TestVarDecl1) { 935 ASSERT_TRUE(PrintedDeclCXX98Matches( 936 "char *const (*(*A)[5])(int);", 937 "A", 938 "char *const (*(*A)[5])(int)")); 939 // Should be: with semicolon 940 } 941 942 TEST(DeclPrinter, TestVarDecl2) { 943 ASSERT_TRUE(PrintedDeclCXX98Matches( 944 "void (*A)() throw(int);", 945 "A", 946 "void (*A)() throw(int)")); 947 // Should be: with semicolon 948 } 949 950 TEST(DeclPrinter, TestVarDecl3) { 951 ASSERT_TRUE(PrintedDeclCXX11Matches( 952 "void (*A)() noexcept;", 953 "A", 954 "void (*A)() noexcept")); 955 // Should be: with semicolon 956 } 957 958 TEST(DeclPrinter, TestFieldDecl1) { 959 ASSERT_TRUE(PrintedDeclCXX98Matches( 960 "template<typename T>" 961 "struct Z { T A; };", 962 "A", 963 "T A")); 964 // Should be: with semicolon 965 } 966 967 TEST(DeclPrinter, TestFieldDecl2) { 968 ASSERT_TRUE(PrintedDeclCXX98Matches( 969 "template<int N>" 970 "struct Z { int A[N]; };", 971 "A", 972 "int A[N]")); 973 // Should be: with semicolon 974 } 975 976 TEST(DeclPrinter, TestClassTemplateDecl1) { 977 ASSERT_TRUE(PrintedDeclCXX98Matches( 978 "template<typename T>" 979 "struct A { T a; };", 980 classTemplateDecl(hasName("A")).bind("id"), 981 "template <typename T> struct A {}")); 982 } 983 984 TEST(DeclPrinter, TestClassTemplateDecl2) { 985 ASSERT_TRUE(PrintedDeclCXX98Matches( 986 "template<typename T = int>" 987 "struct A { T a; };", 988 classTemplateDecl(hasName("A")).bind("id"), 989 "template <typename T = int> struct A {}")); 990 } 991 992 TEST(DeclPrinter, TestClassTemplateDecl3) { 993 ASSERT_TRUE(PrintedDeclCXX98Matches( 994 "template<class T>" 995 "struct A { T a; };", 996 classTemplateDecl(hasName("A")).bind("id"), 997 "template <class T> struct A {}")); 998 } 999 1000 TEST(DeclPrinter, TestClassTemplateDecl4) { 1001 ASSERT_TRUE(PrintedDeclCXX98Matches( 1002 "template<typename T, typename U>" 1003 "struct A { T a; U b; };", 1004 classTemplateDecl(hasName("A")).bind("id"), 1005 "template <typename T, typename U> struct A {}")); 1006 } 1007 1008 TEST(DeclPrinter, TestClassTemplateDecl5) { 1009 ASSERT_TRUE(PrintedDeclCXX98Matches( 1010 "template<int N>" 1011 "struct A { int a[N]; };", 1012 classTemplateDecl(hasName("A")).bind("id"), 1013 "template <int N> struct A {}")); 1014 } 1015 1016 TEST(DeclPrinter, TestClassTemplateDecl6) { 1017 ASSERT_TRUE(PrintedDeclCXX98Matches( 1018 "template<int N = 42>" 1019 "struct A { int a[N]; };", 1020 classTemplateDecl(hasName("A")).bind("id"), 1021 "template <int N = 42> struct A {}")); 1022 } 1023 1024 TEST(DeclPrinter, TestClassTemplateDecl7) { 1025 ASSERT_TRUE(PrintedDeclCXX98Matches( 1026 "typedef int MyInt;" 1027 "template<MyInt N>" 1028 "struct A { int a[N]; };", 1029 classTemplateDecl(hasName("A")).bind("id"), 1030 "template <MyInt N> struct A {}")); 1031 } 1032 1033 TEST(DeclPrinter, TestClassTemplateDecl8) { 1034 ASSERT_TRUE(PrintedDeclCXX98Matches( 1035 "template<template<typename U> class T> struct A { };", 1036 classTemplateDecl(hasName("A")).bind("id"), 1037 "template <template <typename U> class T> struct A {}")); 1038 } 1039 1040 TEST(DeclPrinter, TestClassTemplateDecl9) { 1041 ASSERT_TRUE(PrintedDeclCXX98Matches( 1042 "template<typename T> struct Z { };" 1043 "template<template<typename U> class T = Z> struct A { };", 1044 classTemplateDecl(hasName("A")).bind("id"), 1045 "template <template <typename U> class T> struct A {}")); 1046 } 1047 1048 TEST(DeclPrinter, TestClassTemplateDecl10) { 1049 ASSERT_TRUE(PrintedDeclCXX11Matches( 1050 "template<typename... T>" 1051 "struct A { int a; };", 1052 classTemplateDecl(hasName("A")).bind("id"), 1053 "template <typename ...T> struct A {}")); 1054 } 1055 1056 TEST(DeclPrinter, TestClassTemplateDecl11) { 1057 ASSERT_TRUE(PrintedDeclCXX11Matches( 1058 "template<typename... T>" 1059 "struct A : public T... { int a; };", 1060 classTemplateDecl(hasName("A")).bind("id"), 1061 "template <typename ...T> struct A : public T... {}")); 1062 } 1063 1064 TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl1) { 1065 ASSERT_TRUE(PrintedDeclCXX98Matches( 1066 "template<typename T, typename U>" 1067 "struct A { T a; U b; };" 1068 "template<typename T>" 1069 "struct A<T, int> { T a; };", 1070 classTemplateSpecializationDecl().bind("id"), 1071 "template <typename T> struct A<T, int> {}")); 1072 } 1073 1074 TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl2) { 1075 ASSERT_TRUE(PrintedDeclCXX98Matches( 1076 "template<typename T>" 1077 "struct A { T a; };" 1078 "template<typename T>" 1079 "struct A<T *> { T a; };", 1080 classTemplateSpecializationDecl().bind("id"), 1081 "template <typename T> struct A<T *> {}")); 1082 } 1083 1084 TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) { 1085 ASSERT_TRUE(PrintedDeclCXX98Matches( 1086 "template<typename T>" 1087 "struct A { T a; };" 1088 "template<>" 1089 "struct A<int> { int a; };", 1090 classTemplateSpecializationDecl().bind("id"), 1091 "template<> struct A<int> {}")); 1092 } 1093 1094 TEST(DeclPrinter, TestFunctionTemplateDecl1) { 1095 ASSERT_TRUE(PrintedDeclCXX98Matches( 1096 "template<typename T>" 1097 "void A(T &t);", 1098 functionTemplateDecl(hasName("A")).bind("id"), 1099 "template <typename T> void A(T &t)")); 1100 } 1101 1102 TEST(DeclPrinter, TestFunctionTemplateDecl2) { 1103 ASSERT_TRUE(PrintedDeclCXX98Matches( 1104 "template<typename T>" 1105 "void A(T &t) { }", 1106 functionTemplateDecl(hasName("A")).bind("id"), 1107 "template <typename T> void A(T &t)")); 1108 } 1109 1110 TEST(DeclPrinter, TestFunctionTemplateDecl3) { 1111 ASSERT_TRUE(PrintedDeclCXX11Matches( 1112 "template<typename... T>" 1113 "void A(T... a);", 1114 functionTemplateDecl(hasName("A")).bind("id"), 1115 "template <typename ...T> void A(T ...a)")); 1116 } 1117 1118 TEST(DeclPrinter, TestFunctionTemplateDecl4) { 1119 ASSERT_TRUE(PrintedDeclCXX98Matches( 1120 "struct Z { template<typename T> void A(T t); };", 1121 functionTemplateDecl(hasName("A")).bind("id"), 1122 "template <typename T> void A(T t)")); 1123 } 1124 1125 TEST(DeclPrinter, TestFunctionTemplateDecl5) { 1126 ASSERT_TRUE(PrintedDeclCXX98Matches( 1127 "struct Z { template<typename T> void A(T t) {} };", 1128 functionTemplateDecl(hasName("A")).bind("id"), 1129 "template <typename T> void A(T t)")); 1130 } 1131 1132 TEST(DeclPrinter, TestFunctionTemplateDecl6) { 1133 ASSERT_TRUE(PrintedDeclCXX98Matches( 1134 "template<typename T >struct Z {" 1135 " template<typename U> void A(U t) {}" 1136 "};", 1137 functionTemplateDecl(hasName("A")).bind("id"), 1138 "template <typename U> void A(U t)")); 1139 } 1140 1141 TEST(DeclPrinter, TestUnnamedTemplateParameters) { 1142 ASSERT_TRUE(PrintedDeclCXX17Matches( 1143 "template <typename, int, template <typename, bool> class> void A();", 1144 functionTemplateDecl(hasName("A")).bind("id"), 1145 "template <typename, int, template <typename, bool> class> void A()")); 1146 } 1147 1148 TEST(DeclPrinter, TestUnnamedTemplateParametersPacks) { 1149 ASSERT_TRUE(PrintedDeclCXX17Matches( 1150 "template <typename ..., int ...," 1151 " template <typename ..., bool ...> class ...> void A();", 1152 functionTemplateDecl(hasName("A")).bind("id"), 1153 "template <typename ..., int ...," 1154 " template <typename ..., bool ...> class ...> void A()")); 1155 } 1156 1157 TEST(DeclPrinter, TestNamedTemplateParametersPacks) { 1158 ASSERT_TRUE(PrintedDeclCXX17Matches( 1159 "template <typename ...T, int ...I," 1160 " template <typename ...X, bool ...B> class ...Z> void A();", 1161 functionTemplateDecl(hasName("A")).bind("id"), 1162 "template <typename ...T, int ...I," 1163 " template <typename ...X, bool ...B> class ...Z> void A()")); 1164 } 1165 1166 TEST(DeclPrinter, TestTemplateTemplateParameterWrittenWithTypename) { 1167 ASSERT_TRUE(PrintedDeclCXX17Matches( 1168 "template <template <typename> typename Z> void A();", 1169 functionTemplateDecl(hasName("A")).bind("id"), 1170 "template <template <typename> class Z> void A()")); 1171 // WRONG: We should use typename if the parameter was written with it. 1172 } 1173 1174 TEST(DeclPrinter, TestTemplateArgumentList1) { 1175 ASSERT_TRUE(PrintedDeclCXX98Matches( 1176 "template<typename T> struct Z {};" 1177 "struct X {};" 1178 "Z<X> A;", 1179 "A", 1180 "Z<X> A")); 1181 // Should be: with semicolon 1182 } 1183 1184 TEST(DeclPrinter, TestTemplateArgumentList2) { 1185 ASSERT_TRUE(PrintedDeclCXX98Matches( 1186 "template<typename T, typename U> struct Z {};" 1187 "struct X {};" 1188 "typedef int Y;" 1189 "Z<X, Y> A;", 1190 "A", 1191 "Z<X, Y> A")); 1192 // Should be: with semicolon 1193 } 1194 1195 TEST(DeclPrinter, TestTemplateArgumentList3) { 1196 ASSERT_TRUE(PrintedDeclCXX98Matches( 1197 "template<typename T> struct Z {};" 1198 "template<typename T> struct X {};" 1199 "Z<X<int> > A;", 1200 "A", 1201 "Z<X<int> > A")); 1202 // Should be: with semicolon 1203 } 1204 1205 TEST(DeclPrinter, TestTemplateArgumentList4) { 1206 ASSERT_TRUE(PrintedDeclCXX11Matches( 1207 "template<typename T> struct Z {};" 1208 "template<typename T> struct X {};" 1209 "Z<X<int>> A;", 1210 "A", 1211 "Z<X<int>> A")); 1212 // Should be: with semicolon 1213 } 1214 1215 TEST(DeclPrinter, TestTemplateArgumentList5) { 1216 ASSERT_TRUE(PrintedDeclCXX98Matches( 1217 "template<typename T> struct Z {};" 1218 "template<typename T> struct X { Z<T> A; };", 1219 "A", 1220 "Z<T> A")); 1221 // Should be: with semicolon 1222 } 1223 1224 TEST(DeclPrinter, TestTemplateArgumentList6) { 1225 ASSERT_TRUE(PrintedDeclCXX98Matches( 1226 "template<template<typename T> class U> struct Z {};" 1227 "template<typename T> struct X {};" 1228 "Z<X> A;", 1229 "A", 1230 "Z<X> A")); 1231 // Should be: with semicolon 1232 } 1233 1234 TEST(DeclPrinter, TestTemplateArgumentList7) { 1235 ASSERT_TRUE(PrintedDeclCXX98Matches( 1236 "template<template<typename T> class U> struct Z {};" 1237 "template<template<typename T> class U> struct Y {" 1238 " Z<U> A;" 1239 "};", 1240 "A", 1241 "Z<U> A")); 1242 // Should be: with semicolon 1243 } 1244 1245 TEST(DeclPrinter, TestTemplateArgumentList8) { 1246 ASSERT_TRUE(PrintedDeclCXX98Matches( 1247 "template<typename T> struct Z {};" 1248 "template<template<typename T> class U> struct Y {" 1249 " Z<U<int> > A;" 1250 "};", 1251 "A", 1252 "Z<U<int> > A")); 1253 // Should be: with semicolon 1254 } 1255 1256 TEST(DeclPrinter, TestTemplateArgumentList9) { 1257 ASSERT_TRUE(PrintedDeclCXX98Matches( 1258 "template<unsigned I> struct Z {};" 1259 "Z<0> A;", 1260 "A", 1261 "Z<0> A")); 1262 // Should be: with semicolon 1263 } 1264 1265 TEST(DeclPrinter, TestTemplateArgumentList10) { 1266 ASSERT_TRUE(PrintedDeclCXX98Matches( 1267 "template<unsigned I> struct Z {};" 1268 "template<unsigned I> struct X { Z<I> A; };", 1269 "A", 1270 "Z<I> A")); 1271 // Should be: with semicolon 1272 } 1273 1274 TEST(DeclPrinter, TestTemplateArgumentList11) { 1275 ASSERT_TRUE(PrintedDeclCXX98Matches( 1276 "template<int I> struct Z {};" 1277 "Z<42 * 10 - 420 / 1> A;", 1278 "A", 1279 "Z<42 * 10 - 420 / 1> A")); 1280 // Should be: with semicolon 1281 } 1282 1283 TEST(DeclPrinter, TestTemplateArgumentList12) { 1284 ASSERT_TRUE(PrintedDeclCXX98Matches( 1285 "template<const char *p> struct Z {};" 1286 "extern const char X[] = \"aaa\";" 1287 "Z<X> A;", 1288 "A", 1289 "Z<X> A")); 1290 // Should be: with semicolon 1291 } 1292 1293 TEST(DeclPrinter, TestTemplateArgumentList13) { 1294 ASSERT_TRUE(PrintedDeclCXX11Matches( 1295 "template<typename... T> struct Z {};" 1296 "template<typename... T> struct X {" 1297 " Z<T...> A;" 1298 "};", 1299 "A", 1300 "Z<T...> A")); 1301 // Should be: with semicolon 1302 } 1303 1304 TEST(DeclPrinter, TestTemplateArgumentList14) { 1305 ASSERT_TRUE(PrintedDeclCXX11Matches( 1306 "template<typename... T> struct Z {};" 1307 "template<typename T> struct Y {};" 1308 "template<typename... T> struct X {" 1309 " Z<Y<T>...> A;" 1310 "};", 1311 "A", 1312 "Z<Y<T>...> A")); 1313 // Should be: with semicolon 1314 } 1315 1316 TEST(DeclPrinter, TestTemplateArgumentList15) { 1317 ASSERT_TRUE(PrintedDeclCXX11Matches( 1318 "template<unsigned I> struct Z {};" 1319 "template<typename... T> struct X {" 1320 " Z<sizeof...(T)> A;" 1321 "};", 1322 "A", 1323 "Z<sizeof...(T)> A")); 1324 // Should be: with semicolon 1325 } 1326 1327 TEST(DeclPrinter, TestTemplateArgumentList16) { 1328 llvm::StringLiteral Code = "template<typename T1, int NT1, typename T2 = " 1329 "bool, int NT2 = 5> struct Z {};"; 1330 ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "T1", "typename T1")); 1331 ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "T2", "typename T2 = bool")); 1332 ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "NT1", "int NT1")); 1333 ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "NT2", "int NT2 = 5")); 1334 } 1335 1336 TEST(DeclPrinter, TestFunctionParamUglified) { 1337 llvm::StringLiteral Code = R"cpp( 1338 class __c; 1339 void _A(__c *__param); 1340 )cpp"; 1341 auto Clean = [](PrintingPolicy &Policy) { 1342 Policy.CleanUglifiedParameters = true; 1343 }; 1344 1345 ASSERT_TRUE(PrintedDeclCXX17Matches(Code, namedDecl(hasName("_A")).bind("id"), 1346 "void _A(__c *__param)")); 1347 ASSERT_TRUE(PrintedDeclCXX17Matches(Code, namedDecl(hasName("_A")).bind("id"), 1348 "void _A(__c *param)", Clean)); 1349 } 1350 1351 TEST(DeclPrinter, TestTemplateParamUglified) { 1352 llvm::StringLiteral Code = R"cpp( 1353 template <typename _Tp, int __n, template <typename> class _Container> 1354 struct _A{}; 1355 )cpp"; 1356 auto Clean = [](PrintingPolicy &Policy) { 1357 Policy.CleanUglifiedParameters = true; 1358 }; 1359 1360 ASSERT_TRUE(PrintedDeclCXX17Matches( 1361 Code, classTemplateDecl(hasName("_A")).bind("id"), 1362 "template <typename _Tp, int __n, template <typename> class _Container> " 1363 "struct _A {}")); 1364 ASSERT_TRUE(PrintedDeclCXX17Matches( 1365 Code, classTemplateDecl(hasName("_A")).bind("id"), 1366 "template <typename Tp, int n, template <typename> class Container> " 1367 "struct _A {}", 1368 Clean)); 1369 } 1370 1371 TEST(DeclPrinter, TestStaticAssert1) { 1372 ASSERT_TRUE(PrintedDeclCXX17Matches("static_assert(true);", 1373 staticAssertDecl().bind("id"), 1374 "static_assert(true)")); 1375 } 1376 1377 TEST(DeclPrinter, TestObjCMethod1) { 1378 ASSERT_TRUE(PrintedDeclObjCMatches( 1379 "__attribute__((objc_root_class)) @interface X\n" 1380 "- (int)A:(id)anObject inRange:(long)range;\n" 1381 "@end\n" 1382 "@implementation X\n" 1383 "- (int)A:(id)anObject inRange:(long)range { int printThis; return 0; }\n" 1384 "@end\n", 1385 namedDecl(hasName("A:inRange:"), 1386 hasDescendant(namedDecl(hasName("printThis")))).bind("id"), 1387 "- (int)A:(id)anObject inRange:(long)range")); 1388 } 1389 1390 TEST(DeclPrinter, TestObjCProtocol1) { 1391 ASSERT_TRUE(PrintedDeclObjCMatches( 1392 "@protocol P1, P2;", 1393 namedDecl(hasName("P1")).bind("id"), 1394 "@protocol P1;\n")); 1395 ASSERT_TRUE(PrintedDeclObjCMatches( 1396 "@protocol P1, P2;", 1397 namedDecl(hasName("P2")).bind("id"), 1398 "@protocol P2;\n")); 1399 } 1400 1401 TEST(DeclPrinter, TestObjCProtocol2) { 1402 ASSERT_TRUE(PrintedDeclObjCMatches( 1403 "@protocol P2 @end" 1404 "@protocol P1<P2> @end", 1405 namedDecl(hasName("P1")).bind("id"), 1406 "@protocol P1<P2>\n@end")); 1407 } 1408 1409 TEST(DeclPrinter, TestObjCCategoryInvalidInterface) { 1410 ASSERT_TRUE(PrintedDeclObjCMatches( 1411 "@interface I (Extension) @end", 1412 namedDecl(hasName("Extension")).bind("id"), 1413 "@interface <<error-type>>(Extension)\n@end", /*AllowError=*/true)); 1414 } 1415 1416 TEST(DeclPrinter, TestObjCCategoryImplInvalidInterface) { 1417 ASSERT_TRUE(PrintedDeclObjCMatches( 1418 "@implementation I (Extension) @end", 1419 namedDecl(hasName("Extension")).bind("id"), 1420 "@implementation <<error-type>>(Extension)\n@end", /*AllowError=*/true)); 1421 } 1422 1423 TEST(DeclPrinter, VarDeclWithInitializer) { 1424 ASSERT_TRUE(PrintedDeclCXX17Matches( 1425 "int a = 0x15;", namedDecl(hasName("a")).bind("id"), "int a = 21")); 1426 ASSERT_TRUE(PrintedDeclCXX17Matches( 1427 "int a = 0x15;", namedDecl(hasName("a")).bind("id"), "int a = 0x15", 1428 [](PrintingPolicy &Policy) { Policy.ConstantsAsWritten = true; })); 1429 ASSERT_TRUE( 1430 PrintedDeclCXX17Matches("void foo() {int arr[42]; for(int a : arr);}", 1431 namedDecl(hasName("a")).bind("id"), "int a")); 1432 } 1433