//===--- Block.cpp - Allocated blocks for the interpreter -------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Defines the classes describing allocated blocks. // //===----------------------------------------------------------------------===// #include "InterpBlock.h" #include "Pointer.h" using namespace clang; using namespace clang::interp; void Block::addPointer(Pointer *P) { if (IsStatic) return; if (Pointers) Pointers->Prev = P; P->Next = Pointers; P->Prev = nullptr; Pointers = P; } void Block::removePointer(Pointer *P) { if (IsStatic) return; if (Pointers == P) Pointers = P->Next; if (P->Prev) P->Prev->Next = P->Next; if (P->Next) P->Next->Prev = P->Prev; } void Block::cleanup() { if (Pointers == nullptr && IsDead) (reinterpret_cast(this + 1) - 1)->free(); } void Block::movePointer(Pointer *From, Pointer *To) { if (IsStatic) return; To->Prev = From->Prev; if (To->Prev) To->Prev->Next = To; To->Next = From->Next; if (To->Next) To->Next->Prev = To; if (Pointers == From) Pointers = To; From->Prev = nullptr; From->Next = nullptr; } DeadBlock::DeadBlock(DeadBlock *&Root, Block *Blk) : Root(Root), B(Blk->Desc, Blk->IsStatic, Blk->IsExtern, /*isDead=*/true) { // Add the block to the chain of dead blocks. if (Root) Root->Prev = this; Next = Root; Prev = nullptr; Root = this; // Transfer pointers. B.Pointers = Blk->Pointers; for (Pointer *P = Blk->Pointers; P; P = P->Next) P->Pointee = &B; } void DeadBlock::free() { if (Prev) Prev->Next = Next; if (Next) Next->Prev = Prev; if (Root == this) Root = Next; ::free(this); }