diff --git a/clang/lib/AST/Interp/InterpStack.h b/clang/lib/AST/Interp/InterpStack.h --- a/clang/lib/AST/Interp/InterpStack.h +++ b/clang/lib/AST/Interp/InterpStack.h @@ -13,7 +13,9 @@ #ifndef LLVM_CLANG_AST_INTERP_INTERPSTACK_H #define LLVM_CLANG_AST_INTERP_INTERPSTACK_H +#include "PrimType.h" #include +#include namespace clang { namespace interp { @@ -29,10 +31,18 @@ /// Constructs a value in place on the top of the stack. template void push(Tys &&... Args) { new (grow(aligned_size())) T(std::forward(Args)...); +#ifndef NDEBUG + ItemTypes.push_back(toPrimType()); +#endif } /// Returns the value from the top of the stack and removes it. template T pop() { +#ifndef NDEBUG + assert(!ItemTypes.empty()); + assert(ItemTypes.back() == toPrimType()); + ItemTypes.pop_back(); +#endif auto *Ptr = &peek(); auto Value = std::move(*Ptr); Ptr->~T(); @@ -42,6 +52,10 @@ /// Discards the top value from the stack. template void discard() { +#ifndef NDEBUG + assert(ItemTypes.back() == toPrimType()); + ItemTypes.pop_back(); +#endif auto *Ptr = &peek(); Ptr->~T(); shrink(aligned_size()); @@ -108,6 +122,45 @@ StackChunk *Chunk = nullptr; /// Total size of the stack. size_t StackSize = 0; + +#ifndef NDEBUG + /// vector recording the type of data we pushed into the stack. + std::vector ItemTypes; + + template static constexpr PrimType toPrimType() { + if constexpr (std::is_same_v) + return PT_Ptr; + else if constexpr (std::is_same_v || + std::is_same_v) + return PT_Bool; + else if constexpr (std::is_same_v || + std::is_same_v>) + return PT_Sint8; + else if constexpr (std::is_same_v || + std::is_same_v>) + return PT_Uint8; + else if constexpr (std::is_same_v || + std::is_same_v>) + return PT_Sint16; + else if constexpr (std::is_same_v || + std::is_same_v>) + return PT_Uint16; + else if constexpr (std::is_same_v || + std::is_same_v>) + return PT_Sint32; + else if constexpr (std::is_same_v || + std::is_same_v>) + return PT_Uint32; + else if constexpr (std::is_same_v || + std::is_same_v>) + return PT_Sint64; + else if constexpr (std::is_same_v || + std::is_same_v>) + return PT_Uint64; + + llvm_unreachable("unknown type push()'ed into InterpStack"); + } +#endif }; } // namespace interp