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