1//===- Nodes.td - Node types in the Syntax Tree grammar -------------------===// 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// 9// This file defines concrete nodes in the syntax tree. 10// The archetypes they fall into (Sequence, List etc) are defined in Syntax.td. 11// 12// The C++ classes for the archetypes themselves are written by hand, and the 13// concrete node classes will be generated. Migration to TableGen is not 14// complete, so currently there is a mix of generated and hand-authored code. 15// 16//===----------------------------------------------------------------------===// 17 18include "clang/Tooling/Syntax/Syntax.td" 19 20def TranslationUnit : Unconstrained { 21 let documentation = [{ 22 A root node for a translation unit. Parent is always null. 23 }]; 24} 25 26def UnqualifiedId : External<Tree> {} 27 28// Lists 29def List : External<Tree> {} 30def DeclaratorList : External<List> {} 31def ParameterDeclarationList : External<List> {} 32def CallArguments : External<List> {} 33def NestedNameSpecifier : External<List> {} 34 35def Expression : Alternatives { 36 let documentation = [{ 37 A base class for all expressions. Note that expressions are not statements, 38 even though they are in clang. 39 }]; 40} 41def UnknownExpression : External<Expression> {} 42def UnaryOperatorExpression : External<Tree> {} 43def PrefixUnaryOperatorExpression : External<UnaryOperatorExpression> {} 44def PostfixUnaryOperatorExpression : External<UnaryOperatorExpression> {} 45def BinaryOperatorExpression : External<Expression> {} 46def ParenExpression : Sequence<Expression> { 47 let documentation = [{ 48 Models a parenthesized expression `(E)`. C++ [expr.prim.paren] 49 e.g. `(3 + 2)` in `a = 1 + (3 + 2);` 50 }]; 51 let children = [ 52 Role<"OpenParen", Token<"l_paren">>, 53 Role<"SubExpression", Expression>, 54 Role<"CloseParen", Token<"r_paren">>, 55 ]; 56} 57def LiteralExpression : Alternatives<Expression> { 58 let documentation = [{ 59 Expression for literals. C++ [lex.literal] 60 }]; 61} 62def IntegerLiteralExpression : Sequence<LiteralExpression> { 63 let documentation = [{ 64 Expression for integer literals. C++ [lex.icon] 65 }]; 66 let children = [ 67 Role<"LiteralToken", Token<"numeric_constant">>, 68 ]; 69} 70defvar AnyCharacterLiteral = AnyToken<[ 71 "char_constant", "wide_char_constant", "utf8_char_constant", 72 "utf16_char_constant", "utf32_char_constant" 73]>; 74def CharacterLiteralExpression : Sequence<LiteralExpression> { 75 let documentation = [{ 76 Expression for character literals. C++ [lex.ccon] 77 }]; 78 let children = [ 79 Role<"LiteralToken", AnyCharacterLiteral>, 80 ]; 81} 82def FloatingLiteralExpression : Sequence<LiteralExpression> { 83 let documentation = [{ 84 Expression for floating-point literals. C++ [lex.fcon] 85 }]; 86 let children = [ 87 Role<"LiteralToken", Token<"numeric_constant">>, 88 ]; 89} 90defvar AnyStringLiteral = AnyToken<[ 91 "string_literal", "wide_string_literal", "utf8_string_literal", 92 "utf16_string_literal", "utf32_string_literal" 93]>; 94def StringLiteralExpression : Sequence<LiteralExpression> { 95 let documentation = [{ 96 Expression for string-literals. C++ [lex.string] 97 }]; 98 // FIXME: string literals may consist of multiple tokens. 99 // These are merged in phase 6, but tokens are captured after phase 4. 100 // The child here should be a list of literal tokens instead. 101 let children = [ 102 Role<"LiteralToken", AnyStringLiteral>, 103 ]; 104} 105def BoolLiteralExpression : Sequence<LiteralExpression> { 106 let documentation = [{ 107 Expression for boolean literals. C++ [lex.bool] 108 }]; 109 let children = [ 110 Role<"LiteralToken", AnyToken<["kw_false","kw_true"]>>, 111 ]; 112} 113def CxxNullPtrExpression : Sequence<LiteralExpression> { 114 let documentation = [{ 115 Expression for the `nullptr` literal. C++ [lex.nullptr] 116 }]; 117 let children = [ 118 Role<"LiteralToken", Keyword<"nullptr">>, 119 ]; 120} 121def UserDefinedLiteralExpression : Alternatives<LiteralExpression> { 122 let documentation = [{ 123 Expression for user-defined literal. C++ [lex.ext] 124 user-defined-literal: 125 user-defined-integer-literal 126 user-defined-floating-point-literal 127 user-defined-string-literal 128 user-defined-character-literal 129 }]; 130} 131def IntegerUserDefinedLiteralExpression : Sequence<UserDefinedLiteralExpression> { 132 let documentation = [{ 133 Expression for user-defined-integer-literal. C++ [lex.ext] 134 }]; 135 let children = [ 136 Role<"LiteralToken", Keyword<"numeric_constant">>, 137 ]; 138} 139def FloatUserDefinedLiteralExpression : Sequence<UserDefinedLiteralExpression> { 140 let documentation = [{ 141 Expression for user-defined-floating-point-literal. C++ [lex.ext] 142 }]; 143 let children = [ 144 Role<"LiteralToken", Keyword<"numeric_constant">>, 145 ]; 146} 147def CharUserDefinedLiteralExpression : Sequence<UserDefinedLiteralExpression> { 148 let documentation = [{ 149 Expression for user-defined-character-literal. C++ [lex.ext] 150 }]; 151 let children = [ 152 Role<"LiteralToken", AnyCharacterLiteral>, 153 ]; 154} 155def StringUserDefinedLiteralExpression : Sequence<UserDefinedLiteralExpression> { 156 let documentation = [{ 157 Expression for user-defined-string-literal. C++ [lex.ext] 158 }]; 159 let children = [ 160 Role<"LiteralToken", AnyStringLiteral>, 161 ]; 162} 163def IdExpression : Sequence<Expression> { 164 let documentation = [{ 165 Models an `id-expression`, e.g. `std::vector<int>::size`. 166 C++ [expr.prim.id] 167 id-expression: 168 unqualified-id 169 qualified-id 170 qualified-id: 171 nested-name-specifier template_opt unqualified-id 172 }]; 173 let children = [ 174 Role<"Qualifier", Optional<NestedNameSpecifier>>, 175 Role<"TemplateKeyword", Optional<Keyword<"template">>>, 176 Role<"UnqualifiedId", UnqualifiedId>, 177 ]; 178} 179def MemberExpression : Sequence<Expression> { 180 let documentation = [{ 181 Models a class member access. C++ [expr.ref] 182 member-expression: 183 expression -> template_opt id-expression 184 expression . template_opt id-expression 185 e.g. `x.a`, `xp->a` 186 187 Note: An implicit member access inside a class, i.e. `a` instead of 188 `this->a`, is an `id-expression`. 189 }]; 190 let children = [ 191 Role<"Object", Expression>, 192 Role<"AccessToken", AnyToken<["period","arrow"]>>, 193 Role<"TemplateKeyword", Optional<Keyword<"template">>>, 194 Role<"Member", IdExpression>, 195 ]; 196} 197def ThisExpression : Sequence<Expression> { 198 let documentation = [{ 199 Models a this expression `this`. C++ [expr.prim.this] 200 }]; 201 let children = [ 202 Role<"IntroducerKeyword", Keyword<"this">>, 203 ]; 204} 205def CallExpression : Sequence<Expression> { 206 let documentation = [{ 207 A function call. C++ [expr.call] 208 call-expression: 209 expression '(' call-arguments ')' 210 e.g `f(1, '2')` or `this->Base::f()` 211 }]; 212 let children = [ 213 Role<"Callee", Expression>, 214 Role<"OpenParen", Token<"l_paren">>, 215 Role<"Arguments", CallArguments>, 216 Role<"CloseParen", Token<"r_paren">>, 217 ]; 218} 219 220// Statements. 221def Statement : External<Tree> {} 222def UnknownStatement : External<Statement> {} 223def DeclarationStatement : External<Statement> {} 224def EmptyStatement : External<Statement> {} 225def SwitchStatement : External<Statement> {} 226def CaseStatement : External<Statement> {} 227def DefaultStatement : External<Statement> {} 228def IfStatement : External<Statement> {} 229def ForStatement : External<Statement> {} 230def WhileStatement : External<Statement> {} 231def ContinueStatement : External<Statement> {} 232def BreakStatement : External<Statement> {} 233def ReturnStatement : External<Statement> {} 234def RangeBasedForStatement : External<Statement> {} 235def ExpressionStatement : External<Statement> {} 236def CompoundStatement : External<Statement> {} 237 238// Declarations. 239def Declaration : External<Tree> {} 240def UnknownDeclaration : External<Declaration> {} 241def EmptyDeclaration : External<Declaration> {} 242def StaticAssertDeclaration : External<Declaration> {} 243def LinkageSpecificationDeclaration : External<Declaration> {} 244def SimpleDeclaration : External<Declaration> {} 245def TemplateDeclaration : External<Declaration> {} 246def ExplicitTemplateInstantiation : External<Declaration> {} 247def NamespaceDefinition : External<Declaration> {} 248def NamespaceAliasDefinition : External<Declaration> {} 249def UsingNamespaceDirective : External<Declaration> {} 250def UsingDeclaration : External<Declaration> {} 251def TypeAliasDeclaration : External<Declaration> {} 252 253// Declarators. 254def Declarator : External<Tree> {} 255def SimpleDeclarator : External<Declarator> {} 256def ParenDeclarator : External<Declarator> {} 257 258def ArraySubscript : External<Tree> {} 259def TrailingReturnType : External<Tree> {} 260def ParametersAndQualifiers : External<Tree> {} 261def MemberPointer : External<Tree> {} 262 263// Name Specifiers. 264def NameSpecifier : Alternatives { 265 let documentation = [{ 266 A sequence of these specifiers make a `nested-name-specifier`. 267 e.g. the `std` or `vector<int>` in `std::vector<int>::size`. 268 }]; 269} 270def GlobalNameSpecifier : Unconstrained<NameSpecifier> { 271 let documentation = [{ 272 The global namespace name specifier, this specifier doesn't correspond to a 273 token instead an absence of tokens before a `::` characterizes it, in 274 `::std::vector<int>` it would be characterized by the absence of a token 275 before the first `::` 276 }]; 277} 278def DecltypeNameSpecifier : Unconstrained<NameSpecifier> { 279 let documentation = [{ 280 A name specifier holding a decltype, of the form: `decltype ( expression ) ` 281 e.g. the `decltype(s)` in `decltype(s)::size`. 282 }]; 283} 284def IdentifierNameSpecifier : Unconstrained<NameSpecifier> { 285 let documentation = [{ 286 A identifier name specifier, of the form `identifier` 287 e.g. the `std` in `std::vector<int>::size`. 288 }]; 289} 290def SimpleTemplateNameSpecifier : Unconstrained<NameSpecifier> { 291 let documentation = [{ 292 A name specifier with a simple-template-id, of the form `template_opt 293 identifier < template-args >` e.g. the `vector<int>` in 294 `std::vector<int>::size`. 295 }]; 296} 297