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
28using namespace clang;
29using namespace ast_matchers;
30using namespace tooling;
31
32namespace {
33
34void 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
40class PrintMatch : public MatchFinder::MatchCallback {
41  SmallString<1024> Printed;
42  unsigned NumFoundDecls;
43
44public:
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
142TEST(DeclPrinter, TestNamespace1) {
143  ASSERT_TRUE(PrintedDeclCXX98Matches(
144    "namespace A { int B; }",
145    "A",
146    "namespace A {\n}"));
147    // Should be: with { ... }
148}
149
150TEST(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
158TEST(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
167TEST(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
176TEST(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
184TEST(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
192TEST(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
200TEST(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
209TEST(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
218TEST(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
227TEST(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
236TEST(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
245TEST(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
254TEST(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
263TEST(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
273TEST(DeclPrinter, TestFunctionDecl1) {
274  ASSERT_TRUE(PrintedDeclCXX98Matches(
275    "void A();",
276    "A",
277    "void A()"));
278    // Should be: with semicolon
279}
280
281TEST(DeclPrinter, TestFunctionDecl2) {
282  ASSERT_TRUE(PrintedDeclCXX98Matches(
283    "void A() {}",
284    "A",
285    "void A()"));
286    // Should be: with semicolon
287}
288
289TEST(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
298TEST(DeclPrinter, TestFunctionDecl4) {
299  ASSERT_TRUE(PrintedDeclCXX98Matches(
300    "extern void A();",
301    "A",
302    "extern void A()"));
303    // Should be: with semicolon
304}
305
306TEST(DeclPrinter, TestFunctionDecl5) {
307  ASSERT_TRUE(PrintedDeclCXX98Matches(
308    "static void A();",
309    "A",
310    "static void A()"));
311    // Should be: with semicolon
312}
313
314TEST(DeclPrinter, TestFunctionDecl6) {
315  ASSERT_TRUE(PrintedDeclCXX98Matches(
316    "inline void A();",
317    "A",
318    "inline void A()"));
319    // Should be: with semicolon
320}
321
322TEST(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
330TEST(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
338TEST(DeclPrinter, TestFunctionDecl9) {
339  ASSERT_TRUE(PrintedDeclCXX98Matches(
340    "void A(...);",
341    "A",
342    "void A(...)"));
343    // Should be: with semicolon
344}
345
346TEST(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
354TEST(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
364TEST(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
372TEST(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
380TEST(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
392TEST(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
402TEST(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
412TEST(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
422TEST(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
432TEST(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
442TEST(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
452TEST(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
462TEST(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
472TEST(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
482TEST(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)
494TEST(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
506TEST(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
516TEST(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
526TEST(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
536TEST(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
546TEST(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
557TEST(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
568TEST(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
579TEST(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
589TEST(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
599TEST(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
609TEST(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
637TEST(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
661TEST(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
671TEST(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
681TEST(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
695TEST(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
705TEST(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
715TEST(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
725TEST(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
735TEST(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
745TEST(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
755TEST(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
765TEST(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
775TEST(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
785TEST(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
796TEST(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
806TEST(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
816TEST(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
826TEST(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
837TEST(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
845TEST(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
853TEST(DeclPrinter, TestVarDecl3) {
854  ASSERT_TRUE(PrintedDeclCXX11Matches(
855    "void (*A)() noexcept;",
856    "A",
857    "void (*A)() noexcept"));
858    // Should be: with semicolon
859}
860
861TEST(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
870TEST(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
879TEST(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
888TEST(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
897TEST(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
906TEST(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
915TEST(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
924TEST(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
933TEST(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
943TEST(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
951TEST(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
960TEST(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
969TEST(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
978TEST(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
989TEST(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
1000TEST(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
1011TEST(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
1020TEST(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
1029TEST(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
1040TEST(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
1048TEST(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
1056TEST(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
1066TEST(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
1076TEST(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
1087TEST(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
1097TEST(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
1107TEST(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
1116TEST(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
1126TEST(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
1137TEST(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
1148TEST(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
1157TEST(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
1166TEST(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
1175TEST(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
1185TEST(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
1196TEST(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
1208TEST(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