//===- Nodes.td - Node types in the Syntax Tree grammar -------------------===// // // 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 // //===----------------------------------------------------------------------===// // // This file defines concrete nodes in the syntax tree. // The archetypes they fall into (Sequence, List etc) are defined in Syntax.td. // // The C++ classes for the archetypes themselves are written by hand, and the // concrete node classes will be generated. Migration to TableGen is not // complete, so currently there is a mix of generated and hand-authored code. // //===----------------------------------------------------------------------===// include "clang/Tooling/Syntax/Syntax.td" def TranslationUnit : Unconstrained { let documentation = [{ A root node for a translation unit. Parent is always null. }]; } def UnqualifiedId : External<Tree> {} // Lists def List : External<Tree> {} def DeclaratorList : External<List> {} def ParameterDeclarationList : External<List> {} def CallArguments : External<List> {} def NestedNameSpecifier : External<List> {} def Expression : Alternatives { let documentation = [{ A base class for all expressions. Note that expressions are not statements, even though they are in clang. }]; } def UnknownExpression : External<Expression> {} def UnaryOperatorExpression : External<Tree> {} def PrefixUnaryOperatorExpression : External<UnaryOperatorExpression> {} def PostfixUnaryOperatorExpression : External<UnaryOperatorExpression> {} def BinaryOperatorExpression : External<Expression> {} def ParenExpression : Sequence<Expression> { let documentation = [{ Models a parenthesized expression `(E)`. C++ [expr.prim.paren] e.g. `(3 + 2)` in `a = 1 + (3 + 2);` }]; let children = [ Role<"OpenParen", Token<"l_paren">>, Role<"SubExpression", Expression>, Role<"CloseParen", Token<"r_paren">>, ]; } def LiteralExpression : Alternatives<Expression> { let documentation = [{ Expression for literals. C++ [lex.literal] }]; } def IntegerLiteralExpression : Sequence<LiteralExpression> { let documentation = [{ Expression for integer literals. C++ [lex.icon] }]; let children = [ Role<"LiteralToken", Token<"numeric_constant">>, ]; } defvar AnyCharacterLiteral = AnyToken<[ "char_constant", "wide_char_constant", "utf8_char_constant", "utf16_char_constant", "utf32_char_constant" ]>; def CharacterLiteralExpression : Sequence<LiteralExpression> { let documentation = [{ Expression for character literals. C++ [lex.ccon] }]; let children = [ Role<"LiteralToken", AnyCharacterLiteral>, ]; } def FloatingLiteralExpression : Sequence<LiteralExpression> { let documentation = [{ Expression for floating-point literals. C++ [lex.fcon] }]; let children = [ Role<"LiteralToken", Token<"numeric_constant">>, ]; } defvar AnyStringLiteral = AnyToken<[ "string_literal", "wide_string_literal", "utf8_string_literal", "utf16_string_literal", "utf32_string_literal" ]>; def StringLiteralExpression : Sequence<LiteralExpression> { let documentation = [{ Expression for string-literals. C++ [lex.string] }]; // FIXME: string literals may consist of multiple tokens. // These are merged in phase 6, but tokens are captured after phase 4. // The child here should be a list of literal tokens instead. let children = [ Role<"LiteralToken", AnyStringLiteral>, ]; } def BoolLiteralExpression : Sequence<LiteralExpression> { let documentation = [{ Expression for boolean literals. C++ [lex.bool] }]; let children = [ Role<"LiteralToken", AnyToken<["kw_false","kw_true"]>>, ]; } def CxxNullPtrExpression : Sequence<LiteralExpression> { let documentation = [{ Expression for the `nullptr` literal. C++ [lex.nullptr] }]; let children = [ Role<"LiteralToken", Keyword<"nullptr">>, ]; } def UserDefinedLiteralExpression : Alternatives<LiteralExpression> { let documentation = [{ Expression for user-defined literal. C++ [lex.ext] user-defined-literal: user-defined-integer-literal user-defined-floating-point-literal user-defined-string-literal user-defined-character-literal }]; } def IntegerUserDefinedLiteralExpression : Sequence<UserDefinedLiteralExpression> { let documentation = [{ Expression for user-defined-integer-literal. C++ [lex.ext] }]; let children = [ Role<"LiteralToken", Keyword<"numeric_constant">>, ]; } def FloatUserDefinedLiteralExpression : Sequence<UserDefinedLiteralExpression> { let documentation = [{ Expression for user-defined-floating-point-literal. C++ [lex.ext] }]; let children = [ Role<"LiteralToken", Keyword<"numeric_constant">>, ]; } def CharUserDefinedLiteralExpression : Sequence<UserDefinedLiteralExpression> { let documentation = [{ Expression for user-defined-character-literal. C++ [lex.ext] }]; let children = [ Role<"LiteralToken", AnyCharacterLiteral>, ]; } def StringUserDefinedLiteralExpression : Sequence<UserDefinedLiteralExpression> { let documentation = [{ Expression for user-defined-string-literal. C++ [lex.ext] }]; let children = [ Role<"LiteralToken", AnyStringLiteral>, ]; } def IdExpression : Sequence<Expression> { let documentation = [{ Models an `id-expression`, e.g. `std::vector<int>::size`. C++ [expr.prim.id] id-expression: unqualified-id qualified-id qualified-id: nested-name-specifier template_opt unqualified-id }]; let children = [ Role<"Qualifier", Optional<NestedNameSpecifier>>, Role<"TemplateKeyword", Optional<Keyword<"template">>>, Role<"UnqualifiedId", UnqualifiedId>, ]; } def MemberExpression : Sequence<Expression> { let documentation = [{ Models a class member access. C++ [expr.ref] member-expression: expression -> template_opt id-expression expression . template_opt id-expression e.g. `x.a`, `xp->a` Note: An implicit member access inside a class, i.e. `a` instead of `this->a`, is an `id-expression`. }]; let children = [ Role<"Object", Expression>, Role<"AccessToken", AnyToken<["period","arrow"]>>, Role<"TemplateKeyword", Optional<Keyword<"template">>>, Role<"Member", IdExpression>, ]; } def ThisExpression : Sequence<Expression> { let documentation = [{ Models a this expression `this`. C++ [expr.prim.this] }]; let children = [ Role<"IntroducerKeyword", Keyword<"this">>, ]; } def CallExpression : Sequence<Expression> { let documentation = [{ A function call. C++ [expr.call] call-expression: expression '(' call-arguments ')' e.g `f(1, '2')` or `this->Base::f()` }]; let children = [ Role<"Callee", Expression>, Role<"OpenParen", Token<"l_paren">>, Role<"Arguments", CallArguments>, Role<"CloseParen", Token<"r_paren">>, ]; } // Statements. def Statement : External<Tree> {} def UnknownStatement : External<Statement> {} def DeclarationStatement : External<Statement> {} def EmptyStatement : External<Statement> {} def SwitchStatement : External<Statement> {} def CaseStatement : External<Statement> {} def DefaultStatement : External<Statement> {} def IfStatement : External<Statement> {} def ForStatement : External<Statement> {} def WhileStatement : External<Statement> {} def ContinueStatement : External<Statement> {} def BreakStatement : External<Statement> {} def ReturnStatement : External<Statement> {} def RangeBasedForStatement : External<Statement> {} def ExpressionStatement : External<Statement> {} def CompoundStatement : External<Statement> {} // Declarations. def Declaration : External<Tree> {} def UnknownDeclaration : External<Declaration> {} def EmptyDeclaration : External<Declaration> {} def StaticAssertDeclaration : External<Declaration> {} def LinkageSpecificationDeclaration : External<Declaration> {} def SimpleDeclaration : External<Declaration> {} def TemplateDeclaration : External<Declaration> {} def ExplicitTemplateInstantiation : External<Declaration> {} def NamespaceDefinition : External<Declaration> {} def NamespaceAliasDefinition : External<Declaration> {} def UsingNamespaceDirective : External<Declaration> {} def UsingDeclaration : External<Declaration> {} def TypeAliasDeclaration : External<Declaration> {} // Declarators. def Declarator : External<Tree> {} def SimpleDeclarator : External<Declarator> {} def ParenDeclarator : External<Declarator> {} def ArraySubscript : External<Tree> {} def TrailingReturnType : External<Tree> {} def ParametersAndQualifiers : External<Tree> {} def MemberPointer : External<Tree> {} // Name Specifiers. def NameSpecifier : Alternatives { let documentation = [{ A sequence of these specifiers make a `nested-name-specifier`. e.g. the `std` or `vector<int>` in `std::vector<int>::size`. }]; } def GlobalNameSpecifier : Unconstrained<NameSpecifier> { let documentation = [{ The global namespace name specifier, this specifier doesn't correspond to a token instead an absence of tokens before a `::` characterizes it, in `::std::vector<int>` it would be characterized by the absence of a token before the first `::` }]; } def DecltypeNameSpecifier : Unconstrained<NameSpecifier> { let documentation = [{ A name specifier holding a decltype, of the form: `decltype ( expression ) ` e.g. the `decltype(s)` in `decltype(s)::size`. }]; } def IdentifierNameSpecifier : Unconstrained<NameSpecifier> { let documentation = [{ A identifier name specifier, of the form `identifier` e.g. the `std` in `std::vector<int>::size`. }]; } def SimpleTemplateNameSpecifier : Unconstrained<NameSpecifier> { let documentation = [{ A name specifier with a simple-template-id, of the form `template_opt identifier < template-args >` e.g. the `vector<int>` in `std::vector<int>::size`. }]; }