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

source code of clang/unittests/Tooling/Syntax/BuildTreeTest.cpp