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