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
PrintedDeclCXX11Matches(
91 const DeclarationMatcher
&NodeMatch
,
92 StringRef ExpectedPrinted
) {
93 std::vector
<std::string
> Args(1, "-std=c++11");
94 return PrintedDeclMatches(Code
,
101 ::testing::AssertionResult
PrintedDeclCXX11nonMSCMatches(
103 const DeclarationMatcher
&NodeMatch
,
104 StringRef ExpectedPrinted
) {
105 std::vector
<std::string
> Args
{"-std=c++11", "-fno-delayed-template-parsing"};
106 return PrintedDeclMatches(Code
,
113 ::testing::AssertionResult
114 PrintedDeclCXX17Matches(StringRef Code
, const DeclarationMatcher
&NodeMatch
,
115 StringRef ExpectedPrinted
,
116 PrintingPolicyAdjuster PolicyModifier
= nullptr) {
117 std::vector
<std::string
> Args
{"-std=c++17", "-fno-delayed-template-parsing"};
118 return PrintedDeclMatches(Code
, Args
, NodeMatch
, ExpectedPrinted
, "input.cc",
122 ::testing::AssertionResult
123 PrintedDeclC11Matches(StringRef Code
, const DeclarationMatcher
&NodeMatch
,
124 StringRef ExpectedPrinted
,
125 PrintingPolicyAdjuster PolicyModifier
= nullptr) {
126 std::vector
<std::string
> Args(1, "-std=c11");
127 return PrintedDeclMatches(Code
, Args
, NodeMatch
, ExpectedPrinted
, "input.c",
131 ::testing::AssertionResult
132 PrintedDeclObjCMatches(StringRef Code
, const DeclarationMatcher
&NodeMatch
,
133 StringRef ExpectedPrinted
, bool AllowError
= false) {
134 std::vector
<std::string
> Args(1, "");
135 return PrintedDeclMatches(Code
, Args
, NodeMatch
, ExpectedPrinted
, "input.m",
136 /*PolicyModifier=*/nullptr, AllowError
);
139 } // unnamed namespace
141 TEST(DeclPrinter
, TestTypedef1
) {
142 ASSERT_TRUE(PrintedDeclCXX98Matches(
146 // Should be: with semicolon
149 TEST(DeclPrinter
, TestTypedef2
) {
150 ASSERT_TRUE(PrintedDeclCXX98Matches(
151 "typedef const char *A;",
153 "typedef const char *A"));
154 // Should be: with semicolon
157 TEST(DeclPrinter
, TestTypedef3
) {
158 ASSERT_TRUE(PrintedDeclCXX98Matches(
159 "template <typename Y> class X {};"
162 "typedef X<int> A"));
163 // Should be: with semicolon
166 TEST(DeclPrinter
, TestTypedef4
) {
167 ASSERT_TRUE(PrintedDeclCXX98Matches(
168 "namespace X { class Y {}; }"
172 // Should be: with semicolon
175 TEST(DeclPrinter
, TestNamespace1
) {
176 ASSERT_TRUE(PrintedDeclCXX98Matches(
177 "namespace A { int B; }",
179 "namespace A {\n}"));
180 // Should be: with { ... }
183 TEST(DeclPrinter
, TestNamespace2
) {
184 ASSERT_TRUE(PrintedDeclCXX11Matches(
185 "inline namespace A { int B; }",
187 "inline namespace A {\n}"));
188 // Should be: with { ... }
191 TEST(DeclPrinter
, TestNamespaceAlias1
) {
192 ASSERT_TRUE(PrintedDeclCXX98Matches(
197 // Should be: with semicolon
200 TEST(DeclPrinter
, TestNamespaceAlias2
) {
201 ASSERT_TRUE(PrintedDeclCXX98Matches(
202 "namespace X { namespace Y {} }"
203 "namespace A = X::Y;",
205 "namespace A = X::Y"));
206 // Should be: with semicolon
209 TEST(DeclPrinter
, TestNamespaceUnnamed
) {
210 ASSERT_TRUE(PrintedDeclCXX17Matches(
211 "namespace { int X; }",
212 namespaceDecl(has(varDecl(hasName("X")))).bind("id"),
213 "namespace {\nint X;\n}",
214 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
217 TEST(DeclPrinter
, TestNamespaceUsingDirective
) {
218 ASSERT_TRUE(PrintedDeclCXX17Matches(
219 "namespace X { namespace A {} }"
220 "using namespace X::A;",
221 usingDirectiveDecl().bind("id"), "using namespace X::A",
222 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
225 TEST(DeclPrinter
, TestEnumDecl1
) {
226 ASSERT_TRUE(PrintedDeclCXX17Matches(
227 "enum A { a0, a1, a2 };", enumDecl(hasName("A")).bind("id"),
228 "enum A {\na0,\na1,\na2\n}",
229 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
232 TEST(DeclPrinter
, TestEnumDecl2
) {
233 ASSERT_TRUE(PrintedDeclCXX17Matches(
234 "enum A { a0 = -1, a1, a2 = 1 };", enumDecl(hasName("A")).bind("id"),
235 "enum A {\na0 = -1,\na1,\na2 = 1\n}",
236 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
239 TEST(DeclPrinter
, TestEnumDecl3
) {
240 ASSERT_TRUE(PrintedDeclCXX17Matches(
241 "enum { a0, a1, a2 };",
242 enumDecl(has(enumConstantDecl(hasName("a0")))).bind("id"),
243 "enum {\na0,\na1,\na2\n}",
244 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
247 TEST(DeclPrinter
, TestEnumDecl4
) {
248 ASSERT_TRUE(PrintedDeclCXX17Matches(
249 "enum class A { a0, a1, a2 };", enumDecl(hasName("A")).bind("id"),
250 "enum class A : int {\na0,\na1,\na2\n}",
251 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
254 TEST(DeclPrinter
, TestRecordDecl1
) {
255 ASSERT_TRUE(PrintedDeclC11Matches(
256 "struct A { int a; };", recordDecl(hasName("A")).bind("id"),
257 "struct A {\nint a;\n}",
258 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
261 TEST(DeclPrinter
, TestRecordDecl2
) {
262 ASSERT_TRUE(PrintedDeclC11Matches(
263 "struct A { struct { int i; }; };", recordDecl(hasName("A")).bind("id"),
264 "struct A {\nstruct {\nint i;\n};\n}",
265 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
268 TEST(DeclPrinter
, TestRecordDecl3
) {
269 ASSERT_TRUE(PrintedDeclC11Matches(
270 "union { int A; } u;",
271 recordDecl(has(fieldDecl(hasName("A")))).bind("id"), "union {\nint A;\n}",
272 [](PrintingPolicy
&Policy
) { Policy
.TerseOutput
= false; }));
275 TEST(DeclPrinter
, TestCXXRecordDecl1
) {
276 ASSERT_TRUE(PrintedDeclCXX98Matches(
277 "class A { int a; };",
282 TEST(DeclPrinter
, TestCXXRecordDecl2
) {
283 ASSERT_TRUE(PrintedDeclCXX98Matches(
284 "struct A { int a; };",
289 TEST(DeclPrinter
, TestCXXRecordDecl3
) {
290 ASSERT_TRUE(PrintedDeclCXX98Matches(
291 "union A { int a; };",
296 TEST(DeclPrinter
, TestCXXRecordDecl4
) {
297 ASSERT_TRUE(PrintedDeclCXX98Matches(
298 "class Z { int a; };"
299 "class A : Z { int b; };",
304 TEST(DeclPrinter
, TestCXXRecordDecl5
) {
305 ASSERT_TRUE(PrintedDeclCXX98Matches(
306 "struct Z { int a; };"
307 "struct A : Z { int b; };",
312 TEST(DeclPrinter
, TestCXXRecordDecl6
) {
313 ASSERT_TRUE(PrintedDeclCXX98Matches(
314 "class Z { int a; };"
315 "class A : public Z { int b; };",
317 "class A : public Z {}"));
320 TEST(DeclPrinter
, TestCXXRecordDecl7
) {
321 ASSERT_TRUE(PrintedDeclCXX98Matches(
322 "class Z { int a; };"
323 "class A : protected Z { int b; };",
325 "class A : protected Z {}"));
328 TEST(DeclPrinter
, TestCXXRecordDecl8
) {
329 ASSERT_TRUE(PrintedDeclCXX98Matches(
330 "class Z { int a; };"
331 "class A : private Z { int b; };",
333 "class A : private Z {}"));
336 TEST(DeclPrinter
, TestCXXRecordDecl9
) {
337 ASSERT_TRUE(PrintedDeclCXX98Matches(
338 "class Z { int a; };"
339 "class A : virtual Z { int b; };",
341 "class A : virtual Z {}"));
344 TEST(DeclPrinter
, TestCXXRecordDecl10
) {
345 ASSERT_TRUE(PrintedDeclCXX98Matches(
346 "class Z { int a; };"
347 "class A : virtual public Z { int b; };",
349 "class A : virtual public Z {}"));
352 TEST(DeclPrinter
, TestCXXRecordDecl11
) {
353 ASSERT_TRUE(PrintedDeclCXX98Matches(
354 "class Z { int a; };"
355 "class Y : virtual public Z { int b; };"
356 "class A : virtual public Z, private Y { int c; };",
358 "class A : virtual public Z, private Y {}"));
361 TEST(DeclPrinter
, TestFunctionDecl1
) {
362 ASSERT_TRUE(PrintedDeclCXX98Matches(
368 TEST(DeclPrinter
, TestFreeFunctionDecl_FullyQualifiedName
) {
369 ASSERT_TRUE(PrintedDeclCXX98Matches(
373 [](PrintingPolicy
&Policy
){ Policy
.FullyQualifiedName
= true; }));
376 TEST(DeclPrinter
, TestFreeFunctionDeclInNamespace_FullyQualifiedName
) {
377 ASSERT_TRUE(PrintedDeclCXX98Matches(
378 "namespace X { void A(); };",
381 [](PrintingPolicy
&Policy
){ Policy
.FullyQualifiedName
= true; }));
384 TEST(DeclPrinter
, TestMemberFunction_FullyQualifiedName
) {
385 ASSERT_TRUE(PrintedDeclCXX98Matches(
386 "struct X { void A(); };",
389 [](PrintingPolicy
&Policy
){ Policy
.FullyQualifiedName
= true; }));
392 TEST(DeclPrinter
, TestMemberFunctionInNamespace_FullyQualifiedName
) {
393 ASSERT_TRUE(PrintedDeclCXX98Matches(
394 "namespace Z { struct X { void A(); }; }",
397 [](PrintingPolicy
&Policy
){ Policy
.FullyQualifiedName
= true; }));
400 TEST(DeclPrinter
, TestMemberFunctionOutside_FullyQualifiedName
) {
401 ASSERT_TRUE(PrintedDeclCXX98Matches(
402 "struct X { void A(); };"
404 functionDecl(hasName("A"), isDefinition()).bind("id"),
406 [](PrintingPolicy
&Policy
){ Policy
.FullyQualifiedName
= true; }));
409 TEST(DeclPrinter
, TestFunctionDecl2
) {
410 ASSERT_TRUE(PrintedDeclCXX98Matches(
416 TEST(DeclPrinter
, TestFunctionDecl3
) {
417 ASSERT_TRUE(PrintedDeclCXX98Matches(
424 TEST(DeclPrinter
, TestFunctionDecl4
) {
425 ASSERT_TRUE(PrintedDeclCXX98Matches(
431 TEST(DeclPrinter
, TestFunctionDecl5
) {
432 ASSERT_TRUE(PrintedDeclCXX98Matches(
438 TEST(DeclPrinter
, TestFunctionDecl6
) {
439 ASSERT_TRUE(PrintedDeclCXX98Matches(
445 TEST(DeclPrinter
, TestFunctionDecl7
) {
446 ASSERT_TRUE(PrintedDeclCXX11Matches(
447 "constexpr int A(int a);",
449 "constexpr int A(int a)"));
452 TEST(DeclPrinter
, TestFunctionDecl8
) {
453 ASSERT_TRUE(PrintedDeclCXX98Matches(
459 TEST(DeclPrinter
, TestFunctionDecl9
) {
460 ASSERT_TRUE(PrintedDeclCXX98Matches(
466 TEST(DeclPrinter
, TestFunctionDecl10
) {
467 ASSERT_TRUE(PrintedDeclCXX98Matches(
468 "void A(int a, ...);",
470 "void A(int a, ...)"));
473 TEST(DeclPrinter
, TestFunctionDecl11
) {
474 ASSERT_TRUE(PrintedDeclCXX98Matches(
475 "typedef long ssize_t;"
477 "void A(int a, pInt b, ssize_t c);",
479 "void A(int a, pInt b, ssize_t c)"));
482 TEST(DeclPrinter
, TestFunctionDecl12
) {
483 ASSERT_TRUE(PrintedDeclCXX98Matches(
484 "void A(int a, int b = 0);",
486 "void A(int a, int b = 0)"));
489 TEST(DeclPrinter
, TestFunctionDecl13
) {
490 ASSERT_TRUE(PrintedDeclCXX98Matches(
491 "void (*A(int a))(int b);",
493 "void (*A(int a))(int)"));
494 // Should be: with parameter name (?)
497 TEST(DeclPrinter
, TestFunctionDecl14
) {
498 ASSERT_TRUE(PrintedDeclCXX98Matches(
499 "template<typename T>"
503 functionDecl(hasName("A"), isExplicitTemplateSpecialization()).bind("id"),
504 "template<> void A<int>(int N)"));
508 TEST(DeclPrinter
, TestCXXConstructorDecl1
) {
509 ASSERT_TRUE(PrintedDeclCXX98Matches(
513 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
517 TEST(DeclPrinter
, TestCXXConstructorDecl2
) {
518 ASSERT_TRUE(PrintedDeclCXX98Matches(
522 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
526 TEST(DeclPrinter
, TestCXXConstructorDecl3
) {
527 ASSERT_TRUE(PrintedDeclCXX98Matches(
531 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
535 TEST(DeclPrinter
, TestCXXConstructorDecl4
) {
536 ASSERT_TRUE(PrintedDeclCXX98Matches(
538 " A(const A &a, int = 0);"
540 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
541 "A(const A &a, int = 0)"));
544 TEST(DeclPrinter
, TestCXXConstructorDeclWithMemberInitializer
) {
545 ASSERT_TRUE(PrintedDeclCXX98Matches(
550 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
554 TEST(DeclPrinter
, TestCXXConstructorDeclWithMemberInitializer_NoTerseOutput
) {
555 ASSERT_TRUE(PrintedDeclCXX98Matches(
560 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
562 [](PrintingPolicy
&Policy
){ Policy
.TerseOutput
= false; }));
565 TEST(DeclPrinter
, TestCXXConstructorDecl5
) {
566 ASSERT_TRUE(PrintedDeclCXX11Matches(
570 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
574 TEST(DeclPrinter
, TestCXXConstructorDecl6
) {
575 ASSERT_TRUE(PrintedDeclCXX98Matches(
577 " explicit A(int a);"
579 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
580 "explicit A(int a)"));
583 TEST(DeclPrinter
, TestCXXConstructorDecl7
) {
584 ASSERT_TRUE(PrintedDeclCXX11Matches(
588 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
592 TEST(DeclPrinter
, TestCXXConstructorDecl8
) {
593 ASSERT_TRUE(PrintedDeclCXX11Matches(
597 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
601 TEST(DeclPrinter
, TestCXXConstructorDecl9
) {
602 ASSERT_TRUE(PrintedDeclCXX11Matches(
606 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
610 TEST(DeclPrinter
, TestCXXConstructorDecl10
) {
611 ASSERT_TRUE(PrintedDeclCXX11Matches(
612 "template<typename... T>"
616 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
617 "A<T...>(const A<T...> &a)"));
620 TEST(DeclPrinter
, TestCXXConstructorDecl11
) {
621 ASSERT_TRUE(PrintedDeclCXX11nonMSCMatches(
622 "template<typename... T>"
623 "struct A : public T... {"
624 " A(T&&... ts) : T(ts)... {}"
626 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),
627 "A<T...>(T &&...ts)"));
630 TEST(DeclPrinter
, TestCXXDestructorDecl1
) {
631 ASSERT_TRUE(PrintedDeclCXX98Matches(
635 cxxDestructorDecl(ofClass(hasName("A"))).bind("id"),
639 TEST(DeclPrinter
, TestCXXDestructorDecl2
) {
640 ASSERT_TRUE(PrintedDeclCXX98Matches(
644 cxxDestructorDecl(ofClass(hasName("A"))).bind("id"),
648 TEST(DeclPrinter
, TestCXXConversionDecl1
) {
649 ASSERT_TRUE(PrintedDeclCXX98Matches(
653 cxxMethodDecl(ofClass(hasName("A"))).bind("id"),
657 TEST(DeclPrinter
, TestCXXConversionDecl2
) {
658 ASSERT_TRUE(PrintedDeclCXX98Matches(
662 cxxMethodDecl(ofClass(hasName("A"))).bind("id"),
666 TEST(DeclPrinter
, TestCXXConversionDecl3
) {
667 ASSERT_TRUE(PrintedDeclCXX98Matches(
672 cxxMethodDecl(ofClass(hasName("A"))).bind("id"),
676 TEST(DeclPrinter
, TestCXXMethodDecl_AllocationFunction1
) {
677 ASSERT_TRUE(PrintedDeclCXX11Matches(
678 "namespace std { typedef decltype(sizeof(int)) size_t; }"
680 " void *operator new(std::size_t);"
682 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),
683 "void *operator new(std::size_t)"));
686 TEST(DeclPrinter
, TestCXXMethodDecl_AllocationFunction2
) {
687 ASSERT_TRUE(PrintedDeclCXX11Matches(
688 "namespace std { typedef decltype(sizeof(int)) size_t; }"
690 " void *operator new[](std::size_t);"
692 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),
693 "void *operator new[](std::size_t)"));
696 TEST(DeclPrinter
, TestCXXMethodDecl_AllocationFunction3
) {
697 ASSERT_TRUE(PrintedDeclCXX11Matches(
699 " void operator delete(void *);"
701 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),
702 "void operator delete(void *) noexcept"));
703 // Should be: without noexcept?
706 TEST(DeclPrinter
, TestCXXMethodDecl_AllocationFunction4
) {
707 ASSERT_TRUE(PrintedDeclCXX98Matches(
709 " void operator delete(void *);"
711 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),
712 "void operator delete(void *)"));
715 TEST(DeclPrinter
, TestCXXMethodDecl_AllocationFunction5
) {
716 ASSERT_TRUE(PrintedDeclCXX11Matches(
718 " void operator delete[](void *);"
720 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),
721 "void operator delete[](void *) noexcept"));
722 // Should be: without noexcept?
725 TEST(DeclPrinter
, TestCXXMethodDecl_Operator1
) {
726 const char *OperatorNames
[] = {
727 "+", "-", "*", "/", "%", "^", "&", "|",
728 "=", "<", ">", "+=", "-=", "*=", "/=", "%=",
729 "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==", "!=",
730 "<=", ">=", "&&", "||", ",", "->*",
734 for (unsigned i
= 0, e
= std::size(OperatorNames
); i
!= e
; ++i
) {
735 SmallString
<128> Code
;
736 Code
.append("struct Z { void operator");
737 Code
.append(OperatorNames
[i
]);
738 Code
.append("(Z z); };");
740 SmallString
<128> Expected
;
741 Expected
.append("void operator");
742 Expected
.append(OperatorNames
[i
]);
743 Expected
.append("(Z z)");
745 ASSERT_TRUE(PrintedDeclCXX98Matches(
747 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),
752 TEST(DeclPrinter
, TestCXXMethodDecl_Operator2
) {
753 const char *OperatorNames
[] = {
754 "~", "!", "++", "--", "->"
757 for (unsigned i
= 0, e
= std::size(OperatorNames
); i
!= e
; ++i
) {
758 SmallString
<128> Code
;
759 Code
.append("struct Z { void operator");
760 Code
.append(OperatorNames
[i
]);
761 Code
.append("(); };");
763 SmallString
<128> Expected
;
764 Expected
.append("void operator");
765 Expected
.append(OperatorNames
[i
]);
766 Expected
.append("()");
768 ASSERT_TRUE(PrintedDeclCXX98Matches(
770 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),
775 TEST(DeclPrinter
, TestCXXMethodDecl1
) {
776 ASSERT_TRUE(PrintedDeclCXX98Matches(
784 TEST(DeclPrinter
, TestCXXMethodDecl2
) {
785 ASSERT_TRUE(PrintedDeclCXX98Matches(
787 " virtual void A(int a);"
790 "virtual void A(int a)"));
793 TEST(DeclPrinter
, TestCXXMethodDecl3
) {
794 ASSERT_TRUE(PrintedDeclCXX98Matches(
796 " virtual void A(int a);"
803 // TODO: should we print "virtual"?
806 TEST(DeclPrinter
, TestCXXMethodDecl4
) {
807 ASSERT_TRUE(PrintedDeclCXX98Matches(
809 " inline void A(int a);"
812 "inline void A(int a)"));
815 TEST(DeclPrinter
, TestCXXMethodDecl5
) {
816 ASSERT_TRUE(PrintedDeclCXX98Matches(
818 " virtual void A(int a) = 0;"
821 "virtual void A(int a) = 0"));
824 TEST(DeclPrinter
, TestCXXMethodDecl_CVQualifier1
) {
825 ASSERT_TRUE(PrintedDeclCXX98Matches(
827 " void A(int a) const;"
830 "void A(int a) const"));
833 TEST(DeclPrinter
, TestCXXMethodDecl_CVQualifier2
) {
834 ASSERT_TRUE(PrintedDeclCXX98Matches(
836 " void A(int a) volatile;"
839 "void A(int a) volatile"));
842 TEST(DeclPrinter
, TestCXXMethodDecl_CVQualifier3
) {
843 ASSERT_TRUE(PrintedDeclCXX98Matches(
845 " void A(int a) const volatile;"
848 "void A(int a) const volatile"));
851 TEST(DeclPrinter
, TestCXXMethodDecl_RefQualifier1
) {
852 ASSERT_TRUE(PrintedDeclCXX11Matches(
860 TEST(DeclPrinter
, TestCXXMethodDecl_RefQualifier2
) {
861 ASSERT_TRUE(PrintedDeclCXX11Matches(
866 "void A(int a) &&"));
869 TEST(DeclPrinter
, TestFunctionDecl_ExceptionSpecification1
) {
870 ASSERT_TRUE(PrintedDeclCXX98Matches(
872 " void A(int a) throw();"
875 "void A(int a) throw()"));
878 TEST(DeclPrinter
, TestFunctionDecl_ExceptionSpecification2
) {
879 ASSERT_TRUE(PrintedDeclCXX98Matches(
881 " void A(int a) throw(int);"
884 "void A(int a) throw(int)"));
887 TEST(DeclPrinter
, TestFunctionDecl_ExceptionSpecification3
) {
888 ASSERT_TRUE(PrintedDeclCXX98Matches(
891 " void A(int a) throw(ZZ, int);"
894 "void A(int a) throw(ZZ, int)"));
897 TEST(DeclPrinter
, TestFunctionDecl_ExceptionSpecification4
) {
898 ASSERT_TRUE(PrintedDeclCXX11Matches(
900 " void A(int a) noexcept;"
903 "void A(int a) noexcept"));
906 TEST(DeclPrinter
, TestFunctionDecl_ExceptionSpecification5
) {
907 ASSERT_TRUE(PrintedDeclCXX11Matches(
909 " void A(int a) noexcept(true);"
912 "void A(int a) noexcept(true)"));
915 TEST(DeclPrinter
, TestFunctionDecl_ExceptionSpecification6
) {
916 ASSERT_TRUE(PrintedDeclCXX11Matches(
918 " void A(int a) noexcept(1 < 2);"
921 "void A(int a) noexcept(1 < 2)"));
924 TEST(DeclPrinter
, TestFunctionDecl_ExceptionSpecification7
) {
925 ASSERT_TRUE(PrintedDeclCXX11Matches(
928 " void A(int a) noexcept(N < 2);"
931 "void A(int a) noexcept(N < 2)"));
934 TEST(DeclPrinter
, TestVarDecl1
) {
935 ASSERT_TRUE(PrintedDeclCXX98Matches(
936 "char *const (*(*A)[5])(int);",
938 "char *const (*(*A)[5])(int)"));
939 // Should be: with semicolon
942 TEST(DeclPrinter
, TestVarDecl2
) {
943 ASSERT_TRUE(PrintedDeclCXX98Matches(
944 "void (*A)() throw(int);",
946 "void (*A)() throw(int)"));
947 // Should be: with semicolon
950 TEST(DeclPrinter
, TestVarDecl3
) {
951 ASSERT_TRUE(PrintedDeclCXX11Matches(
952 "void (*A)() noexcept;",
954 "void (*A)() noexcept"));
955 // Should be: with semicolon
958 TEST(DeclPrinter
, TestFieldDecl1
) {
959 ASSERT_TRUE(PrintedDeclCXX98Matches(
960 "template<typename T>"
961 "struct Z { T A; };",
964 // Should be: with semicolon
967 TEST(DeclPrinter
, TestFieldDecl2
) {
968 ASSERT_TRUE(PrintedDeclCXX98Matches(
970 "struct Z { int A[N]; };",
973 // Should be: with semicolon
976 TEST(DeclPrinter
, TestClassTemplateDecl1
) {
977 ASSERT_TRUE(PrintedDeclCXX98Matches(
978 "template<typename T>"
979 "struct A { T a; };",
980 classTemplateDecl(hasName("A")).bind("id"),
981 "template <typename T> struct A {}"));
984 TEST(DeclPrinter
, TestClassTemplateDecl2
) {
985 ASSERT_TRUE(PrintedDeclCXX98Matches(
986 "template<typename T = int>"
987 "struct A { T a; };",
988 classTemplateDecl(hasName("A")).bind("id"),
989 "template <typename T = int> struct A {}"));
992 TEST(DeclPrinter
, TestClassTemplateDecl3
) {
993 ASSERT_TRUE(PrintedDeclCXX98Matches(
995 "struct A { T a; };",
996 classTemplateDecl(hasName("A")).bind("id"),
997 "template <class T> struct A {}"));
1000 TEST(DeclPrinter
, TestClassTemplateDecl4
) {
1001 ASSERT_TRUE(PrintedDeclCXX98Matches(
1002 "template<typename T, typename U>"
1003 "struct A { T a; U b; };",
1004 classTemplateDecl(hasName("A")).bind("id"),
1005 "template <typename T, typename U> struct A {}"));
1008 TEST(DeclPrinter
, TestClassTemplateDecl5
) {
1009 ASSERT_TRUE(PrintedDeclCXX98Matches(
1011 "struct A { int a[N]; };",
1012 classTemplateDecl(hasName("A")).bind("id"),
1013 "template <int N> struct A {}"));
1016 TEST(DeclPrinter
, TestClassTemplateDecl6
) {
1017 ASSERT_TRUE(PrintedDeclCXX98Matches(
1018 "template<int N = 42>"
1019 "struct A { int a[N]; };",
1020 classTemplateDecl(hasName("A")).bind("id"),
1021 "template <int N = 42> struct A {}"));
1024 TEST(DeclPrinter
, TestClassTemplateDecl7
) {
1025 ASSERT_TRUE(PrintedDeclCXX98Matches(
1026 "typedef int MyInt;"
1028 "struct A { int a[N]; };",
1029 classTemplateDecl(hasName("A")).bind("id"),
1030 "template <MyInt N> struct A {}"));
1033 TEST(DeclPrinter
, TestClassTemplateDecl8
) {
1034 ASSERT_TRUE(PrintedDeclCXX98Matches(
1035 "template<template<typename U> class T> struct A { };",
1036 classTemplateDecl(hasName("A")).bind("id"),
1037 "template <template <typename U> class T> struct A {}"));
1040 TEST(DeclPrinter
, TestClassTemplateDecl9
) {
1041 ASSERT_TRUE(PrintedDeclCXX98Matches(
1042 "template<typename T> struct Z { };"
1043 "template<template<typename U> class T = Z> struct A { };",
1044 classTemplateDecl(hasName("A")).bind("id"),
1045 "template <template <typename U> class T> struct A {}"));
1048 TEST(DeclPrinter
, TestClassTemplateDecl10
) {
1049 ASSERT_TRUE(PrintedDeclCXX11Matches(
1050 "template<typename... T>"
1051 "struct A { int a; };",
1052 classTemplateDecl(hasName("A")).bind("id"),
1053 "template <typename ...T> struct A {}"));
1056 TEST(DeclPrinter
, TestClassTemplateDecl11
) {
1057 ASSERT_TRUE(PrintedDeclCXX11Matches(
1058 "template<typename... T>"
1059 "struct A : public T... { int a; };",
1060 classTemplateDecl(hasName("A")).bind("id"),
1061 "template <typename ...T> struct A : public T... {}"));
1064 TEST(DeclPrinter
, TestClassTemplatePartialSpecializationDecl1
) {
1065 ASSERT_TRUE(PrintedDeclCXX98Matches(
1066 "template<typename T, typename U>"
1067 "struct A { T a; U b; };"
1068 "template<typename T>"
1069 "struct A<T, int> { T a; };",
1070 classTemplateSpecializationDecl().bind("id"),
1071 "template <typename T> struct A<T, int> {}"));
1074 TEST(DeclPrinter
, TestClassTemplatePartialSpecializationDecl2
) {
1075 ASSERT_TRUE(PrintedDeclCXX98Matches(
1076 "template<typename T>"
1077 "struct A { T a; };"
1078 "template<typename T>"
1079 "struct A<T *> { T a; };",
1080 classTemplateSpecializationDecl().bind("id"),
1081 "template <typename T> struct A<T *> {}"));
1084 TEST(DeclPrinter
, TestClassTemplateSpecializationDecl1
) {
1085 ASSERT_TRUE(PrintedDeclCXX98Matches(
1086 "template<typename T>"
1087 "struct A { T a; };"
1089 "struct A<int> { int a; };",
1090 classTemplateSpecializationDecl().bind("id"),
1091 "template<> struct A<int> {}"));
1094 TEST(DeclPrinter
, TestFunctionTemplateDecl1
) {
1095 ASSERT_TRUE(PrintedDeclCXX98Matches(
1096 "template<typename T>"
1098 functionTemplateDecl(hasName("A")).bind("id"),
1099 "template <typename T> void A(T &t)"));
1102 TEST(DeclPrinter
, TestFunctionTemplateDecl2
) {
1103 ASSERT_TRUE(PrintedDeclCXX98Matches(
1104 "template<typename T>"
1106 functionTemplateDecl(hasName("A")).bind("id"),
1107 "template <typename T> void A(T &t)"));
1110 TEST(DeclPrinter
, TestFunctionTemplateDecl3
) {
1111 ASSERT_TRUE(PrintedDeclCXX11Matches(
1112 "template<typename... T>"
1114 functionTemplateDecl(hasName("A")).bind("id"),
1115 "template <typename ...T> void A(T ...a)"));
1118 TEST(DeclPrinter
, TestFunctionTemplateDecl4
) {
1119 ASSERT_TRUE(PrintedDeclCXX98Matches(
1120 "struct Z { template<typename T> void A(T t); };",
1121 functionTemplateDecl(hasName("A")).bind("id"),
1122 "template <typename T> void A(T t)"));
1125 TEST(DeclPrinter
, TestFunctionTemplateDecl5
) {
1126 ASSERT_TRUE(PrintedDeclCXX98Matches(
1127 "struct Z { template<typename T> void A(T t) {} };",
1128 functionTemplateDecl(hasName("A")).bind("id"),
1129 "template <typename T> void A(T t)"));
1132 TEST(DeclPrinter
, TestFunctionTemplateDecl6
) {
1133 ASSERT_TRUE(PrintedDeclCXX98Matches(
1134 "template<typename T >struct Z {"
1135 " template<typename U> void A(U t) {}"
1137 functionTemplateDecl(hasName("A")).bind("id"),
1138 "template <typename U> void A(U t)"));
1141 TEST(DeclPrinter
, TestUnnamedTemplateParameters
) {
1142 ASSERT_TRUE(PrintedDeclCXX17Matches(
1143 "template <typename, int, template <typename, bool> class> void A();",
1144 functionTemplateDecl(hasName("A")).bind("id"),
1145 "template <typename, int, template <typename, bool> class> void A()"));
1148 TEST(DeclPrinter
, TestUnnamedTemplateParametersPacks
) {
1149 ASSERT_TRUE(PrintedDeclCXX17Matches(
1150 "template <typename ..., int ...,"
1151 " template <typename ..., bool ...> class ...> void A();",
1152 functionTemplateDecl(hasName("A")).bind("id"),
1153 "template <typename ..., int ...,"
1154 " template <typename ..., bool ...> class ...> void A()"));
1157 TEST(DeclPrinter
, TestNamedTemplateParametersPacks
) {
1158 ASSERT_TRUE(PrintedDeclCXX17Matches(
1159 "template <typename ...T, int ...I,"
1160 " template <typename ...X, bool ...B> class ...Z> void A();",
1161 functionTemplateDecl(hasName("A")).bind("id"),
1162 "template <typename ...T, int ...I,"
1163 " template <typename ...X, bool ...B> class ...Z> void A()"));
1166 TEST(DeclPrinter
, TestTemplateTemplateParameterWrittenWithTypename
) {
1167 ASSERT_TRUE(PrintedDeclCXX17Matches(
1168 "template <template <typename> typename Z> void A();",
1169 functionTemplateDecl(hasName("A")).bind("id"),
1170 "template <template <typename> class Z> void A()"));
1171 // WRONG: We should use typename if the parameter was written with it.
1174 TEST(DeclPrinter
, TestTemplateArgumentList1
) {
1175 ASSERT_TRUE(PrintedDeclCXX98Matches(
1176 "template<typename T> struct Z {};"
1181 // Should be: with semicolon
1184 TEST(DeclPrinter
, TestTemplateArgumentList2
) {
1185 ASSERT_TRUE(PrintedDeclCXX98Matches(
1186 "template<typename T, typename U> struct Z {};"
1192 // Should be: with semicolon
1195 TEST(DeclPrinter
, TestTemplateArgumentList3
) {
1196 ASSERT_TRUE(PrintedDeclCXX98Matches(
1197 "template<typename T> struct Z {};"
1198 "template<typename T> struct X {};"
1202 // Should be: with semicolon
1205 TEST(DeclPrinter
, TestTemplateArgumentList4
) {
1206 ASSERT_TRUE(PrintedDeclCXX11Matches(
1207 "template<typename T> struct Z {};"
1208 "template<typename T> struct X {};"
1212 // Should be: with semicolon
1215 TEST(DeclPrinter
, TestTemplateArgumentList5
) {
1216 ASSERT_TRUE(PrintedDeclCXX98Matches(
1217 "template<typename T> struct Z {};"
1218 "template<typename T> struct X { Z<T> A; };",
1221 // Should be: with semicolon
1224 TEST(DeclPrinter
, TestTemplateArgumentList6
) {
1225 ASSERT_TRUE(PrintedDeclCXX98Matches(
1226 "template<template<typename T> class U> struct Z {};"
1227 "template<typename T> struct X {};"
1231 // Should be: with semicolon
1234 TEST(DeclPrinter
, TestTemplateArgumentList7
) {
1235 ASSERT_TRUE(PrintedDeclCXX98Matches(
1236 "template<template<typename T> class U> struct Z {};"
1237 "template<template<typename T> class U> struct Y {"
1242 // Should be: with semicolon
1245 TEST(DeclPrinter
, TestTemplateArgumentList8
) {
1246 ASSERT_TRUE(PrintedDeclCXX98Matches(
1247 "template<typename T> struct Z {};"
1248 "template<template<typename T> class U> struct Y {"
1253 // Should be: with semicolon
1256 TEST(DeclPrinter
, TestTemplateArgumentList9
) {
1257 ASSERT_TRUE(PrintedDeclCXX98Matches(
1258 "template<unsigned I> struct Z {};"
1262 // Should be: with semicolon
1265 TEST(DeclPrinter
, TestTemplateArgumentList10
) {
1266 ASSERT_TRUE(PrintedDeclCXX98Matches(
1267 "template<unsigned I> struct Z {};"
1268 "template<unsigned I> struct X { Z<I> A; };",
1271 // Should be: with semicolon
1274 TEST(DeclPrinter
, TestTemplateArgumentList11
) {
1275 ASSERT_TRUE(PrintedDeclCXX98Matches(
1276 "template<int I> struct Z {};"
1277 "Z<42 * 10 - 420 / 1> A;",
1279 "Z<42 * 10 - 420 / 1> A"));
1280 // Should be: with semicolon
1283 TEST(DeclPrinter
, TestTemplateArgumentList12
) {
1284 ASSERT_TRUE(PrintedDeclCXX98Matches(
1285 "template<const char *p> struct Z {};"
1286 "extern const char X[] = \"aaa\";"
1290 // Should be: with semicolon
1293 TEST(DeclPrinter
, TestTemplateArgumentList13
) {
1294 ASSERT_TRUE(PrintedDeclCXX11Matches(
1295 "template<typename... T> struct Z {};"
1296 "template<typename... T> struct X {"
1301 // Should be: with semicolon
1304 TEST(DeclPrinter
, TestTemplateArgumentList14
) {
1305 ASSERT_TRUE(PrintedDeclCXX11Matches(
1306 "template<typename... T> struct Z {};"
1307 "template<typename T> struct Y {};"
1308 "template<typename... T> struct X {"
1313 // Should be: with semicolon
1316 TEST(DeclPrinter
, TestTemplateArgumentList15
) {
1317 ASSERT_TRUE(PrintedDeclCXX11Matches(
1318 "template<unsigned I> struct Z {};"
1319 "template<typename... T> struct X {"
1320 " Z<sizeof...(T)> A;"
1323 "Z<sizeof...(T)> A"));
1324 // Should be: with semicolon
1327 TEST(DeclPrinter
, TestTemplateArgumentList16
) {
1328 llvm::StringLiteral Code
= "template<typename T1, int NT1, typename T2 = "
1329 "bool, int NT2 = 5> struct Z {};";
1330 ASSERT_TRUE(PrintedDeclCXX11Matches(Code
, "T1", "typename T1"));
1331 ASSERT_TRUE(PrintedDeclCXX11Matches(Code
, "T2", "typename T2 = bool"));
1332 ASSERT_TRUE(PrintedDeclCXX11Matches(Code
, "NT1", "int NT1"));
1333 ASSERT_TRUE(PrintedDeclCXX11Matches(Code
, "NT2", "int NT2 = 5"));
1336 TEST(DeclPrinter
, TestFunctionParamUglified
) {
1337 llvm::StringLiteral Code
= R
"cpp(
1339 void _A(__c *__param);
1341 auto Clean
= [](PrintingPolicy
&Policy
) {
1342 Policy
.CleanUglifiedParameters
= true;
1345 ASSERT_TRUE(PrintedDeclCXX17Matches(Code
, namedDecl(hasName("_A")).bind("id"),
1346 "void _A(__c *__param)"));
1347 ASSERT_TRUE(PrintedDeclCXX17Matches(Code
, namedDecl(hasName("_A")).bind("id"),
1348 "void _A(__c *param)", Clean
));
1351 TEST(DeclPrinter
, TestTemplateParamUglified
) {
1352 llvm::StringLiteral Code
= R
"cpp(
1353 template <typename _Tp, int __n, template <typename> class _Container>
1356 auto Clean
= [](PrintingPolicy
&Policy
) {
1357 Policy
.CleanUglifiedParameters
= true;
1360 ASSERT_TRUE(PrintedDeclCXX17Matches(
1361 Code
, classTemplateDecl(hasName("_A")).bind("id"),
1362 "template <typename _Tp, int __n, template <typename> class _Container> "
1364 ASSERT_TRUE(PrintedDeclCXX17Matches(
1365 Code
, classTemplateDecl(hasName("_A")).bind("id"),
1366 "template <typename Tp, int n, template <typename> class Container> "
1371 TEST(DeclPrinter
, TestStaticAssert1
) {
1372 ASSERT_TRUE(PrintedDeclCXX17Matches("static_assert(true);",
1373 staticAssertDecl().bind("id"),
1374 "static_assert(true)"));
1377 TEST(DeclPrinter
, TestObjCMethod1
) {
1378 ASSERT_TRUE(PrintedDeclObjCMatches(
1379 "__attribute__((objc_root_class)) @interface X\n"
1380 "- (int)A:(id)anObject inRange:(long)range;\n"
1382 "@implementation X\n"
1383 "- (int)A:(id)anObject inRange:(long)range { int printThis; return 0; }\n"
1385 namedDecl(hasName("A:inRange:"),
1386 hasDescendant(namedDecl(hasName("printThis")))).bind("id"),
1387 "- (int)A:(id)anObject inRange:(long)range"));
1390 TEST(DeclPrinter
, TestObjCProtocol1
) {
1391 ASSERT_TRUE(PrintedDeclObjCMatches(
1392 "@protocol P1, P2;",
1393 namedDecl(hasName("P1")).bind("id"),
1394 "@protocol P1;\n"));
1395 ASSERT_TRUE(PrintedDeclObjCMatches(
1396 "@protocol P1, P2;",
1397 namedDecl(hasName("P2")).bind("id"),
1398 "@protocol P2;\n"));
1401 TEST(DeclPrinter
, TestObjCProtocol2
) {
1402 ASSERT_TRUE(PrintedDeclObjCMatches(
1404 "@protocol P1<P2> @end",
1405 namedDecl(hasName("P1")).bind("id"),
1406 "@protocol P1<P2>\n@end"));
1409 TEST(DeclPrinter
, TestObjCCategoryInvalidInterface
) {
1410 ASSERT_TRUE(PrintedDeclObjCMatches(
1411 "@interface I (Extension) @end",
1412 namedDecl(hasName("Extension")).bind("id"),
1413 "@interface <<error-type>>(Extension)\n@end", /*AllowError=*/true));
1416 TEST(DeclPrinter
, TestObjCCategoryImplInvalidInterface
) {
1417 ASSERT_TRUE(PrintedDeclObjCMatches(
1418 "@implementation I (Extension) @end",
1419 namedDecl(hasName("Extension")).bind("id"),
1420 "@implementation <<error-type>>(Extension)\n@end", /*AllowError=*/true));
1423 TEST(DeclPrinter
, VarDeclWithInitializer
) {
1424 ASSERT_TRUE(PrintedDeclCXX17Matches(
1425 "int a = 0x15;", namedDecl(hasName("a")).bind("id"), "int a = 21"));
1426 ASSERT_TRUE(PrintedDeclCXX17Matches(
1427 "int a = 0x15;", namedDecl(hasName("a")).bind("id"), "int a = 0x15",
1428 [](PrintingPolicy
&Policy
) { Policy
.ConstantsAsWritten
= true; }));
1430 PrintedDeclCXX17Matches("void foo() {int arr[42]; for(int a : arr);}",
1431 namedDecl(hasName("a")).bind("id"), "int a"));