llvm-project/libcxx/include/__availability

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

317 lines
17 KiB
Plaintext
Raw Normal View History

// -*- 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___AVAILABILITY
#define _LIBCPP___AVAILABILITY
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
// Libc++ is shipped by various vendors. In particular, it is used as a system
// library on macOS, iOS and other Apple platforms. In order for users to be
// able to compile a binary that is intended to be deployed to an older version
// of a platform, Clang provides availability attributes [1]. These attributes
// can be placed on declarations and are used to describe the life cycle of a
// symbol in the library.
//
// The main goal is to ensure a compile-time error if a symbol that hasn't been
// introduced in a previously released library is used in a program that targets
// that previously released library. Normally, this would be a load-time error
// when one tries to launch the program against the older library.
//
// For example, the filesystem library was introduced in the dylib in macOS 10.15.
// If a user compiles on a macOS 10.15 host but targets macOS 10.13 with their
// program, the compiler would normally not complain (because the required
// declarations are in the headers), but the dynamic loader would fail to find
// the symbols when actually trying to launch the program on macOS 10.13. To
// turn this into a compile-time issue instead, declarations are annotated with
// when they were introduced, and the compiler can produce a diagnostic if the
// program references something that isn't available on the deployment target.
//
// This mechanism is general in nature, and any vendor can add their markup to
// the library (see below). Whenever a new feature is added that requires support
// in the shared library, a macro should be added below to mark this feature
// as unavailable. When vendors decide to ship the feature as part of their
// shared library, they can update the markup appropriately.
//
// Furthermore, many features in the standard library have corresponding
// feature-test macros. When a feature is made unavailable on some deployment
// target, a macro should be defined to signal that it is unavailable. That
// macro can then be picked up when feature-test macros are generated (see
// generate_feature_test_macro_components.py) to make sure that feature-test
// macros don't announce a feature as being implemented if it has been marked
// as unavailable.
//
// Note that this mechanism is disabled by default in the "upstream" libc++.
// Availability annotations are only meaningful when shipping libc++ inside
// a platform (i.e. as a system library), and so vendors that want them should
// turn those annotations on at CMake configuration time.
//
// [1]: https://clang.llvm.org/docs/AttributeReference.html#availability
// For backwards compatibility, allow users to define _LIBCPP_DISABLE_AVAILABILITY
// for a while.
#if defined(_LIBCPP_DISABLE_AVAILABILITY)
# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS
# endif
#endif
// Availability markup is disabled when building the library, or when the compiler
// doesn't support the proper attributes.
#if defined(_LIBCPP_BUILDING_LIBRARY) || \
defined(_LIBCXXABI_BUILDING_LIBRARY) || \
!__has_feature(attribute_availability_with_strict) || \
!__has_feature(attribute_availability_in_templates) || \
!__has_extension(pragma_clang_attribute_external_declaration)
# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS
# endif
#endif
#if defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
// This controls the availability of std::shared_mutex and std::shared_timed_mutex,
// which were added to the dylib later.
# define _LIBCPP_AVAILABILITY_SHARED_MUTEX
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex
// These macros control the availability of std::bad_optional_access and
// other exception types. These were put in the shared library to prevent
// code bloat from every user program defining the vtable for these exception
// types.
//
// Note that when exceptions are disabled, the methods that normally throw
// these exceptions can be used even on older deployment targets, but those
// methods will abort instead of throwing.
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST
// This controls the availability of std::uncaught_exceptions().
# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS
// This controls the availability of the sized version of ::operator delete,
// ::operator delete[], and their align_val_t variants, which were all added
// in C++17, and hence not present in early dylibs.
# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE
// This controls the availability of the std::future_error exception.
//
// Note that when exceptions are disabled, the methods that normally throw
// std::future_error can be used even on older deployment targets, but those
// methods will abort instead of throwing.
# define _LIBCPP_AVAILABILITY_FUTURE_ERROR
// This controls the availability of std::type_info's vtable.
// I can't imagine how using std::type_info can work at all if
// this isn't supported.
# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE
// This controls the availability of std::locale::category members
// (e.g. std::locale::collate), which are defined in the dylib.
# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
// This controls the availability of atomic operations on std::shared_ptr
// (e.g. `std::atomic_store(std::shared_ptr)`), which require a shared
// lock table located in the dylib.
# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
// These macros control the availability of all parts of <filesystem> that
// depend on something in the dylib.
# define _LIBCPP_AVAILABILITY_FILESYSTEM
# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem
// This controls the availability of std::to_chars for integral arguments.
# define _LIBCPP_AVAILABILITY_TO_CHARS
Microsoft's floating-point to_chars powered by Ryu and Ryu Printf Microsoft would like to contribute its implementation of floating-point to_chars to libc++. This uses the impossibly fast Ryu and Ryu Printf algorithms invented by Ulf Adams at Google. Upstream repos: https://github.com/microsoft/STL and https://github.com/ulfjack/ryu . Licensing notes: MSVC's STL is available under the Apache License v2.0 with LLVM Exception, intentionally chosen to match libc++. We've used Ryu under the Boost Software License. This patch contains minor changes from Jorg Brown at Google, to adapt the code to libc++. He verified that it works in Google's Linux-based environment, but then I applied more changes on top of his, so any compiler errors are my fault. (I haven't tried to build and test libc++ yet.) Please tell me if we need to do anything else in order to follow https://llvm.org/docs/DeveloperPolicy.html#attribution-of-changes . Notes: * libc++'s integer charconv is unchanged (except for a small refactoring). MSVC's integer charconv hasn't been tuned for performance yet, so you're not missing anything. * Floating-point from_chars isn't part of this patch because Jorg found that MSVC's implementation (derived from our CRT's strtod) was slower than Abseil's. If you're unable to use Abseil or another implementation due to licensing or technical considerations, Microsoft would be delighted if you used MSVC's from_chars (and you can just take it, or ask us to provide a patch like this). Ulf is also working on a novel algorithm for from_chars. * This assumes that float is IEEE 32-bit, double is IEEE 64-bit, and long double is also IEEE 64-bit. * I have added MSVC's charconv tests (the whole thing: integer/floating from_chars/to_chars), but haven't adapted them to libcxx's harness at all. (These tests will be available in the microsoft/STL repo soon.) * Jorg added int128 codepaths. These were originally present in upstream Ryu, and I removed them from microsoft/STL purely for performance reasons (MSVC doesn't support int128; Clang on Windows does, but I found that x64 intrinsics were slightly faster). * The implementation is split into 3 headers. In MSVC's STL, charconv contains only Microsoft-written code. xcharconv_ryu.h contains code derived from Ryu (with significant modifications and additions). xcharconv_ryu_tables.h contains Ryu's large lookup tables (they were sufficiently large to make editing inconvenient, hence the separate file). The xmeow.h convention is MSVC's for internal headers; you may wish to rename them. * You should consider separately compiling the lookup tables (see https://github.com/microsoft/STL/issues/172 ) for compiler throughput and reduced object file size. * See https://github.com/StephanTLavavej/llvm-project/commits/charconv for fine-grained history. (If necessary, I can perform some rebase surgery to show you what Jorg changed relative to the microsoft/STL repo; currently that's all fused into the first commit.) Differential Revision: https://reviews.llvm.org/D70631
2021-02-10 00:52:41 +08:00
// This controls the availability of floating-point std::to_chars functions.
// These overloads were added later than the integer overloads.
# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT
// This controls the availability of the C++20 synchronization library,
// which requires shared library support for various operations
// (see libcxx/src/atomic.cpp). This includes <barier>, <latch>,
// <semaphore>, and notification functions on std::atomic.
# define _LIBCPP_AVAILABILITY_SYNC
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore
// This controls the availability of the C++20 format library.
// The library is in development and not ABI stable yet. P2216 is
// retroactively accepted in C++20. This paper contains ABI breaking
// changes.
# define _LIBCPP_AVAILABILITY_FORMAT
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
[libc++] Add a lightweight overridable assertion handler This patch adds a lightweight assertion handler mechanism that can be overriden at link-time in a fashion similar to `operator new`. This is a third take on https://llvm.org/D121123 (which allowed customizing the assertion handler at compile-time), and https://llvm.org/D119969 (which allowed customizing the assertion handler at runtime only). This approach is, I think, the best of all three explored approaches. Indeed, replacing the assertion handler in user code is ergonomic, yet we retain the ability to provide a custom assertion handler when deploying to older platforms that don't have a default handler in the dylib. As-is, this patch provides a pretty good amount of backwards compatibility with the previous debug mode: - Code that used to set _LIBCPP_DEBUG=0 in order to get basic assertions in their code will still get basic assertions out of the box, but those assertions will be using the new assertion handler support. - Code that was previously compiled with references to __libcpp_debug_function and friends will work out-of-the-box, no changes required. This is because we provide the same symbols in the dylib as we used to. - Code that used to set a custom __libcpp_debug_function will stop compiling, because we don't provide that declaration anymore. Users will have to migrate to the new way of setting a custom assertion handler, which is extremely easy. I suspect that pool of users is very limited, so breaking them at compile-time is probably acceptable. The main downside of this approach is that code being compiled with assertions enabled but deploying to an older platform where the assertion handler didn't exist yet will fail to compile. However users can easily fix the problem by providing a custom assertion handler and defining the _LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED macro to let the library know about the custom handler. In a way, this is actually a feature because it avoids a load-time error that one would otherwise get when trying to run the code on the older target. Differential Revision: https://reviews.llvm.org/D121478
2022-03-04 06:37:03 +08:00
// This controls whether the std::__libcpp_assertion_handler default
// assertion handler is provided by the library.
//
// Note that when users provide their own custom assertion handler,
// it doesn't matter whether the dylib provides a default handler,
// and the availability markup can actually give a false positive
// diagnostic (it will think that no handler is provided, when in
// reality the user has provided their own).
//
// Users can pass -D_LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED
// to the compiler to tell the library to ignore the fact that the
// default handler isn't available on their deployment target. Note that
// defining this macro but failing to define a custom assertion handler
// will lead to a load-time error on back-deployment targets, so it
// should be avoided.
# define _LIBCPP_AVAILABILITY_DEFAULT_ASSERTION_HANDLER
#elif defined(__APPLE__)
# define _LIBCPP_AVAILABILITY_SHARED_MUTEX \
__attribute__((availability(macos,strict,introduced=10.12))) \
__attribute__((availability(ios,strict,introduced=10.0))) \
__attribute__((availability(tvos,strict,introduced=10.0))) \
__attribute__((availability(watchos,strict,introduced=3.0)))
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
(defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \
(defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000)
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex
# endif
// Note: bad_optional_access & friends were not introduced in the matching
// macOS and iOS versions, so the version mismatch between macOS and others
// is intended.
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \
__attribute__((availability(macos,strict,introduced=10.13))) \
__attribute__((availability(ios,strict,introduced=12.0))) \
__attribute__((availability(tvos,strict,introduced=12.0))) \
__attribute__((availability(watchos,strict,introduced=5.0)))
# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS \
_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \
_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \
__attribute__((availability(macos,strict,introduced=10.12))) \
__attribute__((availability(ios,strict,introduced=10.0))) \
__attribute__((availability(tvos,strict,introduced=10.0))) \
__attribute__((availability(watchos,strict,introduced=3.0)))
# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \
__attribute__((availability(macos,strict,introduced=10.12))) \
__attribute__((availability(ios,strict,introduced=10.0))) \
__attribute__((availability(tvos,strict,introduced=10.0))) \
__attribute__((availability(watchos,strict,introduced=3.0)))
# define _LIBCPP_AVAILABILITY_FUTURE_ERROR \
__attribute__((availability(ios,strict,introduced=6.0)))
# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \
__attribute__((availability(macos,strict,introduced=10.9))) \
__attribute__((availability(ios,strict,introduced=7.0)))
# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \
__attribute__((availability(macos,strict,introduced=10.9))) \
__attribute__((availability(ios,strict,introduced=7.0)))
# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \
__attribute__((availability(macos,strict,introduced=10.9))) \
__attribute__((availability(ios,strict,introduced=7.0)))
# define _LIBCPP_AVAILABILITY_FILESYSTEM \
__attribute__((availability(macos,strict,introduced=10.15))) \
__attribute__((availability(ios,strict,introduced=13.0))) \
__attribute__((availability(tvos,strict,introduced=13.0))) \
__attribute__((availability(watchos,strict,introduced=6.0)))
# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH \
_Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \
_Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \
_Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \
_Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))")
# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP \
_Pragma("clang attribute pop") \
_Pragma("clang attribute pop") \
_Pragma("clang attribute pop") \
_Pragma("clang attribute pop")
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \
(defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) || \
(defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000)
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem
# endif
# define _LIBCPP_AVAILABILITY_TO_CHARS \
_LIBCPP_AVAILABILITY_FILESYSTEM
Microsoft's floating-point to_chars powered by Ryu and Ryu Printf Microsoft would like to contribute its implementation of floating-point to_chars to libc++. This uses the impossibly fast Ryu and Ryu Printf algorithms invented by Ulf Adams at Google. Upstream repos: https://github.com/microsoft/STL and https://github.com/ulfjack/ryu . Licensing notes: MSVC's STL is available under the Apache License v2.0 with LLVM Exception, intentionally chosen to match libc++. We've used Ryu under the Boost Software License. This patch contains minor changes from Jorg Brown at Google, to adapt the code to libc++. He verified that it works in Google's Linux-based environment, but then I applied more changes on top of his, so any compiler errors are my fault. (I haven't tried to build and test libc++ yet.) Please tell me if we need to do anything else in order to follow https://llvm.org/docs/DeveloperPolicy.html#attribution-of-changes . Notes: * libc++'s integer charconv is unchanged (except for a small refactoring). MSVC's integer charconv hasn't been tuned for performance yet, so you're not missing anything. * Floating-point from_chars isn't part of this patch because Jorg found that MSVC's implementation (derived from our CRT's strtod) was slower than Abseil's. If you're unable to use Abseil or another implementation due to licensing or technical considerations, Microsoft would be delighted if you used MSVC's from_chars (and you can just take it, or ask us to provide a patch like this). Ulf is also working on a novel algorithm for from_chars. * This assumes that float is IEEE 32-bit, double is IEEE 64-bit, and long double is also IEEE 64-bit. * I have added MSVC's charconv tests (the whole thing: integer/floating from_chars/to_chars), but haven't adapted them to libcxx's harness at all. (These tests will be available in the microsoft/STL repo soon.) * Jorg added int128 codepaths. These were originally present in upstream Ryu, and I removed them from microsoft/STL purely for performance reasons (MSVC doesn't support int128; Clang on Windows does, but I found that x64 intrinsics were slightly faster). * The implementation is split into 3 headers. In MSVC's STL, charconv contains only Microsoft-written code. xcharconv_ryu.h contains code derived from Ryu (with significant modifications and additions). xcharconv_ryu_tables.h contains Ryu's large lookup tables (they were sufficiently large to make editing inconvenient, hence the separate file). The xmeow.h convention is MSVC's for internal headers; you may wish to rename them. * You should consider separately compiling the lookup tables (see https://github.com/microsoft/STL/issues/172 ) for compiler throughput and reduced object file size. * See https://github.com/StephanTLavavej/llvm-project/commits/charconv for fine-grained history. (If necessary, I can perform some rebase surgery to show you what Jorg changed relative to the microsoft/STL repo; currently that's all fused into the first commit.) Differential Revision: https://reviews.llvm.org/D70631
2021-02-10 00:52:41 +08:00
# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT \
__attribute__((unavailable))
# define _LIBCPP_AVAILABILITY_SYNC \
__attribute__((availability(macos,strict,introduced=11.0))) \
__attribute__((availability(ios,strict,introduced=14.0))) \
__attribute__((availability(tvos,strict,introduced=14.0))) \
__attribute__((availability(watchos,strict,introduced=7.0)))
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) || \
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \
(defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 140000) || \
(defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 70000)
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore
# endif
# define _LIBCPP_AVAILABILITY_FORMAT \
__attribute__((unavailable))
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
[libc++] Add a lightweight overridable assertion handler This patch adds a lightweight assertion handler mechanism that can be overriden at link-time in a fashion similar to `operator new`. This is a third take on https://llvm.org/D121123 (which allowed customizing the assertion handler at compile-time), and https://llvm.org/D119969 (which allowed customizing the assertion handler at runtime only). This approach is, I think, the best of all three explored approaches. Indeed, replacing the assertion handler in user code is ergonomic, yet we retain the ability to provide a custom assertion handler when deploying to older platforms that don't have a default handler in the dylib. As-is, this patch provides a pretty good amount of backwards compatibility with the previous debug mode: - Code that used to set _LIBCPP_DEBUG=0 in order to get basic assertions in their code will still get basic assertions out of the box, but those assertions will be using the new assertion handler support. - Code that was previously compiled with references to __libcpp_debug_function and friends will work out-of-the-box, no changes required. This is because we provide the same symbols in the dylib as we used to. - Code that used to set a custom __libcpp_debug_function will stop compiling, because we don't provide that declaration anymore. Users will have to migrate to the new way of setting a custom assertion handler, which is extremely easy. I suspect that pool of users is very limited, so breaking them at compile-time is probably acceptable. The main downside of this approach is that code being compiled with assertions enabled but deploying to an older platform where the assertion handler didn't exist yet will fail to compile. However users can easily fix the problem by providing a custom assertion handler and defining the _LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED macro to let the library know about the custom handler. In a way, this is actually a feature because it avoids a load-time error that one would otherwise get when trying to run the code on the older target. Differential Revision: https://reviews.llvm.org/D121478
2022-03-04 06:37:03 +08:00
# define _LIBCPP_AVAILABILITY_DEFAULT_ASSERTION_HANDLER \
__attribute__((unavailable))
#else
// ...New vendors can add availability markup here...
# error "It looks like you're trying to enable vendor availability markup, but you haven't defined the corresponding macros yet!"
#endif
// Define availability attributes that depend on _LIBCPP_NO_EXCEPTIONS.
// Those are defined in terms of the availability attributes above, and
// should not be vendor-specific.
#if defined(_LIBCPP_NO_EXCEPTIONS)
# define _LIBCPP_AVAILABILITY_FUTURE
# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
#else
# define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR
# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST
# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
#endif
[libc++] Add a lightweight overridable assertion handler This patch adds a lightweight assertion handler mechanism that can be overriden at link-time in a fashion similar to `operator new`. This is a third take on https://llvm.org/D121123 (which allowed customizing the assertion handler at compile-time), and https://llvm.org/D119969 (which allowed customizing the assertion handler at runtime only). This approach is, I think, the best of all three explored approaches. Indeed, replacing the assertion handler in user code is ergonomic, yet we retain the ability to provide a custom assertion handler when deploying to older platforms that don't have a default handler in the dylib. As-is, this patch provides a pretty good amount of backwards compatibility with the previous debug mode: - Code that used to set _LIBCPP_DEBUG=0 in order to get basic assertions in their code will still get basic assertions out of the box, but those assertions will be using the new assertion handler support. - Code that was previously compiled with references to __libcpp_debug_function and friends will work out-of-the-box, no changes required. This is because we provide the same symbols in the dylib as we used to. - Code that used to set a custom __libcpp_debug_function will stop compiling, because we don't provide that declaration anymore. Users will have to migrate to the new way of setting a custom assertion handler, which is extremely easy. I suspect that pool of users is very limited, so breaking them at compile-time is probably acceptable. The main downside of this approach is that code being compiled with assertions enabled but deploying to an older platform where the assertion handler didn't exist yet will fail to compile. However users can easily fix the problem by providing a custom assertion handler and defining the _LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED macro to let the library know about the custom handler. In a way, this is actually a feature because it avoids a load-time error that one would otherwise get when trying to run the code on the older target. Differential Revision: https://reviews.llvm.org/D121478
2022-03-04 06:37:03 +08:00
// Define the special assertion handler availability attribute, which can be silenced by
// users if they provide their own custom assertion handler. The rest of the code should
// not use the *_DEFAULT_* macro directly, since that would make it ignore the fact that
// the user provided a custom handler.
#if defined(_LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED)
# define _LIBCPP_AVAILABILITY_ASSERTION_HANDLER /* nothing */
#else
# define _LIBCPP_AVAILABILITY_ASSERTION_HANDLER _LIBCPP_AVAILABILITY_DEFAULT_ASSERTION_HANDLER
#endif
#endif // _LIBCPP___AVAILABILITY