[libc++] Introduce the notion of a minimum header version (#166074)
Introducing the notion of a minimum header version has multiple benefits. It allows us to merge a bunch of ABI macros into a single one. This makes configuring the library significantly easier, since, for a stable ABI, you only need to know which version you started distributing the library with, instead of checking which ABI flags have been introduced at what point. For platforms which have a moving window of the minimum version a program has been compiled against, this also makes it simple to remove symbols from the dylib when they can't be used by any program anymore.
This commit is contained in:
parent
ddb706bbb0
commit
484ee42096
@ -218,6 +218,9 @@ set(LIBCXX_ABI_NAMESPACE "__${LIBCXX_ABI_VERSION}" CACHE STRING "The inline ABI
|
||||
if (NOT LIBCXX_ABI_NAMESPACE MATCHES "__.*")
|
||||
message(FATAL_ERROR "LIBCXX_ABI_NAMESPACE must be a reserved identifier, got '${LIBCXX_ABI_NAMESPACE}'.")
|
||||
endif()
|
||||
set(LIBCXX_AVAILABILITY_MINIMUM_HEADER_VERSION "2" CACHE STRING
|
||||
"Minimum version of the libc++ headers that are allowed to be used by binaries linked against the libc++ library. This
|
||||
version must correspond to the major version of an LLVM release.")
|
||||
option(LIBCXX_ABI_FORCE_ITANIUM "Ignore auto-detection and force use of the Itanium ABI.")
|
||||
option(LIBCXX_ABI_FORCE_MICROSOFT "Ignore auto-detection and force use of the Microsoft ABI.")
|
||||
|
||||
@ -536,6 +539,7 @@ function(cxx_add_basic_build_flags target)
|
||||
# Let the library headers know they are currently being used to build the
|
||||
# library.
|
||||
target_compile_definitions(${target} PRIVATE -D_LIBCPP_BUILDING_LIBRARY)
|
||||
target_compile_definitions(${target} PRIVATE -D_LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION=${LIBCXX_AVAILABILITY_MINIMUM_HEADER_VERSION})
|
||||
|
||||
# Make sure the library can be build without transitive includes. This makes
|
||||
# it easier to upgrade the library to a newer language standard without build
|
||||
|
||||
@ -114,28 +114,6 @@ hand, backwards compatibility is generally guaranteed.
|
||||
|
||||
There are multiple ABI flags that change the symbols exported from the built library:
|
||||
|
||||
``_LIBCPP_ABI_DO_NOT_EXPORT_ALIGN``
|
||||
-------------------------------------------------
|
||||
This removes ``std::align()`` from the built library. In the past, ``std::align()`` was defined in the built library,
|
||||
but nowadays it is an inline function defined in the headers for performance reasons.
|
||||
|
||||
``_LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON``
|
||||
-------------------------------------------------
|
||||
This removes ``__basic_string_common<true>::__throw_length_error()`` and
|
||||
``__basic_string_common<true>::__throw_out_of_range()``. These symbols have been used by ``basic_string`` in the past,
|
||||
but are not referenced from the headers anymore.
|
||||
|
||||
``_LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON``
|
||||
------------------------------------------------
|
||||
This removes ``__vector_base_common<true>::__throw_length_error()`` and
|
||||
``__vector_base_common<true>::__throw_out_of_range()``. These symbols have been used by ``vector`` in the past, but are
|
||||
not referenced from the headers anymore.
|
||||
|
||||
``_LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10``
|
||||
----------------------------------------------
|
||||
This removes ``__itoa::__u32toa()`` and ``__iota::__u64toa``. These symbols have been used by ``to_chars`` in the past,
|
||||
but are not referenced from the headers anymore.
|
||||
|
||||
``_LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION``
|
||||
-------------------------------------------------------
|
||||
This replaces the symbols that are exported for ``basic_string`` to avoid exporting functions which are likely to be
|
||||
|
||||
@ -341,6 +341,22 @@ The following options allow building libc++ for a different ABI version.
|
||||
This option generate and installs a linker script as ``libc++.so`` which
|
||||
links the correct ABI library.
|
||||
|
||||
.. option:: LIBCXX_AVAILABILITY_MINIMUM_HEADER_VERSION:STRING
|
||||
|
||||
**Default**: ``2``
|
||||
|
||||
This option configures the oldest version of the libc++ headers that the built
|
||||
library has to be compatible with. See the
|
||||
:ref:`minimum header version documentation<MinimumHeaderVersion>` for details.
|
||||
|
||||
.. option:: LIBCXXABI_AVAILABILITY_MINIMUM_HEADER_VERSION:STRING
|
||||
|
||||
**Default**: ``2``
|
||||
|
||||
This is the same as ``LIBCXX_AVAILABILITY_MINIMUM_HEADER_VERSION`` documented
|
||||
above, but for libc++abi. The two options should be set to the same value if
|
||||
libc++abi is used.
|
||||
|
||||
.. option:: LIBCXXABI_USE_LLVM_UNWINDER:BOOL
|
||||
|
||||
**Default**: ``ON``
|
||||
@ -643,3 +659,18 @@ if it is unavailable on the deployment target.
|
||||
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.
|
||||
|
||||
.. _MinimumHeaderVersion:
|
||||
|
||||
Minimum Header Version
|
||||
======================
|
||||
|
||||
In libc++ we add new functions and remove the use of other functions in the built library on a regular basis. To avoid
|
||||
breaking programs, we keep old functions in the built library as documented in our
|
||||
:ref:`header support policy<HeaderSupportPolicy>`. However, there are platforms where some of these functions could
|
||||
never be referenced, because that platform never provided headers which referenced these functions. To reduce the size
|
||||
of the built library on these platforms, libc++ provides the notion of a minimum header version. The minimum header
|
||||
version describes the earliest version of the libc++ headers that can be used in a program linking against the library
|
||||
currently being built. Functions which have never been referenced in headers since the minimum header version are
|
||||
removed from the library. The minimum header version can be set with the CMake variables
|
||||
``LIBCXX_AVAILABILITY_MINIMUM_HEADER_VERSION`` and ``LIBCXXABI_AVAILABILITY_MINIMUM_HEADER_VERSION``.
|
||||
|
||||
@ -165,6 +165,11 @@ we don't make any guarantees. If you would like your compiler and/or platform
|
||||
to be formally supported and listed here, please work with the libc++ team to set
|
||||
up testing for your configuration.
|
||||
|
||||
.. _HeaderSupportPolicy:
|
||||
|
||||
Libc++ maintains backwards compatibility with programs compiled against older
|
||||
versions of the headers. The library can currently be configured by vendors to
|
||||
support headers from LLVM 2.8 or any later major release.
|
||||
|
||||
C++ Standards Conformance
|
||||
=========================
|
||||
|
||||
@ -372,16 +372,6 @@ typedef __char32_t char32_t;
|
||||
# endif
|
||||
# define _LIBCPP_HIDE_FROM_ABI_VIRTUAL _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
|
||||
|
||||
# ifdef _LIBCPP_BUILDING_LIBRARY
|
||||
# if _LIBCPP_ABI_VERSION > 1
|
||||
# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
|
||||
# else
|
||||
# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1
|
||||
# endif
|
||||
# else
|
||||
# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
|
||||
# endif
|
||||
|
||||
// Clang modules take a significant compile time hit when pushing and popping diagnostics.
|
||||
// Since all the headers are marked as system headers unless _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER is defined, we can
|
||||
// simply disable this pushing and popping when _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER isn't defined.
|
||||
|
||||
@ -64,10 +64,6 @@
|
||||
// These flags are documented in ABIGuarantees.rst
|
||||
# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
|
||||
# define _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
|
||||
# define _LIBCPP_ABI_DO_NOT_EXPORT_ALIGN
|
||||
# define _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON
|
||||
# define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
|
||||
# define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
|
||||
# define _LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI
|
||||
# define _LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI
|
||||
# define _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION
|
||||
@ -88,17 +84,6 @@
|
||||
# define _LIBCPP_ABI_TRIVIALLY_COPYABLE_BIT_ITERATOR
|
||||
|
||||
#elif _LIBCPP_ABI_VERSION == 1
|
||||
# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
|
||||
// Enable compiling copies of now inline methods into the dylib to support
|
||||
// applications compiled against older libraries. This is unnecessary with
|
||||
// COFF dllexport semantics, since dllexport forces a non-inline definition
|
||||
// of inline functions to be emitted anyway. Our own non-inline copy would
|
||||
// conflict with the dllexport-emitted copy, so we disable it. For XCOFF,
|
||||
// the linker will take issue with the symbols in the shared object if the
|
||||
// weak inline methods get visibility (such as from -fvisibility-inlines-hidden),
|
||||
// so disable it.
|
||||
# define _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS
|
||||
# endif
|
||||
// Feature macros for disabling pre ABI v1 features. All of these options
|
||||
// are deprecated.
|
||||
# if defined(__FreeBSD__)
|
||||
|
||||
@ -304,4 +304,11 @@
|
||||
# define _LIBCPP_AVAILABILITY_INIT_PRIMARY_EXCEPTION
|
||||
#endif
|
||||
|
||||
// Only define a bunch of symbols in the dylib if we need to be compatible with LLVM 7 headers or older
|
||||
# if defined(_LIBCPP_BUILDING_LIBRARY) && _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 8
|
||||
# define _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8
|
||||
# else
|
||||
# define _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 _LIBCPP_HIDE_FROM_ABI
|
||||
# endif
|
||||
|
||||
#endif // _LIBCPP___CONFIGURATION_AVAILABILITY_H
|
||||
|
||||
@ -53,7 +53,7 @@ public:
|
||||
typedef typename traits_type::off_type off_type;
|
||||
|
||||
// 27.7.2.2 Constructor/destructor:
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb) {
|
||||
this->init(__sb);
|
||||
}
|
||||
~basic_ostream() override;
|
||||
@ -67,7 +67,7 @@ protected:
|
||||
// 27.7.2.3 Assign/swap
|
||||
inline _LIBCPP_HIDE_FROM_ABI basic_ostream& operator=(basic_ostream&& __rhs);
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void swap(basic_ostream& __rhs) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void swap(basic_ostream& __rhs) {
|
||||
basic_ios<char_type, traits_type>::swap(__rhs);
|
||||
}
|
||||
|
||||
@ -76,17 +76,17 @@ public:
|
||||
class sentry;
|
||||
|
||||
// 27.7.2.6 Formatted output:
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&)) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&)) {
|
||||
return __pf(*this);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream&
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_ostream&
|
||||
operator<<(basic_ios<char_type, traits_type>& (*__pf)(basic_ios<char_type, traits_type>&)) {
|
||||
__pf(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& operator<<(ios_base& (*__pf)(ios_base&)) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_ostream& operator<<(ios_base& (*__pf)(ios_base&)) {
|
||||
__pf(*this);
|
||||
return *this;
|
||||
}
|
||||
@ -174,9 +174,9 @@ public:
|
||||
basic_ostream& flush();
|
||||
|
||||
// 27.7.2.5 seeks:
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 pos_type tellp();
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& seekp(pos_type __pos);
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& seekp(off_type __off, ios_base::seekdir __dir);
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 pos_type tellp();
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_ostream& seekp(pos_type __pos);
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_ostream& seekp(off_type __off, ios_base::seekdir __dir);
|
||||
|
||||
protected:
|
||||
_LIBCPP_HIDE_FROM_ABI basic_ostream() {} // extension, intentially does not initialize
|
||||
|
||||
@ -209,7 +209,7 @@ public:
|
||||
typedef typename traits_type::off_type off_type;
|
||||
|
||||
// 27.7.1.1.1 Constructor/destructor:
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit basic_istream(basic_streambuf<char_type, traits_type>* __sb)
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 explicit basic_istream(basic_streambuf<char_type, traits_type>* __sb)
|
||||
: __gc_(0) {
|
||||
this->init(__sb);
|
||||
}
|
||||
@ -221,7 +221,7 @@ protected:
|
||||
// 27.7.1.1.2 Assign/swap:
|
||||
inline _LIBCPP_HIDE_FROM_ABI basic_istream& operator=(basic_istream&& __rhs);
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void swap(basic_istream& __rhs) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void swap(basic_istream& __rhs) {
|
||||
std::swap(__gc_, __rhs.__gc_);
|
||||
basic_ios<char_type, traits_type>::swap(__rhs);
|
||||
}
|
||||
@ -234,17 +234,17 @@ public:
|
||||
class sentry;
|
||||
|
||||
// 27.7.1.2 Formatted input:
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&)) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&)) {
|
||||
return __pf(*this);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream&
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream&
|
||||
operator>>(basic_ios<char_type, traits_type>& (*__pf)(basic_ios<char_type, traits_type>&)) {
|
||||
__pf(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& operator>>(ios_base& (*__pf)(ios_base&)) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream& operator>>(ios_base& (*__pf)(ios_base&)) {
|
||||
__pf(*this);
|
||||
return *this;
|
||||
}
|
||||
@ -268,26 +268,26 @@ public:
|
||||
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI streamsize gcount() const { return __gc_; }
|
||||
int_type get();
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& get(char_type& __c) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream& get(char_type& __c) {
|
||||
int_type __ch = get();
|
||||
if (__ch != traits_type::eof())
|
||||
__c = traits_type::to_char_type(__ch);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& get(char_type* __s, streamsize __n) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream& get(char_type* __s, streamsize __n) {
|
||||
return get(__s, __n, this->widen('\n'));
|
||||
}
|
||||
|
||||
basic_istream& get(char_type* __s, streamsize __n, char_type __dlm);
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& get(basic_streambuf<char_type, traits_type>& __sb) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream& get(basic_streambuf<char_type, traits_type>& __sb) {
|
||||
return get(__sb, this->widen('\n'));
|
||||
}
|
||||
|
||||
basic_istream& get(basic_streambuf<char_type, traits_type>& __sb, char_type __dlm);
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& getline(char_type* __s, streamsize __n) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream& getline(char_type* __s, streamsize __n) {
|
||||
return getline(__s, __n, this->widen('\n'));
|
||||
}
|
||||
|
||||
@ -1184,7 +1184,7 @@ public:
|
||||
typedef typename traits_type::off_type off_type;
|
||||
|
||||
// constructor/destructor
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit basic_iostream(basic_streambuf<char_type, traits_type>* __sb)
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 explicit basic_iostream(basic_streambuf<char_type, traits_type>* __sb)
|
||||
: basic_istream<_CharT, _Traits>(__sb) {}
|
||||
|
||||
~basic_iostream() override;
|
||||
@ -1195,7 +1195,7 @@ protected:
|
||||
// assign/swap
|
||||
inline _LIBCPP_HIDE_FROM_ABI basic_iostream& operator=(basic_iostream&& __rhs);
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void swap(basic_iostream& __rhs) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void swap(basic_iostream& __rhs) {
|
||||
basic_istream<char_type, traits_type>::swap(__rhs);
|
||||
}
|
||||
};
|
||||
|
||||
@ -150,35 +150,35 @@ public:
|
||||
virtual ~basic_streambuf() {}
|
||||
|
||||
// 27.6.2.2.1 locales:
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 locale pubimbue(const locale& __loc) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 locale pubimbue(const locale& __loc) {
|
||||
imbue(__loc);
|
||||
locale __r = __loc_;
|
||||
__loc_ = __loc;
|
||||
return __r;
|
||||
}
|
||||
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 locale getloc() const { return __loc_; }
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 locale getloc() const { return __loc_; }
|
||||
|
||||
// 27.6.2.2.2 buffer and positioning:
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_streambuf* pubsetbuf(char_type* __s, streamsize __n) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_streambuf* pubsetbuf(char_type* __s, streamsize __n) {
|
||||
return setbuf(__s, __n);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 pos_type
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 pos_type
|
||||
pubseekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which = ios_base::in | ios_base::out) {
|
||||
return seekoff(__off, __way, __which);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 pos_type
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 pos_type
|
||||
pubseekpos(pos_type __sp, ios_base::openmode __which = ios_base::in | ios_base::out) {
|
||||
return seekpos(__sp, __which);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int pubsync() { return sync(); }
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 int pubsync() { return sync(); }
|
||||
|
||||
// Get and put areas:
|
||||
// 27.6.2.2.3 Get area:
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize in_avail() {
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 streamsize in_avail() {
|
||||
__check_invariants();
|
||||
auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
|
||||
|
||||
@ -187,7 +187,7 @@ public:
|
||||
return showmanyc();
|
||||
}
|
||||
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type snextc() {
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 int_type snextc() {
|
||||
__check_invariants();
|
||||
auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
|
||||
|
||||
@ -196,7 +196,7 @@ public:
|
||||
return sgetc();
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sbumpc() {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 int_type sbumpc() {
|
||||
__check_invariants();
|
||||
auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
|
||||
|
||||
@ -207,7 +207,7 @@ public:
|
||||
return __c;
|
||||
}
|
||||
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sgetc() {
|
||||
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 int_type sgetc() {
|
||||
__check_invariants();
|
||||
auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
|
||||
|
||||
@ -216,10 +216,10 @@ public:
|
||||
return traits_type::to_int_type(*gptr());
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize sgetn(char_type* __s, streamsize __n) { return xsgetn(__s, __n); }
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 streamsize sgetn(char_type* __s, streamsize __n) { return xsgetn(__s, __n); }
|
||||
|
||||
// 27.6.2.2.4 Putback:
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sputbackc(char_type __c) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 int_type sputbackc(char_type __c) {
|
||||
__check_invariants();
|
||||
auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
|
||||
|
||||
@ -229,7 +229,7 @@ public:
|
||||
return traits_type::to_int_type(*gptr());
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sungetc() {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 int_type sungetc() {
|
||||
__check_invariants();
|
||||
auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
|
||||
|
||||
@ -240,7 +240,7 @@ public:
|
||||
}
|
||||
|
||||
// 27.6.2.2.5 Put area:
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sputc(char_type __c) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 int_type sputc(char_type __c) {
|
||||
__check_invariants();
|
||||
auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
|
||||
|
||||
@ -251,7 +251,7 @@ public:
|
||||
return traits_type::to_int_type(__c);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize sputn(const char_type* __s, streamsize __n) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 streamsize sputn(const char_type* __s, streamsize __n) {
|
||||
return xsputn(__s, __n);
|
||||
}
|
||||
|
||||
@ -292,12 +292,12 @@ protected:
|
||||
_LIBCPP_HIDE_FROM_ABI char_type* gptr() const { return __ninp_; }
|
||||
_LIBCPP_HIDE_FROM_ABI char_type* egptr() const { return __einp_; }
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void gbump(int __n) { __ninp_ += __n; }
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void gbump(int __n) { __ninp_ += __n; }
|
||||
|
||||
// gbump takes an int, so it might not be able to represent the offset we want to add.
|
||||
_LIBCPP_HIDE_FROM_ABI void __gbump_ptrdiff(ptrdiff_t __n) { __ninp_ += __n; }
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) {
|
||||
_LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__gbeg, __gnext), "[gbeg, gnext) must be a valid range");
|
||||
_LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__gbeg, __gend), "[gbeg, gend) must be a valid range");
|
||||
_LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__gnext, __gend), "[gnext, gend) must be a valid range");
|
||||
@ -311,11 +311,11 @@ protected:
|
||||
_LIBCPP_HIDE_FROM_ABI char_type* pptr() const { return __nout_; }
|
||||
_LIBCPP_HIDE_FROM_ABI char_type* epptr() const { return __eout_; }
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void pbump(int __n) { __nout_ += __n; }
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void pbump(int __n) { __nout_ += __n; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI void __pbump(streamsize __n) { __nout_ += __n; }
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void setp(char_type* __pbeg, char_type* __pend) {
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void setp(char_type* __pbeg, char_type* __pend) {
|
||||
_LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__pbeg, __pend), "[pbeg, pend) must be a valid range");
|
||||
__bout_ = __nout_ = __pbeg;
|
||||
__eout_ = __pend;
|
||||
|
||||
@ -793,7 +793,7 @@ private:
|
||||
public:
|
||||
// construct/destroy:
|
||||
_LIBCPP_HIDE_FROM_ABI valarray() : __begin_(nullptr), __end_(nullptr) {}
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit valarray(size_t __n);
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 explicit valarray(size_t __n);
|
||||
_LIBCPP_HIDE_FROM_ABI valarray(const value_type& __x, size_t __n);
|
||||
valarray(const value_type* __p, size_t __n);
|
||||
valarray(const valarray& __v);
|
||||
@ -805,7 +805,7 @@ public:
|
||||
valarray(const gslice_array<value_type>& __ga);
|
||||
valarray(const mask_array<value_type>& __ma);
|
||||
valarray(const indirect_array<value_type>& __ia);
|
||||
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 ~valarray();
|
||||
inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 ~valarray();
|
||||
|
||||
// assignment:
|
||||
valarray& operator=(const valarray& __v);
|
||||
|
||||
@ -14,6 +14,8 @@ const char* bad_any_cast::what() const noexcept { return "bad any cast"; }
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 7
|
||||
|
||||
// Preserve std::experimental::any_bad_cast for ABI compatibility
|
||||
// Even though it no longer exists in a header file
|
||||
_LIBCPP_BEGIN_NAMESPACE_LFTS
|
||||
@ -25,4 +27,6 @@ public:
|
||||
|
||||
const char* bad_any_cast::what() const noexcept { return "bad any cast"; }
|
||||
|
||||
#endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_LFTS
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#ifndef _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
|
||||
#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 15
|
||||
|
||||
namespace __itoa {
|
||||
|
||||
@ -27,7 +27,7 @@ _LIBCPP_DIAGNOSTIC_POP
|
||||
|
||||
} // namespace __itoa
|
||||
|
||||
#endif // _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
|
||||
#endif // _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 15
|
||||
|
||||
// The original version of floating-point to_chars was written by Microsoft and
|
||||
// contributed with the following license.
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
#include <__config>
|
||||
#include <__thread/support.h>
|
||||
|
||||
#if _LIBCPP_ABI_VERSION == 1 || !_LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
|
||||
#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 9 || !_LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
|
||||
# define NEEDS_CONDVAR_DESTRUCTOR
|
||||
#endif
|
||||
|
||||
|
||||
@ -8,7 +8,9 @@
|
||||
|
||||
#include <__config>
|
||||
|
||||
#ifdef _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS
|
||||
// This has technically been removed in LLVM 3.4
|
||||
#if !defined(_LIBCPP_OBJECT_FORMAT_COFF) && !defined(_LIBCPP_OBJECT_FORMAT_XCOFF) && \
|
||||
_LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 4
|
||||
# define _LIBCPP_ERROR_CATEGORY_DEFINE_LEGACY_INLINE_FUNCTIONS
|
||||
#endif
|
||||
|
||||
|
||||
@ -7,7 +7,8 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <__config>
|
||||
#ifdef _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS
|
||||
#if !defined(_LIBCPP_OBJECT_FORMAT_COFF) && !defined(_LIBCPP_OBJECT_FORMAT_XCOFF) && \
|
||||
_LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 5
|
||||
# define _LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS
|
||||
#endif
|
||||
|
||||
@ -132,13 +133,16 @@ __sp_mut& __get_sp_mut(const void* p) {
|
||||
|
||||
#endif // _LIBCPP_HAS_THREADS
|
||||
|
||||
#if !defined(_LIBCPP_ABI_DO_NOT_EXPORT_ALIGN)
|
||||
#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 21
|
||||
|
||||
_LIBCPP_EXPORTED_FROM_ABI void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
|
||||
_LIBCPP_DIAGNOSTIC_PUSH
|
||||
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-prototypes")
|
||||
// This function only exists for ABI compatibility and we therefore don't provide a declaration in the headers
|
||||
_LIBCPP_EXPORTED_FROM_ABI void* align(size_t alignment, size_t size, void*& ptr, size_t& space) {
|
||||
return __align_inline::align(alignment, size, ptr, space);
|
||||
}
|
||||
_LIBCPP_DIAGNOSTIC_POP
|
||||
|
||||
#endif // _LIBCPP_ABI_DO_NOT_EXPORT_ALIGN
|
||||
#endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
#include <__config>
|
||||
#include <__thread/support.h>
|
||||
|
||||
#if _LIBCPP_ABI_VERSION == 1 || !_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION
|
||||
#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 9 || !_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION
|
||||
# define NEEDS_MUTEX_DESTRUCTOR
|
||||
#endif
|
||||
|
||||
|
||||
@ -19,6 +19,8 @@ const char* bad_optional_access::what() const noexcept { return "bad_optional_ac
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 7
|
||||
|
||||
// Preserve std::experimental::bad_optional_access for ABI compatibility
|
||||
// Even though it no longer exists in a header file
|
||||
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
|
||||
@ -34,3 +36,5 @@ public:
|
||||
bad_optional_access::~bad_optional_access() noexcept = default;
|
||||
|
||||
_LIBCPP_END_NAMESPACE_EXPERIMENTAL
|
||||
|
||||
#endif // _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 7
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#ifndef _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON
|
||||
#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 14
|
||||
|
||||
template <bool>
|
||||
struct __basic_string_common;
|
||||
@ -35,12 +35,12 @@ struct __basic_string_common<true> {
|
||||
void __basic_string_common<true>::__throw_length_error() const { std::__throw_length_error("basic_string"); }
|
||||
void __basic_string_common<true>::__throw_out_of_range() const { std::__throw_out_of_range("basic_string"); }
|
||||
|
||||
#endif // _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON
|
||||
#endif // _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 14
|
||||
|
||||
// Define legacy ABI functions
|
||||
// ---------------------------
|
||||
|
||||
#ifndef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
|
||||
#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 21
|
||||
|
||||
// This initializes the string with [__s, __s + __sz), but capacity() == __reserve. Assumes that __reserve >= __sz.
|
||||
template <class _CharT, class _Traits, class _Allocator>
|
||||
@ -53,15 +53,12 @@ void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, si
|
||||
__annotate_new(__sz);
|
||||
}
|
||||
|
||||
# define STRING_LEGACY_API(CharT) \
|
||||
template _LIBCPP_EXPORTED_FROM_ABI void basic_string<CharT>::__init(const value_type*, size_type, size_type)
|
||||
|
||||
STRING_LEGACY_API(char);
|
||||
template _LIBCPP_EXPORTED_FROM_ABI void basic_string<char>::__init(const value_type*, size_type, size_type);
|
||||
# if _LIBCPP_HAS_WIDE_CHARACTERS
|
||||
STRING_LEGACY_API(wchar_t);
|
||||
template _LIBCPP_EXPORTED_FROM_ABI void basic_string<wchar_t>::__init(const value_type*, size_type, size_type);
|
||||
# endif
|
||||
|
||||
#endif // _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
|
||||
#endif // _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 21
|
||||
|
||||
#define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template _LIBCPP_EXPORTED_FROM_ABI __VA_ARGS__;
|
||||
#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
|
||||
|
||||
@ -10,8 +10,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// These two symbols are part of the v1 ABI but not part of the >=v2 ABI.
|
||||
#if _LIBCPP_ABI_VERSION == 1
|
||||
#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 9
|
||||
template _LIBCPP_EXPORTED_FROM_ABI valarray<size_t>::valarray(size_t);
|
||||
template _LIBCPP_EXPORTED_FROM_ABI valarray<size_t>::~valarray();
|
||||
#endif
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#ifndef _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
|
||||
#if _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 15
|
||||
|
||||
template <bool>
|
||||
struct __vector_base_common;
|
||||
@ -25,6 +25,6 @@ void __vector_base_common<true>::__throw_length_error() const { std::__throw_len
|
||||
|
||||
void __vector_base_common<true>::__throw_out_of_range() const { std::__throw_out_of_range("vector"); }
|
||||
|
||||
#endif // _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
|
||||
#endif // _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 15
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
@ -64,6 +64,9 @@ option(LIBCXXABI_HAS_WIN32_THREAD_API "Ignore auto-detection and force use of wi
|
||||
option(LIBCXXABI_HAS_EXTERNAL_THREAD_API
|
||||
"Build libc++abi with an externalized threading API.
|
||||
This option may only be set to ON when LIBCXXABI_ENABLE_THREADS=ON." OFF)
|
||||
set(LIBCXXABI_AVAILABILITY_MINIMUM_HEADER_VERSION "2" CACHE STRING
|
||||
"Minimum version of the libc++ headers that are allowed to be used by binaries linked against the libc++ library. This
|
||||
version must correspond to the major version of an LLVM release.")
|
||||
option(LIBCXXABI_ENABLE_FORGIVING_DYNAMIC_CAST
|
||||
"Make dynamic_cast more forgiving when type_info's mistakenly have hidden \
|
||||
visibility, and thus multiple type_infos can exist for a single type. \
|
||||
@ -321,6 +324,7 @@ add_definitions(-D_LIBCXXABI_BUILDING_LIBRARY)
|
||||
# libcxxabi needs to, for various reasons, include the libcpp headers as if
|
||||
# it is being built as part of libcxx.
|
||||
add_definitions(-D_LIBCPP_BUILDING_LIBRARY)
|
||||
add_definitions(-D_LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION=${LIBCXXABI_AVAILABILITY_MINIMUM_HEADER_VERSION})
|
||||
|
||||
# Get feature flags.
|
||||
add_compile_flags_if_supported(-fstrict-aliasing)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user