Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/AST/Interp/InterpBlock.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- Block.cpp - Allocated blocks for the interpreter -------*- 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
//
9
// Defines the classes describing allocated blocks.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "InterpBlock.h"
14
#include "Pointer.h"
15
16
using namespace clang;
17
using namespace clang::interp;
18
19
0
void Block::addPointer(Pointer *P) {
20
0
  assert(P);
21
0
  if (IsStatic) {
22
0
    assert(!Pointers);
23
0
    return;
24
0
  }
25
26
0
#ifndef NDEBUG
27
0
  assert(!hasPointer(P));
28
0
#endif
29
0
  if (Pointers)
30
0
    Pointers->Prev = P;
31
0
  P->Next = Pointers;
32
0
  P->Prev = nullptr;
33
0
  Pointers = P;
34
0
}
35
36
0
void Block::removePointer(Pointer *P) {
37
0
  assert(P);
38
0
  if (IsStatic) {
39
0
    assert(!Pointers);
40
0
    return;
41
0
  }
42
43
0
#ifndef NDEBUG
44
0
  assert(hasPointer(P));
45
0
#endif
46
47
0
  if (Pointers == P)
48
0
    Pointers = P->Next;
49
50
0
  if (P->Prev)
51
0
    P->Prev->Next = P->Next;
52
0
  if (P->Next)
53
0
    P->Next->Prev = P->Prev;
54
0
}
55
56
0
void Block::cleanup() {
57
0
  if (Pointers == nullptr && IsDead)
58
0
    (reinterpret_cast<DeadBlock *>(this + 1) - 1)->free();
59
0
}
60
61
0
void Block::replacePointer(Pointer *Old, Pointer *New) {
62
0
  assert(Old);
63
0
  assert(New);
64
0
  if (IsStatic) {
65
0
    assert(!Pointers);
66
0
    return;
67
0
  }
68
69
0
#ifndef NDEBUG
70
0
  assert(hasPointer(Old));
71
0
#endif
72
73
0
  removePointer(Old);
74
0
  addPointer(New);
75
76
0
  Old->Pointee = nullptr;
77
78
0
#ifndef NDEBUG
79
0
  assert(!hasPointer(Old));
80
0
  assert(hasPointer(New));
81
0
#endif
82
0
}
83
84
#ifndef NDEBUG
85
0
bool Block::hasPointer(const Pointer *P) const {
86
0
  for (const Pointer *C = Pointers; C; C = C->Next) {
87
0
    if (C == P)
88
0
      return true;
89
0
  }
90
0
  return false;
91
0
}
92
#endif
93
94
DeadBlock::DeadBlock(DeadBlock *&Root, Block *Blk)
95
0
    : Root(Root), B(Blk->Desc, Blk->IsStatic, Blk->IsExtern, /*isDead=*/true) {
96
  // Add the block to the chain of dead blocks.
97
0
  if (Root)
98
0
    Root->Prev = this;
99
100
0
  Next = Root;
101
0
  Prev = nullptr;
102
0
  Root = this;
103
104
  // Transfer pointers.
105
0
  B.Pointers = Blk->Pointers;
106
0
  for (Pointer *P = Blk->Pointers; P; P = P->Next)
107
0
    P->Pointee = &B;
108
0
}
109
110
0
void DeadBlock::free() {
111
0
  if (Prev)
112
0
    Prev->Next = Next;
113
0
  if (Next)
114
0
    Next->Prev = Prev;
115
0
  if (Root == this)
116
0
    Root = Next;
117
0
  std::free(this);
118
0
}