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