diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index 8b4cd2636fd4..00ea2deef196 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -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 diff --git a/libcxx/docs/ABIGuarantees.rst b/libcxx/docs/ABIGuarantees.rst index 37f38f4f392c..4bd9737542a4 100644 --- a/libcxx/docs/ABIGuarantees.rst +++ b/libcxx/docs/ABIGuarantees.rst @@ -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::__throw_length_error()`` and -``__basic_string_common::__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::__throw_length_error()`` and -``__vector_base_common::__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 diff --git a/libcxx/docs/VendorDocumentation.rst b/libcxx/docs/VendorDocumentation.rst index fc788178c96e..38fd5ac73e22 100644 --- a/libcxx/docs/VendorDocumentation.rst +++ b/libcxx/docs/VendorDocumentation.rst @@ -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` 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`. 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``. diff --git a/libcxx/docs/index.rst b/libcxx/docs/index.rst index d006b52f24ce..20c63efaac15 100644 --- a/libcxx/docs/index.rst +++ b/libcxx/docs/index.rst @@ -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 ========================= diff --git a/libcxx/include/__config b/libcxx/include/__config index b4db39472ce3..4b1763d69d9e 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -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. diff --git a/libcxx/include/__configuration/abi.h b/libcxx/include/__configuration/abi.h index a0782c52dcd9..5ce040fbcb59 100644 --- a/libcxx/include/__configuration/abi.h +++ b/libcxx/include/__configuration/abi.h @@ -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__) diff --git a/libcxx/include/__configuration/availability.h b/libcxx/include/__configuration/availability.h index ad952bbec1d8..2c76347090fc 100644 --- a/libcxx/include/__configuration/availability.h +++ b/libcxx/include/__configuration/availability.h @@ -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 diff --git a/libcxx/include/__ostream/basic_ostream.h b/libcxx/include/__ostream/basic_ostream.h index 4fa8abc6fcf9..62770be72f98 100644 --- a/libcxx/include/__ostream/basic_ostream.h +++ b/libcxx/include/__ostream/basic_ostream.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* __sb) { + inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 explicit basic_ostream(basic_streambuf* __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::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& (*__pf)(basic_ios&)) { __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 diff --git a/libcxx/include/istream b/libcxx/include/istream index 6b8a339d7323..5f805e8a37d1 100644 --- a/libcxx/include/istream +++ b/libcxx/include/istream @@ -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* __sb) + inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 explicit basic_istream(basic_streambuf* __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::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& (*__pf)(basic_ios&)) { __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& __sb) { + inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 basic_istream& get(basic_streambuf& __sb) { return get(__sb, this->widen('\n')); } basic_istream& get(basic_streambuf& __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* __sb) + inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 explicit basic_iostream(basic_streambuf* __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::swap(__rhs); } }; diff --git a/libcxx/include/streambuf b/libcxx/include/streambuf index be790ffca144..f9dd5b74518f 100644 --- a/libcxx/include/streambuf +++ b/libcxx/include/streambuf @@ -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; diff --git a/libcxx/include/valarray b/libcxx/include/valarray index f04923d08c26..58287b60dd89 100644 --- a/libcxx/include/valarray +++ b/libcxx/include/valarray @@ -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& __ga); valarray(const mask_array& __ma); valarray(const indirect_array& __ia); - inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 ~valarray(); + inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 ~valarray(); // assignment: valarray& operator=(const valarray& __v); diff --git a/libcxx/src/any.cpp b/libcxx/src/any.cpp index f3fc715d517f..47058f55d824 100644 --- a/libcxx/src/any.cpp +++ b/libcxx/src/any.cpp @@ -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 diff --git a/libcxx/src/charconv.cpp b/libcxx/src/charconv.cpp index 6fdee25f9c9b..148068b07e8e 100644 --- a/libcxx/src/charconv.cpp +++ b/libcxx/src/charconv.cpp @@ -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. diff --git a/libcxx/src/condition_variable_destructor.cpp b/libcxx/src/condition_variable_destructor.cpp index f6ffe3368599..fc4b4a601d96 100644 --- a/libcxx/src/condition_variable_destructor.cpp +++ b/libcxx/src/condition_variable_destructor.cpp @@ -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 diff --git a/libcxx/src/error_category.cpp b/libcxx/src/error_category.cpp index 8ae460fb5f1f..9c0ca6a04a52 100644 --- a/libcxx/src/error_category.cpp +++ b/libcxx/src/error_category.cpp @@ -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 diff --git a/libcxx/src/memory.cpp b/libcxx/src/memory.cpp index e7d2dbcbb60c..61aa89d58afd 100644 --- a/libcxx/src/memory.cpp +++ b/libcxx/src/memory.cpp @@ -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 diff --git a/libcxx/src/mutex_destructor.cpp b/libcxx/src/mutex_destructor.cpp index 9f991721f083..4c63ea0da74d 100644 --- a/libcxx/src/mutex_destructor.cpp +++ b/libcxx/src/mutex_destructor.cpp @@ -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 diff --git a/libcxx/src/optional.cpp b/libcxx/src/optional.cpp index faabe66cfcfc..3b92580565bf 100644 --- a/libcxx/src/optional.cpp +++ b/libcxx/src/optional.cpp @@ -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 diff --git a/libcxx/src/string.cpp b/libcxx/src/string.cpp index 5028fc88fe46..178ef710f0bc 100644 --- a/libcxx/src/string.cpp +++ b/libcxx/src/string.cpp @@ -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 struct __basic_string_common; @@ -35,12 +35,12 @@ struct __basic_string_common { void __basic_string_common::__throw_length_error() const { std::__throw_length_error("basic_string"); } void __basic_string_common::__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 @@ -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::__init(const value_type*, size_type, size_type) - -STRING_LEGACY_API(char); +template _LIBCPP_EXPORTED_FROM_ABI void basic_string::__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::__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 diff --git a/libcxx/src/valarray.cpp b/libcxx/src/valarray.cpp index 6ef1f1cafc0e..3d3a9ac30ebd 100644 --- a/libcxx/src/valarray.cpp +++ b/libcxx/src/valarray.cpp @@ -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::valarray(size_t); template _LIBCPP_EXPORTED_FROM_ABI valarray::~valarray(); #endif diff --git a/libcxx/src/vector.cpp b/libcxx/src/vector.cpp index 3f3a906d6421..77a028a48077 100644 --- a/libcxx/src/vector.cpp +++ b/libcxx/src/vector.cpp @@ -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 struct __vector_base_common; @@ -25,6 +25,6 @@ void __vector_base_common::__throw_length_error() const { std::__throw_len void __vector_base_common::__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 diff --git a/libcxxabi/CMakeLists.txt b/libcxxabi/CMakeLists.txt index 3dabd87b9c58..2b67c5972339 100644 --- a/libcxxabi/CMakeLists.txt +++ b/libcxxabi/CMakeLists.txt @@ -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)