eduucaldas updated this revision to Diff 292539.
eduucaldas added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87749/new/

https://reviews.llvm.org/D87749

Files:
  clang/include/clang/Tooling/Syntax/BuildTree.h
  clang/lib/Tooling/Syntax/Synthesis.cpp
  clang/unittests/Tooling/Syntax/SynthesisTest.cpp

Index: clang/unittests/Tooling/Syntax/SynthesisTest.cpp
===================================================================
--- clang/unittests/Tooling/Syntax/SynthesisTest.cpp
+++ clang/unittests/Tooling/Syntax/SynthesisTest.cpp
@@ -137,6 +137,50 @@
   )txt"));
 }
 
+TEST_P(SynthesisTest, Copy_Synthesized) {
+  buildTree("", GetParam());
+
+  auto *LeafContinue = createLeaf(*Arena, tok::kw_continue);
+  auto *LeafSemiColon = createLeaf(*Arena, tok::semi);
+  auto *StatementContinue = createTree(*Arena,
+                                       {{LeafContinue, NodeRole::LiteralToken},
+                                        {LeafSemiColon, NodeRole::Unknown}},
+                                       NodeKind::ContinueStatement);
+
+  auto *Copy = deepCopy(*Arena, StatementContinue);
+  EXPECT_TRUE(
+      treeDumpEqual(Copy, StatementContinue->dump(Arena->getSourceManager())));
+  // FIXME: Test that copy is independent of original, once the Mutations API is
+  // more developed.
+}
+
+TEST_P(SynthesisTest, Copy_Original) {
+  auto *OriginalTree = buildTree("int a;", GetParam());
+
+  auto *Copy = deepCopy(*Arena, OriginalTree);
+  EXPECT_TRUE(treeDumpEqual(Copy, R"txt(
+TranslationUnit Detached synthesized
+`-SimpleDeclaration synthesized
+  |-'int' synthesized
+  |-SimpleDeclarator Declarator synthesized
+  | `-'a' synthesized
+  `-';' synthesized
+  )txt"));
+}
+
+TEST_P(SynthesisTest, Copy_Child) {
+  auto *OriginalTree = buildTree("int a;", GetParam());
+
+  auto *Copy = deepCopy(*Arena, OriginalTree->getFirstChild());
+  EXPECT_TRUE(treeDumpEqual(Copy, R"txt(
+SimpleDeclaration Detached synthesized
+|-'int' synthesized
+|-SimpleDeclarator Declarator synthesized
+| `-'a' synthesized
+`-';' synthesized
+  )txt"));
+}
+
 TEST_P(SynthesisTest, Statement_EmptyStatement) {
   buildTree("", GetParam());
 
Index: clang/lib/Tooling/Syntax/Synthesis.cpp
===================================================================
--- clang/lib/Tooling/Syntax/Synthesis.cpp
+++ clang/lib/Tooling/Syntax/Synthesis.cpp
@@ -199,6 +199,27 @@
   return T;
 }
 
+static syntax::Leaf *copyLeaf(syntax::Arena &A, const syntax::Leaf *L) {
+  auto *Leaf = new (A.getAllocator()) syntax::Leaf(L->getToken());
+  if (L->canModify())
+    syntax::FactoryImpl::setCanModify(Leaf);
+
+  return Leaf;
+}
+
+syntax::Node *clang::syntax::deepCopy(syntax::Arena &A, const Node *N) {
+  if (const auto *L = dyn_cast<Leaf>(N)) {
+    return copyLeaf(A, L);
+  }
+
+  const auto *T = cast<Tree>(N);
+  auto Children = std::vector<std::pair<Node *, NodeRole>>();
+  for (const auto *C = T->getFirstChild(); C; C = C->getNextSibling()) {
+    Children.push_back({deepCopy(A, C), C->getRole()});
+  }
+  return createTree(A, Children, N->getKind());
+}
+
 syntax::EmptyStatement *clang::syntax::createEmptyStatement(syntax::Arena &A) {
   return cast<EmptyStatement>(
       createTree(A, {{createLeaf(A, tok::semi), NodeRole::Unknown}},
Index: clang/include/clang/Tooling/Syntax/BuildTree.h
===================================================================
--- clang/include/clang/Tooling/Syntax/BuildTree.h
+++ clang/include/clang/Tooling/Syntax/BuildTree.h
@@ -42,6 +42,13 @@
            std::vector<std::pair<syntax::Node *, syntax::NodeRole>> Children,
            syntax::NodeKind K);
 
+/// Deep copies `N`.
+///
+/// The copy is detached, i.e. `Parent == NextSibling == nullptr` and
+/// `Role == Detached`.
+/// The copy is synthesized, i.e. `Original == false`.
+syntax::Node *deepCopy(syntax::Arena &A, const syntax::Node *N);
+
 // Synthesis of Syntax Nodes
 syntax::EmptyStatement *createEmptyStatement(syntax::Arena &A);
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to