[libc++] Add _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY to support GCC ABI compatibility

Summary:
GCC and Clang handle visibility attributes on the out-of-line definition of externally instantiated templates differently. For example in the reproducer below Clang will emit both 'foo' and 'bar' with default visibility while GCC only emits a non-hidden 'foo'.  

```
// RUN: g++ -std=c++11 -shared -O3 test.cpp && sym_extract.py a.out
// RUN: clang++ -std=c++11 -shared -O3 test.cpp && sym_extract.py a.out
#define INLINE_VISIBILITY __attribute__((visibility("hidden"), always_inline))

template <class T>
struct Foo {
  void foo();
  void bar();
};

template <class T>
void Foo<T>::foo() {}

template <class T>
inline INLINE_VISIBILITY
void Foo<T>::bar() {}

template struct Foo<int>;
```

This difference creates ABI incompatibilities between Clang and GCC built dylibs. Specifically GCC built dylibs lack definitions for various member functions of `basic_string`, `basic_istream`, `basic_ostream`, `basic_iostream`, and `basic_streambuf` (All of these types are externally instantiated). 

Surprisingly these missing symbols don't cause many problems because the functions are marked `always_inline`  therefore the dylib definition is rarely needed. However when an out-of-line definition is required then GCC built dylibs will fail to link. For example [GCC built dylibs cannot build Clang](http://stackoverflow.com/questions/39454262/clang-build-errors).

This patch works around this issue by adding `_LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY` which is used to mark externally instantiated member functions as always inline. When building the library `_LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY` sets the symbol's visibility to "default" instead of "hidden", otherwise it acts exactly the same as `_LIBCPP_INLINE_VISIBILITY`.

After applying this patch GCC dylibs now contain:
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE7sungetcEv`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE5gbumpEi`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE7sungetcEv`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE9sputbackcEc`
  * `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEE3getERNS_15basic_streambufIwS2_EE`
  * `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEElsEPFRNS_9basic_iosIwS2_EES6_E`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE4setpEPcS4_`
  * `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEEC1EPNS_15basic_streambufIwS2_EE`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE6snextcEv`
  * `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEE4swapERS3_`
  * `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEE4swapERS3_`
  * `_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcm`
  * `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEErsEPFRNS_8ios_baseES5_E`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE9pubsetbufEPcl`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE10pubseekoffExNS_8ios_base7seekdirEj`
  * `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEErsEPFRNS_9basic_iosIwS2_EES6_E`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE5pbumpEi`
  * `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE5seekpENS_4fposI11__mbstate_tEE`
  * `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEE7getlineEPcl`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5sgetcEv`
  * `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEE3getERNS_15basic_streambufIcS2_EE`
  * `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPFRNS_8ios_baseES5_E`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE8in_availEv`
  * `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEErsEPFRNS_8ios_baseES5_E`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE6sbumpcEv`
  * `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPFRNS_9basic_iosIcS2_EES6_E`
  * `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEE3getERc`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE6snextcEv`
  * `_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6__initEmw`
  * `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEE7getlineEPwl`
  * `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE5tellpEv`
  * `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEE3getERw`
  * `_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEmc`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE7pubsyncEv`
  * `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEE3getEPcl`
  * `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEEC2EPNS_15basic_streambufIcS2_EE`
  * `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEErsEPFRNS_9basic_iosIcS2_EES6_E`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE7pubsyncEv`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5sputcEc`
  * `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEE5seekpExNS_8ios_base7seekdirE`
  * `_ZNKSt3__115basic_streambufIcNS_11char_traitsIcEEE6getlocEv`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5gbumpEi`
  * `_ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEE4swapERS3_`
  * `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEE5seekpENS_4fposI11__mbstate_tEE`
  * `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEE5tellpEv`
  * `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEElsEPFRS3_S4_E`
  * `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEE3getEPwl`
  * `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEEC2EPNS_15basic_streambufIwS2_EE`
  * `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPFRS3_S4_E`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE4setgEPcS4_S4_`
  * `_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6__initEPKwmm`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE4setgEPwS4_S4_`
  * `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEEC1EPNS_15basic_streambufIwS2_EE`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE8pubimbueERKNS_6localeE`
  * `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE4swapERS3_`
  * `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEEC2EPNS_15basic_streambufIwS2_EE`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE10pubseekposENS_4fposI11__mbstate_tEEj`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5pbumpEi`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE5sgetcEv`
  * `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEE4swapERS3_`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE10pubseekposENS_4fposI11__mbstate_tEEj`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5sputnEPKcl`
  * `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE5seekpExNS_8ios_base7seekdirE`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE5sgetnEPwl`
  * `_ZNSt3__113basic_ostreamIwNS_11char_traitsIwEEElsEPFRNS_8ios_baseES5_E`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE4setpEPwS4_`
  * `_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5sgetnEPcl`
  * `_ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv`
  * `_ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEEC2EPNS_15basic_streambufIcS2_EE`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE8pubimbueERKNS_6localeE`
  * `_ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEEC1EPNS_15basic_streambufIcS2_EE`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE8in_availEv`
  * `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEEC1EPNS_15basic_streambufIcS2_EE`
  * `_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcmm`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE6sbumpcEv`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE10pubseekoffExNS_8ios_base7seekdirEj`
  * `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEEC2EPNS_15basic_streambufIcS2_EE`
  * `_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEErsEPFRS3_S4_E`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE9sputbackcEw`
  * `_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6__initEPKwm`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE5sputnEPKwl`
  * `_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEErsEPFRS3_S4_E`
  * `_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEEC1EPNS_15basic_streambufIcS2_EE`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE9pubsetbufEPwl`
  * `_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEE5sputcEw`


This patch has no effect on Clang based builds.



Reviewers: mclow.lists, eugenis, danalbert, jroelofs, EricWF

Subscribers: beanz, cfe-commits, mgorny

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

llvm-svn: 281681
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: f8f31c4985f9276811ba4c30ec8ebdd4992093d5
diff --git a/include/string b/include/string
index 39bda49..fa5679d 100644
--- a/include/string
+++ b/include/string
@@ -1269,11 +1269,15 @@
                  __align_it<sizeof(value_type) < __alignment ?
                             __alignment/sizeof(value_type) : 1 > (__s+1)) - 1;}
 
+    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
     void __init(const value_type* __s, size_type __sz, size_type __reserve);
+    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
     void __init(const value_type* __s, size_type __sz);
+    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
     void __init(size_type __n, value_type __c);
 
     template <class _InputIterator>
+    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
     typename enable_if
     <
         __is_exactly_input_iterator<_InputIterator>::value,
@@ -1282,6 +1286,7 @@
     __init(_InputIterator __first, _InputIterator __last);
 
     template <class _ForwardIterator>
+    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
     typename enable_if
     <
         __is_forward_iterator<_ForwardIterator>::value,
@@ -1430,9 +1435,9 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve)
+void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s,
+                                                       size_type __sz,
+                                                       size_type __reserve)
 {
     if (__reserve > max_size())
         this->__throw_length_error();
@@ -1455,7 +1460,6 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
 void
 basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)
 {
@@ -1593,7 +1597,6 @@
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
 void
 basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
 {
@@ -1690,7 +1693,6 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _InputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
     __is_exactly_input_iterator<_InputIterator>::value,
@@ -1718,7 +1720,6 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
     __is_forward_iterator<_ForwardIterator>::value,