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