1717#include " IntegralAP.h"
1818#include " MemberPointer.h"
1919#include " PrimType.h"
20- #include < vector>
2120
2221namespace clang {
2322namespace interp {
@@ -33,18 +32,14 @@ class InterpStack final {
3332 // / Constructs a value in place on the top of the stack.
3433 template <typename T, typename ... Tys> void push (Tys &&...Args) {
3534 new (grow (aligned_size<T>())) T (std::forward<Tys>(Args)...);
36- #ifndef NDEBUG
3735 ItemTypes.push_back (toPrimType<T>());
38- #endif
3936 }
4037
4138 // / Returns the value from the top of the stack and removes it.
4239 template <typename T> T pop () {
43- #ifndef NDEBUG
4440 assert (!ItemTypes.empty ());
4541 assert (ItemTypes.back () == toPrimType<T>());
4642 ItemTypes.pop_back ();
47- #endif
4843 T *Ptr = &peekInternal<T>();
4944 T Value = std::move (*Ptr);
5045 shrink (aligned_size<T>());
@@ -53,22 +48,20 @@ class InterpStack final {
5348
5449 // / Discards the top value from the stack.
5550 template <typename T> void discard () {
56- #ifndef NDEBUG
5751 assert (!ItemTypes.empty ());
5852 assert (ItemTypes.back () == toPrimType<T>());
5953 ItemTypes.pop_back ();
60- #endif
6154 T *Ptr = &peekInternal<T>();
62- Ptr->~T ();
55+ if constexpr (!std::is_trivially_destructible_v<T>) {
56+ Ptr->~T ();
57+ }
6358 shrink (aligned_size<T>());
6459 }
6560
6661 // / Returns a reference to the value on the top of the stack.
6762 template <typename T> T &peek () const {
68- #ifndef NDEBUG
6963 assert (!ItemTypes.empty ());
7064 assert (ItemTypes.back () == toPrimType<T>());
71- #endif
7265 return peekInternal<T>();
7366 }
7467
@@ -83,7 +76,7 @@ class InterpStack final {
8376 // / Returns the size of the stack in bytes.
8477 size_t size () const { return StackSize; }
8578
86- // / Clears the stack without calling any destructors .
79+ // / Clears the stack.
8780 void clear ();
8881 void clearTo (size_t NewSize);
8982
@@ -146,9 +139,11 @@ class InterpStack final {
146139 // / Total size of the stack.
147140 size_t StackSize = 0 ;
148141
149- #ifndef NDEBUG
150- // / vector recording the type of data we pushed into the stack.
151- std::vector<PrimType> ItemTypes;
142+ // / SmallVector recording the type of data we pushed into the stack.
143+ // / We don't usually need this during normal code interpretation but
144+ // / when aborting, we need type information to call the destructors
145+ // / for what's left on the stack.
146+ llvm::SmallVector<PrimType> ItemTypes;
152147
153148 template <typename T> static constexpr PrimType toPrimType () {
154149 if constexpr (std::is_same_v<T, Pointer>)
@@ -192,7 +187,6 @@ class InterpStack final {
192187
193188 llvm_unreachable (" unknown type push()'ed into InterpStack" );
194189 }
195- #endif
196190};
197191
198192} // namespace interp
0 commit comments