/src/llvm-project/clang/lib/AST/Interp/InterpStack.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- InterpStack.h - 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 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // Defines the upwards-growing stack used by the interpreter. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #ifndef LLVM_CLANG_AST_INTERP_INTERPSTACK_H |
14 | | #define LLVM_CLANG_AST_INTERP_INTERPSTACK_H |
15 | | |
16 | | #include "FunctionPointer.h" |
17 | | #include "IntegralAP.h" |
18 | | #include "PrimType.h" |
19 | | #include <memory> |
20 | | #include <vector> |
21 | | |
22 | | namespace clang { |
23 | | namespace interp { |
24 | | |
25 | | /// Stack frame storing temporaries and parameters. |
26 | | class InterpStack final { |
27 | | public: |
28 | 0 | InterpStack() {} |
29 | | |
30 | | /// Destroys the stack, freeing up storage. |
31 | | ~InterpStack(); |
32 | | |
33 | | /// Constructs a value in place on the top of the stack. |
34 | 0 | template <typename T, typename... Tys> void push(Tys &&... Args) { |
35 | 0 | new (grow(aligned_size<T>())) T(std::forward<Tys>(Args)...); |
36 | 0 | #ifndef NDEBUG |
37 | 0 | ItemTypes.push_back(toPrimType<T>()); |
38 | 0 | #endif |
39 | 0 | } Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Floating, clang::interp::Floating&>(clang::interp::Floating&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Boolean, clang::interp::Boolean>(clang::interp::Boolean&&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Pointer, clang::interp::Pointer>(clang::interp::Pointer&&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::IntegralAP<true>, clang::interp::IntegralAP<true> >(clang::interp::IntegralAP<true>&&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::IntegralAP<false>, clang::interp::IntegralAP<false> >(clang::interp::IntegralAP<false>&&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Pointer, clang::interp::Pointer const&>(clang::interp::Pointer const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::FunctionPointer, clang::interp::Function const*&>(clang::interp::Function const*&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Pointer, clang::interp::Block*&, unsigned long>(clang::interp::Block*&, unsigned long&&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<8u, true>, clang::interp::Integral<8u, true>&>(clang::interp::Integral<8u, true>&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<8u, false>, clang::interp::Integral<8u, false>&>(clang::interp::Integral<8u, false>&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<16u, true>, clang::interp::Integral<16u, true>&>(clang::interp::Integral<16u, true>&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<16u, false>, clang::interp::Integral<16u, false>&>(clang::interp::Integral<16u, false>&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<32u, true>, clang::interp::Integral<32u, true>&>(clang::interp::Integral<32u, true>&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<32u, false>, clang::interp::Integral<32u, false>&>(clang::interp::Integral<32u, false>&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<64u, true>, clang::interp::Integral<64u, true>&>(clang::interp::Integral<64u, true>&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<64u, false>, clang::interp::Integral<64u, false>&>(clang::interp::Integral<64u, false>&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::IntegralAP<false>, clang::interp::IntegralAP<false>&>(clang::interp::IntegralAP<false>&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::IntegralAP<true>, clang::interp::IntegralAP<true>&>(clang::interp::IntegralAP<true>&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Boolean, clang::interp::Boolean&>(clang::interp::Boolean&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<8u, false>, clang::interp::Integral<8u, false> >(clang::interp::Integral<8u, false>&&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<8u, true>, clang::interp::Integral<8u, true> >(clang::interp::Integral<8u, true>&&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<16u, false>, clang::interp::Integral<16u, false> >(clang::interp::Integral<16u, false>&&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<16u, true>, clang::interp::Integral<16u, true> >(clang::interp::Integral<16u, true>&&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<32u, false>, clang::interp::Integral<32u, false> >(clang::interp::Integral<32u, false>&&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<32u, true>, clang::interp::Integral<32u, true> >(clang::interp::Integral<32u, true>&&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<64u, false>, clang::interp::Integral<64u, false> >(clang::interp::Integral<64u, false>&&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<64u, true>, clang::interp::Integral<64u, true> >(clang::interp::Integral<64u, true>&&) Unexecuted instantiation: void clang::interp::InterpStack::push<bool, bool const&>(bool const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Floating, clang::interp::Floating const&>(clang::interp::Floating const&) Unexecuted instantiation: void clang::interp::InterpStack::push<signed char, signed char const&>(signed char const&) Unexecuted instantiation: void clang::interp::InterpStack::push<short, short const&>(short const&) Unexecuted instantiation: void clang::interp::InterpStack::push<int, int const&>(int const&) Unexecuted instantiation: void clang::interp::InterpStack::push<long, long const&>(long const&) Unexecuted instantiation: void clang::interp::InterpStack::push<unsigned char, unsigned char const&>(unsigned char const&) Unexecuted instantiation: void clang::interp::InterpStack::push<unsigned short, unsigned short const&>(unsigned short const&) Unexecuted instantiation: void clang::interp::InterpStack::push<unsigned int, unsigned int const&>(unsigned int const&) Unexecuted instantiation: void clang::interp::InterpStack::push<unsigned long, unsigned long const&>(unsigned long const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<8u, true>, clang::interp::Integral<8u, true> const&>(clang::interp::Integral<8u, true> const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<8u, false>, clang::interp::Integral<8u, false> const&>(clang::interp::Integral<8u, false> const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<16u, true>, clang::interp::Integral<16u, true> const&>(clang::interp::Integral<16u, true> const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<16u, false>, clang::interp::Integral<16u, false> const&>(clang::interp::Integral<16u, false> const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<32u, true>, clang::interp::Integral<32u, true> const&>(clang::interp::Integral<32u, true> const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<32u, false>, clang::interp::Integral<32u, false> const&>(clang::interp::Integral<32u, false> const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<64u, true>, clang::interp::Integral<64u, true> const&>(clang::interp::Integral<64u, true> const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Integral<64u, false>, clang::interp::Integral<64u, false> const&>(clang::interp::Integral<64u, false> const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::IntegralAP<false>, clang::interp::IntegralAP<false> const&>(clang::interp::IntegralAP<false> const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::IntegralAP<true>, clang::interp::IntegralAP<true> const&>(clang::interp::IntegralAP<true> const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Pointer, clang::interp::Pointer&>(clang::interp::Pointer&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::FunctionPointer, clang::interp::FunctionPointer&>(clang::interp::FunctionPointer&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Boolean, clang::interp::Boolean const&>(clang::interp::Boolean const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::FunctionPointer, clang::interp::FunctionPointer const&>(clang::interp::FunctionPointer const&) Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Pointer>() Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::FunctionPointer>() Unexecuted instantiation: void clang::interp::InterpStack::push<clang::interp::Floating, clang::interp::Floating>(clang::interp::Floating&&) |
40 | | |
41 | | /// Returns the value from the top of the stack and removes it. |
42 | 0 | template <typename T> T pop() { |
43 | 0 | #ifndef NDEBUG |
44 | 0 | assert(!ItemTypes.empty()); |
45 | 0 | assert(ItemTypes.back() == toPrimType<T>()); |
46 | 0 | ItemTypes.pop_back(); |
47 | 0 | #endif |
48 | 0 | T *Ptr = &peekInternal<T>(); |
49 | 0 | T Value = std::move(*Ptr); |
50 | 0 | Ptr->~T(); |
51 | 0 | shrink(aligned_size<T>()); |
52 | 0 | return Value; |
53 | 0 | } Unexecuted instantiation: clang::interp::Floating clang::interp::InterpStack::pop<clang::interp::Floating>() Unexecuted instantiation: clang::interp::Pointer clang::interp::InterpStack::pop<clang::interp::Pointer>() Unexecuted instantiation: clang::interp::FunctionPointer clang::interp::InterpStack::pop<clang::interp::FunctionPointer>() Unexecuted instantiation: bool clang::interp::InterpStack::pop<bool>() Unexecuted instantiation: clang::interp::Integral<8u, true> clang::interp::InterpStack::pop<clang::interp::Integral<8u, true> >() Unexecuted instantiation: clang::interp::Integral<8u, false> clang::interp::InterpStack::pop<clang::interp::Integral<8u, false> >() Unexecuted instantiation: clang::interp::Integral<16u, true> clang::interp::InterpStack::pop<clang::interp::Integral<16u, true> >() Unexecuted instantiation: clang::interp::Integral<16u, false> clang::interp::InterpStack::pop<clang::interp::Integral<16u, false> >() Unexecuted instantiation: clang::interp::Integral<32u, true> clang::interp::InterpStack::pop<clang::interp::Integral<32u, true> >() Unexecuted instantiation: clang::interp::Integral<32u, false> clang::interp::InterpStack::pop<clang::interp::Integral<32u, false> >() Unexecuted instantiation: clang::interp::Integral<64u, true> clang::interp::InterpStack::pop<clang::interp::Integral<64u, true> >() Unexecuted instantiation: clang::interp::Integral<64u, false> clang::interp::InterpStack::pop<clang::interp::Integral<64u, false> >() Unexecuted instantiation: clang::interp::IntegralAP<false> clang::interp::InterpStack::pop<clang::interp::IntegralAP<false> >() Unexecuted instantiation: clang::interp::IntegralAP<true> clang::interp::InterpStack::pop<clang::interp::IntegralAP<true> >() Unexecuted instantiation: clang::interp::Boolean clang::interp::InterpStack::pop<clang::interp::Boolean>() Unexecuted instantiation: long clang::interp::InterpStack::pop<long>() |
54 | | |
55 | | /// Discards the top value from the stack. |
56 | 0 | template <typename T> void discard() { |
57 | 0 | #ifndef NDEBUG |
58 | 0 | assert(!ItemTypes.empty()); |
59 | 0 | assert(ItemTypes.back() == toPrimType<T>()); |
60 | 0 | ItemTypes.pop_back(); |
61 | 0 | #endif |
62 | 0 | T *Ptr = &peekInternal<T>(); |
63 | 0 | Ptr->~T(); |
64 | 0 | shrink(aligned_size<T>()); |
65 | 0 | } Unexecuted instantiation: void clang::interp::InterpStack::discard<clang::interp::Integral<8u, true> >() Unexecuted instantiation: void clang::interp::InterpStack::discard<clang::interp::Integral<8u, false> >() Unexecuted instantiation: void clang::interp::InterpStack::discard<clang::interp::Integral<16u, true> >() Unexecuted instantiation: void clang::interp::InterpStack::discard<clang::interp::Integral<16u, false> >() Unexecuted instantiation: void clang::interp::InterpStack::discard<clang::interp::Integral<32u, true> >() Unexecuted instantiation: void clang::interp::InterpStack::discard<clang::interp::Integral<32u, false> >() Unexecuted instantiation: void clang::interp::InterpStack::discard<clang::interp::Integral<64u, true> >() Unexecuted instantiation: void clang::interp::InterpStack::discard<clang::interp::Integral<64u, false> >() Unexecuted instantiation: void clang::interp::InterpStack::discard<clang::interp::IntegralAP<false> >() Unexecuted instantiation: void clang::interp::InterpStack::discard<clang::interp::IntegralAP<true> >() Unexecuted instantiation: void clang::interp::InterpStack::discard<clang::interp::Floating>() Unexecuted instantiation: void clang::interp::InterpStack::discard<clang::interp::Boolean>() Unexecuted instantiation: void clang::interp::InterpStack::discard<clang::interp::Pointer>() Unexecuted instantiation: void clang::interp::InterpStack::discard<clang::interp::FunctionPointer>() |
66 | | |
67 | | /// Returns a reference to the value on the top of the stack. |
68 | 0 | template <typename T> T &peek() const { |
69 | 0 | #ifndef NDEBUG |
70 | 0 | assert(!ItemTypes.empty()); |
71 | 0 | assert(ItemTypes.back() == toPrimType<T>()); |
72 | 0 | #endif |
73 | 0 | return peekInternal<T>(); |
74 | 0 | } Unexecuted instantiation: clang::interp::Pointer& clang::interp::InterpStack::peek<clang::interp::Pointer>() const Unexecuted instantiation: clang::interp::Integral<8u, true>& clang::interp::InterpStack::peek<clang::interp::Integral<8u, true> >() const Unexecuted instantiation: clang::interp::Integral<8u, false>& clang::interp::InterpStack::peek<clang::interp::Integral<8u, false> >() const Unexecuted instantiation: clang::interp::Integral<16u, true>& clang::interp::InterpStack::peek<clang::interp::Integral<16u, true> >() const Unexecuted instantiation: clang::interp::Integral<16u, false>& clang::interp::InterpStack::peek<clang::interp::Integral<16u, false> >() const Unexecuted instantiation: clang::interp::Integral<32u, true>& clang::interp::InterpStack::peek<clang::interp::Integral<32u, true> >() const Unexecuted instantiation: clang::interp::Integral<32u, false>& clang::interp::InterpStack::peek<clang::interp::Integral<32u, false> >() const Unexecuted instantiation: clang::interp::Integral<64u, true>& clang::interp::InterpStack::peek<clang::interp::Integral<64u, true> >() const Unexecuted instantiation: clang::interp::Integral<64u, false>& clang::interp::InterpStack::peek<clang::interp::Integral<64u, false> >() const Unexecuted instantiation: clang::interp::IntegralAP<false>& clang::interp::InterpStack::peek<clang::interp::IntegralAP<false> >() const Unexecuted instantiation: clang::interp::IntegralAP<true>& clang::interp::InterpStack::peek<clang::interp::IntegralAP<true> >() const Unexecuted instantiation: clang::interp::Boolean& clang::interp::InterpStack::peek<clang::interp::Boolean>() const Unexecuted instantiation: clang::interp::FunctionPointer& clang::interp::InterpStack::peek<clang::interp::FunctionPointer>() const Unexecuted instantiation: clang::interp::Floating& clang::interp::InterpStack::peek<clang::interp::Floating>() const |
75 | | |
76 | 0 | template <typename T> T &peek(size_t Offset) const { |
77 | 0 | assert(aligned(Offset)); |
78 | 0 | return *reinterpret_cast<T *>(peekData(Offset)); |
79 | 0 | } Unexecuted instantiation: clang::interp::Pointer& clang::interp::InterpStack::peek<clang::interp::Pointer>(unsigned long) const Unexecuted instantiation: clang::interp::Integral<8u, true>& clang::interp::InterpStack::peek<clang::interp::Integral<8u, true> >(unsigned long) const Unexecuted instantiation: clang::interp::Integral<8u, false>& clang::interp::InterpStack::peek<clang::interp::Integral<8u, false> >(unsigned long) const Unexecuted instantiation: clang::interp::Integral<16u, true>& clang::interp::InterpStack::peek<clang::interp::Integral<16u, true> >(unsigned long) const Unexecuted instantiation: clang::interp::Integral<16u, false>& clang::interp::InterpStack::peek<clang::interp::Integral<16u, false> >(unsigned long) const Unexecuted instantiation: clang::interp::Integral<32u, true>& clang::interp::InterpStack::peek<clang::interp::Integral<32u, true> >(unsigned long) const Unexecuted instantiation: clang::interp::Integral<32u, false>& clang::interp::InterpStack::peek<clang::interp::Integral<32u, false> >(unsigned long) const Unexecuted instantiation: clang::interp::Integral<64u, true>& clang::interp::InterpStack::peek<clang::interp::Integral<64u, true> >(unsigned long) const Unexecuted instantiation: clang::interp::Integral<64u, false>& clang::interp::InterpStack::peek<clang::interp::Integral<64u, false> >(unsigned long) const Unexecuted instantiation: clang::interp::IntegralAP<false>& clang::interp::InterpStack::peek<clang::interp::IntegralAP<false> >(unsigned long) const Unexecuted instantiation: clang::interp::IntegralAP<true>& clang::interp::InterpStack::peek<clang::interp::IntegralAP<true> >(unsigned long) const Unexecuted instantiation: clang::interp::Boolean& clang::interp::InterpStack::peek<clang::interp::Boolean>(unsigned long) const Unexecuted instantiation: clang::interp::Floating& clang::interp::InterpStack::peek<clang::interp::Floating>(unsigned long) const Unexecuted instantiation: clang::interp::FunctionPointer& clang::interp::InterpStack::peek<clang::interp::FunctionPointer>(unsigned long) const |
80 | | |
81 | | /// Returns a pointer to the top object. |
82 | 0 | void *top() const { return Chunk ? peekData(0) : nullptr; } |
83 | | |
84 | | /// Returns the size of the stack in bytes. |
85 | 0 | size_t size() const { return StackSize; } |
86 | | |
87 | | /// Clears the stack without calling any destructors. |
88 | | void clear(); |
89 | | |
90 | | /// Returns whether the stack is empty. |
91 | 0 | bool empty() const { return StackSize == 0; } |
92 | | |
93 | | /// dump the stack contents to stderr. |
94 | | void dump() const; |
95 | | |
96 | | private: |
97 | | /// All stack slots are aligned to the native pointer alignment for storage. |
98 | | /// The size of an object is rounded up to a pointer alignment multiple. |
99 | 0 | template <typename T> constexpr size_t aligned_size() const { |
100 | 0 | constexpr size_t PtrAlign = alignof(void *); |
101 | 0 | return ((sizeof(T) + PtrAlign - 1) / PtrAlign) * PtrAlign; |
102 | 0 | } Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<clang::interp::Floating>() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<clang::interp::Pointer>() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<clang::interp::FunctionPointer>() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<clang::interp::Boolean>() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<clang::interp::IntegralAP<true> >() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<clang::interp::IntegralAP<false> >() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<bool>() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<clang::interp::Integral<8u, true> >() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<clang::interp::Integral<8u, false> >() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<clang::interp::Integral<16u, true> >() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<clang::interp::Integral<16u, false> >() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<clang::interp::Integral<32u, true> >() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<clang::interp::Integral<32u, false> >() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<clang::interp::Integral<64u, true> >() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<clang::interp::Integral<64u, false> >() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<signed char>() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<short>() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<int>() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<long>() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<unsigned char>() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<unsigned short>() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<unsigned int>() const Unexecuted instantiation: unsigned long clang::interp::InterpStack::aligned_size<unsigned long>() const |
103 | | |
104 | | /// Like the public peek(), but without the debug type checks. |
105 | 0 | template <typename T> T &peekInternal() const { |
106 | 0 | return *reinterpret_cast<T *>(peekData(aligned_size<T>())); |
107 | 0 | } Unexecuted instantiation: clang::interp::Floating& clang::interp::InterpStack::peekInternal<clang::interp::Floating>() const Unexecuted instantiation: clang::interp::Pointer& clang::interp::InterpStack::peekInternal<clang::interp::Pointer>() const Unexecuted instantiation: clang::interp::FunctionPointer& clang::interp::InterpStack::peekInternal<clang::interp::FunctionPointer>() const Unexecuted instantiation: bool& clang::interp::InterpStack::peekInternal<bool>() const Unexecuted instantiation: clang::interp::Integral<8u, true>& clang::interp::InterpStack::peekInternal<clang::interp::Integral<8u, true> >() const Unexecuted instantiation: clang::interp::Integral<8u, false>& clang::interp::InterpStack::peekInternal<clang::interp::Integral<8u, false> >() const Unexecuted instantiation: clang::interp::Integral<16u, true>& clang::interp::InterpStack::peekInternal<clang::interp::Integral<16u, true> >() const Unexecuted instantiation: clang::interp::Integral<16u, false>& clang::interp::InterpStack::peekInternal<clang::interp::Integral<16u, false> >() const Unexecuted instantiation: clang::interp::Integral<32u, true>& clang::interp::InterpStack::peekInternal<clang::interp::Integral<32u, true> >() const Unexecuted instantiation: clang::interp::Integral<32u, false>& clang::interp::InterpStack::peekInternal<clang::interp::Integral<32u, false> >() const Unexecuted instantiation: clang::interp::Integral<64u, true>& clang::interp::InterpStack::peekInternal<clang::interp::Integral<64u, true> >() const Unexecuted instantiation: clang::interp::Integral<64u, false>& clang::interp::InterpStack::peekInternal<clang::interp::Integral<64u, false> >() const Unexecuted instantiation: clang::interp::IntegralAP<false>& clang::interp::InterpStack::peekInternal<clang::interp::IntegralAP<false> >() const Unexecuted instantiation: clang::interp::IntegralAP<true>& clang::interp::InterpStack::peekInternal<clang::interp::IntegralAP<true> >() const Unexecuted instantiation: clang::interp::Boolean& clang::interp::InterpStack::peekInternal<clang::interp::Boolean>() const Unexecuted instantiation: long& clang::interp::InterpStack::peekInternal<long>() const |
108 | | |
109 | | /// Grows the stack to accommodate a value and returns a pointer to it. |
110 | | void *grow(size_t Size); |
111 | | /// Returns a pointer from the top of the stack. |
112 | | void *peekData(size_t Size) const; |
113 | | /// Shrinks the stack. |
114 | | void shrink(size_t Size); |
115 | | |
116 | | /// Allocate stack space in 1Mb chunks. |
117 | | static constexpr size_t ChunkSize = 1024 * 1024; |
118 | | |
119 | | /// Metadata for each stack chunk. |
120 | | /// |
121 | | /// The stack is composed of a linked list of chunks. Whenever an allocation |
122 | | /// is out of bounds, a new chunk is linked. When a chunk becomes empty, |
123 | | /// it is not immediately freed: a chunk is deallocated only when the |
124 | | /// predecessor becomes empty. |
125 | | struct StackChunk { |
126 | | StackChunk *Next; |
127 | | StackChunk *Prev; |
128 | | char *End; |
129 | | |
130 | | StackChunk(StackChunk *Prev = nullptr) |
131 | 0 | : Next(nullptr), Prev(Prev), End(reinterpret_cast<char *>(this + 1)) {} |
132 | | |
133 | | /// Returns the size of the chunk, minus the header. |
134 | 0 | size_t size() const { return End - start(); } |
135 | | |
136 | | /// Returns a pointer to the start of the data region. |
137 | 0 | char *start() { return reinterpret_cast<char *>(this + 1); } |
138 | 0 | const char *start() const { |
139 | 0 | return reinterpret_cast<const char *>(this + 1); |
140 | 0 | } |
141 | | }; |
142 | | static_assert(sizeof(StackChunk) < ChunkSize, "Invalid chunk size"); |
143 | | |
144 | | /// First chunk on the stack. |
145 | | StackChunk *Chunk = nullptr; |
146 | | /// Total size of the stack. |
147 | | size_t StackSize = 0; |
148 | | |
149 | | #ifndef NDEBUG |
150 | | /// vector recording the type of data we pushed into the stack. |
151 | | std::vector<PrimType> ItemTypes; |
152 | | |
153 | 0 | template <typename T> static constexpr PrimType toPrimType() { |
154 | 0 | if constexpr (std::is_same_v<T, Pointer>) |
155 | 0 | return PT_Ptr; |
156 | 0 | else if constexpr (std::is_same_v<T, bool> || |
157 | 0 | std::is_same_v<T, Boolean>) |
158 | 0 | return PT_Bool; |
159 | 0 | else if constexpr (std::is_same_v<T, int8_t> || |
160 | 0 | std::is_same_v<T, Integral<8, true>>) |
161 | 0 | return PT_Sint8; |
162 | 0 | else if constexpr (std::is_same_v<T, uint8_t> || |
163 | 0 | std::is_same_v<T, Integral<8, false>>) |
164 | 0 | return PT_Uint8; |
165 | 0 | else if constexpr (std::is_same_v<T, int16_t> || |
166 | 0 | std::is_same_v<T, Integral<16, true>>) |
167 | 0 | return PT_Sint16; |
168 | 0 | else if constexpr (std::is_same_v<T, uint16_t> || |
169 | 0 | std::is_same_v<T, Integral<16, false>>) |
170 | 0 | return PT_Uint16; |
171 | 0 | else if constexpr (std::is_same_v<T, int32_t> || |
172 | 0 | std::is_same_v<T, Integral<32, true>>) |
173 | 0 | return PT_Sint32; |
174 | 0 | else if constexpr (std::is_same_v<T, uint32_t> || |
175 | 0 | std::is_same_v<T, Integral<32, false>>) |
176 | 0 | return PT_Uint32; |
177 | 0 | else if constexpr (std::is_same_v<T, int64_t> || |
178 | 0 | std::is_same_v<T, Integral<64, true>>) |
179 | 0 | return PT_Sint64; |
180 | 0 | else if constexpr (std::is_same_v<T, uint64_t> || |
181 | 0 | std::is_same_v<T, Integral<64, false>>) |
182 | 0 | return PT_Uint64; |
183 | 0 | else if constexpr (std::is_same_v<T, Floating>) |
184 | 0 | return PT_Float; |
185 | 0 | else if constexpr (std::is_same_v<T, FunctionPointer>) |
186 | 0 | return PT_FnPtr; |
187 | 0 | else if constexpr (std::is_same_v<T, IntegralAP<true>>) |
188 | 0 | return PT_IntAP; |
189 | 0 | else if constexpr (std::is_same_v<T, IntegralAP<false>>) |
190 | 0 | return PT_IntAP; |
191 | | |
192 | 0 | llvm_unreachable("unknown type push()'ed into InterpStack"); |
193 | 0 | } Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<clang::interp::Floating>() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<clang::interp::Pointer>() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<clang::interp::FunctionPointer>() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<clang::interp::Boolean>() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<clang::interp::IntegralAP<true> >() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<clang::interp::IntegralAP<false> >() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<bool>() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<clang::interp::Integral<8u, true> >() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<clang::interp::Integral<8u, false> >() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<clang::interp::Integral<16u, true> >() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<clang::interp::Integral<16u, false> >() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<clang::interp::Integral<32u, true> >() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<clang::interp::Integral<32u, false> >() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<clang::interp::Integral<64u, true> >() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<clang::interp::Integral<64u, false> >() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<signed char>() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<short>() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<int>() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<long>() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<unsigned char>() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<unsigned short>() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<unsigned int>() Unexecuted instantiation: clang::interp::PrimType clang::interp::InterpStack::toPrimType<unsigned long>() |
194 | | #endif |
195 | | }; |
196 | | |
197 | | } // namespace interp |
198 | | } // namespace clang |
199 | | |
200 | | #endif |