Home | History | Annotate | Line # | Download | only in Syntax
      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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    393   LinkageSpecificationDeclaration()
    394       : Declaration(NodeKind::LinkageSpecificationDeclaration) {}
    395   static bool classof(const Node *N);
    396 };
    397 
    398 class DeclaratorList final : public List {
    399 public:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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