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