clang  10.0.0git
Nodes.h
Go to the documentation of this file.
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"
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,
40 
41  // Expressions
43 
44  // Statements
60 
61  // Declarations
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.
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.
94 
95  // Roles specific to particular node kinds.
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:
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:
123  static bool classof(const Node *N) {
124  return NodeKind::UnknownExpression <= N->kind() &&
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:
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:
144  static bool classof(const Node *N) {
145  return NodeKind::UnknownStatement <= N->kind() &&
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
296  static bool classof(const Node *N) {
297  return N->kind() == NodeKind::ExpressionStatement;
298  }
300 };
301 
302 /// { statement1; statement2; … }
303 class CompoundStatement final : public Statement {
304 public:
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:
322  static bool classof(const Node *N) {
323  return NodeKind::UnknownDeclaration <= N->kind() &&
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:
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:
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:
351  static bool classof(const Node *N) {
353  }
354  syntax::Expression *condition();
355  syntax::Expression *message();
356 };
357 
358 /// extern <string-literal> declaration
359 /// extern <string-literal> { <decls> }
361 public:
364  static bool classof(const Node *N) {
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:
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:
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:
394  static bool classof(const Node *N) {
396  }
397 };
398 
399 /// using namespace <name>
400 class UsingNamespaceDirective final : public Declaration {
401 public:
403  static bool classof(const Node *N) {
405  }
406 };
407 
408 /// using <scope>::<name>
409 /// using typename <scope>::<name>
410 class UsingDeclaration final : public Declaration {
411 public:
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:
421  TypeAliasDeclaration() : Declaration(NodeKind::TypeAliasDeclaration) {}
422  static bool classof(const Node *N) {
423  return N->kind() == NodeKind::TypeAliasDeclaration;
424  }
425 };
426 
427 } // namespace syntax
428 } // namespace clang
429 #endif
while (<cond>) <body>
Definition: Nodes.h:238
static bool classof(const Node *N)
Definition: Nodes.h:341
static bool classof(const Node *N)
Definition: Nodes.h:144
An opening parenthesis in argument lists and blocks, e.g. &#39;{&#39;, &#39;(&#39;, etc.
Children of an unknown semantic nature, e.g. skipped tokens, comments.
Stencil expression(llvm::StringRef Id)
Generates the source of the expression bound to Id, wrapping it in parentheses if it may parse differ...
Definition: Stencil.cpp:315
{ statement1; statement2; … }
Definition: Nodes.h:303
static bool classof(const Node *N)
Definition: Nodes.h:273
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, NodeKind K)
For debugging purposes.
Definition: Nodes.cpp:13
case : <body>
Definition: Nodes.h:190
static bool classof(const Node *N)
Definition: Nodes.h:134
static bool classof(const Node *N)
Definition: Nodes.h:306
static_assert(<condition>, <message>) static_assert(<condition>)
Definition: Nodes.h:348
An expression of an unknown kind, i.e.
Definition: Nodes.h:131
static bool classof(const Node *N)
Definition: Nodes.h:123
A node in a syntax tree.
Definition: Tree.h:76
A root node for a translation unit. Parent is always null.
Definition: Nodes.h:110
for (<init>; <cond>; <increment>) <body>
Definition: Nodes.h:227
for (<decl> : <init>) <body>
Definition: Nodes.h:281
using <scope>::<name> using typename <scope>::<name>
Definition: Nodes.h:410
switch (<cond>) <body>
Definition: Nodes.h:179
static bool classof(const Node *N)
Definition: Nodes.h:262
An inner statement for those that have only a single child of kind statement, e.g.
if (cond) <then-statement> else <else-statement> FIXME: add condition that models &#39;expression or vari...
Definition: Nodes.h:214
static bool classof(const Node *N)
Definition: Nodes.h:364
An abstract node for C++ statements, e.g.
Definition: Nodes.h:141
static bool classof(const Node *N)
Definition: Nodes.h:332
static bool classof(const Node *N)
Definition: Nodes.h:384
static bool classof(const Node *N)
Definition: Nodes.h:164
static bool classof(const Node *N)
Definition: Nodes.h:182
A semicolon in the top-level context. Does not declare anything.
Definition: Nodes.h:338
The no-op statement, i.e. &#39;;&#39;.
Definition: Nodes.h:170
static bool classof(const Node *N)
Definition: Nodes.h:284
A keywords that introduces some grammar construct, e.g. &#39;if&#39;, &#39;try&#39;, etc.
static bool classof(const Node *N)
Definition: Nodes.h:205
static bool classof(const Node *N)
Definition: Nodes.h:155
namespace <name> { <decls> }
Definition: Nodes.h:381
static bool classof(const Node *N)
Definition: Nodes.h:193
Declaration of an unknown kind, e.g. not yet supported in syntax trees.
Definition: Nodes.h:329
static bool classof(const Node *N)
Definition: Nodes.h:241
A statement of an unknown kind, i.e.
Definition: Nodes.h:152
A closing parenthesis in argument lists and blocks, e.g. &#39;}&#39;, &#39;)&#39;, etc.
A node that has children and represents a syntactic language construct.
Definition: Tree.h:150
NodeKind
A kind of a syntax node, used for implementing casts.
Definition: Nodes.h:37
using namespace <name>
Definition: Nodes.h:400
Declaration(NodeKind K)
Definition: Nodes.h:321
E.g. &#39;int a, b = 10;&#39;.
Definition: Nodes.h:161
using <name> = <type>
Definition: Nodes.h:419
A declaration that can appear at the top-level.
Definition: Nodes.h:319
default: <body>
Definition: Nodes.h:202
static bool classof(const Node *N)
Definition: Nodes.h:422
return <expr>; return;
Definition: Nodes.h:270
A node without a parent.
Expression(NodeKind K)
Definition: Nodes.h:122
static bool classof(const Node *N)
Definition: Nodes.h:413
Expression in a statement position, e.g.
Definition: Nodes.h:293
static bool classof(const Node *N)
Definition: Nodes.h:403
NodeRole
A relation between a parent and child node, e.g.
Definition: Nodes.h:78
Dataflow Directional Tag Classes.
static bool classof(const Node *N)
Definition: Nodes.h:394
static bool classof(const Node *N)
Definition: Nodes.h:230
A leaf node points to a single token inside the expanded token stream.
Definition: Tree.h:138
static bool classof(const Node *N)
Definition: Nodes.h:113
static bool classof(const Node *N)
Definition: Nodes.h:322
static bool classof(const Node *N)
Definition: Nodes.h:173
extern <string-literal> declaration extern <string-literal> { <decls> }
Definition: Nodes.h:360
A base class for all expressions.
Definition: Nodes.h:120
static bool classof(const Node *N)
Definition: Nodes.h:351
Statement(NodeKind K)
Definition: Nodes.h:143
Defines the clang::TokenKind enum and support functions.
static bool classof(const Node *N)
Definition: Nodes.h:217
namespace <name> = <namespace-reference>
Definition: Nodes.h:390
static bool classof(const Node *N)
Definition: Nodes.h:375
NodeKind kind() const
Definition: Tree.h:82
static bool classof(const Node *N)
Definition: Nodes.h:252
Groups multiple declarators (e.g.
Definition: Nodes.h:372
static bool classof(const Node *N)
Definition: Nodes.h:296
RangeSelector statements(std::string ID)