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