Skip to content

Commit da769f1

Browse files
kikairoyajeremyd2019
authored andcommitted
[libc++] Introduce a new attribute keyword for Clang improves compatibility with Mingw-GCC
In MinGW environment, Clang handles dllexport attribute of internal class that defined in class template in different way from GCC. This incompatibility should be fixed but breaks ABI of libc++, so introduce a new keyword to keep ABI in MinGW environment with old and patched Clang and to stay ABI compatible on other platforms. This attribute is attached only for basic_ostream::sentry::sentry, basic_ostream::sentry::~sentry and basic_istream::sentry::sentry. Other entities won't be affected by patching Clang so doesn't need to be annotate. At a time to introduce a new class as a non-template inner type of a class template, all non-inline member functions of that class also needs to be attached _LIBCPP_HIDE_FROM_ABI_MINGW_OR_AFTER_V1 or _LIBCPP_HIDE_FROM_ABI, not _LIBCPP_HIDE_FROM_ABI_AFTER_V1. Otherwise, that member functions contained in DLL will be inaccessible on MinGW environment. For time to increase ABI version, _LIBCPP_HIDE_FROM_ABI_MINGW_OR_AFTER_V1 can be simply replaced to _LIBCPP_HIDE_FROM_ABI_AFTER_V1.
1 parent e4f98b8 commit da769f1

File tree

3 files changed

+23
-3
lines changed

3 files changed

+23
-3
lines changed

libcxx/include/__config

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,26 @@ typedef __char32_t char32_t;
530530
# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
531531
# endif
532532

533+
//// ** in-progress: this description block should be here or merged block above? **
534+
// _LIBCPP_HIDE_FROM_ABI(_AFTER_V1) is mandatory for member functions in a inner class in a class template
535+
// (e.g. std::basic_ostream<...>::sentry::sentry(...) ) due to strange behavior of MinGW-GCC about
536+
// instantiation combined with dllimport/dllexport described below. Former clang didn't do this buggy behavior
537+
// but will be aligned to GCC for platform compatibility (in particluar, required by some of libstdc++ package).
538+
// Thus, such member functions exist from a past (they are, ostream::sentry::sentry, ostream::ostream::~sentry
539+
// and istream::sentry::sentry only) need to be HIDE_FROM_ABI but simply attaching simply ABI on other platforms.
540+
// So it's needed a dedicated keyword named _LIBCPP_HIDE_FROM_ABI_MINGW_OR_AFTER_V1 to affects only for MinGW
541+
// target (and, Cygwin too). For other platforms, that is expanded to _LIBCPP_HIDE_FROM_ABI_AFTER_V1 because at
542+
// a time to fix V2 ABI comes, _LIBCPP_HIDE_FROM_ABI_MINGW_OR_AFTER_V1 can be simply replaced into
543+
// _LIBCPP_HIDE_FROM_ABI_AFTER_V1 and be completely removed.
544+
// If time to a new class in a class template comes, all non-inline member functions of that new inner class must
545+
// be declared with _LIBCPP_HIDE_FROM_ABI_AFTER_V1 otherwise they build to DLL will be inaccessible by MinGW-GCC.
546+
//// ** in-progress: describe peculiar behavior of MinGW-GCC **
547+
# if defined(__MINGW32__) || defined(__CYGWIN__)
548+
# define _LIBCPP_HIDE_FROM_ABI_MINGW_OR_AFTER_V1 inline _LIBCPP_HIDE_FROM_ABI
549+
# else
550+
# define _LIBCPP_HIDE_FROM_ABI_MINGW_OR_AFTER_V1 _LIBCPP_HIDE_FROM_ABI_AFTER_V1
551+
# endif
552+
533553
// TODO: Remove this workaround once we drop support for Clang 16
534554
# if __has_warning("-Wc++23-extensions")
535555
# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED_CXX23_EXTENSION _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++23-extensions")

libcxx/include/__ostream/basic_ostream.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ class basic_ostream<_CharT, _Traits>::sentry {
186186
basic_ostream<_CharT, _Traits>& __os_;
187187

188188
public:
189-
explicit sentry(basic_ostream<_CharT, _Traits>& __os);
190-
~sentry();
189+
explicit _LIBCPP_HIDE_FROM_ABI_MINGW_OR_AFTER_V1 sentry(basic_ostream<_CharT, _Traits>& __os);
190+
_LIBCPP_HIDE_FROM_ABI_MINGW_OR_AFTER_V1 ~sentry();
191191
sentry(const sentry&) = delete;
192192
sentry& operator=(const sentry&) = delete;
193193

libcxx/include/istream

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ class basic_istream<_CharT, _Traits>::sentry {
309309
bool __ok_;
310310

311311
public:
312-
explicit sentry(basic_istream<_CharT, _Traits>& __is, bool __noskipws = false);
312+
explicit _LIBCPP_HIDE_FROM_ABI_MINGW_OR_AFTER_V1 sentry(basic_istream<_CharT, _Traits>& __is, bool __noskipws = false);
313313
// ~sentry() = default;
314314

315315
_LIBCPP_HIDE_FROM_ABI explicit operator bool() const { return __ok_; }

0 commit comments

Comments
 (0)