1//===- Mutations.cpp ------------------------------------------*- C++ -*-=====//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8#include "clang/Tooling/Syntax/Mutations.h"
9#include "clang/Basic/LLVM.h"
10#include "clang/Tooling/Syntax/BuildTree.h"
11#include "clang/Tooling/Syntax/Nodes.h"
12#include "clang/Tooling/Syntax/Tree.h"
13#include <cassert>
14
15using namespace clang;
16
17// This class has access to the internals of tree nodes. Its sole purpose is to
18// define helpers that allow implementing the high-level mutation operations.
19class syntax::MutationsImpl {
20public:
21 /// Add a new node with a specified role.
22 static void addAfter(syntax::Node *Anchor, syntax::Node *New, NodeRole Role) {
23 assert(Anchor != nullptr);
24 assert(Anchor->Parent != nullptr);
25 assert(New->Parent == nullptr);
26 assert(New->NextSibling == nullptr);
27 assert(New->PreviousSibling == nullptr);
28 assert(New->isDetached());
29 assert(Role != NodeRole::Detached);
30
31 New->setRole(Role);
32 auto *P = Anchor->getParent();
33 P->replaceChildRangeLowLevel(Begin: Anchor->getNextSibling(),
34 End: Anchor->getNextSibling(), New);
35
36 P->assertInvariants();
37 }
38
39 /// Replace the node, keeping the role.
40 static void replace(syntax::Node *Old, syntax::Node *New) {
41 assert(Old != nullptr);
42 assert(Old->Parent != nullptr);
43 assert(Old->canModify());
44 assert(New->Parent == nullptr);
45 assert(New->NextSibling == nullptr);
46 assert(New->PreviousSibling == nullptr);
47 assert(New->isDetached());
48
49 New->Role = Old->Role;
50 auto *P = Old->getParent();
51 P->replaceChildRangeLowLevel(Begin: Old, End: Old->getNextSibling(), New);
52
53 P->assertInvariants();
54 }
55
56 /// Completely remove the node from its parent.
57 static void remove(syntax::Node *N) {
58 assert(N != nullptr);
59 assert(N->Parent != nullptr);
60 assert(N->canModify());
61
62 auto *P = N->getParent();
63 P->replaceChildRangeLowLevel(Begin: N, End: N->getNextSibling(),
64 /*New=*/nullptr);
65
66 P->assertInvariants();
67 N->assertInvariants();
68 }
69};
70
71void syntax::removeStatement(syntax::Arena &A, TokenBufferTokenManager &TBTM,
72 syntax::Statement *S) {
73 assert(S);
74 assert(S->canModify());
75
76 if (isa<CompoundStatement>(Val: S->getParent())) {
77 // A child of CompoundStatement can just be safely removed.
78 MutationsImpl::remove(N: S);
79 return;
80 }
81 // For the rest, we have to replace with an empty statement.
82 if (isa<EmptyStatement>(Val: S))
83 return; // already an empty statement, nothing to do.
84
85 MutationsImpl::replace(Old: S, New: createEmptyStatement(A, TBTM));
86}
87

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of clang/lib/Tooling/Syntax/Mutations.cpp