// <stacktrace> -*- C++ -*-

// Copyright The GNU Toolchain Authors.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

#ifndef _GLIBCXX_STACKTRACE
#define _GLIBCXX_STACKTRACE 1

#pragma GCC system_header

#include <bits/requires_hosted.h> // std::string bound

#include <bits/c++config.h>

#if __cplusplus > 202002L && _GLIBCXX_HAVE_STACKTRACE
#include <compare>
#include <new>
#include <string>
#include <sstream>
#include <bits/memory_resource.h>
#include <bits/stl_algobase.h>
#include <bits/stl_algo.h>
#include <bits/stl_iterator.h>
#include <bits/stl_uninitialized.h>
#include <ext/numeric_traits.h>

struct __glibcxx_backtrace_state;
struct __glibcxx_backtrace_simple_data;

extern "C"
{
__glibcxx_backtrace_state*
__glibcxx_backtrace_create_state(const char*, int,
				 void(*)(void*, const char*, int),
				 void*);

int
__glibcxx_backtrace_simple(__glibcxx_backtrace_state*, int,
			   int (*) (void*, __UINTPTR_TYPE__),
			   void(*)(void*, const char*, int),
			   void*);
int
__glibcxx_backtrace_pcinfo(__glibcxx_backtrace_state*, __UINTPTR_TYPE__,
			   int (*)(void*, __UINTPTR_TYPE__,
				   const char*, int, const char*),
			   void(*)(void*, const char*, int),
			   void*);

int
__glibcxx_backtrace_syminfo(__glibcxx_backtrace_state*, __UINTPTR_TYPE__ addr,
			    void (*) (void*, __UINTPTR_TYPE__, const char*,
				      __UINTPTR_TYPE__, __UINTPTR_TYPE__),
			    void(*)(void*, const char*, int),
			    void*);
}

namespace __cxxabiv1
{
  extern "C" char*
  __cxa_demangle(const char* __mangled_name, char* __output_buffer,
		 size_t* __length, int* __status);
}

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

#define __cpp_lib_stacktrace 202011L

  // [stacktrace.entry], class stacktrace_entry
  class stacktrace_entry
  {
    using uint_least32_t = __UINT_LEAST32_TYPE__;
    using uintptr_t = __UINTPTR_TYPE__;

  public:
    using native_handle_type = uintptr_t;

    // [stacktrace.entry.ctor], constructors

    constexpr
    stacktrace_entry() noexcept = default;

    constexpr
    stacktrace_entry(const stacktrace_entry& __other) noexcept = default;

    constexpr stacktrace_entry&
    operator=(const stacktrace_entry& __other) noexcept = default;

    ~stacktrace_entry() = default;

    // [stacktrace.entry.obs], observers

    constexpr native_handle_type
    native_handle() const noexcept { return _M_pc; }

    constexpr explicit operator bool() const noexcept { return _M_pc != -1; }

    // [stacktrace.entry.query], query
    string
    description() const
    {
      string __s;
      _M_get_info(&__s, nullptr, nullptr);
      return __s;
    }

    string
    source_file() const
    {
      string __s;
      _M_get_info(nullptr, &__s, nullptr);
      return __s;
    }

    uint_least32_t
    source_line() const
    {
      int __line = 0;
      _M_get_info(nullptr, nullptr, &__line);
      return __line;
    }

    // [stacktrace.entry.cmp], comparison
    friend constexpr bool
    operator==(const stacktrace_entry& __x,
	       const stacktrace_entry& __y) noexcept
    { return __x._M_pc == __y._M_pc; }

    friend constexpr strong_ordering
    operator<=>(const stacktrace_entry& __x,
		const stacktrace_entry& __y) noexcept
    { return __x._M_pc <=> __y._M_pc; }

  private:
    native_handle_type _M_pc = -1;

    template<typename _Allocator> friend class basic_stacktrace;

    static __glibcxx_backtrace_state*
    _S_init()
    {
      static __glibcxx_backtrace_state* __state
	= __glibcxx_backtrace_create_state(nullptr, 1, nullptr, nullptr);
      return __state;
    }

    template<typename _CharT, typename _Traits>
      friend basic_ostream<_CharT, _Traits>&
      operator<<(basic_ostream<_CharT, _Traits>&, const stacktrace_entry&);

    bool
    _M_get_info(string* __desc, string* __file, int* __line) const
    {
      if (!*this)
	return false;

      struct _Data
      {
	string* _M_desc;
	string* _M_file;
	int* _M_line;
      } __data = { __desc, __file, __line };

      auto __cb = [](void* __data, uintptr_t, const char* __filename,
		     int __lineno, const char* __function) -> int {
	  auto& __d = *static_cast<_Data*>(__data);
	  if (__function && __d._M_desc)
	    *__d._M_desc = _S_demangle(__function);
	  if (__filename && __d._M_file)
	    *__d._M_file = __filename;
	  if (__d._M_line)
	    *__d._M_line = __lineno;
	  return __function != nullptr;
      };
      const auto __state = _S_init();
      if (::__glibcxx_backtrace_pcinfo(__state, _M_pc, +__cb, nullptr, &__data))
	return true;
      if (__desc && __desc->empty())
	{
	  auto __cb2 = [](void* __data, uintptr_t, const char* __symname,
	      uintptr_t, uintptr_t) {
	      if (__symname)
		*static_cast<_Data*>(__data)->_M_desc = _S_demangle(__symname);
	  };
	  if (::__glibcxx_backtrace_syminfo(__state, _M_pc, +__cb2, nullptr,
					    &__data))
	    return true;
	}
      return false;
    }

    static string
    _S_demangle(const char* __name)
    {
      string __s;
      int __status;
      char* __str = __cxxabiv1::__cxa_demangle(__name, nullptr, nullptr,
					       &__status);
      if (__status == 0)
	__s = __str;
      __builtin_free(__str);
      return __s;
    }
  };

  // [stacktrace.basic], class template basic_stacktrace
  template<typename _Allocator>
    class basic_stacktrace
    {
      using _AllocTraits = allocator_traits<_Allocator>;
      using uintptr_t = __UINTPTR_TYPE__;

    public:
      using value_type = stacktrace_entry;
      using const_reference = const value_type&;
      using reference = value_type&;
      using const_iterator
	= __gnu_cxx::__normal_iterator<value_type*, basic_stacktrace>;
      using iterator = const_iterator;
      using reverse_iterator = std::reverse_iterator<iterator>;
      using const_reverse_iterator = std::reverse_iterator<const_iterator>;
      using difference_type = ptrdiff_t;
      using size_type = unsigned short;
      using allocator_type = _Allocator;

      // [stacktrace.basic.ctor], creation and assignment

      [[__gnu__::__noinline__]]
      static basic_stacktrace
      current(const allocator_type& __alloc = allocator_type()) noexcept
      {
	basic_stacktrace __ret(__alloc);
	if (auto __cb = __ret._M_prepare()) [[likely]]
	  {
	    auto __state = stacktrace_entry::_S_init();
	    if (__glibcxx_backtrace_simple(__state, 1, __cb, nullptr,
					   std::__addressof(__ret)))
	      __ret._M_clear();
	  }
	return __ret;
      }

      [[__gnu__::__noinline__]]
      static basic_stacktrace
      current(size_type __skip,
	      const allocator_type& __alloc = allocator_type()) noexcept
      {
	basic_stacktrace __ret(__alloc);
	if (__skip >= __INT_MAX__) [[unlikely]]
	  return __ret;
	if (auto __cb = __ret._M_prepare()) [[likely]]
	  {
	    auto __state = stacktrace_entry::_S_init();
	    if (__glibcxx_backtrace_simple(__state, __skip + 1, __cb, nullptr,
					   std::__addressof(__ret)))
	      __ret._M_clear();
	  }

	return __ret;
      }

      [[__gnu__::__noinline__]]
      static basic_stacktrace
      current(size_type __skip, size_type __max_depth,
	      const allocator_type& __alloc = allocator_type()) noexcept
      {
	__glibcxx_assert(__skip <= (size_type(-1) - __max_depth));

	basic_stacktrace __ret(__alloc);
	if (__max_depth == 0) [[unlikely]]
	  return __ret;
	if (__skip >= __INT_MAX__) [[unlikely]]
	  return __ret;
	if (auto __cb = __ret._M_prepare(__max_depth)) [[likely]]
	  {
	    auto __state = stacktrace_entry::_S_init();
	    int __err = __glibcxx_backtrace_simple(__state, __skip + 1, __cb,
						   nullptr,
						   std::__addressof(__ret));
	    if (__err < 0)
	      __ret._M_clear();
	    else if (__ret.size() > __max_depth)
	      {
		__ret._M_impl._M_resize(__max_depth, __ret._M_alloc);

		if (__ret._M_impl._M_capacity / 2 >= __max_depth)
		  {
		    // shrink to fit
		    _Impl __tmp = __ret._M_impl._M_clone(__ret._M_alloc);
		    if (__tmp._M_capacity)
		      {
			__ret._M_clear();
			__ret._M_impl = __tmp;
		      }
		  }
	      }
	  }
	return __ret;
      }

      basic_stacktrace()
      noexcept(is_nothrow_default_constructible_v<allocator_type>)
      { }

      explicit
      basic_stacktrace(const allocator_type& __alloc) noexcept
      : _M_alloc(__alloc)
      { }

      basic_stacktrace(const basic_stacktrace& __other) noexcept
      : basic_stacktrace(__other,
	  _AllocTraits::select_on_container_copy_construction(__other._M_alloc))
      { }

      basic_stacktrace(basic_stacktrace&& __other) noexcept
      : _M_alloc(std::move(__other._M_alloc)),
	_M_impl(std::__exchange(__other._M_impl, {}))
      { }

      basic_stacktrace(const basic_stacktrace& __other,
		       const allocator_type& __alloc) noexcept
      : _M_alloc(__alloc)
      {
	if (const auto __s = __other._M_impl._M_size)
	  _M_impl = __other._M_impl._M_clone(_M_alloc);
      }

      basic_stacktrace(basic_stacktrace&& __other,
		       const allocator_type& __alloc) noexcept
      : _M_alloc(__alloc)
      {
	if constexpr (_Allocator::is_always_equal::value)
	  _M_impl = std::__exchange(__other._M_impl, {});
	else if (_M_alloc == __other._M_alloc)
	  _M_impl = std::__exchange(__other._M_impl, {});
	else if (const auto __s = __other._M_impl._M_size)
	  _M_impl = __other._M_impl._M_clone(_M_alloc);
      }

      basic_stacktrace&
      operator=(const basic_stacktrace& __other) noexcept
      {
	if (std::__addressof(__other) == this)
	  return *this;

	constexpr bool __pocca
	  = _AllocTraits::propagate_on_container_copy_assignment::value;
	constexpr bool __always_eq = _AllocTraits::is_always_equal::value;

	const auto __s = __other.size();

	if constexpr (!__always_eq && __pocca)
	  {
	    if (_M_alloc != __other._M_alloc)
	      {
		// Cannot keep the same storage, so deallocate it now.
		_M_clear();
	      }
	  }

	if (_M_impl._M_capacity < __s)
	  {
	    // Need to allocate new storage.
	    _M_clear();

	    if constexpr (__pocca)
	      _M_alloc = __other._M_alloc;

	    _M_impl = __other._M_impl._M_clone(_M_alloc);
	  }
	else
	  {
	    // Current storage is large enough.
	    _M_impl._M_resize(0, _M_alloc);
	    _M_impl._M_assign(__other._M_impl, _M_alloc);

	    if constexpr (__pocca)
	      _M_alloc = __other._M_alloc;
	  }

	return *this;
      }

      basic_stacktrace&
      operator=(basic_stacktrace&& __other) noexcept
      {
	if (std::__addressof(__other) == this)
	  return *this;

	constexpr bool __pocma
	  = _AllocTraits::propagate_on_container_move_assignment::value;

	if constexpr (_AllocTraits::is_always_equal::value)
	  std::swap(_M_impl, __other._M_impl);
	else if (_M_alloc == __other._M_alloc)
	  std::swap(_M_impl, __other._M_impl);
	else if constexpr (__pocma)
	  {
	    // Free current storage and take ownership of __other's storage.
	    _M_clear();
	    _M_impl = std::__exchange(__other._M_impl, {});
	  }
	else // Allocators are unequal and don't propagate.
	  {
	    const size_type __s = __other.size();

	    if (_M_impl._M_capacity < __s)
	      {
		// Need to allocate new storage.
		_M_clear();
		_M_impl = __other._M_impl._M_clone(_M_alloc);
	      }
	    else
	      {
		// Current storage is large enough.
		_M_impl._M_resize(0, _M_alloc);
		_M_impl._M_assign(__other._M_impl, _M_alloc);
	      }
	  }

	if constexpr (__pocma)
	  _M_alloc = std::move(__other._M_alloc);

	return *this;
      }

      constexpr ~basic_stacktrace()
      {
	_M_clear();
      }

      // [stacktrace.basic.obs], observers
      allocator_type get_allocator() const noexcept { return _M_alloc; }

      const_iterator
      begin() const noexcept
      { return const_iterator{_M_impl._M_frames}; }

      const_iterator
      end() const noexcept
      { return begin() + size(); }

      const_reverse_iterator
      rbegin() const noexcept
      { return std::make_reverse_iterator(end()); }

      const_reverse_iterator
      rend() const noexcept
      { return std::make_reverse_iterator(begin()); }

      const_iterator cbegin() const noexcept { return begin(); }
      const_iterator cend() const noexcept { return end(); }
      const_reverse_iterator crbegin() const noexcept { return rbegin(); };
      const_reverse_iterator crend() const noexcept { return rend(); };

      [[nodiscard]] bool empty() const noexcept { return size() == 0; }
      size_type size() const noexcept { return _M_impl._M_size; }

      size_type
      max_size() const noexcept
      { return _Impl::_S_max_size(_M_impl._M_alloc); }

      const_reference
      operator[](size_type __n) const noexcept
      {
	__glibcxx_assert(__n < size());
	return begin()[__n];
      }

      const_reference
      at(size_type __n) const
      {
	if (__n >= size())
	  __throw_out_of_range("basic_stack_trace::at: bad frame number");
	return begin()[__n];
      }

      // [stacktrace.basic.cmp], comparisons
      template<typename _Allocator2>
	friend bool
	operator==(const basic_stacktrace& __x,
		   const basic_stacktrace<_Allocator2>& __y) noexcept
	{ return std::equal(__x.begin(), __x.end(), __y.begin(), __y.end()); }

      template<typename _Allocator2>
	friend strong_ordering
	operator<=>(const basic_stacktrace& __x,
		    const basic_stacktrace<_Allocator2>& __y) noexcept
	{
	  if (auto __s = __x.size() <=> __y.size(); __s != 0)
	    return __s;
	  return std::lexicographical_compare_three_way(__x.begin(), __x.end(),
							__y.begin(), __y.end());
	}

      // [stacktrace.basic.mod], modifiers
      void
      swap(basic_stacktrace& __other) noexcept
      {
	std::swap(_M_impl, __other._M_impl);
	if constexpr (_AllocTraits::propagate_on_container_swap::value)
	  std::swap(_M_alloc, __other._M_alloc);
	else if constexpr (!_AllocTraits::is_always_equal::value)
	  {
	    __glibcxx_assert(_M_alloc == __other._M_alloc);
	  }
      }

    private:
      bool
      _M_push_back(const value_type& __x) noexcept
      {
	return _M_impl._M_push_back(_M_alloc, __x);
      }

      void
      _M_clear() noexcept
      {
	_M_impl._M_resize(0, _M_alloc);
	_M_impl._M_deallocate(_M_alloc);
      }

      // Precondition: __max_depth != 0
      auto
      _M_prepare(size_type __max_depth = -1) noexcept
      -> int (*) (void*, uintptr_t)
      {
	auto __cb = +[](void* __data, uintptr_t __pc) {
	  auto& __s = *static_cast<basic_stacktrace*>(__data);
	  stacktrace_entry __f;
	  __f._M_pc = __pc;
	  if (__s._M_push_back(__f)) [[likely]]
	    return 0; // continue tracing
	  return -1; // stop tracing due to error
	};

	if (__max_depth > 128)
	  __max_depth = 64; // soft limit, _M_push_back will reallocate
	else
	  __cb = [](void* __data, uintptr_t __pc) {
	    auto& __s = *static_cast<basic_stacktrace*>(__data);
	    stacktrace_entry __f;
	    __f._M_pc = __pc;
	    if (__s.size() == __s._M_impl._M_capacity) [[unlikely]]
	      return 1; // stop tracing due to reaching max depth
	    if (__s._M_push_back(__f)) [[likely]]
	      return 0; // continue tracing
	    return -1; // stop tracing due to error
	  };

	if (_M_impl._M_allocate(_M_alloc, __max_depth)) [[likely]]
	  return __cb;
	return nullptr;
      }

      struct _Impl
      {
	using pointer = typename _AllocTraits::pointer;

	pointer	  _M_frames   = nullptr;
	size_type _M_size     = 0;
	size_type _M_capacity = 0;

	static size_type
	_S_max_size(const allocator_type& __alloc) noexcept
	{
	  const size_t __size_max = __gnu_cxx::__int_traits<size_type>::__max;
	  const size_t __alloc_max = _AllocTraits::max_size(__alloc);
	  return std::min(__size_max, __alloc_max);
	}

#if __has_builtin(__builtin_operator_new) >= 201802L
# define _GLIBCXX_OPERATOR_NEW __builtin_operator_new
# define _GLIBCXX_OPERATOR_DELETE __builtin_operator_delete
#else
# define _GLIBCXX_OPERATOR_NEW ::operator new
# define _GLIBCXX_OPERATOR_DELETE ::operator delete
#endif

	// Precondition: _M_frames == nullptr && __n != 0
	pointer
	_M_allocate(allocator_type& __alloc, size_type __n) noexcept
	{
	  if (__n <= _S_max_size(__alloc)) [[likely]]
	    {
	      if constexpr (is_same_v<allocator_type, allocator<value_type>>)
		{
		  __n *= sizeof(value_type);
		  void* const __p = _GLIBCXX_OPERATOR_NEW (__n, nothrow_t{});
		  if (__p == nullptr) [[unlikely]]
		    return nullptr;
		  _M_frames = static_cast<pointer>(__p);
		}
	      else
		{
		  __try
		    {
		      _M_frames = __alloc.allocate(__n);
		    }
		  __catch (const std::bad_alloc&)
		    {
		      return nullptr;
		    }
		}
	      _M_capacity = __n;
	      return _M_frames;
	    }
	  return nullptr;
	}

	void
	_M_deallocate(allocator_type& __alloc) noexcept
	{
	  if (_M_capacity)
	    {
	      if constexpr (is_same_v<allocator_type, allocator<value_type>>)
		_GLIBCXX_OPERATOR_DELETE (static_cast<void*>(_M_frames),
					  _M_capacity * sizeof(value_type));
	      else
		__alloc.deallocate(_M_frames, _M_capacity);
	      _M_frames = nullptr;
	      _M_capacity = 0;
	    }
	}

#undef _GLIBCXX_OPERATOR_DELETE
#undef _GLIBCXX_OPERATOR_NEW

	// Precondition: __n <= _M_size
	void
	_M_resize(size_type __n, allocator_type& __alloc) noexcept
	{
	  for (size_type __i = __n; __i < _M_size; ++__i)
	    _AllocTraits::destroy(__alloc, &_M_frames[__i]);
	  _M_size = __n;
	}

	bool
	_M_push_back(allocator_type& __alloc,
		     const stacktrace_entry& __f) noexcept
	{
	  if (_M_size == _M_capacity) [[unlikely]]
	    {
	      _Impl __tmp = _M_xclone(_M_capacity ? _M_capacity : 8, __alloc);
	      if (!__tmp._M_capacity) [[unlikely]]
		return false;
	      _M_resize(0, __alloc);
	      _M_deallocate(__alloc);
	      *this = __tmp;
	    }
	  stacktrace_entry* __addr = std::to_address(_M_frames + _M_size++);
	  _AllocTraits::construct(__alloc, __addr, __f);
	  return true;
	}

	// Precondition: _M_size != 0
	_Impl
	_M_clone(allocator_type& __alloc) const noexcept
	{
	  return _M_xclone(_M_size, __alloc);
	}

	// Precondition: _M_size != 0 || __extra != 0
	_Impl
	_M_xclone(size_type __extra, allocator_type& __alloc) const noexcept
	{
	  _Impl __i;
	  if (__i._M_allocate(__alloc, _M_size + __extra)) [[likely]]
	    __i._M_assign(*this, __alloc);
	  return __i;
	}

	// Precondition: _M_capacity >= __other._M_size
	void
	_M_assign(const _Impl& __other, allocator_type& __alloc) noexcept
	{
	  std::__uninitialized_copy_a(__other._M_frames,
				      __other._M_frames + __other._M_size,
				      _M_frames, __alloc);
	  _M_size = __other._M_size;
	}
      };

      [[no_unique_address]] allocator_type  _M_alloc{};

      _Impl _M_impl{};
    };

  // basic_stacktrace typedef names
  using stacktrace = basic_stacktrace<allocator<stacktrace_entry>>;

  // [stacktrace.basic.nonmem], non-member functions
  template<typename _Allocator>
    inline void
    swap(basic_stacktrace<_Allocator>& __a, basic_stacktrace<_Allocator>& __b)
    noexcept(noexcept(__a.swap(__b)))
    { __a.swap(__b); }

  template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>&
    operator<<(basic_ostream<_CharT, _Traits>& __os,
	       const stacktrace_entry& __f)
    {
      string __desc, __file;
      int __line;
      if (__f._M_get_info(&__desc, &__file, &__line))
	{
	  __os.width(4);
	  __os << __desc << " at " << __file << ':' << __line;
	}
      return __os;
    }

  template<typename _CharT, typename _Traits, typename _Allocator>
    inline basic_ostream<_CharT, _Traits>&
    operator<<(basic_ostream<_CharT, _Traits>& __os,
	       const basic_stacktrace<_Allocator>& __st)
    {
      for (stacktrace::size_type __i = 0; __i < __st.size(); ++__i)
	{
	  __os.width(4);
	  __os << __i << "# " << __st[__i] << '\n';
	}
      return __os;
    }

  inline string
  to_string(const stacktrace_entry& __f)
  {
    std::ostringstream __os;
    __os << __f;
    return std::move(__os).str();
  }

  template<typename _Allocator>
    string
    to_string(const basic_stacktrace<_Allocator>& __st)
    {
      std::ostringstream __os;
      __os << __st;
      return std::move(__os).str();
    }

  namespace pmr
  {
    using stacktrace
      = basic_stacktrace<polymorphic_allocator<stacktrace_entry>>;
  }

  // [stacktrace.basic.hash], hash support

  template<>
    struct hash<stacktrace_entry>
    {
      size_t
      operator()(const stacktrace_entry& __f) const noexcept
      {
	using __h = hash<stacktrace_entry::native_handle_type>;
	return __h()(__f.native_handle());
      }
    };

  template<typename _Allocator>
    struct hash<basic_stacktrace<_Allocator>>
    {
      size_t
      operator()(const basic_stacktrace<_Allocator>& __st) const noexcept
      {
	hash<stacktrace_entry::native_handle_type> __h;
	size_t __val = _Hash_impl::hash(__st.size());
	for (const auto& __f : __st)
	  __val = _Hash_impl::__hash_combine(__h(__f), __val);
	return __val;
      }
    };

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++23

#endif /* _GLIBCXX_STACKTRACE */
