Coverage Report

Created: 2020-02-18 08:44

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Tooling/Syntax/Nodes.h
Line
Count
Source (jump to first uncovered line)
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:
112
29
  TranslationUnit() : Tree(NodeKind::TranslationUnit) {}
113
29
  static bool classof(const Node *N) {
114
29
    return N->kind() == NodeKind::TranslationUnit;
115
29
  }
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:
122
24
  Expression(NodeKind K) : Tree(K) {}
123
0
  static bool classof(const Node *N) {
124
0
    return NodeKind::UnknownExpression <= N->kind() &&
125
0
           N->kind() <= NodeKind::UnknownExpression;
126
0
  }
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:
133
24
  UnknownExpression() : Expression(NodeKind::UnknownExpression) {}
134
0
  static bool classof(const Node *N) {
135
0
    return N->kind() == NodeKind::UnknownExpression;
136
0
  }
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:
143
64
  Statement(NodeKind K) : Tree(K) {}
144
3
  static bool classof(const Node *N) {
145
3
    return NodeKind::UnknownStatement <= N->kind() &&
146
3
           N->kind() <= NodeKind::CompoundStatement;
147
3
  }
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:
154
1
  UnknownStatement() : Statement(NodeKind::UnknownStatement) {}
155
0
  static bool classof(const Node *N) {
156
0
    return N->kind() == NodeKind::UnknownStatement;
157
0
  }
158
};
159
160
/// E.g. 'int a, b = 10;'
161
class DeclarationStatement final : public Statement {
162
public:
163
4
  DeclarationStatement() : Statement(NodeKind::DeclarationStatement) {}
164
0
  static bool classof(const Node *N) {
165
0
    return N->kind() == NodeKind::DeclarationStatement;
166
0
  }
167
};
168
169
/// The no-op statement, i.e. ';'.
170
class EmptyStatement final : public Statement {
171
public:
172
6
  EmptyStatement() : Statement(NodeKind::EmptyStatement) {}
173
1
  static bool classof(const Node *N) {
174
1
    return N->kind() == NodeKind::EmptyStatement;
175
1
  }
176
};
177
178
/// switch (<cond>) <body>
179
class SwitchStatement final : public Statement {
180
public:
181
1
  SwitchStatement() : Statement(NodeKind::SwitchStatement) {}
182
0
  static bool classof(const Node *N) {
183
0
    return N->kind() == NodeKind::SwitchStatement;
184
0
  }
185
  syntax::Leaf *switchKeyword();
186
  syntax::Statement *body();
187
};
188
189
/// case <value>: <body>
190
class CaseStatement final : public Statement {
191
public:
192
1
  CaseStatement() : Statement(NodeKind::CaseStatement) {}
193
0
  static bool classof(const Node *N) {
194
0
    return N->kind() == NodeKind::CaseStatement;
195
0
  }
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:
204
1
  DefaultStatement() : Statement(NodeKind::DefaultStatement) {}
205
0
  static bool classof(const Node *N) {
206
0
    return N->kind() == NodeKind::DefaultStatement;
207
0
  }
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:
216
6
  IfStatement() : Statement(NodeKind::IfStatement) {}
217
0
  static bool classof(const Node *N) {
218
0
    return N->kind() == NodeKind::IfStatement;
219
0
  }
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:
229
1
  ForStatement() : Statement(NodeKind::ForStatement) {}
230
0
  static bool classof(const Node *N) {
231
0
    return N->kind() == NodeKind::ForStatement;
232
0
  }
233
  syntax::Leaf *forKeyword();
234
  syntax::Statement *body();
235
};
236
237
/// while (<cond>) <body>
238
class WhileStatement final : public Statement {
239
public:
240
1
  WhileStatement() : Statement(NodeKind::WhileStatement) {}
241
0
  static bool classof(const Node *N) {
242
0
    return N->kind() == NodeKind::WhileStatement;
243
0
  }
244
  syntax::Leaf *whileKeyword();
245
  syntax::Statement *body();
246
};
247
248
/// continue;
249
class ContinueStatement final : public Statement {
250
public:
251
1
  ContinueStatement() : Statement(NodeKind::ContinueStatement) {}
252
0
  static bool classof(const Node *N) {
253
0
    return N->kind() == NodeKind::ContinueStatement;
254
0
  }
255
  syntax::Leaf *continueKeyword();
256
};
257
258
/// break;
259
class BreakStatement final : public Statement {
260
public:
261
1
  BreakStatement() : Statement(NodeKind::BreakStatement) {}
262
0
  static bool classof(const Node *N) {
263
0
    return N->kind() == NodeKind::BreakStatement;
264
0
  }
265
  syntax::Leaf *breakKeyword();
266
};
267
268
/// return <expr>;
269
/// return;
270
class ReturnStatement final : public Statement {
271
public:
272
2
  ReturnStatement() : Statement(NodeKind::ReturnStatement) {}
273
0
  static bool classof(const Node *N) {
274
0
    return N->kind() == NodeKind::ReturnStatement;
275
0
  }
276
  syntax::Leaf *returnKeyword();
277
  syntax::Expression *value();
278
};
279
280
/// for (<decl> : <init>) <body>
281
class RangeBasedForStatement final : public Statement {
282
public:
283
1
  RangeBasedForStatement() : Statement(NodeKind::RangeBasedForStatement) {}
284
0
  static bool classof(const Node *N) {
285
0
    return N->kind() == NodeKind::RangeBasedForStatement;
286
0
  }
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:
295
7
  ExpressionStatement() : Statement(NodeKind::ExpressionStatement) {}
296
0
  static bool classof(const Node *N) {
297
0
    return N->kind() == NodeKind::ExpressionStatement;
298
0
  }
299
  syntax::Expression *expression();
300
};
301
302
/// { statement1; statement2; … }
303
class CompoundStatement final : public Statement {
304
public:
305
30
  CompoundStatement() : Statement(NodeKind::CompoundStatement) {}
306
3
  static bool classof(const Node *N) {
307
3
    return N->kind() == NodeKind::CompoundStatement;
308
3
  }
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:
321
54
  Declaration(NodeKind K) : Tree(K) {}
322
0
  static bool classof(const Node *N) {
323
0
    return NodeKind::UnknownDeclaration <= N->kind() &&
324
0
           N->kind() <= NodeKind::TypeAliasDeclaration;
325
0
  }
326
};
327
328
/// Declaration of an unknown kind, e.g. not yet supported in syntax trees.
329
class UnknownDeclaration final : public Declaration {
330
public:
331
2
  UnknownDeclaration() : Declaration(NodeKind::UnknownDeclaration) {}
332
0
  static bool classof(const Node *N) {
333
0
    return N->kind() == NodeKind::UnknownDeclaration;
334
0
  }
335
};
336
337
/// A semicolon in the top-level context. Does not declare anything.
338
class EmptyDeclaration final : public Declaration {
339
public:
340
1
  EmptyDeclaration() : Declaration(NodeKind::EmptyDeclaration) {}
341
0
  static bool classof(const Node *N) {
342
0
    return N->kind() == NodeKind::EmptyDeclaration;
343
0
  }
344
};
345
346
/// static_assert(<condition>, <message>)
347
/// static_assert(<condition>)
348
class StaticAssertDeclaration final : public Declaration {
349
public:
350
2
  StaticAssertDeclaration() : Declaration(NodeKind::StaticAssertDeclaration) {}
351
0
  static bool classof(const Node *N) {
352
0
    return N->kind() == NodeKind::StaticAssertDeclaration;
353
0
  }
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:
362
  LinkageSpecificationDeclaration()
363
2
      : Declaration(NodeKind::LinkageSpecificationDeclaration) {}
364
0
  static bool classof(const Node *N) {
365
0
    return N->kind() == NodeKind::LinkageSpecificationDeclaration;
366
0
  }
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:
374
35
  SimpleDeclaration() : Declaration(NodeKind::SimpleDeclaration) {}
375
0
  static bool classof(const Node *N) {
376
0
    return N->kind() == NodeKind::SimpleDeclaration;
377
0
  }
378
};
379
380
/// namespace <name> { <decls> }
381
class NamespaceDefinition final : public Declaration {
382
public:
383
6
  NamespaceDefinition() : Declaration(NodeKind::NamespaceDefinition) {}
384
0
  static bool classof(const Node *N) {
385
0
    return N->kind() == NodeKind::NamespaceDefinition;
386
0
  }
387
};
388
389
/// namespace <name> = <namespace-reference>
390
class NamespaceAliasDefinition final : public Declaration {
391
public:
392
  NamespaceAliasDefinition()
393
1
      : Declaration(NodeKind::NamespaceAliasDefinition) {}
394
0
  static bool classof(const Node *N) {
395
0
    return N->kind() == NodeKind::NamespaceAliasDefinition;
396
0
  }
397
};
398
399
/// using namespace <name>
400
class UsingNamespaceDirective final : public Declaration {
401
public:
402
1
  UsingNamespaceDirective() : Declaration(NodeKind::UsingNamespaceDirective) {}
403
0
  static bool classof(const Node *N) {
404
0
    return N->kind() == NodeKind::UsingNamespaceDirective;
405
0
  }
406
};
407
408
/// using <scope>::<name>
409
/// using typename <scope>::<name>
410
class UsingDeclaration final : public Declaration {
411
public:
412
3
  UsingDeclaration() : Declaration(NodeKind::UsingDeclaration) {}
413
0
  static bool classof(const Node *N) {
414
0
    return N->kind() == NodeKind::UsingDeclaration;
415
0
  }
416
};
417
418
/// using <name> = <type>
419
class TypeAliasDeclaration final : public Declaration {
420
public:
421
1
  TypeAliasDeclaration() : Declaration(NodeKind::TypeAliasDeclaration) {}
422
0
  static bool classof(const Node *N) {
423
0
    return N->kind() == NodeKind::TypeAliasDeclaration;
424
0
  }
425
};
426
427
} // namespace syntax
428
} // namespace clang
429
#endif