llvm/clang/include/clang/Tooling/Syntax/Nodes.h

//===- 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