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