blob: 9f179c4a3f2d24891f20e01e9c7de48bc379fdb9 [file] [log] [blame]
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001//===- unittests/AST/DeclPrinterTest.cpp --- Declaration printer tests ----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains tests for Decl::print() and related methods.
11//
12// Search this file for WRONG to see test cases that are producing something
13// completely wrong, invalid C++ or just misleading.
14//
15// These tests have a coding convention:
16// * declaration to be printed is named 'A' unless it should have some special
17// name (e.g., 'operator+');
18// * additional helper declarations are 'Z', 'Y', 'X' and so on.
19//
20//===----------------------------------------------------------------------===//
21
22#include "clang/AST/ASTContext.h"
23#include "clang/ASTMatchers/ASTMatchFinder.h"
24#include "clang/Tooling/Tooling.h"
Daniel Jasper6ed1f852012-08-24 05:50:27 +000025#include "llvm/ADT/SmallString.h"
Dmitri Gribenko309856a2012-08-20 23:39:06 +000026#include "gtest/gtest.h"
27
28using namespace clang;
29using namespace ast_matchers;
30using namespace tooling;
31
32namespace {
33
34void PrintDecl(raw_ostream &Out, const ASTContext *Context, const Decl *D) {
35 PrintingPolicy Policy = Context->getPrintingPolicy();
Dmitri Gribenkoa93a7e82012-08-21 17:36:32 +000036 Policy.TerseOutput = true;
Dmitri Gribenko309856a2012-08-20 23:39:06 +000037 D->print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ false);
38}
39
40class PrintMatch : public MatchFinder::MatchCallback {
41 SmallString<1024> Printed;
42 unsigned NumFoundDecls;
43
44public:
45 PrintMatch() : NumFoundDecls(0) {}
46
47 virtual void run(const MatchFinder::MatchResult &Result) {
48 const Decl *D = Result.Nodes.getDeclAs<Decl>("id");
49 if (!D || D->isImplicit())
50 return;
51 NumFoundDecls++;
52 if (NumFoundDecls > 1)
53 return;
54
55 llvm::raw_svector_ostream Out(Printed);
56 PrintDecl(Out, Result.Context, D);
57 }
58
59 StringRef getPrinted() const {
60 return Printed;
61 }
62
63 unsigned getNumFoundDecls() const {
64 return NumFoundDecls;
65 }
66};
67
Dmitri Gribenko309856a2012-08-20 23:39:06 +000068::testing::AssertionResult PrintedDeclMatches(
69 StringRef Code,
Dmitri Gribenko454a43c2012-08-31 03:23:26 +000070 const std::vector<std::string> &Args,
Dmitri Gribenko309856a2012-08-20 23:39:06 +000071 const DeclarationMatcher &NodeMatch,
Fariborz Jahaniane0586a52012-10-18 19:12:17 +000072 StringRef ExpectedPrinted,
73 StringRef FileName) {
Dmitri Gribenko309856a2012-08-20 23:39:06 +000074 PrintMatch Printer;
75 MatchFinder Finder;
76 Finder.addMatcher(NodeMatch, &Printer);
Ahmed Charlesb8984322014-03-07 20:03:18 +000077 std::unique_ptr<FrontendActionFactory> Factory(
78 newFrontendActionFactory(&Finder));
Dmitri Gribenko309856a2012-08-20 23:39:06 +000079
Fariborz Jahaniane0586a52012-10-18 19:12:17 +000080 if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName))
Saleem Abdulrasool8a8454b2014-01-25 20:04:44 +000081 return testing::AssertionFailure()
82 << "Parsing error in \"" << Code.str() << "\"";
Dmitri Gribenko309856a2012-08-20 23:39:06 +000083
84 if (Printer.getNumFoundDecls() == 0)
85 return testing::AssertionFailure()
86 << "Matcher didn't find any declarations";
87
88 if (Printer.getNumFoundDecls() > 1)
89 return testing::AssertionFailure()
90 << "Matcher should match only one declaration "
91 "(found " << Printer.getNumFoundDecls() << ")";
92
93 if (Printer.getPrinted() != ExpectedPrinted)
94 return ::testing::AssertionFailure()
Saleem Abdulrasool8a8454b2014-01-25 20:04:44 +000095 << "Expected \"" << ExpectedPrinted.str() << "\", "
96 "got \"" << Printer.getPrinted().str() << "\"";
Dmitri Gribenko309856a2012-08-20 23:39:06 +000097
98 return ::testing::AssertionSuccess();
99}
100
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000101::testing::AssertionResult PrintedDeclCXX98Matches(StringRef Code,
102 StringRef DeclName,
103 StringRef ExpectedPrinted) {
Dmitri Gribenko454a43c2012-08-31 03:23:26 +0000104 std::vector<std::string> Args(1, "-std=c++98");
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000105 return PrintedDeclMatches(Code,
Dmitri Gribenko454a43c2012-08-31 03:23:26 +0000106 Args,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000107 namedDecl(hasName(DeclName)).bind("id"),
Fariborz Jahaniane0586a52012-10-18 19:12:17 +0000108 ExpectedPrinted,
109 "input.cc");
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000110}
111
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000112::testing::AssertionResult PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000113 StringRef Code,
114 const DeclarationMatcher &NodeMatch,
115 StringRef ExpectedPrinted) {
Dmitri Gribenko454a43c2012-08-31 03:23:26 +0000116 std::vector<std::string> Args(1, "-std=c++98");
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000117 return PrintedDeclMatches(Code,
Dmitri Gribenko454a43c2012-08-31 03:23:26 +0000118 Args,
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000119 NodeMatch,
Fariborz Jahaniane0586a52012-10-18 19:12:17 +0000120 ExpectedPrinted,
121 "input.cc");
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000122}
123
124::testing::AssertionResult PrintedDeclCXX11Matches(StringRef Code,
125 StringRef DeclName,
126 StringRef ExpectedPrinted) {
Dmitri Gribenko454a43c2012-08-31 03:23:26 +0000127 std::vector<std::string> Args(1, "-std=c++11");
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000128 return PrintedDeclMatches(Code,
Dmitri Gribenko454a43c2012-08-31 03:23:26 +0000129 Args,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000130 namedDecl(hasName(DeclName)).bind("id"),
Fariborz Jahaniane0586a52012-10-18 19:12:17 +0000131 ExpectedPrinted,
132 "input.cc");
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000133}
134
135::testing::AssertionResult PrintedDeclCXX11Matches(
136 StringRef Code,
137 const DeclarationMatcher &NodeMatch,
138 StringRef ExpectedPrinted) {
Dmitri Gribenko454a43c2012-08-31 03:23:26 +0000139 std::vector<std::string> Args(1, "-std=c++11");
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000140 return PrintedDeclMatches(Code,
Dmitri Gribenko454a43c2012-08-31 03:23:26 +0000141 Args,
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000142 NodeMatch,
Fariborz Jahaniane0586a52012-10-18 19:12:17 +0000143 ExpectedPrinted,
144 "input.cc");
145}
146
NAKAMURA Takumi7d2da0b2014-02-16 10:16:09 +0000147::testing::AssertionResult PrintedDeclCXX11nonMSCMatches(
148 StringRef Code,
149 const DeclarationMatcher &NodeMatch,
150 StringRef ExpectedPrinted) {
151 std::vector<std::string> Args(1, "-std=c++11");
152 Args.push_back("-fno-delayed-template-parsing");
153 return PrintedDeclMatches(Code,
154 Args,
155 NodeMatch,
156 ExpectedPrinted,
157 "input.cc");
158}
159
Fariborz Jahaniane0586a52012-10-18 19:12:17 +0000160::testing::AssertionResult PrintedDeclObjCMatches(
161 StringRef Code,
162 const DeclarationMatcher &NodeMatch,
163 StringRef ExpectedPrinted) {
164 std::vector<std::string> Args(1, "");
165 return PrintedDeclMatches(Code,
166 Args,
167 NodeMatch,
168 ExpectedPrinted,
169 "input.m");
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000170}
171
172} // unnamed namespace
173
Dmitri Gribenko5ea34fc2014-03-03 13:21:00 +0000174TEST(DeclPrinter, TestTypedef1) {
175 ASSERT_TRUE(PrintedDeclCXX98Matches(
176 "typedef int A;",
177 "A",
178 "typedef int A"));
179 // Should be: with semicolon
180}
181
182TEST(DeclPrinter, TestTypedef2) {
183 ASSERT_TRUE(PrintedDeclCXX98Matches(
184 "typedef const char *A;",
185 "A",
186 "typedef const char *A"));
187 // Should be: with semicolon
188}
189
190TEST(DeclPrinter, TestTypedef3) {
191 ASSERT_TRUE(PrintedDeclCXX98Matches(
192 "template <typename Y> class X {};"
193 "typedef X<int> A;",
194 "A",
195 "typedef X<int> A"));
196 // Should be: with semicolon
197}
198
199TEST(DeclPrinter, TestTypedef4) {
200 ASSERT_TRUE(PrintedDeclCXX98Matches(
201 "namespace X { class Y {}; }"
202 "typedef X::Y A;",
203 "A",
204 "typedef X::Y A"));
205 // Should be: with semicolon
206}
207
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000208TEST(DeclPrinter, TestNamespace1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000209 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000210 "namespace A { int B; }",
211 "A",
212 "namespace A {\n}"));
213 // Should be: with { ... }
214}
215
216TEST(DeclPrinter, TestNamespace2) {
217 ASSERT_TRUE(PrintedDeclCXX11Matches(
218 "inline namespace A { int B; }",
219 "A",
220 "inline namespace A {\n}"));
221 // Should be: with { ... }
222}
223
224TEST(DeclPrinter, TestNamespaceAlias1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000225 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000226 "namespace Z { }"
227 "namespace A = Z;",
228 "A",
229 "namespace A = Z"));
230 // Should be: with semicolon
231}
232
233TEST(DeclPrinter, TestNamespaceAlias2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000234 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000235 "namespace X { namespace Y {} }"
236 "namespace A = X::Y;",
237 "A",
238 "namespace A = X::Y"));
239 // Should be: with semicolon
240}
241
242TEST(DeclPrinter, TestCXXRecordDecl1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000243 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000244 "class A { int a; };",
245 "A",
246 "class A {\n}"));
247 // Should be: with semicolon, with { ... }
248}
249
250TEST(DeclPrinter, TestCXXRecordDecl2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000251 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000252 "struct A { int a; };",
253 "A",
254 "struct A {\n}"));
255 // Should be: with semicolon, with { ... }
256}
257
258TEST(DeclPrinter, TestCXXRecordDecl3) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000259 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000260 "union A { int a; };",
261 "A",
262 "union A {\n}"));
263 // Should be: with semicolon, with { ... }
264}
265
266TEST(DeclPrinter, TestCXXRecordDecl4) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000267 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000268 "class Z { int a; };"
269 "class A : Z { int b; };",
270 "A",
Richard Smitha5934192014-07-23 03:22:10 +0000271 "class A : Z {\n}"));
272 // Should be: with semicolon, with { ... }
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000273}
274
275TEST(DeclPrinter, TestCXXRecordDecl5) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000276 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000277 "struct Z { int a; };"
278 "struct A : Z { int b; };",
279 "A",
Richard Smitha5934192014-07-23 03:22:10 +0000280 "struct A : Z {\n}"));
281 // Should be: with semicolon, with { ... }
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000282}
283
284TEST(DeclPrinter, TestCXXRecordDecl6) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000285 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000286 "class Z { int a; };"
287 "class A : public Z { int b; };",
288 "A",
289 "class A : public Z {\n}"));
290 // Should be: with semicolon, with { ... }
291}
292
293TEST(DeclPrinter, TestCXXRecordDecl7) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000294 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000295 "class Z { int a; };"
296 "class A : protected Z { int b; };",
297 "A",
298 "class A : protected Z {\n}"));
299 // Should be: with semicolon, with { ... }
300}
301
302TEST(DeclPrinter, TestCXXRecordDecl8) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000303 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000304 "class Z { int a; };"
305 "class A : private Z { int b; };",
306 "A",
307 "class A : private Z {\n}"));
308 // Should be: with semicolon, with { ... }
309}
310
311TEST(DeclPrinter, TestCXXRecordDecl9) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000312 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000313 "class Z { int a; };"
314 "class A : virtual Z { int b; };",
315 "A",
Richard Smitha5934192014-07-23 03:22:10 +0000316 "class A : virtual Z {\n}"));
317 // Should be: with semicolon, with { ... }
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000318}
319
320TEST(DeclPrinter, TestCXXRecordDecl10) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000321 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000322 "class Z { int a; };"
323 "class A : virtual public Z { int b; };",
324 "A",
325 "class A : virtual public Z {\n}"));
326 // Should be: with semicolon, with { ... }
327}
328
329TEST(DeclPrinter, TestCXXRecordDecl11) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000330 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000331 "class Z { int a; };"
332 "class Y : virtual public Z { int b; };"
333 "class A : virtual public Z, private Y { int c; };",
334 "A",
335 "class A : virtual public Z, private Y {\n}"));
336 // Should be: with semicolon, with { ... }
337}
338
339TEST(DeclPrinter, TestFunctionDecl1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000340 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000341 "void A();",
342 "A",
343 "void A()"));
344 // Should be: with semicolon
345}
346
347TEST(DeclPrinter, TestFunctionDecl2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000348 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +0000349 "void A() {}",
350 "A",
351 "void A()"));
352 // Should be: with semicolon
353}
354
355TEST(DeclPrinter, TestFunctionDecl3) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000356 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +0000357 "void Z();"
358 "void A() { Z(); }",
359 "A",
360 "void A()"));
361 // Should be: with semicolon
362}
363
364TEST(DeclPrinter, TestFunctionDecl4) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000365 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000366 "extern void A();",
367 "A",
368 "extern void A()"));
369 // Should be: with semicolon
370}
371
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +0000372TEST(DeclPrinter, TestFunctionDecl5) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000373 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000374 "static void A();",
375 "A",
376 "static void A()"));
377 // Should be: with semicolon
378}
379
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +0000380TEST(DeclPrinter, TestFunctionDecl6) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000381 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000382 "inline void A();",
383 "A",
384 "inline void A()"));
385 // Should be: with semicolon
386}
387
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +0000388TEST(DeclPrinter, TestFunctionDecl7) {
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000389 ASSERT_TRUE(PrintedDeclCXX11Matches(
390 "constexpr int A(int a);",
391 "A",
Benjamin Kramer2907b082014-02-25 18:49:49 +0000392 "constexpr int A(int a)"));
393 // Should be: with semicolon
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000394}
395
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +0000396TEST(DeclPrinter, TestFunctionDecl8) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000397 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000398 "void A(int a);",
399 "A",
400 "void A(int a)"));
401 // Should be: with semicolon
402}
403
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +0000404TEST(DeclPrinter, TestFunctionDecl9) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000405 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000406 "void A(...);",
407 "A",
408 "void A(...)"));
409 // Should be: with semicolon
410}
411
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +0000412TEST(DeclPrinter, TestFunctionDecl10) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000413 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000414 "void A(int a, ...);",
415 "A",
416 "void A(int a, ...)"));
417 // Should be: with semicolon
418}
419
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +0000420TEST(DeclPrinter, TestFunctionDecl11) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000421 ASSERT_TRUE(PrintedDeclCXX98Matches(
David Majnemerd4328de2014-01-14 08:18:49 +0000422 "typedef long ssize_t;"
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000423 "typedef int *pInt;"
David Majnemerd4328de2014-01-14 08:18:49 +0000424 "void A(int a, pInt b, ssize_t c);",
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000425 "A",
David Majnemerd4328de2014-01-14 08:18:49 +0000426 "void A(int a, pInt b, ssize_t c)"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000427 // Should be: with semicolon
428}
429
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +0000430TEST(DeclPrinter, TestFunctionDecl12) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000431 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000432 "void A(int a, int b = 0);",
433 "A",
434 "void A(int a, int b = 0)"));
435 // Should be: with semicolon
436}
437
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +0000438TEST(DeclPrinter, TestFunctionDecl13) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000439 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000440 "void (*A(int a))(int b);",
441 "A",
442 "void (*A(int a))(int)"));
443 // Should be: with semicolon, with parameter name (?)
444}
445
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +0000446TEST(DeclPrinter, TestFunctionDecl14) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000447 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000448 "template<typename T>"
449 "void A(T t) { }"
450 "template<>"
451 "void A(int N) { }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000452 functionDecl(hasName("A"), isExplicitTemplateSpecialization()).bind("id"),
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +0000453 "void A(int N)"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000454 // WRONG; Should be: "template <> void A(int N);"));
455}
456
457
458TEST(DeclPrinter, TestCXXConstructorDecl1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000459 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000460 "struct A {"
461 " A();"
462 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000463 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian14ef4792012-12-05 19:54:11 +0000464 "A()"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000465}
466
467TEST(DeclPrinter, TestCXXConstructorDecl2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000468 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000469 "struct A {"
470 " A(int a);"
471 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000472 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian14ef4792012-12-05 19:54:11 +0000473 "A(int a)"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000474}
475
476TEST(DeclPrinter, TestCXXConstructorDecl3) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000477 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000478 "struct A {"
479 " A(const A &a);"
480 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000481 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian14ef4792012-12-05 19:54:11 +0000482 "A(const A &a)"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000483}
484
485TEST(DeclPrinter, TestCXXConstructorDecl4) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000486 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000487 "struct A {"
488 " A(const A &a, int = 0);"
489 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000490 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian14ef4792012-12-05 19:54:11 +0000491 "A(const A &a, int = 0)"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000492}
493
494TEST(DeclPrinter, TestCXXConstructorDecl5) {
495 ASSERT_TRUE(PrintedDeclCXX11Matches(
496 "struct A {"
497 " A(const A &&a);"
498 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000499 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian14ef4792012-12-05 19:54:11 +0000500 "A(const A &&a)"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000501}
502
503TEST(DeclPrinter, TestCXXConstructorDecl6) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000504 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000505 "struct A {"
506 " explicit A(int a);"
507 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000508 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian69c403c2012-12-05 22:19:06 +0000509 "explicit A(int a)"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000510}
511
512TEST(DeclPrinter, TestCXXConstructorDecl7) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000513 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000514 "struct A {"
515 " constexpr A();"
516 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000517 constructorDecl(ofClass(hasName("A"))).bind("id"),
Benjamin Kramer2907b082014-02-25 18:49:49 +0000518 "constexpr A()"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000519}
520
521TEST(DeclPrinter, TestCXXConstructorDecl8) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000522 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000523 "struct A {"
524 " A() = default;"
525 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000526 constructorDecl(ofClass(hasName("A"))).bind("id"),
Richard Smithbd305122012-12-11 01:14:52 +0000527 "A() = default"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000528}
529
530TEST(DeclPrinter, TestCXXConstructorDecl9) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000531 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000532 "struct A {"
533 " A() = delete;"
534 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000535 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian14ef4792012-12-05 19:54:11 +0000536 "A() = delete"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000537}
538
Dmitri Gribenko340c0f62012-08-24 00:26:25 +0000539TEST(DeclPrinter, TestCXXConstructorDecl10) {
540 ASSERT_TRUE(PrintedDeclCXX11Matches(
541 "template<typename... T>"
542 "struct A {"
543 " A(const A &a);"
544 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000545 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian14ef4792012-12-05 19:54:11 +0000546 "A<T...>(const A<T...> &a)"));
Richard Smitha4bb2922014-07-23 03:17:06 +0000547 // WRONG; Should be: "A(const A<T...> &a);"
Dmitri Gribenko340c0f62012-08-24 00:26:25 +0000548}
549
550TEST(DeclPrinter, TestCXXConstructorDecl11) {
NAKAMURA Takumi7d2da0b2014-02-16 10:16:09 +0000551 ASSERT_TRUE(PrintedDeclCXX11nonMSCMatches(
Dmitri Gribenko340c0f62012-08-24 00:26:25 +0000552 "template<typename... T>"
553 "struct A : public T... {"
554 " A(T&&... ts) : T(ts)... {}"
555 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000556 constructorDecl(ofClass(hasName("A"))).bind("id"),
Richard Smitha4bb2922014-07-23 03:17:06 +0000557 "A<T...>(T &&...ts) : T(ts)..."));
558 // WRONG; Should be: "A(T &&...ts) : T(ts)... {}"
Dmitri Gribenko340c0f62012-08-24 00:26:25 +0000559}
Dmitri Gribenko340c0f62012-08-24 00:26:25 +0000560
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000561TEST(DeclPrinter, TestCXXDestructorDecl1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000562 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000563 "struct A {"
564 " ~A();"
565 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000566 destructorDecl(ofClass(hasName("A"))).bind("id"),
Benjamin Kramer2907b082014-02-25 18:49:49 +0000567 "~A()"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000568}
569
570TEST(DeclPrinter, TestCXXDestructorDecl2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000571 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000572 "struct A {"
573 " virtual ~A();"
574 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000575 destructorDecl(ofClass(hasName("A"))).bind("id"),
Benjamin Kramer2907b082014-02-25 18:49:49 +0000576 "virtual ~A()"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000577}
578
579TEST(DeclPrinter, TestCXXConversionDecl1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000580 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000581 "struct A {"
582 " operator int();"
583 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000584 methodDecl(ofClass(hasName("A"))).bind("id"),
Benjamin Kramer00e8a192014-02-25 18:03:55 +0000585 "operator int()"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000586}
587
588TEST(DeclPrinter, TestCXXConversionDecl2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000589 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000590 "struct A {"
591 " operator bool();"
592 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000593 methodDecl(ofClass(hasName("A"))).bind("id"),
Benjamin Kramer00e8a192014-02-25 18:03:55 +0000594 "operator bool()"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000595}
596
597TEST(DeclPrinter, TestCXXConversionDecl3) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000598 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000599 "struct Z {};"
600 "struct A {"
601 " operator Z();"
602 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000603 methodDecl(ofClass(hasName("A"))).bind("id"),
Benjamin Kramer00e8a192014-02-25 18:03:55 +0000604 "operator Z()"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000605}
606
607TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000608 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000609 "namespace std { typedef decltype(sizeof(int)) size_t; }"
610 "struct Z {"
611 " void *operator new(std::size_t);"
612 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000613 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000614 "void *operator new(std::size_t)"));
615 // Should be: with semicolon
616}
617
618TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000619 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000620 "namespace std { typedef decltype(sizeof(int)) size_t; }"
621 "struct Z {"
622 " void *operator new[](std::size_t);"
623 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000624 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000625 "void *operator new[](std::size_t)"));
626 // Should be: with semicolon
627}
628
629TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction3) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000630 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000631 "struct Z {"
632 " void operator delete(void *);"
633 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000634 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000635 "void operator delete(void *) noexcept"));
636 // Should be: with semicolon, without noexcept?
637}
638
639TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction4) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000640 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000641 "struct Z {"
642 " void operator delete(void *);"
643 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000644 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000645 "void operator delete(void *)"));
646 // Should be: with semicolon
647}
648
649TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction5) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000650 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000651 "struct Z {"
652 " void operator delete[](void *);"
653 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000654 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000655 "void operator delete[](void *) noexcept"));
656 // Should be: with semicolon, without noexcept?
657}
658
659TEST(DeclPrinter, TestCXXMethodDecl_Operator1) {
660 const char *OperatorNames[] = {
661 "+", "-", "*", "/", "%", "^", "&", "|",
662 "=", "<", ">", "+=", "-=", "*=", "/=", "%=",
663 "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==", "!=",
664 "<=", ">=", "&&", "||", ",", "->*",
665 "()", "[]"
666 };
667
668 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
669 SmallString<128> Code;
670 Code.append("struct Z { void operator");
671 Code.append(OperatorNames[i]);
672 Code.append("(Z z); };");
673
674 SmallString<128> Expected;
675 Expected.append("void operator");
676 Expected.append(OperatorNames[i]);
677 Expected.append("(Z z)");
678 // Should be: with semicolon
679
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000680 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000681 Code,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000682 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000683 Expected));
684 }
685}
686
687TEST(DeclPrinter, TestCXXMethodDecl_Operator2) {
688 const char *OperatorNames[] = {
689 "~", "!", "++", "--", "->"
690 };
691
692 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
693 SmallString<128> Code;
694 Code.append("struct Z { void operator");
695 Code.append(OperatorNames[i]);
696 Code.append("(); };");
697
698 SmallString<128> Expected;
699 Expected.append("void operator");
700 Expected.append(OperatorNames[i]);
701 Expected.append("()");
702 // Should be: with semicolon
703
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000704 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000705 Code,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000706 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000707 Expected));
708 }
709}
710
711TEST(DeclPrinter, TestCXXMethodDecl1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000712 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000713 "struct Z {"
714 " void A(int a);"
715 "};",
716 "A",
717 "void A(int a)"));
718 // Should be: with semicolon
719}
720
721TEST(DeclPrinter, TestCXXMethodDecl2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000722 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000723 "struct Z {"
724 " virtual void A(int a);"
725 "};",
726 "A",
727 "virtual void A(int a)"));
728 // Should be: with semicolon
729}
730
731TEST(DeclPrinter, TestCXXMethodDecl3) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000732 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000733 "struct Z {"
734 " virtual void A(int a);"
735 "};"
736 "struct ZZ : Z {"
737 " void A(int a);"
738 "};",
739 "ZZ::A",
740 "void A(int a)"));
741 // Should be: with semicolon
742 // TODO: should we print "virtual"?
743}
744
745TEST(DeclPrinter, TestCXXMethodDecl4) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000746 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000747 "struct Z {"
748 " inline void A(int a);"
749 "};",
750 "A",
751 "inline void A(int a)"));
752 // Should be: with semicolon
753}
754
755TEST(DeclPrinter, TestCXXMethodDecl5) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000756 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000757 "struct Z {"
758 " virtual void A(int a) = 0;"
759 "};",
760 "A",
761 "virtual void A(int a) = 0"));
762 // Should be: with semicolon
763}
764
765TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000766 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000767 "struct Z {"
768 " void A(int a) const;"
769 "};",
770 "A",
771 "void A(int a) const"));
772 // Should be: with semicolon
773}
774
775TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000776 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000777 "struct Z {"
778 " void A(int a) volatile;"
779 "};",
780 "A",
781 "void A(int a) volatile"));
782 // Should be: with semicolon
783}
784
785TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier3) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000786 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000787 "struct Z {"
788 " void A(int a) const volatile;"
789 "};",
790 "A",
791 "void A(int a) const volatile"));
792 // Should be: with semicolon
793}
794
795TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier1) {
796 ASSERT_TRUE(PrintedDeclCXX11Matches(
797 "struct Z {"
798 " void A(int a) &;"
799 "};",
800 "A",
Benjamin Kramer2907b082014-02-25 18:49:49 +0000801 "void A(int a) &"));
802 // Should be: with semicolon
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000803}
804
805TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) {
806 ASSERT_TRUE(PrintedDeclCXX11Matches(
807 "struct Z {"
808 " void A(int a) &&;"
809 "};",
810 "A",
Benjamin Kramer2907b082014-02-25 18:49:49 +0000811 "void A(int a) &&"));
812 // Should be: with semicolon
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000813}
814
815TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000816 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000817 "struct Z {"
818 " void A(int a) throw();"
819 "};",
820 "A",
821 "void A(int a) throw()"));
822 // Should be: with semicolon
823}
824
825TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000826 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000827 "struct Z {"
828 " void A(int a) throw(int);"
829 "};",
830 "A",
831 "void A(int a) throw(int)"));
832 // Should be: with semicolon
833}
834
835TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification3) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000836 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000837 "class ZZ {};"
838 "struct Z {"
839 " void A(int a) throw(ZZ, int);"
840 "};",
841 "A",
842 "void A(int a) throw(ZZ, int)"));
843 // Should be: with semicolon
844}
845
846TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification4) {
847 ASSERT_TRUE(PrintedDeclCXX11Matches(
848 "struct Z {"
849 " void A(int a) noexcept;"
850 "};",
851 "A",
852 "void A(int a) noexcept"));
853 // Should be: with semicolon
854}
855
856TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification5) {
857 ASSERT_TRUE(PrintedDeclCXX11Matches(
858 "struct Z {"
859 " void A(int a) noexcept(true);"
860 "};",
861 "A",
862 "void A(int a) noexcept(trueA(int a) noexcept(true)"));
863 // WRONG; Should be: "void A(int a) noexcept(true);"
864}
865
866TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification6) {
867 ASSERT_TRUE(PrintedDeclCXX11Matches(
868 "struct Z {"
869 " void A(int a) noexcept(1 < 2);"
870 "};",
871 "A",
872 "void A(int a) noexcept(1 < 2A(int a) noexcept(1 < 2)"));
873 // WRONG; Should be: "void A(int a) noexcept(1 < 2);"
874}
875
876TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification7) {
877 ASSERT_TRUE(PrintedDeclCXX11Matches(
878 "template<int N>"
879 "struct Z {"
880 " void A(int a) noexcept(N < 2);"
881 "};",
882 "A",
883 "void A(int a) noexcept(N < 2A(int a) noexcept(N < 2)"));
884 // WRONG; Should be: "void A(int a) noexcept(N < 2);"
885}
886
887TEST(DeclPrinter, TestVarDecl1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000888 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000889 "char *const (*(*A)[5])(int);",
890 "A",
891 "char *const (*(*A)[5])(int)"));
892 // Should be: with semicolon
893}
894
895TEST(DeclPrinter, TestVarDecl2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000896 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000897 "void (*A)() throw(int);",
898 "A",
899 "void (*A)() throw(int)"));
900 // Should be: with semicolon
901}
902
903TEST(DeclPrinter, TestVarDecl3) {
904 ASSERT_TRUE(PrintedDeclCXX11Matches(
905 "void (*A)() noexcept;",
906 "A",
907 "void (*A)() noexcept"));
908 // Should be: with semicolon
909}
910
911TEST(DeclPrinter, TestFieldDecl1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000912 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000913 "template<typename T>"
914 "struct Z { T A; };",
915 "A",
916 "T A"));
917 // Should be: with semicolon
918}
919
920TEST(DeclPrinter, TestFieldDecl2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000921 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000922 "template<int N>"
923 "struct Z { int A[N]; };",
924 "A",
925 "int A[N]"));
926 // Should be: with semicolon
927}
928
929TEST(DeclPrinter, TestClassTemplateDecl1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000930 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000931 "template<typename T>"
932 "struct A { T a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000933 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000934 "template <typename T> struct A {\n}"));
935 // Should be: with semicolon, with { ... }
936}
937
938TEST(DeclPrinter, TestClassTemplateDecl2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000939 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000940 "template<typename T = int>"
941 "struct A { T a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000942 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000943 "template <typename T = int> struct A {\n}"));
944 // Should be: with semicolon, with { ... }
945}
946
947TEST(DeclPrinter, TestClassTemplateDecl3) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000948 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000949 "template<class T>"
950 "struct A { T a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000951 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000952 "template <class T> struct A {\n}"));
953 // Should be: with semicolon, with { ... }
954}
955
956TEST(DeclPrinter, TestClassTemplateDecl4) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000957 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000958 "template<typename T, typename U>"
959 "struct A { T a; U b; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000960 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000961 "template <typename T, typename U> struct A {\n}"));
962 // Should be: with semicolon, with { ... }
963}
964
965TEST(DeclPrinter, TestClassTemplateDecl5) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000966 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000967 "template<int N>"
968 "struct A { int a[N]; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000969 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000970 "template <int N> struct A {\n}"));
971 // Should be: with semicolon, with { ... }
972}
973
974TEST(DeclPrinter, TestClassTemplateDecl6) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000975 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000976 "template<int N = 42>"
977 "struct A { int a[N]; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000978 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000979 "template <int N = 42> struct A {\n}"));
980 // Should be: with semicolon, with { ... }
981}
982
983TEST(DeclPrinter, TestClassTemplateDecl7) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000984 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000985 "typedef int MyInt;"
986 "template<MyInt N>"
987 "struct A { int a[N]; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000988 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000989 "template <MyInt N> struct A {\n}"));
990 // Should be: with semicolon, with { ... }
991}
992
993TEST(DeclPrinter, TestClassTemplateDecl8) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +0000994 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000995 "template<template<typename U> class T> struct A { };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000996 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +0000997 "template <template <typename U> class T> struct A {\n}"));
998 // Should be: with semicolon, with { ... }
999}
1000
1001TEST(DeclPrinter, TestClassTemplateDecl9) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001002 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001003 "template<typename T> struct Z { };"
1004 "template<template<typename U> class T = Z> struct A { };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001005 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001006 "template <template <typename U> class T> struct A {\n}"));
1007 // Should be: with semicolon, with { ... }
1008}
1009
1010TEST(DeclPrinter, TestClassTemplateDecl10) {
1011 ASSERT_TRUE(PrintedDeclCXX11Matches(
1012 "template<typename... T>"
1013 "struct A { int a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001014 classTemplateDecl(hasName("A")).bind("id"),
Richard Smitha4bb2922014-07-23 03:17:06 +00001015 "template <typename ...T> struct A {\n}"));
1016 // Should be: with semicolon, with { ... }
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001017}
1018
1019TEST(DeclPrinter, TestClassTemplateDecl11) {
1020 ASSERT_TRUE(PrintedDeclCXX11Matches(
1021 "template<typename... T>"
1022 "struct A : public T... { int a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001023 classTemplateDecl(hasName("A")).bind("id"),
Richard Smitha4bb2922014-07-23 03:17:06 +00001024 "template <typename ...T> struct A : public T... {\n}"));
1025 // Should be: with semicolon, with { ... }
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001026}
1027
1028TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001029 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001030 "template<typename T, typename U>"
1031 "struct A { T a; U b; };"
1032 "template<typename T>"
1033 "struct A<T, int> { T a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001034 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001035 "struct A {\n}"));
1036 // WRONG; Should be: "template<typename T> struct A<T, int> { ... }"
1037}
1038
1039TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001040 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001041 "template<typename T>"
1042 "struct A { T a; };"
1043 "template<typename T>"
1044 "struct A<T *> { T a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001045 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001046 "struct A {\n}"));
1047 // WRONG; Should be: "template<typename T> struct A<T *> { ... }"
1048}
1049
1050TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001051 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001052 "template<typename T>"
1053 "struct A { T a; };"
1054 "template<>"
1055 "struct A<int> { int a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001056 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001057 "struct A {\n}"));
1058 // WRONG; Should be: "template<> struct A<int> { ... }"
1059}
1060
1061TEST(DeclPrinter, TestFunctionTemplateDecl1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001062 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001063 "template<typename T>"
1064 "void A(T &t);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001065 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001066 "template <typename T> void A(T &t)"));
1067 // Should be: with semicolon
1068}
1069
1070TEST(DeclPrinter, TestFunctionTemplateDecl2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001071 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001072 "template<typename T>"
1073 "void A(T &t) { }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001074 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +00001075 "template <typename T> void A(T &t)"));
1076 // Should be: with semicolon
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001077}
1078
1079TEST(DeclPrinter, TestFunctionTemplateDecl3) {
1080 ASSERT_TRUE(PrintedDeclCXX11Matches(
1081 "template<typename... T>"
1082 "void A(T... a);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001083 functionTemplateDecl(hasName("A")).bind("id"),
Richard Smitha4bb2922014-07-23 03:17:06 +00001084 "template <typename ...T> void A(T ...a)"));
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001085 // Should be: with semicolon.
1086}
1087
1088TEST(DeclPrinter, TestFunctionTemplateDecl4) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001089 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001090 "struct Z { template<typename T> void A(T t); };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001091 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001092 "template <typename T> void A(T t)"));
1093 // Should be: with semicolon
1094}
1095
1096TEST(DeclPrinter, TestFunctionTemplateDecl5) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001097 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001098 "struct Z { template<typename T> void A(T t) {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001099 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +00001100 "template <typename T> void A(T t)"));
1101 // Should be: with semicolon
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001102}
1103
1104TEST(DeclPrinter, TestFunctionTemplateDecl6) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001105 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001106 "template<typename T >struct Z {"
1107 " template<typename U> void A(U t) {}"
1108 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001109 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenkoa9a2af72012-08-21 17:47:24 +00001110 "template <typename U> void A(U t)"));
1111 // Should be: with semicolon
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001112}
1113
1114TEST(DeclPrinter, TestTemplateArgumentList1) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001115 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001116 "template<typename T> struct Z {};"
1117 "struct X {};"
1118 "Z<X> A;",
1119 "A",
1120 "Z<X> A"));
1121 // Should be: with semicolon
1122}
1123
1124TEST(DeclPrinter, TestTemplateArgumentList2) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001125 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001126 "template<typename T, typename U> struct Z {};"
1127 "struct X {};"
1128 "typedef int Y;"
1129 "Z<X, Y> A;",
1130 "A",
1131 "Z<X, Y> A"));
1132 // Should be: with semicolon
1133}
1134
1135TEST(DeclPrinter, TestTemplateArgumentList3) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001136 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001137 "template<typename T> struct Z {};"
1138 "template<typename T> struct X {};"
1139 "Z<X<int> > A;",
1140 "A",
1141 "Z<X<int> > A"));
1142 // Should be: with semicolon
1143}
1144
1145TEST(DeclPrinter, TestTemplateArgumentList4) {
1146 ASSERT_TRUE(PrintedDeclCXX11Matches(
1147 "template<typename T> struct Z {};"
1148 "template<typename T> struct X {};"
1149 "Z<X<int>> A;",
1150 "A",
1151 "Z<X<int> > A"));
1152 // Should be: with semicolon, without extra space in "> >"
1153}
1154
1155TEST(DeclPrinter, TestTemplateArgumentList5) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001156 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001157 "template<typename T> struct Z {};"
1158 "template<typename T> struct X { Z<T> A; };",
1159 "A",
1160 "Z<T> A"));
1161 // Should be: with semicolon
1162}
1163
1164TEST(DeclPrinter, TestTemplateArgumentList6) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001165 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001166 "template<template<typename T> class U> struct Z {};"
1167 "template<typename T> struct X {};"
1168 "Z<X> A;",
1169 "A",
1170 "Z<X> A"));
1171 // Should be: with semicolon
1172}
1173
1174TEST(DeclPrinter, TestTemplateArgumentList7) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001175 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001176 "template<template<typename T> class U> struct Z {};"
1177 "template<template<typename T> class U> struct Y {"
1178 " Z<U> A;"
1179 "};",
1180 "A",
1181 "Z<U> A"));
1182 // Should be: with semicolon
1183}
1184
1185TEST(DeclPrinter, TestTemplateArgumentList8) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001186 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001187 "template<typename T> struct Z {};"
1188 "template<template<typename T> class U> struct Y {"
1189 " Z<U<int> > A;"
1190 "};",
1191 "A",
1192 "Z<U<int> > A"));
1193 // Should be: with semicolon
1194}
1195
1196TEST(DeclPrinter, TestTemplateArgumentList9) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001197 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001198 "template<unsigned I> struct Z {};"
1199 "Z<0> A;",
1200 "A",
1201 "Z<0> A"));
1202 // Should be: with semicolon
1203}
1204
1205TEST(DeclPrinter, TestTemplateArgumentList10) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001206 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001207 "template<unsigned I> struct Z {};"
1208 "template<unsigned I> struct X { Z<I> A; };",
1209 "A",
1210 "Z<I> A"));
1211 // Should be: with semicolon
1212}
1213
1214TEST(DeclPrinter, TestTemplateArgumentList11) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001215 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001216 "template<int I> struct Z {};"
1217 "Z<42 * 10 - 420 / 1> A;",
1218 "A",
1219 "Z<42 * 10 - 420 / 1> A"));
1220 // Should be: with semicolon
1221}
1222
1223TEST(DeclPrinter, TestTemplateArgumentList12) {
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001224 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001225 "template<const char *p> struct Z {};"
1226 "extern const char X[] = \"aaa\";"
1227 "Z<X> A;",
1228 "A",
1229 "Z<X> A"));
1230 // Should be: with semicolon
1231}
1232
1233TEST(DeclPrinter, TestTemplateArgumentList13) {
1234 ASSERT_TRUE(PrintedDeclCXX11Matches(
1235 "template<typename... T> struct Z {};"
1236 "template<typename... T> struct X {"
1237 " Z<T...> A;"
1238 "};",
1239 "A",
1240 "Z<T...> A"));
Richard Smitha4bb2922014-07-23 03:17:06 +00001241 // Should be: with semicolon
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001242}
1243
1244TEST(DeclPrinter, TestTemplateArgumentList14) {
1245 ASSERT_TRUE(PrintedDeclCXX11Matches(
1246 "template<typename... T> struct Z {};"
1247 "template<typename T> struct Y {};"
1248 "template<typename... T> struct X {"
1249 " Z<Y<T>...> A;"
1250 "};",
1251 "A",
1252 "Z<Y<T>...> A"));
Richard Smitha4bb2922014-07-23 03:17:06 +00001253 // Should be: with semicolon
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001254}
1255
1256TEST(DeclPrinter, TestTemplateArgumentList15) {
1257 ASSERT_TRUE(PrintedDeclCXX11Matches(
1258 "template<unsigned I> struct Z {};"
1259 "template<typename... T> struct X {"
1260 " Z<sizeof...(T)> A;"
1261 "};",
1262 "A",
1263 "Z<sizeof...(T)> A"));
Richard Smitha4bb2922014-07-23 03:17:06 +00001264 // Should be: with semicolon
Dmitri Gribenko309856a2012-08-20 23:39:06 +00001265}
Dmitri Gribenkobda79e52012-08-31 03:05:44 +00001266
Fariborz Jahaniane0586a52012-10-18 19:12:17 +00001267TEST(DeclPrinter, TestObjCMethod1) {
1268 ASSERT_TRUE(PrintedDeclObjCMatches(
1269 "__attribute__((objc_root_class)) @interface X\n"
1270 "- (int)A:(id)anObject inRange:(long)range;\n"
1271 "@end\n"
1272 "@implementation X\n"
1273 "- (int)A:(id)anObject inRange:(long)range { int printThis; return 0; }\n"
1274 "@end\n",
1275 namedDecl(hasName("A:inRange:"),
1276 hasDescendant(namedDecl(hasName("printThis")))).bind("id"),
Fariborz Jahanian0389e522012-12-19 23:36:00 +00001277 "- (int) A:(id)anObject inRange:(long)range"));
Fariborz Jahaniane0586a52012-10-18 19:12:17 +00001278}
1279
Fariborz Jahanian44194492012-12-20 02:20:09 +00001280TEST(DeclPrinter, TestObjCProtocol1) {
1281 ASSERT_TRUE(PrintedDeclObjCMatches(
1282 "@protocol P1, P2;",
1283 namedDecl(hasName("P1")).bind("id"),
1284 "@protocol P1;\n"));
1285 ASSERT_TRUE(PrintedDeclObjCMatches(
1286 "@protocol P1, P2;",
1287 namedDecl(hasName("P2")).bind("id"),
1288 "@protocol P2;\n"));
1289}
1290
1291TEST(DeclPrinter, TestObjCProtocol2) {
1292 ASSERT_TRUE(PrintedDeclObjCMatches(
1293 "@protocol P2 @end"
1294 "@protocol P1<P2> @end",
1295 namedDecl(hasName("P1")).bind("id"),
1296 "@protocol P1<P2>\n@end"));
1297}