[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / lib / AST / Interp / InterpStack.cpp
blob91fe40feb7671b6b92c3a6be763a6d4d332723f3
1 //===--- InterpStack.cpp - Stack implementation for the VM ------*- 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 //===----------------------------------------------------------------------===//
9 #include "InterpStack.h"
10 #include "Boolean.h"
11 #include "Floating.h"
12 #include "Integral.h"
13 #include "Pointer.h"
14 #include <cassert>
15 #include <cstdlib>
17 using namespace clang;
18 using namespace clang::interp;
20 InterpStack::~InterpStack() {
21 clear();
24 void InterpStack::clear() {
25 if (Chunk && Chunk->Next)
26 std::free(Chunk->Next);
27 if (Chunk)
28 std::free(Chunk);
29 Chunk = nullptr;
30 StackSize = 0;
31 #ifndef NDEBUG
32 ItemTypes.clear();
33 #endif
36 void *InterpStack::grow(size_t Size) {
37 assert(Size < ChunkSize - sizeof(StackChunk) && "Object too large");
39 if (!Chunk || sizeof(StackChunk) + Chunk->size() + Size > ChunkSize) {
40 if (Chunk && Chunk->Next) {
41 Chunk = Chunk->Next;
42 } else {
43 StackChunk *Next = new (std::malloc(ChunkSize)) StackChunk(Chunk);
44 if (Chunk)
45 Chunk->Next = Next;
46 Chunk = Next;
50 auto *Object = reinterpret_cast<void *>(Chunk->End);
51 Chunk->End += Size;
52 StackSize += Size;
53 return Object;
56 void *InterpStack::peekData(size_t Size) const {
57 assert(Chunk && "Stack is empty!");
59 StackChunk *Ptr = Chunk;
60 while (Size > Ptr->size()) {
61 Size -= Ptr->size();
62 Ptr = Ptr->Prev;
63 assert(Ptr && "Offset too large");
66 return reinterpret_cast<void *>(Ptr->End - Size);
69 void InterpStack::shrink(size_t Size) {
70 assert(Chunk && "Chunk is empty!");
72 while (Size > Chunk->size()) {
73 Size -= Chunk->size();
74 if (Chunk->Next) {
75 std::free(Chunk->Next);
76 Chunk->Next = nullptr;
78 Chunk->End = Chunk->start();
79 Chunk = Chunk->Prev;
80 assert(Chunk && "Offset too large");
83 Chunk->End -= Size;
84 StackSize -= Size;
87 void InterpStack::dump() const {
88 #ifndef NDEBUG
89 llvm::errs() << "Items: " << ItemTypes.size() << ". Size: " << size() << '\n';
90 if (ItemTypes.empty())
91 return;
93 size_t Index = 0;
94 size_t Offset = 0;
96 // The type of the item on the top of the stack is inserted to the back
97 // of the vector, so the iteration has to happen backwards.
98 for (auto TyIt = ItemTypes.rbegin(); TyIt != ItemTypes.rend(); ++TyIt) {
99 Offset += align(primSize(*TyIt));
101 llvm::errs() << Index << '/' << Offset << ": ";
102 TYPE_SWITCH(*TyIt, {
103 const T &V = peek<T>(Offset);
104 llvm::errs() << V;
106 llvm::errs() << '\n';
108 ++Index;
110 #endif