1 //===- unittests/AST/DeclPrinterTest.cpp --- Declaration printer tests ----===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains tests for Decl::print() and related methods.
11 // Search this file for WRONG to see test cases that are producing something
12 // completely wrong, invalid C++ or just misleading.
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.
19 //===----------------------------------------------------------------------===//
22 #include "clang/AST/ASTContext.h"
23 #include "clang/ASTMatchers/ASTMatchFinder.h"
24 #include "clang/ASTMatchers/ASTMatchers.h"
25 #include "clang/Tooling/Tooling.h"
26 #include "llvm/ADT/SmallString.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "gtest/gtest.h"
30 using namespace clang
;
31 using namespace ast_matchers
;
32 using namespace tooling
;
36 void PrintDecl(raw_ostream
&Out
, const ASTContext
*Context
, const Decl
*D
,
37 PrintingPolicyAdjuster PolicyModifier
) {
38 PrintingPolicy Policy
= Context
->getPrintingPolicy();
39 Policy
.TerseOutput
= true;
40 Policy
.Indentation
= 0;
42 PolicyModifier(Policy
);
43 D
->print(Out
, Policy
, /*Indentation*/ 0, /*PrintInstantiation*/ false);
46 ::testing::AssertionResult
47 PrintedDeclMatches(StringRef Code
, const std::vector
<std::string
> &Args
,
48 const DeclarationMatcher
&NodeMatch
,
49 StringRef ExpectedPrinted
, StringRef FileName
,
50 PrintingPolicyAdjuster PolicyModifier
= nullptr,
51 bool AllowError
= false) {
52 return PrintedNodeMatches
<Decl
>(
53 Code
, Args
, NodeMatch
, ExpectedPrinted
, FileName
, PrintDecl
,
54 PolicyModifier
, AllowError
,
55 // Filter out implicit decls
56 [](const Decl
*D
) { return !D
->isImplicit(); });
59 ::testing::AssertionResult
60 PrintedDeclCXX98Matches(StringRef Code
, StringRef DeclName
,
61 StringRef ExpectedPrinted
,
62 PrintingPolicyAdjuster PolicyModifier
= nullptr) {
63 std::vector
<std::string
> Args(1, "-std=c++98");
64 return PrintedDeclMatches(Code
, Args
, namedDecl(hasName(DeclName
)).bind("id"),
65 ExpectedPrinted
, "input.cc", PolicyModifier
);
68 ::testing::AssertionResult
69 PrintedDeclCXX98Matches(StringRef Code
, const DeclarationMatcher
&NodeMatch
,
70 StringRef ExpectedPrinted
,
71 PrintingPolicyAdjuster PolicyModifier
= nullptr) {
72 std::vector
<std::string
> Args(1, "-std=c++98");
73 return PrintedDeclMatches(Code
,
81 ::testing::AssertionResult
PrintedDeclCXX11Matches(StringRef Code
,
83 StringRef ExpectedPrinted
) {
84 std::vector
<std::string
> Args(1, "-std=c++11");
85 return PrintedDeclMatches(Code
, Args
, namedDecl(hasName(DeclName
)).bind("id"),
86 ExpectedPrinted
, "input.cc");
89 ::testing::AssertionResult
90 PrintedDeclCXX11Matches(StringRef Code
, const DeclarationMatcher
&NodeMatch
,
91 StringRef ExpectedPrinted
,
92 PrintingPolicyAdjuster PolicyModifier
= nullptr) {
93 std::vector
<std::string
> Args(1, "-std=c++11");
94 return PrintedDeclMatches(Code
, Args
, NodeMatch
, ExpectedPrinted
, "input.cc",
98 ::testing::AssertionResult
PrintedDeclCXX11nonMSCMatches(
100 const DeclarationMatcher
&NodeMatch
,
101 StringRef ExpectedPrinted
) {
102 std::vector
<std::string
> Args
{"-std=c++11", "-fno-delayed-template-parsing"};
103 return PrintedDeclMatches(Code
,
110 ::testing::AssertionResult
111 PrintedDeclCXX17Matches(StringRef Code
, const DeclarationMatcher
&NodeMatch
,
112 StringRef ExpectedPrinted
,
113 PrintingPolicyAdjuster PolicyModifier
= nullptr) {
114 std::vector
<std::string
> Args
{"-std=c++17", "-fno-delayed-template-parsing"};
115 return PrintedDeclMatches(Code
, Args
, NodeMatch
, ExpectedPrinted
, "input.cc",
119 ::testing::AssertionResult
120 PrintedDeclC11Matches(StringRef Code
, const DeclarationMatcher
&NodeMatch
,
121 StringRef ExpectedPrinted
,
122 PrintingPolicyAdjuster PolicyModifier
= nullptr) {
123 std::vector
<std::string
> Args(1, "-std=c11");
124 return PrintedDeclMatches(Code
, Args
, NodeMatch
, ExpectedPrinted
, "input.c",
128 ::testing::AssertionResult
129 PrintedDeclObjCMatches(StringRef Code
, const DeclarationMatcher
&NodeMatch
,
130 StringRef ExpectedPrinted
, bool AllowError
= false) {
131 std::vector
<std::string
> Args(1, "");
132 return PrintedDeclMatches(Code
, Args
, NodeMatch
, ExpectedPrinted
, "input.m",
133 /*PolicyModifier=*/nullptr, AllowError
);
136 } // unnamed namespace
138 TEST(DeclPrinter
, TestTypedef1
) {
139 ASSERT_TRUE(PrintedDeclCXX98Matches(
143 // Should be: with semicolon
146 TEST(DeclPrinter
, TestTypedef2
) {
147 ASSERT_TRUE(PrintedDeclCXX98Matches(
148 "typedef const char *A;",
150 "typedef const char *A"));
151 // Should be: with semicolon
154 TEST(DeclPrinter
, TestTypedef3
) {
155 ASSERT_TRUE(PrintedDeclCXX98Matches(
156 "template <typename Y> class X {};"
159 "typedef X<int> A"));
160 // Should be: with semicolon
163 TEST(DeclPrinter
, TestTypedef4
) {
164 ASSERT_TRUE(PrintedDeclCXX98Matches(
165 "namespace X { class Y {}; }"
169 // Should be: with semicolon
172 TEST(DeclPrinter
, TestNamespace1
) {
173 ASSERT_TRUE(PrintedDeclCXX98Matches(
174 "namespace A { int B; }",
176 "namespace A {\n}"));
177 // Should be: with { ... }
180 TEST(DeclPrinter
, TestNamespace2
) {
181 ASSERT_TRUE(PrintedDeclCXX11Matches(
182 "inline namespace A { int B; }",
184 "inline namespace A {\n}"));
185 // Should be: with { ... }
188 TEST(DeclPrinter
, TestNamespaceAlias1
) {
189 ASSERT_TRUE(PrintedDeclCXX98Matches(
194 // Should be: with semicolon
197 TEST(DeclPrinter
, TestNamespaceAlias2
) {
198 ASSERT_TRUE(PrintedDeclCXX98Matches(
199 "namespace X { namespace Y {} }"
200 "namespace A = X::Y;",
202 "namespace A = X::Y"));
203 // Should be: with semicolon
206 TEST(DeclPrinter
, TestNamespaceUnnamed
) {
207 ASSERT_TRUE(PrintedDeclCXX17Matches(
208 "namespace { int X; }",
209 namespaceDecl(has(varDecl(hasName("X")))).bind("id"),
210 "namespace {\nint X;\n}",
211 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
214 TEST(DeclPrinter
, TestNamespaceUsingDirective
) {
215 ASSERT_TRUE(PrintedDeclCXX17Matches(
216 "namespace X { namespace A {} }"
217 "using namespace X::A;",
218 usingDirectiveDecl().bind("id"), "using namespace X::A",
219 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
222 TEST(DeclPrinter
, TestEnumDecl1
) {
223 ASSERT_TRUE(PrintedDeclCXX17Matches(
224 "enum A { a0, a1, a2 };", enumDecl(hasName("A")).bind("id"),
225 "enum A {\na0,\na1,\na2\n}",
226 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
229 TEST(DeclPrinter
, TestEnumDecl2
) {
230 ASSERT_TRUE(PrintedDeclCXX17Matches(
231 "enum A { a0 = -1, a1, a2 = 1 };", enumDecl(hasName("A")).bind("id"),
232 "enum A {\na0 = -1,\na1,\na2 = 1\n}",
233 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
236 TEST(DeclPrinter
, TestEnumDecl3
) {
237 ASSERT_TRUE(PrintedDeclCXX17Matches(
238 "enum { a0, a1, a2 };",
239 enumDecl(has(enumConstantDecl(hasName("a0")))).bind("id"),
240 "enum {\na0,\na1,\na2\n}",
241 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
244 TEST(DeclPrinter
, TestEnumDecl4
) {
245 ASSERT_TRUE(PrintedDeclCXX17Matches(
246 "enum class A { a0, a1, a2 };", enumDecl(hasName("A")).bind("id"),
247 "enum class A : int {\na0,\na1,\na2\n}",
248 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
251 TEST(DeclPrinter
, TestRecordDecl1
) {
252 ASSERT_TRUE(PrintedDeclC11Matches(
253 "struct A { int a; };", recordDecl(hasName("A")).bind("id"),
254 "struct A {\nint a;\n}",
255 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
258 TEST(DeclPrinter
, TestRecordDecl2
) {
259 ASSERT_TRUE(PrintedDeclC11Matches(
260 "struct A { struct { int i; }; };", recordDecl(hasName("A")).bind("id"),
261 "struct A {\nstruct {\nint i;\n};\n}",
262 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
265 TEST(DeclPrinter
, TestRecordDecl3
) {
266 ASSERT_TRUE(PrintedDeclC11Matches(
267 "union { int A; } u;",
268 recordDecl(has(fieldDecl(hasName("A")))).bind("id"), "union {\nint A;\n}",
269 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
272 TEST(DeclPrinter
, TestCXXRecordDecl1
) {
273 ASSERT_TRUE(PrintedDeclCXX98Matches(
274 "class A { int a; };",
279 TEST(DeclPrinter
, TestCXXRecordDecl2
) {
280 ASSERT_TRUE(PrintedDeclCXX98Matches(
281 "struct A { int a; };",
286 TEST(DeclPrinter
, TestCXXRecordDecl3
) {
287 ASSERT_TRUE(PrintedDeclCXX98Matches(
288 "union A { int a; };",
293 TEST(DeclPrinter
, TestCXXRecordDecl4
) {
294 ASSERT_TRUE(PrintedDeclCXX98Matches(
295 "class Z { int a; };"
296 "class A : Z { int b; };",
301 TEST(DeclPrinter
, TestCXXRecordDecl5
) {
302 ASSERT_TRUE(PrintedDeclCXX98Matches(
303 "struct Z { int a; };"
304 "struct A : Z { int b; };",
309 TEST(DeclPrinter
, TestCXXRecordDecl6
) {
310 ASSERT_TRUE(PrintedDeclCXX98Matches(
311 "class Z { int a; };"
312 "class A : public Z { int b; };",
314 "class A : public Z {}"));
317 TEST(DeclPrinter
, TestCXXRecordDecl7
) {
318 ASSERT_TRUE(PrintedDeclCXX98Matches(
319 "class Z { int a; };"
320 "class A : protected Z { int b; };",
322 "class A : protected Z {}"));
325 TEST(DeclPrinter
, TestCXXRecordDecl8
) {
326 ASSERT_TRUE(PrintedDeclCXX98Matches(
327 "class Z { int a; };"
328 "class A : private Z { int b; };",
330 "class A : private Z {}"));
333 TEST(DeclPrinter
, TestCXXRecordDecl9
) {
334 ASSERT_TRUE(PrintedDeclCXX98Matches(
335 "class Z { int a; };"
336 "class A : virtual Z { int b; };",
338 "class A : virtual Z {}"));
341 TEST(DeclPrinter
, TestCXXRecordDecl10
) {
342 ASSERT_TRUE(PrintedDeclCXX98Matches(
343 "class Z { int a; };"
344 "class A : virtual public Z { int b; };",
346 "class A : virtual public Z {}"));
349 TEST(DeclPrinter
, TestCXXRecordDecl11
) {
350 ASSERT_TRUE(PrintedDeclCXX98Matches(
351 "class Z { int a; };"
352 "class Y : virtual public Z { int b; };"
353 "class A : virtual public Z, private Y { int c; };",
355 "class A : virtual public Z, private Y {}"));
358 TEST(DeclPrinter
, TestCXXRecordDecl12
) {
360 PrintedDeclCXX98Matches("struct S { int x; };"
361 "namespace NS { class C {};}"
362 "void foo() {using namespace NS; C c;}",
364 "void foo() {\nusing namespace NS;\nclass "
366 [](PrintingPolicy
&Policy
) {
367 Policy
.SuppressTagKeyword
= false;
368 Policy
.SuppressScope
= true;
369 Policy
.TerseOutput
= false;
373 TEST(DeclPrinter
, TestCXXRecordDecl13
) {
374 ASSERT_TRUE(PrintedDeclCXX98Matches(
375 "struct S { int x; };"
377 "S foo() {return s1;}",
378 "foo", "struct S foo() {\nreturn s1;\n}\n", [](PrintingPolicy
&Policy
) {
379 Policy
.SuppressTagKeyword
= false;
380 Policy
.SuppressScope
= true;
381 Policy
.TerseOutput
= false;
385 TEST(DeclPrinter
, TestCXXRecordDecl14
) {
386 ASSERT_TRUE(PrintedDeclCXX98Matches(
387 "struct S { int x; };"
388 "S foo(S s1) {return s1;}",
389 "foo", "struct S foo(struct S s1) {\nreturn s1;\n}\n",
390 [](PrintingPolicy
&Policy
) {
391 Policy
.SuppressTagKeyword
= false;
392 Policy
.SuppressScope
= true;
393 Policy
.TerseOutput
= false;
396 TEST(DeclPrinter
, TestCXXRecordDecl15
) {
397 ASSERT_TRUE(PrintedDeclCXX98Matches(
398 "struct S { int x; };"
399 "namespace NS { class C {};}"
400 "S foo(S s1, NS::C c1) {using namespace NS; C c; return s1;}",
402 "struct S foo(struct S s1, class NS::C c1) {\nusing namespace NS;\nclass "
403 "NS::C c;\nreturn s1;\n}\n",
404 [](PrintingPolicy
&Policy
) {
405 Policy
.SuppressTagKeyword
= false;
406 Policy
.SuppressScope
= true;
407 Policy
.TerseOutput
= false;
411 TEST(DeclPrinter
, TestFunctionDecl1
) {
412 ASSERT_TRUE(PrintedDeclCXX98Matches(
418 TEST(DeclPrinter
, TestFreeFunctionDecl_FullyQualifiedName
) {
419 ASSERT_TRUE(PrintedDeclCXX98Matches(
423 [](PrintingPolicy
&Policy
){ Policy
.FullyQualifiedName
= true; }));
426 TEST(DeclPrinter
, TestFreeFunctionDeclInNamespace_FullyQualifiedName
) {
427 ASSERT_TRUE(PrintedDeclCXX98Matches(
428 "namespace X { void A(); };",
431 [](PrintingPolicy
&Policy
){ Policy
.FullyQualifiedName
= true; }));
434 TEST(DeclPrinter
, TestMemberFunction_FullyQualifiedName
) {
435 ASSERT_TRUE(PrintedDeclCXX98Matches(
436 "struct X { void A(); };",
439 [](PrintingPolicy
&Policy
){ Policy
.FullyQualifiedName
= true; }));
442 TEST(DeclPrinter
, TestMemberFunctionInNamespace_FullyQualifiedName
) {
443 ASSERT_TRUE(PrintedDeclCXX98Matches(
444 "namespace Z { struct X { void A(); }; }",
447 [](PrintingPolicy
&Policy
){ Policy
.FullyQualifiedName
= true; }));
450 TEST(DeclPrinter
, TestMemberFunctionOutside_FullyQualifiedName
) {
451 ASSERT_TRUE(PrintedDeclCXX98Matches(
452 "struct X { void A(); };"
454 functionDecl(hasName("A"), isDefinition()).bind("id"),
456 [](PrintingPolicy
&Policy
){ Policy
.FullyQualifiedName
= true; }));
459 TEST(DeclPrinter
, TestFunctionDecl2
) {
460 ASSERT_TRUE(PrintedDeclCXX98Matches(
466 TEST(DeclPrinter
, TestFunctionDecl3
) {
467 ASSERT_TRUE(PrintedDeclCXX98Matches(
474 TEST(DeclPrinter
, TestFunctionDecl4
) {
475 ASSERT_TRUE(PrintedDeclCXX98Matches(
481 TEST(DeclPrinter
, TestFunctionDecl5
) {
482 ASSERT_TRUE(PrintedDeclCXX98Matches(
488 TEST(DeclPrinter
, TestFunctionDecl6
) {
489 ASSERT_TRUE(PrintedDeclCXX98Matches(
495 TEST(DeclPrinter
, TestFunctionDecl7
) {
496 ASSERT_TRUE(PrintedDeclCXX11Matches(
497 "constexpr int A(int a);",
499 "constexpr int A(int a)"));
502 TEST(DeclPrinter
, TestFunctionDecl8
) {
503 ASSERT_TRUE(PrintedDeclCXX98Matches(
509 TEST(DeclPrinter
, TestFunctionDecl9
) {
510 ASSERT_TRUE(PrintedDeclCXX98Matches(
516 TEST(DeclPrinter
, TestFunctionDecl10
) {
517 ASSERT_TRUE(PrintedDeclCXX98Matches(
518 "void A(int a, ...);",
520 "void A(int a, ...)"));
523 TEST(DeclPrinter
, TestFunctionDecl11
) {
524 ASSERT_TRUE(PrintedDeclCXX98Matches(
525 "typedef long ssize_t;"
527 "void A(int a, pInt b, ssize_t c);",
529 "void A(int a, pInt b, ssize_t c)"));
532 TEST(DeclPrinter
, TestFunctionDecl12
) {
533 ASSERT_TRUE(PrintedDeclCXX98Matches(
534 "void A(int a, int b = 0);",
536 "void A(int a, int b = 0)"));
539 TEST(DeclPrinter
, TestFunctionDecl13
) {
540 ASSERT_TRUE(PrintedDeclCXX98Matches(
541 "void (*A(int a))(int b);",
543 "void (*A(int a))(int)"));
544 // Should be: with parameter name (?)
547 TEST(DeclPrinter
, TestFunctionDecl14
) {
548 ASSERT_TRUE(PrintedDeclCXX98Matches(
549 "template<typename T>"
553 functionDecl(hasName("A"), isExplicitTemplateSpecialization()).bind("id"),
554 "template<> void A<int>(int N)"));
558 TEST(DeclPrinter
, TestCXXConstructorDecl1
) {
559 ASSERT_TRUE(PrintedDeclCXX98Matches(
563 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
567 TEST(DeclPrinter
, TestCXXConstructorDecl2
) {
568 ASSERT_TRUE(PrintedDeclCXX98Matches(
572 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
576 TEST(DeclPrinter
, TestCXXConstructorDecl3
) {
577 ASSERT_TRUE(PrintedDeclCXX98Matches(
581 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
585 TEST(DeclPrinter
, TestCXXConstructorDecl4
) {
586 ASSERT_TRUE(PrintedDeclCXX98Matches(
588 " A(const A &a, int = 0);"
590 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
591 "A(const A &a, int = 0)"));
594 TEST(DeclPrinter
, TestCXXConstructorDeclWithMemberInitializer
) {
595 ASSERT_TRUE(PrintedDeclCXX98Matches(
600 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
604 TEST(DeclPrinter
, TestCXXConstructorDeclWithMemberInitializer_NoTerseOutput
) {
605 ASSERT_TRUE(PrintedDeclCXX98Matches(
610 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
612 [](PrintingPolicy
&Policy
){ Policy
.TerseOutput
= false; }));
615 TEST(DeclPrinter
, TestCXXConstructorDecl5
) {
616 ASSERT_TRUE(PrintedDeclCXX11Matches(
620 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
624 TEST(DeclPrinter
, TestCXXConstructorDecl6
) {
625 ASSERT_TRUE(PrintedDeclCXX98Matches(
627 " explicit A(int a);"
629 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
630 "explicit A(int a)"));
633 TEST(DeclPrinter
, TestCXXConstructorDecl7
) {
634 ASSERT_TRUE(PrintedDeclCXX11Matches(
638 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
642 TEST(DeclPrinter
, TestCXXConstructorDecl8
) {
643 ASSERT_TRUE(PrintedDeclCXX11Matches(
647 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
651 TEST(DeclPrinter
, TestCXXConstructorDecl9
) {
652 ASSERT_TRUE(PrintedDeclCXX11Matches(
656 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
660 TEST(DeclPrinter
, TestCXXConstructorDecl10
) {
661 ASSERT_TRUE(PrintedDeclCXX11Matches(
662 "template<typename... T>"
666 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
667 "A<T...>(const A<T...> &a)"));
670 TEST(DeclPrinter
, TestCXXConstructorDecl11
) {
671 ASSERT_TRUE(PrintedDeclCXX11nonMSCMatches(
672 "template<typename... T>"
673 "struct A : public T... {"
674 " A(T&&... ts) : T(ts)... {}"
676 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
677 "A<T...>(T &&...ts)"));
680 TEST(DeclPrinter
, TestCXXDestructorDecl1
) {
681 ASSERT_TRUE(PrintedDeclCXX98Matches(
685 cxxDestructorDecl(ofClass(hasName("A"))).bind("id"),
689 TEST(DeclPrinter
, TestCXXDestructorDecl2
) {
690 ASSERT_TRUE(PrintedDeclCXX98Matches(
694 cxxDestructorDecl(ofClass(hasName("A"))).bind("id"),
698 TEST(DeclPrinter
, TestCXXConversionDecl1
) {
699 ASSERT_TRUE(PrintedDeclCXX98Matches(
703 cxxMethodDecl(ofClass(hasName("A"))).bind("id"),
707 TEST(DeclPrinter
, TestCXXConversionDecl2
) {
708 ASSERT_TRUE(PrintedDeclCXX98Matches(
712 cxxMethodDecl(ofClass(hasName("A"))).bind("id"),
716 TEST(DeclPrinter
, TestCXXConversionDecl3
) {
717 ASSERT_TRUE(PrintedDeclCXX98Matches(
722 cxxMethodDecl(ofClass(hasName("A"))).bind("id"),
726 TEST(DeclPrinter
, TestCXXMethodDecl_AllocationFunction1
) {
727 ASSERT_TRUE(PrintedDeclCXX11Matches(
728 "namespace std { typedef decltype(sizeof(int)) size_t; }"
730 " void *operator new(std::size_t);"
732 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),
733 "void *operator new(std::size_t)"));
736 TEST(DeclPrinter
, TestCXXMethodDecl_AllocationFunction2
) {
737 ASSERT_TRUE(PrintedDeclCXX11Matches(
738 "namespace std { typedef decltype(sizeof(int)) size_t; }"
740 " void *operator new[](std::size_t);"
742 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),
743 "void *operator new[](std::size_t)"));
746 TEST(DeclPrinter
, TestCXXMethodDecl_AllocationFunction3
) {
747 ASSERT_TRUE(PrintedDeclCXX11Matches(
749 " void operator delete(void *);"
751 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),
752 "void operator delete(void *) noexcept"));
753 // Should be: without noexcept?
756 TEST(DeclPrinter
, TestCXXMethodDecl_AllocationFunction4
) {
757 ASSERT_TRUE(PrintedDeclCXX98Matches(
759 " void operator delete(void *);"
761 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),
762 "void operator delete(void *)"));
765 TEST(DeclPrinter
, TestCXXMethodDecl_AllocationFunction5
) {
766 ASSERT_TRUE(PrintedDeclCXX11Matches(
768 " void operator delete[](void *);"
770 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),
771 "void operator delete[](void *) noexcept"));
772 // Should be: without noexcept?
775 TEST(DeclPrinter
, TestCXXMethodDecl_Operator1
) {
776 const char *OperatorNames
[] = {
777 "+", "-", "*", "/", "%", "^", "&", "|",
778 "=", "<", ">", "+=", "-=", "*=", "/=", "%=",
779 "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==", "!=",
780 "<=", ">=", "&&", "||", ",", "->*",
784 for (unsigned i
= 0, e
= std::size(OperatorNames
); i
!= e
; ++i
) {
785 SmallString
<128> Code
;
786 Code
.append("struct Z { void operator");
787 Code
.append(OperatorNames
[i
]);
788 Code
.append("(Z z); };");
790 SmallString
<128> Expected
;
791 Expected
.append("void operator");
792 Expected
.append(OperatorNames
[i
]);
793 Expected
.append("(Z z)");
795 ASSERT_TRUE(PrintedDeclCXX98Matches(
797 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),
802 TEST(DeclPrinter
, TestCXXMethodDecl_Operator2
) {
803 const char *OperatorNames
[] = {
804 "~", "!", "++", "--", "->"
807 for (unsigned i
= 0, e
= std::size(OperatorNames
); i
!= e
; ++i
) {
808 SmallString
<128> Code
;
809 Code
.append("struct Z { void operator");
810 Code
.append(OperatorNames
[i
]);
811 Code
.append("(); };");
813 SmallString
<128> Expected
;
814 Expected
.append("void operator");
815 Expected
.append(OperatorNames
[i
]);
816 Expected
.append("()");
818 ASSERT_TRUE(PrintedDeclCXX98Matches(
820 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),
825 TEST(DeclPrinter
, TestCXXMethodDecl1
) {
826 ASSERT_TRUE(PrintedDeclCXX98Matches(
834 TEST(DeclPrinter
, TestCXXMethodDecl2
) {
835 ASSERT_TRUE(PrintedDeclCXX98Matches(
837 " virtual void A(int a);"
840 "virtual void A(int a)"));
843 TEST(DeclPrinter
, TestCXXMethodDecl3
) {
844 ASSERT_TRUE(PrintedDeclCXX98Matches(
846 " virtual void A(int a);"
853 // TODO: should we print "virtual"?
856 TEST(DeclPrinter
, TestCXXMethodDecl4
) {
857 ASSERT_TRUE(PrintedDeclCXX98Matches(
859 " inline void A(int a);"
862 "inline void A(int a)"));
865 TEST(DeclPrinter
, TestCXXMethodDecl5
) {
866 ASSERT_TRUE(PrintedDeclCXX98Matches(
868 " virtual void A(int a) = 0;"
871 "virtual void A(int a) = 0"));
874 TEST(DeclPrinter
, TestCXXMethodDecl_CVQualifier1
) {
875 ASSERT_TRUE(PrintedDeclCXX98Matches(
877 " void A(int a) const;"
880 "void A(int a) const"));
883 TEST(DeclPrinter
, TestCXXMethodDecl_CVQualifier2
) {
884 ASSERT_TRUE(PrintedDeclCXX98Matches(
886 " void A(int a) volatile;"
889 "void A(int a) volatile"));
892 TEST(DeclPrinter
, TestCXXMethodDecl_CVQualifier3
) {
893 ASSERT_TRUE(PrintedDeclCXX98Matches(
895 " void A(int a) const volatile;"
898 "void A(int a) const volatile"));
901 TEST(DeclPrinter
, TestCXXMethodDecl_RefQualifier1
) {
902 ASSERT_TRUE(PrintedDeclCXX11Matches(
910 TEST(DeclPrinter
, TestCXXMethodDecl_RefQualifier2
) {
911 ASSERT_TRUE(PrintedDeclCXX11Matches(
916 "void A(int a) &&"));
919 TEST(DeclPrinter
, TestFunctionDecl_ExceptionSpecification1
) {
920 ASSERT_TRUE(PrintedDeclCXX98Matches(
922 " void A(int a) throw();"
925 "void A(int a) throw()"));
928 TEST(DeclPrinter
, TestFunctionDecl_ExceptionSpecification2
) {
929 ASSERT_TRUE(PrintedDeclCXX98Matches(
931 " void A(int a) throw(int);"
934 "void A(int a) throw(int)"));
937 TEST(DeclPrinter
, TestFunctionDecl_ExceptionSpecification3
) {
938 ASSERT_TRUE(PrintedDeclCXX98Matches(
941 " void A(int a) throw(ZZ, int);"
944 "void A(int a) throw(ZZ, int)"));
947 TEST(DeclPrinter
, TestFunctionDecl_ExceptionSpecification4
) {
948 ASSERT_TRUE(PrintedDeclCXX11Matches(
950 " void A(int a) noexcept;"
953 "void A(int a) noexcept"));
956 TEST(DeclPrinter
, TestFunctionDecl_ExceptionSpecification5
) {
957 ASSERT_TRUE(PrintedDeclCXX11Matches(
959 " void A(int a) noexcept(true);"
962 "void A(int a) noexcept(true)"));
965 TEST(DeclPrinter
, TestFunctionDecl_ExceptionSpecification6
) {
966 ASSERT_TRUE(PrintedDeclCXX11Matches(
968 " void A(int a) noexcept(1 < 2);"
971 "void A(int a) noexcept(1 < 2)"));
974 TEST(DeclPrinter
, TestFunctionDecl_ExceptionSpecification7
) {
975 ASSERT_TRUE(PrintedDeclCXX11Matches(
978 " void A(int a) noexcept(N < 2);"
981 "void A(int a) noexcept(N < 2)"));
984 TEST(DeclPrinter
, TestVarDecl1
) {
985 ASSERT_TRUE(PrintedDeclCXX98Matches(
986 "char *const (*(*A)[5])(int);",
988 "char *const (*(*A)[5])(int)"));
989 // Should be: with semicolon
992 TEST(DeclPrinter
, TestVarDecl2
) {
993 ASSERT_TRUE(PrintedDeclCXX98Matches(
994 "void (*A)() throw(int);",
996 "void (*A)() throw(int)"));
997 // Should be: with semicolon
1000 TEST(DeclPrinter
, TestVarDecl3
) {
1001 ASSERT_TRUE(PrintedDeclCXX11Matches(
1002 "void (*A)() noexcept;",
1004 "void (*A)() noexcept"));
1005 // Should be: with semicolon
1008 TEST(DeclPrinter
, TestFieldDecl1
) {
1009 ASSERT_TRUE(PrintedDeclCXX98Matches(
1010 "template<typename T>"
1011 "struct Z { T A; };",
1014 // Should be: with semicolon
1017 TEST(DeclPrinter
, TestFieldDecl2
) {
1018 ASSERT_TRUE(PrintedDeclCXX98Matches(
1020 "struct Z { int A[N]; };",
1023 // Should be: with semicolon
1026 TEST(DeclPrinter
, TestClassTemplateDecl1
) {
1027 ASSERT_TRUE(PrintedDeclCXX98Matches(
1028 "template<typename T>"
1029 "struct A { T a; };",
1030 classTemplateDecl(hasName("A")).bind("id"),
1031 "template <typename T> struct A {}"));
1034 TEST(DeclPrinter
, TestClassTemplateDecl2
) {
1035 ASSERT_TRUE(PrintedDeclCXX98Matches(
1036 "template<typename T = int>"
1037 "struct A { T a; };",
1038 classTemplateDecl(hasName("A")).bind("id"),
1039 "template <typename T = int> struct A {}"));
1042 TEST(DeclPrinter
, TestClassTemplateDecl3
) {
1043 ASSERT_TRUE(PrintedDeclCXX98Matches(
1045 "struct A { T a; };",
1046 classTemplateDecl(hasName("A")).bind("id"),
1047 "template <class T> struct A {}"));
1050 TEST(DeclPrinter
, TestClassTemplateDecl4
) {
1051 ASSERT_TRUE(PrintedDeclCXX98Matches(
1052 "template<typename T, typename U>"
1053 "struct A { T a; U b; };",
1054 classTemplateDecl(hasName("A")).bind("id"),
1055 "template <typename T, typename U> struct A {}"));
1058 TEST(DeclPrinter
, TestClassTemplateDecl5
) {
1059 ASSERT_TRUE(PrintedDeclCXX98Matches(
1061 "struct A { int a[N]; };",
1062 classTemplateDecl(hasName("A")).bind("id"),
1063 "template <int N> struct A {}"));
1066 TEST(DeclPrinter
, TestClassTemplateDecl6
) {
1067 ASSERT_TRUE(PrintedDeclCXX98Matches(
1068 "template<int N = 42>"
1069 "struct A { int a[N]; };",
1070 classTemplateDecl(hasName("A")).bind("id"),
1071 "template <int N = 42> struct A {}"));
1074 TEST(DeclPrinter
, TestClassTemplateDecl7
) {
1075 ASSERT_TRUE(PrintedDeclCXX98Matches(
1076 "typedef int MyInt;"
1078 "struct A { int a[N]; };",
1079 classTemplateDecl(hasName("A")).bind("id"),
1080 "template <MyInt N> struct A {}"));
1083 TEST(DeclPrinter
, TestClassTemplateDecl8
) {
1084 ASSERT_TRUE(PrintedDeclCXX98Matches(
1085 "template<template<typename U> class T> struct A { };",
1086 classTemplateDecl(hasName("A")).bind("id"),
1087 "template <template <typename U> class T> struct A {}"));
1090 TEST(DeclPrinter
, TestClassTemplateDecl9
) {
1091 ASSERT_TRUE(PrintedDeclCXX98Matches(
1092 "template<typename T> struct Z { };"
1093 "template<template<typename U> class T = Z> struct A { };",
1094 classTemplateDecl(hasName("A")).bind("id"),
1095 "template <template <typename U> class T> struct A {}"));
1098 TEST(DeclPrinter
, TestClassTemplateDecl10
) {
1099 ASSERT_TRUE(PrintedDeclCXX11Matches(
1100 "template<typename... T>"
1101 "struct A { int a; };",
1102 classTemplateDecl(hasName("A")).bind("id"),
1103 "template <typename ...T> struct A {}"));
1106 TEST(DeclPrinter
, TestClassTemplateDecl11
) {
1107 ASSERT_TRUE(PrintedDeclCXX11Matches(
1108 "template<typename... T>"
1109 "struct A : public T... { int a; };",
1110 classTemplateDecl(hasName("A")).bind("id"),
1111 "template <typename ...T> struct A : public T... {}"));
1114 TEST(DeclPrinter
, TestClassTemplatePartialSpecializationDecl1
) {
1115 ASSERT_TRUE(PrintedDeclCXX98Matches(
1116 "template<typename T, typename U>"
1117 "struct A { T a; U b; };"
1118 "template<typename T>"
1119 "struct A<T, int> { T a; };",
1120 classTemplateSpecializationDecl().bind("id"),
1121 "template <typename T> struct A<T, int> {}"));
1124 TEST(DeclPrinter
, TestClassTemplatePartialSpecializationDecl2
) {
1125 ASSERT_TRUE(PrintedDeclCXX98Matches(
1126 "template<typename T>"
1127 "struct A { T a; };"
1128 "template<typename T>"
1129 "struct A<T *> { T a; };",
1130 classTemplateSpecializationDecl().bind("id"),
1131 "template <typename T> struct A<T *> {}"));
1134 TEST(DeclPrinter
, TestClassTemplateSpecializationDecl1
) {
1135 ASSERT_TRUE(PrintedDeclCXX98Matches(
1136 "template<typename T>"
1137 "struct A { T a; };"
1139 "struct A<int> { int a; };",
1140 classTemplateSpecializationDecl().bind("id"),
1141 "template<> struct A<int> {}"));
1144 TEST(DeclPrinter
, TestFunctionTemplateDecl1
) {
1145 ASSERT_TRUE(PrintedDeclCXX98Matches(
1146 "template<typename T>"
1148 functionTemplateDecl(hasName("A")).bind("id"),
1149 "template <typename T> void A(T &t)"));
1152 TEST(DeclPrinter
, TestFunctionTemplateDecl2
) {
1153 ASSERT_TRUE(PrintedDeclCXX98Matches(
1154 "template<typename T>"
1156 functionTemplateDecl(hasName("A")).bind("id"),
1157 "template <typename T> void A(T &t)"));
1160 TEST(DeclPrinter
, TestFunctionTemplateDecl3
) {
1161 ASSERT_TRUE(PrintedDeclCXX11Matches(
1162 "template<typename... T>"
1164 functionTemplateDecl(hasName("A")).bind("id"),
1165 "template <typename ...T> void A(T ...a)"));
1168 TEST(DeclPrinter
, TestFunctionTemplateDecl4
) {
1169 ASSERT_TRUE(PrintedDeclCXX98Matches(
1170 "struct Z { template<typename T> void A(T t); };",
1171 functionTemplateDecl(hasName("A")).bind("id"),
1172 "template <typename T> void A(T t)"));
1175 TEST(DeclPrinter
, TestFunctionTemplateDecl5
) {
1176 ASSERT_TRUE(PrintedDeclCXX98Matches(
1177 "struct Z { template<typename T> void A(T t) {} };",
1178 functionTemplateDecl(hasName("A")).bind("id"),
1179 "template <typename T> void A(T t)"));
1182 TEST(DeclPrinter
, TestFunctionTemplateDecl6
) {
1183 ASSERT_TRUE(PrintedDeclCXX98Matches(
1184 "template<typename T >struct Z {"
1185 " template<typename U> void A(U t) {}"
1187 functionTemplateDecl(hasName("A")).bind("id"),
1188 "template <typename U> void A(U t)"));
1191 TEST(DeclPrinter
, TestUnnamedTemplateParameters
) {
1192 ASSERT_TRUE(PrintedDeclCXX17Matches(
1193 "template <typename, int, template <typename, bool> class> void A();",
1194 functionTemplateDecl(hasName("A")).bind("id"),
1195 "template <typename, int, template <typename, bool> class> void A()"));
1198 TEST(DeclPrinter
, TestUnnamedTemplateParametersPacks
) {
1199 ASSERT_TRUE(PrintedDeclCXX17Matches(
1200 "template <typename ..., int ...,"
1201 " template <typename ..., bool ...> class ...> void A();",
1202 functionTemplateDecl(hasName("A")).bind("id"),
1203 "template <typename ..., int ...,"
1204 " template <typename ..., bool ...> class ...> void A()"));
1207 TEST(DeclPrinter
, TestNamedTemplateParametersPacks
) {
1208 ASSERT_TRUE(PrintedDeclCXX17Matches(
1209 "template <typename ...T, int ...I,"
1210 " template <typename ...X, bool ...B> class ...Z> void A();",
1211 functionTemplateDecl(hasName("A")).bind("id"),
1212 "template <typename ...T, int ...I,"
1213 " template <typename ...X, bool ...B> class ...Z> void A()"));
1216 TEST(DeclPrinter
, TestTemplateTemplateParameterWrittenWithTypename
) {
1217 ASSERT_TRUE(PrintedDeclCXX17Matches(
1218 "template <template <typename> typename Z> void A();",
1219 functionTemplateDecl(hasName("A")).bind("id"),
1220 "template <template <typename> typename Z> void A()"));
1223 TEST(DeclPrinter
, TestTemplateArgumentList1
) {
1224 ASSERT_TRUE(PrintedDeclCXX98Matches(
1225 "template<typename T> struct Z {};"
1230 // Should be: with semicolon
1233 TEST(DeclPrinter
, TestTemplateArgumentList2
) {
1234 ASSERT_TRUE(PrintedDeclCXX98Matches(
1235 "template<typename T, typename U> struct Z {};"
1241 // Should be: with semicolon
1244 TEST(DeclPrinter
, TestTemplateArgumentList3
) {
1245 ASSERT_TRUE(PrintedDeclCXX98Matches(
1246 "template<typename T> struct Z {};"
1247 "template<typename T> struct X {};"
1251 // Should be: with semicolon
1254 TEST(DeclPrinter
, TestTemplateArgumentList4
) {
1255 ASSERT_TRUE(PrintedDeclCXX11Matches(
1256 "template<typename T> struct Z {};"
1257 "template<typename T> struct X {};"
1261 // Should be: with semicolon
1264 TEST(DeclPrinter
, TestTemplateArgumentList5
) {
1265 ASSERT_TRUE(PrintedDeclCXX98Matches(
1266 "template<typename T> struct Z {};"
1267 "template<typename T> struct X { Z<T> A; };",
1270 // Should be: with semicolon
1273 TEST(DeclPrinter
, TestTemplateArgumentList6
) {
1274 ASSERT_TRUE(PrintedDeclCXX98Matches(
1275 "template<template<typename T> class U> struct Z {};"
1276 "template<typename T> struct X {};"
1280 // Should be: with semicolon
1283 TEST(DeclPrinter
, TestTemplateArgumentList7
) {
1284 ASSERT_TRUE(PrintedDeclCXX98Matches(
1285 "template<template<typename T> class U> struct Z {};"
1286 "template<template<typename T> class U> struct Y {"
1291 // Should be: with semicolon
1294 TEST(DeclPrinter
, TestTemplateArgumentList8
) {
1295 ASSERT_TRUE(PrintedDeclCXX98Matches(
1296 "template<typename T> struct Z {};"
1297 "template<template<typename T> class U> struct Y {"
1302 // Should be: with semicolon
1305 TEST(DeclPrinter
, TestTemplateArgumentList9
) {
1306 ASSERT_TRUE(PrintedDeclCXX98Matches(
1307 "template<unsigned I> struct Z {};"
1311 // Should be: with semicolon
1314 TEST(DeclPrinter
, TestTemplateArgumentList10
) {
1315 ASSERT_TRUE(PrintedDeclCXX98Matches(
1316 "template<unsigned I> struct Z {};"
1317 "template<unsigned I> struct X { Z<I> A; };",
1320 // Should be: with semicolon
1323 TEST(DeclPrinter
, TestTemplateArgumentList11
) {
1324 ASSERT_TRUE(PrintedDeclCXX98Matches(
1325 "template<int I> struct Z {};"
1326 "Z<42 * 10 - 420 / 1> A;",
1328 "Z<42 * 10 - 420 / 1> A"));
1329 // Should be: with semicolon
1332 TEST(DeclPrinter
, TestTemplateArgumentList12
) {
1333 ASSERT_TRUE(PrintedDeclCXX98Matches(
1334 "template<const char *p> struct Z {};"
1335 "extern const char X[] = \"aaa\";"
1339 // Should be: with semicolon
1342 TEST(DeclPrinter
, TestTemplateArgumentList13
) {
1343 ASSERT_TRUE(PrintedDeclCXX11Matches(
1344 "template<typename... T> struct Z {};"
1345 "template<typename... T> struct X {"
1350 // Should be: with semicolon
1353 TEST(DeclPrinter
, TestTemplateArgumentList14
) {
1354 ASSERT_TRUE(PrintedDeclCXX11Matches(
1355 "template<typename... T> struct Z {};"
1356 "template<typename T> struct Y {};"
1357 "template<typename... T> struct X {"
1362 // Should be: with semicolon
1365 TEST(DeclPrinter
, TestTemplateArgumentList15
) {
1366 ASSERT_TRUE(PrintedDeclCXX11Matches(
1367 "template<unsigned I> struct Z {};"
1368 "template<typename... T> struct X {"
1369 " Z<sizeof...(T)> A;"
1372 "Z<sizeof...(T)> A"));
1373 // Should be: with semicolon
1376 TEST(DeclPrinter
, TestTemplateArgumentList16
) {
1377 llvm::StringLiteral Code
= "template<typename T1, int NT1, typename T2 = "
1378 "bool, int NT2 = 5> struct Z {};";
1379 ASSERT_TRUE(PrintedDeclCXX11Matches(Code
, "T1", "typename T1"));
1380 ASSERT_TRUE(PrintedDeclCXX11Matches(Code
, "T2", "typename T2 = bool"));
1381 ASSERT_TRUE(PrintedDeclCXX11Matches(Code
, "NT1", "int NT1"));
1382 ASSERT_TRUE(PrintedDeclCXX11Matches(Code
, "NT2", "int NT2 = 5"));
1385 TEST(DeclPrinter
, TestCXXRecordDecl17
) {
1386 ASSERT_TRUE(PrintedDeclCXX98Matches(
1387 "template<typename T> struct Z {};"
1391 [](PrintingPolicy
&Policy
) { Policy
.SuppressTagKeyword
= false; }));
1394 TEST(DeclPrinter
, TestCXXRecordDecl18
) {
1395 ASSERT_TRUE(PrintedDeclCXX98Matches(
1396 "template<typename T> struct Z {};"
1399 "template <typename T1, int>"
1402 "B", "Y<Z<X>, 2> B",
1403 [](PrintingPolicy
&Policy
) { Policy
.SuppressTagKeyword
= false; }));
1406 TEST(DeclPrinter
, TestCXXRecordDecl19
) {
1407 ASSERT_TRUE(PrintedDeclCXX98Matches(
1408 "template<typename T> struct Z {};"
1411 "template <typename T1, int>"
1414 "B", "Y<Z<X>, 2> B",
1415 [](PrintingPolicy
&Policy
) { Policy
.SuppressTagKeyword
= true; }));
1418 TEST(DeclPrinter
, TestCXXRecordDecl20
) {
1419 ASSERT_TRUE(PrintedDeclCXX98Matches(
1420 "template <typename T, int N> class Inner;"
1421 "template <typename T, int N>"
1422 "class Inner{Inner(T val){}};"
1423 "template <class InnerClass, int N> class Outer {"
1425 "struct NestedStruct {"
1427 "NestedStruct(int val) : nestedValue(val) {}"
1429 "InnerClass innerInstance;"
1430 "Outer(const InnerClass &inner) : innerInstance(inner) {}"
1432 "Outer<Inner<int, 10>, 5>::NestedStruct nestedInstance(100);",
1434 "Outer<Inner<int, 10>, 5>::NestedStruct nestedInstance(100)",
1435 [](PrintingPolicy
&Policy
) { Policy
.SuppressTagKeyword
= false; }));
1438 TEST(DeclPrinter
, TestCXXRecordDecl21
) {
1439 ASSERT_TRUE(PrintedDeclCXX98Matches(
1440 "template <typename T, int N> class Inner;"
1441 "template <typename T, int N>"
1442 "class Inner{Inner(T val){}};"
1443 "template <class InnerClass, int N> class Outer {"
1445 "struct NestedStruct {"
1447 "NestedStruct(int val) : nestedValue(val) {}"
1449 "InnerClass innerInstance;"
1450 "Outer(const InnerClass &inner) : innerInstance(inner) {}"
1452 "Outer<Inner<int, 10>, 5>::NestedStruct nestedInstance(100);",
1454 "Outer<Inner<int, 10>, 5>::NestedStruct nestedInstance(100)",
1455 [](PrintingPolicy
&Policy
) { Policy
.SuppressTagKeyword
= true; }));
1458 TEST(DeclPrinter
, TestFunctionParamUglified
) {
1459 llvm::StringLiteral Code
= R
"cpp(
1461 void _A(__c *__param);
1463 auto Clean
= [](PrintingPolicy
&Policy
) {
1464 Policy
.CleanUglifiedParameters
= true;
1467 ASSERT_TRUE(PrintedDeclCXX17Matches(Code
, namedDecl(hasName("_A")).bind("id"),
1468 "void _A(__c *__param)"));
1469 ASSERT_TRUE(PrintedDeclCXX17Matches(Code
, namedDecl(hasName("_A")).bind("id"),
1470 "void _A(__c *param)", Clean
));
1473 TEST(DeclPrinter
, TestTemplateParamUglified
) {
1474 llvm::StringLiteral Code
= R
"cpp(
1475 template <typename _Tp, int __n, template <typename> class _Container>
1478 auto Clean
= [](PrintingPolicy
&Policy
) {
1479 Policy
.CleanUglifiedParameters
= true;
1482 ASSERT_TRUE(PrintedDeclCXX17Matches(
1483 Code
, classTemplateDecl(hasName("_A")).bind("id"),
1484 "template <typename _Tp, int __n, template <typename> class _Container> "
1486 ASSERT_TRUE(PrintedDeclCXX17Matches(
1487 Code
, classTemplateDecl(hasName("_A")).bind("id"),
1488 "template <typename Tp, int n, template <typename> class Container> "
1493 TEST(DeclPrinter
, TestStaticAssert1
) {
1494 ASSERT_TRUE(PrintedDeclCXX17Matches("static_assert(true);",
1495 staticAssertDecl().bind("id"),
1496 "static_assert(true)"));
1499 TEST(DeclPrinter
, TestObjCMethod1
) {
1500 ASSERT_TRUE(PrintedDeclObjCMatches(
1501 "__attribute__((objc_root_class)) @interface X\n"
1502 "- (int)A:(id)anObject inRange:(long)range;\n"
1504 "@implementation X\n"
1505 "- (int)A:(id)anObject inRange:(long)range { int printThis; return 0; }\n"
1507 namedDecl(hasName("A:inRange:"),
1508 hasDescendant(namedDecl(hasName("printThis")))).bind("id"),
1509 "- (int)A:(id)anObject inRange:(long)range"));
1512 TEST(DeclPrinter
, TestObjCProtocol1
) {
1513 ASSERT_TRUE(PrintedDeclObjCMatches(
1514 "@protocol P1, P2;",
1515 namedDecl(hasName("P1")).bind("id"),
1516 "@protocol P1;\n"));
1517 ASSERT_TRUE(PrintedDeclObjCMatches(
1518 "@protocol P1, P2;",
1519 namedDecl(hasName("P2")).bind("id"),
1520 "@protocol P2;\n"));
1523 TEST(DeclPrinter
, TestObjCProtocol2
) {
1524 ASSERT_TRUE(PrintedDeclObjCMatches(
1526 "@protocol P1<P2> @end",
1527 namedDecl(hasName("P1")).bind("id"),
1528 "@protocol P1<P2>\n@end"));
1531 TEST(DeclPrinter
, TestObjCCategoryInvalidInterface
) {
1532 ASSERT_TRUE(PrintedDeclObjCMatches(
1533 "@interface I (Extension) @end",
1534 namedDecl(hasName("Extension")).bind("id"),
1535 "@interface <<error-type>>(Extension)\n@end", /*AllowError=*/true));
1538 TEST(DeclPrinter
, TestObjCCategoryImplInvalidInterface
) {
1539 ASSERT_TRUE(PrintedDeclObjCMatches(
1540 "@implementation I (Extension) @end",
1541 namedDecl(hasName("Extension")).bind("id"),
1542 "@implementation <<error-type>>(Extension)\n@end", /*AllowError=*/true));
1545 TEST(DeclPrinter
, VarDeclWithInitializer
) {
1546 ASSERT_TRUE(PrintedDeclCXX17Matches(
1547 "int a = 0x15;", namedDecl(hasName("a")).bind("id"), "int a = 21"));
1548 ASSERT_TRUE(PrintedDeclCXX17Matches(
1549 "int a = 0x15;", namedDecl(hasName("a")).bind("id"), "int a = 0x15",
1550 [](PrintingPolicy
&Policy
) { Policy
.ConstantsAsWritten
= true; }));
1552 PrintedDeclCXX17Matches("void foo() {int arr[42]; for(int a : arr);}",
1553 namedDecl(hasName("a")).bind("id"), "int a"));
1556 TEST(DeclPrinter
, TestTemplateFinal
) {
1557 // By default we should print 'final' keyword whether class is implicitly or
1558 // explicitly marked final.
1559 ASSERT_TRUE(PrintedDeclCXX11Matches(
1560 "template<typename T>\n"
1561 "class FinalTemplate final {};",
1562 classTemplateDecl(hasName("FinalTemplate")).bind("id"),
1563 "template <typename T> class FinalTemplate final {}"));
1566 TEST(DeclPrinter
, TestTemplateFinalWithPolishForDecl
) {
1567 // clangd relies on the 'final' keyword being printed when
1568 // PolishForDeclaration is enabled, so make sure it is even if implicit attrs
1570 ASSERT_TRUE(PrintedDeclCXX11Matches(
1571 "template<typename T>\n"
1572 "class FinalTemplate final {};",
1573 classTemplateDecl(hasName("FinalTemplate")).bind("id"),
1574 "template <typename T> class FinalTemplate final {}",
1575 [](PrintingPolicy
&Policy
) { Policy
.PolishForDeclaration
= true; }));