Path: blob/main/contrib/llvm-project/clang/lib/AST/Interp/InterpStack.cpp
35291 views
//===--- InterpStack.cpp - Stack implementation for the VM ------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "InterpStack.h"9#include "Boolean.h"10#include "Floating.h"11#include "Integral.h"12#include "MemberPointer.h"13#include "Pointer.h"14#include <cassert>15#include <cstdlib>1617using namespace clang;18using namespace clang::interp;1920InterpStack::~InterpStack() {21clear();22}2324void InterpStack::clear() {25if (Chunk && Chunk->Next)26std::free(Chunk->Next);27if (Chunk)28std::free(Chunk);29Chunk = nullptr;30StackSize = 0;31#ifndef NDEBUG32ItemTypes.clear();33#endif34}3536void *InterpStack::grow(size_t Size) {37assert(Size < ChunkSize - sizeof(StackChunk) && "Object too large");3839if (!Chunk || sizeof(StackChunk) + Chunk->size() + Size > ChunkSize) {40if (Chunk && Chunk->Next) {41Chunk = Chunk->Next;42} else {43StackChunk *Next = new (std::malloc(ChunkSize)) StackChunk(Chunk);44if (Chunk)45Chunk->Next = Next;46Chunk = Next;47}48}4950auto *Object = reinterpret_cast<void *>(Chunk->End);51Chunk->End += Size;52StackSize += Size;53return Object;54}5556void *InterpStack::peekData(size_t Size) const {57assert(Chunk && "Stack is empty!");5859StackChunk *Ptr = Chunk;60while (Size > Ptr->size()) {61Size -= Ptr->size();62Ptr = Ptr->Prev;63assert(Ptr && "Offset too large");64}6566return reinterpret_cast<void *>(Ptr->End - Size);67}6869void InterpStack::shrink(size_t Size) {70assert(Chunk && "Chunk is empty!");7172while (Size > Chunk->size()) {73Size -= Chunk->size();74if (Chunk->Next) {75std::free(Chunk->Next);76Chunk->Next = nullptr;77}78Chunk->End = Chunk->start();79Chunk = Chunk->Prev;80assert(Chunk && "Offset too large");81}8283Chunk->End -= Size;84StackSize -= Size;85}8687void InterpStack::dump() const {88#ifndef NDEBUG89llvm::errs() << "Items: " << ItemTypes.size() << ". Size: " << size() << '\n';90if (ItemTypes.empty())91return;9293size_t Index = 0;94size_t Offset = 0;9596// The type of the item on the top of the stack is inserted to the back97// of the vector, so the iteration has to happen backwards.98for (auto TyIt = ItemTypes.rbegin(); TyIt != ItemTypes.rend(); ++TyIt) {99Offset += align(primSize(*TyIt));100101llvm::errs() << Index << '/' << Offset << ": ";102TYPE_SWITCH(*TyIt, {103const T &V = peek<T>(Offset);104llvm::errs() << V;105});106llvm::errs() << '\n';107108++Index;109}110#endif111}112113114