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"
31namespace clang {
32namespace 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.
37enum class NodeKind : uint16_t {
38  Leaf,
39  TranslationUnit,
40
41  // Expressions.
42  UnknownExpression,
43  PrefixUnaryOperatorExpression,
44  PostfixUnaryOperatorExpression,
45  BinaryOperatorExpression,
46  ParenExpression,
47  IntegerLiteralExpression,
48  CharacterLiteralExpression,
49  FloatingLiteralExpression,
50  StringLiteralExpression,
51  BoolLiteralExpression,
52  CxxNullPtrExpression,
53  IntegerUserDefinedLiteralExpression,
54  FloatUserDefinedLiteralExpression,
55  CharUserDefinedLiteralExpression,
56  StringUserDefinedLiteralExpression,
57  IdExpression,
58
59  // Statements.
60  UnknownStatement,
61  DeclarationStatement,
62  EmptyStatement,
63  SwitchStatement,
64  CaseStatement,
65  DefaultStatement,
66  IfStatement,
67  ForStatement,
68  WhileStatement,
69  ContinueStatement,
70  BreakStatement,
71  ReturnStatement,
72  RangeBasedForStatement,
73  ExpressionStatement,
74  CompoundStatement,
75
76  // Declarations.
77  UnknownDeclaration,
78  EmptyDeclaration,
79  StaticAssertDeclaration,
80  LinkageSpecificationDeclaration,
81  SimpleDeclaration,
82  TemplateDeclaration,
83  ExplicitTemplateInstantiation,
84  NamespaceDefinition,
85  NamespaceAliasDefinition,
86  UsingNamespaceDirective,
87  UsingDeclaration,
88  TypeAliasDeclaration,
89
90  // Declarators.
91  SimpleDeclarator,
92  ParenDeclarator,
93
94  ArraySubscript,
95  TrailingReturnType,
96  ParametersAndQualifiers,
97  MemberPointer,
98  NestedNameSpecifier,
99  NameSpecifier,
100  UnqualifiedId
101};
102/// For debugging purposes.
103llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeKind K);
104
105/// A relation between a parent and child node, e.g. 'left-hand-side of
106/// a binary expression'. Used for implementing accessors.
107///
108/// Some roles describe parent/child relations that occur multiple times in
109/// language grammar. We define only one role to describe all instances of such
110/// recurring relations. For example, grammar for both "if" and "while"
111/// statements requires an opening paren and a closing paren. The opening
112/// paren token is assigned the OpenParen role regardless of whether it appears
113/// as a child of IfStatement or WhileStatement node. More generally, when
114/// grammar requires a certain fixed token (like a specific keyword, or an
115/// opening paren), we define a role for this token and use it across all
116/// grammar rules with the same requirement. Names of such reusable roles end
117/// with a ~Token or a ~Keyword suffix.
118///
119/// Some roles are assigned only to child nodes of one specific parent syntax
120/// node type. Names of such roles start with the name of the parent syntax tree
121/// node type. For example, a syntax node with a role
122/// BinaryOperatorExpression_leftHandSide can only appear as a child of a
123/// BinaryOperatorExpression node.
124enum class NodeRole : uint8_t {
125  // Roles common to multiple node kinds.
126  /// A node without a parent
127  Detached,
128  /// Children of an unknown semantic nature, e.g. skipped tokens, comments.
129  Unknown,
130  /// An opening parenthesis in argument lists and blocks, e.g. '{', '(', etc.
131  OpenParen,
132  /// A closing parenthesis in argument lists and blocks, e.g. '}', ')', etc.
133  CloseParen,
134  /// A keywords that introduces some grammar construct, e.g. 'if', 'try', etc.
135  IntroducerKeyword,
136  /// A token that represents a literal, e.g. 'nullptr', '1', 'true', etc.
137  LiteralToken,
138  /// Tokens or Keywords
139  ArrowToken,
140  ExternKeyword,
141  /// An inner statement for those that have only a single child of kind
142  /// statement, e.g. loop body for while, for, etc; inner statement for case,
143  /// default, etc.
144  BodyStatement,
145
146  // Roles specific to particular node kinds.
147  OperatorExpression_operatorToken,
148  UnaryOperatorExpression_operand,
149  BinaryOperatorExpression_leftHandSide,
150  BinaryOperatorExpression_rightHandSide,
151  CaseStatement_value,
152  IfStatement_thenStatement,
153  IfStatement_elseKeyword,
154  IfStatement_elseStatement,
155  ReturnStatement_value,
156  ExpressionStatement_expression,
157  CompoundStatement_statement,
158  StaticAssertDeclaration_condition,
159  StaticAssertDeclaration_message,
160  SimpleDeclaration_declarator,
161  TemplateDeclaration_declaration,
162  ExplicitTemplateInstantiation_declaration,
163  ArraySubscript_sizeExpression,
164  TrailingReturnType_declarator,
165  ParametersAndQualifiers_parameter,
166  ParametersAndQualifiers_trailingReturn,
167  IdExpression_id,
168  IdExpression_qualifier,
169  NestedNameSpecifier_specifier,
170  ParenExpression_subExpression
171};
172/// For debugging purposes.
173llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeRole R);
174
175class SimpleDeclarator;
176
177/// A root node for a translation unit. Parent is always null.
178class TranslationUnit final : public Tree {
179public:
180  TranslationUnit() : Tree(NodeKind::TranslationUnit) {}
181  static bool classof(const Node *N) {
182    return N->kind() == NodeKind::TranslationUnit;
183  }
184};
185
186/// A base class for all expressions. Note that expressions are not statements,
187/// even though they are in clang.
188class Expression : public Tree {
189public:
190  Expression(NodeKind K) : Tree(K) {}
191  static bool classof(const Node *N) {
192    return NodeKind::UnknownExpression <= N->kind() &&
193           N->kind() <= NodeKind::UnknownExpression;
194  }
195};
196
197/// A sequence of these specifiers make a `nested-name-specifier`.
198/// e.g. the `std::` or `vector<int>::` in `std::vector<int>::size`.
199class NameSpecifier final : public Tree {
200public:
201  NameSpecifier() : Tree(NodeKind::NameSpecifier) {}
202  static bool classof(const Node *N) {
203    return N->kind() == NodeKind::NameSpecifier;
204  }
205};
206
207/// Models a `nested-name-specifier`. C++ [expr.prim.id.qual]
208/// e.g. the `std::vector<int>::` in `std::vector<int>::size`.
209class NestedNameSpecifier final : public Tree {
210public:
211  NestedNameSpecifier() : Tree(NodeKind::NestedNameSpecifier) {}
212  static bool classof(const Node *N) {
213    return N->kind() <= NodeKind::NestedNameSpecifier;
214  }
215  std::vector<syntax::NameSpecifier *> specifiers();
216};
217
218/// Models an `unqualified-id`. C++ [expr.prim.id.unqual]
219/// e.g. the `size` in `std::vector<int>::size`.
220class UnqualifiedId final : public Tree {
221public:
222  UnqualifiedId() : Tree(NodeKind::UnqualifiedId) {}
223  static bool classof(const Node *N) {
224    return N->kind() == NodeKind::UnqualifiedId;
225  }
226};
227
228/// Models an `id-expression`, e.g. `std::vector<int>::size`.
229/// C++ [expr.prim.id]
230/// id-expression:
231///   unqualified-id
232///   qualified-id
233/// qualified-id:
234///   nested-name-specifier template_opt unqualified-id
235class IdExpression final : public Expression {
236public:
237  IdExpression() : Expression(NodeKind::IdExpression) {}
238  static bool classof(const Node *N) {
239    return N->kind() == NodeKind::IdExpression;
240  }
241  syntax::NestedNameSpecifier *qualifier();
242  // TODO after expose `id-expression` from `DependentScopeDeclRefExpr`:
243  // Add accessor for `template_opt`.
244  syntax::UnqualifiedId *unqualifiedId();
245};
246
247/// An expression of an unknown kind, i.e. one not currently handled by the
248/// syntax tree.
249class UnknownExpression final : public Expression {
250public:
251  UnknownExpression() : Expression(NodeKind::UnknownExpression) {}
252  static bool classof(const Node *N) {
253    return N->kind() == NodeKind::UnknownExpression;
254  }
255};
256
257/// Models a parenthesized expression `(E)`. C++ [expr.prim.paren]
258/// e.g. `(3 + 2)` in `a = 1 + (3 + 2);`
259class ParenExpression final : public Expression {
260public:
261  ParenExpression() : Expression(NodeKind::ParenExpression) {}
262  static bool classof(const Node *N) {
263    return N->kind() == NodeKind::ParenExpression;
264  }
265  syntax::Leaf *openParen();
266  syntax::Expression *subExpression();
267  syntax::Leaf *closeParen();
268};
269
270/// Expression for integer literals. C++ [lex.icon]
271class IntegerLiteralExpression final : public Expression {
272public:
273  IntegerLiteralExpression() : Expression(NodeKind::IntegerLiteralExpression) {}
274  static bool classof(const Node *N) {
275    return N->kind() == NodeKind::IntegerLiteralExpression;
276  }
277  syntax::Leaf *literalToken();
278};
279
280/// Expression for character literals. C++ [lex.ccon]
281class CharacterLiteralExpression final : public Expression {
282public:
283  CharacterLiteralExpression()
284      : Expression(NodeKind::CharacterLiteralExpression) {}
285  static bool classof(const Node *N) {
286    return N->kind() == NodeKind::CharacterLiteralExpression;
287  }
288  syntax::Leaf *literalToken();
289};
290
291/// Expression for floating-point literals. C++ [lex.fcon]
292class FloatingLiteralExpression final : public Expression {
293public:
294  FloatingLiteralExpression()
295      : Expression(NodeKind::FloatingLiteralExpression) {}
296  static bool classof(const Node *N) {
297    return N->kind() == NodeKind::FloatingLiteralExpression;
298  }
299  syntax::Leaf *literalToken();
300};
301
302/// Expression for string-literals. C++ [lex.string]
303class StringLiteralExpression final : public Expression {
304public:
305  StringLiteralExpression() : Expression(NodeKind::StringLiteralExpression) {}
306  static bool classof(const Node *N) {
307    return N->kind() == NodeKind::StringLiteralExpression;
308  }
309  syntax::Leaf *literalToken();
310};
311
312/// Expression for boolean literals. C++ [lex.bool]
313class BoolLiteralExpression final : public Expression {
314public:
315  BoolLiteralExpression() : Expression(NodeKind::BoolLiteralExpression) {}
316  static bool classof(const Node *N) {
317    return N->kind() == NodeKind::BoolLiteralExpression;
318  }
319  syntax::Leaf *literalToken();
320};
321
322/// Expression for the `nullptr` literal. C++ [lex.nullptr]
323class CxxNullPtrExpression final : public Expression {
324public:
325  CxxNullPtrExpression() : Expression(NodeKind::CxxNullPtrExpression) {}
326  static bool classof(const Node *N) {
327    return N->kind() == NodeKind::CxxNullPtrExpression;
328  }
329  syntax::Leaf *nullPtrKeyword();
330};
331
332/// Expression for user-defined literal. C++ [lex.ext]
333/// user-defined-literal:
334///   user-defined-integer-literal
335///   user-defined-floating-point-literal
336///   user-defined-string-literal
337///   user-defined-character-literal
338class UserDefinedLiteralExpression : public Expression {
339public:
340  UserDefinedLiteralExpression(NodeKind K) : Expression(K) {}
341  static bool classof(const Node *N) {
342    return N->kind() == NodeKind::IntegerUserDefinedLiteralExpression ||
343           N->kind() == NodeKind::FloatUserDefinedLiteralExpression ||
344           N->kind() == NodeKind::CharUserDefinedLiteralExpression ||
345           N->kind() == NodeKind::StringUserDefinedLiteralExpression;
346  }
347  syntax::Leaf *literalToken();
348};
349
350/// Expression for user-defined-integer-literal. C++ [lex.ext]
351class IntegerUserDefinedLiteralExpression final
352    : public UserDefinedLiteralExpression {
353public:
354  IntegerUserDefinedLiteralExpression()
355      : UserDefinedLiteralExpression(
356            NodeKind::IntegerUserDefinedLiteralExpression) {}
357  static bool classof(const Node *N) {
358    return N->kind() == NodeKind::IntegerUserDefinedLiteralExpression;
359  }
360};
361
362/// Expression for user-defined-floating-point-literal. C++ [lex.ext]
363class FloatUserDefinedLiteralExpression final
364    : public UserDefinedLiteralExpression {
365public:
366  FloatUserDefinedLiteralExpression()
367      : UserDefinedLiteralExpression(
368            NodeKind::FloatUserDefinedLiteralExpression) {}
369  static bool classof(const Node *N) {
370    return N->kind() == NodeKind::FloatUserDefinedLiteralExpression;
371  }
372};
373
374/// Expression for user-defined-character-literal. C++ [lex.ext]
375class CharUserDefinedLiteralExpression final
376    : public UserDefinedLiteralExpression {
377public:
378  CharUserDefinedLiteralExpression()
379      : UserDefinedLiteralExpression(
380            NodeKind::CharUserDefinedLiteralExpression) {}
381  static bool classof(const Node *N) {
382    return N->kind() == NodeKind::CharUserDefinedLiteralExpression;
383  }
384};
385
386/// Expression for user-defined-string-literal. C++ [lex.ext]
387class StringUserDefinedLiteralExpression final
388    : public UserDefinedLiteralExpression {
389public:
390  StringUserDefinedLiteralExpression()
391      : UserDefinedLiteralExpression(
392            NodeKind::StringUserDefinedLiteralExpression) {}
393  static bool classof(const Node *N) {
394    return N->kind() == NodeKind::StringUserDefinedLiteralExpression;
395  }
396};
397
398/// An abstract class for prefix and postfix unary operators.
399class UnaryOperatorExpression : public Expression {
400public:
401  UnaryOperatorExpression(NodeKind K) : Expression(K) {}
402  static bool classof(const Node *N) {
403    return N->kind() == NodeKind::PrefixUnaryOperatorExpression ||
404           N->kind() == NodeKind::PostfixUnaryOperatorExpression;
405  }
406  syntax::Leaf *operatorToken();
407  syntax::Expression *operand();
408};
409
410/// <operator> <operand>
411///
412/// For example:
413///   +a          -b
414///   !c          not c
415///   ~d          compl d
416///   *e          &f
417///   ++h         --h
418///   __real i    __imag i
419class PrefixUnaryOperatorExpression final : public UnaryOperatorExpression {
420public:
421  PrefixUnaryOperatorExpression()
422      : UnaryOperatorExpression(NodeKind::PrefixUnaryOperatorExpression) {}
423  static bool classof(const Node *N) {
424    return N->kind() == NodeKind::PrefixUnaryOperatorExpression;
425  }
426};
427
428/// <operand> <operator>
429///
430/// For example:
431///   a++
432///   b--
433class PostfixUnaryOperatorExpression final : public UnaryOperatorExpression {
434public:
435  PostfixUnaryOperatorExpression()
436      : UnaryOperatorExpression(NodeKind::PostfixUnaryOperatorExpression) {}
437  static bool classof(const Node *N) {
438    return N->kind() == NodeKind::PostfixUnaryOperatorExpression;
439  }
440};
441
442/// <lhs> <operator> <rhs>
443///
444/// For example:
445///   a + b
446///   a bitor 1
447///   a |= b
448///   a and_eq b
449class BinaryOperatorExpression final : public Expression {
450public:
451  BinaryOperatorExpression() : Expression(NodeKind::BinaryOperatorExpression) {}
452  static bool classof(const Node *N) {
453    return N->kind() == NodeKind::BinaryOperatorExpression;
454  }
455  syntax::Expression *lhs();
456  syntax::Leaf *operatorToken();
457  syntax::Expression *rhs();
458};
459
460/// An abstract node for C++ statements, e.g. 'while', 'if', etc.
461/// FIXME: add accessors for semicolon of statements that have it.
462class Statement : public Tree {
463public:
464  Statement(NodeKind K) : Tree(K) {}
465  static bool classof(const Node *N) {
466    return NodeKind::UnknownStatement <= N->kind() &&
467           N->kind() <= NodeKind::CompoundStatement;
468  }
469};
470
471/// A statement of an unknown kind, i.e. one not currently handled by the syntax
472/// tree.
473class UnknownStatement final : public Statement {
474public:
475  UnknownStatement() : Statement(NodeKind::UnknownStatement) {}
476  static bool classof(const Node *N) {
477    return N->kind() == NodeKind::UnknownStatement;
478  }
479};
480
481/// E.g. 'int a, b = 10;'
482class DeclarationStatement final : public Statement {
483public:
484  DeclarationStatement() : Statement(NodeKind::DeclarationStatement) {}
485  static bool classof(const Node *N) {
486    return N->kind() == NodeKind::DeclarationStatement;
487  }
488};
489
490/// The no-op statement, i.e. ';'.
491class EmptyStatement final : public Statement {
492public:
493  EmptyStatement() : Statement(NodeKind::EmptyStatement) {}
494  static bool classof(const Node *N) {
495    return N->kind() == NodeKind::EmptyStatement;
496  }
497};
498
499/// switch (<cond>) <body>
500class SwitchStatement final : public Statement {
501public:
502  SwitchStatement() : Statement(NodeKind::SwitchStatement) {}
503  static bool classof(const Node *N) {
504    return N->kind() == NodeKind::SwitchStatement;
505  }
506  syntax::Leaf *switchKeyword();
507  syntax::Statement *body();
508};
509
510/// case <value>: <body>
511class CaseStatement final : public Statement {
512public:
513  CaseStatement() : Statement(NodeKind::CaseStatement) {}
514  static bool classof(const Node *N) {
515    return N->kind() == NodeKind::CaseStatement;
516  }
517  syntax::Leaf *caseKeyword();
518  syntax::Expression *value();
519  syntax::Statement *body();
520};
521
522/// default: <body>
523class DefaultStatement final : public Statement {
524public:
525  DefaultStatement() : Statement(NodeKind::DefaultStatement) {}
526  static bool classof(const Node *N) {
527    return N->kind() == NodeKind::DefaultStatement;
528  }
529  syntax::Leaf *defaultKeyword();
530  syntax::Statement *body();
531};
532
533/// if (cond) <then-statement> else <else-statement>
534/// FIXME: add condition that models 'expression  or variable declaration'
535class IfStatement final : public Statement {
536public:
537  IfStatement() : Statement(NodeKind::IfStatement) {}
538  static bool classof(const Node *N) {
539    return N->kind() == NodeKind::IfStatement;
540  }
541  syntax::Leaf *ifKeyword();
542  syntax::Statement *thenStatement();
543  syntax::Leaf *elseKeyword();
544  syntax::Statement *elseStatement();
545};
546
547/// for (<init>; <cond>; <increment>) <body>
548class ForStatement final : public Statement {
549public:
550  ForStatement() : Statement(NodeKind::ForStatement) {}
551  static bool classof(const Node *N) {
552    return N->kind() == NodeKind::ForStatement;
553  }
554  syntax::Leaf *forKeyword();
555  syntax::Statement *body();
556};
557
558/// while (<cond>) <body>
559class WhileStatement final : public Statement {
560public:
561  WhileStatement() : Statement(NodeKind::WhileStatement) {}
562  static bool classof(const Node *N) {
563    return N->kind() == NodeKind::WhileStatement;
564  }
565  syntax::Leaf *whileKeyword();
566  syntax::Statement *body();
567};
568
569/// continue;
570class ContinueStatement final : public Statement {
571public:
572  ContinueStatement() : Statement(NodeKind::ContinueStatement) {}
573  static bool classof(const Node *N) {
574    return N->kind() == NodeKind::ContinueStatement;
575  }
576  syntax::Leaf *continueKeyword();
577};
578
579/// break;
580class BreakStatement final : public Statement {
581public:
582  BreakStatement() : Statement(NodeKind::BreakStatement) {}
583  static bool classof(const Node *N) {
584    return N->kind() == NodeKind::BreakStatement;
585  }
586  syntax::Leaf *breakKeyword();
587};
588
589/// return <expr>;
590/// return;
591class ReturnStatement final : public Statement {
592public:
593  ReturnStatement() : Statement(NodeKind::ReturnStatement) {}
594  static bool classof(const Node *N) {
595    return N->kind() == NodeKind::ReturnStatement;
596  }
597  syntax::Leaf *returnKeyword();
598  syntax::Expression *value();
599};
600
601/// for (<decl> : <init>) <body>
602class RangeBasedForStatement final : public Statement {
603public:
604  RangeBasedForStatement() : Statement(NodeKind::RangeBasedForStatement) {}
605  static bool classof(const Node *N) {
606    return N->kind() == NodeKind::RangeBasedForStatement;
607  }
608  syntax::Leaf *forKeyword();
609  syntax::Statement *body();
610};
611
612/// Expression in a statement position, e.g. functions calls inside compound
613/// statements or inside a loop body.
614class ExpressionStatement final : public Statement {
615public:
616  ExpressionStatement() : Statement(NodeKind::ExpressionStatement) {}
617  static bool classof(const Node *N) {
618    return N->kind() == NodeKind::ExpressionStatement;
619  }
620  syntax::Expression *expression();
621};
622
623/// { statement1; statement2; ��� }
624class CompoundStatement final : public Statement {
625public:
626  CompoundStatement() : Statement(NodeKind::CompoundStatement) {}
627  static bool classof(const Node *N) {
628    return N->kind() == NodeKind::CompoundStatement;
629  }
630  syntax::Leaf *lbrace();
631  /// FIXME: use custom iterator instead of 'vector'.
632  std::vector<syntax::Statement *> statements();
633  syntax::Leaf *rbrace();
634};
635
636/// A declaration that can appear at the top-level. Note that this does *not*
637/// correspond 1-to-1 to clang::Decl. Syntax trees distinguish between top-level
638/// declarations (e.g. namespace definitions) and declarators (e.g. variables,
639/// typedefs, etc.). Declarators are stored inside SimpleDeclaration.
640class Declaration : public Tree {
641public:
642  Declaration(NodeKind K) : Tree(K) {}
643  static bool classof(const Node *N) {
644    return NodeKind::UnknownDeclaration <= N->kind() &&
645           N->kind() <= NodeKind::TypeAliasDeclaration;
646  }
647};
648
649/// Declaration of an unknown kind, e.g. not yet supported in syntax trees.
650class UnknownDeclaration final : public Declaration {
651public:
652  UnknownDeclaration() : Declaration(NodeKind::UnknownDeclaration) {}
653  static bool classof(const Node *N) {
654    return N->kind() == NodeKind::UnknownDeclaration;
655  }
656};
657
658/// A semicolon in the top-level context. Does not declare anything.
659class EmptyDeclaration final : public Declaration {
660public:
661  EmptyDeclaration() : Declaration(NodeKind::EmptyDeclaration) {}
662  static bool classof(const Node *N) {
663    return N->kind() == NodeKind::EmptyDeclaration;
664  }
665};
666
667/// static_assert(<condition>, <message>)
668/// static_assert(<condition>)
669class StaticAssertDeclaration final : public Declaration {
670public:
671  StaticAssertDeclaration() : Declaration(NodeKind::StaticAssertDeclaration) {}
672  static bool classof(const Node *N) {
673    return N->kind() == NodeKind::StaticAssertDeclaration;
674  }
675  syntax::Expression *condition();
676  syntax::Expression *message();
677};
678
679/// extern <string-literal> declaration
680/// extern <string-literal> { <decls>  }
681class LinkageSpecificationDeclaration final : public Declaration {
682public:
683  LinkageSpecificationDeclaration()
684      : Declaration(NodeKind::LinkageSpecificationDeclaration) {}
685  static bool classof(const Node *N) {
686    return N->kind() == NodeKind::LinkageSpecificationDeclaration;
687  }
688};
689
690/// Groups multiple declarators (e.g. variables, typedefs, etc.) together. All
691/// grouped declarators share the same declaration specifiers (e.g. 'int' or
692/// 'typedef').
693class SimpleDeclaration final : public Declaration {
694public:
695  SimpleDeclaration() : Declaration(NodeKind::SimpleDeclaration) {}
696  static bool classof(const Node *N) {
697    return N->kind() == NodeKind::SimpleDeclaration;
698  }
699  /// FIXME: use custom iterator instead of 'vector'.
700  std::vector<syntax::SimpleDeclarator *> declarators();
701};
702
703/// template <template-parameters> <declaration>
704class TemplateDeclaration final : public Declaration {
705public:
706  TemplateDeclaration() : Declaration(NodeKind::TemplateDeclaration) {}
707  static bool classof(const Node *N) {
708    return N->kind() == NodeKind::TemplateDeclaration;
709  }
710  syntax::Leaf *templateKeyword();
711  syntax::Declaration *declaration();
712};
713
714/// template <declaration>
715/// Examples:
716///     template struct X<int>
717///     template void foo<int>()
718///     template int var<double>
719class ExplicitTemplateInstantiation final : public Declaration {
720public:
721  ExplicitTemplateInstantiation()
722      : Declaration(NodeKind::ExplicitTemplateInstantiation) {}
723  static bool classof(const Node *N) {
724    return N->kind() == NodeKind::ExplicitTemplateInstantiation;
725  }
726  syntax::Leaf *templateKeyword();
727  syntax::Leaf *externKeyword();
728  syntax::Declaration *declaration();
729};
730
731/// namespace <name> { <decls> }
732class NamespaceDefinition final : public Declaration {
733public:
734  NamespaceDefinition() : Declaration(NodeKind::NamespaceDefinition) {}
735  static bool classof(const Node *N) {
736    return N->kind() == NodeKind::NamespaceDefinition;
737  }
738};
739
740/// namespace <name> = <namespace-reference>
741class NamespaceAliasDefinition final : public Declaration {
742public:
743  NamespaceAliasDefinition()
744      : Declaration(NodeKind::NamespaceAliasDefinition) {}
745  static bool classof(const Node *N) {
746    return N->kind() == NodeKind::NamespaceAliasDefinition;
747  }
748};
749
750/// using namespace <name>
751class UsingNamespaceDirective final : public Declaration {
752public:
753  UsingNamespaceDirective() : Declaration(NodeKind::UsingNamespaceDirective) {}
754  static bool classof(const Node *N) {
755    return N->kind() == NodeKind::UsingNamespaceDirective;
756  }
757};
758
759/// using <scope>::<name>
760/// using typename <scope>::<name>
761class UsingDeclaration final : public Declaration {
762public:
763  UsingDeclaration() : Declaration(NodeKind::UsingDeclaration) {}
764  static bool classof(const Node *N) {
765    return N->kind() == NodeKind::UsingDeclaration;
766  }
767};
768
769/// using <name> = <type>
770class TypeAliasDeclaration final : public Declaration {
771public:
772  TypeAliasDeclaration() : Declaration(NodeKind::TypeAliasDeclaration) {}
773  static bool classof(const Node *N) {
774    return N->kind() == NodeKind::TypeAliasDeclaration;
775  }
776};
777
778/// Covers a name, an initializer and a part of the type outside declaration
779/// specifiers. Examples are:
780///     `*a` in `int *a`
781///     `a[10]` in `int a[10]`
782///     `*a = nullptr` in `int *a = nullptr`
783/// Declarators can be unnamed too:
784///     `**` in `new int**`
785///     `* = nullptr` in `void foo(int* = nullptr)`
786/// Most declarators you encounter are instances of SimpleDeclarator. They may
787/// contain an inner declarator inside parentheses, we represent it as
788/// ParenDeclarator. E.g.
789///     `(*a)` in `int (*a) = 10`
790class Declarator : public Tree {
791public:
792  Declarator(NodeKind K) : Tree(K) {}
793  static bool classof(const Node *N) {
794    return NodeKind::SimpleDeclarator <= N->kind() &&
795           N->kind() <= NodeKind::ParenDeclarator;
796  }
797};
798
799/// A top-level declarator without parentheses. See comment of Declarator for
800/// more details.
801class SimpleDeclarator final : public Declarator {
802public:
803  SimpleDeclarator() : Declarator(NodeKind::SimpleDeclarator) {}
804  static bool classof(const Node *N) {
805    return N->kind() == NodeKind::SimpleDeclarator;
806  }
807};
808
809/// Declarator inside parentheses.
810/// E.g. `(***a)` from `int (***a) = nullptr;`
811/// See comment of Declarator for more details.
812class ParenDeclarator final : public Declarator {
813public:
814  ParenDeclarator() : Declarator(NodeKind::ParenDeclarator) {}
815  static bool classof(const Node *N) {
816    return N->kind() == NodeKind::ParenDeclarator;
817  }
818  syntax::Leaf *lparen();
819  syntax::Leaf *rparen();
820};
821
822/// Array size specified inside a declarator.
823/// E.g:
824///   `[10]` in `int a[10];`
825///   `[static 10]` in `void f(int xs[static 10]);`
826class ArraySubscript final : public Tree {
827public:
828  ArraySubscript() : Tree(NodeKind::ArraySubscript) {}
829  static bool classof(const Node *N) {
830    return N->kind() == NodeKind::ArraySubscript;
831  }
832  // TODO: add an accessor for the "static" keyword.
833  syntax::Leaf *lbracket();
834  syntax::Expression *sizeExpression();
835  syntax::Leaf *rbracket();
836};
837
838/// Trailing return type after the parameter list, including the arrow token.
839/// E.g. `-> int***`.
840class TrailingReturnType final : public Tree {
841public:
842  TrailingReturnType() : Tree(NodeKind::TrailingReturnType) {}
843  static bool classof(const Node *N) {
844    return N->kind() == NodeKind::TrailingReturnType;
845  }
846  // TODO: add accessors for specifiers.
847  syntax::Leaf *arrowToken();
848  syntax::SimpleDeclarator *declarator();
849};
850
851/// Parameter list for a function type and a trailing return type, if the
852/// function has one.
853/// E.g.:
854///  `(int a) volatile ` in `int foo(int a) volatile;`
855///  `(int a) &&` in `int foo(int a) &&;`
856///  `() -> int` in `auto foo() -> int;`
857///  `() const` in `int foo() const;`
858///  `() noexcept` in `int foo() noexcept;`
859///  `() throw()` in `int foo() throw();`
860///
861/// (!) override doesn't belong here.
862class ParametersAndQualifiers final : public Tree {
863public:
864  ParametersAndQualifiers() : Tree(NodeKind::ParametersAndQualifiers) {}
865  static bool classof(const Node *N) {
866    return N->kind() == NodeKind::ParametersAndQualifiers;
867  }
868  syntax::Leaf *lparen();
869  /// FIXME: use custom iterator instead of 'vector'.
870  std::vector<syntax::SimpleDeclaration *> parameters();
871  syntax::Leaf *rparen();
872  syntax::TrailingReturnType *trailingReturn();
873};
874
875/// Member pointer inside a declarator
876/// E.g. `X::*` in `int X::* a = 0;`
877class MemberPointer final : public Tree {
878public:
879  MemberPointer() : Tree(NodeKind::MemberPointer) {}
880  static bool classof(const Node *N) {
881    return N->kind() == NodeKind::MemberPointer;
882  }
883};
884
885} // namespace syntax
886} // namespace clang
887#endif
888