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