1//===- Nodes.cpp ----------------------------------------------*- 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#include "clang/Tooling/Syntax/Nodes.h"
9#include "clang/Basic/TokenKinds.h"
10
11using namespace clang;
12
13raw_ostream &syntax::operator<<(raw_ostream &OS, NodeKind K) {
14  switch (K) {
15#define CONCRETE_NODE(Kind, Parent)                                            \
16  case NodeKind::Kind:                                                         \
17    return OS << #Kind;
18#include "clang/Tooling/Syntax/Nodes.inc"
19  }
20  llvm_unreachable("unknown node kind");
21}
22
23raw_ostream &syntax::operator<<(raw_ostream &OS, NodeRole R) {
24  switch (R) {
25  case syntax::NodeRole::Detached:
26    return OS << "Detached";
27  case syntax::NodeRole::Unknown:
28    return OS << "Unknown";
29  case syntax::NodeRole::OpenParen:
30    return OS << "OpenParen";
31  case syntax::NodeRole::CloseParen:
32    return OS << "CloseParen";
33  case syntax::NodeRole::IntroducerKeyword:
34    return OS << "IntroducerKeyword";
35  case syntax::NodeRole::LiteralToken:
36    return OS << "LiteralToken";
37  case syntax::NodeRole::ArrowToken:
38    return OS << "ArrowToken";
39  case syntax::NodeRole::ExternKeyword:
40    return OS << "ExternKeyword";
41  case syntax::NodeRole::TemplateKeyword:
42    return OS << "TemplateKeyword";
43  case syntax::NodeRole::BodyStatement:
44    return OS << "BodyStatement";
45  case syntax::NodeRole::ListElement:
46    return OS << "ListElement";
47  case syntax::NodeRole::ListDelimiter:
48    return OS << "ListDelimiter";
49  case syntax::NodeRole::CaseValue:
50    return OS << "CaseValue";
51  case syntax::NodeRole::ReturnValue:
52    return OS << "ReturnValue";
53  case syntax::NodeRole::ThenStatement:
54    return OS << "ThenStatement";
55  case syntax::NodeRole::ElseKeyword:
56    return OS << "ElseKeyword";
57  case syntax::NodeRole::ElseStatement:
58    return OS << "ElseStatement";
59  case syntax::NodeRole::OperatorToken:
60    return OS << "OperatorToken";
61  case syntax::NodeRole::Operand:
62    return OS << "Operand";
63  case syntax::NodeRole::LeftHandSide:
64    return OS << "LeftHandSide";
65  case syntax::NodeRole::RightHandSide:
66    return OS << "RightHandSide";
67  case syntax::NodeRole::Expression:
68    return OS << "Expression";
69  case syntax::NodeRole::Statement:
70    return OS << "Statement";
71  case syntax::NodeRole::Condition:
72    return OS << "Condition";
73  case syntax::NodeRole::Message:
74    return OS << "Message";
75  case syntax::NodeRole::Declarator:
76    return OS << "Declarator";
77  case syntax::NodeRole::Declaration:
78    return OS << "Declaration";
79  case syntax::NodeRole::Size:
80    return OS << "Size";
81  case syntax::NodeRole::Parameters:
82    return OS << "Parameters";
83  case syntax::NodeRole::TrailingReturn:
84    return OS << "TrailingReturn";
85  case syntax::NodeRole::UnqualifiedId:
86    return OS << "UnqualifiedId";
87  case syntax::NodeRole::Qualifier:
88    return OS << "Qualifier";
89  case syntax::NodeRole::SubExpression:
90    return OS << "SubExpression";
91  case syntax::NodeRole::Object:
92    return OS << "Object";
93  case syntax::NodeRole::AccessToken:
94    return OS << "AccessToken";
95  case syntax::NodeRole::Member:
96    return OS << "Member";
97  case syntax::NodeRole::Callee:
98    return OS << "Callee";
99  case syntax::NodeRole::Arguments:
100    return OS << "Arguments";
101  case syntax::NodeRole::Declarators:
102    return OS << "Declarators";
103  }
104  llvm_unreachable("invalid role");
105}
106
107// We could have an interator in list to not pay memory costs of temporary
108// vector
109std::vector<syntax::NameSpecifier *>
110syntax::NestedNameSpecifier::getSpecifiers() {
111  auto SpecifiersAsNodes = getElementsAsNodes();
112  std::vector<syntax::NameSpecifier *> Children;
113  for (const auto &Element : SpecifiersAsNodes) {
114    Children.push_back(llvm::cast<syntax::NameSpecifier>(Element));
115  }
116  return Children;
117}
118
119std::vector<syntax::List::ElementAndDelimiter<syntax::NameSpecifier>>
120syntax::NestedNameSpecifier::getSpecifiersAndDoubleColons() {
121  auto SpecifiersAsNodesAndDoubleColons = getElementsAsNodesAndDelimiters();
122  std::vector<syntax::List::ElementAndDelimiter<syntax::NameSpecifier>>
123      Children;
124  for (const auto &SpecifierAndDoubleColon : SpecifiersAsNodesAndDoubleColons) {
125    Children.push_back(
126        {llvm::cast<syntax::NameSpecifier>(SpecifierAndDoubleColon.element),
127         SpecifierAndDoubleColon.delimiter});
128  }
129  return Children;
130}
131
132std::vector<syntax::Expression *> syntax::CallArguments::getArguments() {
133  auto ArgumentsAsNodes = getElementsAsNodes();
134  std::vector<syntax::Expression *> Children;
135  for (const auto &ArgumentAsNode : ArgumentsAsNodes) {
136    Children.push_back(llvm::cast<syntax::Expression>(ArgumentAsNode));
137  }
138  return Children;
139}
140
141std::vector<syntax::List::ElementAndDelimiter<syntax::Expression>>
142syntax::CallArguments::getArgumentsAndCommas() {
143  auto ArgumentsAsNodesAndCommas = getElementsAsNodesAndDelimiters();
144  std::vector<syntax::List::ElementAndDelimiter<syntax::Expression>> Children;
145  for (const auto &ArgumentAsNodeAndComma : ArgumentsAsNodesAndCommas) {
146    Children.push_back(
147        {llvm::cast<syntax::Expression>(ArgumentAsNodeAndComma.element),
148         ArgumentAsNodeAndComma.delimiter});
149  }
150  return Children;
151}
152
153std::vector<syntax::SimpleDeclaration *>
154syntax::ParameterDeclarationList::getParameterDeclarations() {
155  auto ParametersAsNodes = getElementsAsNodes();
156  std::vector<syntax::SimpleDeclaration *> Children;
157  for (const auto &ParameterAsNode : ParametersAsNodes) {
158    Children.push_back(llvm::cast<syntax::SimpleDeclaration>(ParameterAsNode));
159  }
160  return Children;
161}
162
163std::vector<syntax::List::ElementAndDelimiter<syntax::SimpleDeclaration>>
164syntax::ParameterDeclarationList::getParametersAndCommas() {
165  auto ParametersAsNodesAndCommas = getElementsAsNodesAndDelimiters();
166  std::vector<syntax::List::ElementAndDelimiter<syntax::SimpleDeclaration>>
167      Children;
168  for (const auto &ParameterAsNodeAndComma : ParametersAsNodesAndCommas) {
169    Children.push_back(
170        {llvm::cast<syntax::SimpleDeclaration>(ParameterAsNodeAndComma.element),
171         ParameterAsNodeAndComma.delimiter});
172  }
173  return Children;
174}
175
176std::vector<syntax::SimpleDeclarator *>
177syntax::DeclaratorList::getDeclarators() {
178  auto DeclaratorsAsNodes = getElementsAsNodes();
179  std::vector<syntax::SimpleDeclarator *> Children;
180  for (const auto &DeclaratorAsNode : DeclaratorsAsNodes) {
181    Children.push_back(llvm::cast<syntax::SimpleDeclarator>(DeclaratorAsNode));
182  }
183  return Children;
184}
185
186std::vector<syntax::List::ElementAndDelimiter<syntax::SimpleDeclarator>>
187syntax::DeclaratorList::getDeclaratorsAndCommas() {
188  auto DeclaratorsAsNodesAndCommas = getElementsAsNodesAndDelimiters();
189  std::vector<syntax::List::ElementAndDelimiter<syntax::SimpleDeclarator>>
190      Children;
191  for (const auto &DeclaratorAsNodeAndComma : DeclaratorsAsNodesAndCommas) {
192    Children.push_back(
193        {llvm::cast<syntax::SimpleDeclarator>(DeclaratorAsNodeAndComma.element),
194         DeclaratorAsNodeAndComma.delimiter});
195  }
196  return Children;
197}
198
199syntax::Expression *syntax::BinaryOperatorExpression::getLhs() {
200  return cast_or_null<syntax::Expression>(
201      findChild(syntax::NodeRole::LeftHandSide));
202}
203
204syntax::Leaf *syntax::UnaryOperatorExpression::getOperatorToken() {
205  return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::OperatorToken));
206}
207
208syntax::Expression *syntax::UnaryOperatorExpression::getOperand() {
209  return cast_or_null<syntax::Expression>(findChild(syntax::NodeRole::Operand));
210}
211
212syntax::Leaf *syntax::BinaryOperatorExpression::getOperatorToken() {
213  return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::OperatorToken));
214}
215
216syntax::Expression *syntax::BinaryOperatorExpression::getRhs() {
217  return cast_or_null<syntax::Expression>(
218      findChild(syntax::NodeRole::RightHandSide));
219}
220
221syntax::Leaf *syntax::SwitchStatement::getSwitchKeyword() {
222  return cast_or_null<syntax::Leaf>(
223      findChild(syntax::NodeRole::IntroducerKeyword));
224}
225
226syntax::Statement *syntax::SwitchStatement::getBody() {
227  return cast_or_null<syntax::Statement>(
228      findChild(syntax::NodeRole::BodyStatement));
229}
230
231syntax::Leaf *syntax::CaseStatement::getCaseKeyword() {
232  return cast_or_null<syntax::Leaf>(
233      findChild(syntax::NodeRole::IntroducerKeyword));
234}
235
236syntax::Expression *syntax::CaseStatement::getCaseValue() {
237  return cast_or_null<syntax::Expression>(
238      findChild(syntax::NodeRole::CaseValue));
239}
240
241syntax::Statement *syntax::CaseStatement::getBody() {
242  return cast_or_null<syntax::Statement>(
243      findChild(syntax::NodeRole::BodyStatement));
244}
245
246syntax::Leaf *syntax::DefaultStatement::getDefaultKeyword() {
247  return cast_or_null<syntax::Leaf>(
248      findChild(syntax::NodeRole::IntroducerKeyword));
249}
250
251syntax::Statement *syntax::DefaultStatement::getBody() {
252  return cast_or_null<syntax::Statement>(
253      findChild(syntax::NodeRole::BodyStatement));
254}
255
256syntax::Leaf *syntax::IfStatement::getIfKeyword() {
257  return cast_or_null<syntax::Leaf>(
258      findChild(syntax::NodeRole::IntroducerKeyword));
259}
260
261syntax::Statement *syntax::IfStatement::getThenStatement() {
262  return cast_or_null<syntax::Statement>(
263      findChild(syntax::NodeRole::ThenStatement));
264}
265
266syntax::Leaf *syntax::IfStatement::getElseKeyword() {
267  return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::ElseKeyword));
268}
269
270syntax::Statement *syntax::IfStatement::getElseStatement() {
271  return cast_or_null<syntax::Statement>(
272      findChild(syntax::NodeRole::ElseStatement));
273}
274
275syntax::Leaf *syntax::ForStatement::getForKeyword() {
276  return cast_or_null<syntax::Leaf>(
277      findChild(syntax::NodeRole::IntroducerKeyword));
278}
279
280syntax::Statement *syntax::ForStatement::getBody() {
281  return cast_or_null<syntax::Statement>(
282      findChild(syntax::NodeRole::BodyStatement));
283}
284
285syntax::Leaf *syntax::WhileStatement::getWhileKeyword() {
286  return cast_or_null<syntax::Leaf>(
287      findChild(syntax::NodeRole::IntroducerKeyword));
288}
289
290syntax::Statement *syntax::WhileStatement::getBody() {
291  return cast_or_null<syntax::Statement>(
292      findChild(syntax::NodeRole::BodyStatement));
293}
294
295syntax::Leaf *syntax::ContinueStatement::getContinueKeyword() {
296  return cast_or_null<syntax::Leaf>(
297      findChild(syntax::NodeRole::IntroducerKeyword));
298}
299
300syntax::Leaf *syntax::BreakStatement::getBreakKeyword() {
301  return cast_or_null<syntax::Leaf>(
302      findChild(syntax::NodeRole::IntroducerKeyword));
303}
304
305syntax::Leaf *syntax::ReturnStatement::getReturnKeyword() {
306  return cast_or_null<syntax::Leaf>(
307      findChild(syntax::NodeRole::IntroducerKeyword));
308}
309
310syntax::Expression *syntax::ReturnStatement::getReturnValue() {
311  return cast_or_null<syntax::Expression>(
312      findChild(syntax::NodeRole::ReturnValue));
313}
314
315syntax::Leaf *syntax::RangeBasedForStatement::getForKeyword() {
316  return cast_or_null<syntax::Leaf>(
317      findChild(syntax::NodeRole::IntroducerKeyword));
318}
319
320syntax::Statement *syntax::RangeBasedForStatement::getBody() {
321  return cast_or_null<syntax::Statement>(
322      findChild(syntax::NodeRole::BodyStatement));
323}
324
325syntax::Expression *syntax::ExpressionStatement::getExpression() {
326  return cast_or_null<syntax::Expression>(
327      findChild(syntax::NodeRole::Expression));
328}
329
330syntax::Leaf *syntax::CompoundStatement::getLbrace() {
331  return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::OpenParen));
332}
333
334std::vector<syntax::Statement *> syntax::CompoundStatement::getStatements() {
335  std::vector<syntax::Statement *> Children;
336  for (auto *C = getFirstChild(); C; C = C->getNextSibling()) {
337    assert(C->getRole() == syntax::NodeRole::Statement);
338    Children.push_back(cast<syntax::Statement>(C));
339  }
340  return Children;
341}
342
343syntax::Leaf *syntax::CompoundStatement::getRbrace() {
344  return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::CloseParen));
345}
346
347syntax::Expression *syntax::StaticAssertDeclaration::getCondition() {
348  return cast_or_null<syntax::Expression>(
349      findChild(syntax::NodeRole::Condition));
350}
351
352syntax::Expression *syntax::StaticAssertDeclaration::getMessage() {
353  return cast_or_null<syntax::Expression>(findChild(syntax::NodeRole::Message));
354}
355
356std::vector<syntax::SimpleDeclarator *>
357syntax::SimpleDeclaration::getDeclarators() {
358  std::vector<syntax::SimpleDeclarator *> Children;
359  for (auto *C = getFirstChild(); C; C = C->getNextSibling()) {
360    if (C->getRole() == syntax::NodeRole::Declarator)
361      Children.push_back(cast<syntax::SimpleDeclarator>(C));
362  }
363  return Children;
364}
365
366syntax::Leaf *syntax::TemplateDeclaration::getTemplateKeyword() {
367  return cast_or_null<syntax::Leaf>(
368      findChild(syntax::NodeRole::IntroducerKeyword));
369}
370
371syntax::Declaration *syntax::TemplateDeclaration::getDeclaration() {
372  return cast_or_null<syntax::Declaration>(
373      findChild(syntax::NodeRole::Declaration));
374}
375
376syntax::Leaf *syntax::ExplicitTemplateInstantiation::getTemplateKeyword() {
377  return cast_or_null<syntax::Leaf>(
378      findChild(syntax::NodeRole::IntroducerKeyword));
379}
380
381syntax::Leaf *syntax::ExplicitTemplateInstantiation::getExternKeyword() {
382  return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::ExternKeyword));
383}
384
385syntax::Declaration *syntax::ExplicitTemplateInstantiation::getDeclaration() {
386  return cast_or_null<syntax::Declaration>(
387      findChild(syntax::NodeRole::Declaration));
388}
389
390syntax::Leaf *syntax::ParenDeclarator::getLparen() {
391  return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::OpenParen));
392}
393
394syntax::Leaf *syntax::ParenDeclarator::getRparen() {
395  return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::CloseParen));
396}
397
398syntax::Leaf *syntax::ArraySubscript::getLbracket() {
399  return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::OpenParen));
400}
401
402syntax::Expression *syntax::ArraySubscript::getSize() {
403  return cast_or_null<syntax::Expression>(findChild(syntax::NodeRole::Size));
404}
405
406syntax::Leaf *syntax::ArraySubscript::getRbracket() {
407  return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::CloseParen));
408}
409
410syntax::Leaf *syntax::TrailingReturnType::getArrowToken() {
411  return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::ArrowToken));
412}
413
414syntax::SimpleDeclarator *syntax::TrailingReturnType::getDeclarator() {
415  return cast_or_null<syntax::SimpleDeclarator>(
416      findChild(syntax::NodeRole::Declarator));
417}
418
419syntax::Leaf *syntax::ParametersAndQualifiers::getLparen() {
420  return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::OpenParen));
421}
422
423syntax::ParameterDeclarationList *
424syntax::ParametersAndQualifiers::getParameters() {
425  return cast_or_null<syntax::ParameterDeclarationList>(
426      findChild(syntax::NodeRole::Parameters));
427}
428
429syntax::Leaf *syntax::ParametersAndQualifiers::getRparen() {
430  return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::CloseParen));
431}
432
433syntax::TrailingReturnType *
434syntax::ParametersAndQualifiers::getTrailingReturn() {
435  return cast_or_null<syntax::TrailingReturnType>(
436      findChild(syntax::NodeRole::TrailingReturn));
437}
438
439#define NODE(Kind, Parent)                                                     \
440  static_assert(sizeof(syntax::Kind) > 0, "Missing Node subclass definition");
441#include "clang/Tooling/Syntax/Nodes.inc"
442