diff --git a/libcxx/include/string b/libcxx/include/string index 87e66b68497a..c6a799dbc7e8 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -613,29 +613,15 @@ operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y); _LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS string operator+, allocator >(char const*, string const&)) template -class _LIBCPP_TEMPLATE_VIS __basic_string_common -{ -protected: - _LIBCPP_NORETURN void __throw_length_error() const; - _LIBCPP_NORETURN void __throw_out_of_range() const; +struct __basic_string_common; + +template <> +struct __basic_string_common { + // Both are defined in string.cpp + _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_length_error() const; + _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_out_of_range() const; }; -template -void -__basic_string_common<__b>::__throw_length_error() const -{ - _VSTD::__throw_length_error("basic_string"); -} - -template -void -__basic_string_common<__b>::__throw_out_of_range() const -{ - _VSTD::__throw_out_of_range("basic_string"); -} - -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __basic_string_common) - template struct __string_is_trivial_iterator : public false_type {}; @@ -688,7 +674,7 @@ class _LIBCPP_PREFERRED_NAME(u32string) #endif basic_string - : private __basic_string_common + : private __basic_string_common // This base class is historical, but it needs to remain for ABI compatibility { public: typedef basic_string __self; diff --git a/libcxx/include/vector b/libcxx/include/vector index c2deb5bb3a7e..626c917f3a6d 100644 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -302,33 +302,18 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -class _LIBCPP_TEMPLATE_VIS __vector_base_common -{ -protected: - _LIBCPP_INLINE_VISIBILITY __vector_base_common() {} - _LIBCPP_NORETURN void __throw_length_error() const; - _LIBCPP_NORETURN void __throw_out_of_range() const; +struct __vector_base_common; + +template <> +struct __vector_base_common { + // Both are defined in vector.cpp + _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_length_error() const; + _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_out_of_range() const; }; -template -void -__vector_base_common<__b>::__throw_length_error() const -{ - _VSTD::__throw_length_error("vector"); -} - -template -void -__vector_base_common<__b>::__throw_out_of_range() const -{ - _VSTD::__throw_out_of_range("vector"); -} - -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __vector_base_common) - template class __vector_base - : protected __vector_base_common + : protected __vector_base_common // This base class is historical, but it needs to remain for ABI compatibility { public: typedef _Allocator allocator_type; diff --git a/libcxx/src/string.cpp b/libcxx/src/string.cpp index 97a773f79a3b..012b2ea08958 100644 --- a/libcxx/src/string.cpp +++ b/libcxx/src/string.cpp @@ -18,7 +18,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __basic_string_common; +void __basic_string_common::__throw_length_error() const { + _VSTD::__throw_length_error("basic_string"); +} + +void __basic_string_common::__throw_out_of_range() const { + _VSTD::__throw_out_of_range("basic_string"); +} #define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__; #ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION diff --git a/libcxx/src/vector.cpp b/libcxx/src/vector.cpp index 3b65e558fd0a..0570ede733c3 100644 --- a/libcxx/src/vector.cpp +++ b/libcxx/src/vector.cpp @@ -10,6 +10,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __vector_base_common; +void __vector_base_common::__throw_length_error() const { + _VSTD::__throw_length_error("vector"); +} + +void __vector_base_common::__throw_out_of_range() const { + _VSTD::__throw_out_of_range("vector"); +} _LIBCPP_END_NAMESPACE_STD