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