[libcxx] r281681 - [libc++] Add _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY to support GCC ABI compatibility

Mehdi Amini via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 28 21:50:15 PDT 2016


Hi Eric,

I’m trying to make sense of _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY here.

If I understand correctly, such a symbol will be present and visible in the dyliib, but emitted as available_externally and visibility hidden in the client code.

I don’t understand the hidden visibility part, it seems incorrect to me as a remaining reference to the symbol, that we expect to get from the dylib, will be marked as hidden and the linker will expect the access to be in the same DSO.

(This is the cause of the failure that causes me to revert: https://reviews.llvm.org/D25624 )

Can you clarify what is the reason to add a "visibility hidden” when building the client code?

Thanks,

Mehdi


> On Sep 15, 2016, at 5:00 PM, Eric Fiselier via cfe-commits <cfe-commits at lists.llvm.org> wrote:
> 
> Author: ericwf
> Date: Thu Sep 15 19:00:48 2016
> New Revision: 281681
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=281681&view=rev
> Log:
> [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
> 
> Modified:
>    libcxx/trunk/CMakeLists.txt
>    libcxx/trunk/docs/DesignDocs/VisibilityMacros.rst
>    libcxx/trunk/include/__config
>    libcxx/trunk/include/istream
>    libcxx/trunk/include/ostream
>    libcxx/trunk/include/streambuf
>    libcxx/trunk/include/string
>    libcxx/trunk/utils/sym_check/sym_diff.py
> 
> Modified: libcxx/trunk/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/CMakeLists.txt?rev=281681&r1=281680&r2=281681&view=diff
> ==============================================================================
> --- libcxx/trunk/CMakeLists.txt (original)
> +++ libcxx/trunk/CMakeLists.txt Thu Sep 15 19:00:48 2016
> @@ -330,6 +330,8 @@ endif()
> # headers
> add_compile_flags_if_supported(-nostdinc++)
> 
> +add_definitions(-D_LIBCPP_BUILDING_LIBRARY)
> +
> # Warning flags ===============================================================
> add_definitions(-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
> add_compile_flags_if_supported(
> 
> Modified: libcxx/trunk/docs/DesignDocs/VisibilityMacros.rst
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/docs/DesignDocs/VisibilityMacros.rst?rev=281681&r1=281680&r2=281681&view=diff
> ==============================================================================
> --- libcxx/trunk/docs/DesignDocs/VisibilityMacros.rst (original)
> +++ libcxx/trunk/docs/DesignDocs/VisibilityMacros.rst Thu Sep 15 19:00:48 2016
> @@ -71,6 +71,16 @@ Visibility Macros
>   However since `_LIBCPP_TYPE_VIS_ONLY` is the same as `_LIBCPP_TYPE_VIS` the
>   visibility is already correct. The macro has an empty definition with GCC.
> 
> +**_LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY**
> +  Mark a member function of a class template as hidden and inline except when
> +  building the libc++ library where it marks the symbol as being exported by
> +  the library.
> +
> +  This macro is used to maintain ABI compatibility for symbols that have been
> +  historically exported by the libc++ library but are now marked inline. It
> +  should only be applied to member functions of class templates that are
> +  externally instantiated.
> +
> **_LIBCPP_EXCEPTION_ABI**
>   Mark the member functions, typeinfo, and vtable of the type as being exported
>   by the libc++ library. This macro must be applied to all *exception types*.
> 
> Modified: libcxx/trunk/include/__config
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=281681&r1=281680&r2=281681&view=diff
> ==============================================================================
> --- libcxx/trunk/include/__config (original)
> +++ libcxx/trunk/include/__config Thu Sep 15 19:00:48 2016
> @@ -562,6 +562,7 @@ namespace std {
> #define _LIBCPP_ENUM_VIS
> #define _LIBCPP_INLINE_VISIBILITY __forceinline
> #define _LIBCPP_ALWAYS_INLINE     __forceinline
> +#define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __forceinline
> #endif // _WIN32
> 
> #ifndef _LIBCPP_HIDDEN
> @@ -616,6 +617,14 @@ namespace std {
> #define _LIBCPP_ALWAYS_INLINE  __attribute__ ((__visibility__("hidden"), __always_inline__))
> #endif
> 
> +#ifndef _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +# ifdef _LIBCPP_BUILDING_LIBRARY
> +#   define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__visibility__("default"), __always_inline__))
> +# else
> +#   define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
> +# endif
> +#endif
> +
> #ifndef _LIBCPP_PREFERRED_OVERLOAD
> #  if __has_attribute(__enable_if__)
> #    define _LIBCPP_PREFERRED_OVERLOAD __attribute__ ((__enable_if__(true, "")))
> 
> Modified: libcxx/trunk/include/istream
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/istream?rev=281681&r1=281680&r2=281681&view=diff
> ==============================================================================
> --- libcxx/trunk/include/istream (original)
> +++ libcxx/trunk/include/istream Thu Sep 15 19:00:48 2016
> @@ -184,19 +184,26 @@ public:
>     typedef typename traits_type::off_type off_type;
> 
>     // 27.7.1.1.1 Constructor/destructor:
> -    explicit basic_istream(basic_streambuf<char_type, traits_type>* __sb);
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    explicit basic_istream(basic_streambuf<char_type, traits_type>* __sb) : __gc_(0)
> +    { this->init(__sb); }
>     virtual ~basic_istream();
> protected:
> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
> -    _LIBCPP_INLINE_VISIBILITY
> +    inline _LIBCPP_INLINE_VISIBILITY
>     basic_istream(basic_istream&& __rhs);
> #endif
>     // 27.7.1.1.2 Assign/swap:
> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
> -    _LIBCPP_INLINE_VISIBILITY
> +    inline _LIBCPP_INLINE_VISIBILITY
>     basic_istream& operator=(basic_istream&& __rhs);
> #endif
> -    void swap(basic_istream& __rhs);
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    void swap(basic_istream& __rhs) {
> +      _VSTD::swap(__gc_, __rhs.__gc_);
> +      basic_ios<char_type, traits_type>::swap(__rhs);
> +    }
> 
> #if _LIBCPP_STD_VER > 11
> #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
> @@ -213,10 +220,19 @@ public:
>     class _LIBCPP_TYPE_VIS_ONLY sentry;
> 
>     // 27.7.1.2 Formatted input:
> -    basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&));
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&))
> +    { return __pf(*this); }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
>     basic_istream& operator>>(basic_ios<char_type, traits_type>&
> -                              (*__pf)(basic_ios<char_type, traits_type>&));
> -    basic_istream& operator>>(ios_base& (*__pf)(ios_base&));
> +                              (*__pf)(basic_ios<char_type, traits_type>&))
> +    { __pf(*this); return *this; }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    basic_istream& operator>>(ios_base& (*__pf)(ios_base&))
> +    { __pf(*this); return *this; }
> +
>     basic_istream& operator>>(basic_streambuf<char_type, traits_type>* __sb);
>     basic_istream& operator>>(bool& __n);
>     basic_istream& operator>>(short& __n);
> @@ -236,13 +252,31 @@ public:
>     _LIBCPP_INLINE_VISIBILITY
>     streamsize gcount() const {return __gc_;}
>     int_type get();
> -    basic_istream& get(char_type& __c);
> -    basic_istream& get(char_type* __s, streamsize __n);
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    basic_istream& get(char_type& __c) {
> +      int_type __ch = get();
> +      if (__ch != traits_type::eof())
> +        __c = traits_type::to_char_type(__ch);
> +      return *this;
> +    }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    basic_istream& get(char_type* __s, streamsize __n)
> +    { return get(__s, __n, this->widen('\n')); }
> +
>     basic_istream& get(char_type* __s, streamsize __n, char_type __dlm);
> -    basic_istream& get(basic_streambuf<char_type, traits_type>& __sb);
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    basic_istream& get(basic_streambuf<char_type, traits_type>& __sb)
> +    { return get(__sb, this->widen('\n')); }
> +
>     basic_istream& get(basic_streambuf<char_type, traits_type>& __sb, char_type __dlm);
> 
> -    basic_istream& getline(char_type* __s, streamsize __n);
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    basic_istream& getline(char_type* __s, streamsize __n)
> +    { return getline(__s, __n, this->widen('\n')); }
> +
>     basic_istream& getline(char_type* __s, streamsize __n, char_type __dlm);
> 
>     basic_istream& ignore(streamsize __n = 1, int_type __dlm = traits_type::eof());
> @@ -303,18 +337,9 @@ basic_istream<_CharT, _Traits>::sentry::
>         __is.setstate(ios_base::failbit);
> }
> 
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -basic_istream<_CharT, _Traits>::basic_istream(basic_streambuf<char_type, traits_type>* __sb)
> -    : __gc_(0)
> -{
> -    this->init(__sb);
> -}
> -
> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
> 
> template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> basic_istream<_CharT, _Traits>::basic_istream(basic_istream&& __rhs)
>     : __gc_(__rhs.__gc_)
> {
> @@ -323,7 +348,6 @@ basic_istream<_CharT, _Traits>::basic_is
> }
> 
> template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> basic_istream<_CharT, _Traits>&
> basic_istream<_CharT, _Traits>::operator=(basic_istream&& __rhs)
> {
> @@ -339,15 +363,6 @@ basic_istream<_CharT, _Traits>::~basic_i
> }
> 
> template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -void
> -basic_istream<_CharT, _Traits>::swap(basic_istream& __rhs)
> -{
> -    _VSTD::swap(__gc_, __rhs.__gc_);
> -    basic_ios<char_type, traits_type>::swap(__rhs);
> -}
> -
> -template <class _CharT, class _Traits>
> basic_istream<_CharT, _Traits>&
> basic_istream<_CharT, _Traits>::operator>>(unsigned short& __n)
> {
> @@ -724,33 +739,6 @@ basic_istream<_CharT, _Traits>::operator
>     return *this;
> }
> 
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -basic_istream<_CharT, _Traits>&
> -basic_istream<_CharT, _Traits>::operator>>(basic_istream& (*__pf)(basic_istream&))
> -{
> -    return __pf(*this);
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -basic_istream<_CharT, _Traits>&
> -basic_istream<_CharT, _Traits>::operator>>(basic_ios<char_type, traits_type>&
> -                                           (*__pf)(basic_ios<char_type, traits_type>&))
> -{
> -    __pf(*this);
> -    return *this;
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -basic_istream<_CharT, _Traits>&
> -basic_istream<_CharT, _Traits>::operator>>(ios_base& (*__pf)(ios_base&))
> -{
> -    __pf(*this);
> -    return *this;
> -}
> -
> template<class _CharT, class _Traits>
> basic_istream<_CharT, _Traits>&
> operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
> @@ -947,17 +935,6 @@ basic_istream<_CharT, _Traits>::get()
> }
> 
> template<class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -basic_istream<_CharT, _Traits>&
> -basic_istream<_CharT, _Traits>::get(char_type& __c)
> -{
> -    int_type __ch = get();
> -    if (__ch != traits_type::eof())
> -        __c = traits_type::to_char_type(__ch);
> -    return *this;
> -}
> -
> -template<class _CharT, class _Traits>
> basic_istream<_CharT, _Traits>&
> basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __dlm)
> {
> @@ -1006,14 +983,6 @@ basic_istream<_CharT, _Traits>::get(char
> }
> 
> template<class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -basic_istream<_CharT, _Traits>&
> -basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n)
> -{
> -    return get(__s, __n, this->widen('\n'));
> -}
> -
> -template<class _CharT, class _Traits>
> basic_istream<_CharT, _Traits>&
> basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __sb,
>                                     char_type __dlm)
> @@ -1068,14 +1037,6 @@ basic_istream<_CharT, _Traits>::get(basi
> }
> 
> template<class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -basic_istream<_CharT, _Traits>&
> -basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __sb)
> -{
> -    return get(__sb, this->widen('\n'));
> -}
> -
> -template<class _CharT, class _Traits>
> basic_istream<_CharT, _Traits>&
> basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_type __dlm)
> {
> @@ -1129,14 +1090,6 @@ basic_istream<_CharT, _Traits>::getline(
> }
> 
> template<class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -basic_istream<_CharT, _Traits>&
> -basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n)
> -{
> -    return getline(__s, __n, this->widen('\n'));
> -}
> -
> -template<class _CharT, class _Traits>
> basic_istream<_CharT, _Traits>&
> basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)
> {
> @@ -1503,41 +1456,38 @@ public:
>     typedef typename traits_type::off_type off_type;
> 
>     // constructor/destructor
> -    explicit basic_iostream(basic_streambuf<char_type, traits_type>* __sb);
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    explicit basic_iostream(basic_streambuf<char_type, traits_type>* __sb)
> +      : basic_istream<_CharT, _Traits>(__sb)
> +    {}
> +
>     virtual ~basic_iostream();
> protected:
> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
> -    _LIBCPP_INLINE_VISIBILITY
> +    inline _LIBCPP_INLINE_VISIBILITY
>     basic_iostream(basic_iostream&& __rhs);
> #endif
> 
>     // assign/swap
> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
> -    _LIBCPP_INLINE_VISIBILITY
> +    inline _LIBCPP_INLINE_VISIBILITY
>     basic_iostream& operator=(basic_iostream&& __rhs);
> #endif
> -    void swap(basic_iostream& __rhs);
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    void swap(basic_iostream& __rhs)
> +    { basic_istream<char_type, traits_type>::swap(__rhs); }
> public:
> };
> 
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -basic_iostream<_CharT, _Traits>::basic_iostream(basic_streambuf<char_type, traits_type>* __sb)
> -    : basic_istream<_CharT, _Traits>(__sb)
> -{
> -}
> -
> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
> 
> template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> basic_iostream<_CharT, _Traits>::basic_iostream(basic_iostream&& __rhs)
>     : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs))
> {
> }
> 
> template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> basic_iostream<_CharT, _Traits>&
> basic_iostream<_CharT, _Traits>::operator=(basic_iostream&& __rhs)
> {
> @@ -1552,14 +1502,6 @@ basic_iostream<_CharT, _Traits>::~basic_
> {
> }
> 
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -void
> -basic_iostream<_CharT, _Traits>::swap(basic_iostream& __rhs)
> -{
> -    basic_istream<char_type, traits_type>::swap(__rhs);
> -}
> -
> template<class _CharT, class _Traits, class _Allocator>
> basic_istream<_CharT, _Traits>&
> operator>>(basic_istream<_CharT, _Traits>& __is,
> 
> Modified: libcxx/trunk/include/ostream
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/ostream?rev=281681&r1=281680&r2=281681&view=diff
> ==============================================================================
> --- libcxx/trunk/include/ostream (original)
> +++ libcxx/trunk/include/ostream Thu Sep 15 19:00:48 2016
> @@ -160,20 +160,24 @@ public:
>     typedef typename traits_type::off_type off_type;
> 
>     // 27.7.2.2 Constructor/destructor:
> -    explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb);
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb)
> +    { this->init(__sb); }
>     virtual ~basic_ostream();
> protected:
> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
> -    _LIBCPP_INLINE_VISIBILITY
> +    inline _LIBCPP_INLINE_VISIBILITY
>     basic_ostream(basic_ostream&& __rhs);
> #endif
> 
>     // 27.7.2.3 Assign/swap
> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
> -    _LIBCPP_INLINE_VISIBILITY
> +    inline _LIBCPP_INLINE_VISIBILITY
>     basic_ostream& operator=(basic_ostream&& __rhs);
> #endif
> -    void swap(basic_ostream& __rhs);
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    void swap(basic_ostream& __rhs)
> +    { basic_ios<char_type, traits_type>::swap(__rhs); }
> 
> #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
>     basic_ostream           (const basic_ostream& __rhs) = delete;
> @@ -188,10 +192,19 @@ public:
>     class _LIBCPP_TYPE_VIS_ONLY sentry;
> 
>     // 27.7.2.6 Formatted output:
> -    basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&));
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&))
> +    { return __pf(*this); }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
>     basic_ostream& operator<<(basic_ios<char_type, traits_type>&
> -                              (*__pf)(basic_ios<char_type,traits_type>&));
> -    basic_ostream& operator<<(ios_base& (*__pf)(ios_base&));
> +                              (*__pf)(basic_ios<char_type,traits_type>&))
> +    { __pf(*this); return *this; }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    basic_ostream& operator<<(ios_base& (*__pf)(ios_base&))
> +    { __pf(*this); return *this; }
> +
>     basic_ostream& operator<<(bool __n);
>     basic_ostream& operator<<(short __n);
>     basic_ostream& operator<<(unsigned short __n);
> @@ -213,8 +226,11 @@ public:
>     basic_ostream& flush();
> 
>     // 27.7.2.5 seeks:
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
>     pos_type tellp();
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
>     basic_ostream& seekp(pos_type __pos);
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
>     basic_ostream& seekp(off_type __off, ios_base::seekdir __dir);
> 
> protected:
> @@ -274,24 +290,15 @@ basic_ostream<_CharT, _Traits>::sentry::
>     }
> }
> 
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -basic_ostream<_CharT, _Traits>::basic_ostream(basic_streambuf<char_type, traits_type>* __sb)
> -{
> -    this->init(__sb);
> -}
> -
> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
> 
> template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> basic_ostream<_CharT, _Traits>::basic_ostream(basic_ostream&& __rhs)
> {
>     this->move(__rhs);
> }
> 
> template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> basic_ostream<_CharT, _Traits>&
> basic_ostream<_CharT, _Traits>::operator=(basic_ostream&& __rhs)
> {
> @@ -307,41 +314,6 @@ basic_ostream<_CharT, _Traits>::~basic_o
> }
> 
> template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -void
> -basic_ostream<_CharT, _Traits>::swap(basic_ostream& __rhs)
> -{
> -    basic_ios<char_type, traits_type>::swap(__rhs);
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -basic_ostream<_CharT, _Traits>&
> -basic_ostream<_CharT, _Traits>::operator<<(basic_ostream& (*__pf)(basic_ostream&))
> -{
> -    return __pf(*this);
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -basic_ostream<_CharT, _Traits>&
> -basic_ostream<_CharT, _Traits>::operator<<(basic_ios<char_type, traits_type>&
> -                                           (*__pf)(basic_ios<char_type,traits_type>&))
> -{
> -    __pf(*this);
> -    return *this;
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -basic_ostream<_CharT, _Traits>&
> -basic_ostream<_CharT, _Traits>::operator<<(ios_base& (*__pf)(ios_base&))
> -{
> -    __pf(*this);
> -    return *this;
> -}
> -
> -template <class _CharT, class _Traits>
> basic_ostream<_CharT, _Traits>&
> basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_type>* __sb)
> {
> @@ -989,7 +961,6 @@ basic_ostream<_CharT, _Traits>::flush()
> }
> 
> template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> typename basic_ostream<_CharT, _Traits>::pos_type
> basic_ostream<_CharT, _Traits>::tellp()
> {
> @@ -999,7 +970,6 @@ basic_ostream<_CharT, _Traits>::tellp()
> }
> 
> template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> basic_ostream<_CharT, _Traits>&
> basic_ostream<_CharT, _Traits>::seekp(pos_type __pos)
> {
> @@ -1013,7 +983,6 @@ basic_ostream<_CharT, _Traits>::seekp(po
> }
> 
> template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> basic_ostream<_CharT, _Traits>&
> basic_ostream<_CharT, _Traits>::seekp(off_type __off, ios_base::seekdir __dir)
> {
> 
> Modified: libcxx/trunk/include/streambuf
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/streambuf?rev=281681&r1=281680&r2=281681&view=diff
> ==============================================================================
> --- libcxx/trunk/include/streambuf (original)
> +++ libcxx/trunk/include/streambuf Thu Sep 15 19:00:48 2016
> @@ -132,32 +132,96 @@ public:
>     virtual ~basic_streambuf();
> 
>     // 27.6.2.2.1 locales:
> -    locale pubimbue(const locale& __loc);
> -    locale getloc() const;
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    locale pubimbue(const locale& __loc) {
> +        imbue(__loc);
> +        locale __r = __loc_;
> +        __loc_ = __loc;
> +        return __r;
> +    }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    locale getloc() const { return __loc_; }
> 
>     // 27.6.2.2.2 buffer and positioning:
> -    basic_streambuf* pubsetbuf(char_type* __s, streamsize __n);
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    basic_streambuf* pubsetbuf(char_type* __s, streamsize __n)
> +    { return setbuf(__s, __n); }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
>     pos_type pubseekoff(off_type __off, ios_base::seekdir __way,
> -                        ios_base::openmode __which = ios_base::in | ios_base::out);
> +                        ios_base::openmode __which = ios_base::in | ios_base::out)
> +    { return seekoff(__off, __way, __which); }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
>     pos_type pubseekpos(pos_type __sp,
> -                        ios_base::openmode __which = ios_base::in | ios_base::out);
> -    int pubsync();
> +                        ios_base::openmode __which = ios_base::in | ios_base::out)
> +    { return seekpos(__sp, __which); }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    int pubsync() { return sync(); }
> 
>     // Get and put areas:
>     // 27.6.2.2.3 Get area:
> -    streamsize in_avail();
> -    int_type snextc();
> -    int_type sbumpc();
> -    int_type sgetc();
> -    streamsize sgetn(char_type* __s, streamsize __n);
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    streamsize in_avail() {
> +        if (__ninp_ < __einp_)
> +            return static_cast<streamsize>(__einp_ - __ninp_);
> +        return showmanyc();
> +    }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    int_type snextc() {
> +        if (sbumpc() == traits_type::eof())
> +            return traits_type::eof();
> +        return sgetc();
> +    }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    int_type sbumpc() {
> +        if (__ninp_ == __einp_)
> +            return uflow();
> +        return traits_type::to_int_type(*__ninp_++);
> +    }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    int_type sgetc() {
> +        if (__ninp_ == __einp_)
> +            return underflow();
> +        return traits_type::to_int_type(*__ninp_);
> +    }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    streamsize sgetn(char_type* __s, streamsize __n)
> +    { return xsgetn(__s, __n); }
> 
>     // 27.6.2.2.4 Putback:
> -    int_type sputbackc(char_type __c);
> -    int_type sungetc();
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    int_type sputbackc(char_type __c) {
> +        if (__binp_ == __ninp_ || !traits_type::eq(__c, __ninp_[-1]))
> +            return pbackfail(traits_type::to_int_type(__c));
> +        return traits_type::to_int_type(*--__ninp_);
> +    }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    int_type sungetc() {
> +        if (__binp_ == __ninp_)
> +          return pbackfail();
> +        return traits_type::to_int_type(*--__ninp_);
> +    }
> 
>     // 27.6.2.2.5 Put area:
> -    int_type sputc(char_type __c);
> -    streamsize sputn(const char_type* __s, streamsize __n);
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    int_type sputc(char_type __c) {
> +        if (__nout_ == __eout_)
> +            return overflow(traits_type::to_int_type(__c));
> +        *__nout_++ = __c;
> +        return traits_type::to_int_type(__c);
> +    }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    streamsize sputn(const char_type* __s, streamsize __n)
> +    { return xsputn(__s, __n); }
> 
> protected:
>     basic_streambuf();
> @@ -169,15 +233,30 @@ protected:
>     _LIBCPP_ALWAYS_INLINE char_type* eback() const {return __binp_;}
>     _LIBCPP_ALWAYS_INLINE char_type* gptr()  const {return __ninp_;}
>     _LIBCPP_ALWAYS_INLINE char_type* egptr() const {return __einp_;}
> -    void gbump(int __n);
> -    void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend);
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    void gbump(int __n) { __ninp_ += __n; }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) {
> +        __binp_ = __gbeg;
> +        __ninp_ = __gnext;
> +        __einp_ = __gend;
> +    }
> 
>     // 27.6.2.3.3 Put area:
>     _LIBCPP_ALWAYS_INLINE char_type* pbase() const {return __bout_;}
>     _LIBCPP_ALWAYS_INLINE char_type* pptr()  const {return __nout_;}
>     _LIBCPP_ALWAYS_INLINE char_type* epptr() const {return __eout_;}
> -    void pbump(int __n);
> -    void setp(char_type* __pbeg, char_type* __pend);
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    void pbump(int __n) { __nout_ += __n; }
> +
> +    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
> +    void setp(char_type* __pbeg, char_type* __pend) {
> +        __bout_ = __nout_ = __pbeg;
> +        __eout_ = __pend;
> +    }
> 
>     // 27.6.2.4 virtual functions:
>     // 27.6.2.4.1 Locales:
> @@ -220,147 +299,6 @@ basic_streambuf<_CharT, _Traits>::~basic
> }
> 
> template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -locale
> -basic_streambuf<_CharT, _Traits>::pubimbue(const locale& __loc)
> -{
> -    imbue(__loc);
> -    locale __r = __loc_;
> -    __loc_ = __loc;
> -    return __r;
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -locale
> -basic_streambuf<_CharT, _Traits>::getloc() const
> -{
> -    return __loc_;
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -basic_streambuf<_CharT, _Traits>*
> -basic_streambuf<_CharT, _Traits>::pubsetbuf(char_type* __s, streamsize __n)
> -{
> -    return setbuf(__s, __n);
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -typename basic_streambuf<_CharT, _Traits>::pos_type
> -basic_streambuf<_CharT, _Traits>::pubseekoff(off_type __off,
> -                                             ios_base::seekdir __way,
> -                                             ios_base::openmode __which)
> -{
> -    return seekoff(__off, __way, __which);
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -typename basic_streambuf<_CharT, _Traits>::pos_type
> -basic_streambuf<_CharT, _Traits>::pubseekpos(pos_type __sp,
> -                                             ios_base::openmode __which)
> -{
> -    return seekpos(__sp, __which);
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -int
> -basic_streambuf<_CharT, _Traits>::pubsync()
> -{
> -    return sync();
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -streamsize
> -basic_streambuf<_CharT, _Traits>::in_avail()
> -{
> -    if (__ninp_ < __einp_)
> -        return static_cast<streamsize>(__einp_ - __ninp_);
> -    return showmanyc();
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -typename basic_streambuf<_CharT, _Traits>::int_type
> -basic_streambuf<_CharT, _Traits>::snextc()
> -{
> -    if (sbumpc() == traits_type::eof())
> -        return traits_type::eof();
> -    return sgetc();
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -typename basic_streambuf<_CharT, _Traits>::int_type
> -basic_streambuf<_CharT, _Traits>::sbumpc()
> -{
> -    if (__ninp_ == __einp_)
> -        return uflow();
> -    return traits_type::to_int_type(*__ninp_++);
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -typename basic_streambuf<_CharT, _Traits>::int_type
> -basic_streambuf<_CharT, _Traits>::sgetc()
> -{
> -    if (__ninp_ == __einp_)
> -        return underflow();
> -    return traits_type::to_int_type(*__ninp_);
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -streamsize
> -basic_streambuf<_CharT, _Traits>::sgetn(char_type* __s, streamsize __n)
> -{
> -    return xsgetn(__s, __n);
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -typename basic_streambuf<_CharT, _Traits>::int_type
> -basic_streambuf<_CharT, _Traits>::sputbackc(char_type __c)
> -{
> -    if (__binp_ == __ninp_ || !traits_type::eq(__c, __ninp_[-1]))
> -        return pbackfail(traits_type::to_int_type(__c));
> -    return traits_type::to_int_type(*--__ninp_);
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -typename basic_streambuf<_CharT, _Traits>::int_type
> -basic_streambuf<_CharT, _Traits>::sungetc()
> -{
> -    if (__binp_ == __ninp_)
> -        return pbackfail();
> -    return traits_type::to_int_type(*--__ninp_);
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -typename basic_streambuf<_CharT, _Traits>::int_type
> -basic_streambuf<_CharT, _Traits>::sputc(char_type __c)
> -{
> -    if (__nout_ == __eout_)
> -        return overflow(traits_type::to_int_type(__c));
> -    *__nout_++ = __c;
> -    return traits_type::to_int_type(__c);
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -streamsize
> -basic_streambuf<_CharT, _Traits>::sputn(const char_type* __s, streamsize __n)
> -{
> -    return xsputn(__s, __n);
> -}
> -
> -template <class _CharT, class _Traits>
> basic_streambuf<_CharT, _Traits>::basic_streambuf()
>     : __binp_(0),
>       __ninp_(0),
> @@ -411,42 +349,6 @@ basic_streambuf<_CharT, _Traits>::swap(b
> }
> 
> template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -void
> -basic_streambuf<_CharT, _Traits>::gbump(int __n)
> -{
> -    __ninp_ += __n;
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -void
> -basic_streambuf<_CharT, _Traits>::setg(char_type* __gbeg, char_type* __gnext,
> -                                                          char_type* __gend)
> -{
> -    __binp_ = __gbeg;
> -    __ninp_ = __gnext;
> -    __einp_ = __gend;
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -void
> -basic_streambuf<_CharT, _Traits>::pbump(int __n)
> -{
> -    __nout_ += __n;
> -}
> -
> -template <class _CharT, class _Traits>
> -inline _LIBCPP_INLINE_VISIBILITY
> -void
> -basic_streambuf<_CharT, _Traits>::setp(char_type* __pbeg, char_type* __pend)
> -{
> -    __bout_ = __nout_ = __pbeg;
> -    __eout_ = __pend;
> -}
> -
> -template <class _CharT, class _Traits>
> void
> basic_streambuf<_CharT, _Traits>::imbue(const locale&)
> {
> 
> Modified: libcxx/trunk/include/string
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/string?rev=281681&r1=281680&r2=281681&view=diff
> ==============================================================================
> --- libcxx/trunk/include/string (original)
> +++ libcxx/trunk/include/string Thu Sep 15 19:00:48 2016
> @@ -1269,11 +1269,15 @@ private:
>                  __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 @@ private:
>     __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 @@ basic_string<_CharT, _Traits, _Allocator
> }
> 
> 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 @@ basic_string<_CharT, _Traits, _Allocator
> }
> 
> 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 @@ basic_string<_CharT, _Traits, _Allocator
> #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 @@ basic_string<_CharT, _Traits, _Allocator
> 
> 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 @@ basic_string<_CharT, _Traits, _Allocator
> 
> template <class _CharT, class _Traits, class _Allocator>
> template <class _ForwardIterator>
> -inline _LIBCPP_INLINE_VISIBILITY
> typename enable_if
> <
>     __is_forward_iterator<_ForwardIterator>::value,
> 
> Modified: libcxx/trunk/utils/sym_check/sym_diff.py
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/sym_check/sym_diff.py?rev=281681&r1=281680&r2=281681&view=diff
> ==============================================================================
> --- libcxx/trunk/utils/sym_check/sym_diff.py (original)
> +++ libcxx/trunk/utils/sym_check/sym_diff.py Thu Sep 15 19:00:48 2016
> @@ -24,6 +24,10 @@ def main():
>         help='Only print symbol names',
>         action='store_true', default=False)
>     parser.add_argument(
> +        '--removed-only', dest='removed_only',
> +        help='Only print removed symbols',
> +        action='store_true', default=False)
> +    parser.add_argument(
>         '-o', '--output', dest='output',
>         help='The output file. stdout is used if not given',
>         type=str, action='store', default=None)
> @@ -41,6 +45,8 @@ def main():
>     new_syms_list = util.extract_or_load(args.new_syms)
> 
>     added, removed, changed = diff.diff(old_syms_list, new_syms_list)
> +    if args.removed_only:
> +        added = {}
>     report, is_break = diff.report_diff(added, removed, changed,
>                                         names_only=args.names_only,
>                                         demangle=args.demangle)
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list