[clang] 1e19165 - [SyntaxTree][Synthesis] Fix allocation in `createTree` for more general use

Eduardo Caldas via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 17 09:19:07 PDT 2020


Author: Eduardo Caldas
Date: 2020-09-17T16:09:35Z
New Revision: 1e19165bd89db6671a80e0b25b32d5c7ae79455c

URL: https://github.com/llvm/llvm-project/commit/1e19165bd89db6671a80e0b25b32d5c7ae79455c
DIFF: https://github.com/llvm/llvm-project/commit/1e19165bd89db6671a80e0b25b32d5c7ae79455c.diff

LOG: [SyntaxTree][Synthesis] Fix allocation in `createTree` for more general use

Prior to this change `createTree` could not create arbitrary syntax
trees. Now it dispatches to the constructor of the concrete syntax tree
according to the `NodeKind` passed as argument. This allows reuse inside
the Synthesis API.  # Please enter the commit message for your changes.
Lines starting

Differential Revision: https://reviews.llvm.org/D87820

Added: 
    

Modified: 
    clang/include/clang/Tooling/Syntax/BuildTree.h
    clang/lib/Tooling/Syntax/Synthesis.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Tooling/Syntax/BuildTree.h b/clang/include/clang/Tooling/Syntax/BuildTree.h
index b9405167bf99..452edf580ae1 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<std::pair<syntax::Node *, syntax::NodeRole>> 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 6de3d5b5752d..2fe95a40cb32 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<std::pair<syntax::Node *, syntax::NodeRole>> 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<EmptyStatement>(
+      createTree(A, {{createLeaf(A, tok::semi), NodeRole::Unknown}},
+                 NodeKind::EmptyStatement));
 }


        


More information about the cfe-commits mailing list