[libcxx-commits] [libcxx] [libc++] Introduce the notion of a minimum header version (PR #166074)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Sun Nov 2 07:42:01 PST 2025


https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/166074

Intoducing 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 minumum 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.


>From 3a9e996ce1220943cf3f9dbfad5d55bd1989cbed Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sun, 2 Nov 2025 16:34:51 +0100
Subject: [PATCH] [libc++] Introduce the notion of a minimum header version

---
 libcxx/CMakeLists.txt                        |  2 ++
 libcxx/docs/ABIGuarantees.rst                | 17 ---------
 libcxx/include/__config                      | 10 ++----
 libcxx/include/__config_site.in              |  1 +
 libcxx/include/__configuration/abi.h         | 14 --------
 libcxx/include/__ostream/basic_ostream.h     | 16 ++++-----
 libcxx/include/istream                       | 22 ++++++------
 libcxx/include/streambuf                     | 38 ++++++++++----------
 libcxx/include/valarray                      |  4 +--
 libcxx/src/any.cpp                           |  4 +++
 libcxx/src/charconv.cpp                      |  4 +--
 libcxx/src/condition_variable_destructor.cpp |  2 +-
 libcxx/src/error_category.cpp                |  4 ++-
 libcxx/src/memory.cpp                        |  3 +-
 libcxx/src/mutex_destructor.cpp              |  2 +-
 libcxx/src/optional.cpp                      |  4 +++
 libcxx/src/string.cpp                        | 15 ++++----
 libcxx/src/valarray.cpp                      |  3 +-
 libcxx/src/vector.cpp                        |  4 +--
 19 files changed, 72 insertions(+), 97 deletions(-)

diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index a119850cd808e..1a860cb30ccea 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -205,6 +205,7 @@ 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 "1" CACHE STRING "Minimum version of the libc++ headers that are used by binaries linked against the libc++ library")
 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.")
 
@@ -729,6 +730,7 @@ endfunction()
 # Configuration file flags =====================================================
 config_define(${LIBCXX_ABI_VERSION} _LIBCPP_ABI_VERSION)
 config_define(${LIBCXX_ABI_NAMESPACE} _LIBCPP_ABI_NAMESPACE)
+config_define(${LIBCXX_AVAILABILITY_MINIMUM_HEADER_VERSION} _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION)
 config_define(${LIBCXX_ABI_FORCE_ITANIUM} _LIBCPP_ABI_FORCE_ITANIUM)
 config_define(${LIBCXX_ABI_FORCE_MICROSOFT} _LIBCPP_ABI_FORCE_MICROSOFT)
 config_define(${LIBCXX_ENABLE_THREADS} _LIBCPP_HAS_THREADS)
diff --git a/libcxx/docs/ABIGuarantees.rst b/libcxx/docs/ABIGuarantees.rst
index 4d4674c7756a4..fc3cf8b7dd0a3 100644
--- a/libcxx/docs/ABIGuarantees.rst
+++ b/libcxx/docs/ABIGuarantees.rst
@@ -114,23 +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_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
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 357f77b7d27d6..035e5fc9e14f7 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -547,14 +547,10 @@ 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
+#  if defined(_LIBCPP_BUILDING_LIBRARY) && _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION < 8
+#    define _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8
 #  else
-#    define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
+#    define _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 _LIBCPP_HIDE_FROM_ABI
 #  endif
 
 // Clang modules take a significant compile time hit when pushing and popping diagnostics.
diff --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in
index b68c0c8258366..30371a9055651 100644
--- a/libcxx/include/__config_site.in
+++ b/libcxx/include/__config_site.in
@@ -11,6 +11,7 @@
 
 #cmakedefine _LIBCPP_ABI_VERSION @_LIBCPP_ABI_VERSION@
 #cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@
+#cmakedefine _LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION @_LIBCPP_AVAILABILITY_MINIMUM_HEADER_VERSION@
 #cmakedefine01 _LIBCPP_ABI_FORCE_ITANIUM
 #cmakedefine01 _LIBCPP_ABI_FORCE_MICROSOFT
 #cmakedefine01 _LIBCPP_HAS_THREADS
diff --git a/libcxx/include/__configuration/abi.h b/libcxx/include/__configuration/abi.h
index 38b85c6ac70de..f088fd92f29c0 100644
--- a/libcxx/include/__configuration/abi.h
+++ b/libcxx/include/__configuration/abi.h
@@ -63,9 +63,6 @@
 
 // These flags are documented in ABIGuarantees.rst
 #  define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
-#  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
@@ -85,17 +82,6 @@
 #  define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
 
 #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/__ostream/basic_ostream.h b/libcxx/include/__ostream/basic_ostream.h
index effeef491f341..ac8bb1a3159f9 100644
--- a/libcxx/include/__ostream/basic_ostream.h
+++ b/libcxx/include/__ostream/basic_ostream.h
@@ -53,7 +53,7 @@ class basic_ostream : virtual public basic_ios<_CharT, _Traits> {
   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 @@ class basic_ostream : virtual public basic_ios<_CharT, _Traits> {
   // 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 @@ class basic_ostream : virtual public basic_ios<_CharT, _Traits> {
   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 @@ class basic_ostream : virtual public basic_ios<_CharT, _Traits> {
   basic_ostream& flush();
 
   // 27.7.2.5 seeks:
-  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);
+  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 7f15521f91a8a..4fc4c6b133552 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<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:
   _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);
   }
 };
diff --git a/libcxx/include/streambuf b/libcxx/include/streambuf
index 7dc4e31cc2324..964dab2b8959d 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;
   }
 
-  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 locale getloc() const { return __loc_; }
+  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:
-  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize in_avail() {
+  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();
   }
 
-  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type snextc() {
+  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;
   }
 
-  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sgetc() {
+  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 215811d5ba475..a97b930eac4a7 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<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);
diff --git a/libcxx/src/any.cpp b/libcxx/src/any.cpp
index f3fc715d517f2..47058f55d8248 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 @@ class _LIBCPP_EXPORTED_FROM_ABI bad_any_cast : public bad_cast {
 
 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 5e8cb7d97703b..5438910a7e751 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 {
 
@@ -24,7 +24,7 @@ _LIBCPP_EXPORTED_FROM_ABI char* __u64toa(uint64_t value, char* buffer) noexcept
 
 } // 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 f6ffe33685990..fc4b4a601d964 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 8ae460fb5f1f4..9c0ca6a04a523 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 9be40cb9c1285..e8631d0ad7e25 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
 
diff --git a/libcxx/src/mutex_destructor.cpp b/libcxx/src/mutex_destructor.cpp
index 9f991721f083f..4c63ea0da74da 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 faabe66cfcfc8..3b92580565bfc 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 @@ class _LIBCPP_EXPORTED_FROM_ABI bad_optional_access : public std::logic_error {
 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 5028fc88fe46d..178ef710f0bcf 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 <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
diff --git a/libcxx/src/valarray.cpp b/libcxx/src/valarray.cpp
index 6ef1f1cafc0e5..3d3a9ac30ebd0 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<size_t>::valarray(size_t);
 template _LIBCPP_EXPORTED_FROM_ABI valarray<size_t>::~valarray();
 #endif
diff --git a/libcxx/src/vector.cpp b/libcxx/src/vector.cpp
index 3f3a906d6421f..77a028a48077d 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 <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



More information about the libcxx-commits mailing list