xref: /freebsd/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Nodes.h (revision fcaf7f8644a9988098ac6be2165bce3ea4786e91)
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:
NestedNameSpecifier()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:
UnqualifiedId()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:
UnknownExpression()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:
CallArguments()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:
UnaryOperatorExpression(NodeKind K)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:
PrefixUnaryOperatorExpression()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:
PostfixUnaryOperatorExpression()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:
BinaryOperatorExpression()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:
Statement(NodeKind K)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:
UnknownStatement()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:
DeclarationStatement()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:
EmptyStatement()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:
SwitchStatement()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:
CaseStatement()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:
DefaultStatement()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:
IfStatement()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:
ForStatement()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:
WhileStatement()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:
ContinueStatement()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:
BreakStatement()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:
ReturnStatement()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:
RangeBasedForStatement()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:
ExpressionStatement()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:
CompoundStatement()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:
Declaration(NodeKind K)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:
UnknownDeclaration()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:
EmptyDeclaration()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:
StaticAssertDeclaration()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:
LinkageSpecificationDeclaration()388   LinkageSpecificationDeclaration()
389       : Declaration(NodeKind::LinkageSpecificationDeclaration) {}
390   static bool classof(const Node *N);
391 };
392 
393 class DeclaratorList final : public List {
394 public:
DeclaratorList()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:
SimpleDeclaration()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:
TemplateDeclaration()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:
ExplicitTemplateInstantiation()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:
NamespaceDefinition()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:
NamespaceAliasDefinition()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:
UsingNamespaceDirective()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:
UsingDeclaration()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:
TypeAliasDeclaration()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:
Declarator(NodeKind K)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:
SimpleDeclarator()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:
ParenDeclarator()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:
ArraySubscript()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:
TrailingReturnType()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:
ParameterDeclarationList()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:
ParametersAndQualifiers()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:
MemberPointer()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
591