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

source code of clang/include/clang/Tooling/Syntax/Nodes.h