Coverage Report

Created: 2024-01-17 10:31

/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