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 28 using namespace clang; 29 using namespace ast_matchers; 30 using namespace tooling; 31 32 namespace { 33 34 void 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 40 class PrintMatch : public MatchFinder::MatchCallback { 41 SmallString<1024> Printed; 42 unsigned NumFoundDecls; 43 44 public: 45 PrintMatch() : NumFoundDecls(0) {} 46 47 void run(const MatchFinder::MatchResult &Result) override { 48 const Decl *D = Result.Nodes.getNodeAs<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 161 PrintedDeclCXX1ZMatches(StringRef Code, const DeclarationMatcher &NodeMatch, 162 StringRef ExpectedPrinted) { 163 std::vector<std::string> Args(1, "-std=c++1z"); 164 return PrintedDeclMatches(Code, 165 Args, 166 NodeMatch, 167 ExpectedPrinted, 168 "input.cc"); 169 } 170 171 ::testing::AssertionResult PrintedDeclObjCMatches( 172 StringRef Code, 173 const DeclarationMatcher &NodeMatch, 174 StringRef ExpectedPrinted) { 175 std::vector<std::string> Args(1, ""); 176 return PrintedDeclMatches(Code, 177 Args, 178 NodeMatch, 179 ExpectedPrinted, 180 "input.m"); 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, TestFunctionDecl2) { 347 ASSERT_TRUE(PrintedDeclCXX98Matches( 348 "void A() {}", 349 "A", 350 "void A()")); 351 } 352 353 TEST(DeclPrinter, TestFunctionDecl3) { 354 ASSERT_TRUE(PrintedDeclCXX98Matches( 355 "void Z();" 356 "void A() { Z(); }", 357 "A", 358 "void A()")); 359 } 360 361 TEST(DeclPrinter, TestFunctionDecl4) { 362 ASSERT_TRUE(PrintedDeclCXX98Matches( 363 "extern void A();", 364 "A", 365 "extern void A()")); 366 } 367 368 TEST(DeclPrinter, TestFunctionDecl5) { 369 ASSERT_TRUE(PrintedDeclCXX98Matches( 370 "static void A();", 371 "A", 372 "static void A()")); 373 } 374 375 TEST(DeclPrinter, TestFunctionDecl6) { 376 ASSERT_TRUE(PrintedDeclCXX98Matches( 377 "inline void A();", 378 "A", 379 "inline void A()")); 380 } 381 382 TEST(DeclPrinter, TestFunctionDecl7) { 383 ASSERT_TRUE(PrintedDeclCXX11Matches( 384 "constexpr int A(int a);", 385 "A", 386 "constexpr int A(int a)")); 387 } 388 389 TEST(DeclPrinter, TestFunctionDecl8) { 390 ASSERT_TRUE(PrintedDeclCXX98Matches( 391 "void A(int a);", 392 "A", 393 "void A(int a)")); 394 } 395 396 TEST(DeclPrinter, TestFunctionDecl9) { 397 ASSERT_TRUE(PrintedDeclCXX98Matches( 398 "void A(...);", 399 "A", 400 "void A(...)")); 401 } 402 403 TEST(DeclPrinter, TestFunctionDecl10) { 404 ASSERT_TRUE(PrintedDeclCXX98Matches( 405 "void A(int a, ...);", 406 "A", 407 "void A(int a, ...)")); 408 } 409 410 TEST(DeclPrinter, TestFunctionDecl11) { 411 ASSERT_TRUE(PrintedDeclCXX98Matches( 412 "typedef long ssize_t;" 413 "typedef int *pInt;" 414 "void A(int a, pInt b, ssize_t c);", 415 "A", 416 "void A(int a, pInt b, ssize_t c)")); 417 } 418 419 TEST(DeclPrinter, TestFunctionDecl12) { 420 ASSERT_TRUE(PrintedDeclCXX98Matches( 421 "void A(int a, int b = 0);", 422 "A", 423 "void A(int a, int b = 0)")); 424 } 425 426 TEST(DeclPrinter, TestFunctionDecl13) { 427 ASSERT_TRUE(PrintedDeclCXX98Matches( 428 "void (*A(int a))(int b);", 429 "A", 430 "void (*A(int a))(int)")); 431 // Should be: with parameter name (?) 432 } 433 434 TEST(DeclPrinter, TestFunctionDecl14) { 435 ASSERT_TRUE(PrintedDeclCXX98Matches( 436 "template<typename T>" 437 "void A(T t) { }" 438 "template<>" 439 "void A(int N) { }", 440 functionDecl(hasName("A"), isExplicitTemplateSpecialization()).bind("id"), 441 "template<> void A<int>(int N)")); 442 } 443 444 445 TEST(DeclPrinter, TestCXXConstructorDecl1) { 446 ASSERT_TRUE(PrintedDeclCXX98Matches( 447 "struct A {" 448 " A();" 449 "};", 450 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 451 "A()")); 452 } 453 454 TEST(DeclPrinter, TestCXXConstructorDecl2) { 455 ASSERT_TRUE(PrintedDeclCXX98Matches( 456 "struct A {" 457 " A(int a);" 458 "};", 459 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 460 "A(int a)")); 461 } 462 463 TEST(DeclPrinter, TestCXXConstructorDecl3) { 464 ASSERT_TRUE(PrintedDeclCXX98Matches( 465 "struct A {" 466 " A(const A &a);" 467 "};", 468 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 469 "A(const A &a)")); 470 } 471 472 TEST(DeclPrinter, TestCXXConstructorDecl4) { 473 ASSERT_TRUE(PrintedDeclCXX98Matches( 474 "struct A {" 475 " A(const A &a, int = 0);" 476 "};", 477 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 478 "A(const A &a, int = 0)")); 479 } 480 481 TEST(DeclPrinter, TestCXXConstructorDecl5) { 482 ASSERT_TRUE(PrintedDeclCXX11Matches( 483 "struct A {" 484 " A(const A &&a);" 485 "};", 486 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 487 "A(const A &&a)")); 488 } 489 490 TEST(DeclPrinter, TestCXXConstructorDecl6) { 491 ASSERT_TRUE(PrintedDeclCXX98Matches( 492 "struct A {" 493 " explicit A(int a);" 494 "};", 495 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 496 "explicit A(int a)")); 497 } 498 499 TEST(DeclPrinter, TestCXXConstructorDecl7) { 500 ASSERT_TRUE(PrintedDeclCXX11Matches( 501 "struct A {" 502 " constexpr A();" 503 "};", 504 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 505 "constexpr A()")); 506 } 507 508 TEST(DeclPrinter, TestCXXConstructorDecl8) { 509 ASSERT_TRUE(PrintedDeclCXX11Matches( 510 "struct A {" 511 " A() = default;" 512 "};", 513 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 514 "A() = default")); 515 } 516 517 TEST(DeclPrinter, TestCXXConstructorDecl9) { 518 ASSERT_TRUE(PrintedDeclCXX11Matches( 519 "struct A {" 520 " A() = delete;" 521 "};", 522 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 523 "A() = delete")); 524 } 525 526 TEST(DeclPrinter, TestCXXConstructorDecl10) { 527 ASSERT_TRUE(PrintedDeclCXX11Matches( 528 "template<typename... T>" 529 "struct A {" 530 " A(const A &a);" 531 "};", 532 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 533 "A<T...>(const A<T...> &a)")); 534 } 535 536 TEST(DeclPrinter, TestCXXConstructorDecl11) { 537 ASSERT_TRUE(PrintedDeclCXX11nonMSCMatches( 538 "template<typename... T>" 539 "struct A : public T... {" 540 " A(T&&... ts) : T(ts)... {}" 541 "};", 542 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 543 "A<T...>(T &&...ts) : T(ts)... {}")); 544 } 545 546 TEST(DeclPrinter, TestCXXDestructorDecl1) { 547 ASSERT_TRUE(PrintedDeclCXX98Matches( 548 "struct A {" 549 " ~A();" 550 "};", 551 cxxDestructorDecl(ofClass(hasName("A"))).bind("id"), 552 "~A()")); 553 } 554 555 TEST(DeclPrinter, TestCXXDestructorDecl2) { 556 ASSERT_TRUE(PrintedDeclCXX98Matches( 557 "struct A {" 558 " virtual ~A();" 559 "};", 560 cxxDestructorDecl(ofClass(hasName("A"))).bind("id"), 561 "virtual ~A()")); 562 } 563 564 TEST(DeclPrinter, TestCXXConversionDecl1) { 565 ASSERT_TRUE(PrintedDeclCXX98Matches( 566 "struct A {" 567 " operator int();" 568 "};", 569 cxxMethodDecl(ofClass(hasName("A"))).bind("id"), 570 "operator int()")); 571 } 572 573 TEST(DeclPrinter, TestCXXConversionDecl2) { 574 ASSERT_TRUE(PrintedDeclCXX98Matches( 575 "struct A {" 576 " operator bool();" 577 "};", 578 cxxMethodDecl(ofClass(hasName("A"))).bind("id"), 579 "operator bool()")); 580 } 581 582 TEST(DeclPrinter, TestCXXConversionDecl3) { 583 ASSERT_TRUE(PrintedDeclCXX98Matches( 584 "struct Z {};" 585 "struct A {" 586 " operator Z();" 587 "};", 588 cxxMethodDecl(ofClass(hasName("A"))).bind("id"), 589 "operator Z()")); 590 } 591 592 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) { 593 ASSERT_TRUE(PrintedDeclCXX11Matches( 594 "namespace std { typedef decltype(sizeof(int)) size_t; }" 595 "struct Z {" 596 " void *operator new(std::size_t);" 597 "};", 598 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 599 "void *operator new(std::size_t)")); 600 } 601 602 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction2) { 603 ASSERT_TRUE(PrintedDeclCXX11Matches( 604 "namespace std { typedef decltype(sizeof(int)) size_t; }" 605 "struct Z {" 606 " void *operator new[](std::size_t);" 607 "};", 608 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 609 "void *operator new[](std::size_t)")); 610 } 611 612 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction3) { 613 ASSERT_TRUE(PrintedDeclCXX11Matches( 614 "struct Z {" 615 " void operator delete(void *);" 616 "};", 617 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 618 "void operator delete(void *) noexcept")); 619 // Should be: without noexcept? 620 } 621 622 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction4) { 623 ASSERT_TRUE(PrintedDeclCXX98Matches( 624 "struct Z {" 625 " void operator delete(void *);" 626 "};", 627 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 628 "void operator delete(void *)")); 629 } 630 631 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction5) { 632 ASSERT_TRUE(PrintedDeclCXX11Matches( 633 "struct Z {" 634 " void operator delete[](void *);" 635 "};", 636 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 637 "void operator delete[](void *) noexcept")); 638 // Should be: without noexcept? 639 } 640 641 TEST(DeclPrinter, TestCXXMethodDecl_Operator1) { 642 const char *OperatorNames[] = { 643 "+", "-", "*", "/", "%", "^", "&", "|", 644 "=", "<", ">", "+=", "-=", "*=", "/=", "%=", 645 "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==", "!=", 646 "<=", ">=", "&&", "||", ",", "->*", 647 "()", "[]" 648 }; 649 650 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) { 651 SmallString<128> Code; 652 Code.append("struct Z { void operator"); 653 Code.append(OperatorNames[i]); 654 Code.append("(Z z); };"); 655 656 SmallString<128> Expected; 657 Expected.append("void operator"); 658 Expected.append(OperatorNames[i]); 659 Expected.append("(Z z)"); 660 661 ASSERT_TRUE(PrintedDeclCXX98Matches( 662 Code, 663 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 664 Expected)); 665 } 666 } 667 668 TEST(DeclPrinter, TestCXXMethodDecl_Operator2) { 669 const char *OperatorNames[] = { 670 "~", "!", "++", "--", "->" 671 }; 672 673 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) { 674 SmallString<128> Code; 675 Code.append("struct Z { void operator"); 676 Code.append(OperatorNames[i]); 677 Code.append("(); };"); 678 679 SmallString<128> Expected; 680 Expected.append("void operator"); 681 Expected.append(OperatorNames[i]); 682 Expected.append("()"); 683 684 ASSERT_TRUE(PrintedDeclCXX98Matches( 685 Code, 686 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 687 Expected)); 688 } 689 } 690 691 TEST(DeclPrinter, TestCXXMethodDecl1) { 692 ASSERT_TRUE(PrintedDeclCXX98Matches( 693 "struct Z {" 694 " void A(int a);" 695 "};", 696 "A", 697 "void A(int a)")); 698 } 699 700 TEST(DeclPrinter, TestCXXMethodDecl2) { 701 ASSERT_TRUE(PrintedDeclCXX98Matches( 702 "struct Z {" 703 " virtual void A(int a);" 704 "};", 705 "A", 706 "virtual void A(int a)")); 707 } 708 709 TEST(DeclPrinter, TestCXXMethodDecl3) { 710 ASSERT_TRUE(PrintedDeclCXX98Matches( 711 "struct Z {" 712 " virtual void A(int a);" 713 "};" 714 "struct ZZ : Z {" 715 " void A(int a);" 716 "};", 717 "ZZ::A", 718 "void A(int a)")); 719 // TODO: should we print "virtual"? 720 } 721 722 TEST(DeclPrinter, TestCXXMethodDecl4) { 723 ASSERT_TRUE(PrintedDeclCXX98Matches( 724 "struct Z {" 725 " inline void A(int a);" 726 "};", 727 "A", 728 "inline void A(int a)")); 729 } 730 731 TEST(DeclPrinter, TestCXXMethodDecl5) { 732 ASSERT_TRUE(PrintedDeclCXX98Matches( 733 "struct Z {" 734 " virtual void A(int a) = 0;" 735 "};", 736 "A", 737 "virtual void A(int a) = 0")); 738 } 739 740 TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier1) { 741 ASSERT_TRUE(PrintedDeclCXX98Matches( 742 "struct Z {" 743 " void A(int a) const;" 744 "};", 745 "A", 746 "void A(int a) const")); 747 } 748 749 TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier2) { 750 ASSERT_TRUE(PrintedDeclCXX98Matches( 751 "struct Z {" 752 " void A(int a) volatile;" 753 "};", 754 "A", 755 "void A(int a) volatile")); 756 } 757 758 TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier3) { 759 ASSERT_TRUE(PrintedDeclCXX98Matches( 760 "struct Z {" 761 " void A(int a) const volatile;" 762 "};", 763 "A", 764 "void A(int a) const volatile")); 765 } 766 767 TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier1) { 768 ASSERT_TRUE(PrintedDeclCXX11Matches( 769 "struct Z {" 770 " void A(int a) &;" 771 "};", 772 "A", 773 "void A(int a) &")); 774 } 775 776 TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) { 777 ASSERT_TRUE(PrintedDeclCXX11Matches( 778 "struct Z {" 779 " void A(int a) &&;" 780 "};", 781 "A", 782 "void A(int a) &&")); 783 } 784 785 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) { 786 ASSERT_TRUE(PrintedDeclCXX98Matches( 787 "struct Z {" 788 " void A(int a) throw();" 789 "};", 790 "A", 791 "void A(int a) throw()")); 792 } 793 794 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification2) { 795 ASSERT_TRUE(PrintedDeclCXX98Matches( 796 "struct Z {" 797 " void A(int a) throw(int);" 798 "};", 799 "A", 800 "void A(int a) throw(int)")); 801 } 802 803 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification3) { 804 ASSERT_TRUE(PrintedDeclCXX98Matches( 805 "class ZZ {};" 806 "struct Z {" 807 " void A(int a) throw(ZZ, int);" 808 "};", 809 "A", 810 "void A(int a) throw(ZZ, int)")); 811 } 812 813 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification4) { 814 ASSERT_TRUE(PrintedDeclCXX11Matches( 815 "struct Z {" 816 " void A(int a) noexcept;" 817 "};", 818 "A", 819 "void A(int a) noexcept")); 820 } 821 822 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification5) { 823 ASSERT_TRUE(PrintedDeclCXX11Matches( 824 "struct Z {" 825 " void A(int a) noexcept(true);" 826 "};", 827 "A", 828 "void A(int a) noexcept(trueA(int a) noexcept(true)")); 829 // WRONG; Should be: "void A(int a) noexcept(true);" 830 } 831 832 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification6) { 833 ASSERT_TRUE(PrintedDeclCXX11Matches( 834 "struct Z {" 835 " void A(int a) noexcept(1 < 2);" 836 "};", 837 "A", 838 "void A(int a) noexcept(1 < 2A(int a) noexcept(1 < 2)")); 839 // WRONG; Should be: "void A(int a) noexcept(1 < 2);" 840 } 841 842 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification7) { 843 ASSERT_TRUE(PrintedDeclCXX11Matches( 844 "template<int N>" 845 "struct Z {" 846 " void A(int a) noexcept(N < 2);" 847 "};", 848 "A", 849 "void A(int a) noexcept(N < 2A(int a) noexcept(N < 2)")); 850 // WRONG; Should be: "void A(int a) noexcept(N < 2);" 851 } 852 853 TEST(DeclPrinter, TestVarDecl1) { 854 ASSERT_TRUE(PrintedDeclCXX98Matches( 855 "char *const (*(*A)[5])(int);", 856 "A", 857 "char *const (*(*A)[5])(int)")); 858 // Should be: with semicolon 859 } 860 861 TEST(DeclPrinter, TestVarDecl2) { 862 ASSERT_TRUE(PrintedDeclCXX98Matches( 863 "void (*A)() throw(int);", 864 "A", 865 "void (*A)() throw(int)")); 866 // Should be: with semicolon 867 } 868 869 TEST(DeclPrinter, TestVarDecl3) { 870 ASSERT_TRUE(PrintedDeclCXX11Matches( 871 "void (*A)() noexcept;", 872 "A", 873 "void (*A)() noexcept")); 874 // Should be: with semicolon 875 } 876 877 TEST(DeclPrinter, TestFieldDecl1) { 878 ASSERT_TRUE(PrintedDeclCXX98Matches( 879 "template<typename T>" 880 "struct Z { T A; };", 881 "A", 882 "T A")); 883 // Should be: with semicolon 884 } 885 886 TEST(DeclPrinter, TestFieldDecl2) { 887 ASSERT_TRUE(PrintedDeclCXX98Matches( 888 "template<int N>" 889 "struct Z { int A[N]; };", 890 "A", 891 "int A[N]")); 892 // Should be: with semicolon 893 } 894 895 TEST(DeclPrinter, TestClassTemplateDecl1) { 896 ASSERT_TRUE(PrintedDeclCXX98Matches( 897 "template<typename T>" 898 "struct A { T a; };", 899 classTemplateDecl(hasName("A")).bind("id"), 900 "template <typename T> struct A {}")); 901 } 902 903 TEST(DeclPrinter, TestClassTemplateDecl2) { 904 ASSERT_TRUE(PrintedDeclCXX98Matches( 905 "template<typename T = int>" 906 "struct A { T a; };", 907 classTemplateDecl(hasName("A")).bind("id"), 908 "template <typename T = int> struct A {}")); 909 } 910 911 TEST(DeclPrinter, TestClassTemplateDecl3) { 912 ASSERT_TRUE(PrintedDeclCXX98Matches( 913 "template<class T>" 914 "struct A { T a; };", 915 classTemplateDecl(hasName("A")).bind("id"), 916 "template <class T> struct A {}")); 917 } 918 919 TEST(DeclPrinter, TestClassTemplateDecl4) { 920 ASSERT_TRUE(PrintedDeclCXX98Matches( 921 "template<typename T, typename U>" 922 "struct A { T a; U b; };", 923 classTemplateDecl(hasName("A")).bind("id"), 924 "template <typename T, typename U> struct A {}")); 925 } 926 927 TEST(DeclPrinter, TestClassTemplateDecl5) { 928 ASSERT_TRUE(PrintedDeclCXX98Matches( 929 "template<int N>" 930 "struct A { int a[N]; };", 931 classTemplateDecl(hasName("A")).bind("id"), 932 "template <int N> struct A {}")); 933 } 934 935 TEST(DeclPrinter, TestClassTemplateDecl6) { 936 ASSERT_TRUE(PrintedDeclCXX98Matches( 937 "template<int N = 42>" 938 "struct A { int a[N]; };", 939 classTemplateDecl(hasName("A")).bind("id"), 940 "template <int N = 42> struct A {}")); 941 } 942 943 TEST(DeclPrinter, TestClassTemplateDecl7) { 944 ASSERT_TRUE(PrintedDeclCXX98Matches( 945 "typedef int MyInt;" 946 "template<MyInt N>" 947 "struct A { int a[N]; };", 948 classTemplateDecl(hasName("A")).bind("id"), 949 "template <MyInt N> struct A {}")); 950 } 951 952 TEST(DeclPrinter, TestClassTemplateDecl8) { 953 ASSERT_TRUE(PrintedDeclCXX98Matches( 954 "template<template<typename U> class T> struct A { };", 955 classTemplateDecl(hasName("A")).bind("id"), 956 "template <template <typename U> class T> struct A {}")); 957 } 958 959 TEST(DeclPrinter, TestClassTemplateDecl9) { 960 ASSERT_TRUE(PrintedDeclCXX98Matches( 961 "template<typename T> struct Z { };" 962 "template<template<typename U> class T = Z> struct A { };", 963 classTemplateDecl(hasName("A")).bind("id"), 964 "template <template <typename U> class T> struct A {}")); 965 } 966 967 TEST(DeclPrinter, TestClassTemplateDecl10) { 968 ASSERT_TRUE(PrintedDeclCXX11Matches( 969 "template<typename... T>" 970 "struct A { int a; };", 971 classTemplateDecl(hasName("A")).bind("id"), 972 "template <typename ...T> struct A {}")); 973 } 974 975 TEST(DeclPrinter, TestClassTemplateDecl11) { 976 ASSERT_TRUE(PrintedDeclCXX11Matches( 977 "template<typename... T>" 978 "struct A : public T... { int a; };", 979 classTemplateDecl(hasName("A")).bind("id"), 980 "template <typename ...T> struct A : public T... {}")); 981 } 982 983 TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl1) { 984 ASSERT_TRUE(PrintedDeclCXX98Matches( 985 "template<typename T, typename U>" 986 "struct A { T a; U b; };" 987 "template<typename T>" 988 "struct A<T, int> { T a; };", 989 classTemplateSpecializationDecl().bind("id"), 990 "template <typename T> struct A<T, int> {}")); 991 } 992 993 TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl2) { 994 ASSERT_TRUE(PrintedDeclCXX98Matches( 995 "template<typename T>" 996 "struct A { T a; };" 997 "template<typename T>" 998 "struct A<T *> { T a; };", 999 classTemplateSpecializationDecl().bind("id"), 1000 "template <typename T> struct A<type-parameter-0-0 *> {}")); 1001 // WRONG; Should be: "template<typename T> struct A<T *> { ... }" 1002 } 1003 1004 TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) { 1005 ASSERT_TRUE(PrintedDeclCXX98Matches( 1006 "template<typename T>" 1007 "struct A { T a; };" 1008 "template<>" 1009 "struct A<int> { int a; };", 1010 classTemplateSpecializationDecl().bind("id"), 1011 "template<> struct A<int> {}")); 1012 } 1013 1014 TEST(DeclPrinter, TestFunctionTemplateDecl1) { 1015 ASSERT_TRUE(PrintedDeclCXX98Matches( 1016 "template<typename T>" 1017 "void A(T &t);", 1018 functionTemplateDecl(hasName("A")).bind("id"), 1019 "template <typename T> void A(T &t)")); 1020 } 1021 1022 TEST(DeclPrinter, TestFunctionTemplateDecl2) { 1023 ASSERT_TRUE(PrintedDeclCXX98Matches( 1024 "template<typename T>" 1025 "void A(T &t) { }", 1026 functionTemplateDecl(hasName("A")).bind("id"), 1027 "template <typename T> void A(T &t)")); 1028 } 1029 1030 TEST(DeclPrinter, TestFunctionTemplateDecl3) { 1031 ASSERT_TRUE(PrintedDeclCXX11Matches( 1032 "template<typename... T>" 1033 "void A(T... a);", 1034 functionTemplateDecl(hasName("A")).bind("id"), 1035 "template <typename ...T> void A(T ...a)")); 1036 } 1037 1038 TEST(DeclPrinter, TestFunctionTemplateDecl4) { 1039 ASSERT_TRUE(PrintedDeclCXX98Matches( 1040 "struct Z { template<typename T> void A(T t); };", 1041 functionTemplateDecl(hasName("A")).bind("id"), 1042 "template <typename T> void A(T t)")); 1043 } 1044 1045 TEST(DeclPrinter, TestFunctionTemplateDecl5) { 1046 ASSERT_TRUE(PrintedDeclCXX98Matches( 1047 "struct Z { template<typename T> void A(T t) {} };", 1048 functionTemplateDecl(hasName("A")).bind("id"), 1049 "template <typename T> void A(T t)")); 1050 } 1051 1052 TEST(DeclPrinter, TestFunctionTemplateDecl6) { 1053 ASSERT_TRUE(PrintedDeclCXX98Matches( 1054 "template<typename T >struct Z {" 1055 " template<typename U> void A(U t) {}" 1056 "};", 1057 functionTemplateDecl(hasName("A")).bind("id"), 1058 "template <typename U> void A(U t)")); 1059 } 1060 1061 TEST(DeclPrinter, TestTemplateArgumentList1) { 1062 ASSERT_TRUE(PrintedDeclCXX98Matches( 1063 "template<typename T> struct Z {};" 1064 "struct X {};" 1065 "Z<X> A;", 1066 "A", 1067 "Z<X> A")); 1068 // Should be: with semicolon 1069 } 1070 1071 TEST(DeclPrinter, TestTemplateArgumentList2) { 1072 ASSERT_TRUE(PrintedDeclCXX98Matches( 1073 "template<typename T, typename U> struct Z {};" 1074 "struct X {};" 1075 "typedef int Y;" 1076 "Z<X, Y> A;", 1077 "A", 1078 "Z<X, Y> A")); 1079 // Should be: with semicolon 1080 } 1081 1082 TEST(DeclPrinter, TestTemplateArgumentList3) { 1083 ASSERT_TRUE(PrintedDeclCXX98Matches( 1084 "template<typename T> struct Z {};" 1085 "template<typename T> struct X {};" 1086 "Z<X<int> > A;", 1087 "A", 1088 "Z<X<int> > A")); 1089 // Should be: with semicolon 1090 } 1091 1092 TEST(DeclPrinter, TestTemplateArgumentList4) { 1093 ASSERT_TRUE(PrintedDeclCXX11Matches( 1094 "template<typename T> struct Z {};" 1095 "template<typename T> struct X {};" 1096 "Z<X<int>> A;", 1097 "A", 1098 "Z<X<int> > A")); 1099 // Should be: with semicolon, without extra space in "> >" 1100 } 1101 1102 TEST(DeclPrinter, TestTemplateArgumentList5) { 1103 ASSERT_TRUE(PrintedDeclCXX98Matches( 1104 "template<typename T> struct Z {};" 1105 "template<typename T> struct X { Z<T> A; };", 1106 "A", 1107 "Z<T> A")); 1108 // Should be: with semicolon 1109 } 1110 1111 TEST(DeclPrinter, TestTemplateArgumentList6) { 1112 ASSERT_TRUE(PrintedDeclCXX98Matches( 1113 "template<template<typename T> class U> struct Z {};" 1114 "template<typename T> struct X {};" 1115 "Z<X> A;", 1116 "A", 1117 "Z<X> A")); 1118 // Should be: with semicolon 1119 } 1120 1121 TEST(DeclPrinter, TestTemplateArgumentList7) { 1122 ASSERT_TRUE(PrintedDeclCXX98Matches( 1123 "template<template<typename T> class U> struct Z {};" 1124 "template<template<typename T> class U> struct Y {" 1125 " Z<U> A;" 1126 "};", 1127 "A", 1128 "Z<U> A")); 1129 // Should be: with semicolon 1130 } 1131 1132 TEST(DeclPrinter, TestTemplateArgumentList8) { 1133 ASSERT_TRUE(PrintedDeclCXX98Matches( 1134 "template<typename T> struct Z {};" 1135 "template<template<typename T> class U> struct Y {" 1136 " Z<U<int> > A;" 1137 "};", 1138 "A", 1139 "Z<U<int> > A")); 1140 // Should be: with semicolon 1141 } 1142 1143 TEST(DeclPrinter, TestTemplateArgumentList9) { 1144 ASSERT_TRUE(PrintedDeclCXX98Matches( 1145 "template<unsigned I> struct Z {};" 1146 "Z<0> A;", 1147 "A", 1148 "Z<0> A")); 1149 // Should be: with semicolon 1150 } 1151 1152 TEST(DeclPrinter, TestTemplateArgumentList10) { 1153 ASSERT_TRUE(PrintedDeclCXX98Matches( 1154 "template<unsigned I> struct Z {};" 1155 "template<unsigned I> struct X { Z<I> A; };", 1156 "A", 1157 "Z<I> A")); 1158 // Should be: with semicolon 1159 } 1160 1161 TEST(DeclPrinter, TestTemplateArgumentList11) { 1162 ASSERT_TRUE(PrintedDeclCXX98Matches( 1163 "template<int I> struct Z {};" 1164 "Z<42 * 10 - 420 / 1> A;", 1165 "A", 1166 "Z<42 * 10 - 420 / 1> A")); 1167 // Should be: with semicolon 1168 } 1169 1170 TEST(DeclPrinter, TestTemplateArgumentList12) { 1171 ASSERT_TRUE(PrintedDeclCXX98Matches( 1172 "template<const char *p> struct Z {};" 1173 "extern const char X[] = \"aaa\";" 1174 "Z<X> A;", 1175 "A", 1176 "Z<X> A")); 1177 // Should be: with semicolon 1178 } 1179 1180 TEST(DeclPrinter, TestTemplateArgumentList13) { 1181 ASSERT_TRUE(PrintedDeclCXX11Matches( 1182 "template<typename... T> struct Z {};" 1183 "template<typename... T> struct X {" 1184 " Z<T...> A;" 1185 "};", 1186 "A", 1187 "Z<T...> A")); 1188 // Should be: with semicolon 1189 } 1190 1191 TEST(DeclPrinter, TestTemplateArgumentList14) { 1192 ASSERT_TRUE(PrintedDeclCXX11Matches( 1193 "template<typename... T> struct Z {};" 1194 "template<typename T> struct Y {};" 1195 "template<typename... T> struct X {" 1196 " Z<Y<T>...> A;" 1197 "};", 1198 "A", 1199 "Z<Y<T>...> A")); 1200 // Should be: with semicolon 1201 } 1202 1203 TEST(DeclPrinter, TestTemplateArgumentList15) { 1204 ASSERT_TRUE(PrintedDeclCXX11Matches( 1205 "template<unsigned I> struct Z {};" 1206 "template<typename... T> struct X {" 1207 " Z<sizeof...(T)> A;" 1208 "};", 1209 "A", 1210 "Z<sizeof...(T)> A")); 1211 // Should be: with semicolon 1212 } 1213 1214 TEST(DeclPrinter, TestStaticAssert1) { 1215 ASSERT_TRUE(PrintedDeclCXX1ZMatches( 1216 "static_assert(true);", 1217 staticAssertDecl().bind("id"), 1218 "static_assert(true)")); 1219 } 1220 1221 TEST(DeclPrinter, TestObjCMethod1) { 1222 ASSERT_TRUE(PrintedDeclObjCMatches( 1223 "__attribute__((objc_root_class)) @interface X\n" 1224 "- (int)A:(id)anObject inRange:(long)range;\n" 1225 "@end\n" 1226 "@implementation X\n" 1227 "- (int)A:(id)anObject inRange:(long)range { int printThis; return 0; }\n" 1228 "@end\n", 1229 namedDecl(hasName("A:inRange:"), 1230 hasDescendant(namedDecl(hasName("printThis")))).bind("id"), 1231 "- (int) A:(id)anObject inRange:(long)range")); 1232 } 1233 1234 TEST(DeclPrinter, TestObjCProtocol1) { 1235 ASSERT_TRUE(PrintedDeclObjCMatches( 1236 "@protocol P1, P2;", 1237 namedDecl(hasName("P1")).bind("id"), 1238 "@protocol P1;\n")); 1239 ASSERT_TRUE(PrintedDeclObjCMatches( 1240 "@protocol P1, P2;", 1241 namedDecl(hasName("P2")).bind("id"), 1242 "@protocol P2;\n")); 1243 } 1244 1245 TEST(DeclPrinter, TestObjCProtocol2) { 1246 ASSERT_TRUE(PrintedDeclObjCMatches( 1247 "@protocol P2 @end" 1248 "@protocol P1<P2> @end", 1249 namedDecl(hasName("P1")).bind("id"), 1250 "@protocol P1<P2>\n@end")); 1251 } 1252