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