Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions libcxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,20 @@ config_define(${LIBCXX_ENABLE_WIDE_CHARACTERS} _LIBCPP_HAS_WIDE_CHARACTERS)
config_define(${LIBCXX_ENABLE_TIME_ZONE_DATABASE} _LIBCPP_HAS_TIME_ZONE_DATABASE)
config_define(${LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS} _LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS)

if (LIBCXX_CXX_ABI STREQUAL "none")
config_define(1 _LIBCPP_CXX_ABI_NONE)
elseif (LIBCXX_CXX_ABI STREQUAL "libcxxabi" OR LIBCXX_CXX_ABI STREQUAL "system-libcxxabi")
config_define(1 _LIBCPP_CXX_ABI_LIBCXXABI)
elseif (LIBCXX_CXX_ABI STREQUAL "libcxxrt")
config_define(1 _LIBCPP_CXX_ABI_LIBCXXRT)
elseif (LIBCXX_CXX_ABI STREQUAL "libstdc++")
config_define(1 _LIBCPP_CXX_ABI_LIBSTDCXX)
elseif (LIBCXX_CXX_ABI STREQUAL "libsupc++")
config_define(1 _LIBCPP_CXX_ABI_LIBSUPCXX)
elseif (LIBCXX_CXX_ABI STREQUAL "vcruntime")
config_define(1 _LIBCPP_CXX_ABI_VCRUNTIME)
endif()

# TODO: Remove in LLVM 21. We're leaving an error to make this fail explicitly.
if (LIBCXX_ENABLE_ASSERTIONS)
message(FATAL_ERROR "LIBCXX_ENABLE_ASSERTIONS has been removed. Please use LIBCXX_HARDENING_MODE instead.")
Expand Down
4 changes: 0 additions & 4 deletions libcxx/cmake/Modules/HandleLibCXXABI.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ elseif ("${LIBCXX_CXX_ABI}" STREQUAL "libsupc++")
elseif ("${LIBCXX_CXX_ABI}" STREQUAL "libcxxabi")
add_library(libcxx-abi-headers INTERFACE)
target_link_libraries(libcxx-abi-headers INTERFACE cxxabi-headers)
target_compile_definitions(libcxx-abi-headers INTERFACE "-DLIBCXX_BUILDING_LIBCXXABI")

if (TARGET cxxabi_shared)
add_library(libcxx-abi-shared INTERFACE)
Expand Down Expand Up @@ -156,7 +155,6 @@ elseif ("${LIBCXX_CXX_ABI}" STREQUAL "system-libcxxabi")

add_library(libcxx-abi-headers INTERFACE)
import_private_headers(libcxx-abi-headers "${LIBCXX_CXX_ABI_INCLUDE_PATHS}" "cxxabi.h;__cxxabi_config.h")
target_compile_definitions(libcxx-abi-headers INTERFACE "-DLIBCXX_BUILDING_LIBCXXABI")

import_shared_library(libcxx-abi-shared c++abi)
target_link_libraries(libcxx-abi-shared INTERFACE libcxx-abi-headers)
Expand All @@ -173,7 +171,6 @@ elseif ("${LIBCXX_CXX_ABI}" STREQUAL "libcxxrt")
add_library(libcxx-abi-headers INTERFACE)
import_private_headers(libcxx-abi-headers "${LIBCXX_CXX_ABI_INCLUDE_PATHS}"
"cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h")
target_compile_definitions(libcxx-abi-headers INTERFACE "-DLIBCXXRT")

import_shared_library(libcxx-abi-shared cxxrt)
target_link_libraries(libcxx-abi-shared INTERFACE libcxx-abi-headers)
Expand All @@ -191,7 +188,6 @@ elseif ("${LIBCXX_CXX_ABI}" STREQUAL "vcruntime")
# Don't link against any ABI library
elseif ("${LIBCXX_CXX_ABI}" STREQUAL "none")
add_library(libcxx-abi-headers INTERFACE)
target_compile_definitions(libcxx-abi-headers INTERFACE "-D_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY")

add_library(libcxx-abi-shared INTERFACE)
target_link_libraries(libcxx-abi-shared INTERFACE libcxx-abi-headers)
Expand Down
19 changes: 19 additions & 0 deletions libcxx/docs/DesignDocs/VisibilityMacros.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,25 @@ Visibility Macros
used on class templates. On classes it should only be used if the vtable
lives in the built library.

**_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE**
Mark a symbol as exported from the libc++ library, while still providing an
inlineable definition that can be used by the compiler for optimization
purposes.

To use this macro on a class method, define the method body
*outside* of the class definition and annotate that definition with
`_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE`. Make sure to include the
header in at least one translation unit linked into the libc++ library.

This macro works by applying `[[gnu::gnu_inline]] inline` to the funciton
in the header, thereby suppressing code generation while still allowing the
compiler to use the function for optimization purposes.
During the build of libc++, we trigger code generation by expanding the
macro to `/*empty*/`. Since the function is no longer marked as `inline`,
it will be emitted even if not called. (For this reason its paramount to
not define methods in the class definition, since those definitions would
be implicitly `inline`.)

**_LIBCPP_OVERRIDABLE_FUNC_VIS**
Mark a symbol as being exported by the libc++ library, but allow it to be
overridden locally. On non-Windows, this is equivalent to `_LIBCPP_FUNC_VIS`.
Expand Down
3 changes: 3 additions & 0 deletions libcxx/docs/ReleaseNotes/22.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ Improvements and New Features

- The performance of ``std::find`` has been improved by up to 2x for integral types

- ``std::exception_ptr`` was optimized, allowing the compiler to generate better code especially for empty
``std::exception_ptr`` values.

Deprecations and Removals
-------------------------

Expand Down
4 changes: 4 additions & 0 deletions libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,10 @@ set(files
__debug_utils/strict_weak_ordering_check.h
__exception/exception.h
__exception/exception_ptr.h
__exception/exception_ptr_cxxabi.ipp
__exception/exception_ptr_glibcxx.ipp
__exception/exception_ptr_msvc.ipp
__exception/exception_ptr_unimplemented.ipp
__exception/nested_exception.h
__exception/operations.h
__exception/terminate.h
Expand Down
8 changes: 8 additions & 0 deletions libcxx/include/__config_site.in
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@
#cmakedefine01 _LIBCPP_HAS_TIME_ZONE_DATABASE
#cmakedefine01 _LIBCPP_INSTRUMENTED_WITH_ASAN

// LIBCXX_CXX_ABI backends
#cmakedefine _LIBCPP_CXX_ABI_NONE
#cmakedefine _LIBCPP_CXX_ABI_LIBCXXABI
#cmakedefine _LIBCPP_CXX_ABI_LIBCXXRT
#cmakedefine _LIBCPP_CXX_ABI_LIBSTDCXX
#cmakedefine _LIBCPP_CXX_ABI_LIBSUPCXX
#cmakedefine _LIBCPP_CXX_ABI_VCRUNTIME

// PSTL backends
#cmakedefine _LIBCPP_PSTL_BACKEND_SERIAL
#cmakedefine _LIBCPP_PSTL_BACKEND_STD_THREAD
Expand Down
136 changes: 112 additions & 24 deletions libcxx/include/__exception/exception_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,37 @@
#include <__memory/construct_at.h>
#include <__type_traits/decay.h>
#include <__type_traits/is_pointer.h>
#include <__verbose_abort> // used by exception_ptr_{unimplemented,cxxabi}.ipp
#include <cstdlib>
#include <typeinfo>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

#ifndef _LIBCPP_ABI_MICROSOFT
// Previously, parts of exception_ptr were defined out-of-line, which prevented
// useful compiler optimizations. Changing the out-of-line definitions to inline
// definitions is an ABI break, however. To prevent this, we have to make sure
// the symbols remain available in the libc++ library, in addition to being
// defined inline here in this header.
// To this end, we use _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE macro:
// The macro is defined as empty for src/exception.cpp, forcing the definitions of
// the functions to be emitted and included in the library. When users of libc++
// compile their code, the __gnu_inline__ attribute will suppress generation of
// these functions while making their definitions available for inlining.
#ifdef _LIBCPP_EMIT_CODE_FOR_EXCEPTION_PTR
# define _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE _LIBCPP_EXPORTED_FROM_ABI
#else
# if !__has_cpp_attribute(__gnu__::__gnu_inline__)
# error "GNU inline attribute is not supported"
# endif
# define _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE [[__gnu__::__gnu_inline__]] inline
#endif

# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgnu-inline-cpp-without-extern")

#ifdef _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION

namespace __cxxabiv1 {

Expand All @@ -49,18 +70,25 @@ _LIBCPP_OVERRIDABLE_FUNC_VIS __cxa_exception* __cxa_init_primary_exception(

} // namespace __cxxabiv1

# endif

#endif

_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD

#ifndef _LIBCPP_ABI_MICROSOFT
class _LIBCPP_EXPORTED_FROM_ABI exception_ptr;
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr current_exception() _NOEXCEPT;
[[__noreturn__]] _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE void rethrow_exception(exception_ptr);

#ifndef _LIBCPP_CXX_ABI_VCRUNTIME

class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
void* __ptr_;

static exception_ptr __from_native_exception_pointer(void*) _NOEXCEPT;
// Customization points to adjust the reference counting for cxxabi or
// libsupc++/libstdc++
_LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static void __increment_refcount(void* __ptr) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE static void __decrement_refcount(void* __ptr) _NOEXCEPT;

_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE static exception_ptr __from_native_exception_pointer(void*) _NOEXCEPT;

template <class _Ep>
friend _LIBCPP_HIDE_FROM_ABI exception_ptr __make_exception_ptr_explicit(_Ep&) _NOEXCEPT;
Expand All @@ -74,9 +102,11 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
_LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {}
_LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}

exception_ptr(const exception_ptr&) _NOEXCEPT;
exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
~exception_ptr() _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr(const exception_ptr&) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI exception_ptr(exception_ptr&&) _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI exception_ptr& operator=(exception_ptr&&) _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE ~exception_ptr() _NOEXCEPT;

_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_ != nullptr; }

Expand All @@ -88,10 +118,54 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
return !(__x == __y);
}

friend _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
friend _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
friend _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) {
void* __tmp = __x.__ptr_;
__x.__ptr_ = __y.__ptr_;
__y.__ptr_ = __tmp;
}

friend exception_ptr current_exception() _NOEXCEPT;
friend void rethrow_exception(exception_ptr);
};

// Must be defined outside the class definition due to _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) _NOEXCEPT {
__increment_refcount(__e);
exception_ptr __ptr;
__ptr.__ptr_ = __e;
return __ptr;
}

// Must be defined outside the class definition due to _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr::exception_ptr(const exception_ptr& __other) _NOEXCEPT
: __ptr_(__other.__ptr_) {
__increment_refcount(__ptr_);
}

_LIBCPP_HIDE_FROM_ABI inline exception_ptr::exception_ptr(exception_ptr&& __other) _NOEXCEPT : __ptr_(__other.__ptr_) {
__other.__ptr_ = nullptr;
}

// Must be defined outside the class definition due to _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr& exception_ptr::operator=(const exception_ptr& __other) _NOEXCEPT {
if (__ptr_ != __other.__ptr_) {
__increment_refcount(__other.__ptr_);
__decrement_refcount(__ptr_);
__ptr_ = __other.__ptr_;
}
return *this;
}

_LIBCPP_HIDE_FROM_ABI inline exception_ptr& exception_ptr::operator=(exception_ptr&& __other) _NOEXCEPT {
__decrement_refcount(__ptr_);
__ptr_ = __other.__ptr_;
__other.__ptr_ = nullptr;
return *this;
}

// Must be defined outside the class definition due to _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr::~exception_ptr() _NOEXCEPT { __decrement_refcount(__ptr_); }

# if _LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
template <class _Ep>
Expand Down Expand Up @@ -159,34 +233,34 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep) _NOEXCEPT {

#else // _LIBCPP_ABI_MICROSOFT

class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
class exception_ptr {
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field")
void* __ptr1_;
void* __ptr2_;
_LIBCPP_DIAGNOSTIC_POP

public:
exception_ptr() _NOEXCEPT;
exception_ptr(nullptr_t) _NOEXCEPT;
exception_ptr(const exception_ptr& __other) _NOEXCEPT;
exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT;
exception_ptr& operator=(nullptr_t) _NOEXCEPT;
~exception_ptr() _NOEXCEPT;
explicit operator bool() const _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr() _NOEXCEPT;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not convinced this new macro is necessary. IIUC these functions are supposed to be inlined, so there isn't much point in providing an external version (except for ABI of course, but we don't need to use the dylib functions).

Copy link
Member Author

@vogelsgesang vogelsgesang Oct 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Full disclosure: This isn't actually my idea. It was yours (modulo potential misunderstandings on my side). It was originally proposed back in April 2022 in https://reviews.llvm.org/D122536. Happy to adjust it however you prefer

IIUC these functions are supposed to be inlined, so there isn't much point in providing an external version

correct

except for ABI of course

How should we ensure that the functions are still emitted as part of the dylib? Currently I rely on _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE to be marked inline in the headers but as non-inline in the dylib. By marking it non-inline in the dylib, I ensure that the compiler actually emits code for it. If I would mark them inline also in the dylib, the compiler wouldn't actually emit any code, since the functions are never called / instantiated by the dylib

except for ABI of course but we don't need to use the dylib functions

Right, I think we can let the compiler choose freely to either use the inlined or the dylib-provided version. This means we might not need [[gnu::inline]] / __attribute__((__gnu_inline__)).

I used it primarily because you proposed its usage back in April 2022 in https://reviews.llvm.org/D122536. It provides a slight benefit that the linker has less work to do (it doesn't have to discard many duplicated definitions of the same inline function). Not sure if we consider this to be worth it, though 🤷

_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr(nullptr_t) _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr(const exception_ptr& __other) _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr& operator=(nullptr_t) _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE ~exception_ptr() _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE explicit operator bool() const _NOEXCEPT;
};

_LIBCPP_EXPORTED_FROM_ABI bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT;

inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {
return !(__x == __y);
}

_LIBCPP_EXPORTED_FROM_ABI void swap(exception_ptr&, exception_ptr&) _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE void swap(exception_ptr&, exception_ptr&) _NOEXCEPT;

_LIBCPP_EXPORTED_FROM_ABI exception_ptr __copy_exception_ptr(void* __except, const void* __ptr);
_LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
[[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr __copy_exception_ptr(void* __except, const void* __ptr);
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr current_exception() _NOEXCEPT;
[[__noreturn__]] _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE void rethrow_exception(exception_ptr);

// This is a built-in template function which automagically extracts the required
// information.
Expand All @@ -201,4 +275,18 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
#endif // _LIBCPP_ABI_MICROSOFT
_LIBCPP_END_UNVERSIONED_NAMESPACE_STD

#if defined(_LIBCPP_CXX_ABI_NONE)
# include <__exception/exception_ptr_unimplemented.ipp>
#elif defined(_LIBCPP_CXX_ABI_LIBCXXABI) || defined(_LIBCPP_CXX_ABI_LIBCXXRT)
# include <__exception/exception_ptr_cxxabi.ipp>
#elif defined(_LIBCPP_CXX_ABI_LIBSTDCXX) || defined(_LIBCPP_CXX_ABI_LIBSUPCXX)
# include <__exception/exception_ptr_glibcxx.ipp>
#elif defined(_LIBCPP_CXX_ABI_VCRUNTIME)
# include <__exception/exception_ptr_msvc.ipp>
#else
# error "Unsupported C++ ABI library"
#endif

_LIBCPP_DIAGNOSTIC_POP

#endif // _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
48 changes: 48 additions & 0 deletions libcxx/include/__exception/exception_ptr_cxxabi.ipp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// -*- 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
//
//===----------------------------------------------------------------------===//

namespace __cxxabiv1 {

extern "C" {
_LIBCPP_OVERRIDABLE_FUNC_VIS void __cxa_increment_exception_refcount(void*) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void __cxa_decrement_exception_refcount(void*) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void* __cxa_current_primary_exception() _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void __cxa_rethrow_primary_exception(void*);
}

} // namespace __cxxabiv1

namespace std {

_LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE inline void exception_ptr::__increment_refcount(void* __ptr) _NOEXCEPT {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't spray always_inline everywhere.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only added it to exception_ptr::__{increment,decrement}_refcount since this was a net-new indirection which I introduced also into already pre-existing functions (such as exception_ptr::~exception_ptr) and I considered it to be less risky if I mark this indirection with _LIBCPP_ALWAYS_INLINE to make sure the compiler actually removes that indirection again.

That being said, I guess I was overly careful here. I will remove it

if (__ptr)
__cxxabiv1::__cxa_increment_exception_refcount(__ptr);
}

_LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE inline void exception_ptr::__decrement_refcount(void* __ptr) _NOEXCEPT {
if (__ptr)
__cxxabiv1::__cxa_decrement_exception_refcount(__ptr);
}

_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr current_exception() _NOEXCEPT {
// It would be nicer if there was a constructor that took a ptr, then
// this whole function would be just:
// return exception_ptr(__cxa_current_primary_exception());
exception_ptr __ptr;
__ptr.__ptr_ = __cxxabiv1::__cxa_current_primary_exception();
return __ptr;
}

_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE void rethrow_exception(exception_ptr __ptr) {
__cxxabiv1::__cxa_rethrow_primary_exception(__ptr.__ptr_);
// if __ptr.__ptr_ is NULL, above returns so we terminate.
_LIBCPP_VERBOSE_ABORT("tried to rethrow an empty exception_ptr\n");
}

} // namespace std
Loading
Loading