[libc++] Make sure we can build libc++ with -fvisibility=hidden

Summary:
When building with -fvisibility=hidden, some symbols do not get exported from
libc++.dylib. This means that some entities are not explicitly given default
visibility in the source code, and that we rely on the fact -fvisibility=default
is the default. This commit explicitly gives default visibility to those
symbols to avoid being dependent on the command line flags used.

The commit also remove symbols from the dylib -- those symbols do not
actually need to be exported from the dylib and this should not be an
ABI break.

Finally, in the future, we may want to mark the whole std:: namespace as
having hidden visibility (to switch from opt-out to opt-in), in which
case the changes done in this commit will be required.

Reviewers: EricWF

Subscribers: mgorny, christof, dexonsmith, libcxx-commits

Differential Revision: https://reviews.llvm.org/D52662

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@345260 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/__config b/include/__config
index 51068b3..f602074 100644
--- a/include/__config
+++ b/include/__config
@@ -675,21 +675,23 @@
 #  define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
 #  define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
 #  define _LIBCPP_OVERRIDABLE_FUNC_VIS
+#  define _LIBCPP_EXPORTED_FROM_ABI
 #elif defined(_LIBCPP_BUILDING_LIBRARY)
 #  define _LIBCPP_DLL_VIS __declspec(dllexport)
 #  define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
 #  define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS
 #  define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS
+#  define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllexport)
 #else
 #  define _LIBCPP_DLL_VIS __declspec(dllimport)
 #  define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS
 #  define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
 #  define _LIBCPP_OVERRIDABLE_FUNC_VIS
+#  define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport)
 #endif
 
 #define _LIBCPP_TYPE_VIS            _LIBCPP_DLL_VIS
 #define _LIBCPP_FUNC_VIS            _LIBCPP_DLL_VIS
-#define _LIBCPP_EXTERN_VIS          _LIBCPP_DLL_VIS
 #define _LIBCPP_EXCEPTION_ABI       _LIBCPP_DLL_VIS
 #define _LIBCPP_HIDDEN
 #define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
@@ -743,8 +745,8 @@
 #  endif
 #endif
 
-#ifndef _LIBCPP_EXTERN_VIS
-#define _LIBCPP_EXTERN_VIS
+#ifndef _LIBCPP_EXPORTED_FROM_ABI
+#  define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default")))
 #endif
 
 #ifndef _LIBCPP_OVERRIDABLE_FUNC_VIS
diff --git a/include/__debug b/include/__debug
index d01bacd..a8788f6 100644
--- a/include/__debug
+++ b/include/__debug
@@ -74,7 +74,7 @@
 
 /// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT
 ///    fails.
-extern _LIBCPP_EXTERN_VIS __libcpp_debug_function_type __libcpp_debug_function;
+extern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function;
 
 /// __libcpp_abort_debug_function - A debug handler that aborts when called.
 _LIBCPP_NORETURN _LIBCPP_FUNC_VIS
diff --git a/include/__functional_base b/include/__functional_base
index 1887974..032be99 100644
--- a/include/__functional_base
+++ b/include/__functional_base
@@ -562,7 +562,7 @@
 struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { };
 
 #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
-extern const allocator_arg_t allocator_arg;
+extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg;
 #else
 /* _LIBCPP_INLINE_VAR */ constexpr allocator_arg_t allocator_arg = allocator_arg_t();
 #endif
diff --git a/include/__locale b/include/__locale
index f43e7b4..cde9cc8 100644
--- a/include/__locale
+++ b/include/__locale
@@ -1255,13 +1255,13 @@
 };
 
 template <>
-struct __narrow_to_utf8<16>
+struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16>
     : public codecvt<char16_t, char, mbstate_t>
 {
     _LIBCPP_INLINE_VISIBILITY
     __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
 
-    ~__narrow_to_utf8();
+    _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
 
     template <class _OutputIterator, class _CharT>
     _LIBCPP_INLINE_VISIBILITY
@@ -1289,13 +1289,13 @@
 };
 
 template <>
-struct __narrow_to_utf8<32>
+struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32>
     : public codecvt<char32_t, char, mbstate_t>
 {
     _LIBCPP_INLINE_VISIBILITY
     __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
 
-    ~__narrow_to_utf8();
+    _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
 
     template <class _OutputIterator, class _CharT>
     _LIBCPP_INLINE_VISIBILITY
@@ -1345,13 +1345,13 @@
 };
 
 template <>
-struct __widen_from_utf8<16>
+struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16>
     : public codecvt<char16_t, char, mbstate_t>
 {
     _LIBCPP_INLINE_VISIBILITY
     __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
 
-    ~__widen_from_utf8();
+    _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
 
     template <class _OutputIterator>
     _LIBCPP_INLINE_VISIBILITY
@@ -1379,13 +1379,13 @@
 };
 
 template <>
-struct __widen_from_utf8<32>
+struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32>
     : public codecvt<char32_t, char, mbstate_t>
 {
     _LIBCPP_INLINE_VISIBILITY
     __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
 
-    ~__widen_from_utf8();
+    _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
 
     template <class _OutputIterator>
     _LIBCPP_INLINE_VISIBILITY
diff --git a/include/__mutex_base b/include/__mutex_base
index 4659ca9..da21a5f 100644
--- a/include/__mutex_base
+++ b/include/__mutex_base
@@ -76,9 +76,9 @@
 
 #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
 
-extern const defer_lock_t  defer_lock;
-extern const try_to_lock_t try_to_lock;
-extern const adopt_lock_t  adopt_lock;
+extern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t  defer_lock;
+extern _LIBCPP_EXPORTED_FROM_ABI const try_to_lock_t try_to_lock;
+extern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t  adopt_lock;
 
 #else
 
diff --git a/include/charconv b/include/charconv
index 7cb790e..c0cb9c5 100644
--- a/include/charconv
+++ b/include/charconv
@@ -89,6 +89,11 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+namespace __itoa {
+_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
+_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);
+}
+
 #if _LIBCPP_STD_VER > 11
 
 enum class _LIBCPP_ENUM_VIS chars_format
@@ -147,9 +152,6 @@
     UINT32_C(1000000000),
 };
 
-_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
-_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);
-
 template <typename _Tp, typename = void>
 struct _LIBCPP_HIDDEN __traits_base
 {
diff --git a/include/locale b/include/locale
index e240799..7be358e 100644
--- a/include/locale
+++ b/include/locale
@@ -2408,6 +2408,23 @@
     string_type __analyze(char __fmt, const ctype<_CharT>&);
 };
 
+#define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \
+template <> _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
+template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
+template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
+template <> _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
+template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
+extern template _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
+extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
+extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
+extern template _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
+extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
+/**/
+
+_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char)
+_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t)
+#undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION
+
 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
 class _LIBCPP_TEMPLATE_VIS time_get_byname
     : public time_get<_CharT, _InputIterator>,
diff --git a/include/thread b/include/thread
index 0629d70..8c0115f 100644
--- a/include/thread
+++ b/include/thread
@@ -151,7 +151,7 @@
     __thread_specific_ptr(const __thread_specific_ptr&);
     __thread_specific_ptr& operator=(const __thread_specific_ptr&);
 
-    static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
+    _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
 
 public:
     typedef _Tp* pointer;
diff --git a/include/utility b/include/utility
index 5388585..30e26f1 100644
--- a/include/utility
+++ b/include/utility
@@ -297,7 +297,7 @@
 
 struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { };
 #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
-extern const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
+extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
 #else
 /* _LIBCPP_INLINE_VAR */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
 #endif