EricWF created this revision. EricWF added reviewers: mclow.lists, eugenis, danalbert, jroelofs. EricWF added a subscriber: cfe-commits. Herald added subscribers: mgorny, beanz.
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. https://reviews.llvm.org/D24600 Files: CMakeLists.txt include/__config include/istream include/ostream include/streambuf include/string utils/sym_check/sym_diff.py
Index: utils/sym_check/sym_diff.py =================================================================== --- utils/sym_check/sym_diff.py +++ utils/sym_check/sym_diff.py @@ -24,6 +24,10 @@ 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 @@ 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) Index: include/string =================================================================== --- include/string +++ include/string @@ -1430,7 +1430,7 @@ } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve) { @@ -1455,7 +1455,7 @@ } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) { @@ -1593,7 +1593,7 @@ #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) { @@ -1690,7 +1690,7 @@ template <class _CharT, class _Traits, class _Allocator> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename enable_if < __is_exactly_input_iterator<_InputIterator>::value, @@ -1718,7 +1718,7 @@ template <class _CharT, class _Traits, class _Allocator> template <class _ForwardIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename enable_if < __is_forward_iterator<_ForwardIterator>::value, Index: include/streambuf =================================================================== --- include/streambuf +++ include/streambuf @@ -220,7 +220,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY locale basic_streambuf<_CharT, _Traits>::pubimbue(const locale& __loc) { @@ -231,23 +231,23 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY locale basic_streambuf<_CharT, _Traits>::getloc() const { return __loc_; } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_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 +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename basic_streambuf<_CharT, _Traits>::pos_type basic_streambuf<_CharT, _Traits>::pubseekoff(off_type __off, ios_base::seekdir __way, @@ -257,24 +257,24 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_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 +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY int basic_streambuf<_CharT, _Traits>::pubsync() { return sync(); } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY streamsize basic_streambuf<_CharT, _Traits>::in_avail() { @@ -284,7 +284,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>::snextc() { @@ -294,7 +294,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>::sbumpc() { @@ -304,7 +304,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>::sgetc() { @@ -314,15 +314,15 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_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 +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>::sputbackc(char_type __c) { @@ -332,7 +332,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>::sungetc() { @@ -342,7 +342,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>::sputc(char_type __c) { @@ -353,7 +353,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY streamsize basic_streambuf<_CharT, _Traits>::sputn(const char_type* __s, streamsize __n) { @@ -411,15 +411,15 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void basic_streambuf<_CharT, _Traits>::gbump(int __n) { __ninp_ += __n; } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void basic_streambuf<_CharT, _Traits>::setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) @@ -430,15 +430,15 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void basic_streambuf<_CharT, _Traits>::pbump(int __n) { __nout_ += __n; } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void basic_streambuf<_CharT, _Traits>::setp(char_type* __pbeg, char_type* __pend) { Index: include/ostream =================================================================== --- include/ostream +++ include/ostream @@ -164,13 +164,13 @@ 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); @@ -275,23 +275,21 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_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,23 +305,23 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_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 +inline _LIBCPP_EXTERN_TEMPLATE_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 +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(basic_ios<char_type, traits_type>& (*__pf)(basic_ios<char_type,traits_type>&)) @@ -333,7 +331,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(ios_base& (*__pf)(ios_base&)) { @@ -989,7 +987,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename basic_ostream<_CharT, _Traits>::pos_type basic_ostream<_CharT, _Traits>::tellp() { @@ -999,7 +997,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::seekp(pos_type __pos) { @@ -1013,7 +1011,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::seekp(off_type __off, ios_base::seekdir __dir) { Index: include/istream =================================================================== --- include/istream +++ include/istream @@ -188,12 +188,12 @@ 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); @@ -304,7 +304,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_istream<_CharT, _Traits>::basic_istream(basic_streambuf<char_type, traits_type>* __sb) : __gc_(0) { @@ -314,16 +314,14 @@ #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_) { __rhs.__gc_ = 0; this->move(__rhs); } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator=(basic_istream&& __rhs) { @@ -339,7 +337,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void basic_istream<_CharT, _Traits>::swap(basic_istream& __rhs) { @@ -725,15 +723,15 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_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 +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(basic_ios<char_type, traits_type>& (*__pf)(basic_ios<char_type, traits_type>&)) @@ -743,7 +741,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(ios_base& (*__pf)(ios_base&)) { @@ -947,7 +945,7 @@ } template<class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::get(char_type& __c) { @@ -1006,7 +1004,7 @@ } template<class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n) { @@ -1068,7 +1066,7 @@ } template<class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __sb) { @@ -1129,7 +1127,7 @@ } template<class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n) { @@ -1507,37 +1505,35 @@ 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); public: }; template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_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) { @@ -1553,7 +1549,7 @@ } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void basic_iostream<_CharT, _Traits>::swap(basic_iostream& __rhs) { Index: include/__config =================================================================== --- include/__config +++ include/__config @@ -232,6 +232,12 @@ # endif #endif +#ifndef _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY +# ifdef _LIBCPP_MSVC +# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __forceinline +# endif +#endif + #ifndef _LIBCPP_EXCEPTION_ABI #define _LIBCPP_EXCEPTION_ABI _LIBCPP_TYPE_VIS #endif @@ -286,6 +292,14 @@ #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 + #if defined(__clang__) // _LIBCPP_ALTERNATE_STRING_LAYOUT is an old name for Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -330,6 +330,8 @@ # 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(
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits