From f8f31c4985f9276811ba4c30ec8ebdd4992093d5 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 16 Sep 2016 00:00:48 +0000 Subject: [PATCH] [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 struct Foo { void foo(); void bar(); }; template void Foo::foo() {} template inline INLINE_VISIBILITY void Foo::bar() {} template struct Foo; ``` 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 --- libcxx/CMakeLists.txt | 2 + libcxx/docs/DesignDocs/VisibilityMacros.rst | 10 + libcxx/include/__config | 9 + libcxx/include/istream | 168 ++++++---------- libcxx/include/ostream | 77 +++----- libcxx/include/streambuf | 294 ++++++++++------------------ libcxx/include/string | 15 +- libcxx/utils/sym_check/sym_diff.py | 6 + 8 files changed, 211 insertions(+), 370 deletions(-) diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index 7c0f061..a80349a 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -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( diff --git a/libcxx/docs/DesignDocs/VisibilityMacros.rst b/libcxx/docs/DesignDocs/VisibilityMacros.rst index 6e2294d..db98315 100644 --- a/libcxx/docs/DesignDocs/VisibilityMacros.rst +++ b/libcxx/docs/DesignDocs/VisibilityMacros.rst @@ -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*. diff --git a/libcxx/include/__config b/libcxx/include/__config index 1afed4f..5dd9104 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -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, ""))) diff --git a/libcxx/include/istream b/libcxx/include/istream index 3ef6382..180a395 100644 --- a/libcxx/include/istream +++ b/libcxx/include/istream @@ -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* __sb); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + explicit basic_istream(basic_streambuf* __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::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& - (*__pf)(basic_ios&)); - basic_istream& operator>>(ios_base& (*__pf)(ios_base&)); + (*__pf)(basic_ios&)) + { __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* __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& __sb); + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + basic_istream& get(basic_streambuf& __sb) + { return get(__sb, this->widen('\n')); } + basic_istream& get(basic_streambuf& __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::sentry(basic_istream<_CharT, _Traits>& _ __is.setstate(ios_base::failbit); } -template -inline _LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>::basic_istream(basic_streambuf* __sb) - : __gc_(0) -{ - this->init(__sb); -} - #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template -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_istream(basic_istream&& __rhs) } template -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_istream() } template -inline _LIBCPP_INLINE_VISIBILITY -void -basic_istream<_CharT, _Traits>::swap(basic_istream& __rhs) -{ - _VSTD::swap(__gc_, __rhs.__gc_); - basic_ios::swap(__rhs); -} - -template basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(unsigned short& __n) { @@ -724,33 +739,6 @@ basic_istream<_CharT, _Traits>::operator>>(int& __n) return *this; } -template -inline _LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>& -basic_istream<_CharT, _Traits>::operator>>(basic_istream& (*__pf)(basic_istream&)) -{ - return __pf(*this); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>& -basic_istream<_CharT, _Traits>::operator>>(basic_ios& - (*__pf)(basic_ios&)) -{ - __pf(*this); - return *this; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>& -basic_istream<_CharT, _Traits>::operator>>(ios_base& (*__pf)(ios_base&)) -{ - __pf(*this); - return *this; -} - template basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s) @@ -947,17 +935,6 @@ basic_istream<_CharT, _Traits>::get() } template -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 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_type* __s, streamsize __n, char_type __ } template -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 basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::get(basic_streambuf& __sb, char_type __dlm) @@ -1068,14 +1037,6 @@ basic_istream<_CharT, _Traits>::get(basic_streambuf& __s } template -inline _LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>& -basic_istream<_CharT, _Traits>::get(basic_streambuf& __sb) -{ - return get(__sb, this->widen('\n')); -} - -template 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(char_type* __s, streamsize __n, char_typ } template -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 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* __sb); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + explicit basic_iostream(basic_streambuf* __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::swap(__rhs); } public: }; -template -inline _LIBCPP_INLINE_VISIBILITY -basic_iostream<_CharT, _Traits>::basic_iostream(basic_streambuf* __sb) - : basic_istream<_CharT, _Traits>(__sb) -{ -} - #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template -inline _LIBCPP_INLINE_VISIBILITY basic_iostream<_CharT, _Traits>::basic_iostream(basic_iostream&& __rhs) : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs)) { } template -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_iostream() { } -template -inline _LIBCPP_INLINE_VISIBILITY -void -basic_iostream<_CharT, _Traits>::swap(basic_iostream& __rhs) -{ - basic_istream::swap(__rhs); -} - template basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, diff --git a/libcxx/include/ostream b/libcxx/include/ostream index 3a4c218..cf20514 100644 --- a/libcxx/include/ostream +++ b/libcxx/include/ostream @@ -160,20 +160,24 @@ public: typedef typename traits_type::off_type off_type; // 27.7.2.2 Constructor/destructor: - explicit basic_ostream(basic_streambuf* __sb); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + explicit basic_ostream(basic_streambuf* __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::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& - (*__pf)(basic_ios&)); - basic_ostream& operator<<(ios_base& (*__pf)(ios_base&)); + (*__pf)(basic_ios&)) + { __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::~sentry() } } -template -inline _LIBCPP_INLINE_VISIBILITY -basic_ostream<_CharT, _Traits>::basic_ostream(basic_streambuf* __sb) -{ - this->init(__sb); -} - #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template -inline _LIBCPP_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>::basic_ostream(basic_ostream&& __rhs) { this->move(__rhs); } template -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_ostream() } template -inline _LIBCPP_INLINE_VISIBILITY -void -basic_ostream<_CharT, _Traits>::swap(basic_ostream& __rhs) -{ - basic_ios::swap(__rhs); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -basic_ostream<_CharT, _Traits>& -basic_ostream<_CharT, _Traits>::operator<<(basic_ostream& (*__pf)(basic_ostream&)) -{ - return __pf(*this); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -basic_ostream<_CharT, _Traits>& -basic_ostream<_CharT, _Traits>::operator<<(basic_ios& - (*__pf)(basic_ios&)) -{ - __pf(*this); - return *this; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -basic_ostream<_CharT, _Traits>& -basic_ostream<_CharT, _Traits>::operator<<(ios_base& (*__pf)(ios_base&)) -{ - __pf(*this); - return *this; -} - -template basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf* __sb) { @@ -989,7 +961,6 @@ basic_ostream<_CharT, _Traits>::flush() } template -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 -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(pos_type __pos) } template -inline _LIBCPP_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::seekp(off_type __off, ios_base::seekdir __dir) { diff --git a/libcxx/include/streambuf b/libcxx/include/streambuf index 3ffe413..6c47838 100644 --- a/libcxx/include/streambuf +++ b/libcxx/include/streambuf @@ -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(__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_streambuf() } template -inline _LIBCPP_INLINE_VISIBILITY -locale -basic_streambuf<_CharT, _Traits>::pubimbue(const locale& __loc) -{ - imbue(__loc); - locale __r = __loc_; - __loc_ = __loc; - return __r; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -locale -basic_streambuf<_CharT, _Traits>::getloc() const -{ - return __loc_; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -basic_streambuf<_CharT, _Traits>* -basic_streambuf<_CharT, _Traits>::pubsetbuf(char_type* __s, streamsize __n) -{ - return setbuf(__s, __n); -} - -template -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 -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 -inline _LIBCPP_INLINE_VISIBILITY -int -basic_streambuf<_CharT, _Traits>::pubsync() -{ - return sync(); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -streamsize -basic_streambuf<_CharT, _Traits>::in_avail() -{ - if (__ninp_ < __einp_) - return static_cast(__einp_ - __ninp_); - return showmanyc(); -} - -template -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 -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 -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 -inline _LIBCPP_INLINE_VISIBILITY -streamsize -basic_streambuf<_CharT, _Traits>::sgetn(char_type* __s, streamsize __n) -{ - return xsgetn(__s, __n); -} - -template -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 -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 -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 -inline _LIBCPP_INLINE_VISIBILITY -streamsize -basic_streambuf<_CharT, _Traits>::sputn(const char_type* __s, streamsize __n) -{ - return xsputn(__s, __n); -} - -template basic_streambuf<_CharT, _Traits>::basic_streambuf() : __binp_(0), __ninp_(0), @@ -411,42 +349,6 @@ basic_streambuf<_CharT, _Traits>::swap(basic_streambuf& __sb) } template -inline _LIBCPP_INLINE_VISIBILITY -void -basic_streambuf<_CharT, _Traits>::gbump(int __n) -{ - __ninp_ += __n; -} - -template -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 -inline _LIBCPP_INLINE_VISIBILITY -void -basic_streambuf<_CharT, _Traits>::pbump(int __n) -{ - __nout_ += __n; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -void -basic_streambuf<_CharT, _Traits>::setp(char_type* __pbeg, char_type* __pend) -{ - __bout_ = __nout_ = __pbeg; - __eout_ = __pend; -} - -template void basic_streambuf<_CharT, _Traits>::imbue(const locale&) { diff --git a/libcxx/include/string b/libcxx/include/string index 39bda49..fa5679d 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -1269,11 +1269,15 @@ private: __align_it (__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 + 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 + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename enable_if < __is_forward_iterator<_ForwardIterator>::value, @@ -1430,9 +1435,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __ } template -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>::__init(const value_type* __s, size_ty } template -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>::basic_string(basic_string&& __str, co #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template -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>::basic_string(__self_view __sv, const template template -inline _LIBCPP_INLINE_VISIBILITY typename enable_if < __is_exactly_input_iterator<_InputIterator>::value, @@ -1718,7 +1720,6 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _Input template template -inline _LIBCPP_INLINE_VISIBILITY typename enable_if < __is_forward_iterator<_ForwardIterator>::value, diff --git a/libcxx/utils/sym_check/sym_diff.py b/libcxx/utils/sym_check/sym_diff.py index 69c3400..0d88a2b 100755 --- a/libcxx/utils/sym_check/sym_diff.py +++ b/libcxx/utils/sym_check/sym_diff.py @@ -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) -- 2.7.4