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