Coverage Report

Created: 2021-01-19 06:58

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Tooling/Syntax/Mutations.cpp
Line
Count
Source (jump to first uncovered line)
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/Basic/SourceLocation.h"
11
#include "clang/Lex/Token.h"
12
#include "clang/Tooling/Core/Replacement.h"
13
#include "clang/Tooling/Syntax/BuildTree.h"
14
#include "clang/Tooling/Syntax/Nodes.h"
15
#include "clang/Tooling/Syntax/Tokens.h"
16
#include "clang/Tooling/Syntax/Tree.h"
17
#include "llvm/ADT/ArrayRef.h"
18
#include "llvm/ADT/Optional.h"
19
#include "llvm/ADT/STLExtras.h"
20
#include "llvm/Support/Casting.h"
21
#include <cassert>
22
#include <string>
23
24
using namespace clang;
25
26
// This class has access to the internals of tree nodes. Its sole purpose is to
27
// define helpers that allow implementing the high-level mutation operations.
28
class syntax::MutationsImpl {
29
public:
30
  /// Add a new node with a specified role.
31
0
  static void addAfter(syntax::Node *Anchor, syntax::Node *New, NodeRole Role) {
32
0
    assert(Anchor != nullptr);
33
0
    assert(Anchor->Parent != nullptr);
34
0
    assert(New->Parent == nullptr);
35
0
    assert(New->NextSibling == nullptr);
36
0
    assert(New->PreviousSibling == nullptr);
37
0
    assert(New->isDetached());
38
0
    assert(Role != NodeRole::Detached);
39
0
40
0
    New->setRole(Role);
41
0
    auto *P = Anchor->getParent();
42
0
    P->replaceChildRangeLowLevel(Anchor->getNextSibling(),
43
0
                                 Anchor->getNextSibling(), New);
44
0
45
0
    P->assertInvariants();
46
0
  }
47
48
  /// Replace the node, keeping the role.
49
14
  static void replace(syntax::Node *Old, syntax::Node *New) {
50
14
    assert(Old != nullptr);
51
14
    assert(Old->Parent != nullptr);
52
14
    assert(Old->canModify());
53
14
    assert(New->Parent == nullptr);
54
14
    assert(New->NextSibling == nullptr);
55
14
    assert(New->PreviousSibling == nullptr);
56
14
    assert(New->isDetached());
57
58
14
    New->Role = Old->Role;
59
14
    auto *P = Old->getParent();
60
14
    P->replaceChildRangeLowLevel(Old, Old->getNextSibling(), New);
61
62
14
    P->assertInvariants();
63
14
  }
64
65
  /// Completely remove the node from its parent.
66
28
  static void remove(syntax::Node *N) {
67
28
    assert(N != nullptr);
68
28
    assert(N->Parent != nullptr);
69
28
    assert(N->canModify());
70
71
28
    auto *P = N->getParent();
72
28
    P->replaceChildRangeLowLevel(N, N->getNextSibling(),
73
28
                                 /*New=*/nullptr);
74
75
28
    P->assertInvariants();
76
28
    N->assertInvariants();
77
28
  }
78
};
79
80
42
void syntax::removeStatement(syntax::Arena &A, syntax::Statement *S) {
81
42
  assert(S);
82
42
  assert(S->canModify());
83
84
42
  if (isa<CompoundStatement>(S->getParent())) {
85
    // A child of CompoundStatement can just be safely removed.
86
28
    MutationsImpl::remove(S);
87
28
    return;
88
28
  }
89
  // For the rest, we have to replace with an empty statement.
90
14
  if (isa<EmptyStatement>(S))
91
0
    return; // already an empty statement, nothing to do.
92
93
14
  MutationsImpl::replace(S, createEmptyStatement(A));
94
14
}