[libcxx-commits] [libcxx] Add C++23 stacktrace (P0881R7) (PR #136528)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Mon Sep 1 01:29:57 PDT 2025


================
@@ -0,0 +1,342 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_STACKTRACE_BASIC
+#define _LIBCPP_STACKTRACE_BASIC
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if _LIBCPP_STD_VER >= 23
+
+#  include <__assert>
+#  include <__cstddef/size_t.h>
+#  include <__functional/function.h>
+#  include <__functional/hash.h>
+#  include <__iterator/iterator.h>
+#  include <__iterator/reverse_iterator.h>
+#  include <__memory/allocator_traits.h>
+#  include <__memory_resource/polymorphic_allocator.h>
+#  include <__new/allocate.h>
+#  include <__type_traits/is_nothrow_constructible.h>
+#  include <__vector/vector.h>
+#  include <cstddef>
+#  include <cstdint>
+#  include <string>
+#  include <utility>
+
+#  if _LIBCPP_HAS_LOCALIZATION
+#    include <__fwd/format.h>
+#    include <__fwd/ostream.h>
+#  endif // _LIBCPP_HAS_LOCALIZATION
+
+#  include <__stacktrace/stacktrace_entry.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __stacktrace {
+
+template <typename _Tp, typename _Bp = _Tp>
+struct iters {
+  _Tp* __data_{};
+  size_t __size_{};
+
+  _Bp* data() { return (_Bp*)__data_; }
+  size_t size() const { return __size_; }
+  _Bp* begin() { return data(); }
+  _Bp* end() { return data() + size(); }
+};
+
+struct base {
+  constexpr static size_t __default_max_depth  = 64;
+  constexpr static size_t __absolute_max_depth = 256;
+
+  str_alloc<char> __string_alloc_;
+
+  using _EntryIters _LIBCPP_NODEBUG = iters<stacktrace_entry, entry_base>;
+  function<_EntryIters()> __entry_iters_;
+  function<entry_base&()> __entry_append_;
+
+  template <class _Allocator>
+  _LIBCPP_HIDE_FROM_ABI
+  base(_Allocator const& __alloc, function<_EntryIters()> __entry_iters, function<entry_base&()> __entry_append)
+      : __string_alloc_(std::move(str_alloc<char>::make(__alloc))),
+        __entry_iters_(__entry_iters),
+        __entry_append_(__entry_append) {}
+
+  _LIBCPP_NO_TAIL_CALLS _LIBCPP_NOINLINE _LIBCPP_EXPORTED_FROM_ABI void current_impl(size_t __skip, size_t __max_depth);
+
+  _LIBCPP_HIDE_FROM_ABI void find_images();
+  _LIBCPP_HIDE_FROM_ABI void find_symbols();
+  _LIBCPP_HIDE_FROM_ABI void find_source_locs();
+
+  _LIBCPP_EXPORTED_FROM_ABI ostream& write_to(ostream& __os) const;
+  _LIBCPP_EXPORTED_FROM_ABI string to_string() const;
+
+  _LIBCPP_HIDE_FROM_ABI str __create_str() { return str(__string_alloc_); }
+};
+
+} // namespace __stacktrace
+
+// (19.6.4)
+// Class template basic_stacktrace [stacktrace.basic]
+
+class stacktrace_entry;
+
+template <class _Allocator>
+class basic_stacktrace : private __stacktrace::base {
+  friend struct hash<basic_stacktrace<_Allocator>>;
+  friend struct __stacktrace::base;
+
+  using _ATraits _LIBCPP_NODEBUG            = allocator_traits<_Allocator>;
+  constexpr static bool __kPropOnCopyAssign = _ATraits::propagate_on_container_copy_assignment::value;
+  constexpr static bool __kPropOnMoveAssign = _ATraits::propagate_on_container_move_assignment::value;
+  constexpr static bool __kPropOnSwap       = _ATraits::propagate_on_container_swap::value;
+  constexpr static bool __kAlwaysEqual      = _ATraits::is_always_equal::value;
+  constexpr static bool __kNoThrowAlloc     = noexcept(noexcept(_Allocator().allocate(1)));
+
+  _LIBCPP_NO_UNIQUE_ADDRESS _Allocator __alloc_;
+
+  vector<stacktrace_entry, _Allocator> __entries_;
+  _LIBCPP_HIDE_FROM_ABI _EntryIters entry_iters() { return {__entries_.data(), __entries_.size()}; }
+  _LIBCPP_HIDE_FROM_ABI __stacktrace::entry_base& entry_append() {
+    return (__stacktrace::entry_base&)__entries_.emplace_back();
+  }
+
+  _LIBCPP_HIDE_FROM_ABI auto entry_iters_fn() {
+    return [this] -> _EntryIters { return entry_iters(); };
+  }
+  _LIBCPP_HIDE_FROM_ABI auto entry_append_fn() {
+    return [this] -> __stacktrace::entry_base& { return entry_append(); };
+  }
+
+public:
+  // (19.6.4.1)
+  // Overview [stacktrace.basic.overview]
+
+  using value_type             = stacktrace_entry;
+  using const_reference        = value_type const&;
+  using reference              = value_type&;
+  using difference_type        = ptrdiff_t;
+  using size_type              = size_t;
+  using allocator_type         = _Allocator;
+  using iterator               = decltype(__entries_.begin());
+  using const_iterator         = decltype(__entries_.cbegin());
+  using reverse_iterator       = decltype(__entries_.rbegin());
+  using const_reverse_iterator = decltype(__entries_.crbegin());
----------------
philnik777 wrote:

Why does this differ from the standard wording?

https://github.com/llvm/llvm-project/pull/136528


More information about the libcxx-commits mailing list