diff --git a/libcxx/include/string b/libcxx/include/string --- a/libcxx/include/string +++ b/libcxx/include/string @@ -613,28 +613,14 @@ _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; -}; - -template -void -__basic_string_common<__b>::__throw_length_error() const -{ - _VSTD::__throw_length_error("basic_string"); -} +struct __basic_string_common; -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 __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 struct __string_is_trivial_iterator : public false_type {}; @@ -688,7 +674,7 @@ _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 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -302,33 +302,18 @@ _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; -}; - -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"); -} +struct __vector_base_common; -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __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 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 --- 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 --- 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