diff --git a/clang/include/clang/Tooling/Syntax/BuildTree.h b/clang/include/clang/Tooling/Syntax/BuildTree.h index b9405167bf99ba..452edf580ae179 100644 --- a/clang/include/clang/Tooling/Syntax/BuildTree.h +++ b/clang/include/clang/Tooling/Syntax/BuildTree.h @@ -35,13 +35,15 @@ syntax::Leaf *createLeaf(syntax::Arena &A, tok::TokenKind K, syntax::Leaf *createLeaf(syntax::Arena &A, tok::TokenKind K); // Synthesis of Trees +/// Creates the concrete syntax node according to the specified `NodeKind` `K`. +/// Returns it as a pointer to the base class `Tree`. syntax::Tree * -createTree(Arena &A, +createTree(syntax::Arena &A, std::vector> Children, syntax::NodeKind K); // Synthesis of Syntax Nodes -clang::syntax::EmptyStatement *createEmptyStatement(clang::syntax::Arena &A); +syntax::EmptyStatement *createEmptyStatement(syntax::Arena &A); } // namespace syntax } // namespace clang diff --git a/clang/lib/Tooling/Syntax/Synthesis.cpp b/clang/lib/Tooling/Syntax/Synthesis.cpp index 6de3d5b5752da7..2fe95a40cb3257 100644 --- a/clang/lib/Tooling/Syntax/Synthesis.cpp +++ b/clang/lib/Tooling/Syntax/Synthesis.cpp @@ -52,11 +52,144 @@ syntax::Leaf *clang::syntax::createLeaf(syntax::Arena &A, tok::TokenKind K) { return createLeaf(A, K, Spelling); } +namespace { +// Allocates the concrete syntax `Tree` according to its `NodeKind`. +syntax::Tree *allocateTree(syntax::Arena &A, syntax::NodeKind Kind) { + switch (Kind) { + case syntax::NodeKind::Leaf: + assert(false); + case syntax::NodeKind::TranslationUnit: + return new (A.getAllocator()) syntax::TranslationUnit; + case syntax::NodeKind::UnknownExpression: + return new (A.getAllocator()) syntax::UnknownExpression; + case syntax::NodeKind::ParenExpression: + return new (A.getAllocator()) syntax::ParenExpression; + case syntax::NodeKind::ThisExpression: + return new (A.getAllocator()) syntax::ThisExpression; + case syntax::NodeKind::IntegerLiteralExpression: + return new (A.getAllocator()) syntax::IntegerLiteralExpression; + case syntax::NodeKind::CharacterLiteralExpression: + return new (A.getAllocator()) syntax::CharacterLiteralExpression; + case syntax::NodeKind::FloatingLiteralExpression: + return new (A.getAllocator()) syntax::FloatingLiteralExpression; + case syntax::NodeKind::StringLiteralExpression: + return new (A.getAllocator()) syntax::StringLiteralExpression; + case syntax::NodeKind::BoolLiteralExpression: + return new (A.getAllocator()) syntax::BoolLiteralExpression; + case syntax::NodeKind::CxxNullPtrExpression: + return new (A.getAllocator()) syntax::CxxNullPtrExpression; + case syntax::NodeKind::IntegerUserDefinedLiteralExpression: + return new (A.getAllocator()) syntax::IntegerUserDefinedLiteralExpression; + case syntax::NodeKind::FloatUserDefinedLiteralExpression: + return new (A.getAllocator()) syntax::FloatUserDefinedLiteralExpression; + case syntax::NodeKind::CharUserDefinedLiteralExpression: + return new (A.getAllocator()) syntax::CharUserDefinedLiteralExpression; + case syntax::NodeKind::StringUserDefinedLiteralExpression: + return new (A.getAllocator()) syntax::StringUserDefinedLiteralExpression; + case syntax::NodeKind::PrefixUnaryOperatorExpression: + return new (A.getAllocator()) syntax::PrefixUnaryOperatorExpression; + case syntax::NodeKind::PostfixUnaryOperatorExpression: + return new (A.getAllocator()) syntax::PostfixUnaryOperatorExpression; + case syntax::NodeKind::BinaryOperatorExpression: + return new (A.getAllocator()) syntax::BinaryOperatorExpression; + case syntax::NodeKind::UnqualifiedId: + return new (A.getAllocator()) syntax::UnqualifiedId; + case syntax::NodeKind::IdExpression: + return new (A.getAllocator()) syntax::IdExpression; + case syntax::NodeKind::CallExpression: + return new (A.getAllocator()) syntax::CallExpression; + case syntax::NodeKind::UnknownStatement: + return new (A.getAllocator()) syntax::UnknownStatement; + case syntax::NodeKind::DeclarationStatement: + return new (A.getAllocator()) syntax::DeclarationStatement; + case syntax::NodeKind::EmptyStatement: + return new (A.getAllocator()) syntax::EmptyStatement; + case syntax::NodeKind::SwitchStatement: + return new (A.getAllocator()) syntax::SwitchStatement; + case syntax::NodeKind::CaseStatement: + return new (A.getAllocator()) syntax::CaseStatement; + case syntax::NodeKind::DefaultStatement: + return new (A.getAllocator()) syntax::DefaultStatement; + case syntax::NodeKind::IfStatement: + return new (A.getAllocator()) syntax::IfStatement; + case syntax::NodeKind::ForStatement: + return new (A.getAllocator()) syntax::ForStatement; + case syntax::NodeKind::WhileStatement: + return new (A.getAllocator()) syntax::WhileStatement; + case syntax::NodeKind::ContinueStatement: + return new (A.getAllocator()) syntax::ContinueStatement; + case syntax::NodeKind::BreakStatement: + return new (A.getAllocator()) syntax::BreakStatement; + case syntax::NodeKind::ReturnStatement: + return new (A.getAllocator()) syntax::ReturnStatement; + case syntax::NodeKind::RangeBasedForStatement: + return new (A.getAllocator()) syntax::RangeBasedForStatement; + case syntax::NodeKind::ExpressionStatement: + return new (A.getAllocator()) syntax::ExpressionStatement; + case syntax::NodeKind::CompoundStatement: + return new (A.getAllocator()) syntax::CompoundStatement; + case syntax::NodeKind::UnknownDeclaration: + return new (A.getAllocator()) syntax::UnknownDeclaration; + case syntax::NodeKind::EmptyDeclaration: + return new (A.getAllocator()) syntax::EmptyDeclaration; + case syntax::NodeKind::StaticAssertDeclaration: + return new (A.getAllocator()) syntax::StaticAssertDeclaration; + case syntax::NodeKind::LinkageSpecificationDeclaration: + return new (A.getAllocator()) syntax::LinkageSpecificationDeclaration; + case syntax::NodeKind::SimpleDeclaration: + return new (A.getAllocator()) syntax::SimpleDeclaration; + case syntax::NodeKind::TemplateDeclaration: + return new (A.getAllocator()) syntax::TemplateDeclaration; + case syntax::NodeKind::ExplicitTemplateInstantiation: + return new (A.getAllocator()) syntax::ExplicitTemplateInstantiation; + case syntax::NodeKind::NamespaceDefinition: + return new (A.getAllocator()) syntax::NamespaceDefinition; + case syntax::NodeKind::NamespaceAliasDefinition: + return new (A.getAllocator()) syntax::NamespaceAliasDefinition; + case syntax::NodeKind::UsingNamespaceDirective: + return new (A.getAllocator()) syntax::UsingNamespaceDirective; + case syntax::NodeKind::UsingDeclaration: + return new (A.getAllocator()) syntax::UsingDeclaration; + case syntax::NodeKind::TypeAliasDeclaration: + return new (A.getAllocator()) syntax::TypeAliasDeclaration; + case syntax::NodeKind::SimpleDeclarator: + return new (A.getAllocator()) syntax::SimpleDeclarator; + case syntax::NodeKind::ParenDeclarator: + return new (A.getAllocator()) syntax::ParenDeclarator; + case syntax::NodeKind::ArraySubscript: + return new (A.getAllocator()) syntax::ArraySubscript; + case syntax::NodeKind::TrailingReturnType: + return new (A.getAllocator()) syntax::TrailingReturnType; + case syntax::NodeKind::ParametersAndQualifiers: + return new (A.getAllocator()) syntax::ParametersAndQualifiers; + case syntax::NodeKind::MemberPointer: + return new (A.getAllocator()) syntax::MemberPointer; + case syntax::NodeKind::GlobalNameSpecifier: + return new (A.getAllocator()) syntax::GlobalNameSpecifier; + case syntax::NodeKind::DecltypeNameSpecifier: + return new (A.getAllocator()) syntax::DecltypeNameSpecifier; + case syntax::NodeKind::IdentifierNameSpecifier: + return new (A.getAllocator()) syntax::IdentifierNameSpecifier; + case syntax::NodeKind::SimpleTemplateNameSpecifier: + return new (A.getAllocator()) syntax::SimpleTemplateNameSpecifier; + case syntax::NodeKind::NestedNameSpecifier: + return new (A.getAllocator()) syntax::NestedNameSpecifier; + case syntax::NodeKind::MemberExpression: + return new (A.getAllocator()) syntax::MemberExpression; + case syntax::NodeKind::CallArguments: + return new (A.getAllocator()) syntax::CallArguments; + case syntax::NodeKind::ParameterDeclarationList: + return new (A.getAllocator()) syntax::ParameterDeclarationList; + } + llvm_unreachable("unknown node kind"); +} +} // namespace + syntax::Tree *clang::syntax::createTree( syntax::Arena &A, std::vector> Children, syntax::NodeKind K) { - auto *T = new (A.getAllocator()) syntax::Tree(K); + auto *T = allocateTree(A, K); FactoryImpl::setCanModify(T); for (auto ChildIt = Children.rbegin(); ChildIt != Children.rend(); std::advance(ChildIt, 1)) @@ -67,10 +200,7 @@ syntax::Tree *clang::syntax::createTree( } syntax::EmptyStatement *clang::syntax::createEmptyStatement(syntax::Arena &A) { - auto *S = new (A.getAllocator()) syntax::EmptyStatement; - FactoryImpl::setCanModify(S); - FactoryImpl::prependChildLowLevel(S, createLeaf(A, tok::semi), - NodeRole::Unknown); - S->assertInvariants(); - return S; + return cast( + createTree(A, {{createLeaf(A, tok::semi), NodeRole::Unknown}}, + NodeKind::EmptyStatement)); }