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