1//===- Nodes.td - Node types in the Syntax Tree grammar -------------------===//
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 defines concrete nodes in the syntax tree.
10// The archetypes they fall into (Sequence, List etc) are defined in Syntax.td.
11//
12// The C++ classes for the archetypes themselves are written by hand, and the
13// concrete node classes will be generated. Migration to TableGen is not
14// complete, so currently there is a mix of generated and hand-authored code.
15//
16//===----------------------------------------------------------------------===//
17
18include "clang/Tooling/Syntax/Syntax.td"
19
20def TranslationUnit : Unconstrained {
21  let documentation = [{
22    A root node for a translation unit. Parent is always null.
23  }];
24}
25
26def UnqualifiedId : External<Tree> {}
27
28// Lists
29def List : External<Tree> {}
30def DeclaratorList : External<List> {}
31def ParameterDeclarationList : External<List> {}
32def CallArguments : External<List> {}
33def NestedNameSpecifier : External<List> {}
34
35def Expression : Alternatives {
36  let documentation = [{
37    A base class for all expressions. Note that expressions are not statements,
38    even though they are in clang.
39  }];
40}
41def UnknownExpression : External<Expression> {}
42def UnaryOperatorExpression : External<Tree> {}
43def PrefixUnaryOperatorExpression : External<UnaryOperatorExpression> {}
44def PostfixUnaryOperatorExpression : External<UnaryOperatorExpression> {}
45def BinaryOperatorExpression : External<Expression> {}
46def ParenExpression : Sequence<Expression> {
47  let documentation = [{
48    Models a parenthesized expression `(E)`. C++ [expr.prim.paren]
49    e.g. `(3 + 2)` in `a = 1 + (3 + 2);`
50  }];
51  let children = [
52    Role<"OpenParen", Token<"l_paren">>,
53    Role<"SubExpression", Expression>,
54    Role<"CloseParen", Token<"r_paren">>,
55  ];
56}
57def LiteralExpression : Alternatives<Expression> {
58  let documentation = [{
59    Expression for literals. C++ [lex.literal]
60  }];
61}
62def IntegerLiteralExpression : Sequence<LiteralExpression> {
63  let documentation = [{
64    Expression for integer literals. C++ [lex.icon]
65  }];
66  let children = [
67    Role<"LiteralToken", Token<"numeric_constant">>,
68  ];
69}
70defvar AnyCharacterLiteral = AnyToken<[
71  "char_constant", "wide_char_constant", "utf8_char_constant",
72  "utf16_char_constant", "utf32_char_constant"
73]>;
74def CharacterLiteralExpression : Sequence<LiteralExpression> {
75  let documentation = [{
76    Expression for character literals. C++ [lex.ccon]
77  }];
78  let children = [
79    Role<"LiteralToken", AnyCharacterLiteral>,
80  ];
81}
82def FloatingLiteralExpression : Sequence<LiteralExpression> {
83  let documentation = [{
84    Expression for floating-point literals. C++ [lex.fcon]
85  }];
86  let children = [
87    Role<"LiteralToken", Token<"numeric_constant">>,
88  ];
89}
90defvar AnyStringLiteral = AnyToken<[
91  "string_literal", "wide_string_literal", "utf8_string_literal",
92  "utf16_string_literal", "utf32_string_literal"
93]>;
94def StringLiteralExpression : Sequence<LiteralExpression> {
95  let documentation = [{
96    Expression for string-literals. C++ [lex.string]
97  }];
98  // FIXME: string literals may consist of multiple tokens.
99  // These are merged in phase 6, but tokens are captured after phase 4.
100  // The child here should be a list of literal tokens instead.
101  let children = [
102    Role<"LiteralToken", AnyStringLiteral>,
103  ];
104}
105def BoolLiteralExpression : Sequence<LiteralExpression> {
106  let documentation = [{
107    Expression for boolean literals. C++ [lex.bool]
108  }];
109  let children = [
110    Role<"LiteralToken", AnyToken<["kw_false","kw_true"]>>,
111  ];
112}
113def CxxNullPtrExpression : Sequence<LiteralExpression> {
114  let documentation = [{
115    Expression for the `nullptr` literal. C++ [lex.nullptr]
116  }];
117  let children = [
118    Role<"LiteralToken", Keyword<"nullptr">>,
119  ];
120}
121def UserDefinedLiteralExpression : Alternatives<LiteralExpression> {
122  let documentation = [{
123    Expression for user-defined literal. C++ [lex.ext]
124    user-defined-literal:
125      user-defined-integer-literal
126      user-defined-floating-point-literal
127      user-defined-string-literal
128      user-defined-character-literal
129  }];
130}
131def IntegerUserDefinedLiteralExpression : Sequence<UserDefinedLiteralExpression> {
132  let documentation = [{
133    Expression for user-defined-integer-literal. C++ [lex.ext]
134  }];
135  let children = [
136    Role<"LiteralToken", Keyword<"numeric_constant">>,
137  ];
138}
139def FloatUserDefinedLiteralExpression : Sequence<UserDefinedLiteralExpression> {
140  let documentation = [{
141    Expression for user-defined-floating-point-literal. C++ [lex.ext]
142  }];
143  let children = [
144    Role<"LiteralToken", Keyword<"numeric_constant">>,
145  ];
146}
147def CharUserDefinedLiteralExpression : Sequence<UserDefinedLiteralExpression> {
148  let documentation = [{
149    Expression for user-defined-character-literal. C++ [lex.ext]
150  }];
151  let children = [
152    Role<"LiteralToken", AnyCharacterLiteral>,
153  ];
154}
155def StringUserDefinedLiteralExpression : Sequence<UserDefinedLiteralExpression> {
156  let documentation = [{
157    Expression for user-defined-string-literal. C++ [lex.ext]
158  }];
159  let children = [
160    Role<"LiteralToken", AnyStringLiteral>,
161  ];
162}
163def IdExpression : Sequence<Expression> {
164  let documentation = [{
165    Models an `id-expression`, e.g. `std::vector<int>::size`.
166    C++ [expr.prim.id]
167    id-expression:
168      unqualified-id
169      qualified-id
170    qualified-id:
171      nested-name-specifier template_opt unqualified-id
172  }];
173  let children = [
174    Role<"Qualifier", Optional<NestedNameSpecifier>>,
175    Role<"TemplateKeyword", Optional<Keyword<"template">>>,
176    Role<"UnqualifiedId", UnqualifiedId>,
177  ];
178}
179def MemberExpression : Sequence<Expression> {
180  let documentation = [{
181    Models a class member access. C++ [expr.ref]
182    member-expression:
183      expression -> template_opt id-expression
184      expression .  template_opt id-expression
185    e.g. `x.a`, `xp->a`
186
187    Note: An implicit member access inside a class, i.e. `a` instead of
188    `this->a`, is an `id-expression`.
189  }];
190  let children = [
191    Role<"Object", Expression>,
192    Role<"AccessToken", AnyToken<["period","arrow"]>>,
193    Role<"TemplateKeyword", Optional<Keyword<"template">>>,
194    Role<"Member", IdExpression>,
195  ];
196}
197def ThisExpression : Sequence<Expression> {
198  let documentation = [{
199    Models a this expression `this`. C++ [expr.prim.this]
200  }];
201  let children = [
202    Role<"IntroducerKeyword", Keyword<"this">>,
203  ];
204}
205def CallExpression : Sequence<Expression> {
206  let documentation = [{
207    A function call. C++ [expr.call]
208    call-expression:
209      expression '(' call-arguments ')'
210    e.g `f(1, '2')` or `this->Base::f()`
211  }];
212  let children = [
213    Role<"Callee", Expression>,
214    Role<"OpenParen", Token<"l_paren">>,
215    Role<"Arguments", CallArguments>,
216    Role<"CloseParen", Token<"r_paren">>,
217  ];
218}
219
220// Statements.
221def Statement : External<Tree> {}
222def UnknownStatement : External<Statement> {}
223def DeclarationStatement : External<Statement> {}
224def EmptyStatement : External<Statement> {}
225def SwitchStatement : External<Statement> {}
226def CaseStatement : External<Statement> {}
227def DefaultStatement : External<Statement> {}
228def IfStatement : External<Statement> {}
229def ForStatement : External<Statement> {}
230def WhileStatement : External<Statement> {}
231def ContinueStatement : External<Statement> {}
232def BreakStatement : External<Statement> {}
233def ReturnStatement : External<Statement> {}
234def RangeBasedForStatement : External<Statement> {}
235def ExpressionStatement : External<Statement> {}
236def CompoundStatement : External<Statement> {}
237
238// Declarations.
239def Declaration : External<Tree> {}
240def UnknownDeclaration : External<Declaration> {}
241def EmptyDeclaration : External<Declaration> {}
242def StaticAssertDeclaration : External<Declaration> {}
243def LinkageSpecificationDeclaration : External<Declaration> {}
244def SimpleDeclaration : External<Declaration> {}
245def TemplateDeclaration : External<Declaration> {}
246def ExplicitTemplateInstantiation : External<Declaration> {}
247def NamespaceDefinition : External<Declaration> {}
248def NamespaceAliasDefinition : External<Declaration> {}
249def UsingNamespaceDirective : External<Declaration> {}
250def UsingDeclaration : External<Declaration> {}
251def TypeAliasDeclaration : External<Declaration> {}
252
253// Declarators.
254def Declarator : External<Tree> {}
255def SimpleDeclarator : External<Declarator> {}
256def ParenDeclarator : External<Declarator> {}
257
258def ArraySubscript : External<Tree> {}
259def TrailingReturnType : External<Tree> {}
260def ParametersAndQualifiers : External<Tree> {}
261def MemberPointer : External<Tree> {}
262
263// Name Specifiers.
264def NameSpecifier : Alternatives {
265  let documentation = [{
266    A sequence of these specifiers make a `nested-name-specifier`.
267    e.g. the `std` or `vector<int>` in `std::vector<int>::size`.
268  }];
269}
270def GlobalNameSpecifier : Unconstrained<NameSpecifier> {
271  let documentation = [{
272    The global namespace name specifier, this specifier doesn't correspond to a
273    token instead an absence of tokens before a `::` characterizes it, in
274    `::std::vector<int>` it would be characterized by the absence of a token
275    before the first `::`
276  }];
277}
278def DecltypeNameSpecifier : Unconstrained<NameSpecifier> {
279  let documentation = [{
280    A name specifier holding a decltype, of the form: `decltype ( expression ) `
281    e.g. the `decltype(s)` in `decltype(s)::size`.
282  }];
283}
284def IdentifierNameSpecifier : Unconstrained<NameSpecifier> {
285  let documentation = [{
286    A identifier name specifier, of the form `identifier`
287    e.g. the `std` in `std::vector<int>::size`.
288  }];
289}
290def SimpleTemplateNameSpecifier : Unconstrained<NameSpecifier> {
291  let documentation = [{
292    A name specifier with a simple-template-id, of the form `template_opt
293    identifier < template-args >` e.g. the `vector<int>` in
294    `std::vector<int>::size`.
295  }];
296}
297