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/LLVM.h" 25 #include "clang/Tooling/Syntax/Tree.h" 26 namespace clang { 27 namespace syntax { 28 29 /// A kind of a syntax node, used for implementing casts. The ordering and 30 /// blocks of enumerator constants must correspond to the inheritance hierarchy 31 /// of syntax::Node. 32 enum class NodeKind : uint16_t { 33 #define CONCRETE_NODE(Kind, Base) Kind, 34 #include "clang/Tooling/Syntax/Nodes.inc" 35 }; 36 /// For debugging purposes. 37 raw_ostream &operator<<(raw_ostream &OS, NodeKind K); 38 39 /// A relation between a parent and child node, e.g. 'left-hand-side of 40 /// a binary expression'. Used for implementing accessors. 41 /// 42 /// In general `NodeRole`s should be named the same as their accessors. 43 /// 44 /// Some roles describe parent/child relations that occur multiple times in 45 /// language grammar. We define only one role to describe all instances of such 46 /// recurring relations. For example, grammar for both "if" and "while" 47 /// statements requires an opening paren and a closing paren. The opening 48 /// paren token is assigned the OpenParen role regardless of whether it appears 49 /// as a child of IfStatement or WhileStatement node. More generally, when 50 /// grammar requires a certain fixed token (like a specific keyword, or an 51 /// opening paren), we define a role for this token and use it across all 52 /// grammar rules with the same requirement. Names of such reusable roles end 53 /// with a ~Token or a ~Keyword suffix. 54 enum class NodeRole : uint8_t { 55 // Roles common to multiple node kinds. 56 /// A node without a parent 57 Detached, 58 /// Children of an unknown semantic nature, e.g. skipped tokens, comments. 59 Unknown, 60 /// An opening parenthesis in argument lists and blocks, e.g. '{', '(', etc. 61 OpenParen, 62 /// A closing parenthesis in argument lists and blocks, e.g. '}', ')', etc. 63 CloseParen, 64 /// A keywords that introduces some grammar construct, e.g. 'if', 'try', etc. 65 IntroducerKeyword, 66 /// A token that represents a literal, e.g. 'nullptr', '1', 'true', etc. 67 LiteralToken, 68 /// Tokens or Keywords. 69 ArrowToken, 70 ExternKeyword, 71 TemplateKeyword, 72 /// An inner statement for those that have only a single child of kind 73 /// statement, e.g. loop body for while, for, etc; inner statement for case, 74 /// default, etc. 75 BodyStatement, 76 /// List API roles. 77 ListElement, 78 ListDelimiter, 79 80 // Roles specific to particular node kinds. 81 OperatorToken, 82 Operand, 83 LeftHandSide, 84 RightHandSide, 85 ReturnValue, 86 CaseValue, 87 ThenStatement, 88 ElseKeyword, 89 ElseStatement, 90 Expression, 91 Statement, 92 Condition, 93 Message, 94 Declarator, 95 Declaration, 96 Size, 97 Parameters, 98 TrailingReturn, 99 UnqualifiedId, 100 Qualifier, 101 SubExpression, 102 Object, 103 AccessToken, 104 Member, 105 Callee, 106 Arguments, 107 Declarators 108 }; 109 /// For debugging purposes. 110 raw_ostream &operator<<(raw_ostream &OS, NodeRole R); 111 112 #include "clang/Tooling/Syntax/NodeClasses.inc" 113 114 /// Models a `nested-name-specifier`. C++ [expr.prim.id.qual] 115 /// e.g. the `std::vector<int>::` in `std::vector<int>::size`. 116 class NestedNameSpecifier final : public List { 117 public: NestedNameSpecifier()118 NestedNameSpecifier() : List(NodeKind::NestedNameSpecifier) {} 119 static bool classof(const Node *N); 120 std::vector<NameSpecifier *> getSpecifiers(); 121 std::vector<List::ElementAndDelimiter<syntax::NameSpecifier>> 122 getSpecifiersAndDoubleColons(); 123 }; 124 125 /// Models an `unqualified-id`. C++ [expr.prim.id.unqual] 126 /// e.g. the `size` in `std::vector<int>::size`. 127 class UnqualifiedId final : public Tree { 128 public: UnqualifiedId()129 UnqualifiedId() : Tree(NodeKind::UnqualifiedId) {} 130 static bool classof(const Node *N); 131 }; 132 133 /// An expression of an unknown kind, i.e. one not currently handled by the 134 /// syntax tree. 135 class UnknownExpression final : public Expression { 136 public: UnknownExpression()137 UnknownExpression() : Expression(NodeKind::UnknownExpression) {} 138 static bool classof(const Node *N); 139 }; 140 141 /// Models arguments of a function call. 142 /// call-arguments: 143 /// delimited_list(expression, ',') 144 /// Note: This construct is a simplification of the grammar rule for 145 /// `expression-list`, that is used in the definition of `call-expression` 146 class CallArguments final : public List { 147 public: CallArguments()148 CallArguments() : List(NodeKind::CallArguments) {} 149 static bool classof(const Node *N); 150 std::vector<Expression *> getArguments(); 151 std::vector<List::ElementAndDelimiter<Expression>> getArgumentsAndCommas(); 152 }; 153 154 /// An abstract class for prefix and postfix unary operators. 155 class UnaryOperatorExpression : public Expression { 156 public: UnaryOperatorExpression(NodeKind K)157 UnaryOperatorExpression(NodeKind K) : Expression(K) {} 158 static bool classof(const Node *N); 159 Leaf *getOperatorToken(); 160 Expression *getOperand(); 161 }; 162 163 /// <operator> <operand> 164 /// 165 /// For example: 166 /// +a -b 167 /// !c not c 168 /// ~d compl d 169 /// *e &f 170 /// ++h --h 171 /// __real i __imag i 172 class PrefixUnaryOperatorExpression final : public UnaryOperatorExpression { 173 public: PrefixUnaryOperatorExpression()174 PrefixUnaryOperatorExpression() 175 : UnaryOperatorExpression(NodeKind::PrefixUnaryOperatorExpression) {} 176 static bool classof(const Node *N); 177 }; 178 179 /// <operand> <operator> 180 /// 181 /// For example: 182 /// a++ 183 /// b-- 184 class PostfixUnaryOperatorExpression final : public UnaryOperatorExpression { 185 public: PostfixUnaryOperatorExpression()186 PostfixUnaryOperatorExpression() 187 : UnaryOperatorExpression(NodeKind::PostfixUnaryOperatorExpression) {} 188 static bool classof(const Node *N); 189 }; 190 191 /// <lhs> <operator> <rhs> 192 /// 193 /// For example: 194 /// a + b 195 /// a bitor 1 196 /// a |= b 197 /// a and_eq b 198 class BinaryOperatorExpression final : public Expression { 199 public: BinaryOperatorExpression()200 BinaryOperatorExpression() : Expression(NodeKind::BinaryOperatorExpression) {} 201 static bool classof(const Node *N); 202 Expression *getLhs(); 203 Leaf *getOperatorToken(); 204 Expression *getRhs(); 205 }; 206 207 /// An abstract node for C++ statements, e.g. 'while', 'if', etc. 208 /// FIXME: add accessors for semicolon of statements that have it. 209 class Statement : public Tree { 210 public: Statement(NodeKind K)211 Statement(NodeKind K) : Tree(K) {} 212 static bool classof(const Node *N); 213 }; 214 215 /// A statement of an unknown kind, i.e. one not currently handled by the syntax 216 /// tree. 217 class UnknownStatement final : public Statement { 218 public: UnknownStatement()219 UnknownStatement() : Statement(NodeKind::UnknownStatement) {} 220 static bool classof(const Node *N); 221 }; 222 223 /// E.g. 'int a, b = 10;' 224 class DeclarationStatement final : public Statement { 225 public: DeclarationStatement()226 DeclarationStatement() : Statement(NodeKind::DeclarationStatement) {} 227 static bool classof(const Node *N); 228 }; 229 230 /// The no-op statement, i.e. ';'. 231 class EmptyStatement final : public Statement { 232 public: EmptyStatement()233 EmptyStatement() : Statement(NodeKind::EmptyStatement) {} 234 static bool classof(const Node *N); 235 }; 236 237 /// switch (<cond>) <body> 238 class SwitchStatement final : public Statement { 239 public: SwitchStatement()240 SwitchStatement() : Statement(NodeKind::SwitchStatement) {} 241 static bool classof(const Node *N); 242 Leaf *getSwitchKeyword(); 243 Statement *getBody(); 244 }; 245 246 /// case <value>: <body> 247 class CaseStatement final : public Statement { 248 public: CaseStatement()249 CaseStatement() : Statement(NodeKind::CaseStatement) {} 250 static bool classof(const Node *N); 251 Leaf *getCaseKeyword(); 252 Expression *getCaseValue(); 253 Statement *getBody(); 254 }; 255 256 /// default: <body> 257 class DefaultStatement final : public Statement { 258 public: DefaultStatement()259 DefaultStatement() : Statement(NodeKind::DefaultStatement) {} 260 static bool classof(const Node *N); 261 Leaf *getDefaultKeyword(); 262 Statement *getBody(); 263 }; 264 265 /// if (cond) <then-statement> else <else-statement> 266 /// FIXME: add condition that models 'expression or variable declaration' 267 class IfStatement final : public Statement { 268 public: IfStatement()269 IfStatement() : Statement(NodeKind::IfStatement) {} 270 static bool classof(const Node *N); 271 Leaf *getIfKeyword(); 272 Statement *getThenStatement(); 273 Leaf *getElseKeyword(); 274 Statement *getElseStatement(); 275 }; 276 277 /// for (<init>; <cond>; <increment>) <body> 278 class ForStatement final : public Statement { 279 public: ForStatement()280 ForStatement() : Statement(NodeKind::ForStatement) {} 281 static bool classof(const Node *N); 282 Leaf *getForKeyword(); 283 Statement *getBody(); 284 }; 285 286 /// while (<cond>) <body> 287 class WhileStatement final : public Statement { 288 public: WhileStatement()289 WhileStatement() : Statement(NodeKind::WhileStatement) {} 290 static bool classof(const Node *N); 291 Leaf *getWhileKeyword(); 292 Statement *getBody(); 293 }; 294 295 /// continue; 296 class ContinueStatement final : public Statement { 297 public: ContinueStatement()298 ContinueStatement() : Statement(NodeKind::ContinueStatement) {} 299 static bool classof(const Node *N); 300 Leaf *getContinueKeyword(); 301 }; 302 303 /// break; 304 class BreakStatement final : public Statement { 305 public: BreakStatement()306 BreakStatement() : Statement(NodeKind::BreakStatement) {} 307 static bool classof(const Node *N); 308 Leaf *getBreakKeyword(); 309 }; 310 311 /// return <expr>; 312 /// return; 313 class ReturnStatement final : public Statement { 314 public: ReturnStatement()315 ReturnStatement() : Statement(NodeKind::ReturnStatement) {} 316 static bool classof(const Node *N); 317 Leaf *getReturnKeyword(); 318 Expression *getReturnValue(); 319 }; 320 321 /// for (<decl> : <init>) <body> 322 class RangeBasedForStatement final : public Statement { 323 public: RangeBasedForStatement()324 RangeBasedForStatement() : Statement(NodeKind::RangeBasedForStatement) {} 325 static bool classof(const Node *N); 326 Leaf *getForKeyword(); 327 Statement *getBody(); 328 }; 329 330 /// Expression in a statement position, e.g. functions calls inside compound 331 /// statements or inside a loop body. 332 class ExpressionStatement final : public Statement { 333 public: ExpressionStatement()334 ExpressionStatement() : Statement(NodeKind::ExpressionStatement) {} 335 static bool classof(const Node *N); 336 Expression *getExpression(); 337 }; 338 339 /// { statement1; statement2; … } 340 class CompoundStatement final : public Statement { 341 public: CompoundStatement()342 CompoundStatement() : Statement(NodeKind::CompoundStatement) {} 343 static bool classof(const Node *N); 344 Leaf *getLbrace(); 345 /// FIXME: use custom iterator instead of 'vector'. 346 std::vector<Statement *> getStatements(); 347 Leaf *getRbrace(); 348 }; 349 350 /// A declaration that can appear at the top-level. Note that this does *not* 351 /// correspond 1-to-1 to clang::Decl. Syntax trees distinguish between top-level 352 /// declarations (e.g. namespace definitions) and declarators (e.g. variables, 353 /// typedefs, etc.). Declarators are stored inside SimpleDeclaration. 354 class Declaration : public Tree { 355 public: Declaration(NodeKind K)356 Declaration(NodeKind K) : Tree(K) {} 357 static bool classof(const Node *N); 358 }; 359 360 /// Declaration of an unknown kind, e.g. not yet supported in syntax trees. 361 class UnknownDeclaration final : public Declaration { 362 public: UnknownDeclaration()363 UnknownDeclaration() : Declaration(NodeKind::UnknownDeclaration) {} 364 static bool classof(const Node *N); 365 }; 366 367 /// A semicolon in the top-level context. Does not declare anything. 368 class EmptyDeclaration final : public Declaration { 369 public: EmptyDeclaration()370 EmptyDeclaration() : Declaration(NodeKind::EmptyDeclaration) {} 371 static bool classof(const Node *N); 372 }; 373 374 /// static_assert(<condition>, <message>) 375 /// static_assert(<condition>) 376 class StaticAssertDeclaration final : public Declaration { 377 public: StaticAssertDeclaration()378 StaticAssertDeclaration() : Declaration(NodeKind::StaticAssertDeclaration) {} 379 static bool classof(const Node *N); 380 Expression *getCondition(); 381 Expression *getMessage(); 382 }; 383 384 /// extern <string-literal> declaration 385 /// extern <string-literal> { <decls> } 386 class LinkageSpecificationDeclaration final : public Declaration { 387 public: LinkageSpecificationDeclaration()388 LinkageSpecificationDeclaration() 389 : Declaration(NodeKind::LinkageSpecificationDeclaration) {} 390 static bool classof(const Node *N); 391 }; 392 393 class DeclaratorList final : public List { 394 public: DeclaratorList()395 DeclaratorList() : List(NodeKind::DeclaratorList) {} 396 static bool classof(const Node *N); 397 std::vector<SimpleDeclarator *> getDeclarators(); 398 std::vector<List::ElementAndDelimiter<syntax::SimpleDeclarator>> 399 getDeclaratorsAndCommas(); 400 }; 401 402 /// Groups multiple declarators (e.g. variables, typedefs, etc.) together. All 403 /// grouped declarators share the same declaration specifiers (e.g. 'int' or 404 /// 'typedef'). 405 class SimpleDeclaration final : public Declaration { 406 public: SimpleDeclaration()407 SimpleDeclaration() : Declaration(NodeKind::SimpleDeclaration) {} 408 static bool classof(const Node *N); 409 /// FIXME: use custom iterator instead of 'vector'. 410 std::vector<SimpleDeclarator *> getDeclarators(); 411 }; 412 413 /// template <template-parameters> <declaration> 414 class TemplateDeclaration final : public Declaration { 415 public: TemplateDeclaration()416 TemplateDeclaration() : Declaration(NodeKind::TemplateDeclaration) {} 417 static bool classof(const Node *N); 418 Leaf *getTemplateKeyword(); 419 Declaration *getDeclaration(); 420 }; 421 422 /// template <declaration> 423 /// Examples: 424 /// template struct X<int> 425 /// template void foo<int>() 426 /// template int var<double> 427 class ExplicitTemplateInstantiation final : public Declaration { 428 public: ExplicitTemplateInstantiation()429 ExplicitTemplateInstantiation() 430 : Declaration(NodeKind::ExplicitTemplateInstantiation) {} 431 static bool classof(const Node *N); 432 Leaf *getTemplateKeyword(); 433 Leaf *getExternKeyword(); 434 Declaration *getDeclaration(); 435 }; 436 437 /// namespace <name> { <decls> } 438 class NamespaceDefinition final : public Declaration { 439 public: NamespaceDefinition()440 NamespaceDefinition() : Declaration(NodeKind::NamespaceDefinition) {} 441 static bool classof(const Node *N); 442 }; 443 444 /// namespace <name> = <namespace-reference> 445 class NamespaceAliasDefinition final : public Declaration { 446 public: NamespaceAliasDefinition()447 NamespaceAliasDefinition() 448 : Declaration(NodeKind::NamespaceAliasDefinition) {} 449 static bool classof(const Node *N); 450 }; 451 452 /// using namespace <name> 453 class UsingNamespaceDirective final : public Declaration { 454 public: UsingNamespaceDirective()455 UsingNamespaceDirective() : Declaration(NodeKind::UsingNamespaceDirective) {} 456 static bool classof(const Node *N); 457 }; 458 459 /// using <scope>::<name> 460 /// using typename <scope>::<name> 461 class UsingDeclaration final : public Declaration { 462 public: UsingDeclaration()463 UsingDeclaration() : Declaration(NodeKind::UsingDeclaration) {} 464 static bool classof(const Node *N); 465 }; 466 467 /// using <name> = <type> 468 class TypeAliasDeclaration final : public Declaration { 469 public: TypeAliasDeclaration()470 TypeAliasDeclaration() : Declaration(NodeKind::TypeAliasDeclaration) {} 471 static bool classof(const Node *N); 472 }; 473 474 /// Covers a name, an initializer and a part of the type outside declaration 475 /// specifiers. Examples are: 476 /// `*a` in `int *a` 477 /// `a[10]` in `int a[10]` 478 /// `*a = nullptr` in `int *a = nullptr` 479 /// Declarators can be unnamed too: 480 /// `**` in `new int**` 481 /// `* = nullptr` in `void foo(int* = nullptr)` 482 /// Most declarators you encounter are instances of SimpleDeclarator. They may 483 /// contain an inner declarator inside parentheses, we represent it as 484 /// ParenDeclarator. E.g. 485 /// `(*a)` in `int (*a) = 10` 486 class Declarator : public Tree { 487 public: Declarator(NodeKind K)488 Declarator(NodeKind K) : Tree(K) {} 489 static bool classof(const Node *N); 490 }; 491 492 /// A top-level declarator without parentheses. See comment of Declarator for 493 /// more details. 494 class SimpleDeclarator final : public Declarator { 495 public: SimpleDeclarator()496 SimpleDeclarator() : Declarator(NodeKind::SimpleDeclarator) {} 497 static bool classof(const Node *N); 498 }; 499 500 /// Declarator inside parentheses. 501 /// E.g. `(***a)` from `int (***a) = nullptr;` 502 /// See comment of Declarator for more details. 503 class ParenDeclarator final : public Declarator { 504 public: ParenDeclarator()505 ParenDeclarator() : Declarator(NodeKind::ParenDeclarator) {} 506 static bool classof(const Node *N); 507 Leaf *getLparen(); 508 Leaf *getRparen(); 509 }; 510 511 /// Array size specified inside a declarator. 512 /// E.g: 513 /// `[10]` in `int a[10];` 514 /// `[static 10]` in `void f(int xs[static 10]);` 515 class ArraySubscript final : public Tree { 516 public: ArraySubscript()517 ArraySubscript() : Tree(NodeKind::ArraySubscript) {} 518 static bool classof(const Node *N); 519 // TODO: add an accessor for the "static" keyword. 520 Leaf *getLbracket(); 521 Expression *getSize(); 522 Leaf *getRbracket(); 523 }; 524 525 /// Trailing return type after the parameter list, including the arrow token. 526 /// E.g. `-> int***`. 527 class TrailingReturnType final : public Tree { 528 public: TrailingReturnType()529 TrailingReturnType() : Tree(NodeKind::TrailingReturnType) {} 530 static bool classof(const Node *N); 531 // TODO: add accessors for specifiers. 532 Leaf *getArrowToken(); 533 // FIXME: This should be a `type-id` following the grammar. Fix this once we 534 // have a representation of `type-id`s. 535 SimpleDeclarator *getDeclarator(); 536 }; 537 538 /// Models a `parameter-declaration-list` which appears within 539 /// `parameters-and-qualifiers`. See C++ [dcl.fct] 540 class ParameterDeclarationList final : public List { 541 public: ParameterDeclarationList()542 ParameterDeclarationList() : List(NodeKind::ParameterDeclarationList) {} 543 static bool classof(const Node *N); 544 std::vector<SimpleDeclaration *> getParameterDeclarations(); 545 std::vector<List::ElementAndDelimiter<syntax::SimpleDeclaration>> 546 getParametersAndCommas(); 547 }; 548 549 /// Parameter list for a function type and a trailing return type, if the 550 /// function has one. 551 /// E.g.: 552 /// `(int a) volatile ` in `int foo(int a) volatile;` 553 /// `(int a) &&` in `int foo(int a) &&;` 554 /// `() -> int` in `auto foo() -> int;` 555 /// `() const` in `int foo() const;` 556 /// `() noexcept` in `int foo() noexcept;` 557 /// `() throw()` in `int foo() throw();` 558 /// 559 /// (!) override doesn't belong here. 560 class ParametersAndQualifiers final : public Tree { 561 public: ParametersAndQualifiers()562 ParametersAndQualifiers() : Tree(NodeKind::ParametersAndQualifiers) {} 563 static bool classof(const Node *N); 564 Leaf *getLparen(); 565 ParameterDeclarationList *getParameters(); 566 Leaf *getRparen(); 567 TrailingReturnType *getTrailingReturn(); 568 }; 569 570 /// Member pointer inside a declarator 571 /// E.g. `X::*` in `int X::* a = 0;` 572 class MemberPointer final : public Tree { 573 public: MemberPointer()574 MemberPointer() : Tree(NodeKind::MemberPointer) {} 575 static bool classof(const Node *N); 576 }; 577 578 #define CONCRETE_NODE(Kind, Base) \ 579 inline bool Kind::classof(const Node *N) { \ 580 return N->getKind() == NodeKind::Kind; \ 581 } 582 #define ABSTRACT_NODE(Kind, Base, First, Last) \ 583 inline bool Kind::classof(const Node *N) { \ 584 return N->getKind() >= NodeKind::First && N->getKind() <= NodeKind::Last; \ 585 } 586 #include "clang/Tooling/Syntax/Nodes.inc" 587 588 } // namespace syntax 589 } // namespace clang 590 #endif 591