diff --git a/libcxx/include/__locale b/libcxx/include/__locale --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -25,6 +25,8 @@ #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS # include +#else +# include <__mbstate_t.h> #endif #if defined(_LIBCPP_MSVCRT_LIKE) diff --git a/libcxx/include/__mbstate_t.h b/libcxx/include/__mbstate_t.h --- a/libcxx/include/__mbstate_t.h +++ b/libcxx/include/__mbstate_t.h @@ -16,29 +16,27 @@ # pragma GCC system_header #endif -// TODO(ldionne): -// The goal of this header is to provide mbstate_t without having to pull in -// or . This is necessary because we need that type even -// when we don't have (or try to provide) support for wchar_t, because several -// types like std::fpos are defined in terms of mbstate_t. +// The goal of this header is to provide mbstate_t without requiring all of +// or . It's also used by the libc++ versions of +// and to get mbstate_t when the C library doesn't provide +// or , hence the #include_next of those headers instead of #include. +// (e.g. if isn't present in the C library, the libc++ +// will include this header. This header needs to not turn around and cyclically +// include , but fall through to .) // -// This is a gruesome hack, but I don't know how to make it cleaner for -// the time being. +// This does not define std::mbstate_t -- this only brings in the declaration +// in the global namespace. -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -# include // for mbstate_t -#elif __has_include() +#if __has_include() # include // works on most Unixes #elif __has_include() # include // works on Darwin +#elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) && __has_include_next() +# include_next // fall back to the C standard provider of mbstate_t +#elif __has_include_next() +# include_next // is also required to make mbstate_t visible #else -# error "The library was configured without support for wide-characters, but we don't know how to get the definition of mbstate_t without on your platform." +# error "We don't know how to get the definition of mbstate_t without on your platform." #endif -_LIBCPP_BEGIN_NAMESPACE_STD - -using ::mbstate_t _LIBCPP_USING_IF_EXISTS; - -_LIBCPP_END_NAMESPACE_STD - #endif // _LIBCPP___MBSTATE_T_H diff --git a/libcxx/include/uchar.h b/libcxx/include/uchar.h --- a/libcxx/include/uchar.h +++ b/libcxx/include/uchar.h @@ -42,10 +42,12 @@ // Some platforms don't implement and we don't want to give a hard // error on those platforms. When the platform doesn't provide , at -// least include so we get the declaration for size_t. +// least include so we get the declaration for size_t, and try to +// get the declaration of mbstate_t too. #if __has_include_next() # include_next #else +# include <__mbstate_t.h> # include #endif diff --git a/libcxx/include/wchar.h b/libcxx/include/wchar.h --- a/libcxx/include/wchar.h +++ b/libcxx/include/wchar.h @@ -122,6 +122,8 @@ # if __has_include_next() # include_next +# else +# include <__mbstate_t.h> // make sure we have mbstate_t regardless of the existence of # endif // Determine whether we have const-correct overloads for wcschr and friends.