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