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