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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits