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