Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- Nodes.h - syntax nodes for C/C++ grammar constructs ----*- C++ -*-=====// |
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 | // Syntax tree nodes for C, C++ and Objective-C grammar constructs. |
||
9 | // |
||
10 | // Nodes provide access to their syntactic components, e.g. IfStatement provides |
||
11 | // a way to get its condition, then and else branches, tokens for 'if' and |
||
12 | // 'else' keywords. |
||
13 | // When using the accessors, please assume they can return null. This happens |
||
14 | // because: |
||
15 | // - the corresponding subnode is optional in the C++ grammar, e.g. an else |
||
16 | // branch of an if statement, |
||
17 | // - syntactic errors occurred while parsing the corresponding subnode. |
||
18 | // One notable exception is "introducer" keywords, e.g. the accessor for the |
||
19 | // 'if' keyword of an if statement will never return null. |
||
20 | //===----------------------------------------------------------------------===// |
||
21 | #ifndef LLVM_CLANG_TOOLING_SYNTAX_NODES_H |
||
22 | #define LLVM_CLANG_TOOLING_SYNTAX_NODES_H |
||
23 | |||
24 | #include "clang/Basic/LLVM.h" |
||
25 | #include "clang/Tooling/Syntax/Tree.h" |
||
26 | namespace clang { |
||
27 | namespace syntax { |
||
28 | |||
29 | /// A kind of a syntax node, used for implementing casts. The ordering and |
||
30 | /// blocks of enumerator constants must correspond to the inheritance hierarchy |
||
31 | /// of syntax::Node. |
||
32 | enum class NodeKind : uint16_t { |
||
33 | #define CONCRETE_NODE(Kind, Base) Kind, |
||
34 | #include "clang/Tooling/Syntax/Nodes.inc" |
||
35 | }; |
||
36 | /// For debugging purposes. |
||
37 | raw_ostream &operator<<(raw_ostream &OS, NodeKind K); |
||
38 | |||
39 | /// A relation between a parent and child node, e.g. 'left-hand-side of |
||
40 | /// a binary expression'. Used for implementing accessors. |
||
41 | /// |
||
42 | /// In general `NodeRole`s should be named the same as their accessors. |
||
43 | /// |
||
44 | /// Some roles describe parent/child relations that occur multiple times in |
||
45 | /// language grammar. We define only one role to describe all instances of such |
||
46 | /// recurring relations. For example, grammar for both "if" and "while" |
||
47 | /// statements requires an opening paren and a closing paren. The opening |
||
48 | /// paren token is assigned the OpenParen role regardless of whether it appears |
||
49 | /// as a child of IfStatement or WhileStatement node. More generally, when |
||
50 | /// grammar requires a certain fixed token (like a specific keyword, or an |
||
51 | /// opening paren), we define a role for this token and use it across all |
||
52 | /// grammar rules with the same requirement. Names of such reusable roles end |
||
53 | /// with a ~Token or a ~Keyword suffix. |
||
54 | enum class NodeRole : uint8_t { |
||
55 | // Roles common to multiple node kinds. |
||
56 | /// A node without a parent |
||
57 | Detached, |
||
58 | /// Children of an unknown semantic nature, e.g. skipped tokens, comments. |
||
59 | Unknown, |
||
60 | /// An opening parenthesis in argument lists and blocks, e.g. '{', '(', etc. |
||
61 | OpenParen, |
||
62 | /// A closing parenthesis in argument lists and blocks, e.g. '}', ')', etc. |
||
63 | CloseParen, |
||
64 | /// A keywords that introduces some grammar construct, e.g. 'if', 'try', etc. |
||
65 | IntroducerKeyword, |
||
66 | /// A token that represents a literal, e.g. 'nullptr', '1', 'true', etc. |
||
67 | LiteralToken, |
||
68 | /// Tokens or Keywords. |
||
69 | ArrowToken, |
||
70 | ExternKeyword, |
||
71 | TemplateKeyword, |
||
72 | /// An inner statement for those that have only a single child of kind |
||
73 | /// statement, e.g. loop body for while, for, etc; inner statement for case, |
||
74 | /// default, etc. |
||
75 | BodyStatement, |
||
76 | /// List API roles. |
||
77 | ListElement, |
||
78 | ListDelimiter, |
||
79 | |||
80 | // Roles specific to particular node kinds. |
||
81 | OperatorToken, |
||
82 | Operand, |
||
83 | LeftHandSide, |
||
84 | RightHandSide, |
||
85 | ReturnValue, |
||
86 | CaseValue, |
||
87 | ThenStatement, |
||
88 | ElseKeyword, |
||
89 | ElseStatement, |
||
90 | Expression, |
||
91 | Statement, |
||
92 | Condition, |
||
93 | Message, |
||
94 | Declarator, |
||
95 | Declaration, |
||
96 | Size, |
||
97 | Parameters, |
||
98 | TrailingReturn, |
||
99 | UnqualifiedId, |
||
100 | Qualifier, |
||
101 | SubExpression, |
||
102 | Object, |
||
103 | AccessToken, |
||
104 | Member, |
||
105 | Callee, |
||
106 | Arguments, |
||
107 | Declarators |
||
108 | }; |
||
109 | /// For debugging purposes. |
||
110 | raw_ostream &operator<<(raw_ostream &OS, NodeRole R); |
||
111 | |||
112 | #include "clang/Tooling/Syntax/NodeClasses.inc" |
||
113 | |||
114 | /// Models a `nested-name-specifier`. C++ [expr.prim.id.qual] |
||
115 | /// e.g. the `std::vector<int>::` in `std::vector<int>::size`. |
||
116 | class NestedNameSpecifier final : public List { |
||
117 | public: |
||
118 | NestedNameSpecifier() : List(NodeKind::NestedNameSpecifier) {} |
||
119 | static bool classof(const Node *N); |
||
120 | std::vector<NameSpecifier *> getSpecifiers(); |
||
121 | std::vector<List::ElementAndDelimiter<syntax::NameSpecifier>> |
||
122 | getSpecifiersAndDoubleColons(); |
||
123 | }; |
||
124 | |||
125 | /// Models an `unqualified-id`. C++ [expr.prim.id.unqual] |
||
126 | /// e.g. the `size` in `std::vector<int>::size`. |
||
127 | class UnqualifiedId final : public Tree { |
||
128 | public: |
||
129 | UnqualifiedId() : Tree(NodeKind::UnqualifiedId) {} |
||
130 | static bool classof(const Node *N); |
||
131 | }; |
||
132 | |||
133 | /// An expression of an unknown kind, i.e. one not currently handled by the |
||
134 | /// syntax tree. |
||
135 | class UnknownExpression final : public Expression { |
||
136 | public: |
||
137 | UnknownExpression() : Expression(NodeKind::UnknownExpression) {} |
||
138 | static bool classof(const Node *N); |
||
139 | }; |
||
140 | |||
141 | /// Models arguments of a function call. |
||
142 | /// call-arguments: |
||
143 | /// delimited_list(expression, ',') |
||
144 | /// Note: This construct is a simplification of the grammar rule for |
||
145 | /// `expression-list`, that is used in the definition of `call-expression` |
||
146 | class CallArguments final : public List { |
||
147 | public: |
||
148 | CallArguments() : List(NodeKind::CallArguments) {} |
||
149 | static bool classof(const Node *N); |
||
150 | std::vector<Expression *> getArguments(); |
||
151 | std::vector<List::ElementAndDelimiter<Expression>> getArgumentsAndCommas(); |
||
152 | }; |
||
153 | |||
154 | /// An abstract class for prefix and postfix unary operators. |
||
155 | class UnaryOperatorExpression : public Expression { |
||
156 | public: |
||
157 | UnaryOperatorExpression(NodeKind K) : Expression(K) {} |
||
158 | static bool classof(const Node *N); |
||
159 | Leaf *getOperatorToken(); |
||
160 | Expression *getOperand(); |
||
161 | }; |
||
162 | |||
163 | /// <operator> <operand> |
||
164 | /// |
||
165 | /// For example: |
||
166 | /// +a -b |
||
167 | /// !c not c |
||
168 | /// ~d compl d |
||
169 | /// *e &f |
||
170 | /// ++h --h |
||
171 | /// __real i __imag i |
||
172 | class PrefixUnaryOperatorExpression final : public UnaryOperatorExpression { |
||
173 | public: |
||
174 | PrefixUnaryOperatorExpression() |
||
175 | : UnaryOperatorExpression(NodeKind::PrefixUnaryOperatorExpression) {} |
||
176 | static bool classof(const Node *N); |
||
177 | }; |
||
178 | |||
179 | /// <operand> <operator> |
||
180 | /// |
||
181 | /// For example: |
||
182 | /// a++ |
||
183 | /// b-- |
||
184 | class PostfixUnaryOperatorExpression final : public UnaryOperatorExpression { |
||
185 | public: |
||
186 | PostfixUnaryOperatorExpression() |
||
187 | : UnaryOperatorExpression(NodeKind::PostfixUnaryOperatorExpression) {} |
||
188 | static bool classof(const Node *N); |
||
189 | }; |
||
190 | |||
191 | /// <lhs> <operator> <rhs> |
||
192 | /// |
||
193 | /// For example: |
||
194 | /// a + b |
||
195 | /// a bitor 1 |
||
196 | /// a |= b |
||
197 | /// a and_eq b |
||
198 | class BinaryOperatorExpression final : public Expression { |
||
199 | public: |
||
200 | BinaryOperatorExpression() : Expression(NodeKind::BinaryOperatorExpression) {} |
||
201 | static bool classof(const Node *N); |
||
202 | Expression *getLhs(); |
||
203 | Leaf *getOperatorToken(); |
||
204 | Expression *getRhs(); |
||
205 | }; |
||
206 | |||
207 | /// An abstract node for C++ statements, e.g. 'while', 'if', etc. |
||
208 | /// FIXME: add accessors for semicolon of statements that have it. |
||
209 | class Statement : public Tree { |
||
210 | public: |
||
211 | Statement(NodeKind K) : Tree(K) {} |
||
212 | static bool classof(const Node *N); |
||
213 | }; |
||
214 | |||
215 | /// A statement of an unknown kind, i.e. one not currently handled by the syntax |
||
216 | /// tree. |
||
217 | class UnknownStatement final : public Statement { |
||
218 | public: |
||
219 | UnknownStatement() : Statement(NodeKind::UnknownStatement) {} |
||
220 | static bool classof(const Node *N); |
||
221 | }; |
||
222 | |||
223 | /// E.g. 'int a, b = 10;' |
||
224 | class DeclarationStatement final : public Statement { |
||
225 | public: |
||
226 | DeclarationStatement() : Statement(NodeKind::DeclarationStatement) {} |
||
227 | static bool classof(const Node *N); |
||
228 | }; |
||
229 | |||
230 | /// The no-op statement, i.e. ';'. |
||
231 | class EmptyStatement final : public Statement { |
||
232 | public: |
||
233 | EmptyStatement() : Statement(NodeKind::EmptyStatement) {} |
||
234 | static bool classof(const Node *N); |
||
235 | }; |
||
236 | |||
237 | /// switch (<cond>) <body> |
||
238 | class SwitchStatement final : public Statement { |
||
239 | public: |
||
240 | SwitchStatement() : Statement(NodeKind::SwitchStatement) {} |
||
241 | static bool classof(const Node *N); |
||
242 | Leaf *getSwitchKeyword(); |
||
243 | Statement *getBody(); |
||
244 | }; |
||
245 | |||
246 | /// case <value>: <body> |
||
247 | class CaseStatement final : public Statement { |
||
248 | public: |
||
249 | CaseStatement() : Statement(NodeKind::CaseStatement) {} |
||
250 | static bool classof(const Node *N); |
||
251 | Leaf *getCaseKeyword(); |
||
252 | Expression *getCaseValue(); |
||
253 | Statement *getBody(); |
||
254 | }; |
||
255 | |||
256 | /// default: <body> |
||
257 | class DefaultStatement final : public Statement { |
||
258 | public: |
||
259 | DefaultStatement() : Statement(NodeKind::DefaultStatement) {} |
||
260 | static bool classof(const Node *N); |
||
261 | Leaf *getDefaultKeyword(); |
||
262 | Statement *getBody(); |
||
263 | }; |
||
264 | |||
265 | /// if (cond) <then-statement> else <else-statement> |
||
266 | /// FIXME: add condition that models 'expression or variable declaration' |
||
267 | class IfStatement final : public Statement { |
||
268 | public: |
||
269 | IfStatement() : Statement(NodeKind::IfStatement) {} |
||
270 | static bool classof(const Node *N); |
||
271 | Leaf *getIfKeyword(); |
||
272 | Statement *getThenStatement(); |
||
273 | Leaf *getElseKeyword(); |
||
274 | Statement *getElseStatement(); |
||
275 | }; |
||
276 | |||
277 | /// for (<init>; <cond>; <increment>) <body> |
||
278 | class ForStatement final : public Statement { |
||
279 | public: |
||
280 | ForStatement() : Statement(NodeKind::ForStatement) {} |
||
281 | static bool classof(const Node *N); |
||
282 | Leaf *getForKeyword(); |
||
283 | Statement *getBody(); |
||
284 | }; |
||
285 | |||
286 | /// while (<cond>) <body> |
||
287 | class WhileStatement final : public Statement { |
||
288 | public: |
||
289 | WhileStatement() : Statement(NodeKind::WhileStatement) {} |
||
290 | static bool classof(const Node *N); |
||
291 | Leaf *getWhileKeyword(); |
||
292 | Statement *getBody(); |
||
293 | }; |
||
294 | |||
295 | /// continue; |
||
296 | class ContinueStatement final : public Statement { |
||
297 | public: |
||
298 | ContinueStatement() : Statement(NodeKind::ContinueStatement) {} |
||
299 | static bool classof(const Node *N); |
||
300 | Leaf *getContinueKeyword(); |
||
301 | }; |
||
302 | |||
303 | /// break; |
||
304 | class BreakStatement final : public Statement { |
||
305 | public: |
||
306 | BreakStatement() : Statement(NodeKind::BreakStatement) {} |
||
307 | static bool classof(const Node *N); |
||
308 | Leaf *getBreakKeyword(); |
||
309 | }; |
||
310 | |||
311 | /// return <expr>; |
||
312 | /// return; |
||
313 | class ReturnStatement final : public Statement { |
||
314 | public: |
||
315 | ReturnStatement() : Statement(NodeKind::ReturnStatement) {} |
||
316 | static bool classof(const Node *N); |
||
317 | Leaf *getReturnKeyword(); |
||
318 | Expression *getReturnValue(); |
||
319 | }; |
||
320 | |||
321 | /// for (<decl> : <init>) <body> |
||
322 | class RangeBasedForStatement final : public Statement { |
||
323 | public: |
||
324 | RangeBasedForStatement() : Statement(NodeKind::RangeBasedForStatement) {} |
||
325 | static bool classof(const Node *N); |
||
326 | Leaf *getForKeyword(); |
||
327 | Statement *getBody(); |
||
328 | }; |
||
329 | |||
330 | /// Expression in a statement position, e.g. functions calls inside compound |
||
331 | /// statements or inside a loop body. |
||
332 | class ExpressionStatement final : public Statement { |
||
333 | public: |
||
334 | ExpressionStatement() : Statement(NodeKind::ExpressionStatement) {} |
||
335 | static bool classof(const Node *N); |
||
336 | Expression *getExpression(); |
||
337 | }; |
||
338 | |||
339 | /// { statement1; statement2; … } |
||
340 | class CompoundStatement final : public Statement { |
||
341 | public: |
||
342 | CompoundStatement() : Statement(NodeKind::CompoundStatement) {} |
||
343 | static bool classof(const Node *N); |
||
344 | Leaf *getLbrace(); |
||
345 | /// FIXME: use custom iterator instead of 'vector'. |
||
346 | std::vector<Statement *> getStatements(); |
||
347 | Leaf *getRbrace(); |
||
348 | }; |
||
349 | |||
350 | /// A declaration that can appear at the top-level. Note that this does *not* |
||
351 | /// correspond 1-to-1 to clang::Decl. Syntax trees distinguish between top-level |
||
352 | /// declarations (e.g. namespace definitions) and declarators (e.g. variables, |
||
353 | /// typedefs, etc.). Declarators are stored inside SimpleDeclaration. |
||
354 | class Declaration : public Tree { |
||
355 | public: |
||
356 | Declaration(NodeKind K) : Tree(K) {} |
||
357 | static bool classof(const Node *N); |
||
358 | }; |
||
359 | |||
360 | /// Declaration of an unknown kind, e.g. not yet supported in syntax trees. |
||
361 | class UnknownDeclaration final : public Declaration { |
||
362 | public: |
||
363 | UnknownDeclaration() : Declaration(NodeKind::UnknownDeclaration) {} |
||
364 | static bool classof(const Node *N); |
||
365 | }; |
||
366 | |||
367 | /// A semicolon in the top-level context. Does not declare anything. |
||
368 | class EmptyDeclaration final : public Declaration { |
||
369 | public: |
||
370 | EmptyDeclaration() : Declaration(NodeKind::EmptyDeclaration) {} |
||
371 | static bool classof(const Node *N); |
||
372 | }; |
||
373 | |||
374 | /// static_assert(<condition>, <message>) |
||
375 | /// static_assert(<condition>) |
||
376 | class StaticAssertDeclaration final : public Declaration { |
||
377 | public: |
||
378 | StaticAssertDeclaration() : Declaration(NodeKind::StaticAssertDeclaration) {} |
||
379 | static bool classof(const Node *N); |
||
380 | Expression *getCondition(); |
||
381 | Expression *getMessage(); |
||
382 | }; |
||
383 | |||
384 | /// extern <string-literal> declaration |
||
385 | /// extern <string-literal> { <decls> } |
||
386 | class LinkageSpecificationDeclaration final : public Declaration { |
||
387 | public: |
||
388 | LinkageSpecificationDeclaration() |
||
389 | : Declaration(NodeKind::LinkageSpecificationDeclaration) {} |
||
390 | static bool classof(const Node *N); |
||
391 | }; |
||
392 | |||
393 | class DeclaratorList final : public List { |
||
394 | public: |
||
395 | DeclaratorList() : List(NodeKind::DeclaratorList) {} |
||
396 | static bool classof(const Node *N); |
||
397 | std::vector<SimpleDeclarator *> getDeclarators(); |
||
398 | std::vector<List::ElementAndDelimiter<syntax::SimpleDeclarator>> |
||
399 | getDeclaratorsAndCommas(); |
||
400 | }; |
||
401 | |||
402 | /// Groups multiple declarators (e.g. variables, typedefs, etc.) together. All |
||
403 | /// grouped declarators share the same declaration specifiers (e.g. 'int' or |
||
404 | /// 'typedef'). |
||
405 | class SimpleDeclaration final : public Declaration { |
||
406 | public: |
||
407 | SimpleDeclaration() : Declaration(NodeKind::SimpleDeclaration) {} |
||
408 | static bool classof(const Node *N); |
||
409 | /// FIXME: use custom iterator instead of 'vector'. |
||
410 | std::vector<SimpleDeclarator *> getDeclarators(); |
||
411 | }; |
||
412 | |||
413 | /// template <template-parameters> <declaration> |
||
414 | class TemplateDeclaration final : public Declaration { |
||
415 | public: |
||
416 | TemplateDeclaration() : Declaration(NodeKind::TemplateDeclaration) {} |
||
417 | static bool classof(const Node *N); |
||
418 | Leaf *getTemplateKeyword(); |
||
419 | Declaration *getDeclaration(); |
||
420 | }; |
||
421 | |||
422 | /// template <declaration> |
||
423 | /// Examples: |
||
424 | /// template struct X<int> |
||
425 | /// template void foo<int>() |
||
426 | /// template int var<double> |
||
427 | class ExplicitTemplateInstantiation final : public Declaration { |
||
428 | public: |
||
429 | ExplicitTemplateInstantiation() |
||
430 | : Declaration(NodeKind::ExplicitTemplateInstantiation) {} |
||
431 | static bool classof(const Node *N); |
||
432 | Leaf *getTemplateKeyword(); |
||
433 | Leaf *getExternKeyword(); |
||
434 | Declaration *getDeclaration(); |
||
435 | }; |
||
436 | |||
437 | /// namespace <name> { <decls> } |
||
438 | class NamespaceDefinition final : public Declaration { |
||
439 | public: |
||
440 | NamespaceDefinition() : Declaration(NodeKind::NamespaceDefinition) {} |
||
441 | static bool classof(const Node *N); |
||
442 | }; |
||
443 | |||
444 | /// namespace <name> = <namespace-reference> |
||
445 | class NamespaceAliasDefinition final : public Declaration { |
||
446 | public: |
||
447 | NamespaceAliasDefinition() |
||
448 | : Declaration(NodeKind::NamespaceAliasDefinition) {} |
||
449 | static bool classof(const Node *N); |
||
450 | }; |
||
451 | |||
452 | /// using namespace <name> |
||
453 | class UsingNamespaceDirective final : public Declaration { |
||
454 | public: |
||
455 | UsingNamespaceDirective() : Declaration(NodeKind::UsingNamespaceDirective) {} |
||
456 | static bool classof(const Node *N); |
||
457 | }; |
||
458 | |||
459 | /// using <scope>::<name> |
||
460 | /// using typename <scope>::<name> |
||
461 | class UsingDeclaration final : public Declaration { |
||
462 | public: |
||
463 | UsingDeclaration() : Declaration(NodeKind::UsingDeclaration) {} |
||
464 | static bool classof(const Node *N); |
||
465 | }; |
||
466 | |||
467 | /// using <name> = <type> |
||
468 | class TypeAliasDeclaration final : public Declaration { |
||
469 | public: |
||
470 | TypeAliasDeclaration() : Declaration(NodeKind::TypeAliasDeclaration) {} |
||
471 | static bool classof(const Node *N); |
||
472 | }; |
||
473 | |||
474 | /// Covers a name, an initializer and a part of the type outside declaration |
||
475 | /// specifiers. Examples are: |
||
476 | /// `*a` in `int *a` |
||
477 | /// `a[10]` in `int a[10]` |
||
478 | /// `*a = nullptr` in `int *a = nullptr` |
||
479 | /// Declarators can be unnamed too: |
||
480 | /// `**` in `new int**` |
||
481 | /// `* = nullptr` in `void foo(int* = nullptr)` |
||
482 | /// Most declarators you encounter are instances of SimpleDeclarator. They may |
||
483 | /// contain an inner declarator inside parentheses, we represent it as |
||
484 | /// ParenDeclarator. E.g. |
||
485 | /// `(*a)` in `int (*a) = 10` |
||
486 | class Declarator : public Tree { |
||
487 | public: |
||
488 | Declarator(NodeKind K) : Tree(K) {} |
||
489 | static bool classof(const Node *N); |
||
490 | }; |
||
491 | |||
492 | /// A top-level declarator without parentheses. See comment of Declarator for |
||
493 | /// more details. |
||
494 | class SimpleDeclarator final : public Declarator { |
||
495 | public: |
||
496 | SimpleDeclarator() : Declarator(NodeKind::SimpleDeclarator) {} |
||
497 | static bool classof(const Node *N); |
||
498 | }; |
||
499 | |||
500 | /// Declarator inside parentheses. |
||
501 | /// E.g. `(***a)` from `int (***a) = nullptr;` |
||
502 | /// See comment of Declarator for more details. |
||
503 | class ParenDeclarator final : public Declarator { |
||
504 | public: |
||
505 | ParenDeclarator() : Declarator(NodeKind::ParenDeclarator) {} |
||
506 | static bool classof(const Node *N); |
||
507 | Leaf *getLparen(); |
||
508 | Leaf *getRparen(); |
||
509 | }; |
||
510 | |||
511 | /// Array size specified inside a declarator. |
||
512 | /// E.g: |
||
513 | /// `[10]` in `int a[10];` |
||
514 | /// `[static 10]` in `void f(int xs[static 10]);` |
||
515 | class ArraySubscript final : public Tree { |
||
516 | public: |
||
517 | ArraySubscript() : Tree(NodeKind::ArraySubscript) {} |
||
518 | static bool classof(const Node *N); |
||
519 | // TODO: add an accessor for the "static" keyword. |
||
520 | Leaf *getLbracket(); |
||
521 | Expression *getSize(); |
||
522 | Leaf *getRbracket(); |
||
523 | }; |
||
524 | |||
525 | /// Trailing return type after the parameter list, including the arrow token. |
||
526 | /// E.g. `-> int***`. |
||
527 | class TrailingReturnType final : public Tree { |
||
528 | public: |
||
529 | TrailingReturnType() : Tree(NodeKind::TrailingReturnType) {} |
||
530 | static bool classof(const Node *N); |
||
531 | // TODO: add accessors for specifiers. |
||
532 | Leaf *getArrowToken(); |
||
533 | // FIXME: This should be a `type-id` following the grammar. Fix this once we |
||
534 | // have a representation of `type-id`s. |
||
535 | SimpleDeclarator *getDeclarator(); |
||
536 | }; |
||
537 | |||
538 | /// Models a `parameter-declaration-list` which appears within |
||
539 | /// `parameters-and-qualifiers`. See C++ [dcl.fct] |
||
540 | class ParameterDeclarationList final : public List { |
||
541 | public: |
||
542 | ParameterDeclarationList() : List(NodeKind::ParameterDeclarationList) {} |
||
543 | static bool classof(const Node *N); |
||
544 | std::vector<SimpleDeclaration *> getParameterDeclarations(); |
||
545 | std::vector<List::ElementAndDelimiter<syntax::SimpleDeclaration>> |
||
546 | getParametersAndCommas(); |
||
547 | }; |
||
548 | |||
549 | /// Parameter list for a function type and a trailing return type, if the |
||
550 | /// function has one. |
||
551 | /// E.g.: |
||
552 | /// `(int a) volatile ` in `int foo(int a) volatile;` |
||
553 | /// `(int a) &&` in `int foo(int a) &&;` |
||
554 | /// `() -> int` in `auto foo() -> int;` |
||
555 | /// `() const` in `int foo() const;` |
||
556 | /// `() noexcept` in `int foo() noexcept;` |
||
557 | /// `() throw()` in `int foo() throw();` |
||
558 | /// |
||
559 | /// (!) override doesn't belong here. |
||
560 | class ParametersAndQualifiers final : public Tree { |
||
561 | public: |
||
562 | ParametersAndQualifiers() : Tree(NodeKind::ParametersAndQualifiers) {} |
||
563 | static bool classof(const Node *N); |
||
564 | Leaf *getLparen(); |
||
565 | ParameterDeclarationList *getParameters(); |
||
566 | Leaf *getRparen(); |
||
567 | TrailingReturnType *getTrailingReturn(); |
||
568 | }; |
||
569 | |||
570 | /// Member pointer inside a declarator |
||
571 | /// E.g. `X::*` in `int X::* a = 0;` |
||
572 | class MemberPointer final : public Tree { |
||
573 | public: |
||
574 | MemberPointer() : Tree(NodeKind::MemberPointer) {} |
||
575 | static bool classof(const Node *N); |
||
576 | }; |
||
577 | |||
578 | #define CONCRETE_NODE(Kind, Base) \ |
||
579 | inline bool Kind::classof(const Node *N) { \ |
||
580 | return N->getKind() == NodeKind::Kind; \ |
||
581 | } |
||
582 | #define ABSTRACT_NODE(Kind, Base, First, Last) \ |
||
583 | inline bool Kind::classof(const Node *N) { \ |
||
584 | return N->getKind() >= NodeKind::First && N->getKind() <= NodeKind::Last; \ |
||
585 | } |
||
586 | #include "clang/Tooling/Syntax/Nodes.inc" |
||
587 | |||
588 | } // namespace syntax |
||
589 | } // namespace clang |
||
590 | #endif |