brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.8 KiB · 8557b62 Raw
87 lines · cpp
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-exception6//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 to18// 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(Anchor->getNextSibling(),34                                 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(Old, 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(N, 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>(S->getParent())) {77    // A child of CompoundStatement can just be safely removed.78    MutationsImpl::remove(S);79    return;80  }81  // For the rest, we have to replace with an empty statement.82  if (isa<EmptyStatement>(S))83    return; // already an empty statement, nothing to do.84 85  MutationsImpl::replace(S, createEmptyStatement(A, TBTM));86}87