Coverage Report

Created: 2020-09-15 12:33

/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
  PrefixUnaryOperatorExpression,
44
  PostfixUnaryOperatorExpression,
45
  BinaryOperatorExpression,
46
  ParenExpression,
47
  IntegerLiteralExpression,
48
  CharacterLiteralExpression,
49
  FloatingLiteralExpression,
50
  StringLiteralExpression,
51
  BoolLiteralExpression,
52
  CxxNullPtrExpression,
53
  IntegerUserDefinedLiteralExpression,
54
  FloatUserDefinedLiteralExpression,
55
  CharUserDefinedLiteralExpression,
56
  StringUserDefinedLiteralExpression,
57
  IdExpression,
58
  MemberExpression,
59
  ThisExpression,
60
  CallExpression,
61
62
  // Statements.
63
  UnknownStatement,
64
  DeclarationStatement,
65
  EmptyStatement,
66
  SwitchStatement,
67
  CaseStatement,
68
  DefaultStatement,
69
  IfStatement,
70
  ForStatement,
71
  WhileStatement,
72
  ContinueStatement,
73
  BreakStatement,
74
  ReturnStatement,
75
  RangeBasedForStatement,
76
  ExpressionStatement,
77
  CompoundStatement,
78
79
  // Declarations.
80
  UnknownDeclaration,
81
  EmptyDeclaration,
82
  StaticAssertDeclaration,
83
  LinkageSpecificationDeclaration,
84
  SimpleDeclaration,
85
  TemplateDeclaration,
86
  ExplicitTemplateInstantiation,
87
  NamespaceDefinition,
88
  NamespaceAliasDefinition,
89
  UsingNamespaceDirective,
90
  UsingDeclaration,
91
  TypeAliasDeclaration,
92
93
  // Declarators.
94
  SimpleDeclarator,
95
  ParenDeclarator,
96
97
  ArraySubscript,
98
  TrailingReturnType,
99
  ParametersAndQualifiers,
100
  MemberPointer,
101
  UnqualifiedId,
102
  ParameterDeclarationList,
103
  CallArguments,
104
  // Nested Name Specifiers.
105
  NestedNameSpecifier,
106
  GlobalNameSpecifier,
107
  DecltypeNameSpecifier,
108
  IdentifierNameSpecifier,
109
  SimpleTemplateNameSpecifier,
110
};
111
/// For debugging purposes.
112
raw_ostream &operator<<(raw_ostream &OS, NodeKind K);
113
114
/// A relation between a parent and child node, e.g. 'left-hand-side of
115
/// a binary expression'. Used for implementing accessors.
116
///
117
/// In general `NodeRole`s should be named the same as their accessors.
118
///
119
/// Some roles describe parent/child relations that occur multiple times in
120
/// language grammar. We define only one role to describe all instances of such
121
/// recurring relations. For example, grammar for both "if" and "while"
122
/// statements requires an opening paren and a closing paren. The opening
123
/// paren token is assigned the OpenParen role regardless of whether it appears
124
/// as a child of IfStatement or WhileStatement node. More generally, when
125
/// grammar requires a certain fixed token (like a specific keyword, or an
126
/// opening paren), we define a role for this token and use it across all
127
/// grammar rules with the same requirement. Names of such reusable roles end
128
/// with a ~Token or a ~Keyword suffix.
129
enum class NodeRole : uint8_t {
130
  // Roles common to multiple node kinds.
131
  /// A node without a parent
132
  Detached,
133
  /// Children of an unknown semantic nature, e.g. skipped tokens, comments.
134
  Unknown,
135
  /// An opening parenthesis in argument lists and blocks, e.g. '{', '(', etc.
136
  OpenParen,
137
  /// A closing parenthesis in argument lists and blocks, e.g. '}', ')', etc.
138
  CloseParen,
139
  /// A keywords that introduces some grammar construct, e.g. 'if', 'try', etc.
140
  IntroducerKeyword,
141
  /// A token that represents a literal, e.g. 'nullptr', '1', 'true', etc.
142
  LiteralToken,
143
  /// Tokens or Keywords.
144
  ArrowToken,
145
  ExternKeyword,
146
  TemplateKeyword,
147
  /// An inner statement for those that have only a single child of kind
148
  /// statement, e.g. loop body for while, for, etc; inner statement for case,
149
  /// default, etc.
150
  BodyStatement,
151
  /// List API roles.
152
  ListElement,
153
  ListDelimiter,
154
155
  // Roles specific to particular node kinds.
156
  OperatorToken,
157
  Operand,
158
  LeftHandSide,
159
  RightHandSide,
160
  ReturnValue,
161
  CaseValue,
162
  ThenStatement,
163
  ElseKeyword,
164
  ElseStatement,
165
  Expression,
166
  Statement,
167
  Condition,
168
  Message,
169
  Declarator,
170
  Declaration,
171
  Size,
172
  Parameters,
173
  TrailingReturn,
174
  UnqualifiedId,
175
  Qualifier,
176
  SubExpression,
177
  Object,
178
  AccessToken,
179
  Member,
180
  Callee,
181
  Arguments,
182
};
183
/// For debugging purposes.
184
raw_ostream &operator<<(raw_ostream &OS, NodeRole R);
185
186
class SimpleDeclarator;
187
188
/// A root node for a translation unit. Parent is always null.
189
class TranslationUnit final : public Tree {
190
public:
191
1.87k
  TranslationUnit() : Tree(NodeKind::TranslationUnit) {}
192
1.87k
  static bool classof(const Node *N) {
193
1.87k
    return N->getKind() == NodeKind::TranslationUnit;
194
1.87k
  }
195
};
196
197
/// A base class for all expressions. Note that expressions are not statements,
198
/// even though they are in clang.
199
class Expression : public Tree {
200
public:
201
4.72k
  Expression(NodeKind K) : Tree(K) {}
202
0
  static bool classof(const Node *N) {
203
0
    return NodeKind::UnknownExpression <= N->getKind() &&
204
0
           N->getKind() <= NodeKind::UnknownExpression;
205
0
  }
206
};
207
208
/// A sequence of these specifiers make a `nested-name-specifier`.
209
/// e.g. the `std` or `vector<int>` in `std::vector<int>::size`.
210
class NameSpecifier : public Tree {
211
public:
212
271
  NameSpecifier(NodeKind K) : Tree(K) {}
213
0
  static bool classof(const Node *N) {
214
0
    return N->getKind() == NodeKind::GlobalNameSpecifier ||
215
0
           N->getKind() == NodeKind::DecltypeNameSpecifier ||
216
0
           N->getKind() == NodeKind::IdentifierNameSpecifier ||
217
0
           N->getKind() == NodeKind::SimpleTemplateNameSpecifier;
218
0
  }
219
};
220
221
/// The global namespace name specifier, this specifier doesn't correspond to a
222
/// token instead an absence of tokens before a `::` characterizes it, in
223
/// `::std::vector<int>` it would be characterized by the absence of a token
224
/// before the first `::`
225
class GlobalNameSpecifier final : public NameSpecifier {
226
public:
227
60
  GlobalNameSpecifier() : NameSpecifier(NodeKind::GlobalNameSpecifier) {}
228
0
  static bool classof(const Node *N) {
229
0
    return N->getKind() == NodeKind::GlobalNameSpecifier;
230
0
  }
231
};
232
233
/// A name specifier holding a decltype, of the form: `decltype ( expression ) `
234
/// e.g. the `decltype(s)` in `decltype(s)::size`.
235
class DecltypeNameSpecifier final : public NameSpecifier {
236
public:
237
8
  DecltypeNameSpecifier() : NameSpecifier(NodeKind::DecltypeNameSpecifier) {}
238
0
  static bool classof(const Node *N) {
239
0
    return N->getKind() == NodeKind::DecltypeNameSpecifier;
240
0
  }
241
};
242
243
/// A identifier name specifier, of the form `identifier`
244
/// e.g. the `std` in `std::vector<int>::size`.
245
class IdentifierNameSpecifier final : public NameSpecifier {
246
public:
247
  IdentifierNameSpecifier()
248
148
      : NameSpecifier(NodeKind::IdentifierNameSpecifier) {}
249
0
  static bool classof(const Node *N) {
250
0
    return N->getKind() == NodeKind::IdentifierNameSpecifier;
251
0
  }
252
};
253
254
/// A name specifier with a simple-template-id, of the form `template_opt
255
/// identifier < template-args >` e.g. the `vector<int>` in
256
/// `std::vector<int>::size`.
257
class SimpleTemplateNameSpecifier final : public NameSpecifier {
258
public:
259
  SimpleTemplateNameSpecifier()
260
55
      : NameSpecifier(NodeKind::SimpleTemplateNameSpecifier) {}
261
0
  static bool classof(const Node *N) {
262
0
    return N->getKind() == NodeKind::SimpleTemplateNameSpecifier;
263
0
  }
264
};
265
266
/// Models a `nested-name-specifier`. C++ [expr.prim.id.qual]
267
/// e.g. the `std::vector<int>::` in `std::vector<int>::size`.
268
class NestedNameSpecifier final : public List {
269
public:
270
201
  NestedNameSpecifier() : List(NodeKind::NestedNameSpecifier) {}
271
0
  static bool classof(const Node *N) {
272
0
    return N->getKind() <= NodeKind::NestedNameSpecifier;
273
0
  }
274
  std::vector<NameSpecifier *> getSpecifiers();
275
  std::vector<List::ElementAndDelimiter<syntax::NameSpecifier>>
276
  getSpecifiersAndDoubleColons();
277
};
278
279
/// Models an `unqualified-id`. C++ [expr.prim.id.unqual]
280
/// e.g. the `size` in `std::vector<int>::size`.
281
class UnqualifiedId final : public Tree {
282
public:
283
1.22k
  UnqualifiedId() : Tree(NodeKind::UnqualifiedId) {}
284
0
  static bool classof(const Node *N) {
285
0
    return N->getKind() == NodeKind::UnqualifiedId;
286
0
  }
287
};
288
289
/// Models an `id-expression`, e.g. `std::vector<int>::size`.
290
/// C++ [expr.prim.id]
291
/// id-expression:
292
///   unqualified-id
293
///   qualified-id
294
/// qualified-id:
295
///   nested-name-specifier template_opt unqualified-id
296
class IdExpression final : public Expression {
297
public:
298
1.22k
  IdExpression() : Expression(NodeKind::IdExpression) {}
299
0
  static bool classof(const Node *N) {
300
0
    return N->getKind() == NodeKind::IdExpression;
301
0
  }
302
  NestedNameSpecifier *getQualifier();
303
  Leaf *getTemplateKeyword();
304
  UnqualifiedId *getUnqualifiedId();
305
};
306
307
/// An expression of an unknown kind, i.e. one not currently handled by the
308
/// syntax tree.
309
class UnknownExpression final : public Expression {
310
public:
311
306
  UnknownExpression() : Expression(NodeKind::UnknownExpression) {}
312
0
  static bool classof(const Node *N) {
313
0
    return N->getKind() == NodeKind::UnknownExpression;
314
0
  }
315
};
316
317
/// Models a this expression `this`. C++ [expr.prim.this]
318
class ThisExpression final : public Expression {
319
public:
320
40
  ThisExpression() : Expression(NodeKind::ThisExpression) {}
321
0
  static bool classof(const Node *N) {
322
0
    return N->getKind() == NodeKind::ThisExpression;
323
0
  }
324
  Leaf *getThisKeyword();
325
};
326
327
/// Models arguments of a function call.
328
///   call-arguments:
329
///     delimited_list(expression, ',')
330
/// Note: This construct is a simplification of the grammar rule for
331
/// `expression-list`, that is used in the definition of `call-expression`
332
class CallArguments final : public List {
333
public:
334
437
  CallArguments() : List(NodeKind::CallArguments) {}
335
0
  static bool classof(const Node *N) {
336
0
    return N->getKind() <= NodeKind::CallArguments;
337
0
  }
338
  std::vector<Expression *> getArguments();
339
  std::vector<List::ElementAndDelimiter<Expression>> getArgumentsAndCommas();
340
};
341
342
/// A function call. C++ [expr.call]
343
/// call-expression:
344
///   expression '(' call-arguments ')'
345
/// e.g `f(1, '2')` or `this->Base::f()`
346
class CallExpression final : public Expression {
347
public:
348
437
  CallExpression() : Expression(NodeKind::CallExpression) {}
349
0
  static bool classof(const Node *N) {
350
0
    return N->getKind() == NodeKind::CallExpression;
351
0
  }
352
  Expression *getCallee();
353
  Leaf *getOpenParen();
354
  CallArguments *getArguments();
355
  Leaf *getCloseParen();
356
};
357
358
/// Models a parenthesized expression `(E)`. C++ [expr.prim.paren]
359
/// e.g. `(3 + 2)` in `a = 1 + (3 + 2);`
360
class ParenExpression final : public Expression {
361
public:
362
118
  ParenExpression() : Expression(NodeKind::ParenExpression) {}
363
0
  static bool classof(const Node *N) {
364
0
    return N->getKind() == NodeKind::ParenExpression;
365
0
  }
366
  Leaf *getOpenParen();
367
  Expression *getSubExpression();
368
  Leaf *getCloseParen();
369
};
370
371
/// Models a class member access. C++ [expr.ref]
372
/// member-expression:
373
///   expression -> template_opt id-expression
374
///   expression .  template_opt id-expression
375
/// e.g. `x.a`, `xp->a`
376
///
377
/// Note: An implicit member access inside a class, i.e. `a` instead of
378
/// `this->a`, is an `id-expression`.
379
class MemberExpression final : public Expression {
380
public:
381
210
  MemberExpression() : Expression(NodeKind::MemberExpression) {}
382
0
  static bool classof(const Node *N) {
383
0
    return N->getKind() == NodeKind::MemberExpression;
384
0
  }
385
  Expression *getObject();
386
  Leaf *getAccessToken();
387
  Leaf *getTemplateKeyword();
388
  IdExpression *getMember();
389
};
390
391
/// Expression for literals. C++ [lex.literal]
392
class LiteralExpression : public Expression {
393
public:
394
1.67k
  LiteralExpression(NodeKind K) : Expression(K) {}
395
0
  static bool classof(const Node *N) {
396
0
    return N->getKind() == NodeKind::IntegerLiteralExpression ||
397
0
           N->getKind() == NodeKind::CharacterLiteralExpression ||
398
0
           N->getKind() == NodeKind::FloatingLiteralExpression ||
399
0
           N->getKind() == NodeKind::StringLiteralExpression ||
400
0
           N->getKind() == NodeKind::BoolLiteralExpression ||
401
0
           N->getKind() == NodeKind::CxxNullPtrExpression ||
402
0
           N->getKind() == NodeKind::IntegerUserDefinedLiteralExpression ||
403
0
           N->getKind() == NodeKind::FloatUserDefinedLiteralExpression ||
404
0
           N->getKind() == NodeKind::CharUserDefinedLiteralExpression ||
405
0
           N->getKind() == NodeKind::StringUserDefinedLiteralExpression;
406
0
  }
407
  Leaf *getLiteralToken();
408
};
409
410
/// Expression for integer literals. C++ [lex.icon]
411
class IntegerLiteralExpression final : public LiteralExpression {
412
public:
413
  IntegerLiteralExpression()
414
1.13k
      : LiteralExpression(NodeKind::IntegerLiteralExpression) {}
415
0
  static bool classof(const Node *N) {
416
0
    return N->getKind() == NodeKind::IntegerLiteralExpression;
417
0
  }
418
};
419
420
/// Expression for character literals. C++ [lex.ccon]
421
class CharacterLiteralExpression final : public LiteralExpression {
422
public:
423
  CharacterLiteralExpression()
424
198
      : LiteralExpression(NodeKind::CharacterLiteralExpression) {}
425
0
  static bool classof(const Node *N) {
426
0
    return N->getKind() == NodeKind::CharacterLiteralExpression;
427
0
  }
428
};
429
430
/// Expression for floating-point literals. C++ [lex.fcon]
431
class FloatingLiteralExpression final : public LiteralExpression {
432
public:
433
  FloatingLiteralExpression()
434
128
      : LiteralExpression(NodeKind::FloatingLiteralExpression) {}
435
0
  static bool classof(const Node *N) {
436
0
    return N->getKind() == NodeKind::FloatingLiteralExpression;
437
0
  }
438
};
439
440
/// Expression for string-literals. C++ [lex.string]
441
class StringLiteralExpression final : public LiteralExpression {
442
public:
443
  StringLiteralExpression()
444
68
      : LiteralExpression(NodeKind::StringLiteralExpression) {}
445
0
  static bool classof(const Node *N) {
446
0
    return N->getKind() == NodeKind::StringLiteralExpression;
447
0
  }
448
};
449
450
/// Expression for boolean literals. C++ [lex.bool]
451
class BoolLiteralExpression final : public LiteralExpression {
452
public:
453
  BoolLiteralExpression()
454
80
      : LiteralExpression(NodeKind::BoolLiteralExpression) {}
455
0
  static bool classof(const Node *N) {
456
0
    return N->getKind() == NodeKind::BoolLiteralExpression;
457
0
  }
458
};
459
460
/// Expression for the `nullptr` literal. C++ [lex.nullptr]
461
class CxxNullPtrExpression final : public LiteralExpression {
462
public:
463
8
  CxxNullPtrExpression() : LiteralExpression(NodeKind::CxxNullPtrExpression) {}
464
0
  static bool classof(const Node *N) {
465
0
    return N->getKind() == NodeKind::CxxNullPtrExpression;
466
0
  }
467
};
468
469
/// Expression for user-defined literal. C++ [lex.ext]
470
/// user-defined-literal:
471
///   user-defined-integer-literal
472
///   user-defined-floating-point-literal
473
///   user-defined-string-literal
474
///   user-defined-character-literal
475
class UserDefinedLiteralExpression : public LiteralExpression {
476
public:
477
64
  UserDefinedLiteralExpression(NodeKind K) : LiteralExpression(K) {}
478
0
  static bool classof(const Node *N) {
479
0
    return N->getKind() == NodeKind::IntegerUserDefinedLiteralExpression ||
480
0
           N->getKind() == NodeKind::FloatUserDefinedLiteralExpression ||
481
0
           N->getKind() == NodeKind::CharUserDefinedLiteralExpression ||
482
0
           N->getKind() == NodeKind::StringUserDefinedLiteralExpression;
483
0
  }
484
};
485
486
/// Expression for user-defined-integer-literal. C++ [lex.ext]
487
class IntegerUserDefinedLiteralExpression final
488
    : public UserDefinedLiteralExpression {
489
public:
490
  IntegerUserDefinedLiteralExpression()
491
      : UserDefinedLiteralExpression(
492
24
            NodeKind::IntegerUserDefinedLiteralExpression) {}
493
0
  static bool classof(const Node *N) {
494
0
    return N->getKind() == NodeKind::IntegerUserDefinedLiteralExpression;
495
0
  }
496
};
497
498
/// Expression for user-defined-floating-point-literal. C++ [lex.ext]
499
class FloatUserDefinedLiteralExpression final
500
    : public UserDefinedLiteralExpression {
501
public:
502
  FloatUserDefinedLiteralExpression()
503
      : UserDefinedLiteralExpression(
504
24
            NodeKind::FloatUserDefinedLiteralExpression) {}
505
0
  static bool classof(const Node *N) {
506
0
    return N->getKind() == NodeKind::FloatUserDefinedLiteralExpression;
507
0
  }
508
};
509
510
/// Expression for user-defined-character-literal. C++ [lex.ext]
511
class CharUserDefinedLiteralExpression final
512
    : public UserDefinedLiteralExpression {
513
public:
514
  CharUserDefinedLiteralExpression()
515
      : UserDefinedLiteralExpression(
516
8
            NodeKind::CharUserDefinedLiteralExpression) {}
517
0
  static bool classof(const Node *N) {
518
0
    return N->getKind() == NodeKind::CharUserDefinedLiteralExpression;
519
0
  }
520
};
521
522
/// Expression for user-defined-string-literal. C++ [lex.ext]
523
class StringUserDefinedLiteralExpression final
524
    : public UserDefinedLiteralExpression {
525
public:
526
  StringUserDefinedLiteralExpression()
527
      : UserDefinedLiteralExpression(
528
8
            NodeKind::StringUserDefinedLiteralExpression) {}
529
0
  static bool classof(const Node *N) {
530
0
    return N->getKind() == NodeKind::StringUserDefinedLiteralExpression;
531
0
  }
532
};
533
534
/// An abstract class for prefix and postfix unary operators.
535
class UnaryOperatorExpression : public Expression {
536
public:
537
262
  UnaryOperatorExpression(NodeKind K) : Expression(K) {}
538
0
  static bool classof(const Node *N) {
539
0
    return N->getKind() == NodeKind::PrefixUnaryOperatorExpression ||
540
0
           N->getKind() == NodeKind::PostfixUnaryOperatorExpression;
541
0
  }
542
  Leaf *getOperatorToken();
543
  Expression *getOperand();
544
};
545
546
/// <operator> <operand>
547
///
548
/// For example:
549
///   +a          -b
550
///   !c          not c
551
///   ~d          compl d
552
///   *e          &f
553
///   ++h         --h
554
///   __real i    __imag i
555
class PrefixUnaryOperatorExpression final : public UnaryOperatorExpression {
556
public:
557
  PrefixUnaryOperatorExpression()
558
224
      : UnaryOperatorExpression(NodeKind::PrefixUnaryOperatorExpression) {}
559
0
  static bool classof(const Node *N) {
560
0
    return N->getKind() == NodeKind::PrefixUnaryOperatorExpression;
561
0
  }
562
};
563
564
/// <operand> <operator>
565
///
566
/// For example:
567
///   a++
568
///   b--
569
class PostfixUnaryOperatorExpression final : public UnaryOperatorExpression {
570
public:
571
  PostfixUnaryOperatorExpression()
572
38
      : UnaryOperatorExpression(NodeKind::PostfixUnaryOperatorExpression) {}
573
0
  static bool classof(const Node *N) {
574
0
    return N->getKind() == NodeKind::PostfixUnaryOperatorExpression;
575
0
  }
576
};
577
578
/// <lhs> <operator> <rhs>
579
///
580
/// For example:
581
///   a + b
582
///   a bitor 1
583
///   a |= b
584
///   a and_eq b
585
class BinaryOperatorExpression final : public Expression {
586
public:
587
452
  BinaryOperatorExpression() : Expression(NodeKind::BinaryOperatorExpression) {}
588
0
  static bool classof(const Node *N) {
589
0
    return N->getKind() == NodeKind::BinaryOperatorExpression;
590
0
  }
591
  Expression *getLhs();
592
  Leaf *getOperatorToken();
593
  Expression *getRhs();
594
};
595
596
/// An abstract node for C++ statements, e.g. 'while', 'if', etc.
597
/// FIXME: add accessors for semicolon of statements that have it.
598
class Statement : public Tree {
599
public:
600
3.28k
  Statement(NodeKind K) : Tree(K) {}
601
42
  static bool classof(const Node *N) {
602
42
    return NodeKind::UnknownStatement <= N->getKind() &&
603
42
           N->getKind() <= NodeKind::CompoundStatement;
604
42
  }
605
};
606
607
/// A statement of an unknown kind, i.e. one not currently handled by the syntax
608
/// tree.
609
class UnknownStatement final : public Statement {
610
public:
611
14
  UnknownStatement() : Statement(NodeKind::UnknownStatement) {}
612
0
  static bool classof(const Node *N) {
613
0
    return N->getKind() == NodeKind::UnknownStatement;
614
0
  }
615
};
616
617
/// E.g. 'int a, b = 10;'
618
class DeclarationStatement final : public Statement {
619
public:
620
188
  DeclarationStatement() : Statement(NodeKind::DeclarationStatement) {}
621
0
  static bool classof(const Node *N) {
622
0
    return N->getKind() == NodeKind::DeclarationStatement;
623
0
  }
624
};
625
626
/// The no-op statement, i.e. ';'.
627
class EmptyStatement final : public Statement {
628
public:
629
64
  EmptyStatement() : Statement(NodeKind::EmptyStatement) {}
630
14
  static bool classof(const Node *N) {
631
14
    return N->getKind() == NodeKind::EmptyStatement;
632
14
  }
633
};
634
635
/// switch (<cond>) <body>
636
class SwitchStatement final : public Statement {
637
public:
638
14
  SwitchStatement() : Statement(NodeKind::SwitchStatement) {}
639
0
  static bool classof(const Node *N) {
640
0
    return N->getKind() == NodeKind::SwitchStatement;
641
0
  }
642
  Leaf *getSwitchKeyword();
643
  Statement *getBody();
644
};
645
646
/// case <value>: <body>
647
class CaseStatement final : public Statement {
648
public:
649
14
  CaseStatement() : Statement(NodeKind::CaseStatement) {}
650
0
  static bool classof(const Node *N) {
651
0
    return N->getKind() == NodeKind::CaseStatement;
652
0
  }
653
  Leaf *getCaseKeyword();
654
  Expression *getCaseValue();
655
  Statement *getBody();
656
};
657
658
/// default: <body>
659
class DefaultStatement final : public Statement {
660
public:
661
14
  DefaultStatement() : Statement(NodeKind::DefaultStatement) {}
662
0
  static bool classof(const Node *N) {
663
0
    return N->getKind() == NodeKind::DefaultStatement;
664
0
  }
665
  Leaf *getDefaultKeyword();
666
  Statement *getBody();
667
};
668
669
/// if (cond) <then-statement> else <else-statement>
670
/// FIXME: add condition that models 'expression  or variable declaration'
671
class IfStatement final : public Statement {
672
public:
673
84
  IfStatement() : Statement(NodeKind::IfStatement) {}
674
0
  static bool classof(const Node *N) {
675
0
    return N->getKind() == NodeKind::IfStatement;
676
0
  }
677
  Leaf *getIfKeyword();
678
  Statement *getThenStatement();
679
  Leaf *getElseKeyword();
680
  Statement *getElseStatement();
681
};
682
683
/// for (<init>; <cond>; <increment>) <body>
684
class ForStatement final : public Statement {
685
public:
686
14
  ForStatement() : Statement(NodeKind::ForStatement) {}
687
0
  static bool classof(const Node *N) {
688
0
    return N->getKind() == NodeKind::ForStatement;
689
0
  }
690
  Leaf *getForKeyword();
691
  Statement *getBody();
692
};
693
694
/// while (<cond>) <body>
695
class WhileStatement final : public Statement {
696
public:
697
14
  WhileStatement() : Statement(NodeKind::WhileStatement) {}
698
0
  static bool classof(const Node *N) {
699
0
    return N->getKind() == NodeKind::WhileStatement;
700
0
  }
701
  Leaf *getWhileKeyword();
702
  Statement *getBody();
703
};
704
705
/// continue;
706
class ContinueStatement final : public Statement {
707
public:
708
14
  ContinueStatement() : Statement(NodeKind::ContinueStatement) {}
709
0
  static bool classof(const Node *N) {
710
0
    return N->getKind() == NodeKind::ContinueStatement;
711
0
  }
712
  Leaf *getContinueKeyword();
713
};
714
715
/// break;
716
class BreakStatement final : public Statement {
717
public:
718
14
  BreakStatement() : Statement(NodeKind::BreakStatement) {}
719
0
  static bool classof(const Node *N) {
720
0
    return N->getKind() == NodeKind::BreakStatement;
721
0
  }
722
  Leaf *getBreakKeyword();
723
};
724
725
/// return <expr>;
726
/// return;
727
class ReturnStatement final : public Statement {
728
public:
729
74
  ReturnStatement() : Statement(NodeKind::ReturnStatement) {}
730
0
  static bool classof(const Node *N) {
731
0
    return N->getKind() == NodeKind::ReturnStatement;
732
0
  }
733
  Leaf *getReturnKeyword();
734
  Expression *getReturnValue();
735
};
736
737
/// for (<decl> : <init>) <body>
738
class RangeBasedForStatement final : public Statement {
739
public:
740
8
  RangeBasedForStatement() : Statement(NodeKind::RangeBasedForStatement) {}
741
0
  static bool classof(const Node *N) {
742
0
    return N->getKind() == NodeKind::RangeBasedForStatement;
743
0
  }
744
  Leaf *getForKeyword();
745
  Statement *getBody();
746
};
747
748
/// Expression in a statement position, e.g. functions calls inside compound
749
/// statements or inside a loop body.
750
class ExpressionStatement final : public Statement {
751
public:
752
1.47k
  ExpressionStatement() : Statement(NodeKind::ExpressionStatement) {}
753
0
  static bool classof(const Node *N) {
754
0
    return N->getKind() == NodeKind::ExpressionStatement;
755
0
  }
756
  Expression *getExpression();
757
};
758
759
/// { statement1; statement2; … }
760
class CompoundStatement final : public Statement {
761
public:
762
1.27k
  CompoundStatement() : Statement(NodeKind::CompoundStatement) {}
763
42
  static bool classof(const Node *N) {
764
42
    return N->getKind() == NodeKind::CompoundStatement;
765
42
  }
766
  Leaf *getLbrace();
767
  /// FIXME: use custom iterator instead of 'vector'.
768
  std::vector<Statement *> getStatements();
769
  Leaf *getRbrace();
770
};
771
772
/// A declaration that can appear at the top-level. Note that this does *not*
773
/// correspond 1-to-1 to clang::Decl. Syntax trees distinguish between top-level
774
/// declarations (e.g. namespace definitions) and declarators (e.g. variables,
775
/// typedefs, etc.). Declarators are stored inside SimpleDeclaration.
776
class Declaration : public Tree {
777
public:
778
6.00k
  Declaration(NodeKind K) : Tree(K) {}
779
0
  static bool classof(const Node *N) {
780
0
    return NodeKind::UnknownDeclaration <= N->getKind() &&
781
0
           N->getKind() <= NodeKind::TypeAliasDeclaration;
782
0
  }
783
};
784
785
/// Declaration of an unknown kind, e.g. not yet supported in syntax trees.
786
class UnknownDeclaration final : public Declaration {
787
public:
788
331
  UnknownDeclaration() : Declaration(NodeKind::UnknownDeclaration) {}
789
0
  static bool classof(const Node *N) {
790
0
    return N->getKind() == NodeKind::UnknownDeclaration;
791
0
  }
792
};
793
794
/// A semicolon in the top-level context. Does not declare anything.
795
class EmptyDeclaration final : public Declaration {
796
public:
797
14
  EmptyDeclaration() : Declaration(NodeKind::EmptyDeclaration) {}
798
0
  static bool classof(const Node *N) {
799
0
    return N->getKind() == NodeKind::EmptyDeclaration;
800
0
  }
801
};
802
803
/// static_assert(<condition>, <message>)
804
/// static_assert(<condition>)
805
class StaticAssertDeclaration final : public Declaration {
806
public:
807
12
  StaticAssertDeclaration() : Declaration(NodeKind::StaticAssertDeclaration) {}
808
0
  static bool classof(const Node *N) {
809
0
    return N->getKind() == NodeKind::StaticAssertDeclaration;
810
0
  }
811
  Expression *getCondition();
812
  Expression *getMessage();
813
};
814
815
/// extern <string-literal> declaration
816
/// extern <string-literal> { <decls>  }
817
class LinkageSpecificationDeclaration final : public Declaration {
818
public:
819
  LinkageSpecificationDeclaration()
820
20
      : Declaration(NodeKind::LinkageSpecificationDeclaration) {}
821
0
  static bool classof(const Node *N) {
822
0
    return N->getKind() == NodeKind::LinkageSpecificationDeclaration;
823
0
  }
824
};
825
826
/// Groups multiple declarators (e.g. variables, typedefs, etc.) together. All
827
/// grouped declarators share the same declaration specifiers (e.g. 'int' or
828
/// 'typedef').
829
class SimpleDeclaration final : public Declaration {
830
public:
831
5.15k
  SimpleDeclaration() : Declaration(NodeKind::SimpleDeclaration) {}
832
20
  static bool classof(const Node *N) {
833
20
    return N->getKind() == NodeKind::SimpleDeclaration;
834
20
  }
835
  /// FIXME: use custom iterator instead of 'vector'.
836
  std::vector<SimpleDeclarator *> getDeclarators();
837
};
838
839
/// template <template-parameters> <declaration>
840
class TemplateDeclaration final : public Declaration {
841
public:
842
303
  TemplateDeclaration() : Declaration(NodeKind::TemplateDeclaration) {}
843
0
  static bool classof(const Node *N) {
844
0
    return N->getKind() == NodeKind::TemplateDeclaration;
845
0
  }
846
  Leaf *getTemplateKeyword();
847
  Declaration *getDeclaration();
848
};
849
850
/// template <declaration>
851
/// Examples:
852
///     template struct X<int>
853
///     template void foo<int>()
854
///     template int var<double>
855
class ExplicitTemplateInstantiation final : public Declaration {
856
public:
857
  ExplicitTemplateInstantiation()
858
20
      : Declaration(NodeKind::ExplicitTemplateInstantiation) {}
859
0
  static bool classof(const Node *N) {
860
0
    return N->getKind() == NodeKind::ExplicitTemplateInstantiation;
861
0
  }
862
  Leaf *getTemplateKeyword();
863
  Leaf *getExternKeyword();
864
  Declaration *getDeclaration();
865
};
866
867
/// namespace <name> { <decls> }
868
class NamespaceDefinition final : public Declaration {
869
public:
870
94
  NamespaceDefinition() : Declaration(NodeKind::NamespaceDefinition) {}
871
0
  static bool classof(const Node *N) {
872
0
    return N->getKind() == NodeKind::NamespaceDefinition;
873
0
  }
874
};
875
876
/// namespace <name> = <namespace-reference>
877
class NamespaceAliasDefinition final : public Declaration {
878
public:
879
  NamespaceAliasDefinition()
880
10
      : Declaration(NodeKind::NamespaceAliasDefinition) {}
881
0
  static bool classof(const Node *N) {
882
0
    return N->getKind() == NodeKind::NamespaceAliasDefinition;
883
0
  }
884
};
885
886
/// using namespace <name>
887
class UsingNamespaceDirective final : public Declaration {
888
public:
889
10
  UsingNamespaceDirective() : Declaration(NodeKind::UsingNamespaceDirective) {}
890
0
  static bool classof(const Node *N) {
891
0
    return N->getKind() == NodeKind::UsingNamespaceDirective;
892
0
  }
893
};
894
895
/// using <scope>::<name>
896
/// using typename <scope>::<name>
897
class UsingDeclaration final : public Declaration {
898
public:
899
30
  UsingDeclaration() : Declaration(NodeKind::UsingDeclaration) {}
900
0
  static bool classof(const Node *N) {
901
0
    return N->getKind() == NodeKind::UsingDeclaration;
902
0
  }
903
};
904
905
/// using <name> = <type>
906
class TypeAliasDeclaration final : public Declaration {
907
public:
908
8
  TypeAliasDeclaration() : Declaration(NodeKind::TypeAliasDeclaration) {}
909
0
  static bool classof(const Node *N) {
910
0
    return N->getKind() == NodeKind::TypeAliasDeclaration;
911
0
  }
912
};
913
914
/// Covers a name, an initializer and a part of the type outside declaration
915
/// specifiers. Examples are:
916
///     `*a` in `int *a`
917
///     `a[10]` in `int a[10]`
918
///     `*a = nullptr` in `int *a = nullptr`
919
/// Declarators can be unnamed too:
920
///     `**` in `new int**`
921
///     `* = nullptr` in `void foo(int* = nullptr)`
922
/// Most declarators you encounter are instances of SimpleDeclarator. They may
923
/// contain an inner declarator inside parentheses, we represent it as
924
/// ParenDeclarator. E.g.
925
///     `(*a)` in `int (*a) = 10`
926
class Declarator : public Tree {
927
public:
928
4.04k
  Declarator(NodeKind K) : Tree(K) {}
929
0
  static bool classof(const Node *N) {
930
0
    return NodeKind::SimpleDeclarator <= N->getKind() &&
931
0
           N->getKind() <= NodeKind::ParenDeclarator;
932
0
  }
933
};
934
935
/// A top-level declarator without parentheses. See comment of Declarator for
936
/// more details.
937
class SimpleDeclarator final : public Declarator {
938
public:
939
3.88k
  SimpleDeclarator() : Declarator(NodeKind::SimpleDeclarator) {}
940
0
  static bool classof(const Node *N) {
941
0
    return N->getKind() == NodeKind::SimpleDeclarator;
942
0
  }
943
};
944
945
/// Declarator inside parentheses.
946
/// E.g. `(***a)` from `int (***a) = nullptr;`
947
/// See comment of Declarator for more details.
948
class ParenDeclarator final : public Declarator {
949
public:
950
156
  ParenDeclarator() : Declarator(NodeKind::ParenDeclarator) {}
951
0
  static bool classof(const Node *N) {
952
0
    return N->getKind() == NodeKind::ParenDeclarator;
953
0
  }
954
  Leaf *getLparen();
955
  Leaf *getRparen();
956
};
957
958
/// Array size specified inside a declarator.
959
/// E.g:
960
///   `[10]` in `int a[10];`
961
///   `[static 10]` in `void f(int xs[static 10]);`
962
class ArraySubscript final : public Tree {
963
public:
964
88
  ArraySubscript() : Tree(NodeKind::ArraySubscript) {}
965
0
  static bool classof(const Node *N) {
966
0
    return N->getKind() == NodeKind::ArraySubscript;
967
0
  }
968
  // TODO: add an accessor for the "static" keyword.
969
  Leaf *getLbracket();
970
  Expression *getSize();
971
  Leaf *getRbracket();
972
};
973
974
/// Trailing return type after the parameter list, including the arrow token.
975
/// E.g. `-> int***`.
976
class TrailingReturnType final : public Tree {
977
public:
978
24
  TrailingReturnType() : Tree(NodeKind::TrailingReturnType) {}
979
0
  static bool classof(const Node *N) {
980
0
    return N->getKind() == NodeKind::TrailingReturnType;
981
0
  }
982
  // TODO: add accessors for specifiers.
983
  Leaf *getArrowToken();
984
  // FIXME: This should be a `type-id` following the grammar. Fix this once we
985
  // have a representation of `type-id`s.
986
  SimpleDeclarator *getDeclarator();
987
};
988
989
/// Models a `parameter-declaration-list` which appears within
990
/// `parameters-and-qualifiers`. See C++ [dcl.fct]
991
class ParameterDeclarationList final : public List {
992
public:
993
2.20k
  ParameterDeclarationList() : List(NodeKind::ParameterDeclarationList) {}
994
0
  static bool classof(const Node *N) {
995
0
    return N->getKind() == NodeKind::ParameterDeclarationList;
996
0
  }
997
  std::vector<SimpleDeclaration *> getParameterDeclarations();
998
  std::vector<List::ElementAndDelimiter<syntax::SimpleDeclaration>>
999
  getParametersAndCommas();
1000
};
1001
1002
/// Parameter list for a function type and a trailing return type, if the
1003
/// function has one.
1004
/// E.g.:
1005
///  `(int a) volatile ` in `int foo(int a) volatile;`
1006
///  `(int a) &&` in `int foo(int a) &&;`
1007
///  `() -> int` in `auto foo() -> int;`
1008
///  `() const` in `int foo() const;`
1009
///  `() noexcept` in `int foo() noexcept;`
1010
///  `() throw()` in `int foo() throw();`
1011
///
1012
/// (!) override doesn't belong here.
1013
class ParametersAndQualifiers final : public Tree {
1014
public:
1015
2.20k
  ParametersAndQualifiers() : Tree(NodeKind::ParametersAndQualifiers) {}
1016
0
  static bool classof(const Node *N) {
1017
0
    return N->getKind() == NodeKind::ParametersAndQualifiers;
1018
0
  }
1019
  Leaf *getLparen();
1020
  ParameterDeclarationList *getParameters();
1021
  Leaf *getRparen();
1022
  TrailingReturnType *getTrailingReturn();
1023
};
1024
1025
/// Member pointer inside a declarator
1026
/// E.g. `X::*` in `int X::* a = 0;`
1027
class MemberPointer final : public Tree {
1028
public:
1029
70
  MemberPointer() : Tree(NodeKind::MemberPointer) {}
1030
0
  static bool classof(const Node *N) {
1031
0
    return N->getKind() == NodeKind::MemberPointer;
1032
0
  }
1033
};
1034
1035
} // namespace syntax
1036
} // namespace clang
1037
#endif