Clang Project

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