• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___AVAILABILITY
11#define _LIBCPP___AVAILABILITY
12
13#include <__config>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#  pragma GCC system_header
17#endif
18
19// Libc++ is shipped by various vendors. In particular, it is used as a system
20// library on macOS, iOS and other Apple platforms. In order for users to be
21// able to compile a binary that is intended to be deployed to an older version
22// of a platform, Clang provides availability attributes [1]. These attributes
23// can be placed on declarations and are used to describe the life cycle of a
24// symbol in the library.
25//
26// The main goal is to ensure a compile-time error if a symbol that hasn't been
27// introduced in a previously released library is used in a program that targets
28// that previously released library. Normally, this would be a load-time error
29// when one tries to launch the program against the older library.
30//
31// For example, the filesystem library was introduced in the dylib in macOS 10.15.
32// If a user compiles on a macOS 10.15 host but targets macOS 10.13 with their
33// program, the compiler would normally not complain (because the required
34// declarations are in the headers), but the dynamic loader would fail to find
35// the symbols when actually trying to launch the program on macOS 10.13. To
36// turn this into a compile-time issue instead, declarations are annotated with
37// when they were introduced, and the compiler can produce a diagnostic if the
38// program references something that isn't available on the deployment target.
39//
40// This mechanism is general in nature, and any vendor can add their markup to
41// the library (see below). Whenever a new feature is added that requires support
42// in the shared library, two macros are added below to allow marking the feature
43// as unavailable:
44// 1. A macro named `_LIBCPP_AVAILABILITY_HAS_NO_<feature>` which must be defined
45//    exactly when compiling for a target that doesn't support the feature.
46// 2. A macro named `_LIBCPP_AVAILABILITY_<feature>`, which must always be defined
47//    and must expand to the proper availability attribute for the platform.
48//
49// When vendors decide to ship the feature as part of their shared library, they
50// can update these macros appropriately for their platform, and the library will
51// use those to provide an optimal user experience.
52//
53// Furthermore, many features in the standard library have corresponding
54// feature-test macros. The `_LIBCPP_AVAILABILITY_HAS_NO_<feature>` macros
55// are checked by the corresponding feature-test macros generated by
56// generate_feature_test_macro_components.py to ensure that the library
57// doesn't announce a feature as being implemented if it is unavailable on
58// the deployment target.
59//
60// Note that this mechanism is disabled by default in the "upstream" libc++.
61// Availability annotations are only meaningful when shipping libc++ inside
62// a platform (i.e. as a system library), and so vendors that want them should
63// turn those annotations on at CMake configuration time.
64//
65// [1]: https://clang.llvm.org/docs/AttributeReference.html#availability
66
67
68// For backwards compatibility, allow users to define _LIBCPP_DISABLE_AVAILABILITY
69// for a while.
70#if defined(_LIBCPP_DISABLE_AVAILABILITY)
71#   if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
72#       define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS
73#   endif
74#endif
75
76// Availability markup is disabled when building the library, or when the compiler
77// doesn't support the proper attributes.
78#if defined(_LIBCPP_BUILDING_LIBRARY) ||                                        \
79    defined(_LIBCXXABI_BUILDING_LIBRARY) ||                                     \
80    !__has_feature(attribute_availability_with_strict) ||                       \
81    !__has_feature(attribute_availability_in_templates) ||                      \
82    !__has_extension(pragma_clang_attribute_external_declaration)
83#   if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
84#       define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS
85#   endif
86#endif
87
88#if defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
89
90// These macros control the availability of std::bad_optional_access and
91// other exception types. These were put in the shared library to prevent
92// code bloat from every user program defining the vtable for these exception
93// types.
94//
95// Note that when exceptions are disabled, the methods that normally throw
96// these exceptions can be used even on older deployment targets, but those
97// methods will abort instead of throwing.
98#  define _LIBCPP_AVAILABILITY_HAS_BAD_OPTIONAL_ACCESS 1
99#  define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
100
101#  define _LIBCPP_AVAILABILITY_HAS_BAD_VARIANT_ACCESS 1
102#  define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
103
104#  define _LIBCPP_AVAILABILITY_HAS_BAD_ANY_CAST 1
105#  define _LIBCPP_AVAILABILITY_BAD_ANY_CAST
106
107// These macros control the availability of all parts of <filesystem> that
108// depend on something in the dylib.
109#  define _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY 1
110#  define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
111#  define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH
112#  define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP
113
114// This controls the availability of floating-point std::to_chars functions.
115// These overloads were added later than the integer overloads.
116#  define _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT 1
117#  define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT
118
119// This controls the availability of the C++20 synchronization library,
120// which requires shared library support for various operations
121// (see libcxx/src/atomic.cpp). This includes <barier>, <latch>,
122// <semaphore>, and notification functions on std::atomic.
123#  define _LIBCPP_AVAILABILITY_HAS_SYNC 1
124#  define _LIBCPP_AVAILABILITY_SYNC
125
126// This controls whether the library claims to provide a default verbose
127// termination function, and consequently whether the headers will try
128// to use it when the mechanism isn't overriden at compile-time.
129#  define _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT 1
130#  define _LIBCPP_AVAILABILITY_VERBOSE_ABORT
131
132// This controls the availability of the C++17 std::pmr library,
133// which is implemented in large part in the built library.
134#  define _LIBCPP_AVAILABILITY_HAS_PMR 1
135#  define _LIBCPP_AVAILABILITY_PMR
136
137// This controls the availability of the C++20 time zone database.
138// The parser code is built in the library.
139#  define _LIBCPP_AVAILABILITY_HAS_TZDB 1
140#  define _LIBCPP_AVAILABILITY_TZDB
141
142// Enable additional explicit instantiations of iostreams components. This
143// reduces the number of weak definitions generated in programs that use
144// iostreams by providing a single strong definition in the shared library.
145//
146// TODO: Enable additional explicit instantiations on GCC once it supports exclude_from_explicit_instantiation,
147//       or once libc++ doesn't use the attribute anymore.
148// TODO: Enable them on Windows once https://llvm.org/PR41018 has been fixed.
149#  if !defined(_LIBCPP_COMPILER_GCC) && !defined(_WIN32)
150#    define _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 1
151#  else
152#    define _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 0
153#  endif
154
155#elif defined(__APPLE__)
156
157#  define _LIBCPP_AVAILABILITY_HAS_BAD_OPTIONAL_ACCESS                                                                 \
158    (!defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) || __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 50000)
159
160#  define _LIBCPP_AVAILABILITY_HAS_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_HAS_BAD_OPTIONAL_ACCESS
161#  define _LIBCPP_AVAILABILITY_HAS_BAD_ANY_CAST _LIBCPP_AVAILABILITY_HAS_BAD_OPTIONAL_ACCESS
162
163#  define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((availability(watchos,strict,introduced=5.0)))
164#  define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
165#  define _LIBCPP_AVAILABILITY_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
166
167// <filesystem>
168#  if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) ||   \
169      (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \
170      (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) ||         \
171      (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000)
172#    define _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY 0
173#  else
174#    define _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY 1
175#  endif
176#   define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY                              \
177        __attribute__((availability(macos,strict,introduced=10.15)))            \
178        __attribute__((availability(ios,strict,introduced=13.0)))               \
179        __attribute__((availability(tvos,strict,introduced=13.0)))              \
180        __attribute__((availability(watchos,strict,introduced=6.0)))
181#   define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH                                 \
182        _Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \
183        _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))")    \
184        _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))")   \
185        _Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))")
186#   define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP                                  \
187        _Pragma("clang attribute pop")                                          \
188        _Pragma("clang attribute pop")                                          \
189        _Pragma("clang attribute pop")                                          \
190        _Pragma("clang attribute pop")
191
192// std::to_chars(floating-point)
193#  if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 130300) ||   \
194      (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 160300) || \
195      (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 160300) ||         \
196      (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 90300)
197#    define _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT 0
198#  else
199#    define _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT 1
200#  endif
201#   define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT                         \
202        __attribute__((availability(macos,strict,introduced=13.3)))             \
203        __attribute__((availability(ios,strict,introduced=16.3)))               \
204        __attribute__((availability(tvos,strict,introduced=16.3)))              \
205        __attribute__((availability(watchos,strict,introduced=9.3)))
206
207    // c++20 synchronization library
208#   if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) ||   \
209       (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \
210       (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 140000) ||         \
211       (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 70000)
212#    define _LIBCPP_AVAILABILITY_HAS_SYNC 0
213#  else
214#    define _LIBCPP_AVAILABILITY_HAS_SYNC 1
215#   endif
216#   define _LIBCPP_AVAILABILITY_SYNC                                            \
217        __attribute__((availability(macos,strict,introduced=11.0)))             \
218        __attribute__((availability(ios,strict,introduced=14.0)))               \
219        __attribute__((availability(tvos,strict,introduced=14.0)))              \
220        __attribute__((availability(watchos,strict,introduced=7.0)))
221
222// __libcpp_verbose_abort
223// TODO: Update once this is released
224#  define _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT 0
225
226#   define _LIBCPP_AVAILABILITY_VERBOSE_ABORT                                   \
227        __attribute__((unavailable))
228
229// std::pmr
230#  if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 140000) ||   \
231      (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 170000) || \
232      (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 170000) ||         \
233      (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 100000)
234#    define _LIBCPP_AVAILABILITY_HAS_PMR 0
235#  else
236#    define _LIBCPP_AVAILABILITY_HAS_PMR 1
237#  endif
238// TODO: Enable std::pmr markup once https://github.com/llvm/llvm-project/issues/40340 has been fixed
239//       Until then, it is possible for folks to try to use `std::pmr` when back-deploying to targets that don't support
240//       it and it'll be a load-time error, but we don't have a good alternative because the library won't compile if we
241//       use availability annotations until that bug has been fixed.
242#  if 0
243#    define _LIBCPP_AVAILABILITY_PMR                                                                                   \
244      __attribute__((availability(macos, strict, introduced = 14.0)))                                                  \
245      __attribute__((availability(ios, strict, introduced = 17.0)))                                                    \
246      __attribute__((availability(tvos, strict, introduced = 17.0)))                                                   \
247      __attribute__((availability(watchos, strict, introduced = 10.0)))
248#  else
249#    define _LIBCPP_AVAILABILITY_PMR
250#  endif
251
252#  define _LIBCPP_AVAILABILITY_HAS_TZDB 0
253#  define _LIBCPP_AVAILABILITY_TZDB __attribute__((unavailable))
254
255#  if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 120000)   || \
256      (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 150000) || \
257      (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 150000)         || \
258      (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 80000)
259#    define _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 0
260#  else
261#    define _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 1
262#  endif
263#else
264
265// ...New vendors can add availability markup here...
266
267#   error "It looks like you're trying to enable vendor availability markup, but you haven't defined the corresponding macros yet!"
268
269#endif
270
271// Define availability attributes that depend on _LIBCPP_HAS_NO_EXCEPTIONS.
272// Those are defined in terms of the availability attributes above, and
273// should not be vendor-specific.
274#if defined(_LIBCPP_HAS_NO_EXCEPTIONS)
275#   define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
276#   define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
277#   define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
278#else
279#   define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST        _LIBCPP_AVAILABILITY_BAD_ANY_CAST
280#   define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
281#   define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS  _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
282#endif
283
284#endif // _LIBCPP___AVAILABILITY
285