xref: /openbsd-src/gnu/llvm/clang/lib/AST/Interp/InterpBlock.cpp (revision ec727ea710c91afd8ce4f788c5aaa8482b7b69b2)
1*ec727ea7Spatrick //===--- Block.cpp - Allocated blocks for the interpreter -------*- C++ -*-===//
2*ec727ea7Spatrick //
3*ec727ea7Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*ec727ea7Spatrick // See https://llvm.org/LICENSE.txt for license information.
5*ec727ea7Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*ec727ea7Spatrick //
7*ec727ea7Spatrick //===----------------------------------------------------------------------===//
8*ec727ea7Spatrick //
9*ec727ea7Spatrick // Defines the classes describing allocated blocks.
10*ec727ea7Spatrick //
11*ec727ea7Spatrick //===----------------------------------------------------------------------===//
12*ec727ea7Spatrick 
13*ec727ea7Spatrick #include "InterpBlock.h"
14*ec727ea7Spatrick #include "Pointer.h"
15*ec727ea7Spatrick 
16*ec727ea7Spatrick using namespace clang;
17*ec727ea7Spatrick using namespace clang::interp;
18*ec727ea7Spatrick 
19*ec727ea7Spatrick 
20*ec727ea7Spatrick 
addPointer(Pointer * P)21*ec727ea7Spatrick void Block::addPointer(Pointer *P) {
22*ec727ea7Spatrick   if (IsStatic)
23*ec727ea7Spatrick     return;
24*ec727ea7Spatrick   if (Pointers)
25*ec727ea7Spatrick     Pointers->Prev = P;
26*ec727ea7Spatrick   P->Next = Pointers;
27*ec727ea7Spatrick   P->Prev = nullptr;
28*ec727ea7Spatrick   Pointers = P;
29*ec727ea7Spatrick }
30*ec727ea7Spatrick 
removePointer(Pointer * P)31*ec727ea7Spatrick void Block::removePointer(Pointer *P) {
32*ec727ea7Spatrick   if (IsStatic)
33*ec727ea7Spatrick     return;
34*ec727ea7Spatrick   if (Pointers == P)
35*ec727ea7Spatrick     Pointers = P->Next;
36*ec727ea7Spatrick   if (P->Prev)
37*ec727ea7Spatrick     P->Prev->Next = P->Next;
38*ec727ea7Spatrick   if (P->Next)
39*ec727ea7Spatrick     P->Next->Prev = P->Prev;
40*ec727ea7Spatrick }
41*ec727ea7Spatrick 
cleanup()42*ec727ea7Spatrick void Block::cleanup() {
43*ec727ea7Spatrick   if (Pointers == nullptr && IsDead)
44*ec727ea7Spatrick     (reinterpret_cast<DeadBlock *>(this + 1) - 1)->free();
45*ec727ea7Spatrick }
46*ec727ea7Spatrick 
movePointer(Pointer * From,Pointer * To)47*ec727ea7Spatrick void Block::movePointer(Pointer *From, Pointer *To) {
48*ec727ea7Spatrick   if (IsStatic)
49*ec727ea7Spatrick     return;
50*ec727ea7Spatrick   To->Prev = From->Prev;
51*ec727ea7Spatrick   if (To->Prev)
52*ec727ea7Spatrick     To->Prev->Next = To;
53*ec727ea7Spatrick   To->Next = From->Next;
54*ec727ea7Spatrick   if (To->Next)
55*ec727ea7Spatrick     To->Next->Prev = To;
56*ec727ea7Spatrick   if (Pointers == From)
57*ec727ea7Spatrick     Pointers = To;
58*ec727ea7Spatrick 
59*ec727ea7Spatrick   From->Prev = nullptr;
60*ec727ea7Spatrick   From->Next = nullptr;
61*ec727ea7Spatrick }
62*ec727ea7Spatrick 
DeadBlock(DeadBlock * & Root,Block * Blk)63*ec727ea7Spatrick DeadBlock::DeadBlock(DeadBlock *&Root, Block *Blk)
64*ec727ea7Spatrick     : Root(Root), B(Blk->Desc, Blk->IsStatic, Blk->IsExtern, /*isDead=*/true) {
65*ec727ea7Spatrick   // Add the block to the chain of dead blocks.
66*ec727ea7Spatrick   if (Root)
67*ec727ea7Spatrick     Root->Prev = this;
68*ec727ea7Spatrick 
69*ec727ea7Spatrick   Next = Root;
70*ec727ea7Spatrick   Prev = nullptr;
71*ec727ea7Spatrick   Root = this;
72*ec727ea7Spatrick 
73*ec727ea7Spatrick   // Transfer pointers.
74*ec727ea7Spatrick   B.Pointers = Blk->Pointers;
75*ec727ea7Spatrick   for (Pointer *P = Blk->Pointers; P; P = P->Next)
76*ec727ea7Spatrick     P->Pointee = &B;
77*ec727ea7Spatrick }
78*ec727ea7Spatrick 
free()79*ec727ea7Spatrick void DeadBlock::free() {
80*ec727ea7Spatrick   if (Prev)
81*ec727ea7Spatrick     Prev->Next = Next;
82*ec727ea7Spatrick   if (Next)
83*ec727ea7Spatrick     Next->Prev = Prev;
84*ec727ea7Spatrick   if (Root == this)
85*ec727ea7Spatrick     Root = Next;
86*ec727ea7Spatrick   ::free(this);
87*ec727ea7Spatrick }
88