smeenai created this revision.

When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.

An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.

Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
small methods were marked for inlining; the larger ones hidden.

It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.


https://reviews.llvm.org/D29157

Files:
  include/__config
  include/locale
  include/string

Index: include/string
===================================================================
--- include/string
+++ include/string
@@ -792,6 +792,7 @@
     basic_string(const basic_string& __str, size_type __pos,
                  const allocator_type& __a = allocator_type());
     template<class _Tp>
+        _LIBCPP_HIDDEN
         basic_string(const _Tp& __t, size_type __pos, size_type __n, 
                      const allocator_type& __a = allocator_type(),
                      typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type* = 0);
@@ -927,6 +928,7 @@
     basic_string& append(__self_view __sv) { return append(__sv.data(), __sv.size()); }
     basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
     template <class _Tp>
+        _LIBCPP_HIDDEN
         typename enable_if
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -988,6 +990,7 @@
 #endif
     basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
     template <class _Tp>
+        _LIBCPP_HIDDEN
         typename enable_if
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -998,14 +1001,16 @@
     basic_string& assign(const value_type* __s);
     basic_string& assign(size_type __n, value_type __c);
     template<class _InputIterator>
+        _LIBCPP_HIDDEN
         typename enable_if
         <
            __is_exactly_input_iterator<_InputIterator>::value
                 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
             basic_string&
         >::type
         assign(_InputIterator __first, _InputIterator __last);
     template<class _ForwardIterator>
+        _LIBCPP_HIDDEN
         typename enable_if
         <
             __is_forward_iterator<_ForwardIterator>::value
@@ -1023,6 +1028,7 @@
     _LIBCPP_INLINE_VISIBILITY
     basic_string& insert(size_type __pos1, __self_view __sv) { return insert(__pos1, __sv.data(), __sv.size()); }
     template <class _Tp>
+        _LIBCPP_HIDDEN
         typename enable_if
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -1037,14 +1043,16 @@
     _LIBCPP_INLINE_VISIBILITY
     iterator      insert(const_iterator __pos, size_type __n, value_type __c);
     template<class _InputIterator>
+        _LIBCPP_HIDDEN
         typename enable_if
         <
            __is_exactly_input_iterator<_InputIterator>::value
                 || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
             iterator
         >::type
         insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
     template<class _ForwardIterator>
+        _LIBCPP_HIDDEN
         typename enable_if
         <
             __is_forward_iterator<_ForwardIterator>::value
@@ -1070,6 +1078,7 @@
     basic_string& replace(size_type __pos1, size_type __n1, __self_view __sv) { return replace(__pos1, __n1, __sv.data(), __sv.size()); }
     basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
     template <class _Tp>
+        _LIBCPP_HIDDEN
         typename enable_if
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -1090,6 +1099,7 @@
     _LIBCPP_INLINE_VISIBILITY
     basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c);
     template<class _InputIterator>
+        inline _LIBCPP_INLINE_VISIBILITY
         typename enable_if
         <
             __is_input_iterator<_InputIterator>::value,
Index: include/locale
===================================================================
--- include/locale
+++ include/locale
@@ -623,16 +623,19 @@
     ~num_get() {}
 
     template <class _Fp>
+    _LIBCPP_HIDDEN
     iter_type __do_get_floating_point
                             (iter_type __b, iter_type __e, ios_base& __iob,
                              ios_base::iostate& __err, _Fp& __v) const;
 
     template <class _Signed>
+    _LIBCPP_HIDDEN
     iter_type __do_get_signed
                             (iter_type __b, iter_type __e, ios_base& __iob,
                              ios_base::iostate& __err, _Signed& __v) const;
 
     template <class _Unsigned>
+    _LIBCPP_HIDDEN
     iter_type __do_get_unsigned
                             (iter_type __b, iter_type __e, ios_base& __iob,
                              ios_base::iostate& __err, _Unsigned& __v) const;
Index: include/__config
===================================================================
--- include/__config
+++ include/__config
@@ -676,7 +676,7 @@
 
 #ifndef _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
 #  if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && __has_attribute(__type_visibility__)
-#    define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __attribute__ ((__type_visibility__("default")))
+#    define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __attribute__ ((__visibility__("default")))
 #  else
 #    define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
 #  endif
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to