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