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