summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/clang/lib/Tooling/Syntax/Mutations.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2020-08-03 14:31:31 +0000
committerpatrick <patrick@openbsd.org>2020-08-03 14:31:31 +0000
commite5dd70708596ae51455a0ffa086a00c5b29f8583 (patch)
tree5d676f27b570bacf71e786c3b5cff3e6f6679b59 /gnu/llvm/clang/lib/Tooling/Syntax/Mutations.cpp
parentImport LLVM 10.0.0 release including clang, lld and lldb. (diff)
downloadwireguard-openbsd-e5dd70708596ae51455a0ffa086a00c5b29f8583.tar.xz
wireguard-openbsd-e5dd70708596ae51455a0ffa086a00c5b29f8583.zip
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom tested by plenty
Diffstat (limited to 'gnu/llvm/clang/lib/Tooling/Syntax/Mutations.cpp')
-rw-r--r--gnu/llvm/clang/lib/Tooling/Syntax/Mutations.cpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/gnu/llvm/clang/lib/Tooling/Syntax/Mutations.cpp b/gnu/llvm/clang/lib/Tooling/Syntax/Mutations.cpp
new file mode 100644
index 00000000000..72458528202
--- /dev/null
+++ b/gnu/llvm/clang/lib/Tooling/Syntax/Mutations.cpp
@@ -0,0 +1,98 @@
+//===- Mutations.cpp ------------------------------------------*- C++ -*-=====//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Tooling/Syntax/Mutations.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Token.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "clang/Tooling/Syntax/BuildTree.h"
+#include "clang/Tooling/Syntax/Nodes.h"
+#include "clang/Tooling/Syntax/Tokens.h"
+#include "clang/Tooling/Syntax/Tree.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
+#include <string>
+
+using namespace clang;
+
+// This class has access to the internals of tree nodes. Its sole purpose is to
+// define helpers that allow implementing the high-level mutation operations.
+class syntax::MutationsImpl {
+public:
+ /// Add a new node with a specified role.
+ static void addAfter(syntax::Node *Anchor, syntax::Node *New, NodeRole Role) {
+ assert(Anchor != nullptr);
+ assert(New->Parent == nullptr);
+ assert(New->NextSibling == nullptr);
+ assert(!New->isDetached());
+ assert(Role != NodeRole::Detached);
+
+ New->Role = static_cast<unsigned>(Role);
+ auto *P = Anchor->parent();
+ P->replaceChildRangeLowLevel(Anchor, Anchor, New);
+
+ P->assertInvariants();
+ }
+
+ /// Replace the node, keeping the role.
+ static void replace(syntax::Node *Old, syntax::Node *New) {
+ assert(Old != nullptr);
+ assert(Old->Parent != nullptr);
+ assert(Old->canModify());
+ assert(New->Parent == nullptr);
+ assert(New->NextSibling == nullptr);
+ assert(New->isDetached());
+
+ New->Role = Old->Role;
+ auto *P = Old->parent();
+ P->replaceChildRangeLowLevel(findPrevious(Old), Old->nextSibling(), New);
+
+ P->assertInvariants();
+ }
+
+ /// Completely remove the node from its parent.
+ static void remove(syntax::Node *N) {
+ auto *P = N->parent();
+ P->replaceChildRangeLowLevel(findPrevious(N), N->nextSibling(),
+ /*New=*/nullptr);
+
+ P->assertInvariants();
+ N->assertInvariants();
+ }
+
+private:
+ static syntax::Node *findPrevious(syntax::Node *N) {
+ if (N->parent()->firstChild() == N)
+ return nullptr;
+ for (syntax::Node *C = N->parent()->firstChild(); C != nullptr;
+ C = C->nextSibling()) {
+ if (C->nextSibling() == N)
+ return C;
+ }
+ llvm_unreachable("could not find a child node");
+ }
+};
+
+void syntax::removeStatement(syntax::Arena &A, syntax::Statement *S) {
+ assert(S);
+ assert(S->canModify());
+
+ if (isa<CompoundStatement>(S->parent())) {
+ // A child of CompoundStatement can just be safely removed.
+ MutationsImpl::remove(S);
+ return;
+ }
+ // For the rest, we have to replace with an empty statement.
+ if (isa<EmptyStatement>(S))
+ return; // already an empty statement, nothing to do.
+
+ MutationsImpl::replace(S, createEmptyStatement(A));
+}