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 Leaf, 39 TranslationUnit, 40 41 // Expressions 42 UnknownExpression, 43 44 // Statements 45 UnknownStatement, 46 DeclarationStatement, 47 EmptyStatement, 48 SwitchStatement, 49 CaseStatement, 50 DefaultStatement, 51 IfStatement, 52 ForStatement, 53 WhileStatement, 54 ContinueStatement, 55 BreakStatement, 56 ReturnStatement, 57 RangeBasedForStatement, 58 ExpressionStatement, 59 CompoundStatement, 60 61 // Declarations 62 UnknownDeclaration, 63 EmptyDeclaration, 64 StaticAssertDeclaration, 65 LinkageSpecificationDeclaration, 66 SimpleDeclaration, 67 NamespaceDefinition, 68 NamespaceAliasDefinition, 69 UsingNamespaceDirective, 70 UsingDeclaration, 71 TypeAliasDeclaration 72 }; 73 /// For debugging purposes. 74 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeKind K); 75 76 /// A relation between a parent and child node, e.g. 'left-hand-side of 77 /// a binary expression'. Used for implementing accessors. 78 enum class NodeRole : uint8_t { 79 // Roles common to multiple node kinds. 80 /// A node without a parent 81 Detached, 82 /// Children of an unknown semantic nature, e.g. skipped tokens, comments. 83 Unknown, 84 /// An opening parenthesis in argument lists and blocks, e.g. '{', '(', etc. 85 OpenParen, 86 /// A closing parenthesis in argument lists and blocks, e.g. '}', ')', etc. 87 CloseParen, 88 /// A keywords that introduces some grammar construct, e.g. 'if', 'try', etc. 89 IntroducerKeyword, 90 /// An inner statement for those that have only a single child of kind 91 /// statement, e.g. loop body for while, for, etc; inner statement for case, 92 /// default, etc. 93 BodyStatement, 94 95 // Roles specific to particular node kinds. 96 CaseStatement_value, 97 IfStatement_thenStatement, 98 IfStatement_elseKeyword, 99 IfStatement_elseStatement, 100 ReturnStatement_value, 101 ExpressionStatement_expression, 102 CompoundStatement_statement, 103 StaticAssertDeclaration_condition, 104 StaticAssertDeclaration_message 105 }; 106 /// For debugging purposes. 107 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeRole R); 108 109 /// A root node for a translation unit. Parent is always null. 110 class TranslationUnit final : public Tree { 111 public: TranslationUnit()112 TranslationUnit() : Tree(NodeKind::TranslationUnit) {} classof(const Node * N)113 static bool classof(const Node *N) { 114 return N->kind() == NodeKind::TranslationUnit; 115 } 116 }; 117 118 /// A base class for all expressions. Note that expressions are not statements, 119 /// even though they are in clang. 120 class Expression : public Tree { 121 public: Expression(NodeKind K)122 Expression(NodeKind K) : Tree(K) {} classof(const Node * N)123 static bool classof(const Node *N) { 124 return NodeKind::UnknownExpression <= N->kind() && 125 N->kind() <= NodeKind::UnknownExpression; 126 } 127 }; 128 129 /// An expression of an unknown kind, i.e. one not currently handled by the 130 /// syntax tree. 131 class UnknownExpression final : public Expression { 132 public: UnknownExpression()133 UnknownExpression() : Expression(NodeKind::UnknownExpression) {} classof(const Node * N)134 static bool classof(const Node *N) { 135 return N->kind() == NodeKind::UnknownExpression; 136 } 137 }; 138 139 /// An abstract node for C++ statements, e.g. 'while', 'if', etc. 140 /// FIXME: add accessors for semicolon of statements that have it. 141 class Statement : public Tree { 142 public: Statement(NodeKind K)143 Statement(NodeKind K) : Tree(K) {} classof(const Node * N)144 static bool classof(const Node *N) { 145 return NodeKind::UnknownStatement <= N->kind() && 146 N->kind() <= NodeKind::CompoundStatement; 147 } 148 }; 149 150 /// A statement of an unknown kind, i.e. one not currently handled by the syntax 151 /// tree. 152 class UnknownStatement final : public Statement { 153 public: UnknownStatement()154 UnknownStatement() : Statement(NodeKind::UnknownStatement) {} classof(const Node * N)155 static bool classof(const Node *N) { 156 return N->kind() == NodeKind::UnknownStatement; 157 } 158 }; 159 160 /// E.g. 'int a, b = 10;' 161 class DeclarationStatement final : public Statement { 162 public: DeclarationStatement()163 DeclarationStatement() : Statement(NodeKind::DeclarationStatement) {} classof(const Node * N)164 static bool classof(const Node *N) { 165 return N->kind() == NodeKind::DeclarationStatement; 166 } 167 }; 168 169 /// The no-op statement, i.e. ';'. 170 class EmptyStatement final : public Statement { 171 public: EmptyStatement()172 EmptyStatement() : Statement(NodeKind::EmptyStatement) {} classof(const Node * N)173 static bool classof(const Node *N) { 174 return N->kind() == NodeKind::EmptyStatement; 175 } 176 }; 177 178 /// switch (<cond>) <body> 179 class SwitchStatement final : public Statement { 180 public: SwitchStatement()181 SwitchStatement() : Statement(NodeKind::SwitchStatement) {} classof(const Node * N)182 static bool classof(const Node *N) { 183 return N->kind() == NodeKind::SwitchStatement; 184 } 185 syntax::Leaf *switchKeyword(); 186 syntax::Statement *body(); 187 }; 188 189 /// case <value>: <body> 190 class CaseStatement final : public Statement { 191 public: CaseStatement()192 CaseStatement() : Statement(NodeKind::CaseStatement) {} classof(const Node * N)193 static bool classof(const Node *N) { 194 return N->kind() == NodeKind::CaseStatement; 195 } 196 syntax::Leaf *caseKeyword(); 197 syntax::Expression *value(); 198 syntax::Statement *body(); 199 }; 200 201 /// default: <body> 202 class DefaultStatement final : public Statement { 203 public: DefaultStatement()204 DefaultStatement() : Statement(NodeKind::DefaultStatement) {} classof(const Node * N)205 static bool classof(const Node *N) { 206 return N->kind() == NodeKind::DefaultStatement; 207 } 208 syntax::Leaf *defaultKeyword(); 209 syntax::Statement *body(); 210 }; 211 212 /// if (cond) <then-statement> else <else-statement> 213 /// FIXME: add condition that models 'expression or variable declaration' 214 class IfStatement final : public Statement { 215 public: IfStatement()216 IfStatement() : Statement(NodeKind::IfStatement) {} classof(const Node * N)217 static bool classof(const Node *N) { 218 return N->kind() == NodeKind::IfStatement; 219 } 220 syntax::Leaf *ifKeyword(); 221 syntax::Statement *thenStatement(); 222 syntax::Leaf *elseKeyword(); 223 syntax::Statement *elseStatement(); 224 }; 225 226 /// for (<init>; <cond>; <increment>) <body> 227 class ForStatement final : public Statement { 228 public: ForStatement()229 ForStatement() : Statement(NodeKind::ForStatement) {} classof(const Node * N)230 static bool classof(const Node *N) { 231 return N->kind() == NodeKind::ForStatement; 232 } 233 syntax::Leaf *forKeyword(); 234 syntax::Statement *body(); 235 }; 236 237 /// while (<cond>) <body> 238 class WhileStatement final : public Statement { 239 public: WhileStatement()240 WhileStatement() : Statement(NodeKind::WhileStatement) {} classof(const Node * N)241 static bool classof(const Node *N) { 242 return N->kind() == NodeKind::WhileStatement; 243 } 244 syntax::Leaf *whileKeyword(); 245 syntax::Statement *body(); 246 }; 247 248 /// continue; 249 class ContinueStatement final : public Statement { 250 public: ContinueStatement()251 ContinueStatement() : Statement(NodeKind::ContinueStatement) {} classof(const Node * N)252 static bool classof(const Node *N) { 253 return N->kind() == NodeKind::ContinueStatement; 254 } 255 syntax::Leaf *continueKeyword(); 256 }; 257 258 /// break; 259 class BreakStatement final : public Statement { 260 public: BreakStatement()261 BreakStatement() : Statement(NodeKind::BreakStatement) {} classof(const Node * N)262 static bool classof(const Node *N) { 263 return N->kind() == NodeKind::BreakStatement; 264 } 265 syntax::Leaf *breakKeyword(); 266 }; 267 268 /// return <expr>; 269 /// return; 270 class ReturnStatement final : public Statement { 271 public: ReturnStatement()272 ReturnStatement() : Statement(NodeKind::ReturnStatement) {} classof(const Node * N)273 static bool classof(const Node *N) { 274 return N->kind() == NodeKind::ReturnStatement; 275 } 276 syntax::Leaf *returnKeyword(); 277 syntax::Expression *value(); 278 }; 279 280 /// for (<decl> : <init>) <body> 281 class RangeBasedForStatement final : public Statement { 282 public: RangeBasedForStatement()283 RangeBasedForStatement() : Statement(NodeKind::RangeBasedForStatement) {} classof(const Node * N)284 static bool classof(const Node *N) { 285 return N->kind() == NodeKind::RangeBasedForStatement; 286 } 287 syntax::Leaf *forKeyword(); 288 syntax::Statement *body(); 289 }; 290 291 /// Expression in a statement position, e.g. functions calls inside compound 292 /// statements or inside a loop body. 293 class ExpressionStatement final : public Statement { 294 public: ExpressionStatement()295 ExpressionStatement() : Statement(NodeKind::ExpressionStatement) {} classof(const Node * N)296 static bool classof(const Node *N) { 297 return N->kind() == NodeKind::ExpressionStatement; 298 } 299 syntax::Expression *expression(); 300 }; 301 302 /// { statement1; statement2; … } 303 class CompoundStatement final : public Statement { 304 public: CompoundStatement()305 CompoundStatement() : Statement(NodeKind::CompoundStatement) {} classof(const Node * N)306 static bool classof(const Node *N) { 307 return N->kind() == NodeKind::CompoundStatement; 308 } 309 syntax::Leaf *lbrace(); 310 /// FIXME: use custom iterator instead of 'vector'. 311 std::vector<syntax::Statement *> statements(); 312 syntax::Leaf *rbrace(); 313 }; 314 315 /// A declaration that can appear at the top-level. Note that this does *not* 316 /// correspond 1-to-1 to clang::Decl. Syntax trees distinguish between top-level 317 /// declarations (e.g. namespace definitions) and declarators (e.g. variables, 318 /// typedefs, etc.). Declarators are stored inside SimpleDeclaration. 319 class Declaration : public Tree { 320 public: Declaration(NodeKind K)321 Declaration(NodeKind K) : Tree(K) {} classof(const Node * N)322 static bool classof(const Node *N) { 323 return NodeKind::UnknownDeclaration <= N->kind() && 324 N->kind() <= NodeKind::TypeAliasDeclaration; 325 } 326 }; 327 328 /// Declaration of an unknown kind, e.g. not yet supported in syntax trees. 329 class UnknownDeclaration final : public Declaration { 330 public: UnknownDeclaration()331 UnknownDeclaration() : Declaration(NodeKind::UnknownDeclaration) {} classof(const Node * N)332 static bool classof(const Node *N) { 333 return N->kind() == NodeKind::UnknownDeclaration; 334 } 335 }; 336 337 /// A semicolon in the top-level context. Does not declare anything. 338 class EmptyDeclaration final : public Declaration { 339 public: EmptyDeclaration()340 EmptyDeclaration() : Declaration(NodeKind::EmptyDeclaration) {} classof(const Node * N)341 static bool classof(const Node *N) { 342 return N->kind() == NodeKind::EmptyDeclaration; 343 } 344 }; 345 346 /// static_assert(<condition>, <message>) 347 /// static_assert(<condition>) 348 class StaticAssertDeclaration final : public Declaration { 349 public: StaticAssertDeclaration()350 StaticAssertDeclaration() : Declaration(NodeKind::StaticAssertDeclaration) {} classof(const Node * N)351 static bool classof(const Node *N) { 352 return N->kind() == NodeKind::StaticAssertDeclaration; 353 } 354 syntax::Expression *condition(); 355 syntax::Expression *message(); 356 }; 357 358 /// extern <string-literal> declaration 359 /// extern <string-literal> { <decls> } 360 class LinkageSpecificationDeclaration final : public Declaration { 361 public: LinkageSpecificationDeclaration()362 LinkageSpecificationDeclaration() 363 : Declaration(NodeKind::LinkageSpecificationDeclaration) {} classof(const Node * N)364 static bool classof(const Node *N) { 365 return N->kind() == NodeKind::LinkageSpecificationDeclaration; 366 } 367 }; 368 369 /// Groups multiple declarators (e.g. variables, typedefs, etc.) together. All 370 /// grouped declarators share the same declaration specifiers (e.g. 'int' or 371 /// 'typedef'). 372 class SimpleDeclaration final : public Declaration { 373 public: SimpleDeclaration()374 SimpleDeclaration() : Declaration(NodeKind::SimpleDeclaration) {} classof(const Node * N)375 static bool classof(const Node *N) { 376 return N->kind() == NodeKind::SimpleDeclaration; 377 } 378 }; 379 380 /// namespace <name> { <decls> } 381 class NamespaceDefinition final : public Declaration { 382 public: NamespaceDefinition()383 NamespaceDefinition() : Declaration(NodeKind::NamespaceDefinition) {} classof(const Node * N)384 static bool classof(const Node *N) { 385 return N->kind() == NodeKind::NamespaceDefinition; 386 } 387 }; 388 389 /// namespace <name> = <namespace-reference> 390 class NamespaceAliasDefinition final : public Declaration { 391 public: NamespaceAliasDefinition()392 NamespaceAliasDefinition() 393 : Declaration(NodeKind::NamespaceAliasDefinition) {} classof(const Node * N)394 static bool classof(const Node *N) { 395 return N->kind() == NodeKind::NamespaceAliasDefinition; 396 } 397 }; 398 399 /// using namespace <name> 400 class UsingNamespaceDirective final : public Declaration { 401 public: UsingNamespaceDirective()402 UsingNamespaceDirective() : Declaration(NodeKind::UsingNamespaceDirective) {} classof(const Node * N)403 static bool classof(const Node *N) { 404 return N->kind() == NodeKind::UsingNamespaceDirective; 405 } 406 }; 407 408 /// using <scope>::<name> 409 /// using typename <scope>::<name> 410 class UsingDeclaration final : public Declaration { 411 public: UsingDeclaration()412 UsingDeclaration() : Declaration(NodeKind::UsingDeclaration) {} classof(const Node * N)413 static bool classof(const Node *N) { 414 return N->kind() == NodeKind::UsingDeclaration; 415 } 416 }; 417 418 /// using <name> = <type> 419 class TypeAliasDeclaration final : public Declaration { 420 public: TypeAliasDeclaration()421 TypeAliasDeclaration() : Declaration(NodeKind::TypeAliasDeclaration) {} classof(const Node * N)422 static bool classof(const Node *N) { 423 return N->kind() == NodeKind::TypeAliasDeclaration; 424 } 425 }; 426 427 } // namespace syntax 428 } // namespace clang 429 #endif 430