[libcxx-commits] [libcxx] 166e5b1 - [libc++][NFC] Refactor string's extern template lists (#137264)

via libcxx-commits libcxx-commits at lists.llvm.org
Fri Apr 25 01:43:16 PDT 2025


Author: Nikolas Klauser
Date: 2025-04-25T10:43:13+02:00
New Revision: 166e5b1f0f68252f267146724fdb4ecc25dea894

URL: https://github.com/llvm/llvm-project/commit/166e5b1f0f68252f267146724fdb4ecc25dea894
DIFF: https://github.com/llvm/llvm-project/commit/166e5b1f0f68252f267146724fdb4ecc25dea894.diff

LOG: [libc++][NFC] Refactor string's extern template lists (#137264)

This patch moves the functions common between our two extern template
lists into a common list and avoids some unnecessary _Uglification. This
makes the code a lot nicer to read and makes the differences between the
two lists obvious.

Added: 
    

Modified: 
    libcxx/include/__string/extern_template_lists.h
    libcxx/include/string
    libcxx/src/string.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__string/extern_template_lists.h b/libcxx/include/__string/extern_template_lists.h
index dc66fa512b8bd..18f0ff9f11bd5 100644
--- a/libcxx/include/__string/extern_template_lists.h
+++ b/libcxx/include/__string/extern_template_lists.h
@@ -17,114 +17,77 @@
 
 // clang-format off
 
-// We maintain 2 ABI lists:
+// We maintain multiple ABI lists:
+// - _LIBCPP_STRING_COMMON_EXTERN_TEMPLATE_LIST
 // - _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST
 // - _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST
-// As the name implies, the ABI lists define the V1 (Stable) and unstable ABI.
+// As the name implies, the ABI lists define a common subset, the V1 (Stable) and unstable ABI.
 //
-// For unstable, we may explicitly remove function that are external in V1,
-// and add (new) external functions to better control inlining and compiler
-// optimization opportunities.
+// For unstable, we may explicitly remove function that are external in V1.
 //
 // For stable, the ABI list should rarely change, except for adding new
 // functions supporting new c++ version / API changes. Typically entries
 // must never be removed from the stable list.
-#define _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&, allocator<_CharType> const&)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::~basic_string()) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(value_type const*, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI const _CharType& basic_string<_CharType>::at(size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::reserve(size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(size_type, value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::push_back(value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(value_type const*) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI _CharType& basic_string<_CharType>::at(size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::resize(size_type, value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
+#define _LIBCPP_STRING_COMMON_EXTERN_TEMPLATE_LIST(Func, CharT)                                                        \
+    Func(void basic_string<CharT>::__init(const value_type*, size_type))                                               \
+    Func(void basic_string<CharT>::__init(size_type, value_type))                                                      \
+    Func(basic_string<CharT>::basic_string(const basic_string&, size_type, size_type, const allocator<CharT>&))        \
+    Func(basic_string<CharT>::~basic_string())                                                                         \
+    Func(basic_string<CharT>& basic_string<CharT>::operator=(value_type))                                              \
+    Func(basic_string<CharT>& basic_string<CharT>::assign(size_type, value_type))                                      \
+    Func(basic_string<CharT>& basic_string<CharT>::assign(const basic_string&, size_type, size_type))                  \
+    Func(basic_string<CharT>& basic_string<CharT>::append(size_type, value_type))                                      \
+    Func(basic_string<CharT>& basic_string<CharT>::append(const value_type*))                                          \
+    Func(basic_string<CharT>& basic_string<CharT>::append(const value_type*, size_type))                               \
+    Func(basic_string<CharT>& basic_string<CharT>::append(const basic_string&, size_type, size_type))                  \
+    Func(void basic_string<CharT>::push_back(value_type))                                                              \
+    Func(basic_string<CharT>& basic_string<CharT>::insert(size_type, const value_type*))                               \
+    Func(basic_string<CharT>& basic_string<CharT>::insert(size_type, size_type, value_type))                           \
+    Func(basic_string<CharT>& basic_string<CharT>::insert(size_type, const value_type*, size_type))                    \
+    Func(basic_string<CharT>& basic_string<CharT>::insert(size_type, const basic_string&, size_type, size_type))       \
+    Func(basic_string<CharT>::iterator basic_string<CharT>::insert(basic_string::const_iterator, value_type))          \
+    Func(basic_string<CharT>& basic_string<CharT>::replace(size_type, size_type, const value_type*))                   \
+    Func(basic_string<CharT>& basic_string<CharT>::replace(size_type, size_type, size_type, value_type))               \
+    Func(basic_string<CharT>& basic_string<CharT>::replace(size_type, size_type, const value_type*, size_type))        \
+    Func(basic_string<CharT>& basic_string<CharT>::replace(size_type, size_type, const basic_string&, size_type, size_type)) \
+    Func(void basic_string<CharT>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, const value_type*)) \
+    Func(void basic_string<CharT>::resize(size_type, value_type))                                                      \
+    Func(void basic_string<CharT>::reserve(size_type))                                                                 \
+    Func(basic_string<CharT>::size_type basic_string<CharT>::copy(value_type*, size_type, size_type) const)            \
+    Func(basic_string<CharT>::size_type basic_string<CharT>::find(value_type, size_type) const)                        \
+    Func(basic_string<CharT>::size_type basic_string<CharT>::find(const value_type*, size_type, size_type) const)      \
+    Func(basic_string<CharT>::size_type basic_string<CharT>::rfind(value_type, size_type) const)                       \
+    Func(basic_string<CharT>::size_type basic_string<CharT>::rfind(const value_type*, size_type, size_type) const)     \
+    Func(basic_string<CharT>::size_type basic_string<CharT>::find_first_of(const value_type*, size_type, size_type) const) \
+    Func(basic_string<CharT>::size_type basic_string<CharT>::find_last_of(const value_type*, size_type, size_type) const) \
+    Func(basic_string<CharT>::size_type basic_string<CharT>::find_first_not_of(const value_type*, size_type, size_type) const) \
+    Func(basic_string<CharT>::size_type basic_string<CharT>::find_last_not_of(const value_type*, size_type, size_type) const) \
+    Func(CharT& basic_string<CharT>::at(size_type))                                                                    \
+    Func(const CharT& basic_string<CharT>::at(size_type) const)                                                        \
+    Func(int basic_string<CharT>::compare(const value_type*) const)                                                    \
+    Func(int basic_string<CharT>::compare(size_type, size_type, const value_type*) const)                              \
+    Func(int basic_string<CharT>::compare(size_type, size_type, const value_type*, size_type) const)                   \
+    Func(int basic_string<CharT>::compare(size_type, size_type, const basic_string&, size_type, size_type) const)      \
+    Func(const basic_string<CharT>::size_type basic_string<CharT>::npos)                                               \
 
-#define _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::~basic_string()) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(value_type const*, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init_copy_ctor_external(value_type const*, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI const _CharType& basic_string<_CharType>::at(size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::reserve(size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(size_type, value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::push_back(value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(value_type const*) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI _CharType& basic_string<_CharType>::at(size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::resize(size_type, value_type)) \
-  _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
+#define _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(Func, CharT)                                                            \
+  _LIBCPP_STRING_COMMON_EXTERN_TEMPLATE_LIST(Func, CharT)                                                              \
+  Func(basic_string<CharT>::basic_string(const basic_string&))                                                         \
+  Func(basic_string<CharT>::basic_string(const basic_string&, const allocator<CharT>&))                                \
+  Func(basic_string<CharT>& basic_string<CharT>::assign(const value_type*))                                            \
+  Func(basic_string<CharT>& basic_string<CharT>::assign(const value_type*, size_type))                                 \
+  Func(basic_string<CharT>& basic_string<CharT>::operator=(basic_string const&))                                       \
+  Func(void basic_string<CharT>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type))          \
+  Func(basic_string<CharT>& basic_string<CharT>::erase(size_type, size_type))                                          \
+
+#define _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(Func, CharT)                                                      \
+  _LIBCPP_STRING_COMMON_EXTERN_TEMPLATE_LIST(Func, CharT)                                                              \
+  Func(void basic_string<CharT>::__init_copy_ctor_external(const value_type*, size_type))                              \
+  Func(basic_string<CharT>& basic_string<CharT>::__assign_external(const value_type*, size_type))                      \
+  Func(basic_string<CharT>& basic_string<CharT>::__assign_external(const value_type*))                                 \
+  Func(basic_string<CharT>& basic_string<CharT>::__assign_no_alias<false>(const value_type*, size_type))               \
+  Func(basic_string<CharT>& basic_string<CharT>::__assign_no_alias<true>(const value_type*, size_type))                \
+  Func(void basic_string<CharT>::__erase_external_with_move(size_type, size_type))
 
 // clang-format on
 

diff  --git a/libcxx/include/string b/libcxx/include/string
index ce36b49524c53..f60616d522cfe 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -2490,7 +2490,7 @@ private:
 
 // These declarations must appear before any functions are implicitly used
 // so that they have the correct visibility specifier.
-#  define _LIBCPP_DECLARE(...) extern template __VA_ARGS__;
+#  define _LIBCPP_DECLARE(...) extern template _LIBCPP_EXPORTED_FROM_ABI __VA_ARGS__;
 #  ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
 #    if _LIBCPP_HAS_WIDE_CHARACTERS

diff  --git a/libcxx/src/string.cpp b/libcxx/src/string.cpp
index e335639883dba..55d19a68802b5 100644
--- a/libcxx/src/string.cpp
+++ b/libcxx/src/string.cpp
@@ -75,7 +75,7 @@ STRING_LEGACY_API(wchar_t);
 
 #endif // _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
 
-#define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__;
+#define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template _LIBCPP_EXPORTED_FROM_ABI __VA_ARGS__;
 #ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
 _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char)
 #  if _LIBCPP_HAS_WIDE_CHARACTERS


        


More information about the libcxx-commits mailing list