1 | //===- BuildTreeTest.cpp --------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file tests the syntax tree generation from the ClangAST. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "TreeTestBase.h" |
14 | |
15 | using namespace clang; |
16 | using namespace clang::syntax; |
17 | |
18 | namespace { |
19 | |
20 | class BuildSyntaxTreeTest : public SyntaxTreeTest { |
21 | protected: |
22 | ::testing::AssertionResult treeDumpEqual(StringRef Code, StringRef Tree) { |
23 | SCOPED_TRACE(llvm::join(GetParam().getCommandLineArgs(), " " )); |
24 | |
25 | auto *Root = buildTree(Code, GetParam()); |
26 | auto ErrorOK = errorOK(RawCode: Code); |
27 | if (!ErrorOK) |
28 | return ErrorOK; |
29 | auto Actual = StringRef(Root->dump(*TM)).trim().str(); |
30 | // EXPECT_EQ shows the diff between the two strings if they are different. |
31 | EXPECT_EQ(Tree.trim().str(), Actual); |
32 | if (Actual != Tree.trim().str()) { |
33 | return ::testing::AssertionFailure(); |
34 | } |
35 | return ::testing::AssertionSuccess(); |
36 | } |
37 | |
38 | ::testing::AssertionResult |
39 | treeDumpEqualOnAnnotations(StringRef CodeWithAnnotations, |
40 | ArrayRef<StringRef> TreeDumps) { |
41 | SCOPED_TRACE(llvm::join(GetParam().getCommandLineArgs(), " " )); |
42 | |
43 | auto AnnotatedCode = llvm::Annotations(CodeWithAnnotations); |
44 | auto *Root = buildTree(AnnotatedCode.code(), GetParam()); |
45 | |
46 | auto ErrorOK = errorOK(RawCode: AnnotatedCode.code()); |
47 | if (!ErrorOK) |
48 | return ErrorOK; |
49 | |
50 | auto AnnotatedRanges = AnnotatedCode.ranges(); |
51 | if (AnnotatedRanges.size() != TreeDumps.size()) { |
52 | return ::testing::AssertionFailure() |
53 | << "The number of annotated ranges in the source code is " |
54 | "different " |
55 | "to the number of their corresponding tree dumps." ; |
56 | } |
57 | bool Failed = false; |
58 | for (unsigned i = 0; i < AnnotatedRanges.size(); i++) { |
59 | auto *AnnotatedNode = nodeByRange(R: AnnotatedRanges[i], Root: Root); |
60 | assert(AnnotatedNode); |
61 | auto AnnotatedNodeDump = |
62 | StringRef(AnnotatedNode->dump(*TM)) |
63 | .trim() |
64 | .str(); |
65 | // EXPECT_EQ shows the diff between the two strings if they are different. |
66 | EXPECT_EQ(TreeDumps[i].trim().str(), AnnotatedNodeDump) |
67 | << "Dumps diverged for the code:\n" |
68 | << AnnotatedCode.code().slice(Start: AnnotatedRanges[i].Begin, |
69 | End: AnnotatedRanges[i].End); |
70 | if (AnnotatedNodeDump != TreeDumps[i].trim().str()) |
71 | Failed = true; |
72 | } |
73 | return Failed ? ::testing::AssertionFailure() |
74 | : ::testing::AssertionSuccess(); |
75 | } |
76 | |
77 | private: |
78 | ::testing::AssertionResult errorOK(StringRef RawCode) { |
79 | if (!RawCode.contains(Other: "error-ok" )) { |
80 | if (Diags->getClient()->getNumErrors() != 0) { |
81 | return ::testing::AssertionFailure() |
82 | << "Source file has syntax errors (suppress with /*error-ok*/), " |
83 | "they were printed to the " |
84 | "test log" ; |
85 | } |
86 | } |
87 | return ::testing::AssertionSuccess(); |
88 | } |
89 | }; |
90 | |
91 | INSTANTIATE_TEST_SUITE_P(SyntaxTreeTests, BuildSyntaxTreeTest, |
92 | testing::ValuesIn(allTestClangConfigs()) ); |
93 | |
94 | TEST_P(BuildSyntaxTreeTest, Simple) { |
95 | EXPECT_TRUE(treeDumpEqual( |
96 | R"cpp( |
97 | int main() {} |
98 | void foo() {} |
99 | )cpp" , |
100 | R"txt( |
101 | TranslationUnit Detached |
102 | |-SimpleDeclaration |
103 | | |-'int' |
104 | | |-DeclaratorList Declarators |
105 | | | `-SimpleDeclarator ListElement |
106 | | | |-'main' |
107 | | | `-ParametersAndQualifiers |
108 | | | |-'(' OpenParen |
109 | | | `-')' CloseParen |
110 | | `-CompoundStatement |
111 | | |-'{' OpenParen |
112 | | `-'}' CloseParen |
113 | `-SimpleDeclaration |
114 | |-'void' |
115 | |-DeclaratorList Declarators |
116 | | `-SimpleDeclarator ListElement |
117 | | |-'foo' |
118 | | `-ParametersAndQualifiers |
119 | | |-'(' OpenParen |
120 | | `-')' CloseParen |
121 | `-CompoundStatement |
122 | |-'{' OpenParen |
123 | `-'}' CloseParen |
124 | )txt" )); |
125 | } |
126 | |
127 | TEST_P(BuildSyntaxTreeTest, SimpleVariable) { |
128 | EXPECT_TRUE(treeDumpEqual( |
129 | R"cpp( |
130 | int a; |
131 | int b = 42; |
132 | )cpp" , |
133 | R"txt( |
134 | TranslationUnit Detached |
135 | |-SimpleDeclaration |
136 | | |-'int' |
137 | | |-DeclaratorList Declarators |
138 | | | `-SimpleDeclarator ListElement |
139 | | | `-'a' |
140 | | `-';' |
141 | `-SimpleDeclaration |
142 | |-'int' |
143 | |-DeclaratorList Declarators |
144 | | `-SimpleDeclarator ListElement |
145 | | |-'b' |
146 | | |-'=' |
147 | | `-IntegerLiteralExpression |
148 | | `-'42' LiteralToken |
149 | `-';' |
150 | )txt" )); |
151 | } |
152 | |
153 | TEST_P(BuildSyntaxTreeTest, SimpleFunction) { |
154 | EXPECT_TRUE(treeDumpEqual( |
155 | R"cpp( |
156 | void foo(int a, int b) {} |
157 | )cpp" , |
158 | R"txt( |
159 | TranslationUnit Detached |
160 | `-SimpleDeclaration |
161 | |-'void' |
162 | |-DeclaratorList Declarators |
163 | | `-SimpleDeclarator ListElement |
164 | | |-'foo' |
165 | | `-ParametersAndQualifiers |
166 | | |-'(' OpenParen |
167 | | |-ParameterDeclarationList Parameters |
168 | | | |-SimpleDeclaration ListElement |
169 | | | | |-'int' |
170 | | | | `-DeclaratorList Declarators |
171 | | | | `-SimpleDeclarator ListElement |
172 | | | | `-'a' |
173 | | | |-',' ListDelimiter |
174 | | | `-SimpleDeclaration ListElement |
175 | | | |-'int' |
176 | | | `-DeclaratorList Declarators |
177 | | | `-SimpleDeclarator ListElement |
178 | | | `-'b' |
179 | | `-')' CloseParen |
180 | `-CompoundStatement |
181 | |-'{' OpenParen |
182 | `-'}' CloseParen |
183 | )txt" )); |
184 | } |
185 | |
186 | TEST_P(BuildSyntaxTreeTest, Simple_BackslashInsideToken) { |
187 | EXPECT_TRUE(treeDumpEqual( |
188 | R"cpp( |
189 | in\ |
190 | t a; |
191 | )cpp" , |
192 | R"txt( |
193 | TranslationUnit Detached |
194 | `-SimpleDeclaration |
195 | |-'in\ |
196 | t' |
197 | |-DeclaratorList Declarators |
198 | | `-SimpleDeclarator ListElement |
199 | | `-'a' |
200 | `-';' |
201 | )txt" )); |
202 | } |
203 | |
204 | TEST_P(BuildSyntaxTreeTest, If) { |
205 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
206 | R"cpp( |
207 | void test() { |
208 | [[if (1) {}]] |
209 | [[if (1) {} else if (0) {}]] |
210 | } |
211 | )cpp" , |
212 | {R"txt( |
213 | IfStatement Statement |
214 | |-'if' IntroducerKeyword |
215 | |-'(' |
216 | |-ExpressionStatement Condition |
217 | | `-IntegerLiteralExpression Expression |
218 | | `-'1' LiteralToken |
219 | |-')' |
220 | `-CompoundStatement ThenStatement |
221 | |-'{' OpenParen |
222 | `-'}' CloseParen |
223 | )txt" , |
224 | R"txt( |
225 | IfStatement Statement |
226 | |-'if' IntroducerKeyword |
227 | |-'(' |
228 | |-ExpressionStatement Condition |
229 | | `-IntegerLiteralExpression Expression |
230 | | `-'1' LiteralToken |
231 | |-')' |
232 | |-CompoundStatement ThenStatement |
233 | | |-'{' OpenParen |
234 | | `-'}' CloseParen |
235 | |-'else' ElseKeyword |
236 | `-IfStatement ElseStatement |
237 | |-'if' IntroducerKeyword |
238 | |-'(' |
239 | |-ExpressionStatement Condition |
240 | | `-IntegerLiteralExpression Expression |
241 | | `-'0' LiteralToken |
242 | |-')' |
243 | `-CompoundStatement ThenStatement |
244 | |-'{' OpenParen |
245 | `-'}' CloseParen |
246 | )txt" })); |
247 | } |
248 | |
249 | TEST_P(BuildSyntaxTreeTest, IfDecl) { |
250 | if (!GetParam().isCXX17OrLater()) { |
251 | return; |
252 | } |
253 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
254 | R"cpp( |
255 | void test() { |
256 | [[if (int a = 5) {}]] |
257 | [[if (int a; a == 5) {}]] |
258 | } |
259 | )cpp" , |
260 | {R"txt( |
261 | IfStatement Statement |
262 | |-'if' IntroducerKeyword |
263 | |-'(' |
264 | |-DeclarationStatement Condition |
265 | | `-SimpleDeclaration |
266 | | |-'int' |
267 | | `-DeclaratorList Declarators |
268 | | `-SimpleDeclarator ListElement |
269 | | |-'a' |
270 | | |-'=' |
271 | | `-IntegerLiteralExpression |
272 | | `-'5' LiteralToken |
273 | |-')' |
274 | `-CompoundStatement ThenStatement |
275 | |-'{' OpenParen |
276 | `-'}' CloseParen |
277 | )txt" , |
278 | R"txt( |
279 | IfStatement Statement |
280 | |-'if' IntroducerKeyword |
281 | |-'(' |
282 | |-DeclarationStatement |
283 | | |-SimpleDeclaration |
284 | | | |-'int' |
285 | | | `-DeclaratorList Declarators |
286 | | | `-SimpleDeclarator ListElement |
287 | | | `-'a' |
288 | | `-';' |
289 | |-ExpressionStatement Condition |
290 | | `-BinaryOperatorExpression Expression |
291 | | |-IdExpression LeftHandSide |
292 | | | `-UnqualifiedId UnqualifiedId |
293 | | | `-'a' |
294 | | |-'==' OperatorToken |
295 | | `-IntegerLiteralExpression RightHandSide |
296 | | `-'5' LiteralToken |
297 | |-')' |
298 | `-CompoundStatement ThenStatement |
299 | |-'{' OpenParen |
300 | `-'}' CloseParen |
301 | )txt" })); |
302 | } |
303 | |
304 | TEST_P(BuildSyntaxTreeTest, For) { |
305 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
306 | R"cpp( |
307 | void test() { |
308 | [[for (;;) {}]] |
309 | } |
310 | )cpp" , |
311 | {R"txt( |
312 | ForStatement Statement |
313 | |-'for' IntroducerKeyword |
314 | |-'(' |
315 | |-';' |
316 | |-';' |
317 | |-')' |
318 | `-CompoundStatement BodyStatement |
319 | |-'{' OpenParen |
320 | `-'}' CloseParen |
321 | )txt" })); |
322 | } |
323 | |
324 | TEST_P(BuildSyntaxTreeTest, RangeBasedFor) { |
325 | if (!GetParam().isCXX11OrLater()) { |
326 | return; |
327 | } |
328 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
329 | R"cpp( |
330 | void test() { |
331 | int a[3]; |
332 | [[for (int x : a) |
333 | ;]] |
334 | } |
335 | )cpp" , |
336 | {R"txt( |
337 | RangeBasedForStatement Statement |
338 | |-'for' IntroducerKeyword |
339 | |-'(' |
340 | |-SimpleDeclaration |
341 | | |-'int' |
342 | | |-DeclaratorList Declarators |
343 | | | `-SimpleDeclarator ListElement |
344 | | | `-'x' |
345 | | `-':' |
346 | |-IdExpression |
347 | | `-UnqualifiedId UnqualifiedId |
348 | | `-'a' |
349 | |-')' |
350 | `-EmptyStatement BodyStatement |
351 | `-';' |
352 | )txt" })); |
353 | } |
354 | |
355 | TEST_P(BuildSyntaxTreeTest, DeclarationStatement) { |
356 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
357 | R"cpp( |
358 | void test() { |
359 | [[int a = 10;]] |
360 | } |
361 | )cpp" , |
362 | {R"txt( |
363 | DeclarationStatement Statement |
364 | |-SimpleDeclaration |
365 | | |-'int' |
366 | | `-DeclaratorList Declarators |
367 | | `-SimpleDeclarator ListElement |
368 | | |-'a' |
369 | | |-'=' |
370 | | `-IntegerLiteralExpression |
371 | | `-'10' LiteralToken |
372 | `-';' |
373 | )txt" })); |
374 | } |
375 | |
376 | TEST_P(BuildSyntaxTreeTest, Switch) { |
377 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
378 | R"cpp( |
379 | void test() { |
380 | [[switch (1) { |
381 | case 0: |
382 | default:; |
383 | }]] |
384 | } |
385 | )cpp" , |
386 | {R"txt( |
387 | SwitchStatement Statement |
388 | |-'switch' IntroducerKeyword |
389 | |-'(' |
390 | |-IntegerLiteralExpression |
391 | | `-'1' LiteralToken |
392 | |-')' |
393 | `-CompoundStatement BodyStatement |
394 | |-'{' OpenParen |
395 | |-CaseStatement Statement |
396 | | |-'case' IntroducerKeyword |
397 | | |-IntegerLiteralExpression CaseValue |
398 | | | `-'0' LiteralToken |
399 | | |-':' |
400 | | `-DefaultStatement BodyStatement |
401 | | |-'default' IntroducerKeyword |
402 | | |-':' |
403 | | `-EmptyStatement BodyStatement |
404 | | `-';' |
405 | `-'}' CloseParen |
406 | )txt" })); |
407 | } |
408 | |
409 | TEST_P(BuildSyntaxTreeTest, While) { |
410 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
411 | R"cpp( |
412 | void test() { |
413 | [[while (1) { continue; break; }]] |
414 | } |
415 | )cpp" , |
416 | {R"txt( |
417 | WhileStatement Statement |
418 | |-'while' IntroducerKeyword |
419 | |-'(' |
420 | |-IntegerLiteralExpression |
421 | | `-'1' LiteralToken |
422 | |-')' |
423 | `-CompoundStatement BodyStatement |
424 | |-'{' OpenParen |
425 | |-ContinueStatement Statement |
426 | | |-'continue' IntroducerKeyword |
427 | | `-';' |
428 | |-BreakStatement Statement |
429 | | |-'break' IntroducerKeyword |
430 | | `-';' |
431 | `-'}' CloseParen |
432 | )txt" })); |
433 | } |
434 | |
435 | TEST_P(BuildSyntaxTreeTest, UnhandledStatement) { |
436 | // Unhandled statements should end up as 'unknown statement'. |
437 | // This example uses a 'label statement', which does not yet have a syntax |
438 | // counterpart. |
439 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
440 | R"cpp( |
441 | int test() { |
442 | [[foo: return 100;]] |
443 | } |
444 | )cpp" , |
445 | {R"txt( |
446 | UnknownStatement Statement |
447 | |-'foo' |
448 | |-':' |
449 | `-ReturnStatement |
450 | |-'return' IntroducerKeyword |
451 | |-IntegerLiteralExpression ReturnValue |
452 | | `-'100' LiteralToken |
453 | `-';' |
454 | )txt" })); |
455 | } |
456 | |
457 | TEST_P(BuildSyntaxTreeTest, Expressions) { |
458 | // expressions should be wrapped in 'ExpressionStatement' when they appear |
459 | // in a statement position. |
460 | EXPECT_TRUE(treeDumpEqual( |
461 | R"cpp( |
462 | void test() { |
463 | test(); |
464 | if (1) test(); else test(); |
465 | } |
466 | )cpp" , |
467 | R"txt( |
468 | TranslationUnit Detached |
469 | `-SimpleDeclaration |
470 | |-'void' |
471 | |-DeclaratorList Declarators |
472 | | `-SimpleDeclarator ListElement |
473 | | |-'test' |
474 | | `-ParametersAndQualifiers |
475 | | |-'(' OpenParen |
476 | | `-')' CloseParen |
477 | `-CompoundStatement |
478 | |-'{' OpenParen |
479 | |-ExpressionStatement Statement |
480 | | |-CallExpression Expression |
481 | | | |-IdExpression Callee |
482 | | | | `-UnqualifiedId UnqualifiedId |
483 | | | | `-'test' |
484 | | | |-'(' OpenParen |
485 | | | `-')' CloseParen |
486 | | `-';' |
487 | |-IfStatement Statement |
488 | | |-'if' IntroducerKeyword |
489 | | |-'(' |
490 | | |-ExpressionStatement Condition |
491 | | | `-IntegerLiteralExpression Expression |
492 | | | `-'1' LiteralToken |
493 | | |-')' |
494 | | |-ExpressionStatement ThenStatement |
495 | | | |-CallExpression Expression |
496 | | | | |-IdExpression Callee |
497 | | | | | `-UnqualifiedId UnqualifiedId |
498 | | | | | `-'test' |
499 | | | | |-'(' OpenParen |
500 | | | | `-')' CloseParen |
501 | | | `-';' |
502 | | |-'else' ElseKeyword |
503 | | `-ExpressionStatement ElseStatement |
504 | | |-CallExpression Expression |
505 | | | |-IdExpression Callee |
506 | | | | `-UnqualifiedId UnqualifiedId |
507 | | | | `-'test' |
508 | | | |-'(' OpenParen |
509 | | | `-')' CloseParen |
510 | | `-';' |
511 | `-'}' CloseParen |
512 | )txt" )); |
513 | } |
514 | |
515 | TEST_P(BuildSyntaxTreeTest, ConditionalOperator) { |
516 | // FIXME: conditional expression is not modeled yet. |
517 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
518 | R"cpp( |
519 | void test() { |
520 | [[1?:2]]; |
521 | } |
522 | )cpp" , |
523 | {R"txt( |
524 | UnknownExpression Expression |
525 | |-IntegerLiteralExpression |
526 | | `-'1' LiteralToken |
527 | |-'?' |
528 | |-':' |
529 | `-IntegerLiteralExpression |
530 | `-'2' LiteralToken |
531 | )txt" })); |
532 | } |
533 | |
534 | TEST_P(BuildSyntaxTreeTest, UnqualifiedId_Identifier) { |
535 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
536 | R"cpp( |
537 | void test(int a) { |
538 | [[a]]; |
539 | } |
540 | )cpp" , |
541 | {R"txt( |
542 | IdExpression Expression |
543 | `-UnqualifiedId UnqualifiedId |
544 | `-'a' |
545 | )txt" })); |
546 | } |
547 | |
548 | TEST_P(BuildSyntaxTreeTest, UnqualifiedId_OperatorFunctionId) { |
549 | if (!GetParam().isCXX()) { |
550 | return; |
551 | } |
552 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
553 | R"cpp( |
554 | struct X { |
555 | friend X operator+(const X&, const X&); |
556 | }; |
557 | void test(X x) { |
558 | [[operator+(x, x)]]; |
559 | } |
560 | )cpp" , |
561 | {R"txt( |
562 | CallExpression Expression |
563 | |-IdExpression Callee |
564 | | `-UnqualifiedId UnqualifiedId |
565 | | |-'operator' |
566 | | `-'+' |
567 | |-'(' OpenParen |
568 | |-CallArguments Arguments |
569 | | |-IdExpression ListElement |
570 | | | `-UnqualifiedId UnqualifiedId |
571 | | | `-'x' |
572 | | |-',' ListDelimiter |
573 | | `-IdExpression ListElement |
574 | | `-UnqualifiedId UnqualifiedId |
575 | | `-'x' |
576 | `-')' CloseParen |
577 | )txt" })); |
578 | } |
579 | |
580 | TEST_P(BuildSyntaxTreeTest, UnqualifiedId_ConversionFunctionId) { |
581 | if (!GetParam().isCXX()) { |
582 | return; |
583 | } |
584 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
585 | R"cpp( |
586 | struct X { |
587 | operator int(); |
588 | }; |
589 | void test(X x) { |
590 | [[x.operator int()]]; |
591 | } |
592 | )cpp" , |
593 | {R"txt( |
594 | CallExpression Expression |
595 | |-MemberExpression Callee |
596 | | |-IdExpression Object |
597 | | | `-UnqualifiedId UnqualifiedId |
598 | | | `-'x' |
599 | | |-'.' AccessToken |
600 | | `-IdExpression Member |
601 | | `-UnqualifiedId UnqualifiedId |
602 | | |-'operator' |
603 | | `-'int' |
604 | |-'(' OpenParen |
605 | `-')' CloseParen |
606 | )txt" })); |
607 | } |
608 | |
609 | TEST_P(BuildSyntaxTreeTest, UnqualifiedId_LiteralOperatorId) { |
610 | if (!GetParam().isCXX11OrLater()) { |
611 | return; |
612 | } |
613 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
614 | R"cpp( |
615 | unsigned operator "" _w(char); |
616 | void test() { |
617 | [[operator "" _w('1')]]; |
618 | } |
619 | )cpp" , |
620 | {R"txt( |
621 | CallExpression Expression |
622 | |-IdExpression Callee |
623 | | `-UnqualifiedId UnqualifiedId |
624 | | |-'operator' |
625 | | |-'""' |
626 | | `-'_w' |
627 | |-'(' OpenParen |
628 | |-CallArguments Arguments |
629 | | `-CharacterLiteralExpression ListElement |
630 | | `-''1'' LiteralToken |
631 | `-')' CloseParen |
632 | )txt" })); |
633 | } |
634 | |
635 | TEST_P(BuildSyntaxTreeTest, UnqualifiedId_Destructor) { |
636 | if (!GetParam().isCXX()) { |
637 | return; |
638 | } |
639 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
640 | R"cpp( |
641 | struct X { }; |
642 | void test(X x) { |
643 | [[x.~X()]]; |
644 | } |
645 | )cpp" , |
646 | {R"txt( |
647 | CallExpression Expression |
648 | |-MemberExpression Callee |
649 | | |-IdExpression Object |
650 | | | `-UnqualifiedId UnqualifiedId |
651 | | | `-'x' |
652 | | |-'.' AccessToken |
653 | | `-IdExpression Member |
654 | | `-UnqualifiedId UnqualifiedId |
655 | | |-'~' |
656 | | `-'X' |
657 | |-'(' OpenParen |
658 | `-')' CloseParen |
659 | )txt" })); |
660 | } |
661 | |
662 | TEST_P(BuildSyntaxTreeTest, UnqualifiedId_DecltypeDestructor) { |
663 | if (!GetParam().isCXX11OrLater()) { |
664 | return; |
665 | } |
666 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
667 | R"cpp( |
668 | struct X { }; |
669 | void test(X x) { |
670 | // FIXME: Make `decltype(x)` a child of `MemberExpression`. It is currently |
671 | // not because `Expr::getSourceRange()` returns the range of `x.~` for the |
672 | // `MemberExpr` instead of the expected `x.~decltype(x)`, this is a bug in |
673 | // clang. |
674 | [[x.~decltype(x)()]]; |
675 | } |
676 | )cpp" , |
677 | {R"txt( |
678 | CallExpression Expression |
679 | |-MemberExpression Callee |
680 | | |-IdExpression Object |
681 | | | `-UnqualifiedId UnqualifiedId |
682 | | | `-'x' |
683 | | |-'.' AccessToken |
684 | | `-IdExpression Member |
685 | | `-UnqualifiedId UnqualifiedId |
686 | | `-'~' |
687 | |-'decltype' |
688 | |-'(' |
689 | |-'x' |
690 | |-')' |
691 | |-'(' |
692 | `-')' CloseParen |
693 | )txt" })); |
694 | } |
695 | |
696 | TEST_P(BuildSyntaxTreeTest, UnqualifiedId_TemplateId) { |
697 | if (!GetParam().isCXX()) { |
698 | return; |
699 | } |
700 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
701 | R"cpp( |
702 | template<typename T> |
703 | T f(); |
704 | void test() { |
705 | [[f<int>()]]; |
706 | } |
707 | )cpp" , |
708 | {R"txt( |
709 | CallExpression Expression |
710 | |-IdExpression Callee |
711 | | `-UnqualifiedId UnqualifiedId |
712 | | |-'f' |
713 | | |-'<' |
714 | | |-'int' |
715 | | `-'>' |
716 | |-'(' OpenParen |
717 | `-')' CloseParen |
718 | )txt" })); |
719 | } |
720 | |
721 | TEST_P(BuildSyntaxTreeTest, QualifiedId_NamespaceSpecifier) { |
722 | if (!GetParam().isCXX()) { |
723 | return; |
724 | } |
725 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
726 | R"cpp( |
727 | namespace n { |
728 | struct S { }; |
729 | } |
730 | void test() { |
731 | [[::n::S s1]]; |
732 | [[n::S s2]]; |
733 | } |
734 | )cpp" , |
735 | {R"txt( |
736 | SimpleDeclaration |
737 | |-NestedNameSpecifier |
738 | | |-'::' ListDelimiter |
739 | | |-IdentifierNameSpecifier ListElement |
740 | | | `-'n' |
741 | | `-'::' ListDelimiter |
742 | |-'S' |
743 | `-DeclaratorList Declarators |
744 | `-SimpleDeclarator ListElement |
745 | `-'s1' |
746 | )txt" , |
747 | R"txt( |
748 | SimpleDeclaration |
749 | |-NestedNameSpecifier |
750 | | |-IdentifierNameSpecifier ListElement |
751 | | | `-'n' |
752 | | `-'::' ListDelimiter |
753 | |-'S' |
754 | `-DeclaratorList Declarators |
755 | `-SimpleDeclarator ListElement |
756 | `-'s2' |
757 | )txt" })); |
758 | } |
759 | |
760 | TEST_P(BuildSyntaxTreeTest, QualifiedId_TemplateSpecifier) { |
761 | if (!GetParam().isCXX()) { |
762 | return; |
763 | } |
764 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
765 | R"cpp( |
766 | template<typename T> |
767 | struct ST { |
768 | struct S { }; |
769 | }; |
770 | void test() { |
771 | [[::template ST<int>::S s1]]; |
772 | [[::ST<int>::S s2]]; |
773 | } |
774 | )cpp" , |
775 | {R"txt( |
776 | SimpleDeclaration |
777 | |-NestedNameSpecifier |
778 | | |-'::' ListDelimiter |
779 | | |-SimpleTemplateNameSpecifier ListElement |
780 | | | |-'template' |
781 | | | |-'ST' |
782 | | | |-'<' |
783 | | | |-'int' |
784 | | | `-'>' |
785 | | `-'::' ListDelimiter |
786 | |-'S' |
787 | `-DeclaratorList Declarators |
788 | `-SimpleDeclarator ListElement |
789 | `-'s1' |
790 | )txt" , |
791 | R"txt( |
792 | SimpleDeclaration |
793 | |-NestedNameSpecifier |
794 | | |-'::' ListDelimiter |
795 | | |-SimpleTemplateNameSpecifier ListElement |
796 | | | |-'ST' |
797 | | | |-'<' |
798 | | | |-'int' |
799 | | | `-'>' |
800 | | `-'::' ListDelimiter |
801 | |-'S' |
802 | `-DeclaratorList Declarators |
803 | `-SimpleDeclarator ListElement |
804 | `-'s2' |
805 | )txt" })); |
806 | } |
807 | |
808 | TEST_P(BuildSyntaxTreeTest, QualifiedId_DecltypeSpecifier) { |
809 | if (!GetParam().isCXX11OrLater()) { |
810 | return; |
811 | } |
812 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
813 | R"cpp( |
814 | struct S { |
815 | static void f(){} |
816 | }; |
817 | void test(S s) { |
818 | [[decltype(s)::f()]]; |
819 | } |
820 | )cpp" , |
821 | {R"txt( |
822 | CallExpression Expression |
823 | |-IdExpression Callee |
824 | | |-NestedNameSpecifier Qualifier |
825 | | | |-DecltypeNameSpecifier ListElement |
826 | | | | |-'decltype' |
827 | | | | |-'(' |
828 | | | | |-IdExpression |
829 | | | | | `-UnqualifiedId UnqualifiedId |
830 | | | | | `-'s' |
831 | | | | `-')' |
832 | | | `-'::' ListDelimiter |
833 | | `-UnqualifiedId UnqualifiedId |
834 | | `-'f' |
835 | |-'(' OpenParen |
836 | `-')' CloseParen |
837 | )txt" })); |
838 | } |
839 | |
840 | TEST_P(BuildSyntaxTreeTest, QualifiedId_OptionalTemplateKw) { |
841 | if (!GetParam().isCXX()) { |
842 | return; |
843 | } |
844 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
845 | R"cpp( |
846 | struct S { |
847 | template<typename U> |
848 | static U f(); |
849 | }; |
850 | void test() { |
851 | [[S::f<int>()]]; |
852 | [[S::template f<int>()]]; |
853 | } |
854 | )cpp" , |
855 | {R"txt( |
856 | CallExpression Expression |
857 | |-IdExpression Callee |
858 | | |-NestedNameSpecifier Qualifier |
859 | | | |-IdentifierNameSpecifier ListElement |
860 | | | | `-'S' |
861 | | | `-'::' ListDelimiter |
862 | | `-UnqualifiedId UnqualifiedId |
863 | | |-'f' |
864 | | |-'<' |
865 | | |-'int' |
866 | | `-'>' |
867 | |-'(' OpenParen |
868 | `-')' CloseParen |
869 | )txt" , |
870 | R"txt( |
871 | CallExpression Expression |
872 | |-IdExpression Callee |
873 | | |-NestedNameSpecifier Qualifier |
874 | | | |-IdentifierNameSpecifier ListElement |
875 | | | | `-'S' |
876 | | | `-'::' ListDelimiter |
877 | | |-'template' TemplateKeyword |
878 | | `-UnqualifiedId UnqualifiedId |
879 | | |-'f' |
880 | | |-'<' |
881 | | |-'int' |
882 | | `-'>' |
883 | |-'(' OpenParen |
884 | `-')' CloseParen |
885 | )txt" })); |
886 | } |
887 | |
888 | TEST_P(BuildSyntaxTreeTest, QualifiedId_Complex) { |
889 | if (!GetParam().isCXX()) { |
890 | return; |
891 | } |
892 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
893 | R"cpp( |
894 | namespace n { |
895 | template<typename T> |
896 | struct ST { |
897 | template<typename U> |
898 | static U f(); |
899 | }; |
900 | } |
901 | void test() { |
902 | [[::n::template ST<int>::template f<int>()]]; |
903 | } |
904 | )cpp" , |
905 | {R"txt( |
906 | CallExpression Expression |
907 | |-IdExpression Callee |
908 | | |-NestedNameSpecifier Qualifier |
909 | | | |-'::' ListDelimiter |
910 | | | |-IdentifierNameSpecifier ListElement |
911 | | | | `-'n' |
912 | | | |-'::' ListDelimiter |
913 | | | |-SimpleTemplateNameSpecifier ListElement |
914 | | | | |-'template' |
915 | | | | |-'ST' |
916 | | | | |-'<' |
917 | | | | |-'int' |
918 | | | | `-'>' |
919 | | | `-'::' ListDelimiter |
920 | | |-'template' TemplateKeyword |
921 | | `-UnqualifiedId UnqualifiedId |
922 | | |-'f' |
923 | | |-'<' |
924 | | |-'int' |
925 | | `-'>' |
926 | |-'(' OpenParen |
927 | `-')' CloseParen |
928 | )txt" })); |
929 | } |
930 | |
931 | TEST_P(BuildSyntaxTreeTest, QualifiedId_DependentType) { |
932 | if (!GetParam().isCXX()) { |
933 | return; |
934 | } |
935 | if (GetParam().hasDelayedTemplateParsing()) { |
936 | // FIXME: Make this test work on Windows by generating the expected syntax |
937 | // tree when `-fdelayed-template-parsing` is active. |
938 | return; |
939 | } |
940 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
941 | R"cpp( |
942 | template <typename T> |
943 | void test() { |
944 | [[T::template U<int>::f()]]; |
945 | [[T::U::f()]]; |
946 | [[T::template f<0>()]]; |
947 | } |
948 | )cpp" , |
949 | {R"txt( |
950 | CallExpression Expression |
951 | |-IdExpression Callee |
952 | | |-NestedNameSpecifier Qualifier |
953 | | | |-IdentifierNameSpecifier ListElement |
954 | | | | `-'T' |
955 | | | |-'::' ListDelimiter |
956 | | | |-SimpleTemplateNameSpecifier ListElement |
957 | | | | |-'template' |
958 | | | | |-'U' |
959 | | | | |-'<' |
960 | | | | |-'int' |
961 | | | | `-'>' |
962 | | | `-'::' ListDelimiter |
963 | | `-UnqualifiedId UnqualifiedId |
964 | | `-'f' |
965 | |-'(' OpenParen |
966 | `-')' CloseParen |
967 | )txt" , |
968 | R"txt( |
969 | CallExpression Expression |
970 | |-IdExpression Callee |
971 | | |-NestedNameSpecifier Qualifier |
972 | | | |-IdentifierNameSpecifier ListElement |
973 | | | | `-'T' |
974 | | | |-'::' ListDelimiter |
975 | | | |-IdentifierNameSpecifier ListElement |
976 | | | | `-'U' |
977 | | | `-'::' ListDelimiter |
978 | | `-UnqualifiedId UnqualifiedId |
979 | | `-'f' |
980 | |-'(' OpenParen |
981 | `-')' CloseParen |
982 | )txt" , |
983 | R"txt( |
984 | CallExpression Expression |
985 | |-IdExpression Callee |
986 | | |-NestedNameSpecifier Qualifier |
987 | | | |-IdentifierNameSpecifier ListElement |
988 | | | | `-'T' |
989 | | | `-'::' ListDelimiter |
990 | | |-'template' TemplateKeyword |
991 | | `-UnqualifiedId UnqualifiedId |
992 | | |-'f' |
993 | | |-'<' |
994 | | |-IntegerLiteralExpression |
995 | | | `-'0' LiteralToken |
996 | | `-'>' |
997 | |-'(' OpenParen |
998 | `-')' CloseParen |
999 | )txt" })); |
1000 | } |
1001 | |
1002 | TEST_P(BuildSyntaxTreeTest, This_Simple) { |
1003 | if (!GetParam().isCXX()) { |
1004 | return; |
1005 | } |
1006 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1007 | R"cpp( |
1008 | struct S { |
1009 | S* test(){ |
1010 | return [[this]]; |
1011 | } |
1012 | }; |
1013 | )cpp" , |
1014 | {R"txt( |
1015 | ThisExpression ReturnValue |
1016 | `-'this' IntroducerKeyword |
1017 | )txt" })); |
1018 | } |
1019 | |
1020 | TEST_P(BuildSyntaxTreeTest, This_ExplicitMemberAccess) { |
1021 | if (!GetParam().isCXX()) { |
1022 | return; |
1023 | } |
1024 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1025 | R"cpp( |
1026 | struct S { |
1027 | int a; |
1028 | void test(){ |
1029 | [[this->a]]; |
1030 | } |
1031 | }; |
1032 | )cpp" , |
1033 | {R"txt( |
1034 | MemberExpression Expression |
1035 | |-ThisExpression Object |
1036 | | `-'this' IntroducerKeyword |
1037 | |-'->' AccessToken |
1038 | `-IdExpression Member |
1039 | `-UnqualifiedId UnqualifiedId |
1040 | `-'a' |
1041 | )txt" })); |
1042 | } |
1043 | |
1044 | TEST_P(BuildSyntaxTreeTest, This_ImplicitMemberAccess) { |
1045 | if (!GetParam().isCXX()) { |
1046 | return; |
1047 | } |
1048 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1049 | R"cpp( |
1050 | struct S { |
1051 | int a; |
1052 | void test(){ |
1053 | [[a]]; |
1054 | } |
1055 | }; |
1056 | )cpp" , |
1057 | {R"txt( |
1058 | IdExpression Expression |
1059 | `-UnqualifiedId UnqualifiedId |
1060 | `-'a' |
1061 | )txt" })); |
1062 | } |
1063 | |
1064 | TEST_P(BuildSyntaxTreeTest, ParenExpr) { |
1065 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1066 | R"cpp( |
1067 | void test() { |
1068 | [[(1)]]; |
1069 | [[((1))]]; |
1070 | [[(1 + (2))]]; |
1071 | } |
1072 | )cpp" , |
1073 | {R"txt( |
1074 | ParenExpression Expression |
1075 | |-'(' OpenParen |
1076 | |-IntegerLiteralExpression SubExpression |
1077 | | `-'1' LiteralToken |
1078 | `-')' CloseParen |
1079 | )txt" , |
1080 | R"txt( |
1081 | ParenExpression Expression |
1082 | |-'(' OpenParen |
1083 | |-ParenExpression SubExpression |
1084 | | |-'(' OpenParen |
1085 | | |-IntegerLiteralExpression SubExpression |
1086 | | | `-'1' LiteralToken |
1087 | | `-')' CloseParen |
1088 | `-')' CloseParen |
1089 | )txt" , |
1090 | R"txt( |
1091 | ParenExpression Expression |
1092 | |-'(' OpenParen |
1093 | |-BinaryOperatorExpression SubExpression |
1094 | | |-IntegerLiteralExpression LeftHandSide |
1095 | | | `-'1' LiteralToken |
1096 | | |-'+' OperatorToken |
1097 | | `-ParenExpression RightHandSide |
1098 | | |-'(' OpenParen |
1099 | | |-IntegerLiteralExpression SubExpression |
1100 | | | `-'2' LiteralToken |
1101 | | `-')' CloseParen |
1102 | `-')' CloseParen |
1103 | )txt" })); |
1104 | } |
1105 | |
1106 | TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Char) { |
1107 | if (!GetParam().isCXX11OrLater()) { |
1108 | return; |
1109 | } |
1110 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1111 | R"cpp( |
1112 | unsigned operator "" _c(char); |
1113 | void test() { |
1114 | [['2'_c]]; |
1115 | } |
1116 | )cpp" , |
1117 | {R"txt( |
1118 | CharUserDefinedLiteralExpression Expression |
1119 | `-''2'_c' LiteralToken |
1120 | )txt" })); |
1121 | } |
1122 | |
1123 | TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_String) { |
1124 | if (!GetParam().isCXX11OrLater()) { |
1125 | return; |
1126 | } |
1127 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1128 | R"cpp( |
1129 | typedef decltype(sizeof(void *)) size_t; |
1130 | |
1131 | unsigned operator "" _s(const char*, size_t); |
1132 | |
1133 | void test() { |
1134 | [["12"_s]]; |
1135 | } |
1136 | )cpp" , |
1137 | {R"txt( |
1138 | StringUserDefinedLiteralExpression Expression |
1139 | `-'"12"_s' LiteralToken |
1140 | )txt" })); |
1141 | } |
1142 | |
1143 | TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Integer) { |
1144 | if (!GetParam().isCXX11OrLater()) { |
1145 | return; |
1146 | } |
1147 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1148 | R"cpp( |
1149 | unsigned operator "" _i(unsigned long long); |
1150 | unsigned operator "" _r(const char*); |
1151 | template <char...> |
1152 | unsigned operator "" _t(); |
1153 | |
1154 | void test() { |
1155 | [[12_i]]; |
1156 | [[12_r]]; |
1157 | [[12_t]]; |
1158 | } |
1159 | )cpp" , |
1160 | {R"txt( |
1161 | IntegerUserDefinedLiteralExpression Expression |
1162 | `-'12_i' LiteralToken |
1163 | )txt" , |
1164 | R"txt( |
1165 | IntegerUserDefinedLiteralExpression Expression |
1166 | `-'12_r' LiteralToken |
1167 | )txt" , |
1168 | R"txt( |
1169 | IntegerUserDefinedLiteralExpression Expression |
1170 | `-'12_t' LiteralToken |
1171 | )txt" })); |
1172 | } |
1173 | |
1174 | TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Float) { |
1175 | if (!GetParam().isCXX11OrLater()) { |
1176 | return; |
1177 | } |
1178 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1179 | R"cpp( |
1180 | unsigned operator "" _f(long double); |
1181 | unsigned operator "" _r(const char*); |
1182 | template <char...> |
1183 | unsigned operator "" _t(); |
1184 | |
1185 | void test() { |
1186 | [[1.2_f]]; |
1187 | [[1.2_r]]; |
1188 | [[1.2_t]]; |
1189 | } |
1190 | )cpp" , |
1191 | {R"txt( |
1192 | FloatUserDefinedLiteralExpression Expression |
1193 | `-'1.2_f' LiteralToken |
1194 | )txt" , |
1195 | R"txt( |
1196 | FloatUserDefinedLiteralExpression Expression |
1197 | `-'1.2_r' LiteralToken |
1198 | )txt" , |
1199 | R"txt( |
1200 | FloatUserDefinedLiteralExpression Expression |
1201 | `-'1.2_t' LiteralToken |
1202 | )txt" })); |
1203 | } |
1204 | |
1205 | TEST_P(BuildSyntaxTreeTest, IntegerLiteral_LongLong) { |
1206 | if (!GetParam().isCXX11OrLater()) { |
1207 | return; |
1208 | } |
1209 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1210 | R"cpp( |
1211 | void test() { |
1212 | [[12ll]]; |
1213 | [[12ull]]; |
1214 | } |
1215 | )cpp" , |
1216 | {R"txt( |
1217 | IntegerLiteralExpression Expression |
1218 | `-'12ll' LiteralToken |
1219 | )txt" , |
1220 | R"txt( |
1221 | IntegerLiteralExpression Expression |
1222 | `-'12ull' LiteralToken |
1223 | )txt" })); |
1224 | } |
1225 | |
1226 | TEST_P(BuildSyntaxTreeTest, IntegerLiteral_Binary) { |
1227 | if (!GetParam().isCXX14OrLater()) { |
1228 | return; |
1229 | } |
1230 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1231 | R"cpp( |
1232 | void test() { |
1233 | [[0b1100]]; |
1234 | } |
1235 | )cpp" , |
1236 | {R"txt( |
1237 | IntegerLiteralExpression Expression |
1238 | `-'0b1100' LiteralToken |
1239 | )txt" })); |
1240 | } |
1241 | |
1242 | TEST_P(BuildSyntaxTreeTest, IntegerLiteral_WithDigitSeparators) { |
1243 | if (!GetParam().isCXX14OrLater()) { |
1244 | return; |
1245 | } |
1246 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1247 | R"cpp( |
1248 | void test() { |
1249 | [[1'2'0ull]]; |
1250 | } |
1251 | )cpp" , |
1252 | {R"txt( |
1253 | IntegerLiteralExpression Expression |
1254 | `-'1'2'0ull' LiteralToken |
1255 | )txt" })); |
1256 | } |
1257 | |
1258 | TEST_P(BuildSyntaxTreeTest, CharacterLiteral) { |
1259 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1260 | R"cpp( |
1261 | void test() { |
1262 | [['a']]; |
1263 | [['\n']]; |
1264 | [['\x20']]; |
1265 | [['\0']]; |
1266 | [[L'a']]; |
1267 | [[L'α']]; |
1268 | } |
1269 | )cpp" , |
1270 | {R"txt( |
1271 | CharacterLiteralExpression Expression |
1272 | `-''a'' LiteralToken |
1273 | )txt" , |
1274 | R"txt( |
1275 | CharacterLiteralExpression Expression |
1276 | `-''\n'' LiteralToken |
1277 | )txt" , |
1278 | R"txt( |
1279 | CharacterLiteralExpression Expression |
1280 | `-''\x20'' LiteralToken |
1281 | )txt" , |
1282 | R"txt( |
1283 | CharacterLiteralExpression Expression |
1284 | `-''\0'' LiteralToken |
1285 | )txt" , |
1286 | R"txt( |
1287 | CharacterLiteralExpression Expression |
1288 | `-'L'a'' LiteralToken |
1289 | )txt" , |
1290 | R"txt( |
1291 | CharacterLiteralExpression Expression |
1292 | `-'L'α'' LiteralToken |
1293 | )txt" })); |
1294 | } |
1295 | |
1296 | TEST_P(BuildSyntaxTreeTest, CharacterLiteral_Utf) { |
1297 | if (!GetParam().isCXX11OrLater()) { |
1298 | return; |
1299 | } |
1300 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1301 | R"cpp( |
1302 | void test() { |
1303 | [[u'a']]; |
1304 | [[u'構']]; |
1305 | [[U'a']]; |
1306 | [[U'🌲']]; |
1307 | } |
1308 | )cpp" , |
1309 | {R"txt( |
1310 | CharacterLiteralExpression Expression |
1311 | `-'u'a'' LiteralToken |
1312 | )txt" , |
1313 | R"txt( |
1314 | CharacterLiteralExpression Expression |
1315 | `-'u'構'' LiteralToken |
1316 | )txt" , |
1317 | R"txt( |
1318 | CharacterLiteralExpression Expression |
1319 | `-'U'a'' LiteralToken |
1320 | )txt" , |
1321 | R"txt( |
1322 | CharacterLiteralExpression Expression |
1323 | `-'U'🌲'' LiteralToken |
1324 | )txt" })); |
1325 | } |
1326 | |
1327 | TEST_P(BuildSyntaxTreeTest, CharacterLiteral_Utf8) { |
1328 | if (!GetParam().isCXX17OrLater()) { |
1329 | return; |
1330 | } |
1331 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1332 | R"cpp( |
1333 | void test() { |
1334 | [[u8'a']]; |
1335 | [[u8'\x7f']]; |
1336 | } |
1337 | )cpp" , |
1338 | {R"txt( |
1339 | CharacterLiteralExpression Expression |
1340 | `-'u8'a'' LiteralToken |
1341 | )txt" , |
1342 | R"txt( |
1343 | CharacterLiteralExpression Expression |
1344 | `-'u8'\x7f'' LiteralToken |
1345 | )txt" })); |
1346 | } |
1347 | |
1348 | TEST_P(BuildSyntaxTreeTest, FloatingLiteral) { |
1349 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1350 | R"cpp( |
1351 | void test() { |
1352 | [[1e-2]]; |
1353 | [[2.]]; |
1354 | [[.2]]; |
1355 | [[2.f]]; |
1356 | } |
1357 | )cpp" , |
1358 | {R"txt( |
1359 | FloatingLiteralExpression Expression |
1360 | `-'1e-2' LiteralToken |
1361 | )txt" , |
1362 | R"txt( |
1363 | FloatingLiteralExpression Expression |
1364 | `-'2.' LiteralToken |
1365 | )txt" , |
1366 | R"txt( |
1367 | FloatingLiteralExpression Expression |
1368 | `-'.2' LiteralToken |
1369 | )txt" , |
1370 | R"txt( |
1371 | FloatingLiteralExpression Expression |
1372 | `-'2.f' LiteralToken |
1373 | )txt" })); |
1374 | } |
1375 | |
1376 | TEST_P(BuildSyntaxTreeTest, FloatingLiteral_Hexadecimal) { |
1377 | if (!GetParam().isCXX17OrLater()) { |
1378 | return; |
1379 | } |
1380 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1381 | R"cpp( |
1382 | void test() { |
1383 | [[0xfp1]]; |
1384 | [[0xf.p1]]; |
1385 | [[0x.fp1]]; |
1386 | [[0xf.fp1f]]; |
1387 | } |
1388 | )cpp" , |
1389 | {R"txt( |
1390 | FloatingLiteralExpression Expression |
1391 | `-'0xfp1' LiteralToken |
1392 | )txt" , |
1393 | R"txt( |
1394 | FloatingLiteralExpression Expression |
1395 | `-'0xf.p1' LiteralToken |
1396 | )txt" , |
1397 | R"txt( |
1398 | FloatingLiteralExpression Expression |
1399 | `-'0x.fp1' LiteralToken |
1400 | )txt" , |
1401 | R"txt( |
1402 | FloatingLiteralExpression Expression |
1403 | `-'0xf.fp1f' LiteralToken |
1404 | )txt" })); |
1405 | } |
1406 | |
1407 | TEST_P(BuildSyntaxTreeTest, StringLiteral) { |
1408 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1409 | R"cpp( |
1410 | void test() { |
1411 | [["a\n\0\x20"]]; |
1412 | [[L"αβ"]]; |
1413 | } |
1414 | )cpp" , |
1415 | {R"txt( |
1416 | StringLiteralExpression Expression |
1417 | `-'"a\n\0\x20"' LiteralToken |
1418 | )txt" , |
1419 | R"txt( |
1420 | StringLiteralExpression Expression |
1421 | `-'L"αβ"' LiteralToken |
1422 | )txt" })); |
1423 | } |
1424 | |
1425 | TEST_P(BuildSyntaxTreeTest, StringLiteral_Utf) { |
1426 | if (!GetParam().isCXX11OrLater()) { |
1427 | return; |
1428 | } |
1429 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1430 | R"cpp( |
1431 | void test() { |
1432 | [[u8"a\x1f\x05"]]; |
1433 | [[u"C++抽象構文木"]]; |
1434 | [[U"📖🌲\n"]]; |
1435 | } |
1436 | )cpp" , |
1437 | {R"txt( |
1438 | StringLiteralExpression Expression |
1439 | `-'u8"a\x1f\x05"' LiteralToken |
1440 | )txt" , |
1441 | R"txt( |
1442 | StringLiteralExpression Expression |
1443 | `-'u"C++抽象構文木"' LiteralToken |
1444 | )txt" , |
1445 | R"txt( |
1446 | StringLiteralExpression Expression |
1447 | `-'U"📖🌲\n"' LiteralToken |
1448 | )txt" })); |
1449 | } |
1450 | |
1451 | TEST_P(BuildSyntaxTreeTest, StringLiteral_Raw) { |
1452 | if (!GetParam().isCXX11OrLater()) { |
1453 | return; |
1454 | } |
1455 | // This test uses regular string literals instead of raw string literals to |
1456 | // hold source code and expected output because of a bug in MSVC up to MSVC |
1457 | // 2019 16.2: |
1458 | // https://developercommunity.visualstudio.com/content/problem/67300/stringifying-raw-string-literal.html |
1459 | EXPECT_TRUE(treeDumpEqual( // |
1460 | "void test() {\n" |
1461 | " R\"SyntaxTree(\n" |
1462 | " Hello \"Syntax\" \\\"\n" |
1463 | " )SyntaxTree\";\n" |
1464 | "}\n" , |
1465 | "TranslationUnit Detached\n" |
1466 | "`-SimpleDeclaration\n" |
1467 | " |-'void'\n" |
1468 | " |-DeclaratorList Declarators\n" |
1469 | " | `-SimpleDeclarator ListElement\n" |
1470 | " | |-'test'\n" |
1471 | " | `-ParametersAndQualifiers\n" |
1472 | " | |-'(' OpenParen\n" |
1473 | " | `-')' CloseParen\n" |
1474 | " `-CompoundStatement\n" |
1475 | " |-'{' OpenParen\n" |
1476 | " |-ExpressionStatement Statement\n" |
1477 | " | |-StringLiteralExpression Expression\n" |
1478 | " | | `-'R\"SyntaxTree(\n" |
1479 | " Hello \"Syntax\" \\\"\n" |
1480 | " )SyntaxTree\"' LiteralToken\n" |
1481 | " | `-';'\n" |
1482 | " `-'}' CloseParen\n" )); |
1483 | } |
1484 | |
1485 | TEST_P(BuildSyntaxTreeTest, BoolLiteral) { |
1486 | if (GetParam().isC()) { |
1487 | return; |
1488 | } |
1489 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1490 | R"cpp( |
1491 | void test() { |
1492 | [[true]]; |
1493 | [[false]]; |
1494 | } |
1495 | )cpp" , |
1496 | {R"txt( |
1497 | BoolLiteralExpression Expression |
1498 | `-'true' LiteralToken |
1499 | )txt" , |
1500 | R"txt( |
1501 | BoolLiteralExpression Expression |
1502 | `-'false' LiteralToken |
1503 | )txt" })); |
1504 | } |
1505 | |
1506 | TEST_P(BuildSyntaxTreeTest, CxxNullPtrLiteral) { |
1507 | if (!GetParam().isCXX11OrLater()) { |
1508 | return; |
1509 | } |
1510 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1511 | R"cpp( |
1512 | void test() { |
1513 | [[nullptr]]; |
1514 | } |
1515 | )cpp" , |
1516 | {R"txt( |
1517 | CxxNullPtrExpression Expression |
1518 | `-'nullptr' LiteralToken |
1519 | )txt" })); |
1520 | } |
1521 | |
1522 | TEST_P(BuildSyntaxTreeTest, PostfixUnaryOperator) { |
1523 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1524 | R"cpp( |
1525 | void test(int a) { |
1526 | [[a++]]; |
1527 | [[a--]]; |
1528 | } |
1529 | )cpp" , |
1530 | {R"txt( |
1531 | PostfixUnaryOperatorExpression Expression |
1532 | |-IdExpression Operand |
1533 | | `-UnqualifiedId UnqualifiedId |
1534 | | `-'a' |
1535 | `-'++' OperatorToken |
1536 | )txt" , |
1537 | R"txt( |
1538 | PostfixUnaryOperatorExpression Expression |
1539 | |-IdExpression Operand |
1540 | | `-UnqualifiedId UnqualifiedId |
1541 | | `-'a' |
1542 | `-'--' OperatorToken |
1543 | )txt" })); |
1544 | } |
1545 | |
1546 | TEST_P(BuildSyntaxTreeTest, PrefixUnaryOperator) { |
1547 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1548 | R"cpp( |
1549 | void test(int a, int *ap) { |
1550 | [[--a]]; [[++a]]; |
1551 | [[~a]]; |
1552 | [[-a]]; |
1553 | [[+a]]; |
1554 | [[&a]]; |
1555 | [[*ap]]; |
1556 | [[!a]]; |
1557 | [[__real a]]; [[__imag a]]; |
1558 | } |
1559 | )cpp" , |
1560 | {R"txt( |
1561 | PrefixUnaryOperatorExpression Expression |
1562 | |-'--' OperatorToken |
1563 | `-IdExpression Operand |
1564 | `-UnqualifiedId UnqualifiedId |
1565 | `-'a' |
1566 | )txt" , |
1567 | R"txt( |
1568 | PrefixUnaryOperatorExpression Expression |
1569 | |-'++' OperatorToken |
1570 | `-IdExpression Operand |
1571 | `-UnqualifiedId UnqualifiedId |
1572 | `-'a' |
1573 | )txt" , |
1574 | R"txt( |
1575 | PrefixUnaryOperatorExpression Expression |
1576 | |-'~' OperatorToken |
1577 | `-IdExpression Operand |
1578 | `-UnqualifiedId UnqualifiedId |
1579 | `-'a' |
1580 | )txt" , |
1581 | R"txt( |
1582 | PrefixUnaryOperatorExpression Expression |
1583 | |-'-' OperatorToken |
1584 | `-IdExpression Operand |
1585 | `-UnqualifiedId UnqualifiedId |
1586 | `-'a' |
1587 | )txt" , |
1588 | R"txt( |
1589 | PrefixUnaryOperatorExpression Expression |
1590 | |-'+' OperatorToken |
1591 | `-IdExpression Operand |
1592 | `-UnqualifiedId UnqualifiedId |
1593 | `-'a' |
1594 | )txt" , |
1595 | R"txt( |
1596 | PrefixUnaryOperatorExpression Expression |
1597 | |-'&' OperatorToken |
1598 | `-IdExpression Operand |
1599 | `-UnqualifiedId UnqualifiedId |
1600 | `-'a' |
1601 | )txt" , |
1602 | R"txt( |
1603 | PrefixUnaryOperatorExpression Expression |
1604 | |-'*' OperatorToken |
1605 | `-IdExpression Operand |
1606 | `-UnqualifiedId UnqualifiedId |
1607 | `-'ap' |
1608 | )txt" , |
1609 | R"txt( |
1610 | PrefixUnaryOperatorExpression Expression |
1611 | |-'!' OperatorToken |
1612 | `-IdExpression Operand |
1613 | `-UnqualifiedId UnqualifiedId |
1614 | `-'a' |
1615 | )txt" , |
1616 | R"txt( |
1617 | PrefixUnaryOperatorExpression Expression |
1618 | |-'__real' OperatorToken |
1619 | `-IdExpression Operand |
1620 | `-UnqualifiedId UnqualifiedId |
1621 | `-'a' |
1622 | )txt" , |
1623 | R"txt( |
1624 | PrefixUnaryOperatorExpression Expression |
1625 | |-'__imag' OperatorToken |
1626 | `-IdExpression Operand |
1627 | `-UnqualifiedId UnqualifiedId |
1628 | `-'a' |
1629 | )txt" })); |
1630 | } |
1631 | |
1632 | TEST_P(BuildSyntaxTreeTest, PrefixUnaryOperatorCxx) { |
1633 | if (!GetParam().isCXX()) { |
1634 | return; |
1635 | } |
1636 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1637 | R"cpp( |
1638 | void test(int a, bool b) { |
1639 | [[compl a]]; |
1640 | [[not b]]; |
1641 | } |
1642 | )cpp" , |
1643 | {R"txt( |
1644 | PrefixUnaryOperatorExpression Expression |
1645 | |-'compl' OperatorToken |
1646 | `-IdExpression Operand |
1647 | `-UnqualifiedId UnqualifiedId |
1648 | `-'a' |
1649 | )txt" , |
1650 | R"txt( |
1651 | PrefixUnaryOperatorExpression Expression |
1652 | |-'not' OperatorToken |
1653 | `-IdExpression Operand |
1654 | `-UnqualifiedId UnqualifiedId |
1655 | `-'b' |
1656 | )txt" })); |
1657 | } |
1658 | |
1659 | TEST_P(BuildSyntaxTreeTest, BinaryOperator) { |
1660 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1661 | R"cpp( |
1662 | void test(int a) { |
1663 | [[1 - 2]]; |
1664 | [[1 == 2]]; |
1665 | [[a = 1]]; |
1666 | [[a <<= 1]]; |
1667 | [[1 || 0]]; |
1668 | [[1 & 2]]; |
1669 | [[a != 3]]; |
1670 | } |
1671 | )cpp" , |
1672 | {R"txt( |
1673 | BinaryOperatorExpression Expression |
1674 | |-IntegerLiteralExpression LeftHandSide |
1675 | | `-'1' LiteralToken |
1676 | |-'-' OperatorToken |
1677 | `-IntegerLiteralExpression RightHandSide |
1678 | `-'2' LiteralToken |
1679 | )txt" , |
1680 | R"txt( |
1681 | BinaryOperatorExpression Expression |
1682 | |-IntegerLiteralExpression LeftHandSide |
1683 | | `-'1' LiteralToken |
1684 | |-'==' OperatorToken |
1685 | `-IntegerLiteralExpression RightHandSide |
1686 | `-'2' LiteralToken |
1687 | )txt" , |
1688 | R"txt( |
1689 | BinaryOperatorExpression Expression |
1690 | |-IdExpression LeftHandSide |
1691 | | `-UnqualifiedId UnqualifiedId |
1692 | | `-'a' |
1693 | |-'=' OperatorToken |
1694 | `-IntegerLiteralExpression RightHandSide |
1695 | `-'1' LiteralToken |
1696 | )txt" , |
1697 | R"txt( |
1698 | BinaryOperatorExpression Expression |
1699 | |-IdExpression LeftHandSide |
1700 | | `-UnqualifiedId UnqualifiedId |
1701 | | `-'a' |
1702 | |-'<<=' OperatorToken |
1703 | `-IntegerLiteralExpression RightHandSide |
1704 | `-'1' LiteralToken |
1705 | )txt" , |
1706 | R"txt( |
1707 | BinaryOperatorExpression Expression |
1708 | |-IntegerLiteralExpression LeftHandSide |
1709 | | `-'1' LiteralToken |
1710 | |-'||' OperatorToken |
1711 | `-IntegerLiteralExpression RightHandSide |
1712 | `-'0' LiteralToken |
1713 | )txt" , |
1714 | R"txt( |
1715 | BinaryOperatorExpression Expression |
1716 | |-IntegerLiteralExpression LeftHandSide |
1717 | | `-'1' LiteralToken |
1718 | |-'&' OperatorToken |
1719 | `-IntegerLiteralExpression RightHandSide |
1720 | `-'2' LiteralToken |
1721 | )txt" , |
1722 | R"txt( |
1723 | BinaryOperatorExpression Expression |
1724 | |-IdExpression LeftHandSide |
1725 | | `-UnqualifiedId UnqualifiedId |
1726 | | `-'a' |
1727 | |-'!=' OperatorToken |
1728 | `-IntegerLiteralExpression RightHandSide |
1729 | `-'3' LiteralToken |
1730 | )txt" })); |
1731 | } |
1732 | |
1733 | TEST_P(BuildSyntaxTreeTest, BinaryOperatorCxx) { |
1734 | if (!GetParam().isCXX()) { |
1735 | return; |
1736 | } |
1737 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1738 | R"cpp( |
1739 | void test(int a) { |
1740 | [[true || false]]; |
1741 | [[true or false]]; |
1742 | [[1 bitand 2]]; |
1743 | [[a xor_eq 3]]; |
1744 | } |
1745 | )cpp" , |
1746 | {R"txt( |
1747 | BinaryOperatorExpression Expression |
1748 | |-BoolLiteralExpression LeftHandSide |
1749 | | `-'true' LiteralToken |
1750 | |-'||' OperatorToken |
1751 | `-BoolLiteralExpression RightHandSide |
1752 | `-'false' LiteralToken |
1753 | )txt" , |
1754 | R"txt( |
1755 | BinaryOperatorExpression Expression |
1756 | |-BoolLiteralExpression LeftHandSide |
1757 | | `-'true' LiteralToken |
1758 | |-'or' OperatorToken |
1759 | `-BoolLiteralExpression RightHandSide |
1760 | `-'false' LiteralToken |
1761 | )txt" , |
1762 | R"txt( |
1763 | BinaryOperatorExpression Expression |
1764 | |-IntegerLiteralExpression LeftHandSide |
1765 | | `-'1' LiteralToken |
1766 | |-'bitand' OperatorToken |
1767 | `-IntegerLiteralExpression RightHandSide |
1768 | `-'2' LiteralToken |
1769 | )txt" , |
1770 | R"txt( |
1771 | BinaryOperatorExpression Expression |
1772 | |-IdExpression LeftHandSide |
1773 | | `-UnqualifiedId UnqualifiedId |
1774 | | `-'a' |
1775 | |-'xor_eq' OperatorToken |
1776 | `-IntegerLiteralExpression RightHandSide |
1777 | `-'3' LiteralToken |
1778 | )txt" })); |
1779 | } |
1780 | |
1781 | TEST_P(BuildSyntaxTreeTest, BinaryOperator_NestedWithParenthesis) { |
1782 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1783 | R"cpp( |
1784 | void test() { |
1785 | [[(1 + 2) * (4 / 2)]]; |
1786 | } |
1787 | )cpp" , |
1788 | {R"txt( |
1789 | BinaryOperatorExpression Expression |
1790 | |-ParenExpression LeftHandSide |
1791 | | |-'(' OpenParen |
1792 | | |-BinaryOperatorExpression SubExpression |
1793 | | | |-IntegerLiteralExpression LeftHandSide |
1794 | | | | `-'1' LiteralToken |
1795 | | | |-'+' OperatorToken |
1796 | | | `-IntegerLiteralExpression RightHandSide |
1797 | | | `-'2' LiteralToken |
1798 | | `-')' CloseParen |
1799 | |-'*' OperatorToken |
1800 | `-ParenExpression RightHandSide |
1801 | |-'(' OpenParen |
1802 | |-BinaryOperatorExpression SubExpression |
1803 | | |-IntegerLiteralExpression LeftHandSide |
1804 | | | `-'4' LiteralToken |
1805 | | |-'/' OperatorToken |
1806 | | `-IntegerLiteralExpression RightHandSide |
1807 | | `-'2' LiteralToken |
1808 | `-')' CloseParen |
1809 | )txt" })); |
1810 | } |
1811 | |
1812 | TEST_P(BuildSyntaxTreeTest, BinaryOperator_Associativity) { |
1813 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1814 | R"cpp( |
1815 | void test(int a, int b) { |
1816 | [[a + b + 42]]; |
1817 | [[a = b = 42]]; |
1818 | } |
1819 | )cpp" , |
1820 | {R"txt( |
1821 | BinaryOperatorExpression Expression |
1822 | |-BinaryOperatorExpression LeftHandSide |
1823 | | |-IdExpression LeftHandSide |
1824 | | | `-UnqualifiedId UnqualifiedId |
1825 | | | `-'a' |
1826 | | |-'+' OperatorToken |
1827 | | `-IdExpression RightHandSide |
1828 | | `-UnqualifiedId UnqualifiedId |
1829 | | `-'b' |
1830 | |-'+' OperatorToken |
1831 | `-IntegerLiteralExpression RightHandSide |
1832 | `-'42' LiteralToken |
1833 | )txt" , |
1834 | R"txt( |
1835 | BinaryOperatorExpression Expression |
1836 | |-IdExpression LeftHandSide |
1837 | | `-UnqualifiedId UnqualifiedId |
1838 | | `-'a' |
1839 | |-'=' OperatorToken |
1840 | `-BinaryOperatorExpression RightHandSide |
1841 | |-IdExpression LeftHandSide |
1842 | | `-UnqualifiedId UnqualifiedId |
1843 | | `-'b' |
1844 | |-'=' OperatorToken |
1845 | `-IntegerLiteralExpression RightHandSide |
1846 | `-'42' LiteralToken |
1847 | )txt" })); |
1848 | } |
1849 | |
1850 | TEST_P(BuildSyntaxTreeTest, BinaryOperator_Precedence) { |
1851 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1852 | R"cpp( |
1853 | void test() { |
1854 | [[1 + 2 * 3 + 4]]; |
1855 | [[1 % 2 + 3 * 4]]; |
1856 | } |
1857 | )cpp" , |
1858 | {R"txt( |
1859 | BinaryOperatorExpression Expression |
1860 | |-BinaryOperatorExpression LeftHandSide |
1861 | | |-IntegerLiteralExpression LeftHandSide |
1862 | | | `-'1' LiteralToken |
1863 | | |-'+' OperatorToken |
1864 | | `-BinaryOperatorExpression RightHandSide |
1865 | | |-IntegerLiteralExpression LeftHandSide |
1866 | | | `-'2' LiteralToken |
1867 | | |-'*' OperatorToken |
1868 | | `-IntegerLiteralExpression RightHandSide |
1869 | | `-'3' LiteralToken |
1870 | |-'+' OperatorToken |
1871 | `-IntegerLiteralExpression RightHandSide |
1872 | `-'4' LiteralToken |
1873 | )txt" , |
1874 | R"txt( |
1875 | BinaryOperatorExpression Expression |
1876 | |-BinaryOperatorExpression LeftHandSide |
1877 | | |-IntegerLiteralExpression LeftHandSide |
1878 | | | `-'1' LiteralToken |
1879 | | |-'%' OperatorToken |
1880 | | `-IntegerLiteralExpression RightHandSide |
1881 | | `-'2' LiteralToken |
1882 | |-'+' OperatorToken |
1883 | `-BinaryOperatorExpression RightHandSide |
1884 | |-IntegerLiteralExpression LeftHandSide |
1885 | | `-'3' LiteralToken |
1886 | |-'*' OperatorToken |
1887 | `-IntegerLiteralExpression RightHandSide |
1888 | `-'4' LiteralToken |
1889 | )txt" })); |
1890 | } |
1891 | |
1892 | TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Assignment) { |
1893 | if (!GetParam().isCXX()) { |
1894 | return; |
1895 | } |
1896 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1897 | R"cpp( |
1898 | struct X { |
1899 | X& operator=(const X&); |
1900 | }; |
1901 | void test(X x, X y) { |
1902 | [[x = y]]; |
1903 | } |
1904 | )cpp" , |
1905 | {R"txt( |
1906 | BinaryOperatorExpression Expression |
1907 | |-IdExpression LeftHandSide |
1908 | | `-UnqualifiedId UnqualifiedId |
1909 | | `-'x' |
1910 | |-'=' OperatorToken |
1911 | `-IdExpression RightHandSide |
1912 | `-UnqualifiedId UnqualifiedId |
1913 | `-'y' |
1914 | )txt" })); |
1915 | } |
1916 | |
1917 | TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Plus) { |
1918 | if (!GetParam().isCXX()) { |
1919 | return; |
1920 | } |
1921 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1922 | R"cpp( |
1923 | struct X { |
1924 | friend X operator+(X, const X&); |
1925 | }; |
1926 | void test(X x, X y) { |
1927 | [[x + y]]; |
1928 | } |
1929 | )cpp" , |
1930 | {R"txt( |
1931 | BinaryOperatorExpression Expression |
1932 | |-IdExpression LeftHandSide |
1933 | | `-UnqualifiedId UnqualifiedId |
1934 | | `-'x' |
1935 | |-'+' OperatorToken |
1936 | `-IdExpression RightHandSide |
1937 | `-UnqualifiedId UnqualifiedId |
1938 | `-'y' |
1939 | )txt" })); |
1940 | } |
1941 | |
1942 | TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Less) { |
1943 | if (!GetParam().isCXX()) { |
1944 | return; |
1945 | } |
1946 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1947 | R"cpp( |
1948 | struct X { |
1949 | friend bool operator<(const X&, const X&); |
1950 | }; |
1951 | void test(X x, X y) { |
1952 | [[x < y]]; |
1953 | } |
1954 | )cpp" , |
1955 | {R"txt( |
1956 | BinaryOperatorExpression Expression |
1957 | |-IdExpression LeftHandSide |
1958 | | `-UnqualifiedId UnqualifiedId |
1959 | | `-'x' |
1960 | |-'<' OperatorToken |
1961 | `-IdExpression RightHandSide |
1962 | `-UnqualifiedId UnqualifiedId |
1963 | `-'y' |
1964 | )txt" })); |
1965 | } |
1966 | |
1967 | TEST_P(BuildSyntaxTreeTest, OverloadedOperator_LeftShift) { |
1968 | if (!GetParam().isCXX()) { |
1969 | return; |
1970 | } |
1971 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1972 | R"cpp( |
1973 | struct X { |
1974 | friend X operator<<(X&, const X&); |
1975 | }; |
1976 | void test(X x, X y) { |
1977 | [[x << y]]; |
1978 | } |
1979 | )cpp" , |
1980 | {R"txt( |
1981 | BinaryOperatorExpression Expression |
1982 | |-IdExpression LeftHandSide |
1983 | | `-UnqualifiedId UnqualifiedId |
1984 | | `-'x' |
1985 | |-'<<' OperatorToken |
1986 | `-IdExpression RightHandSide |
1987 | `-UnqualifiedId UnqualifiedId |
1988 | `-'y' |
1989 | )txt" })); |
1990 | } |
1991 | |
1992 | TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Comma) { |
1993 | if (!GetParam().isCXX()) { |
1994 | return; |
1995 | } |
1996 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
1997 | R"cpp( |
1998 | struct X { |
1999 | X operator,(X&); |
2000 | }; |
2001 | void test(X x, X y) { |
2002 | [[x, y]]; |
2003 | } |
2004 | )cpp" , |
2005 | {R"txt( |
2006 | BinaryOperatorExpression Expression |
2007 | |-IdExpression LeftHandSide |
2008 | | `-UnqualifiedId UnqualifiedId |
2009 | | `-'x' |
2010 | |-',' OperatorToken |
2011 | `-IdExpression RightHandSide |
2012 | `-UnqualifiedId UnqualifiedId |
2013 | `-'y' |
2014 | )txt" })); |
2015 | } |
2016 | |
2017 | TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PointerToMember) { |
2018 | if (!GetParam().isCXX()) { |
2019 | return; |
2020 | } |
2021 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2022 | R"cpp( |
2023 | struct X { |
2024 | X operator->*(int); |
2025 | }; |
2026 | void test(X* xp, int X::* pmi) { |
2027 | [[xp->*pmi]]; |
2028 | } |
2029 | )cpp" , |
2030 | {R"txt( |
2031 | BinaryOperatorExpression Expression |
2032 | |-IdExpression LeftHandSide |
2033 | | `-UnqualifiedId UnqualifiedId |
2034 | | `-'xp' |
2035 | |-'->*' OperatorToken |
2036 | `-IdExpression RightHandSide |
2037 | `-UnqualifiedId UnqualifiedId |
2038 | `-'pmi' |
2039 | )txt" })); |
2040 | } |
2041 | |
2042 | TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Negation) { |
2043 | if (!GetParam().isCXX()) { |
2044 | return; |
2045 | } |
2046 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2047 | R"cpp( |
2048 | struct X { |
2049 | bool operator!(); |
2050 | }; |
2051 | void test(X x) { |
2052 | [[!x]]; |
2053 | } |
2054 | )cpp" , |
2055 | {R"txt( |
2056 | PrefixUnaryOperatorExpression Expression |
2057 | |-'!' OperatorToken |
2058 | `-IdExpression Operand |
2059 | `-UnqualifiedId UnqualifiedId |
2060 | `-'x' |
2061 | )txt" })); |
2062 | } |
2063 | |
2064 | TEST_P(BuildSyntaxTreeTest, OverloadedOperator_AddressOf) { |
2065 | if (!GetParam().isCXX()) { |
2066 | return; |
2067 | } |
2068 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2069 | R"cpp( |
2070 | struct X { |
2071 | X* operator&(); |
2072 | }; |
2073 | void test(X x) { |
2074 | [[&x]]; |
2075 | } |
2076 | )cpp" , |
2077 | {R"txt( |
2078 | PrefixUnaryOperatorExpression Expression |
2079 | |-'&' OperatorToken |
2080 | `-IdExpression Operand |
2081 | `-UnqualifiedId UnqualifiedId |
2082 | `-'x' |
2083 | )txt" })); |
2084 | } |
2085 | |
2086 | TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PrefixIncrement) { |
2087 | if (!GetParam().isCXX()) { |
2088 | return; |
2089 | } |
2090 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2091 | R"cpp( |
2092 | struct X { |
2093 | X operator++(); |
2094 | }; |
2095 | void test(X x) { |
2096 | [[++x]]; |
2097 | } |
2098 | )cpp" , |
2099 | {R"txt( |
2100 | PrefixUnaryOperatorExpression Expression |
2101 | |-'++' OperatorToken |
2102 | `-IdExpression Operand |
2103 | `-UnqualifiedId UnqualifiedId |
2104 | `-'x' |
2105 | )txt" })); |
2106 | } |
2107 | |
2108 | TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PostfixIncrement) { |
2109 | if (!GetParam().isCXX()) { |
2110 | return; |
2111 | } |
2112 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2113 | R"cpp( |
2114 | struct X { |
2115 | X operator++(int); |
2116 | }; |
2117 | void test(X x) { |
2118 | [[x++]]; |
2119 | } |
2120 | )cpp" , |
2121 | {R"txt( |
2122 | PostfixUnaryOperatorExpression Expression |
2123 | |-IdExpression Operand |
2124 | | `-UnqualifiedId UnqualifiedId |
2125 | | `-'x' |
2126 | `-'++' OperatorToken |
2127 | )txt" })); |
2128 | } |
2129 | |
2130 | TEST_P(BuildSyntaxTreeTest, MemberExpression_SimpleWithDot) { |
2131 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2132 | R"cpp( |
2133 | struct S { |
2134 | int a; |
2135 | }; |
2136 | void test(struct S s) { |
2137 | [[s.a]]; |
2138 | } |
2139 | )cpp" , |
2140 | {R"txt( |
2141 | MemberExpression Expression |
2142 | |-IdExpression Object |
2143 | | `-UnqualifiedId UnqualifiedId |
2144 | | `-'s' |
2145 | |-'.' AccessToken |
2146 | `-IdExpression Member |
2147 | `-UnqualifiedId UnqualifiedId |
2148 | `-'a' |
2149 | )txt" })); |
2150 | } |
2151 | |
2152 | TEST_P(BuildSyntaxTreeTest, MemberExpression_StaticDataMember) { |
2153 | if (!GetParam().isCXX()) { |
2154 | return; |
2155 | } |
2156 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2157 | R"cpp( |
2158 | struct S { |
2159 | static int a; |
2160 | }; |
2161 | void test(S s) { |
2162 | [[s.a]]; |
2163 | } |
2164 | )cpp" , |
2165 | {R"txt( |
2166 | MemberExpression Expression |
2167 | |-IdExpression Object |
2168 | | `-UnqualifiedId UnqualifiedId |
2169 | | `-'s' |
2170 | |-'.' AccessToken |
2171 | `-IdExpression Member |
2172 | `-UnqualifiedId UnqualifiedId |
2173 | `-'a' |
2174 | )txt" })); |
2175 | } |
2176 | |
2177 | TEST_P(BuildSyntaxTreeTest, MemberExpression_SimpleWithArrow) { |
2178 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2179 | R"cpp( |
2180 | struct S { |
2181 | int a; |
2182 | }; |
2183 | void test(struct S* sp) { |
2184 | [[sp->a]]; |
2185 | } |
2186 | )cpp" , |
2187 | {R"txt( |
2188 | MemberExpression Expression |
2189 | |-IdExpression Object |
2190 | | `-UnqualifiedId UnqualifiedId |
2191 | | `-'sp' |
2192 | |-'->' AccessToken |
2193 | `-IdExpression Member |
2194 | `-UnqualifiedId UnqualifiedId |
2195 | `-'a' |
2196 | )txt" })); |
2197 | } |
2198 | |
2199 | TEST_P(BuildSyntaxTreeTest, MemberExpression_Chaining) { |
2200 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2201 | R"cpp( |
2202 | struct S { |
2203 | struct S* next; |
2204 | }; |
2205 | void test(struct S s){ |
2206 | [[s.next->next]]; |
2207 | } |
2208 | )cpp" , |
2209 | {R"txt( |
2210 | MemberExpression Expression |
2211 | |-MemberExpression Object |
2212 | | |-IdExpression Object |
2213 | | | `-UnqualifiedId UnqualifiedId |
2214 | | | `-'s' |
2215 | | |-'.' AccessToken |
2216 | | `-IdExpression Member |
2217 | | `-UnqualifiedId UnqualifiedId |
2218 | | `-'next' |
2219 | |-'->' AccessToken |
2220 | `-IdExpression Member |
2221 | `-UnqualifiedId UnqualifiedId |
2222 | `-'next' |
2223 | )txt" })); |
2224 | } |
2225 | |
2226 | TEST_P(BuildSyntaxTreeTest, MemberExpression_OperatorFunction) { |
2227 | if (!GetParam().isCXX()) { |
2228 | return; |
2229 | } |
2230 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2231 | R"cpp( |
2232 | struct S { |
2233 | bool operator!(); |
2234 | }; |
2235 | void test(S s) { |
2236 | [[s.operator!()]]; |
2237 | } |
2238 | )cpp" , |
2239 | {R"txt( |
2240 | CallExpression Expression |
2241 | |-MemberExpression Callee |
2242 | | |-IdExpression Object |
2243 | | | `-UnqualifiedId UnqualifiedId |
2244 | | | `-'s' |
2245 | | |-'.' AccessToken |
2246 | | `-IdExpression Member |
2247 | | `-UnqualifiedId UnqualifiedId |
2248 | | |-'operator' |
2249 | | `-'!' |
2250 | |-'(' OpenParen |
2251 | `-')' CloseParen |
2252 | )txt" })); |
2253 | } |
2254 | |
2255 | TEST_P(BuildSyntaxTreeTest, MemberExpression_VariableTemplate) { |
2256 | if (!GetParam().isCXX14OrLater()) { |
2257 | return; |
2258 | } |
2259 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2260 | R"cpp( |
2261 | struct S { |
2262 | template<typename T> |
2263 | static constexpr T x = 42; |
2264 | }; |
2265 | void test(S s) [[{ |
2266 | s.x<int>; |
2267 | }]] |
2268 | )cpp" , |
2269 | {R"txt( |
2270 | CompoundStatement |
2271 | |-'{' OpenParen |
2272 | |-ExpressionStatement Statement |
2273 | | |-MemberExpression Expression |
2274 | | | |-IdExpression Object |
2275 | | | | `-UnqualifiedId UnqualifiedId |
2276 | | | | `-'s' |
2277 | | | |-'.' AccessToken |
2278 | | | `-IdExpression Member |
2279 | | | `-UnqualifiedId UnqualifiedId |
2280 | | | |-'x' |
2281 | | | |-'<' |
2282 | | | |-'int' |
2283 | | | `-'>' |
2284 | | `-';' |
2285 | `-'}' CloseParen |
2286 | )txt" })); |
2287 | } |
2288 | |
2289 | TEST_P(BuildSyntaxTreeTest, MemberExpression_FunctionTemplate) { |
2290 | if (!GetParam().isCXX()) { |
2291 | return; |
2292 | } |
2293 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2294 | R"cpp( |
2295 | struct S { |
2296 | template<typename T> |
2297 | T f(); |
2298 | }; |
2299 | void test(S* sp){ |
2300 | [[sp->f<int>()]]; |
2301 | } |
2302 | )cpp" , |
2303 | {R"txt( |
2304 | CallExpression Expression |
2305 | |-MemberExpression Callee |
2306 | | |-IdExpression Object |
2307 | | | `-UnqualifiedId UnqualifiedId |
2308 | | | `-'sp' |
2309 | | |-'->' AccessToken |
2310 | | `-IdExpression Member |
2311 | | `-UnqualifiedId UnqualifiedId |
2312 | | |-'f' |
2313 | | |-'<' |
2314 | | |-'int' |
2315 | | `-'>' |
2316 | |-'(' OpenParen |
2317 | `-')' CloseParen |
2318 | )txt" })); |
2319 | } |
2320 | |
2321 | TEST_P(BuildSyntaxTreeTest, |
2322 | MemberExpression_FunctionTemplateWithTemplateKeyword) { |
2323 | if (!GetParam().isCXX()) { |
2324 | return; |
2325 | } |
2326 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2327 | R"cpp( |
2328 | struct S { |
2329 | template<typename T> |
2330 | T f(); |
2331 | }; |
2332 | void test(S s){ |
2333 | [[s.template f<int>()]]; |
2334 | } |
2335 | )cpp" , |
2336 | {R"txt( |
2337 | CallExpression Expression |
2338 | |-MemberExpression Callee |
2339 | | |-IdExpression Object |
2340 | | | `-UnqualifiedId UnqualifiedId |
2341 | | | `-'s' |
2342 | | |-'.' AccessToken |
2343 | | |-'template' |
2344 | | `-IdExpression Member |
2345 | | `-UnqualifiedId UnqualifiedId |
2346 | | |-'f' |
2347 | | |-'<' |
2348 | | |-'int' |
2349 | | `-'>' |
2350 | |-'(' OpenParen |
2351 | `-')' CloseParen |
2352 | )txt" })); |
2353 | } |
2354 | |
2355 | TEST_P(BuildSyntaxTreeTest, MemberExpression_WithQualifier) { |
2356 | if (!GetParam().isCXX()) { |
2357 | return; |
2358 | } |
2359 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2360 | R"cpp( |
2361 | struct Base { |
2362 | void f(); |
2363 | }; |
2364 | struct S : public Base {}; |
2365 | void test(S s){ |
2366 | [[s.Base::f()]]; |
2367 | [[s.::S::~S()]]; |
2368 | } |
2369 | )cpp" , |
2370 | {R"txt( |
2371 | CallExpression Expression |
2372 | |-MemberExpression Callee |
2373 | | |-IdExpression Object |
2374 | | | `-UnqualifiedId UnqualifiedId |
2375 | | | `-'s' |
2376 | | |-'.' AccessToken |
2377 | | `-IdExpression Member |
2378 | | |-NestedNameSpecifier Qualifier |
2379 | | | |-IdentifierNameSpecifier ListElement |
2380 | | | | `-'Base' |
2381 | | | `-'::' ListDelimiter |
2382 | | `-UnqualifiedId UnqualifiedId |
2383 | | `-'f' |
2384 | |-'(' OpenParen |
2385 | `-')' CloseParen |
2386 | )txt" , |
2387 | R"txt( |
2388 | CallExpression Expression |
2389 | |-MemberExpression Callee |
2390 | | |-IdExpression Object |
2391 | | | `-UnqualifiedId UnqualifiedId |
2392 | | | `-'s' |
2393 | | |-'.' AccessToken |
2394 | | `-IdExpression Member |
2395 | | |-NestedNameSpecifier Qualifier |
2396 | | | |-'::' ListDelimiter |
2397 | | | |-IdentifierNameSpecifier ListElement |
2398 | | | | `-'S' |
2399 | | | `-'::' ListDelimiter |
2400 | | `-UnqualifiedId UnqualifiedId |
2401 | | |-'~' |
2402 | | `-'S' |
2403 | |-'(' OpenParen |
2404 | `-')' CloseParen |
2405 | )txt" })); |
2406 | } |
2407 | |
2408 | TEST_P(BuildSyntaxTreeTest, MemberExpression_Complex) { |
2409 | if (!GetParam().isCXX()) { |
2410 | return; |
2411 | } |
2412 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2413 | R"cpp( |
2414 | template<typename T> |
2415 | struct U { |
2416 | template<typename U> |
2417 | U f(); |
2418 | }; |
2419 | struct S { |
2420 | U<int> getU(); |
2421 | }; |
2422 | void test(S* sp) { |
2423 | // FIXME: The first 'template' keyword is a child of `NestedNameSpecifier`, |
2424 | // but it should be a child of `MemberExpression` according to the grammar. |
2425 | // However one might argue that the 'template' keyword fits better inside |
2426 | // `NestedNameSpecifier` because if we change `U<int>` to `UI` we would like |
2427 | // equally to change the `NameSpecifier` `template U<int>` to just `UI`. |
2428 | [[sp->getU().template U<int>::template f<int>()]]; |
2429 | } |
2430 | )cpp" , |
2431 | {R"txt( |
2432 | CallExpression Expression |
2433 | |-MemberExpression Callee |
2434 | | |-CallExpression Object |
2435 | | | |-MemberExpression Callee |
2436 | | | | |-IdExpression Object |
2437 | | | | | `-UnqualifiedId UnqualifiedId |
2438 | | | | | `-'sp' |
2439 | | | | |-'->' AccessToken |
2440 | | | | `-IdExpression Member |
2441 | | | | `-UnqualifiedId UnqualifiedId |
2442 | | | | `-'getU' |
2443 | | | |-'(' OpenParen |
2444 | | | `-')' CloseParen |
2445 | | |-'.' AccessToken |
2446 | | `-IdExpression Member |
2447 | | |-NestedNameSpecifier Qualifier |
2448 | | | |-SimpleTemplateNameSpecifier ListElement |
2449 | | | | |-'template' |
2450 | | | | |-'U' |
2451 | | | | |-'<' |
2452 | | | | |-'int' |
2453 | | | | `-'>' |
2454 | | | `-'::' ListDelimiter |
2455 | | |-'template' TemplateKeyword |
2456 | | `-UnqualifiedId UnqualifiedId |
2457 | | |-'f' |
2458 | | |-'<' |
2459 | | |-'int' |
2460 | | `-'>' |
2461 | |-'(' OpenParen |
2462 | `-')' CloseParen |
2463 | )txt" })); |
2464 | } |
2465 | |
2466 | TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_Member) { |
2467 | if (!GetParam().isCXX()) { |
2468 | return; |
2469 | } |
2470 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2471 | R"cpp( |
2472 | struct S{ |
2473 | void f(); |
2474 | }; |
2475 | void test(S s) { |
2476 | [[s.f()]]; |
2477 | } |
2478 | )cpp" , |
2479 | {R"txt( |
2480 | CallExpression Expression |
2481 | |-MemberExpression Callee |
2482 | | |-IdExpression Object |
2483 | | | `-UnqualifiedId UnqualifiedId |
2484 | | | `-'s' |
2485 | | |-'.' AccessToken |
2486 | | `-IdExpression Member |
2487 | | `-UnqualifiedId UnqualifiedId |
2488 | | `-'f' |
2489 | |-'(' OpenParen |
2490 | `-')' CloseParen |
2491 | )txt" })); |
2492 | } |
2493 | |
2494 | TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_OperatorParens) { |
2495 | if (!GetParam().isCXX()) { |
2496 | return; |
2497 | } |
2498 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2499 | R"cpp( |
2500 | struct S { |
2501 | void operator()(); |
2502 | }; |
2503 | void test(S s) { |
2504 | [[s()]]; |
2505 | } |
2506 | )cpp" , |
2507 | {R"txt( |
2508 | CallExpression Expression |
2509 | |-IdExpression Callee |
2510 | | `-UnqualifiedId UnqualifiedId |
2511 | | `-'s' |
2512 | |-'(' OpenParen |
2513 | `-')' CloseParen |
2514 | )txt" })); |
2515 | } |
2516 | |
2517 | TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_OperatorParensChaining) { |
2518 | if (!GetParam().isCXX()) { |
2519 | return; |
2520 | } |
2521 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2522 | R"cpp( |
2523 | struct S { |
2524 | S operator()(); |
2525 | }; |
2526 | void test(S s) { |
2527 | [[s()()]]; |
2528 | } |
2529 | )cpp" , |
2530 | {R"txt( |
2531 | CallExpression Expression |
2532 | |-CallExpression Callee |
2533 | | |-IdExpression Callee |
2534 | | | `-UnqualifiedId UnqualifiedId |
2535 | | | `-'s' |
2536 | | |-'(' OpenParen |
2537 | | `-')' CloseParen |
2538 | |-'(' OpenParen |
2539 | `-')' CloseParen |
2540 | )txt" })); |
2541 | } |
2542 | |
2543 | TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_MemberWithThis) { |
2544 | if (!GetParam().isCXX()) { |
2545 | return; |
2546 | } |
2547 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2548 | R"cpp( |
2549 | struct Base { |
2550 | void f(); |
2551 | }; |
2552 | struct S: public Base { |
2553 | void f(); |
2554 | void test() { |
2555 | [[this->f()]]; |
2556 | [[f()]]; |
2557 | [[this->Base::f()]]; |
2558 | } |
2559 | }; |
2560 | )cpp" , |
2561 | {R"txt( |
2562 | CallExpression Expression |
2563 | |-MemberExpression Callee |
2564 | | |-ThisExpression Object |
2565 | | | `-'this' IntroducerKeyword |
2566 | | |-'->' AccessToken |
2567 | | `-IdExpression Member |
2568 | | `-UnqualifiedId UnqualifiedId |
2569 | | `-'f' |
2570 | |-'(' OpenParen |
2571 | `-')' CloseParen |
2572 | )txt" , |
2573 | R"txt( |
2574 | CallExpression Expression |
2575 | |-IdExpression Callee |
2576 | | `-UnqualifiedId UnqualifiedId |
2577 | | `-'f' |
2578 | |-'(' OpenParen |
2579 | `-')' CloseParen |
2580 | )txt" , |
2581 | R"txt( |
2582 | CallExpression Expression |
2583 | |-MemberExpression Callee |
2584 | | |-ThisExpression Object |
2585 | | | `-'this' IntroducerKeyword |
2586 | | |-'->' AccessToken |
2587 | | `-IdExpression Member |
2588 | | |-NestedNameSpecifier Qualifier |
2589 | | | |-IdentifierNameSpecifier ListElement |
2590 | | | | `-'Base' |
2591 | | | `-'::' ListDelimiter |
2592 | | `-UnqualifiedId UnqualifiedId |
2593 | | `-'f' |
2594 | |-'(' OpenParen |
2595 | `-')' CloseParen |
2596 | )txt" })); |
2597 | } |
2598 | |
2599 | TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_FunctionPointer) { |
2600 | if (!GetParam().isCXX()) { |
2601 | return; |
2602 | } |
2603 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2604 | R"cpp( |
2605 | void (*pf)(); |
2606 | void test() { |
2607 | [[pf()]]; |
2608 | [[(*pf)()]]; |
2609 | } |
2610 | )cpp" , |
2611 | {R"txt( |
2612 | CallExpression Expression |
2613 | |-IdExpression Callee |
2614 | | `-UnqualifiedId UnqualifiedId |
2615 | | `-'pf' |
2616 | |-'(' OpenParen |
2617 | `-')' CloseParen |
2618 | )txt" , |
2619 | R"txt( |
2620 | CallExpression Expression |
2621 | |-ParenExpression Callee |
2622 | | |-'(' OpenParen |
2623 | | |-PrefixUnaryOperatorExpression SubExpression |
2624 | | | |-'*' OperatorToken |
2625 | | | `-IdExpression Operand |
2626 | | | `-UnqualifiedId UnqualifiedId |
2627 | | | `-'pf' |
2628 | | `-')' CloseParen |
2629 | |-'(' OpenParen |
2630 | `-')' CloseParen |
2631 | )txt" })); |
2632 | } |
2633 | |
2634 | TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_MemberFunctionPointer) { |
2635 | if (!GetParam().isCXX()) { |
2636 | return; |
2637 | } |
2638 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2639 | R"cpp( |
2640 | struct S { |
2641 | void f(); |
2642 | }; |
2643 | void test(S s) { |
2644 | void (S::*pmf)(); |
2645 | pmf = &S::f; |
2646 | [[(s.*pmf)()]]; |
2647 | } |
2648 | )cpp" , |
2649 | {R"txt( |
2650 | CallExpression Expression |
2651 | |-ParenExpression Callee |
2652 | | |-'(' OpenParen |
2653 | | |-BinaryOperatorExpression SubExpression |
2654 | | | |-IdExpression LeftHandSide |
2655 | | | | `-UnqualifiedId UnqualifiedId |
2656 | | | | `-'s' |
2657 | | | |-'.*' OperatorToken |
2658 | | | `-IdExpression RightHandSide |
2659 | | | `-UnqualifiedId UnqualifiedId |
2660 | | | `-'pmf' |
2661 | | `-')' CloseParen |
2662 | |-'(' OpenParen |
2663 | `-')' CloseParen |
2664 | )txt" })); |
2665 | } |
2666 | |
2667 | TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Zero) { |
2668 | if (!GetParam().isCXX()) { |
2669 | return; |
2670 | } |
2671 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2672 | R"cpp( |
2673 | void f(); |
2674 | void test() { |
2675 | [[f();]] |
2676 | } |
2677 | )cpp" , |
2678 | {R"txt( |
2679 | ExpressionStatement Statement |
2680 | |-CallExpression Expression |
2681 | | |-IdExpression Callee |
2682 | | | `-UnqualifiedId UnqualifiedId |
2683 | | | `-'f' |
2684 | | |-'(' OpenParen |
2685 | | `-')' CloseParen |
2686 | `-';' |
2687 | )txt" })); |
2688 | } |
2689 | |
2690 | TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_One) { |
2691 | if (!GetParam().isCXX()) { |
2692 | return; |
2693 | } |
2694 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2695 | R"cpp( |
2696 | void f(int); |
2697 | void test() { |
2698 | [[f(1);]] |
2699 | } |
2700 | )cpp" , |
2701 | {R"txt( |
2702 | ExpressionStatement Statement |
2703 | |-CallExpression Expression |
2704 | | |-IdExpression Callee |
2705 | | | `-UnqualifiedId UnqualifiedId |
2706 | | | `-'f' |
2707 | | |-'(' OpenParen |
2708 | | |-CallArguments Arguments |
2709 | | | `-IntegerLiteralExpression ListElement |
2710 | | | `-'1' LiteralToken |
2711 | | `-')' CloseParen |
2712 | `-';' |
2713 | )txt" })); |
2714 | } |
2715 | |
2716 | TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Multiple) { |
2717 | if (!GetParam().isCXX()) { |
2718 | return; |
2719 | } |
2720 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2721 | R"cpp( |
2722 | void f(int, char, float); |
2723 | void test() { |
2724 | [[f(1, '2', 3.);]] |
2725 | } |
2726 | )cpp" , |
2727 | {R"txt( |
2728 | ExpressionStatement Statement |
2729 | |-CallExpression Expression |
2730 | | |-IdExpression Callee |
2731 | | | `-UnqualifiedId UnqualifiedId |
2732 | | | `-'f' |
2733 | | |-'(' OpenParen |
2734 | | |-CallArguments Arguments |
2735 | | | |-IntegerLiteralExpression ListElement |
2736 | | | | `-'1' LiteralToken |
2737 | | | |-',' ListDelimiter |
2738 | | | |-CharacterLiteralExpression ListElement |
2739 | | | | `-''2'' LiteralToken |
2740 | | | |-',' ListDelimiter |
2741 | | | `-FloatingLiteralExpression ListElement |
2742 | | | `-'3.' LiteralToken |
2743 | | `-')' CloseParen |
2744 | `-';' |
2745 | )txt" })); |
2746 | } |
2747 | |
2748 | TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Assignment) { |
2749 | if (!GetParam().isCXX()) { |
2750 | return; |
2751 | } |
2752 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2753 | R"cpp( |
2754 | void f(int); |
2755 | void test(int a) { |
2756 | [[f(a = 1);]] |
2757 | } |
2758 | )cpp" , |
2759 | {R"txt( |
2760 | ExpressionStatement Statement |
2761 | |-CallExpression Expression |
2762 | | |-IdExpression Callee |
2763 | | | `-UnqualifiedId UnqualifiedId |
2764 | | | `-'f' |
2765 | | |-'(' OpenParen |
2766 | | |-CallArguments Arguments |
2767 | | | `-BinaryOperatorExpression ListElement |
2768 | | | |-IdExpression LeftHandSide |
2769 | | | | `-UnqualifiedId UnqualifiedId |
2770 | | | | `-'a' |
2771 | | | |-'=' OperatorToken |
2772 | | | `-IntegerLiteralExpression RightHandSide |
2773 | | | `-'1' LiteralToken |
2774 | | `-')' CloseParen |
2775 | `-';' |
2776 | )txt" })); |
2777 | } |
2778 | |
2779 | TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_BracedInitList_Empty) { |
2780 | if (!GetParam().isCXX11OrLater()) { |
2781 | return; |
2782 | } |
2783 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2784 | R"cpp( |
2785 | void f(int[]); |
2786 | void test() { |
2787 | [[f({});]] |
2788 | } |
2789 | )cpp" , |
2790 | {R"txt( |
2791 | ExpressionStatement Statement |
2792 | |-CallExpression Expression |
2793 | | |-IdExpression Callee |
2794 | | | `-UnqualifiedId UnqualifiedId |
2795 | | | `-'f' |
2796 | | |-'(' OpenParen |
2797 | | |-CallArguments Arguments |
2798 | | | `-UnknownExpression ListElement |
2799 | | | `-UnknownExpression |
2800 | | | |-'{' |
2801 | | | `-'}' |
2802 | | `-')' CloseParen |
2803 | `-';' |
2804 | )txt" })); |
2805 | } |
2806 | |
2807 | TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_BracedInitList_Simple) { |
2808 | if (!GetParam().isCXX11OrLater()) { |
2809 | return; |
2810 | } |
2811 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2812 | R"cpp( |
2813 | struct TT {}; |
2814 | struct T{ |
2815 | int a; |
2816 | TT b; |
2817 | }; |
2818 | void f(T); |
2819 | void test() { |
2820 | [[f({1, {}});]] |
2821 | } |
2822 | )cpp" , |
2823 | {R"txt( |
2824 | ExpressionStatement Statement |
2825 | |-CallExpression Expression |
2826 | | |-IdExpression Callee |
2827 | | | `-UnqualifiedId UnqualifiedId |
2828 | | | `-'f' |
2829 | | |-'(' OpenParen |
2830 | | |-CallArguments Arguments |
2831 | | | `-UnknownExpression ListElement |
2832 | | | `-UnknownExpression |
2833 | | | |-'{' |
2834 | | | |-IntegerLiteralExpression |
2835 | | | | `-'1' LiteralToken |
2836 | | | |-',' |
2837 | | | |-UnknownExpression |
2838 | | | | `-UnknownExpression |
2839 | | | | |-'{' |
2840 | | | | `-'}' |
2841 | | | `-'}' |
2842 | | `-')' CloseParen |
2843 | `-';' |
2844 | )txt" })); |
2845 | } |
2846 | |
2847 | TEST_P(BuildSyntaxTreeTest, |
2848 | CallExpression_Arguments_BracedInitList_Designated) { |
2849 | if (!GetParam().isCXX11OrLater()) { |
2850 | return; |
2851 | } |
2852 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2853 | R"cpp( |
2854 | struct TT {}; |
2855 | struct T{ |
2856 | int a; |
2857 | TT b; |
2858 | }; |
2859 | void f(T); |
2860 | void test() { |
2861 | [[f({.a = 1, .b {}});]] |
2862 | } |
2863 | )cpp" , |
2864 | {R"txt( |
2865 | ExpressionStatement Statement |
2866 | |-CallExpression Expression |
2867 | | |-IdExpression Callee |
2868 | | | `-UnqualifiedId UnqualifiedId |
2869 | | | `-'f' |
2870 | | |-'(' OpenParen |
2871 | | |-CallArguments Arguments |
2872 | | | `-UnknownExpression ListElement |
2873 | | | `-UnknownExpression |
2874 | | | |-'{' |
2875 | | | |-UnknownExpression |
2876 | | | | |-'.' |
2877 | | | | |-'a' |
2878 | | | | |-'=' |
2879 | | | | `-IntegerLiteralExpression |
2880 | | | | `-'1' LiteralToken |
2881 | | | |-',' |
2882 | | | |-UnknownExpression |
2883 | | | | |-'.' |
2884 | | | | |-'b' |
2885 | | | | `-UnknownExpression |
2886 | | | | `-UnknownExpression |
2887 | | | | |-'{' |
2888 | | | | `-'}' |
2889 | | | `-'}' |
2890 | | `-')' CloseParen |
2891 | `-';' |
2892 | )txt" })); |
2893 | } |
2894 | |
2895 | TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_ParameterPack) { |
2896 | if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) { |
2897 | return; |
2898 | } |
2899 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2900 | R"cpp( |
2901 | template<typename T, typename... Args> |
2902 | void test(T t, Args... args) { |
2903 | [[test(args...)]]; |
2904 | } |
2905 | )cpp" , |
2906 | {R"txt( |
2907 | CallExpression Expression |
2908 | |-UnknownExpression Callee |
2909 | | `-'test' |
2910 | |-'(' OpenParen |
2911 | |-CallArguments Arguments |
2912 | | `-UnknownExpression ListElement |
2913 | | |-IdExpression |
2914 | | | `-UnqualifiedId UnqualifiedId |
2915 | | | `-'args' |
2916 | | `-'...' |
2917 | `-')' CloseParen |
2918 | )txt" })); |
2919 | } |
2920 | |
2921 | TEST_P(BuildSyntaxTreeTest, CallExpression_DefaultArguments) { |
2922 | if (!GetParam().isCXX11OrLater()) { |
2923 | return; |
2924 | } |
2925 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
2926 | R"cpp( |
2927 | void f(int i = 1, char c = '2'); |
2928 | void test() { |
2929 | [[f()]]; |
2930 | [[f(1)]]; |
2931 | [[f(1, '2')]]; |
2932 | } |
2933 | )cpp" , |
2934 | {R"txt( |
2935 | CallExpression Expression |
2936 | |-IdExpression Callee |
2937 | | `-UnqualifiedId UnqualifiedId |
2938 | | `-'f' |
2939 | |-'(' OpenParen |
2940 | `-')' CloseParen |
2941 | )txt" , |
2942 | R"txt( |
2943 | CallExpression Expression |
2944 | |-IdExpression Callee |
2945 | | `-UnqualifiedId UnqualifiedId |
2946 | | `-'f' |
2947 | |-'(' OpenParen |
2948 | |-CallArguments Arguments |
2949 | | `-IntegerLiteralExpression ListElement |
2950 | | `-'1' LiteralToken |
2951 | `-')' CloseParen |
2952 | )txt" , |
2953 | R"txt( |
2954 | CallExpression Expression |
2955 | |-IdExpression Callee |
2956 | | `-UnqualifiedId UnqualifiedId |
2957 | | `-'f' |
2958 | |-'(' OpenParen |
2959 | |-CallArguments Arguments |
2960 | | |-IntegerLiteralExpression ListElement |
2961 | | | `-'1' LiteralToken |
2962 | | |-',' ListDelimiter |
2963 | | `-CharacterLiteralExpression ListElement |
2964 | | `-''2'' LiteralToken |
2965 | `-')' CloseParen |
2966 | )txt" })); |
2967 | } |
2968 | |
2969 | TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsGrouping) { |
2970 | EXPECT_TRUE(treeDumpEqual( |
2971 | R"cpp( |
2972 | int *a, b; |
2973 | int *c, d; |
2974 | )cpp" , |
2975 | R"txt( |
2976 | TranslationUnit Detached |
2977 | |-SimpleDeclaration |
2978 | | |-'int' |
2979 | | |-DeclaratorList Declarators |
2980 | | | |-SimpleDeclarator ListElement |
2981 | | | | |-'*' |
2982 | | | | `-'a' |
2983 | | | |-',' ListDelimiter |
2984 | | | `-SimpleDeclarator ListElement |
2985 | | | `-'b' |
2986 | | `-';' |
2987 | `-SimpleDeclaration |
2988 | |-'int' |
2989 | |-DeclaratorList Declarators |
2990 | | |-SimpleDeclarator ListElement |
2991 | | | |-'*' |
2992 | | | `-'c' |
2993 | | |-',' ListDelimiter |
2994 | | `-SimpleDeclarator ListElement |
2995 | | `-'d' |
2996 | `-';' |
2997 | )txt" )); |
2998 | } |
2999 | |
3000 | TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsGroupingTypedef) { |
3001 | EXPECT_TRUE(treeDumpEqual( |
3002 | R"cpp( |
3003 | typedef int *a, b; |
3004 | )cpp" , |
3005 | R"txt( |
3006 | TranslationUnit Detached |
3007 | `-SimpleDeclaration |
3008 | |-'typedef' |
3009 | |-'int' |
3010 | |-DeclaratorList Declarators |
3011 | | |-SimpleDeclarator ListElement |
3012 | | | |-'*' |
3013 | | | `-'a' |
3014 | | |-',' ListDelimiter |
3015 | | `-SimpleDeclarator ListElement |
3016 | | `-'b' |
3017 | `-';' |
3018 | )txt" )); |
3019 | } |
3020 | |
3021 | TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsInsideStatement) { |
3022 | EXPECT_TRUE(treeDumpEqual( |
3023 | R"cpp( |
3024 | void foo() { |
3025 | int *a, b; |
3026 | typedef int *ta, tb; |
3027 | } |
3028 | )cpp" , |
3029 | R"txt( |
3030 | TranslationUnit Detached |
3031 | `-SimpleDeclaration |
3032 | |-'void' |
3033 | |-DeclaratorList Declarators |
3034 | | `-SimpleDeclarator ListElement |
3035 | | |-'foo' |
3036 | | `-ParametersAndQualifiers |
3037 | | |-'(' OpenParen |
3038 | | `-')' CloseParen |
3039 | `-CompoundStatement |
3040 | |-'{' OpenParen |
3041 | |-DeclarationStatement Statement |
3042 | | |-SimpleDeclaration |
3043 | | | |-'int' |
3044 | | | `-DeclaratorList Declarators |
3045 | | | |-SimpleDeclarator ListElement |
3046 | | | | |-'*' |
3047 | | | | `-'a' |
3048 | | | |-',' ListDelimiter |
3049 | | | `-SimpleDeclarator ListElement |
3050 | | | `-'b' |
3051 | | `-';' |
3052 | |-DeclarationStatement Statement |
3053 | | |-SimpleDeclaration |
3054 | | | |-'typedef' |
3055 | | | |-'int' |
3056 | | | `-DeclaratorList Declarators |
3057 | | | |-SimpleDeclarator ListElement |
3058 | | | | |-'*' |
3059 | | | | `-'ta' |
3060 | | | |-',' ListDelimiter |
3061 | | | `-SimpleDeclarator ListElement |
3062 | | | `-'tb' |
3063 | | `-';' |
3064 | `-'}' CloseParen |
3065 | )txt" )); |
3066 | } |
3067 | |
3068 | TEST_P(BuildSyntaxTreeTest, SizeTTypedef) { |
3069 | if (!GetParam().isCXX11OrLater()) { |
3070 | return; |
3071 | } |
3072 | EXPECT_TRUE(treeDumpEqual( |
3073 | R"cpp( |
3074 | typedef decltype(sizeof(void *)) size_t; |
3075 | )cpp" , |
3076 | R"txt( |
3077 | TranslationUnit Detached |
3078 | `-SimpleDeclaration |
3079 | |-'typedef' |
3080 | |-'decltype' |
3081 | |-'(' |
3082 | |-UnknownExpression |
3083 | | |-'sizeof' |
3084 | | |-'(' |
3085 | | |-'void' |
3086 | | |-'*' |
3087 | | `-')' |
3088 | |-')' |
3089 | |-DeclaratorList Declarators |
3090 | | `-SimpleDeclarator ListElement |
3091 | | `-'size_t' |
3092 | `-';' |
3093 | )txt" )); |
3094 | } |
3095 | |
3096 | TEST_P(BuildSyntaxTreeTest, Namespace_Nested) { |
3097 | if (!GetParam().isCXX()) { |
3098 | return; |
3099 | } |
3100 | EXPECT_TRUE(treeDumpEqual( |
3101 | R"cpp( |
3102 | namespace a { namespace b {} } |
3103 | )cpp" , |
3104 | R"txt( |
3105 | TranslationUnit Detached |
3106 | `-NamespaceDefinition |
3107 | |-'namespace' |
3108 | |-'a' |
3109 | |-'{' |
3110 | |-NamespaceDefinition |
3111 | | |-'namespace' |
3112 | | |-'b' |
3113 | | |-'{' |
3114 | | `-'}' |
3115 | `-'}' |
3116 | )txt" )); |
3117 | } |
3118 | |
3119 | TEST_P(BuildSyntaxTreeTest, Namespace_NestedDefinition) { |
3120 | if (!GetParam().isCXX17OrLater()) { |
3121 | return; |
3122 | } |
3123 | EXPECT_TRUE(treeDumpEqual( |
3124 | R"cpp( |
3125 | namespace a::b {} |
3126 | )cpp" , |
3127 | R"txt( |
3128 | TranslationUnit Detached |
3129 | `-NamespaceDefinition |
3130 | |-'namespace' |
3131 | |-'a' |
3132 | |-'::' |
3133 | |-'b' |
3134 | |-'{' |
3135 | `-'}' |
3136 | )txt" )); |
3137 | } |
3138 | |
3139 | TEST_P(BuildSyntaxTreeTest, Namespace_Unnamed) { |
3140 | if (!GetParam().isCXX()) { |
3141 | return; |
3142 | } |
3143 | EXPECT_TRUE(treeDumpEqual( |
3144 | R"cpp( |
3145 | namespace {} |
3146 | )cpp" , |
3147 | R"txt( |
3148 | TranslationUnit Detached |
3149 | `-NamespaceDefinition |
3150 | |-'namespace' |
3151 | |-'{' |
3152 | `-'}' |
3153 | )txt" )); |
3154 | } |
3155 | |
3156 | TEST_P(BuildSyntaxTreeTest, Namespace_Alias) { |
3157 | if (!GetParam().isCXX()) { |
3158 | return; |
3159 | } |
3160 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3161 | R"cpp( |
3162 | namespace a {} |
3163 | [[namespace foo = a;]] |
3164 | )cpp" , |
3165 | {R"txt( |
3166 | NamespaceAliasDefinition |
3167 | |-'namespace' |
3168 | |-'foo' |
3169 | |-'=' |
3170 | |-'a' |
3171 | `-';' |
3172 | )txt" })); |
3173 | } |
3174 | |
3175 | TEST_P(BuildSyntaxTreeTest, UsingDirective) { |
3176 | if (!GetParam().isCXX()) { |
3177 | return; |
3178 | } |
3179 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3180 | R"cpp( |
3181 | namespace ns {} |
3182 | [[using namespace ::ns;]] |
3183 | )cpp" , |
3184 | {R"txt( |
3185 | UsingNamespaceDirective |
3186 | |-'using' |
3187 | |-'namespace' |
3188 | |-NestedNameSpecifier |
3189 | | `-'::' ListDelimiter |
3190 | |-'ns' |
3191 | `-';' |
3192 | )txt" })); |
3193 | } |
3194 | |
3195 | TEST_P(BuildSyntaxTreeTest, UsingDeclaration_Namespace) { |
3196 | if (!GetParam().isCXX()) { |
3197 | return; |
3198 | } |
3199 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3200 | R"cpp( |
3201 | namespace ns { int a; } |
3202 | [[using ns::a;]] |
3203 | )cpp" , |
3204 | {R"txt( |
3205 | UsingDeclaration |
3206 | |-'using' |
3207 | |-NestedNameSpecifier |
3208 | | |-IdentifierNameSpecifier ListElement |
3209 | | | `-'ns' |
3210 | | `-'::' ListDelimiter |
3211 | |-'a' |
3212 | `-';' |
3213 | )txt" })); |
3214 | } |
3215 | |
3216 | TEST_P(BuildSyntaxTreeTest, UsingDeclaration_ClassMember) { |
3217 | if (!GetParam().isCXX()) { |
3218 | return; |
3219 | } |
3220 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3221 | R"cpp( |
3222 | template <class T> struct X { |
3223 | [[using T::foo;]] |
3224 | [[using typename T::bar;]] |
3225 | }; |
3226 | )cpp" , |
3227 | {R"txt( |
3228 | UsingDeclaration |
3229 | |-'using' |
3230 | |-NestedNameSpecifier |
3231 | | |-IdentifierNameSpecifier ListElement |
3232 | | | `-'T' |
3233 | | `-'::' ListDelimiter |
3234 | |-'foo' |
3235 | `-';' |
3236 | )txt" , |
3237 | R"txt( |
3238 | UsingDeclaration |
3239 | |-'using' |
3240 | |-'typename' |
3241 | |-NestedNameSpecifier |
3242 | | |-IdentifierNameSpecifier ListElement |
3243 | | | `-'T' |
3244 | | `-'::' ListDelimiter |
3245 | |-'bar' |
3246 | `-';' |
3247 | )txt" })); |
3248 | } |
3249 | |
3250 | TEST_P(BuildSyntaxTreeTest, UsingTypeAlias) { |
3251 | if (!GetParam().isCXX11OrLater()) { |
3252 | return; |
3253 | } |
3254 | EXPECT_TRUE(treeDumpEqual( |
3255 | R"cpp( |
3256 | using type = int; |
3257 | )cpp" , |
3258 | R"txt( |
3259 | TranslationUnit Detached |
3260 | `-TypeAliasDeclaration |
3261 | |-'using' |
3262 | |-'type' |
3263 | |-'=' |
3264 | |-'int' |
3265 | `-';' |
3266 | )txt" )); |
3267 | } |
3268 | |
3269 | TEST_P(BuildSyntaxTreeTest, FreeStandingClass_ForwardDeclaration) { |
3270 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3271 | R"cpp( |
3272 | [[struct X;]] |
3273 | [[struct Y *y1;]] |
3274 | )cpp" , |
3275 | {R"txt( |
3276 | SimpleDeclaration |
3277 | |-'struct' |
3278 | |-'X' |
3279 | `-';' |
3280 | )txt" , |
3281 | R"txt( |
3282 | SimpleDeclaration |
3283 | |-'struct' |
3284 | |-'Y' |
3285 | |-DeclaratorList Declarators |
3286 | | `-SimpleDeclarator ListElement |
3287 | | |-'*' |
3288 | | `-'y1' |
3289 | `-';' |
3290 | )txt" })); |
3291 | } |
3292 | |
3293 | TEST_P(BuildSyntaxTreeTest, FreeStandingClasses_Definition) { |
3294 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3295 | R"cpp( |
3296 | [[struct X {};]] |
3297 | [[struct Y {} *y2;]] |
3298 | [[struct {} *a1;]] |
3299 | )cpp" , |
3300 | {R"txt( |
3301 | SimpleDeclaration |
3302 | |-'struct' |
3303 | |-'X' |
3304 | |-'{' |
3305 | |-'}' |
3306 | `-';' |
3307 | )txt" , |
3308 | R"txt( |
3309 | SimpleDeclaration |
3310 | |-'struct' |
3311 | |-'Y' |
3312 | |-'{' |
3313 | |-'}' |
3314 | |-DeclaratorList Declarators |
3315 | | `-SimpleDeclarator ListElement |
3316 | | |-'*' |
3317 | | `-'y2' |
3318 | `-';' |
3319 | )txt" , |
3320 | R"txt( |
3321 | SimpleDeclaration |
3322 | |-'struct' |
3323 | |-'{' |
3324 | |-'}' |
3325 | |-DeclaratorList Declarators |
3326 | | `-SimpleDeclarator ListElement |
3327 | | |-'*' |
3328 | | `-'a1' |
3329 | `-';' |
3330 | )txt" })); |
3331 | } |
3332 | |
3333 | TEST_P(BuildSyntaxTreeTest, StaticMemberFunction) { |
3334 | if (!GetParam().isCXX11OrLater()) { |
3335 | return; |
3336 | } |
3337 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3338 | R"cpp( |
3339 | struct S { |
3340 | [[static void f(){}]] |
3341 | }; |
3342 | )cpp" , |
3343 | {R"txt( |
3344 | SimpleDeclaration |
3345 | |-'static' |
3346 | |-'void' |
3347 | |-DeclaratorList Declarators |
3348 | | `-SimpleDeclarator ListElement |
3349 | | |-'f' |
3350 | | `-ParametersAndQualifiers |
3351 | | |-'(' OpenParen |
3352 | | `-')' CloseParen |
3353 | `-CompoundStatement |
3354 | |-'{' OpenParen |
3355 | `-'}' CloseParen |
3356 | )txt" })); |
3357 | } |
3358 | |
3359 | TEST_P(BuildSyntaxTreeTest, OutOfLineMemberFunctionDefinition) { |
3360 | if (!GetParam().isCXX11OrLater()) { |
3361 | return; |
3362 | } |
3363 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3364 | R"cpp( |
3365 | struct S { |
3366 | void f(); |
3367 | }; |
3368 | [[void S::f(){}]] |
3369 | )cpp" , |
3370 | {R"txt( |
3371 | SimpleDeclaration |
3372 | |-'void' |
3373 | |-DeclaratorList Declarators |
3374 | | `-SimpleDeclarator ListElement |
3375 | | |-NestedNameSpecifier |
3376 | | | |-IdentifierNameSpecifier ListElement |
3377 | | | | `-'S' |
3378 | | | `-'::' ListDelimiter |
3379 | | |-'f' |
3380 | | `-ParametersAndQualifiers |
3381 | | |-'(' OpenParen |
3382 | | `-')' CloseParen |
3383 | `-CompoundStatement |
3384 | |-'{' OpenParen |
3385 | `-'}' CloseParen |
3386 | )txt" })); |
3387 | } |
3388 | |
3389 | TEST_P(BuildSyntaxTreeTest, ConversionMemberFunction) { |
3390 | if (!GetParam().isCXX()) { |
3391 | return; |
3392 | } |
3393 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3394 | R"cpp( |
3395 | struct X { |
3396 | [[operator int();]] |
3397 | }; |
3398 | )cpp" , |
3399 | {R"txt( |
3400 | SimpleDeclaration |
3401 | |-DeclaratorList Declarators |
3402 | | `-SimpleDeclarator ListElement |
3403 | | |-'operator' |
3404 | | |-'int' |
3405 | | `-ParametersAndQualifiers |
3406 | | |-'(' OpenParen |
3407 | | `-')' CloseParen |
3408 | `-';' |
3409 | )txt" })); |
3410 | } |
3411 | |
3412 | TEST_P(BuildSyntaxTreeTest, LiteralOperatorDeclaration) { |
3413 | if (!GetParam().isCXX11OrLater()) { |
3414 | return; |
3415 | } |
3416 | EXPECT_TRUE(treeDumpEqual( |
3417 | R"cpp( |
3418 | unsigned operator "" _c(char); |
3419 | )cpp" , |
3420 | R"txt( |
3421 | TranslationUnit Detached |
3422 | `-SimpleDeclaration |
3423 | |-'unsigned' |
3424 | |-DeclaratorList Declarators |
3425 | | `-SimpleDeclarator ListElement |
3426 | | |-'operator' |
3427 | | |-'""' |
3428 | | |-'_c' |
3429 | | `-ParametersAndQualifiers |
3430 | | |-'(' OpenParen |
3431 | | |-ParameterDeclarationList Parameters |
3432 | | | `-SimpleDeclaration ListElement |
3433 | | | `-'char' |
3434 | | `-')' CloseParen |
3435 | `-';' |
3436 | )txt" )); |
3437 | } |
3438 | |
3439 | TEST_P(BuildSyntaxTreeTest, NumericLiteralOperatorTemplateDeclaration) { |
3440 | if (!GetParam().isCXX11OrLater()) { |
3441 | return; |
3442 | } |
3443 | EXPECT_TRUE(treeDumpEqual( |
3444 | R"cpp( |
3445 | template <char...> |
3446 | unsigned operator "" _t(); |
3447 | )cpp" , |
3448 | R"txt( |
3449 | TranslationUnit Detached |
3450 | `-TemplateDeclaration Declaration |
3451 | |-'template' IntroducerKeyword |
3452 | |-'<' |
3453 | |-SimpleDeclaration |
3454 | | `-'char' |
3455 | |-'...' |
3456 | |-'>' |
3457 | `-SimpleDeclaration |
3458 | |-'unsigned' |
3459 | |-DeclaratorList Declarators |
3460 | | `-SimpleDeclarator ListElement |
3461 | | |-'operator' |
3462 | | |-'""' |
3463 | | |-'_t' |
3464 | | `-ParametersAndQualifiers |
3465 | | |-'(' OpenParen |
3466 | | `-')' CloseParen |
3467 | `-';' |
3468 | )txt" )); |
3469 | } |
3470 | |
3471 | TEST_P(BuildSyntaxTreeTest, OverloadedOperatorDeclaration) { |
3472 | if (!GetParam().isCXX()) { |
3473 | return; |
3474 | } |
3475 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3476 | R"cpp( |
3477 | struct X { |
3478 | [[X& operator=(const X&);]] |
3479 | }; |
3480 | )cpp" , |
3481 | {R"txt( |
3482 | SimpleDeclaration |
3483 | |-'X' |
3484 | |-DeclaratorList Declarators |
3485 | | `-SimpleDeclarator ListElement |
3486 | | |-'&' |
3487 | | |-'operator' |
3488 | | |-'=' |
3489 | | `-ParametersAndQualifiers |
3490 | | |-'(' OpenParen |
3491 | | |-ParameterDeclarationList Parameters |
3492 | | | `-SimpleDeclaration ListElement |
3493 | | | |-'const' |
3494 | | | |-'X' |
3495 | | | `-DeclaratorList Declarators |
3496 | | | `-SimpleDeclarator ListElement |
3497 | | | `-'&' |
3498 | | `-')' CloseParen |
3499 | `-';' |
3500 | )txt" })); |
3501 | } |
3502 | |
3503 | TEST_P(BuildSyntaxTreeTest, OverloadedOperatorFriendDeclaration) { |
3504 | if (!GetParam().isCXX()) { |
3505 | return; |
3506 | } |
3507 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3508 | R"cpp( |
3509 | struct X { |
3510 | [[friend X operator+(X, const X&);]] |
3511 | }; |
3512 | )cpp" , |
3513 | {R"txt( |
3514 | UnknownDeclaration |
3515 | `-SimpleDeclaration |
3516 | |-'friend' |
3517 | |-'X' |
3518 | |-DeclaratorList Declarators |
3519 | | `-SimpleDeclarator ListElement |
3520 | | |-'operator' |
3521 | | |-'+' |
3522 | | `-ParametersAndQualifiers |
3523 | | |-'(' OpenParen |
3524 | | |-ParameterDeclarationList Parameters |
3525 | | | |-SimpleDeclaration ListElement |
3526 | | | | `-'X' |
3527 | | | |-',' ListDelimiter |
3528 | | | `-SimpleDeclaration ListElement |
3529 | | | |-'const' |
3530 | | | |-'X' |
3531 | | | `-DeclaratorList Declarators |
3532 | | | `-SimpleDeclarator ListElement |
3533 | | | `-'&' |
3534 | | `-')' CloseParen |
3535 | `-';' |
3536 | )txt" })); |
3537 | } |
3538 | |
3539 | TEST_P(BuildSyntaxTreeTest, ClassTemplateDeclaration) { |
3540 | if (!GetParam().isCXX()) { |
3541 | return; |
3542 | } |
3543 | EXPECT_TRUE(treeDumpEqual( |
3544 | R"cpp( |
3545 | template<typename T> |
3546 | struct ST {}; |
3547 | )cpp" , |
3548 | R"txt( |
3549 | TranslationUnit Detached |
3550 | `-TemplateDeclaration Declaration |
3551 | |-'template' IntroducerKeyword |
3552 | |-'<' |
3553 | |-UnknownDeclaration |
3554 | | |-'typename' |
3555 | | `-'T' |
3556 | |-'>' |
3557 | `-SimpleDeclaration |
3558 | |-'struct' |
3559 | |-'ST' |
3560 | |-'{' |
3561 | |-'}' |
3562 | `-';' |
3563 | )txt" )); |
3564 | } |
3565 | |
3566 | TEST_P(BuildSyntaxTreeTest, FunctionTemplateDeclaration) { |
3567 | if (!GetParam().isCXX()) { |
3568 | return; |
3569 | } |
3570 | EXPECT_TRUE(treeDumpEqual( |
3571 | R"cpp( |
3572 | template<typename T> |
3573 | T f(); |
3574 | )cpp" , |
3575 | R"txt( |
3576 | TranslationUnit Detached |
3577 | `-TemplateDeclaration Declaration |
3578 | |-'template' IntroducerKeyword |
3579 | |-'<' |
3580 | |-UnknownDeclaration |
3581 | | |-'typename' |
3582 | | `-'T' |
3583 | |-'>' |
3584 | `-SimpleDeclaration |
3585 | |-'T' |
3586 | |-DeclaratorList Declarators |
3587 | | `-SimpleDeclarator ListElement |
3588 | | |-'f' |
3589 | | `-ParametersAndQualifiers |
3590 | | |-'(' OpenParen |
3591 | | `-')' CloseParen |
3592 | `-';' |
3593 | )txt" )); |
3594 | } |
3595 | |
3596 | TEST_P(BuildSyntaxTreeTest, VariableTemplateDeclaration) { |
3597 | if (!GetParam().isCXX14OrLater()) { |
3598 | return; |
3599 | } |
3600 | EXPECT_TRUE(treeDumpEqual( |
3601 | R"cpp( |
3602 | template <class T> T var = 10; |
3603 | )cpp" , |
3604 | R"txt( |
3605 | TranslationUnit Detached |
3606 | `-TemplateDeclaration Declaration |
3607 | |-'template' IntroducerKeyword |
3608 | |-'<' |
3609 | |-UnknownDeclaration |
3610 | | |-'class' |
3611 | | `-'T' |
3612 | |-'>' |
3613 | `-SimpleDeclaration |
3614 | |-'T' |
3615 | |-DeclaratorList Declarators |
3616 | | `-SimpleDeclarator ListElement |
3617 | | |-'var' |
3618 | | |-'=' |
3619 | | `-IntegerLiteralExpression |
3620 | | `-'10' LiteralToken |
3621 | `-';' |
3622 | )txt" )); |
3623 | } |
3624 | |
3625 | TEST_P(BuildSyntaxTreeTest, StaticMemberFunctionTemplate) { |
3626 | if (!GetParam().isCXX()) { |
3627 | return; |
3628 | } |
3629 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3630 | R"cpp( |
3631 | struct S { |
3632 | [[template<typename U> |
3633 | static U f();]] |
3634 | }; |
3635 | )cpp" , |
3636 | {R"txt( |
3637 | TemplateDeclaration Declaration |
3638 | |-'template' IntroducerKeyword |
3639 | |-'<' |
3640 | |-UnknownDeclaration |
3641 | | |-'typename' |
3642 | | `-'U' |
3643 | |-'>' |
3644 | `-SimpleDeclaration |
3645 | |-'static' |
3646 | |-'U' |
3647 | |-DeclaratorList Declarators |
3648 | | `-SimpleDeclarator ListElement |
3649 | | |-'f' |
3650 | | `-ParametersAndQualifiers |
3651 | | |-'(' OpenParen |
3652 | | `-')' CloseParen |
3653 | `-';' |
3654 | )txt" })); |
3655 | } |
3656 | |
3657 | TEST_P(BuildSyntaxTreeTest, NestedTemplates) { |
3658 | if (!GetParam().isCXX()) { |
3659 | return; |
3660 | } |
3661 | EXPECT_TRUE(treeDumpEqual( |
3662 | R"cpp( |
3663 | template <class T> |
3664 | struct X { |
3665 | template <class U> |
3666 | U foo(); |
3667 | }; |
3668 | )cpp" , |
3669 | R"txt( |
3670 | TranslationUnit Detached |
3671 | `-TemplateDeclaration Declaration |
3672 | |-'template' IntroducerKeyword |
3673 | |-'<' |
3674 | |-UnknownDeclaration |
3675 | | |-'class' |
3676 | | `-'T' |
3677 | |-'>' |
3678 | `-SimpleDeclaration |
3679 | |-'struct' |
3680 | |-'X' |
3681 | |-'{' |
3682 | |-TemplateDeclaration Declaration |
3683 | | |-'template' IntroducerKeyword |
3684 | | |-'<' |
3685 | | |-UnknownDeclaration |
3686 | | | |-'class' |
3687 | | | `-'U' |
3688 | | |-'>' |
3689 | | `-SimpleDeclaration |
3690 | | |-'U' |
3691 | | |-DeclaratorList Declarators |
3692 | | | `-SimpleDeclarator ListElement |
3693 | | | |-'foo' |
3694 | | | `-ParametersAndQualifiers |
3695 | | | |-'(' OpenParen |
3696 | | | `-')' CloseParen |
3697 | | `-';' |
3698 | |-'}' |
3699 | `-';' |
3700 | )txt" )); |
3701 | } |
3702 | |
3703 | TEST_P(BuildSyntaxTreeTest, NestedTemplatesInNamespace) { |
3704 | if (!GetParam().isCXX()) { |
3705 | return; |
3706 | } |
3707 | EXPECT_TRUE(treeDumpEqual( |
3708 | R"cpp( |
3709 | namespace n { |
3710 | template<typename T> |
3711 | struct ST { |
3712 | template<typename U> |
3713 | static U f(); |
3714 | }; |
3715 | } |
3716 | )cpp" , |
3717 | R"txt( |
3718 | TranslationUnit Detached |
3719 | `-NamespaceDefinition |
3720 | |-'namespace' |
3721 | |-'n' |
3722 | |-'{' |
3723 | |-TemplateDeclaration Declaration |
3724 | | |-'template' IntroducerKeyword |
3725 | | |-'<' |
3726 | | |-UnknownDeclaration |
3727 | | | |-'typename' |
3728 | | | `-'T' |
3729 | | |-'>' |
3730 | | `-SimpleDeclaration |
3731 | | |-'struct' |
3732 | | |-'ST' |
3733 | | |-'{' |
3734 | | |-TemplateDeclaration Declaration |
3735 | | | |-'template' IntroducerKeyword |
3736 | | | |-'<' |
3737 | | | |-UnknownDeclaration |
3738 | | | | |-'typename' |
3739 | | | | `-'U' |
3740 | | | |-'>' |
3741 | | | `-SimpleDeclaration |
3742 | | | |-'static' |
3743 | | | |-'U' |
3744 | | | |-DeclaratorList Declarators |
3745 | | | | `-SimpleDeclarator ListElement |
3746 | | | | |-'f' |
3747 | | | | `-ParametersAndQualifiers |
3748 | | | | |-'(' OpenParen |
3749 | | | | `-')' CloseParen |
3750 | | | `-';' |
3751 | | |-'}' |
3752 | | `-';' |
3753 | `-'}' |
3754 | )txt" )); |
3755 | } |
3756 | |
3757 | TEST_P(BuildSyntaxTreeTest, ClassTemplate_MemberClassDefinition) { |
3758 | if (!GetParam().isCXX()) { |
3759 | return; |
3760 | } |
3761 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3762 | R"cpp( |
3763 | template <class T> struct X { struct Y; }; |
3764 | [[template <class T> struct X<T>::Y {};]] |
3765 | )cpp" , |
3766 | {R"txt( |
3767 | TemplateDeclaration Declaration |
3768 | |-'template' IntroducerKeyword |
3769 | |-'<' |
3770 | |-UnknownDeclaration |
3771 | | |-'class' |
3772 | | `-'T' |
3773 | |-'>' |
3774 | `-SimpleDeclaration |
3775 | |-'struct' |
3776 | |-NestedNameSpecifier |
3777 | | |-SimpleTemplateNameSpecifier ListElement |
3778 | | | |-'X' |
3779 | | | |-'<' |
3780 | | | |-'T' |
3781 | | | `-'>' |
3782 | | `-'::' ListDelimiter |
3783 | |-'Y' |
3784 | |-'{' |
3785 | |-'}' |
3786 | `-';' |
3787 | )txt" })); |
3788 | } |
3789 | |
3790 | TEST_P(BuildSyntaxTreeTest, ExplicitClassTemplateInstantiation_Definition) { |
3791 | if (!GetParam().isCXX()) { |
3792 | return; |
3793 | } |
3794 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3795 | R"cpp( |
3796 | template <class T> struct X {}; |
3797 | [[template struct X<double>;]] |
3798 | )cpp" , |
3799 | {R"txt( |
3800 | ExplicitTemplateInstantiation |
3801 | |-'template' IntroducerKeyword |
3802 | `-SimpleDeclaration Declaration |
3803 | |-'struct' |
3804 | |-'X' |
3805 | |-'<' |
3806 | |-'double' |
3807 | |-'>' |
3808 | `-';' |
3809 | )txt" })); |
3810 | } |
3811 | |
3812 | TEST_P(BuildSyntaxTreeTest, ExplicitClassTemplateInstantiation_Declaration) { |
3813 | if (!GetParam().isCXX()) { |
3814 | return; |
3815 | } |
3816 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3817 | R"cpp( |
3818 | template <class T> struct X {}; |
3819 | [[extern template struct X<float>;]] |
3820 | )cpp" , |
3821 | {R"txt( |
3822 | ExplicitTemplateInstantiation |
3823 | |-'extern' ExternKeyword |
3824 | |-'template' IntroducerKeyword |
3825 | `-SimpleDeclaration Declaration |
3826 | |-'struct' |
3827 | |-'X' |
3828 | |-'<' |
3829 | |-'float' |
3830 | |-'>' |
3831 | `-';' |
3832 | )txt" })); |
3833 | } |
3834 | |
3835 | TEST_P(BuildSyntaxTreeTest, ClassTemplateSpecialization_Partial) { |
3836 | if (!GetParam().isCXX()) { |
3837 | return; |
3838 | } |
3839 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3840 | R"cpp( |
3841 | template <class T> struct X {}; |
3842 | [[template <class T> struct X<T*> {};]] |
3843 | )cpp" , |
3844 | {R"txt( |
3845 | TemplateDeclaration Declaration |
3846 | |-'template' IntroducerKeyword |
3847 | |-'<' |
3848 | |-UnknownDeclaration |
3849 | | |-'class' |
3850 | | `-'T' |
3851 | |-'>' |
3852 | `-SimpleDeclaration |
3853 | |-'struct' |
3854 | |-'X' |
3855 | |-'<' |
3856 | |-'T' |
3857 | |-'*' |
3858 | |-'>' |
3859 | |-'{' |
3860 | |-'}' |
3861 | `-';' |
3862 | )txt" })); |
3863 | } |
3864 | |
3865 | TEST_P(BuildSyntaxTreeTest, ClassTemplateSpecialization_Full) { |
3866 | if (!GetParam().isCXX()) { |
3867 | return; |
3868 | } |
3869 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
3870 | R"cpp( |
3871 | template <class T> struct X {}; |
3872 | [[template <> struct X<int> {};]] |
3873 | )cpp" , |
3874 | {R"txt( |
3875 | TemplateDeclaration Declaration |
3876 | |-'template' IntroducerKeyword |
3877 | |-'<' |
3878 | |-'>' |
3879 | `-SimpleDeclaration |
3880 | |-'struct' |
3881 | |-'X' |
3882 | |-'<' |
3883 | |-'int' |
3884 | |-'>' |
3885 | |-'{' |
3886 | |-'}' |
3887 | `-';' |
3888 | )txt" })); |
3889 | } |
3890 | |
3891 | TEST_P(BuildSyntaxTreeTest, EmptyDeclaration) { |
3892 | EXPECT_TRUE(treeDumpEqual( |
3893 | R"cpp( |
3894 | ; |
3895 | )cpp" , |
3896 | R"txt( |
3897 | TranslationUnit Detached |
3898 | `-EmptyDeclaration |
3899 | `-';' |
3900 | )txt" )); |
3901 | } |
3902 | |
3903 | TEST_P(BuildSyntaxTreeTest, StaticAssert) { |
3904 | if (!GetParam().isCXX11OrLater()) { |
3905 | return; |
3906 | } |
3907 | EXPECT_TRUE(treeDumpEqual( |
3908 | R"cpp( |
3909 | static_assert(true, "message"); |
3910 | )cpp" , |
3911 | R"txt( |
3912 | TranslationUnit Detached |
3913 | `-StaticAssertDeclaration |
3914 | |-'static_assert' |
3915 | |-'(' |
3916 | |-BoolLiteralExpression Condition |
3917 | | `-'true' LiteralToken |
3918 | |-',' |
3919 | |-StringLiteralExpression Message |
3920 | | `-'"message"' LiteralToken |
3921 | |-')' |
3922 | `-';' |
3923 | )txt" )); |
3924 | } |
3925 | |
3926 | TEST_P(BuildSyntaxTreeTest, StaticAssert_WithoutMessage) { |
3927 | if (!GetParam().isCXX17OrLater()) { |
3928 | return; |
3929 | } |
3930 | EXPECT_TRUE(treeDumpEqual( |
3931 | R"cpp( |
3932 | static_assert(true); |
3933 | )cpp" , |
3934 | R"txt( |
3935 | TranslationUnit Detached |
3936 | `-StaticAssertDeclaration |
3937 | |-'static_assert' |
3938 | |-'(' |
3939 | |-BoolLiteralExpression Condition |
3940 | | `-'true' LiteralToken |
3941 | |-')' |
3942 | `-';' |
3943 | )txt" )); |
3944 | } |
3945 | |
3946 | TEST_P(BuildSyntaxTreeTest, ExternC) { |
3947 | if (!GetParam().isCXX()) { |
3948 | return; |
3949 | } |
3950 | EXPECT_TRUE(treeDumpEqual( |
3951 | R"cpp( |
3952 | extern "C" int a; |
3953 | extern "C" { int b; int c; } |
3954 | )cpp" , |
3955 | R"txt( |
3956 | TranslationUnit Detached |
3957 | |-LinkageSpecificationDeclaration |
3958 | | |-'extern' |
3959 | | |-'"C"' |
3960 | | `-SimpleDeclaration |
3961 | | |-'int' |
3962 | | |-DeclaratorList Declarators |
3963 | | | `-SimpleDeclarator ListElement |
3964 | | | `-'a' |
3965 | | `-';' |
3966 | `-LinkageSpecificationDeclaration |
3967 | |-'extern' |
3968 | |-'"C"' |
3969 | |-'{' |
3970 | |-SimpleDeclaration |
3971 | | |-'int' |
3972 | | |-DeclaratorList Declarators |
3973 | | | `-SimpleDeclarator ListElement |
3974 | | | `-'b' |
3975 | | `-';' |
3976 | |-SimpleDeclaration |
3977 | | |-'int' |
3978 | | |-DeclaratorList Declarators |
3979 | | | `-SimpleDeclarator ListElement |
3980 | | | `-'c' |
3981 | | `-';' |
3982 | `-'}' |
3983 | )txt" )); |
3984 | } |
3985 | |
3986 | TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_Leaf) { |
3987 | // All nodes can be mutated. |
3988 | EXPECT_TRUE(treeDumpEqual( |
3989 | R"cpp( |
3990 | #define OPEN { |
3991 | #define CLOSE } |
3992 | |
3993 | void test() { |
3994 | OPEN |
3995 | 1; |
3996 | CLOSE |
3997 | |
3998 | OPEN |
3999 | 2; |
4000 | } |
4001 | } |
4002 | )cpp" , |
4003 | R"txt( |
4004 | TranslationUnit Detached |
4005 | `-SimpleDeclaration |
4006 | |-'void' |
4007 | |-DeclaratorList Declarators |
4008 | | `-SimpleDeclarator ListElement |
4009 | | |-'test' |
4010 | | `-ParametersAndQualifiers |
4011 | | |-'(' OpenParen |
4012 | | `-')' CloseParen |
4013 | `-CompoundStatement |
4014 | |-'{' OpenParen |
4015 | |-CompoundStatement Statement |
4016 | | |-'{' OpenParen |
4017 | | |-ExpressionStatement Statement |
4018 | | | |-IntegerLiteralExpression Expression |
4019 | | | | `-'1' LiteralToken |
4020 | | | `-';' |
4021 | | `-'}' CloseParen |
4022 | |-CompoundStatement Statement |
4023 | | |-'{' OpenParen |
4024 | | |-ExpressionStatement Statement |
4025 | | | |-IntegerLiteralExpression Expression |
4026 | | | | `-'2' LiteralToken |
4027 | | | `-';' |
4028 | | `-'}' CloseParen |
4029 | `-'}' CloseParen |
4030 | )txt" )); |
4031 | } |
4032 | |
4033 | TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MatchTree) { |
4034 | // Some nodes are unmodifiable, they are marked with 'unmodifiable'. |
4035 | EXPECT_TRUE(treeDumpEqual( |
4036 | R"cpp( |
4037 | #define BRACES {} |
4038 | |
4039 | void test() BRACES |
4040 | )cpp" , |
4041 | R"txt( |
4042 | TranslationUnit Detached |
4043 | `-SimpleDeclaration |
4044 | |-'void' |
4045 | |-DeclaratorList Declarators |
4046 | | `-SimpleDeclarator ListElement |
4047 | | |-'test' |
4048 | | `-ParametersAndQualifiers |
4049 | | |-'(' OpenParen |
4050 | | `-')' CloseParen |
4051 | `-CompoundStatement |
4052 | |-'{' OpenParen unmodifiable |
4053 | `-'}' CloseParen unmodifiable |
4054 | )txt" )); |
4055 | } |
4056 | |
4057 | TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MismatchTree) { |
4058 | EXPECT_TRUE(treeDumpEqual( |
4059 | R"cpp( |
4060 | #define HALF_IF if (1+ |
4061 | #define HALF_IF_2 1) {} |
4062 | void test() { |
4063 | HALF_IF HALF_IF_2 else {} |
4064 | })cpp" , |
4065 | R"txt( |
4066 | TranslationUnit Detached |
4067 | `-SimpleDeclaration |
4068 | |-'void' |
4069 | |-DeclaratorList Declarators |
4070 | | `-SimpleDeclarator ListElement |
4071 | | |-'test' |
4072 | | `-ParametersAndQualifiers |
4073 | | |-'(' OpenParen |
4074 | | `-')' CloseParen |
4075 | `-CompoundStatement |
4076 | |-'{' OpenParen |
4077 | |-IfStatement Statement |
4078 | | |-'if' IntroducerKeyword unmodifiable |
4079 | | |-'(' unmodifiable |
4080 | | |-ExpressionStatement Condition unmodifiable |
4081 | | | `-BinaryOperatorExpression Expression unmodifiable |
4082 | | | |-IntegerLiteralExpression LeftHandSide unmodifiable |
4083 | | | | `-'1' LiteralToken unmodifiable |
4084 | | | |-'+' OperatorToken unmodifiable |
4085 | | | `-IntegerLiteralExpression RightHandSide unmodifiable |
4086 | | | `-'1' LiteralToken unmodifiable |
4087 | | |-')' unmodifiable |
4088 | | |-CompoundStatement ThenStatement unmodifiable |
4089 | | | |-'{' OpenParen unmodifiable |
4090 | | | `-'}' CloseParen unmodifiable |
4091 | | |-'else' ElseKeyword |
4092 | | `-CompoundStatement ElseStatement |
4093 | | |-'{' OpenParen |
4094 | | `-'}' CloseParen |
4095 | `-'}' CloseParen |
4096 | )txt" )); |
4097 | } |
4098 | |
4099 | TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_ModifiableArguments) { |
4100 | // FIXME: Note that the substitutions for `X` and `Y` are marked modifiable. |
4101 | // However we cannot change `X` freely. Indeed if we change its substitution |
4102 | // in the condition we should also change it the then-branch. |
4103 | EXPECT_TRUE(treeDumpEqual( |
4104 | R"cpp( |
4105 | #define MIN(X,Y) X < Y ? X : Y |
4106 | |
4107 | void test() { |
4108 | MIN(1,2); |
4109 | } |
4110 | )cpp" , |
4111 | R"txt( |
4112 | TranslationUnit Detached |
4113 | `-SimpleDeclaration |
4114 | |-'void' |
4115 | |-DeclaratorList Declarators |
4116 | | `-SimpleDeclarator ListElement |
4117 | | |-'test' |
4118 | | `-ParametersAndQualifiers |
4119 | | |-'(' OpenParen |
4120 | | `-')' CloseParen |
4121 | `-CompoundStatement |
4122 | |-'{' OpenParen |
4123 | |-ExpressionStatement Statement |
4124 | | |-UnknownExpression Expression |
4125 | | | |-BinaryOperatorExpression unmodifiable |
4126 | | | | |-IntegerLiteralExpression LeftHandSide |
4127 | | | | | `-'1' LiteralToken |
4128 | | | | |-'<' OperatorToken unmodifiable |
4129 | | | | `-IntegerLiteralExpression RightHandSide |
4130 | | | | `-'2' LiteralToken |
4131 | | | |-'?' unmodifiable |
4132 | | | |-IntegerLiteralExpression |
4133 | | | | `-'1' LiteralToken |
4134 | | | |-':' unmodifiable |
4135 | | | `-IntegerLiteralExpression |
4136 | | | `-'2' LiteralToken |
4137 | | `-';' |
4138 | `-'}' CloseParen |
4139 | )txt" )); |
4140 | } |
4141 | |
4142 | TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_MismatchTree) { |
4143 | EXPECT_TRUE(treeDumpEqual( |
4144 | R"cpp( |
4145 | #define HALF_IF(X) if (X && |
4146 | #define HALF_IF_2(Y) Y) {} |
4147 | void test() { |
4148 | HALF_IF(1) HALF_IF_2(0) else {} |
4149 | })cpp" , |
4150 | R"txt( |
4151 | TranslationUnit Detached |
4152 | `-SimpleDeclaration |
4153 | |-'void' |
4154 | |-DeclaratorList Declarators |
4155 | | `-SimpleDeclarator ListElement |
4156 | | |-'test' |
4157 | | `-ParametersAndQualifiers |
4158 | | |-'(' OpenParen |
4159 | | `-')' CloseParen |
4160 | `-CompoundStatement |
4161 | |-'{' OpenParen |
4162 | |-IfStatement Statement |
4163 | | |-'if' IntroducerKeyword unmodifiable |
4164 | | |-'(' unmodifiable |
4165 | | |-ExpressionStatement Condition unmodifiable |
4166 | | | `-BinaryOperatorExpression Expression unmodifiable |
4167 | | | |-IntegerLiteralExpression LeftHandSide |
4168 | | | | `-'1' LiteralToken |
4169 | | | |-'&&' OperatorToken unmodifiable |
4170 | | | `-IntegerLiteralExpression RightHandSide |
4171 | | | `-'0' LiteralToken |
4172 | | |-')' unmodifiable |
4173 | | |-CompoundStatement ThenStatement unmodifiable |
4174 | | | |-'{' OpenParen unmodifiable |
4175 | | | `-'}' CloseParen unmodifiable |
4176 | | |-'else' ElseKeyword |
4177 | | `-CompoundStatement ElseStatement |
4178 | | |-'{' OpenParen |
4179 | | `-'}' CloseParen |
4180 | `-'}' CloseParen |
4181 | )txt" )); |
4182 | } |
4183 | |
4184 | TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_Variadic) { |
4185 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4186 | R"cpp( |
4187 | #define CALL(F_NAME, ...) F_NAME(__VA_ARGS__) |
4188 | |
4189 | void f(int); |
4190 | void g(int, int); |
4191 | void test() [[{ |
4192 | CALL(f, 0); |
4193 | CALL(g, 0, 1); |
4194 | }]] |
4195 | )cpp" , |
4196 | {R"txt( |
4197 | CompoundStatement |
4198 | |-'{' OpenParen |
4199 | |-ExpressionStatement Statement |
4200 | | |-CallExpression Expression |
4201 | | | |-IdExpression Callee |
4202 | | | | `-UnqualifiedId UnqualifiedId |
4203 | | | | `-'f' |
4204 | | | |-'(' OpenParen unmodifiable |
4205 | | | |-CallArguments Arguments |
4206 | | | | `-IntegerLiteralExpression ListElement |
4207 | | | | `-'0' LiteralToken |
4208 | | | `-')' CloseParen unmodifiable |
4209 | | `-';' |
4210 | |-ExpressionStatement Statement |
4211 | | |-CallExpression Expression |
4212 | | | |-IdExpression Callee |
4213 | | | | `-UnqualifiedId UnqualifiedId |
4214 | | | | `-'g' |
4215 | | | |-'(' OpenParen unmodifiable |
4216 | | | |-CallArguments Arguments |
4217 | | | | |-IntegerLiteralExpression ListElement |
4218 | | | | | `-'0' LiteralToken |
4219 | | | | |-',' ListDelimiter |
4220 | | | | `-IntegerLiteralExpression ListElement |
4221 | | | | `-'1' LiteralToken |
4222 | | | `-')' CloseParen unmodifiable |
4223 | | `-';' |
4224 | `-'}' CloseParen |
4225 | )txt" })); |
4226 | } |
4227 | |
4228 | TEST_P(BuildSyntaxTreeTest, InitDeclarator_Equal) { |
4229 | if (!GetParam().isCXX()) { |
4230 | return; |
4231 | } |
4232 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4233 | R"cpp( |
4234 | struct S { S(int);}; |
4235 | void test() { |
4236 | [[S s = 1]]; |
4237 | } |
4238 | )cpp" , |
4239 | {R"txt( |
4240 | SimpleDeclaration |
4241 | |-'S' |
4242 | `-DeclaratorList Declarators |
4243 | `-SimpleDeclarator ListElement |
4244 | |-'s' |
4245 | |-'=' |
4246 | `-IntegerLiteralExpression |
4247 | `-'1' LiteralToken |
4248 | )txt" })); |
4249 | } |
4250 | |
4251 | TEST_P(BuildSyntaxTreeTest, InitDeclarator_Brace) { |
4252 | if (!GetParam().isCXX11OrLater()) { |
4253 | return; |
4254 | } |
4255 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4256 | R"cpp( |
4257 | struct S { |
4258 | S(); |
4259 | S(int); |
4260 | S(int, float); |
4261 | }; |
4262 | void test(){ |
4263 | // FIXME: 's...' is a declarator and '{...}' is initializer |
4264 | [[S s0{}]]; |
4265 | [[S s1{1}]]; |
4266 | [[S s2{1, 2.}]]; |
4267 | } |
4268 | )cpp" , |
4269 | {R"txt( |
4270 | SimpleDeclaration |
4271 | |-'S' |
4272 | `-DeclaratorList Declarators |
4273 | `-SimpleDeclarator ListElement |
4274 | `-UnknownExpression |
4275 | |-'s0' |
4276 | |-'{' |
4277 | `-'}' |
4278 | )txt" , |
4279 | R"txt( |
4280 | SimpleDeclaration |
4281 | |-'S' |
4282 | `-DeclaratorList Declarators |
4283 | `-SimpleDeclarator ListElement |
4284 | `-UnknownExpression |
4285 | |-'s1' |
4286 | |-'{' |
4287 | |-IntegerLiteralExpression |
4288 | | `-'1' LiteralToken |
4289 | `-'}' |
4290 | )txt" , |
4291 | R"txt( |
4292 | SimpleDeclaration |
4293 | |-'S' |
4294 | `-DeclaratorList Declarators |
4295 | `-SimpleDeclarator ListElement |
4296 | `-UnknownExpression |
4297 | |-'s2' |
4298 | |-'{' |
4299 | |-IntegerLiteralExpression |
4300 | | `-'1' LiteralToken |
4301 | |-',' |
4302 | |-FloatingLiteralExpression |
4303 | | `-'2.' LiteralToken |
4304 | `-'}' |
4305 | )txt" })); |
4306 | } |
4307 | |
4308 | TEST_P(BuildSyntaxTreeTest, InitDeclarator_EqualBrace) { |
4309 | if (!GetParam().isCXX11OrLater()) { |
4310 | return; |
4311 | } |
4312 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4313 | R"cpp( |
4314 | struct S { |
4315 | S(); |
4316 | S(int); |
4317 | S(int, float); |
4318 | }; |
4319 | void test() { |
4320 | // FIXME: '= {...}' is initializer |
4321 | [[S s0 = {}]]; |
4322 | [[S s1 = {1}]]; |
4323 | [[S s2 = {1, 2.}]]; |
4324 | } |
4325 | )cpp" , |
4326 | {R"txt( |
4327 | SimpleDeclaration |
4328 | |-'S' |
4329 | `-DeclaratorList Declarators |
4330 | `-SimpleDeclarator ListElement |
4331 | |-'s0' |
4332 | |-'=' |
4333 | `-UnknownExpression |
4334 | |-'{' |
4335 | `-'}' |
4336 | )txt" , |
4337 | R"txt( |
4338 | SimpleDeclaration |
4339 | |-'S' |
4340 | `-DeclaratorList Declarators |
4341 | `-SimpleDeclarator ListElement |
4342 | |-'s1' |
4343 | |-'=' |
4344 | `-UnknownExpression |
4345 | |-'{' |
4346 | |-IntegerLiteralExpression |
4347 | | `-'1' LiteralToken |
4348 | `-'}' |
4349 | )txt" , |
4350 | R"txt( |
4351 | SimpleDeclaration |
4352 | |-'S' |
4353 | `-DeclaratorList Declarators |
4354 | `-SimpleDeclarator ListElement |
4355 | |-'s2' |
4356 | |-'=' |
4357 | `-UnknownExpression |
4358 | |-'{' |
4359 | |-IntegerLiteralExpression |
4360 | | `-'1' LiteralToken |
4361 | |-',' |
4362 | |-FloatingLiteralExpression |
4363 | | `-'2.' LiteralToken |
4364 | `-'}' |
4365 | )txt" })); |
4366 | } |
4367 | |
4368 | TEST_P(BuildSyntaxTreeTest, InitDeclarator_Paren) { |
4369 | if (!GetParam().isCXX()) { |
4370 | return; |
4371 | } |
4372 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4373 | R"cpp( |
4374 | struct S { |
4375 | S(int); |
4376 | S(int, float); |
4377 | }; |
4378 | // FIXME: 's...' is a declarator and '(...)' is initializer |
4379 | [[S s1(1);]] |
4380 | [[S s2(1, 2.);]] |
4381 | )cpp" , |
4382 | {R"txt( |
4383 | SimpleDeclaration |
4384 | |-'S' |
4385 | |-DeclaratorList Declarators |
4386 | | `-SimpleDeclarator ListElement |
4387 | | `-UnknownExpression |
4388 | | |-'s1' |
4389 | | |-'(' |
4390 | | |-IntegerLiteralExpression |
4391 | | | `-'1' LiteralToken |
4392 | | `-')' |
4393 | `-';' |
4394 | )txt" , |
4395 | R"txt( |
4396 | SimpleDeclaration |
4397 | |-'S' |
4398 | |-DeclaratorList Declarators |
4399 | | `-SimpleDeclarator ListElement |
4400 | | `-UnknownExpression |
4401 | | |-'s2' |
4402 | | |-'(' |
4403 | | |-IntegerLiteralExpression |
4404 | | | `-'1' LiteralToken |
4405 | | |-',' |
4406 | | |-FloatingLiteralExpression |
4407 | | | `-'2.' LiteralToken |
4408 | | `-')' |
4409 | `-';' |
4410 | )txt" })); |
4411 | } |
4412 | |
4413 | TEST_P(BuildSyntaxTreeTest, InitDeclarator_Paren_DefaultArguments) { |
4414 | if (!GetParam().isCXX()) { |
4415 | return; |
4416 | } |
4417 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4418 | R"cpp( |
4419 | struct S { |
4420 | S(int i = 1, float = 2.); |
4421 | }; |
4422 | [[S s0;]] |
4423 | // FIXME: 's...' is a declarator and '(...)' is initializer |
4424 | [[S s1(1);]] |
4425 | [[S s2(1, 2.);]] |
4426 | )cpp" , |
4427 | {R"txt( |
4428 | SimpleDeclaration |
4429 | |-'S' |
4430 | |-DeclaratorList Declarators |
4431 | | `-SimpleDeclarator ListElement |
4432 | | `-'s0' |
4433 | `-';' |
4434 | )txt" , |
4435 | R"txt( |
4436 | SimpleDeclaration |
4437 | |-'S' |
4438 | |-DeclaratorList Declarators |
4439 | | `-SimpleDeclarator ListElement |
4440 | | `-UnknownExpression |
4441 | | |-'s1' |
4442 | | |-'(' |
4443 | | |-IntegerLiteralExpression |
4444 | | | `-'1' LiteralToken |
4445 | | `-')' |
4446 | `-';' |
4447 | )txt" , |
4448 | R"txt( |
4449 | SimpleDeclaration |
4450 | |-'S' |
4451 | |-DeclaratorList Declarators |
4452 | | `-SimpleDeclarator ListElement |
4453 | | `-UnknownExpression |
4454 | | |-'s2' |
4455 | | |-'(' |
4456 | | |-IntegerLiteralExpression |
4457 | | | `-'1' LiteralToken |
4458 | | |-',' |
4459 | | |-FloatingLiteralExpression |
4460 | | | `-'2.' LiteralToken |
4461 | | `-')' |
4462 | `-';' |
4463 | )txt" })); |
4464 | } |
4465 | |
4466 | TEST_P(BuildSyntaxTreeTest, ImplicitConversion_Argument) { |
4467 | if (!GetParam().isCXX()) { |
4468 | return; |
4469 | } |
4470 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4471 | R"cpp( |
4472 | struct X { |
4473 | X(int); |
4474 | }; |
4475 | void TakeX(const X&); |
4476 | void test() { |
4477 | [[TakeX(1)]]; |
4478 | } |
4479 | )cpp" , |
4480 | {R"txt( |
4481 | CallExpression Expression |
4482 | |-IdExpression Callee |
4483 | | `-UnqualifiedId UnqualifiedId |
4484 | | `-'TakeX' |
4485 | |-'(' OpenParen |
4486 | |-CallArguments Arguments |
4487 | | `-IntegerLiteralExpression ListElement |
4488 | | `-'1' LiteralToken |
4489 | `-')' CloseParen |
4490 | )txt" })); |
4491 | } |
4492 | |
4493 | TEST_P(BuildSyntaxTreeTest, ImplicitConversion_Return) { |
4494 | if (!GetParam().isCXX()) { |
4495 | return; |
4496 | } |
4497 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4498 | R"cpp( |
4499 | struct X { |
4500 | X(int); |
4501 | }; |
4502 | X CreateX(){ |
4503 | [[return 1;]] |
4504 | } |
4505 | )cpp" , |
4506 | {R"txt( |
4507 | ReturnStatement Statement |
4508 | |-'return' IntroducerKeyword |
4509 | |-IntegerLiteralExpression ReturnValue |
4510 | | `-'1' LiteralToken |
4511 | `-';' |
4512 | )txt" })); |
4513 | } |
4514 | |
4515 | TEST_P(BuildSyntaxTreeTest, ConstructorCall_ZeroArguments) { |
4516 | if (!GetParam().isCXX()) { |
4517 | return; |
4518 | } |
4519 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4520 | R"cpp( |
4521 | struct X { |
4522 | X(); |
4523 | }; |
4524 | X test() { |
4525 | [[return X();]] |
4526 | } |
4527 | )cpp" , |
4528 | {R"txt( |
4529 | ReturnStatement Statement |
4530 | |-'return' IntroducerKeyword |
4531 | |-UnknownExpression ReturnValue |
4532 | | |-'X' |
4533 | | |-'(' |
4534 | | `-')' |
4535 | `-';' |
4536 | )txt" })); |
4537 | } |
4538 | |
4539 | TEST_P(BuildSyntaxTreeTest, ConstructorCall_OneArgument) { |
4540 | if (!GetParam().isCXX()) { |
4541 | return; |
4542 | } |
4543 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4544 | R"cpp( |
4545 | struct X { |
4546 | X(int); |
4547 | }; |
4548 | X test() { |
4549 | [[return X(1);]] |
4550 | } |
4551 | )cpp" , |
4552 | {R"txt( |
4553 | ReturnStatement Statement |
4554 | |-'return' IntroducerKeyword |
4555 | |-UnknownExpression ReturnValue |
4556 | | |-'X' |
4557 | | |-'(' |
4558 | | |-IntegerLiteralExpression |
4559 | | | `-'1' LiteralToken |
4560 | | `-')' |
4561 | `-';' |
4562 | )txt" })); |
4563 | } |
4564 | |
4565 | TEST_P(BuildSyntaxTreeTest, ConstructorCall_MultipleArguments) { |
4566 | if (!GetParam().isCXX()) { |
4567 | return; |
4568 | } |
4569 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4570 | R"cpp( |
4571 | struct X { |
4572 | X(int, char); |
4573 | }; |
4574 | X test() { |
4575 | [[return X(1, '2');]] |
4576 | } |
4577 | )cpp" , |
4578 | {R"txt( |
4579 | ReturnStatement Statement |
4580 | |-'return' IntroducerKeyword |
4581 | |-UnknownExpression ReturnValue |
4582 | | |-'X' |
4583 | | |-'(' |
4584 | | |-IntegerLiteralExpression |
4585 | | | `-'1' LiteralToken |
4586 | | |-',' |
4587 | | |-CharacterLiteralExpression |
4588 | | | `-''2'' LiteralToken |
4589 | | `-')' |
4590 | `-';' |
4591 | )txt" })); |
4592 | } |
4593 | |
4594 | TEST_P(BuildSyntaxTreeTest, ConstructorCall_DefaultArguments) { |
4595 | if (!GetParam().isCXX()) { |
4596 | return; |
4597 | } |
4598 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4599 | R"cpp( |
4600 | struct X { |
4601 | X(int i = 1, char c = '2'); |
4602 | }; |
4603 | X test() { |
4604 | auto x0 = [[X()]]; |
4605 | auto x1 = [[X(1)]]; |
4606 | auto x2 = [[X(1, '2')]]; |
4607 | } |
4608 | )cpp" , |
4609 | {R"txt( |
4610 | UnknownExpression |
4611 | |-'X' |
4612 | |-'(' |
4613 | `-')' |
4614 | )txt" , |
4615 | R"txt( |
4616 | UnknownExpression |
4617 | |-'X' |
4618 | |-'(' |
4619 | |-IntegerLiteralExpression |
4620 | | `-'1' LiteralToken |
4621 | `-')' |
4622 | )txt" , |
4623 | R"txt( |
4624 | UnknownExpression |
4625 | |-'X' |
4626 | |-'(' |
4627 | |-IntegerLiteralExpression |
4628 | | `-'1' LiteralToken |
4629 | |-',' |
4630 | |-CharacterLiteralExpression |
4631 | | `-''2'' LiteralToken |
4632 | `-')' |
4633 | )txt" })); |
4634 | } |
4635 | |
4636 | TEST_P(BuildSyntaxTreeTest, TypeConversion_FunctionalNotation) { |
4637 | if (!GetParam().isCXX()) { |
4638 | return; |
4639 | } |
4640 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4641 | R"cpp( |
4642 | float test() { |
4643 | [[return float(1);]] |
4644 | } |
4645 | )cpp" , |
4646 | {R"txt( |
4647 | ReturnStatement Statement |
4648 | |-'return' IntroducerKeyword |
4649 | |-UnknownExpression ReturnValue |
4650 | | |-'float' |
4651 | | |-'(' |
4652 | | |-IntegerLiteralExpression |
4653 | | | `-'1' LiteralToken |
4654 | | `-')' |
4655 | `-';' |
4656 | )txt" })); |
4657 | } |
4658 | |
4659 | TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Simple) { |
4660 | EXPECT_TRUE(treeDumpEqual( |
4661 | R"cpp( |
4662 | int a[10]; |
4663 | )cpp" , |
4664 | R"txt( |
4665 | TranslationUnit Detached |
4666 | `-SimpleDeclaration |
4667 | |-'int' |
4668 | |-DeclaratorList Declarators |
4669 | | `-SimpleDeclarator ListElement |
4670 | | |-'a' |
4671 | | `-ArraySubscript |
4672 | | |-'[' OpenParen |
4673 | | |-IntegerLiteralExpression Size |
4674 | | | `-'10' LiteralToken |
4675 | | `-']' CloseParen |
4676 | `-';' |
4677 | )txt" )); |
4678 | } |
4679 | |
4680 | TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Multidimensional) { |
4681 | EXPECT_TRUE(treeDumpEqual( |
4682 | R"cpp( |
4683 | int b[1][2][3]; |
4684 | )cpp" , |
4685 | R"txt( |
4686 | TranslationUnit Detached |
4687 | `-SimpleDeclaration |
4688 | |-'int' |
4689 | |-DeclaratorList Declarators |
4690 | | `-SimpleDeclarator ListElement |
4691 | | |-'b' |
4692 | | |-ArraySubscript |
4693 | | | |-'[' OpenParen |
4694 | | | |-IntegerLiteralExpression Size |
4695 | | | | `-'1' LiteralToken |
4696 | | | `-']' CloseParen |
4697 | | |-ArraySubscript |
4698 | | | |-'[' OpenParen |
4699 | | | |-IntegerLiteralExpression Size |
4700 | | | | `-'2' LiteralToken |
4701 | | | `-']' CloseParen |
4702 | | `-ArraySubscript |
4703 | | |-'[' OpenParen |
4704 | | |-IntegerLiteralExpression Size |
4705 | | | `-'3' LiteralToken |
4706 | | `-']' CloseParen |
4707 | `-';' |
4708 | )txt" )); |
4709 | } |
4710 | |
4711 | TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_UnknownBound) { |
4712 | EXPECT_TRUE(treeDumpEqual( |
4713 | R"cpp( |
4714 | int c[] = {1,2,3}; |
4715 | )cpp" , |
4716 | R"txt( |
4717 | TranslationUnit Detached |
4718 | `-SimpleDeclaration |
4719 | |-'int' |
4720 | |-DeclaratorList Declarators |
4721 | | `-SimpleDeclarator ListElement |
4722 | | |-'c' |
4723 | | |-ArraySubscript |
4724 | | | |-'[' OpenParen |
4725 | | | `-']' CloseParen |
4726 | | |-'=' |
4727 | | `-UnknownExpression |
4728 | | `-UnknownExpression |
4729 | | |-'{' |
4730 | | |-IntegerLiteralExpression |
4731 | | | `-'1' LiteralToken |
4732 | | |-',' |
4733 | | |-IntegerLiteralExpression |
4734 | | | `-'2' LiteralToken |
4735 | | |-',' |
4736 | | |-IntegerLiteralExpression |
4737 | | | `-'3' LiteralToken |
4738 | | `-'}' |
4739 | `-';' |
4740 | )txt" )); |
4741 | } |
4742 | |
4743 | TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Static) { |
4744 | if (!GetParam().isC99OrLater()) { |
4745 | return; |
4746 | } |
4747 | EXPECT_TRUE(treeDumpEqual( |
4748 | R"cpp( |
4749 | void f(int xs[static 10]); |
4750 | )cpp" , |
4751 | R"txt( |
4752 | TranslationUnit Detached |
4753 | `-SimpleDeclaration |
4754 | |-'void' |
4755 | |-DeclaratorList Declarators |
4756 | | `-SimpleDeclarator ListElement |
4757 | | |-'f' |
4758 | | `-ParametersAndQualifiers |
4759 | | |-'(' OpenParen |
4760 | | |-ParameterDeclarationList Parameters |
4761 | | | `-SimpleDeclaration ListElement |
4762 | | | |-'int' |
4763 | | | `-DeclaratorList Declarators |
4764 | | | `-SimpleDeclarator ListElement |
4765 | | | |-'xs' |
4766 | | | `-ArraySubscript |
4767 | | | |-'[' OpenParen |
4768 | | | |-'static' |
4769 | | | |-IntegerLiteralExpression Size |
4770 | | | | `-'10' LiteralToken |
4771 | | | `-']' CloseParen |
4772 | | `-')' CloseParen |
4773 | `-';' |
4774 | )txt" )); |
4775 | } |
4776 | |
4777 | TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Empty) { |
4778 | EXPECT_TRUE(treeDumpEqual( |
4779 | R"cpp( |
4780 | int func(); |
4781 | )cpp" , |
4782 | R"txt( |
4783 | TranslationUnit Detached |
4784 | `-SimpleDeclaration |
4785 | |-'int' |
4786 | |-DeclaratorList Declarators |
4787 | | `-SimpleDeclarator ListElement |
4788 | | |-'func' |
4789 | | `-ParametersAndQualifiers |
4790 | | |-'(' OpenParen |
4791 | | `-')' CloseParen |
4792 | `-';' |
4793 | )txt" )); |
4794 | } |
4795 | |
4796 | TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Named) { |
4797 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4798 | R"cpp( |
4799 | int func1([[int a]]); |
4800 | int func2([[int *ap]]); |
4801 | int func3([[int a, float b]]); |
4802 | int func4([[undef a]]); // error-ok: no crash on invalid type |
4803 | )cpp" , |
4804 | {R"txt( |
4805 | ParameterDeclarationList Parameters |
4806 | `-SimpleDeclaration ListElement |
4807 | |-'int' |
4808 | `-DeclaratorList Declarators |
4809 | `-SimpleDeclarator ListElement |
4810 | `-'a' |
4811 | )txt" , |
4812 | R"txt( |
4813 | ParameterDeclarationList Parameters |
4814 | `-SimpleDeclaration ListElement |
4815 | |-'int' |
4816 | `-DeclaratorList Declarators |
4817 | `-SimpleDeclarator ListElement |
4818 | |-'*' |
4819 | `-'ap' |
4820 | )txt" , |
4821 | R"txt( |
4822 | ParameterDeclarationList Parameters |
4823 | |-SimpleDeclaration ListElement |
4824 | | |-'int' |
4825 | | `-DeclaratorList Declarators |
4826 | | `-SimpleDeclarator ListElement |
4827 | | `-'a' |
4828 | |-',' ListDelimiter |
4829 | `-SimpleDeclaration ListElement |
4830 | |-'float' |
4831 | `-DeclaratorList Declarators |
4832 | `-SimpleDeclarator ListElement |
4833 | `-'b' |
4834 | )txt" , |
4835 | R"txt( |
4836 | ParameterDeclarationList Parameters |
4837 | `-SimpleDeclaration ListElement |
4838 | |-'undef' |
4839 | `-DeclaratorList Declarators |
4840 | `-SimpleDeclarator ListElement |
4841 | `-'a' |
4842 | )txt" })); |
4843 | } |
4844 | |
4845 | TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Unnamed) { |
4846 | EXPECT_TRUE(treeDumpEqual( |
4847 | R"cpp( |
4848 | int func1(int); |
4849 | int func2(int *); |
4850 | int func3(int, float); |
4851 | )cpp" , |
4852 | R"txt( |
4853 | TranslationUnit Detached |
4854 | |-SimpleDeclaration |
4855 | | |-'int' |
4856 | | |-DeclaratorList Declarators |
4857 | | | `-SimpleDeclarator ListElement |
4858 | | | |-'func1' |
4859 | | | `-ParametersAndQualifiers |
4860 | | | |-'(' OpenParen |
4861 | | | |-ParameterDeclarationList Parameters |
4862 | | | | `-SimpleDeclaration ListElement |
4863 | | | | `-'int' |
4864 | | | `-')' CloseParen |
4865 | | `-';' |
4866 | |-SimpleDeclaration |
4867 | | |-'int' |
4868 | | |-DeclaratorList Declarators |
4869 | | | `-SimpleDeclarator ListElement |
4870 | | | |-'func2' |
4871 | | | `-ParametersAndQualifiers |
4872 | | | |-'(' OpenParen |
4873 | | | |-ParameterDeclarationList Parameters |
4874 | | | | `-SimpleDeclaration ListElement |
4875 | | | | |-'int' |
4876 | | | | `-DeclaratorList Declarators |
4877 | | | | `-SimpleDeclarator ListElement |
4878 | | | | `-'*' |
4879 | | | `-')' CloseParen |
4880 | | `-';' |
4881 | `-SimpleDeclaration |
4882 | |-'int' |
4883 | |-DeclaratorList Declarators |
4884 | | `-SimpleDeclarator ListElement |
4885 | | |-'func3' |
4886 | | `-ParametersAndQualifiers |
4887 | | |-'(' OpenParen |
4888 | | |-ParameterDeclarationList Parameters |
4889 | | | |-SimpleDeclaration ListElement |
4890 | | | | `-'int' |
4891 | | | |-',' ListDelimiter |
4892 | | | `-SimpleDeclaration ListElement |
4893 | | | `-'float' |
4894 | | `-')' CloseParen |
4895 | `-';' |
4896 | )txt" )); |
4897 | } |
4898 | |
4899 | TEST_P(BuildSyntaxTreeTest, |
4900 | ParametersAndQualifiers_InFreeFunctions_Default_One) { |
4901 | if (!GetParam().isCXX()) { |
4902 | return; |
4903 | } |
4904 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4905 | R"cpp( |
4906 | int func1([[int a = 1]]); |
4907 | )cpp" , |
4908 | {R"txt( |
4909 | ParameterDeclarationList Parameters |
4910 | `-SimpleDeclaration ListElement |
4911 | |-'int' |
4912 | `-DeclaratorList Declarators |
4913 | `-SimpleDeclarator ListElement |
4914 | |-'a' |
4915 | |-'=' |
4916 | `-IntegerLiteralExpression |
4917 | `-'1' LiteralToken |
4918 | )txt" })); |
4919 | } |
4920 | |
4921 | TEST_P(BuildSyntaxTreeTest, |
4922 | ParametersAndQualifiers_InFreeFunctions_Default_Multiple) { |
4923 | if (!GetParam().isCXX()) { |
4924 | return; |
4925 | } |
4926 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4927 | R"cpp( |
4928 | int func2([[int *ap, int a = 1, char c = '2']]); |
4929 | )cpp" , |
4930 | {R"txt( |
4931 | ParameterDeclarationList Parameters |
4932 | |-SimpleDeclaration ListElement |
4933 | | |-'int' |
4934 | | `-DeclaratorList Declarators |
4935 | | `-SimpleDeclarator ListElement |
4936 | | |-'*' |
4937 | | `-'ap' |
4938 | |-',' ListDelimiter |
4939 | |-SimpleDeclaration ListElement |
4940 | | |-'int' |
4941 | | `-DeclaratorList Declarators |
4942 | | `-SimpleDeclarator ListElement |
4943 | | |-'a' |
4944 | | |-'=' |
4945 | | `-IntegerLiteralExpression |
4946 | | `-'1' LiteralToken |
4947 | |-',' ListDelimiter |
4948 | `-SimpleDeclaration ListElement |
4949 | |-'char' |
4950 | `-DeclaratorList Declarators |
4951 | `-SimpleDeclarator ListElement |
4952 | |-'c' |
4953 | |-'=' |
4954 | `-CharacterLiteralExpression |
4955 | `-''2'' LiteralToken |
4956 | )txt" })); |
4957 | } |
4958 | |
4959 | TEST_P(BuildSyntaxTreeTest, |
4960 | ParametersAndQualifiers_InVariadicFunctionTemplate_ParameterPack) { |
4961 | if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) { |
4962 | return; |
4963 | } |
4964 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4965 | R"cpp( |
4966 | template<typename T, typename... Args> |
4967 | [[void test(T , Args... );]] |
4968 | )cpp" , |
4969 | {R"txt( |
4970 | SimpleDeclaration |
4971 | |-'void' |
4972 | |-DeclaratorList Declarators |
4973 | | `-SimpleDeclarator ListElement |
4974 | | |-'test' |
4975 | | `-ParametersAndQualifiers |
4976 | | |-'(' OpenParen |
4977 | | |-ParameterDeclarationList Parameters |
4978 | | | |-SimpleDeclaration ListElement |
4979 | | | | `-'T' |
4980 | | | |-',' ListDelimiter |
4981 | | | `-SimpleDeclaration ListElement |
4982 | | | |-'Args' |
4983 | | | `-'...' |
4984 | | `-')' CloseParen |
4985 | `-';' |
4986 | )txt" })); |
4987 | } |
4988 | |
4989 | TEST_P(BuildSyntaxTreeTest, |
4990 | ParametersAndQualifiers_InVariadicFunctionTemplate_NamedParameterPack) { |
4991 | if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) { |
4992 | return; |
4993 | } |
4994 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
4995 | R"cpp( |
4996 | template<typename T, typename... Args> |
4997 | [[void test(T t, Args... args);]] |
4998 | )cpp" , |
4999 | {R"txt( |
5000 | SimpleDeclaration |
5001 | |-'void' |
5002 | |-DeclaratorList Declarators |
5003 | | `-SimpleDeclarator ListElement |
5004 | | |-'test' |
5005 | | `-ParametersAndQualifiers |
5006 | | |-'(' OpenParen |
5007 | | |-ParameterDeclarationList Parameters |
5008 | | | |-SimpleDeclaration ListElement |
5009 | | | | |-'T' |
5010 | | | | `-DeclaratorList Declarators |
5011 | | | | `-SimpleDeclarator ListElement |
5012 | | | | `-'t' |
5013 | | | |-',' ListDelimiter |
5014 | | | `-SimpleDeclaration ListElement |
5015 | | | |-'Args' |
5016 | | | |-'...' |
5017 | | | `-DeclaratorList Declarators |
5018 | | | `-SimpleDeclarator ListElement |
5019 | | | `-'args' |
5020 | | `-')' CloseParen |
5021 | `-';' |
5022 | )txt" })); |
5023 | } |
5024 | |
5025 | TEST_P(BuildSyntaxTreeTest, |
5026 | ParametersAndQualifiers_InFreeFunctions_VariadicArguments) { |
5027 | if (!GetParam().isCXX11OrLater()) { |
5028 | return; |
5029 | } |
5030 | EXPECT_TRUE(treeDumpEqual( |
5031 | R"cpp( |
5032 | void test(int , char ...); |
5033 | )cpp" , |
5034 | R"txt( |
5035 | TranslationUnit Detached |
5036 | `-SimpleDeclaration |
5037 | |-'void' |
5038 | |-DeclaratorList Declarators |
5039 | | `-SimpleDeclarator ListElement |
5040 | | |-'test' |
5041 | | `-ParametersAndQualifiers |
5042 | | |-'(' OpenParen |
5043 | | |-ParameterDeclarationList Parameters |
5044 | | | |-SimpleDeclaration ListElement |
5045 | | | | `-'int' |
5046 | | | |-',' ListDelimiter |
5047 | | | `-SimpleDeclaration ListElement |
5048 | | | `-'char' |
5049 | | |-'...' |
5050 | | `-')' CloseParen |
5051 | `-';' |
5052 | )txt" )); |
5053 | } |
5054 | |
5055 | TEST_P(BuildSyntaxTreeTest, |
5056 | ParametersAndQualifiers_InFreeFunctions_Cxx_CvQualifiers) { |
5057 | if (!GetParam().isCXX()) { |
5058 | return; |
5059 | } |
5060 | EXPECT_TRUE(treeDumpEqual( |
5061 | R"cpp( |
5062 | int func(const int a, volatile int b, const volatile int c); |
5063 | )cpp" , |
5064 | R"txt( |
5065 | TranslationUnit Detached |
5066 | `-SimpleDeclaration |
5067 | |-'int' |
5068 | |-DeclaratorList Declarators |
5069 | | `-SimpleDeclarator ListElement |
5070 | | |-'func' |
5071 | | `-ParametersAndQualifiers |
5072 | | |-'(' OpenParen |
5073 | | |-ParameterDeclarationList Parameters |
5074 | | | |-SimpleDeclaration ListElement |
5075 | | | | |-'const' |
5076 | | | | |-'int' |
5077 | | | | `-DeclaratorList Declarators |
5078 | | | | `-SimpleDeclarator ListElement |
5079 | | | | `-'a' |
5080 | | | |-',' ListDelimiter |
5081 | | | |-SimpleDeclaration ListElement |
5082 | | | | |-'volatile' |
5083 | | | | |-'int' |
5084 | | | | `-DeclaratorList Declarators |
5085 | | | | `-SimpleDeclarator ListElement |
5086 | | | | `-'b' |
5087 | | | |-',' ListDelimiter |
5088 | | | `-SimpleDeclaration ListElement |
5089 | | | |-'const' |
5090 | | | |-'volatile' |
5091 | | | |-'int' |
5092 | | | `-DeclaratorList Declarators |
5093 | | | `-SimpleDeclarator ListElement |
5094 | | | `-'c' |
5095 | | `-')' CloseParen |
5096 | `-';' |
5097 | )txt" )); |
5098 | } |
5099 | |
5100 | TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx_Ref) { |
5101 | if (!GetParam().isCXX()) { |
5102 | return; |
5103 | } |
5104 | EXPECT_TRUE(treeDumpEqual( |
5105 | R"cpp( |
5106 | int func(int& a); |
5107 | )cpp" , |
5108 | R"txt( |
5109 | TranslationUnit Detached |
5110 | `-SimpleDeclaration |
5111 | |-'int' |
5112 | |-DeclaratorList Declarators |
5113 | | `-SimpleDeclarator ListElement |
5114 | | |-'func' |
5115 | | `-ParametersAndQualifiers |
5116 | | |-'(' OpenParen |
5117 | | |-ParameterDeclarationList Parameters |
5118 | | | `-SimpleDeclaration ListElement |
5119 | | | |-'int' |
5120 | | | `-DeclaratorList Declarators |
5121 | | | `-SimpleDeclarator ListElement |
5122 | | | |-'&' |
5123 | | | `-'a' |
5124 | | `-')' CloseParen |
5125 | `-';' |
5126 | )txt" )); |
5127 | } |
5128 | |
5129 | TEST_P(BuildSyntaxTreeTest, |
5130 | ParametersAndQualifiers_InFreeFunctions_Cxx11_RefRef) { |
5131 | if (!GetParam().isCXX11OrLater()) { |
5132 | return; |
5133 | } |
5134 | EXPECT_TRUE(treeDumpEqual( |
5135 | R"cpp( |
5136 | int func(int&& a); |
5137 | )cpp" , |
5138 | R"txt( |
5139 | TranslationUnit Detached |
5140 | `-SimpleDeclaration |
5141 | |-'int' |
5142 | |-DeclaratorList Declarators |
5143 | | `-SimpleDeclarator ListElement |
5144 | | |-'func' |
5145 | | `-ParametersAndQualifiers |
5146 | | |-'(' OpenParen |
5147 | | |-ParameterDeclarationList Parameters |
5148 | | | `-SimpleDeclaration ListElement |
5149 | | | |-'int' |
5150 | | | `-DeclaratorList Declarators |
5151 | | | `-SimpleDeclarator ListElement |
5152 | | | |-'&&' |
5153 | | | `-'a' |
5154 | | `-')' CloseParen |
5155 | `-';' |
5156 | )txt" )); |
5157 | } |
5158 | |
5159 | TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Simple) { |
5160 | if (!GetParam().isCXX()) { |
5161 | return; |
5162 | } |
5163 | EXPECT_TRUE(treeDumpEqual( |
5164 | R"cpp( |
5165 | struct Test { |
5166 | int a(); |
5167 | }; |
5168 | )cpp" , |
5169 | R"txt( |
5170 | TranslationUnit Detached |
5171 | `-SimpleDeclaration |
5172 | |-'struct' |
5173 | |-'Test' |
5174 | |-'{' |
5175 | |-SimpleDeclaration |
5176 | | |-'int' |
5177 | | |-DeclaratorList Declarators |
5178 | | | `-SimpleDeclarator ListElement |
5179 | | | |-'a' |
5180 | | | `-ParametersAndQualifiers |
5181 | | | |-'(' OpenParen |
5182 | | | `-')' CloseParen |
5183 | | `-';' |
5184 | |-'}' |
5185 | `-';' |
5186 | )txt" )); |
5187 | } |
5188 | |
5189 | TEST_P(BuildSyntaxTreeTest, |
5190 | ParametersAndQualifiers_InMemberFunctions_CvQualifiers) { |
5191 | if (!GetParam().isCXX()) { |
5192 | return; |
5193 | } |
5194 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
5195 | R"cpp( |
5196 | struct Test { |
5197 | [[int b() const;]] |
5198 | [[int c() volatile;]] |
5199 | [[int d() const volatile;]] |
5200 | }; |
5201 | )cpp" , |
5202 | {R"txt( |
5203 | SimpleDeclaration |
5204 | |-'int' |
5205 | |-DeclaratorList Declarators |
5206 | | `-SimpleDeclarator ListElement |
5207 | | |-'b' |
5208 | | `-ParametersAndQualifiers |
5209 | | |-'(' OpenParen |
5210 | | |-')' CloseParen |
5211 | | `-'const' |
5212 | `-';' |
5213 | )txt" , |
5214 | R"txt( |
5215 | SimpleDeclaration |
5216 | |-'int' |
5217 | |-DeclaratorList Declarators |
5218 | | `-SimpleDeclarator ListElement |
5219 | | |-'c' |
5220 | | `-ParametersAndQualifiers |
5221 | | |-'(' OpenParen |
5222 | | |-')' CloseParen |
5223 | | `-'volatile' |
5224 | `-';' |
5225 | )txt" , |
5226 | R"txt( |
5227 | SimpleDeclaration |
5228 | |-'int' |
5229 | |-DeclaratorList Declarators |
5230 | | `-SimpleDeclarator ListElement |
5231 | | |-'d' |
5232 | | `-ParametersAndQualifiers |
5233 | | |-'(' OpenParen |
5234 | | |-')' CloseParen |
5235 | | |-'const' |
5236 | | `-'volatile' |
5237 | `-';' |
5238 | )txt" })); |
5239 | } |
5240 | |
5241 | TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Ref) { |
5242 | if (!GetParam().isCXX11OrLater()) { |
5243 | return; |
5244 | } |
5245 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
5246 | R"cpp( |
5247 | struct Test { |
5248 | [[int e() &;]] |
5249 | }; |
5250 | )cpp" , |
5251 | {R"txt( |
5252 | SimpleDeclaration |
5253 | |-'int' |
5254 | |-DeclaratorList Declarators |
5255 | | `-SimpleDeclarator ListElement |
5256 | | |-'e' |
5257 | | `-ParametersAndQualifiers |
5258 | | |-'(' OpenParen |
5259 | | |-')' CloseParen |
5260 | | `-'&' |
5261 | `-';' |
5262 | )txt" })); |
5263 | } |
5264 | |
5265 | TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_RefRef) { |
5266 | if (!GetParam().isCXX11OrLater()) { |
5267 | return; |
5268 | } |
5269 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
5270 | R"cpp( |
5271 | struct Test { |
5272 | [[int f() &&;]] |
5273 | }; |
5274 | )cpp" , |
5275 | {R"txt( |
5276 | SimpleDeclaration |
5277 | |-'int' |
5278 | |-DeclaratorList Declarators |
5279 | | `-SimpleDeclarator ListElement |
5280 | | |-'f' |
5281 | | `-ParametersAndQualifiers |
5282 | | |-'(' OpenParen |
5283 | | |-')' CloseParen |
5284 | | `-'&&' |
5285 | `-';' |
5286 | )txt" })); |
5287 | } |
5288 | |
5289 | TEST_P(BuildSyntaxTreeTest, TrailingReturn) { |
5290 | if (!GetParam().isCXX11OrLater()) { |
5291 | return; |
5292 | } |
5293 | EXPECT_TRUE(treeDumpEqual( |
5294 | R"cpp( |
5295 | auto foo() -> int; |
5296 | )cpp" , |
5297 | R"txt( |
5298 | TranslationUnit Detached |
5299 | `-SimpleDeclaration |
5300 | |-'auto' |
5301 | |-DeclaratorList Declarators |
5302 | | `-SimpleDeclarator ListElement |
5303 | | |-'foo' |
5304 | | `-ParametersAndQualifiers |
5305 | | |-'(' OpenParen |
5306 | | |-')' CloseParen |
5307 | | `-TrailingReturnType TrailingReturn |
5308 | | |-'->' ArrowToken |
5309 | | `-'int' |
5310 | `-';' |
5311 | )txt" )); |
5312 | } |
5313 | |
5314 | TEST_P(BuildSyntaxTreeTest, DynamicExceptionSpecification) { |
5315 | if (!GetParam().supportsCXXDynamicExceptionSpecification()) { |
5316 | return; |
5317 | } |
5318 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
5319 | R"cpp( |
5320 | struct MyException1 {}; |
5321 | struct MyException2 {}; |
5322 | [[int a() throw();]] |
5323 | [[int b() throw(...);]] |
5324 | [[int c() throw(MyException1);]] |
5325 | [[int d() throw(MyException1, MyException2);]] |
5326 | )cpp" , |
5327 | {R"txt( |
5328 | SimpleDeclaration |
5329 | |-'int' |
5330 | |-DeclaratorList Declarators |
5331 | | `-SimpleDeclarator ListElement |
5332 | | |-'a' |
5333 | | `-ParametersAndQualifiers |
5334 | | |-'(' OpenParen |
5335 | | |-')' CloseParen |
5336 | | |-'throw' |
5337 | | |-'(' |
5338 | | `-')' |
5339 | `-';' |
5340 | )txt" , |
5341 | R"txt( |
5342 | SimpleDeclaration |
5343 | |-'int' |
5344 | |-DeclaratorList Declarators |
5345 | | `-SimpleDeclarator ListElement |
5346 | | |-'b' |
5347 | | `-ParametersAndQualifiers |
5348 | | |-'(' OpenParen |
5349 | | |-')' CloseParen |
5350 | | |-'throw' |
5351 | | |-'(' |
5352 | | |-'...' |
5353 | | `-')' |
5354 | `-';' |
5355 | )txt" , |
5356 | R"txt( |
5357 | SimpleDeclaration |
5358 | |-'int' |
5359 | |-DeclaratorList Declarators |
5360 | | `-SimpleDeclarator ListElement |
5361 | | |-'c' |
5362 | | `-ParametersAndQualifiers |
5363 | | |-'(' OpenParen |
5364 | | |-')' CloseParen |
5365 | | |-'throw' |
5366 | | |-'(' |
5367 | | |-'MyException1' |
5368 | | `-')' |
5369 | `-';' |
5370 | )txt" , |
5371 | R"txt( |
5372 | SimpleDeclaration |
5373 | |-'int' |
5374 | |-DeclaratorList Declarators |
5375 | | `-SimpleDeclarator ListElement |
5376 | | |-'d' |
5377 | | `-ParametersAndQualifiers |
5378 | | |-'(' OpenParen |
5379 | | |-')' CloseParen |
5380 | | |-'throw' |
5381 | | |-'(' |
5382 | | |-'MyException1' |
5383 | | |-',' |
5384 | | |-'MyException2' |
5385 | | `-')' |
5386 | `-';' |
5387 | )txt" })); |
5388 | } |
5389 | |
5390 | TEST_P(BuildSyntaxTreeTest, NoexceptExceptionSpecification) { |
5391 | if (!GetParam().isCXX11OrLater()) { |
5392 | return; |
5393 | } |
5394 | EXPECT_TRUE(treeDumpEqual( |
5395 | R"cpp( |
5396 | int a() noexcept; |
5397 | int b() noexcept(true); |
5398 | )cpp" , |
5399 | R"txt( |
5400 | TranslationUnit Detached |
5401 | |-SimpleDeclaration |
5402 | | |-'int' |
5403 | | |-DeclaratorList Declarators |
5404 | | | `-SimpleDeclarator ListElement |
5405 | | | |-'a' |
5406 | | | `-ParametersAndQualifiers |
5407 | | | |-'(' OpenParen |
5408 | | | |-')' CloseParen |
5409 | | | `-'noexcept' |
5410 | | `-';' |
5411 | `-SimpleDeclaration |
5412 | |-'int' |
5413 | |-DeclaratorList Declarators |
5414 | | `-SimpleDeclarator ListElement |
5415 | | |-'b' |
5416 | | `-ParametersAndQualifiers |
5417 | | |-'(' OpenParen |
5418 | | |-')' CloseParen |
5419 | | |-'noexcept' |
5420 | | |-'(' |
5421 | | |-BoolLiteralExpression |
5422 | | | `-'true' LiteralToken |
5423 | | `-')' |
5424 | `-';' |
5425 | )txt" )); |
5426 | } |
5427 | |
5428 | TEST_P(BuildSyntaxTreeTest, DeclaratorsInParentheses) { |
5429 | EXPECT_TRUE(treeDumpEqual( |
5430 | R"cpp( |
5431 | int (a); |
5432 | int *(b); |
5433 | int (*c)(int); |
5434 | int *(d)(int); |
5435 | )cpp" , |
5436 | R"txt( |
5437 | TranslationUnit Detached |
5438 | |-SimpleDeclaration |
5439 | | |-'int' |
5440 | | |-DeclaratorList Declarators |
5441 | | | `-SimpleDeclarator ListElement |
5442 | | | `-ParenDeclarator |
5443 | | | |-'(' OpenParen |
5444 | | | |-'a' |
5445 | | | `-')' CloseParen |
5446 | | `-';' |
5447 | |-SimpleDeclaration |
5448 | | |-'int' |
5449 | | |-DeclaratorList Declarators |
5450 | | | `-SimpleDeclarator ListElement |
5451 | | | |-'*' |
5452 | | | `-ParenDeclarator |
5453 | | | |-'(' OpenParen |
5454 | | | |-'b' |
5455 | | | `-')' CloseParen |
5456 | | `-';' |
5457 | |-SimpleDeclaration |
5458 | | |-'int' |
5459 | | |-DeclaratorList Declarators |
5460 | | | `-SimpleDeclarator ListElement |
5461 | | | |-ParenDeclarator |
5462 | | | | |-'(' OpenParen |
5463 | | | | |-'*' |
5464 | | | | |-'c' |
5465 | | | | `-')' CloseParen |
5466 | | | `-ParametersAndQualifiers |
5467 | | | |-'(' OpenParen |
5468 | | | |-ParameterDeclarationList Parameters |
5469 | | | | `-SimpleDeclaration ListElement |
5470 | | | | `-'int' |
5471 | | | `-')' CloseParen |
5472 | | `-';' |
5473 | `-SimpleDeclaration |
5474 | |-'int' |
5475 | |-DeclaratorList Declarators |
5476 | | `-SimpleDeclarator ListElement |
5477 | | |-'*' |
5478 | | |-ParenDeclarator |
5479 | | | |-'(' OpenParen |
5480 | | | |-'d' |
5481 | | | `-')' CloseParen |
5482 | | `-ParametersAndQualifiers |
5483 | | |-'(' OpenParen |
5484 | | |-ParameterDeclarationList Parameters |
5485 | | | `-SimpleDeclaration ListElement |
5486 | | | `-'int' |
5487 | | `-')' CloseParen |
5488 | `-';' |
5489 | )txt" )); |
5490 | } |
5491 | |
5492 | TEST_P(BuildSyntaxTreeTest, Declaration_ConstVolatileQualifiers_SimpleConst) { |
5493 | EXPECT_TRUE(treeDumpEqual( |
5494 | R"cpp( |
5495 | const int west = -1; |
5496 | int const east = 1; |
5497 | )cpp" , |
5498 | R"txt( |
5499 | TranslationUnit Detached |
5500 | |-SimpleDeclaration |
5501 | | |-'const' |
5502 | | |-'int' |
5503 | | |-DeclaratorList Declarators |
5504 | | | `-SimpleDeclarator ListElement |
5505 | | | |-'west' |
5506 | | | |-'=' |
5507 | | | `-PrefixUnaryOperatorExpression |
5508 | | | |-'-' OperatorToken |
5509 | | | `-IntegerLiteralExpression Operand |
5510 | | | `-'1' LiteralToken |
5511 | | `-';' |
5512 | `-SimpleDeclaration |
5513 | |-'int' |
5514 | |-'const' |
5515 | |-DeclaratorList Declarators |
5516 | | `-SimpleDeclarator ListElement |
5517 | | |-'east' |
5518 | | |-'=' |
5519 | | `-IntegerLiteralExpression |
5520 | | `-'1' LiteralToken |
5521 | `-';' |
5522 | )txt" )); |
5523 | } |
5524 | |
5525 | TEST_P(BuildSyntaxTreeTest, Declaration_ConstVolatileQualifiers_MultipleConst) { |
5526 | EXPECT_TRUE(treeDumpEqual( |
5527 | R"cpp( |
5528 | const int const universal = 0; |
5529 | )cpp" , |
5530 | R"txt( |
5531 | TranslationUnit Detached |
5532 | `-SimpleDeclaration |
5533 | |-'const' |
5534 | |-'int' |
5535 | |-'const' |
5536 | |-DeclaratorList Declarators |
5537 | | `-SimpleDeclarator ListElement |
5538 | | |-'universal' |
5539 | | |-'=' |
5540 | | `-IntegerLiteralExpression |
5541 | | `-'0' LiteralToken |
5542 | `-';' |
5543 | )txt" )); |
5544 | } |
5545 | |
5546 | TEST_P(BuildSyntaxTreeTest, |
5547 | Declaration_ConstVolatileQualifiers_ConstAndVolatile) { |
5548 | EXPECT_TRUE(treeDumpEqual( |
5549 | R"cpp( |
5550 | const int const *const *volatile b; |
5551 | )cpp" , |
5552 | R"txt( |
5553 | TranslationUnit Detached |
5554 | `-SimpleDeclaration |
5555 | |-'const' |
5556 | |-'int' |
5557 | |-'const' |
5558 | |-DeclaratorList Declarators |
5559 | | `-SimpleDeclarator ListElement |
5560 | | |-'*' |
5561 | | |-'const' |
5562 | | |-'*' |
5563 | | |-'volatile' |
5564 | | `-'b' |
5565 | `-';' |
5566 | )txt" )); |
5567 | } |
5568 | |
5569 | TEST_P(BuildSyntaxTreeTest, RangesOfDeclaratorsWithTrailingReturnTypes) { |
5570 | if (!GetParam().isCXX11OrLater()) { |
5571 | return; |
5572 | } |
5573 | EXPECT_TRUE(treeDumpEqual( |
5574 | R"cpp( |
5575 | auto foo() -> auto(*)(int) -> double*; |
5576 | )cpp" , |
5577 | R"txt( |
5578 | TranslationUnit Detached |
5579 | `-SimpleDeclaration |
5580 | |-'auto' |
5581 | |-DeclaratorList Declarators |
5582 | | `-SimpleDeclarator ListElement |
5583 | | |-'foo' |
5584 | | `-ParametersAndQualifiers |
5585 | | |-'(' OpenParen |
5586 | | |-')' CloseParen |
5587 | | `-TrailingReturnType TrailingReturn |
5588 | | |-'->' ArrowToken |
5589 | | |-'auto' |
5590 | | `-SimpleDeclarator Declarator |
5591 | | |-ParenDeclarator |
5592 | | | |-'(' OpenParen |
5593 | | | |-'*' |
5594 | | | `-')' CloseParen |
5595 | | `-ParametersAndQualifiers |
5596 | | |-'(' OpenParen |
5597 | | |-ParameterDeclarationList Parameters |
5598 | | | `-SimpleDeclaration ListElement |
5599 | | | `-'int' |
5600 | | |-')' CloseParen |
5601 | | `-TrailingReturnType TrailingReturn |
5602 | | |-'->' ArrowToken |
5603 | | |-'double' |
5604 | | `-SimpleDeclarator Declarator |
5605 | | `-'*' |
5606 | `-';' |
5607 | )txt" )); |
5608 | } |
5609 | |
5610 | TEST_P(BuildSyntaxTreeTest, MemberPointers) { |
5611 | if (!GetParam().isCXX()) { |
5612 | return; |
5613 | } |
5614 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
5615 | R"cpp( |
5616 | struct X {}; |
5617 | [[int X::* a;]] |
5618 | [[const int X::* b;]] |
5619 | )cpp" , |
5620 | {R"txt( |
5621 | SimpleDeclaration |
5622 | |-'int' |
5623 | |-DeclaratorList Declarators |
5624 | | `-SimpleDeclarator ListElement |
5625 | | |-MemberPointer |
5626 | | | |-'X' |
5627 | | | |-'::' |
5628 | | | `-'*' |
5629 | | `-'a' |
5630 | `-';' |
5631 | )txt" , |
5632 | R"txt( |
5633 | SimpleDeclaration |
5634 | |-'const' |
5635 | |-'int' |
5636 | |-DeclaratorList Declarators |
5637 | | `-SimpleDeclarator ListElement |
5638 | | |-MemberPointer |
5639 | | | |-'X' |
5640 | | | |-'::' |
5641 | | | `-'*' |
5642 | | `-'b' |
5643 | `-';' |
5644 | )txt" })); |
5645 | } |
5646 | |
5647 | TEST_P(BuildSyntaxTreeTest, MemberFunctionPointer) { |
5648 | if (!GetParam().isCXX()) { |
5649 | return; |
5650 | } |
5651 | EXPECT_TRUE(treeDumpEqualOnAnnotations( |
5652 | R"cpp( |
5653 | struct X { |
5654 | struct Y {}; |
5655 | }; |
5656 | [[void (X::*xp)();]] |
5657 | [[void (X::**xpp)(const int*);]] |
5658 | // FIXME: Generate the right syntax tree for this type, |
5659 | // i.e. create a syntax node for the outer member pointer |
5660 | [[void (X::Y::*xyp)(const int*, char);]] |
5661 | )cpp" , |
5662 | {R"txt( |
5663 | SimpleDeclaration |
5664 | |-'void' |
5665 | |-DeclaratorList Declarators |
5666 | | `-SimpleDeclarator ListElement |
5667 | | |-ParenDeclarator |
5668 | | | |-'(' OpenParen |
5669 | | | |-MemberPointer |
5670 | | | | |-'X' |
5671 | | | | |-'::' |
5672 | | | | `-'*' |
5673 | | | |-'xp' |
5674 | | | `-')' CloseParen |
5675 | | `-ParametersAndQualifiers |
5676 | | |-'(' OpenParen |
5677 | | `-')' CloseParen |
5678 | `-';' |
5679 | )txt" , |
5680 | R"txt( |
5681 | SimpleDeclaration |
5682 | |-'void' |
5683 | |-DeclaratorList Declarators |
5684 | | `-SimpleDeclarator ListElement |
5685 | | |-ParenDeclarator |
5686 | | | |-'(' OpenParen |
5687 | | | |-MemberPointer |
5688 | | | | |-'X' |
5689 | | | | |-'::' |
5690 | | | | `-'*' |
5691 | | | |-'*' |
5692 | | | |-'xpp' |
5693 | | | `-')' CloseParen |
5694 | | `-ParametersAndQualifiers |
5695 | | |-'(' OpenParen |
5696 | | |-ParameterDeclarationList Parameters |
5697 | | | `-SimpleDeclaration ListElement |
5698 | | | |-'const' |
5699 | | | |-'int' |
5700 | | | `-DeclaratorList Declarators |
5701 | | | `-SimpleDeclarator ListElement |
5702 | | | `-'*' |
5703 | | `-')' CloseParen |
5704 | `-';' |
5705 | )txt" , |
5706 | R"txt( |
5707 | SimpleDeclaration |
5708 | |-'void' |
5709 | |-DeclaratorList Declarators |
5710 | | `-SimpleDeclarator ListElement |
5711 | | |-ParenDeclarator |
5712 | | | |-'(' OpenParen |
5713 | | | |-'X' |
5714 | | | |-'::' |
5715 | | | |-MemberPointer |
5716 | | | | |-'Y' |
5717 | | | | |-'::' |
5718 | | | | `-'*' |
5719 | | | |-'xyp' |
5720 | | | `-')' CloseParen |
5721 | | `-ParametersAndQualifiers |
5722 | | |-'(' OpenParen |
5723 | | |-ParameterDeclarationList Parameters |
5724 | | | |-SimpleDeclaration ListElement |
5725 | | | | |-'const' |
5726 | | | | |-'int' |
5727 | | | | `-DeclaratorList Declarators |
5728 | | | | `-SimpleDeclarator ListElement |
5729 | | | | `-'*' |
5730 | | | |-',' ListDelimiter |
5731 | | | `-SimpleDeclaration ListElement |
5732 | | | `-'char' |
5733 | | `-')' CloseParen |
5734 | `-';' |
5735 | )txt" })); |
5736 | } |
5737 | |
5738 | TEST_P(BuildSyntaxTreeTest, ComplexDeclarator) { |
5739 | EXPECT_TRUE(treeDumpEqual( |
5740 | R"cpp( |
5741 | void x(char a, short (*b)(int)); |
5742 | )cpp" , |
5743 | R"txt( |
5744 | TranslationUnit Detached |
5745 | `-SimpleDeclaration |
5746 | |-'void' |
5747 | |-DeclaratorList Declarators |
5748 | | `-SimpleDeclarator ListElement |
5749 | | |-'x' |
5750 | | `-ParametersAndQualifiers |
5751 | | |-'(' OpenParen |
5752 | | |-ParameterDeclarationList Parameters |
5753 | | | |-SimpleDeclaration ListElement |
5754 | | | | |-'char' |
5755 | | | | `-DeclaratorList Declarators |
5756 | | | | `-SimpleDeclarator ListElement |
5757 | | | | `-'a' |
5758 | | | |-',' ListDelimiter |
5759 | | | `-SimpleDeclaration ListElement |
5760 | | | |-'short' |
5761 | | | `-DeclaratorList Declarators |
5762 | | | `-SimpleDeclarator ListElement |
5763 | | | |-ParenDeclarator |
5764 | | | | |-'(' OpenParen |
5765 | | | | |-'*' |
5766 | | | | |-'b' |
5767 | | | | `-')' CloseParen |
5768 | | | `-ParametersAndQualifiers |
5769 | | | |-'(' OpenParen |
5770 | | | |-ParameterDeclarationList Parameters |
5771 | | | | `-SimpleDeclaration ListElement |
5772 | | | | `-'int' |
5773 | | | `-')' CloseParen |
5774 | | `-')' CloseParen |
5775 | `-';' |
5776 | )txt" )); |
5777 | } |
5778 | |
5779 | TEST_P(BuildSyntaxTreeTest, ComplexDeclarator2) { |
5780 | EXPECT_TRUE(treeDumpEqual( |
5781 | R"cpp( |
5782 | void x(char a, short (*b)(int), long (**c)(long long)); |
5783 | )cpp" , |
5784 | R"txt( |
5785 | TranslationUnit Detached |
5786 | `-SimpleDeclaration |
5787 | |-'void' |
5788 | |-DeclaratorList Declarators |
5789 | | `-SimpleDeclarator ListElement |
5790 | | |-'x' |
5791 | | `-ParametersAndQualifiers |
5792 | | |-'(' OpenParen |
5793 | | |-ParameterDeclarationList Parameters |
5794 | | | |-SimpleDeclaration ListElement |
5795 | | | | |-'char' |
5796 | | | | `-DeclaratorList Declarators |
5797 | | | | `-SimpleDeclarator ListElement |
5798 | | | | `-'a' |
5799 | | | |-',' ListDelimiter |
5800 | | | |-SimpleDeclaration ListElement |
5801 | | | | |-'short' |
5802 | | | | `-DeclaratorList Declarators |
5803 | | | | `-SimpleDeclarator ListElement |
5804 | | | | |-ParenDeclarator |
5805 | | | | | |-'(' OpenParen |
5806 | | | | | |-'*' |
5807 | | | | | |-'b' |
5808 | | | | | `-')' CloseParen |
5809 | | | | `-ParametersAndQualifiers |
5810 | | | | |-'(' OpenParen |
5811 | | | | |-ParameterDeclarationList Parameters |
5812 | | | | | `-SimpleDeclaration ListElement |
5813 | | | | | `-'int' |
5814 | | | | `-')' CloseParen |
5815 | | | |-',' ListDelimiter |
5816 | | | `-SimpleDeclaration ListElement |
5817 | | | |-'long' |
5818 | | | `-DeclaratorList Declarators |
5819 | | | `-SimpleDeclarator ListElement |
5820 | | | |-ParenDeclarator |
5821 | | | | |-'(' OpenParen |
5822 | | | | |-'*' |
5823 | | | | |-'*' |
5824 | | | | |-'c' |
5825 | | | | `-')' CloseParen |
5826 | | | `-ParametersAndQualifiers |
5827 | | | |-'(' OpenParen |
5828 | | | |-ParameterDeclarationList Parameters |
5829 | | | | `-SimpleDeclaration ListElement |
5830 | | | | |-'long' |
5831 | | | | `-'long' |
5832 | | | `-')' CloseParen |
5833 | | `-')' CloseParen |
5834 | `-';' |
5835 | )txt" )); |
5836 | } |
5837 | |
5838 | } // namespace |
5839 | |