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