//===- Nodes.h - syntax nodes for C/C++ grammar constructs ----*- C++ -*-=====// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // Syntax tree nodes for C, C++ and Objective-C grammar constructs. // // Nodes provide access to their syntactic components, e.g. IfStatement provides // a way to get its condition, then and else branches, tokens for 'if' and // 'else' keywords. // When using the accessors, please assume they can return null. This happens // because: // - the corresponding subnode is optional in the C++ grammar, e.g. an else // branch of an if statement, // - syntactic errors occurred while parsing the corresponding subnode. // One notable exception is "introducer" keywords, e.g. the accessor for the // 'if' keyword of an if statement will never return null. //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_TOOLING_SYNTAX_NODES_H #define LLVM_CLANG_TOOLING_SYNTAX_NODES_H #include "clang/Basic/LLVM.h" #include "clang/Tooling/Syntax/Tree.h" namespace clang { namespace syntax { /// A kind of a syntax node, used for implementing casts. The ordering and /// blocks of enumerator constants must correspond to the inheritance hierarchy /// of syntax::Node. enum class NodeKind : uint16_t { … }; /// For debugging purposes. raw_ostream &operator<<(raw_ostream &OS, NodeKind K); /// A relation between a parent and child node, e.g. 'left-hand-side of /// a binary expression'. Used for implementing accessors. /// /// In general `NodeRole`s should be named the same as their accessors. /// /// Some roles describe parent/child relations that occur multiple times in /// language grammar. We define only one role to describe all instances of such /// recurring relations. For example, grammar for both "if" and "while" /// statements requires an opening paren and a closing paren. The opening /// paren token is assigned the OpenParen role regardless of whether it appears /// as a child of IfStatement or WhileStatement node. More generally, when /// grammar requires a certain fixed token (like a specific keyword, or an /// opening paren), we define a role for this token and use it across all /// grammar rules with the same requirement. Names of such reusable roles end /// with a ~Token or a ~Keyword suffix. enum class NodeRole : uint8_t { … }; /// For debugging purposes. raw_ostream &operator<<(raw_ostream &OS, NodeRole R); #include "clang/Tooling/Syntax/NodeClasses.inc" /// Models a `nested-name-specifier`. C++ [expr.prim.id.qual] /// e.g. the `std::vector<int>::` in `std::vector<int>::size`. class NestedNameSpecifier final : public List { … }; /// Models an `unqualified-id`. C++ [expr.prim.id.unqual] /// e.g. the `size` in `std::vector<int>::size`. class UnqualifiedId final : public Tree { … }; /// An expression of an unknown kind, i.e. one not currently handled by the /// syntax tree. class UnknownExpression final : public Expression { … }; /// Models arguments of a function call. /// call-arguments: /// delimited_list(expression, ',') /// Note: This construct is a simplification of the grammar rule for /// `expression-list`, that is used in the definition of `call-expression` class CallArguments final : public List { … }; /// An abstract class for prefix and postfix unary operators. class UnaryOperatorExpression : public Expression { … }; /// <operator> <operand> /// /// For example: /// +a -b /// !c not c /// ~d compl d /// *e &f /// ++h --h /// __real i __imag i class PrefixUnaryOperatorExpression final : public UnaryOperatorExpression { … }; /// <operand> <operator> /// /// For example: /// a++ /// b-- class PostfixUnaryOperatorExpression final : public UnaryOperatorExpression { … }; /// <lhs> <operator> <rhs> /// /// For example: /// a + b /// a bitor 1 /// a |= b /// a and_eq b class BinaryOperatorExpression final : public Expression { … }; /// An abstract node for C++ statements, e.g. 'while', 'if', etc. /// FIXME: add accessors for semicolon of statements that have it. class Statement : public Tree { … }; /// A statement of an unknown kind, i.e. one not currently handled by the syntax /// tree. class UnknownStatement final : public Statement { … }; /// E.g. 'int a, b = 10;' class DeclarationStatement final : public Statement { … }; /// The no-op statement, i.e. ';'. class EmptyStatement final : public Statement { … }; /// switch (<cond>) <body> class SwitchStatement final : public Statement { … }; /// case <value>: <body> class CaseStatement final : public Statement { … }; /// default: <body> class DefaultStatement final : public Statement { … }; /// if (cond) <then-statement> else <else-statement> /// FIXME: add condition that models 'expression or variable declaration' class IfStatement final : public Statement { … }; /// for (<init>; <cond>; <increment>) <body> class ForStatement final : public Statement { … }; /// while (<cond>) <body> class WhileStatement final : public Statement { … }; /// continue; class ContinueStatement final : public Statement { … }; /// break; class BreakStatement final : public Statement { … }; /// return <expr>; /// return; class ReturnStatement final : public Statement { … }; /// for (<decl> : <init>) <body> class RangeBasedForStatement final : public Statement { … }; /// Expression in a statement position, e.g. functions calls inside compound /// statements or inside a loop body. class ExpressionStatement final : public Statement { … }; /// { statement1; statement2; … } class CompoundStatement final : public Statement { … }; /// A declaration that can appear at the top-level. Note that this does *not* /// correspond 1-to-1 to clang::Decl. Syntax trees distinguish between top-level /// declarations (e.g. namespace definitions) and declarators (e.g. variables, /// typedefs, etc.). Declarators are stored inside SimpleDeclaration. class Declaration : public Tree { … }; /// Declaration of an unknown kind, e.g. not yet supported in syntax trees. class UnknownDeclaration final : public Declaration { … }; /// A semicolon in the top-level context. Does not declare anything. class EmptyDeclaration final : public Declaration { … }; /// static_assert(<condition>, <message>) /// static_assert(<condition>) class StaticAssertDeclaration final : public Declaration { … }; /// extern <string-literal> declaration /// extern <string-literal> { <decls> } class LinkageSpecificationDeclaration final : public Declaration { … }; class DeclaratorList final : public List { … }; /// Groups multiple declarators (e.g. variables, typedefs, etc.) together. All /// grouped declarators share the same declaration specifiers (e.g. 'int' or /// 'typedef'). class SimpleDeclaration final : public Declaration { … }; /// template <template-parameters> <declaration> class TemplateDeclaration final : public Declaration { … }; /// template <declaration> /// Examples: /// template struct X<int> /// template void foo<int>() /// template int var<double> class ExplicitTemplateInstantiation final : public Declaration { … }; /// namespace <name> { <decls> } class NamespaceDefinition final : public Declaration { … }; /// namespace <name> = <namespace-reference> class NamespaceAliasDefinition final : public Declaration { … }; /// using namespace <name> class UsingNamespaceDirective final : public Declaration { … }; /// using <scope>::<name> /// using typename <scope>::<name> class UsingDeclaration final : public Declaration { … }; /// using <name> = <type> class TypeAliasDeclaration final : public Declaration { … }; /// Covers a name, an initializer and a part of the type outside declaration /// specifiers. Examples are: /// `*a` in `int *a` /// `a[10]` in `int a[10]` /// `*a = nullptr` in `int *a = nullptr` /// Declarators can be unnamed too: /// `**` in `new int**` /// `* = nullptr` in `void foo(int* = nullptr)` /// Most declarators you encounter are instances of SimpleDeclarator. They may /// contain an inner declarator inside parentheses, we represent it as /// ParenDeclarator. E.g. /// `(*a)` in `int (*a) = 10` class Declarator : public Tree { … }; /// A top-level declarator without parentheses. See comment of Declarator for /// more details. class SimpleDeclarator final : public Declarator { … }; /// Declarator inside parentheses. /// E.g. `(***a)` from `int (***a) = nullptr;` /// See comment of Declarator for more details. class ParenDeclarator final : public Declarator { … }; /// Array size specified inside a declarator. /// E.g: /// `[10]` in `int a[10];` /// `[static 10]` in `void f(int xs[static 10]);` class ArraySubscript final : public Tree { … }; /// Trailing return type after the parameter list, including the arrow token. /// E.g. `-> int***`. class TrailingReturnType final : public Tree { … }; /// Models a `parameter-declaration-list` which appears within /// `parameters-and-qualifiers`. See C++ [dcl.fct] class ParameterDeclarationList final : public List { … }; /// Parameter list for a function type and a trailing return type, if the /// function has one. /// E.g.: /// `(int a) volatile ` in `int foo(int a) volatile;` /// `(int a) &&` in `int foo(int a) &&;` /// `() -> int` in `auto foo() -> int;` /// `() const` in `int foo() const;` /// `() noexcept` in `int foo() noexcept;` /// `() throw()` in `int foo() throw();` /// /// (!) override doesn't belong here. class ParametersAndQualifiers final : public Tree { … }; /// Member pointer inside a declarator /// E.g. `X::*` in `int X::* a = 0;` class MemberPointer final : public Tree { … }; #define CONCRETE_NODE … #define ABSTRACT_NODE … #include "clang/Tooling/Syntax/Nodes.inc" } // namespace syntax } // namespace clang #endif