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