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 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 174 TEST(DeclPrinter, TestTypedef1) { 175 ASSERT_TRUE(PrintedDeclCXX98Matches( 176 "typedef int A;", 177 "A", 178 "typedef int A")); 179 // Should be: with semicolon 180 } 181 182 TEST(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 190 TEST(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 199 TEST(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 208 TEST(DeclPrinter, TestNamespace1) { 209 ASSERT_TRUE(PrintedDeclCXX98Matches( 210 "namespace A { int B; }", 211 "A", 212 "namespace A {\n}")); 213 // Should be: with { ... } 214 } 215 216 TEST(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 224 TEST(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 233 TEST(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 242 TEST(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 250 TEST(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 258 TEST(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 266 TEST(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 275 TEST(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 284 TEST(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 293 TEST(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 302 TEST(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 311 TEST(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 320 TEST(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 329 TEST(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 339 TEST(DeclPrinter, TestFunctionDecl1) { 340 ASSERT_TRUE(PrintedDeclCXX98Matches( 341 "void A();", 342 "A", 343 "void A()")); 344 // Should be: with semicolon 345 } 346 347 TEST(DeclPrinter, TestFunctionDecl2) { 348 ASSERT_TRUE(PrintedDeclCXX98Matches( 349 "void A() {}", 350 "A", 351 "void A()")); 352 // Should be: with semicolon 353 } 354 355 TEST(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 364 TEST(DeclPrinter, TestFunctionDecl4) { 365 ASSERT_TRUE(PrintedDeclCXX98Matches( 366 "extern void A();", 367 "A", 368 "extern void A()")); 369 // Should be: with semicolon 370 } 371 372 TEST(DeclPrinter, TestFunctionDecl5) { 373 ASSERT_TRUE(PrintedDeclCXX98Matches( 374 "static void A();", 375 "A", 376 "static void A()")); 377 // Should be: with semicolon 378 } 379 380 TEST(DeclPrinter, TestFunctionDecl6) { 381 ASSERT_TRUE(PrintedDeclCXX98Matches( 382 "inline void A();", 383 "A", 384 "inline void A()")); 385 // Should be: with semicolon 386 } 387 388 TEST(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 396 TEST(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 404 TEST(DeclPrinter, TestFunctionDecl9) { 405 ASSERT_TRUE(PrintedDeclCXX98Matches( 406 "void A(...);", 407 "A", 408 "void A(...)")); 409 // Should be: with semicolon 410 } 411 412 TEST(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 420 TEST(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 430 TEST(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 438 TEST(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 446 TEST(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 458 TEST(DeclPrinter, TestCXXConstructorDecl1) { 459 ASSERT_TRUE(PrintedDeclCXX98Matches( 460 "struct A {" 461 " A();" 462 "};", 463 constructorDecl(ofClass(hasName("A"))).bind("id"), 464 "A()")); 465 } 466 467 TEST(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 476 TEST(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 485 TEST(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 494 TEST(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 503 TEST(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 512 TEST(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 521 TEST(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 530 TEST(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 539 TEST(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 549 TEST(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 560 TEST(DeclPrinter, TestCXXDestructorDecl1) { 561 ASSERT_TRUE(PrintedDeclCXX98Matches( 562 "struct A {" 563 " ~A();" 564 "};", 565 destructorDecl(ofClass(hasName("A"))).bind("id"), 566 "~A()")); 567 } 568 569 TEST(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 578 TEST(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 587 TEST(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 596 TEST(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 606 TEST(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 617 TEST(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 628 TEST(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 638 TEST(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 648 TEST(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 658 TEST(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 686 TEST(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 710 TEST(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 720 TEST(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 730 TEST(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 744 TEST(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 754 TEST(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 764 TEST(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 774 TEST(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 784 TEST(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 794 TEST(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 804 TEST(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 814 TEST(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 824 TEST(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 834 TEST(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 845 TEST(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 855 TEST(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 865 TEST(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 875 TEST(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 886 TEST(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 894 TEST(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 902 TEST(DeclPrinter, TestVarDecl3) { 903 ASSERT_TRUE(PrintedDeclCXX11Matches( 904 "void (*A)() noexcept;", 905 "A", 906 "void (*A)() noexcept")); 907 // Should be: with semicolon 908 } 909 910 TEST(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 919 TEST(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 928 TEST(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 937 TEST(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 946 TEST(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 955 TEST(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 964 TEST(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 973 TEST(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 982 TEST(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 992 TEST(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 1000 TEST(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 1009 TEST(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 1018 TEST(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 1027 TEST(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 1038 TEST(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 1049 TEST(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 1060 TEST(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 1069 TEST(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 1078 TEST(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 1089 TEST(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 1097 TEST(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 1105 TEST(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 1115 TEST(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 1125 TEST(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 1136 TEST(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 1146 TEST(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 1156 TEST(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 1165 TEST(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 1175 TEST(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 1186 TEST(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 1197 TEST(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 1206 TEST(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 1215 TEST(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 1224 TEST(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 1234 TEST(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 1245 TEST(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 1257 TEST(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 1268 TEST(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 1281 TEST(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 1292 TEST(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