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