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