eduucaldas created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
eduucaldas requested review of this revision.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D87925
Files:
clang/include/clang/Tooling/Syntax/BuildTree.h
clang/lib/Tooling/Syntax/Synthesis.cpp
Index: clang/lib/Tooling/Syntax/Synthesis.cpp
===================================================================
--- clang/lib/Tooling/Syntax/Synthesis.cpp
+++ clang/lib/Tooling/Syntax/Synthesis.cpp
@@ -8,6 +8,7 @@
#include "clang/Basic/TokenKinds.h"
#include "clang/Tooling/Syntax/BuildTree.h"
#include "clang/Tooling/Syntax/Tree.h"
+#include <algorithm>
using namespace clang;
@@ -184,12 +185,48 @@
}
llvm_unreachable("unknown node kind");
}
+
+bool canModifyAllDescendants(const syntax::Node *N) {
+ if (const auto *L = dyn_cast<syntax::Leaf>(N))
+ return L->canModify();
+
+ const auto *T = cast<syntax::Tree>(N);
+
+ if (!T->canModify())
+ return false;
+ for (const auto *Child = T->getFirstChild(); Child;
+ Child = Child->getNextSibling())
+ if (!Child->canModify())
+ return false;
+
+ return true;
+}
+
+bool areAllSynthesized(const syntax::Node *N) {
+ if (const auto *L = dyn_cast<syntax::Leaf>(N))
+ return !L->isOriginal();
+
+ const auto *T = cast<syntax::Tree>(N);
+
+ if (T->isOriginal())
+ return false;
+ for (const auto *Child = T->getFirstChild(); Child;
+ Child = Child->getNextSibling())
+ if (Child->isOriginal())
+ return false;
+
+ return true;
+}
} // namespace
syntax::Tree *clang::syntax::createTree(
syntax::Arena &A,
std::vector<std::pair<syntax::Node *, syntax::NodeRole>> Children,
syntax::NodeKind K) {
+ if (std::all_of(Children.begin(), Children.end(),
+ [](auto p) { return areAllSynthesized(p.first); }))
+ return nullptr;
+
auto *T = allocateTree(A, K);
FactoryImpl::setCanModify(T);
for (auto ChildIt = Children.rbegin(); ChildIt != Children.rend();
Index: clang/include/clang/Tooling/Syntax/BuildTree.h
===================================================================
--- clang/include/clang/Tooling/Syntax/BuildTree.h
+++ clang/include/clang/Tooling/Syntax/BuildTree.h
@@ -37,6 +37,9 @@
// Synthesis of Trees
/// Creates the concrete syntax node according to the specified `NodeKind` `K`.
/// Returns it as a pointer to the base class `Tree`.
+///
+/// EXPECT: Nodes in `Children` are all synthesized, i.e. not backed by source
+/// code.
syntax::Tree *
createTree(syntax::Arena &A,
std::vector<std::pair<syntax::Node *, syntax::NodeRole>> Children,
Index: clang/lib/Tooling/Syntax/Synthesis.cpp
===================================================================
--- clang/lib/Tooling/Syntax/Synthesis.cpp
+++ clang/lib/Tooling/Syntax/Synthesis.cpp
@@ -8,6 +8,7 @@
#include "clang/Basic/TokenKinds.h"
#include "clang/Tooling/Syntax/BuildTree.h"
#include "clang/Tooling/Syntax/Tree.h"
+#include <algorithm>
using namespace clang;
@@ -184,12 +185,48 @@
}
llvm_unreachable("unknown node kind");
}
+
+bool canModifyAllDescendants(const syntax::Node *N) {
+ if (const auto *L = dyn_cast<syntax::Leaf>(N))
+ return L->canModify();
+
+ const auto *T = cast<syntax::Tree>(N);
+
+ if (!T->canModify())
+ return false;
+ for (const auto *Child = T->getFirstChild(); Child;
+ Child = Child->getNextSibling())
+ if (!Child->canModify())
+ return false;
+
+ return true;
+}
+
+bool areAllSynthesized(const syntax::Node *N) {
+ if (const auto *L = dyn_cast<syntax::Leaf>(N))
+ return !L->isOriginal();
+
+ const auto *T = cast<syntax::Tree>(N);
+
+ if (T->isOriginal())
+ return false;
+ for (const auto *Child = T->getFirstChild(); Child;
+ Child = Child->getNextSibling())
+ if (Child->isOriginal())
+ return false;
+
+ return true;
+}
} // namespace
syntax::Tree *clang::syntax::createTree(
syntax::Arena &A,
std::vector<std::pair<syntax::Node *, syntax::NodeRole>> Children,
syntax::NodeKind K) {
+ if (std::all_of(Children.begin(), Children.end(),
+ [](auto p) { return areAllSynthesized(p.first); }))
+ return nullptr;
+
auto *T = allocateTree(A, K);
FactoryImpl::setCanModify(T);
for (auto ChildIt = Children.rbegin(); ChildIt != Children.rend();
Index: clang/include/clang/Tooling/Syntax/BuildTree.h
===================================================================
--- clang/include/clang/Tooling/Syntax/BuildTree.h
+++ clang/include/clang/Tooling/Syntax/BuildTree.h
@@ -37,6 +37,9 @@
// Synthesis of Trees
/// Creates the concrete syntax node according to the specified `NodeKind` `K`.
/// Returns it as a pointer to the base class `Tree`.
+///
+/// EXPECT: Nodes in `Children` are all synthesized, i.e. not backed by source
+/// code.
syntax::Tree *
createTree(syntax::Arena &A,
std::vector<std::pair<syntax::Node *, syntax::NodeRole>> Children,
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits